DesignX
IDE@paxeer/ide/command-paletteimplemented

Command palette

shadcn Command + Dialog overlay with grouped results.

Install

$pnpm exec designx add @paxeer/ide/command-palette

Preview

Loading preview...

Source code

components/designx/ide/command-palette.tsxtsx
"use client";

import { useMemo, useState } from "react";
import {
  Button,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandShortcut,
} from "@paxeer/core";

export interface CommandPaletteItem {
  id: string;
  label: string;
  group: string;
  hint?: string;
}

export interface CommandPaletteProps {
  items: CommandPaletteItem[];
  onSelect?: (item: CommandPaletteItem) => void;
  triggerLabel?: string;
}

export function CommandPalette({
  items,
  onSelect,
  triggerLabel = "Command palette",
}: CommandPaletteProps) {
  const [open, setOpen] = useState(false);

  const groups = useMemo(() => {
    const map = new Map<string, CommandPaletteItem[]>();
    for (const item of items) {
      const list = map.get(item.group) ?? [];
      list.push(item);
      map.set(item.group, list);
    }
    return [...map.entries()];
  }, [items]);

  return (
    <>
      <Button variant="tonal" size="dense" onClick={() => setOpen(true)}>
        {triggerLabel}
      </Button>
      <CommandDialog open={open} onOpenChange={setOpen} title="Command palette">
        <CommandInput placeholder="Type a command or file" />
        <CommandList>
          <CommandEmpty>No matches.</CommandEmpty>
          {groups.map(([group, groupItems]) => (
            <CommandGroup key={group} heading={group}>
              {groupItems.map((item) => (
                <CommandItem
                  key={item.id}
                  value={`${item.group} ${item.label}`}
                  onSelect={() => {
                    onSelect?.(item);
                    setOpen(false);
                  }}
                >
                  {item.label}
                  {item.hint ? <CommandShortcut>{item.hint}</CommandShortcut> : null}
                </CommandItem>
              ))}
            </CommandGroup>
          ))}
        </CommandList>
      </CommandDialog>
    </>
  );
}

Dependencies