IDE@paxeer/ide/command-paletteimplemented
Command palette
shadcn Command + Dialog overlay with grouped results.
Install
$
pnpm exec designx add @paxeer/ide/command-palettePreview
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
Registry dependencies