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