import { ui } from "@rezi-ui/core";
type Command = {
id: string;
label: string;
description: string;
shortcut?: string;
action: () => void;
};
type State = {
showPalette: boolean;
paletteQuery: string;
};
const commands: Command[] = [
{
id: "save",
label: "Save",
description: "Save current document",
shortcut: "Ctrl+S",
action: () => console.log("Save"),
},
{
id: "settings",
label: "Open Settings",
description: "Open application settings",
shortcut: "Ctrl+,",
action: () => console.log("Settings"),
},
{
id: "quit",
label: "Quit",
description: "Exit application",
shortcut: "Ctrl+Q",
action: () => app.stop(),
},
];
function filterCommands(commands: Command[], query: string): Command[] {
if (!query) return commands;
const lower = query.toLowerCase();
return commands.filter(
(cmd) =>
cmd.label.toLowerCase().includes(lower) ||
cmd.description.toLowerCase().includes(lower) ||
cmd.shortcut?.toLowerCase().includes(lower)
);
}
const app = createNodeApp<State>({
initialState: { showPalette: false, paletteQuery: "" },
});
app.view((state) => {
const filtered = filterCommands(commands, state.paletteQuery);
return ui.layers([
ui.page({ p: 1 }, [
ui.panel("Application", [
ui.text("Press Ctrl+P to open command palette"),
]),
]),
state.showPalette &&
ui.commandPalette({
id: "palette",
query: state.paletteQuery,
items: filtered.map((cmd) => ({
id: cmd.id,
label: cmd.label,
description: cmd.description,
shortcut: cmd.shortcut,
onSelect: () => {
cmd.action();
app.update((s) => ({ ...s, showPalette: false, paletteQuery: "" }));
},
})),
onQueryChange: (query) =>
app.update((s) => ({ ...s, paletteQuery: query })),
onClose: () =>
app.update((s) => ({ ...s, showPalette: false, paletteQuery: "" })),
placeholder: "Type a command...",
}),
]);
});
app.keys({
"ctrl+p": {
handler: (ctx) => ctx.update((s) => ({ ...s, showPalette: true })),
description: "Open command palette",
},
});
await app.start();