惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
博客园 - 【当耐特】
博客园_首页
The GitHub Blog
The GitHub Blog
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
博客园 - 三生石上(FineUI控件)
D
Docker
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
小众软件
小众软件
I
InfoQ
A
About on SuperTechFans
T
The Blog of Author Tim Ferriss
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - Franky

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I Rebuilt the Cmd-K Command Palette in ~60 Lines of JavaS...
Devanshu Biswas · 2026-06-17 · via DEV Community

Devanshu Biswas

Every great app has it now: hit ⌘K, a palette pops up, you fuzzy-type a few letters, hit Enter, done. Linear, Raycast, VS Code, GitHub. It feels like deep machinery — it's about 60 lines of vanilla JavaScript.

Try it live: https://dev48v.infy.uk/design/day10-command-palette.html

1. One global shortcut

The whole feature hinges on a single document-level listener. You MUST preventDefault — browsers bind Ctrl+K to their own search:

document.addEventListener("keydown", e => {
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
    e.preventDefault();
    openPalette();
  }
});

2. Commands are data, not buttons

Every action becomes one object. The UI is generic — it lists objects and calls run() on the chosen one:

const COMMANDS = [
  { icon: "🌙", label: "Toggle dark mode", group: "Theme", run: toggleDark },
  { icon: "📄", label: "New file",         group: "File",  run: newFile },
];

Adding a command is adding one line, never new markup.

3. Fuzzy matching feels like mind-reading

Palettes don't do substring match — they do subsequence match: the query's characters appear in order, not necessarily adjacent. So tgldk finds "Toggle dark mode":

function fuzzy(q, text) {
  let i = 0;
  for (const ch of text.toLowerCase()) if (ch === q[i]) i++;
  return i === q.length;   // all query chars found, in order
}

A tiny loop with one pointer — and it's why you can fly through commands with sloppy half-typed queries.

4. Keyboard-first navigation

The point is to never touch the mouse. Up/Down move a selection index (modulo wraparound), Enter runs, Escape closes:

if (e.key === "ArrowDown") sel = (sel + 1) % shown.length;
if (e.key === "ArrowUp")   sel = (sel - 1 + shown.length) % shown.length;
if (e.key === "Enter")     { shown[sel].run(); close(); }

5. Autofocus is the whole UX

The detail that makes it feel instant: focus the input the moment it opens, so the user types immediately — no click:

overlay.show();
input.focus();

The takeaway

Global shortcut + command data + fuzzy filter + autofocus. That's the entire command palette. Build it once and you understand the interaction pattern behind half of modern power-user tooling. Open the demo and press ⌘K.