ผมสร้าง Command Palette แบบ Cmd-K ขึ้นมาใหม่ด้วยโค้ดเพียง 60 บรรทัด

แอปอย่าง Linear, Raycast และ VS Code ใช้ command palette คุณแค่กด ⌘K พิมพ์ตัวอักษรไม่กี่ตัว แล้วกด Enter มันดูเหมือนจะซับซ้อน แต่จริงๆ แล้วใช้ JavaScript เพียง 60 บรรทัดเท่านั้น

นี่คือวิธีที่คุณสร้างมันขึ้นมา:

  1. ตัวดักจับคีย์บอร์ด (The Keyboard Listener) คุณต้องมี global listener เนื่องจากเบราว์เซอร์ใช้ Ctrl+K สำหรับการค้นหา คุณจึงต้องใช้ preventDefault เพื่อหยุดการทำงานนั้น
document.addEventListener("keydown", e => {
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
    e.preventDefault();
    openPalette();
  }
});
  1. ข้อมูลคำสั่ง (Command Data) เก็บทุกการกระทำไว้ในรูปแบบ object วิธีนี้จะทำให้ UI เรียบง่าย โดยจะแสดงรายการ object เหล่านี้และรันฟังก์ชันที่คุณเลือก การเพิ่มฟีเจอร์ใหม่ก็แค่เพิ่มโค้ดเพียงบรรทัดเดียวลงในรายการของคุณ
const COMMANDS = [
  { icon: "🌙", label: "Toggle dark mode", group: "Theme", run: toggleDark },
  { icon: "📄", label: "New file",         group: "File",  run: newFile },
];
  1. การค้นหาแบบ Fuzzy (Fuzzy Search) Command palette ที่ดีจะใช้การจับคู่แบบ subsequence หมายความว่าตัวอักษรต้องปรากฏตามลำดับ แต่ไม่จำเป็นต้องอยู่ติดกัน เช่น การพิมพ์ "tgldk" ควรจะค้นหา "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;
}
  1. การควบคุมด้วยคีย์บอร์ด (Keyboard Navigation) เป้าหมายคือการเลิกใช้เมาส์ ใช้ปุ่มลูกศร (Arrow keys) เพื่อเปลี่ยนลำดับการเลือก ใช้ Enter เพื่อรันคำสั่ง และใช้ Escape เพื่อปิดเมนู

  2. ความรู้สึกที่รวดเร็วทันใจ (The Instant Feel) ให้โฟกัสที่ช่อง input ทันทีที่ palette เปิดขึ้น วิธีนี้จะช่วยให้คุณพิมพ์ได้เลยโดยไม่ต้องคลิก

Command palette ต้องการ 4 สิ่งนี้:

ลองสร้างสิ่งนี้ดูสักครั้ง เพื่อทำความเข้าใจว่าเครื่องมือสำหรับ power-user สมัยใหม่ทำงานอย่างไร

ลองเล่นแบบ Live: https://dev48v.infy.uk/design/day10-command-palette.html

ที่มา: https://dev.to/dev48v/i-rebuilt-the-cmd-k-command-palette-in-60-lines-of-javascript-3a1l