"use client"; import { Command } from "cmdk"; import { useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { contact } from "@/lib/portfolio"; type PaletteAction = | { kind: "scroll"; targetId: "work" | "capabilities" | "operator" | "contact" } | { kind: "route"; href: "/blog/" } | { kind: "copy-email" } | { kind: "external"; href: string }; const commands: { label: string; hint: string; keywords: string[]; action: PaletteAction; }[] = [ { label: "Go to Work", hint: "#work", keywords: ["projects", "dossiers", "selected work"], action: { kind: "scroll", targetId: "work" }, }, { label: "Go to Capabilities", hint: "#capabilities", keywords: ["skills", "systems", "kernel"], action: { kind: "scroll", targetId: "capabilities" }, }, { label: "Go to Operator", hint: "#operator", keywords: ["profile", "identity", "honors"], action: { kind: "scroll", targetId: "operator" }, }, { label: "Go to Contact", hint: "#contact", keywords: ["email", "signal"], action: { kind: "scroll", targetId: "contact" }, }, { label: "Open Field Notes", hint: "/blog/", keywords: ["blog", "notes", "archive"], action: { kind: "route", href: "/blog/" }, }, { label: "Copy Email", hint: "copy", keywords: [contact.email, "mail", "contact"], action: { kind: "copy-email" }, }, { label: "Open Git profile", hint: "git", keywords: ["source", "forge", "code"], action: { kind: "external", href: contact.git }, }, { label: "Open LinkedIn", hint: "in", keywords: ["profile", "social", "linkedin"], action: { kind: "external", href: contact.linkedIn }, }, ]; export function CommandPalette() { const router = useRouter(); const [open, setOpen] = useState(false); const [pendingAction, setPendingAction] = useState(null); const lastFocusedElement = useRef(null); const wasOpen = useRef(false); useEffect(() => { function rememberFocus() { lastFocusedElement.current = document.activeElement instanceof HTMLElement ? document.activeElement : null; } function onKeyDown(event: KeyboardEvent) { if (event.key.toLowerCase() !== "k" || (!event.metaKey && !event.ctrlKey)) { return; } event.preventDefault(); rememberFocus(); setOpen((current) => !current); } function onPaletteEvent() { rememberFocus(); setOpen(true); } window.addEventListener("keydown", onKeyDown); window.addEventListener("blacksite:palette", onPaletteEvent); return () => { window.removeEventListener("keydown", onKeyDown); window.removeEventListener("blacksite:palette", onPaletteEvent); }; }, []); useEffect(() => { if (wasOpen.current && !open) { lastFocusedElement.current?.focus(); } wasOpen.current = open; }, [open]); useEffect(() => { if (!pendingAction) { return; } let cancelled = false; async function runAction(action: PaletteAction) { if (action.kind === "scroll") { document.getElementById(action.targetId)?.scrollIntoView({ block: "start" }); } if (action.kind === "route") { router.push(action.href); } if (action.kind === "copy-email") { try { await navigator.clipboard.writeText(contact.email); } catch { // Clipboard failures should not strand the command dialog open. } } if (action.kind === "external") { window.open(action.href, "_blank", "noopener"); } if (!cancelled) { setOpen(false); setPendingAction(null); } } void runAction(pendingAction); return () => { cancelled = true; }; }, [pendingAction, router]); return (

COMMAND PALETTE

No matching command. {commands.map((command) => ( setPendingAction(command.action)} className="group flex cursor-pointer select-none items-center justify-between gap-4 rounded-md border border-transparent px-3 py-3 font-mono text-sm text-blacksite-text outline-none transition-colors data-[selected=true]:border-signal-cyan/60 data-[selected=true]:bg-signal-cyan/12 data-[selected=true]:text-signal-cyan data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50" > {command.label} {command.hint} ))}
↑↓ select Enter run · Esc close
); }