Command
Command opens a searchable menu of actions or destinations. Group items to give related results context, and keep open and inputValue controlled by the consuming view.
import { useState } from "react";
import { Button, Command } from "density-base-ui";
import { FileText, Settings, Users } from "lucide-react";
const commandGroups = [
{
id: "workspace",
label: "Workspace",
items: [
{
id: "projects",
label: "Projects",
icon: <FileText size={16} />,
onSelect: () => {},
},
{
id: "team",
label: "Team",
icon: <Users size={16} />,
onSelect: () => {},
},
],
},
{
id: "settings",
items: [
{
id: "settings",
label: "Settings",
icon: <Settings size={16} />,
onSelect: () => {},
},
],
},
];
export default function CommandExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open command menu</Button>}
/>
);
}Groups and icons
Groups separate related items with labeled dividers. Use icon for a compact visual cue.
import { useState } from "react";
import { Button, Command } from "density-base-ui";
import { FileText, Settings, Users } from "lucide-react";
const commandGroups = [
{
id: "workspace",
label: "Workspace",
items: [
{
id: "projects",
label: "Projects",
icon: <FileText size={16} />,
onSelect: () => {},
},
{
id: "team",
label: "Team",
icon: <Users size={16} />,
onSelect: () => {},
},
],
},
{
id: "settings",
label: "Preferences",
items: [
{
id: "settings",
label: "Settings",
icon: <Settings size={16} />,
onSelect: () => {},
},
],
},
];
export default function CommandGroupsExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open grouped commands</Button>}
/>
);
}Shortcuts
import { useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "actions",
label: "Actions",
items: [
{
id: "new-report",
label: "New report",
shortcut: "⌘ N",
onSelect: () => {},
},
{
id: "open-settings",
label: "Open settings",
shortcut: "⌘ ,",
onSelect: () => {},
},
],
},
];
export default function CommandShortcutsExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open action commands</Button>}
/>
);
}Filtering and empty state
Filtering matches item labels and keywords. Try people or a query with no matches.
import { useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "workspace",
items: [
{ id: "projects", label: "Projects", onSelect: () => {} },
{ id: "team", label: "Team", keywords: ["people"], onSelect: () => {} },
],
},
];
export default function CommandFilteringExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
emptyLabel="No matching workspace action"
trigger={<Button type="button">Open workspace commands</Button>}
/>
);
}Global shortcut
Omit trigger when the consuming view owns how the palette opens, such as a global Cmd/Ctrl-K shortcut.
import { useEffect, useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "actions",
items: [{ id: "search", label: "Search", onSelect: () => {} }],
},
];
export default function CommandGlobalShortcutExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
event.preventDefault();
setOpen(true);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
return (
<>
<Button type="button" onClick={() => setOpen(true)}>
Open with ⌘ K
</Button>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
/>
</>
);
}Each CommandGroup has an id, optional label, and items. An item has id, label, required onSelect, and optional keywords, icon, shortcut, disabled, and color props.
Title
import { useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
export default function CommandTitleExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open command menu</Button>}
title="Go to"
/>
);
}Placeholder
import { useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
export default function CommandPlaceholderExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open command menu</Button>}
placeholder="Search reports"
/>
);
}Empty label
import { useState } from "react";
import { Button, Command } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
export default function CommandEmptyLabelExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">Open command menu</Button>}
emptyLabel="No matching reports"
/>
);
}Size
import { useState } from "react";
import { Button, Command, View } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
export default function CommandSizeExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<View align="center" gap="md" orientation="horizontal" padding={false} wrap>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">2xs</Button>}
size="2xs"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">xs</Button>}
size="xs"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">sm</Button>}
size="sm"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">md</Button>}
size="md"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">lg</Button>}
size="lg"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">xl</Button>}
size="xl"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">2xl</Button>}
size="2xl"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">3xl</Button>}
size="3xl"
/>
</View>
);
}Depth
import { useState } from "react";
import { Button, Command, View } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
export default function CommandDepthExample() {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<View align="center" gap="md" orientation="horizontal" padding={false} wrap>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">1</Button>}
depth="1"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">2</Button>}
depth="2"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">3</Button>}
depth="3"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">4</Button>}
depth="4"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">5</Button>}
depth="5"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">6</Button>}
depth="6"
/>
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">7</Button>}
depth="7"
/>
</View>
);
}Padding
import { useState } from "react";
import { Button, Command, View } from "density-base-ui";
const commandGroups = [
{
id: "pages",
items: [{ id: "reports", label: "Reports", onSelect: () => {} }],
},
];
type CommandPaddingPreviewProps = {
padding: boolean;
triggerLabel: string;
};
function CommandPaddingPreview({
padding,
triggerLabel,
}: CommandPaddingPreviewProps) {
const [open, setOpen] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<Command
items={commandGroups}
open={open}
onOpenChange={setOpen}
inputValue={inputValue}
onInputValueChange={setInputValue}
trigger={<Button type="button">{triggerLabel}</Button>}
padding={padding}
/>
);
}
export default function CommandPaddingExample() {
return (
<View align="center" gap="md" orientation="horizontal" padding={false} wrap>
<CommandPaddingPreview padding={false} triggerLabel="None" />
<CommandPaddingPreview padding triggerLabel="Padding enabled" />
</View>
);
}| Prop | Values | Required | Default | Behavior | Description |
|---|---|---|---|---|---|
depth | 1, 2, 3, 4, 5, 6, 7 | Not required | "1" | Attribute: data-dn-depth | — |
emptyLabel | React.ReactNode | Not required | "No results found." | — | — |
inputValue | string | Required | — | — | — |
items | CommandGroup[] | Required | — | — | — |
onInputValueChange | (value: string) => void | Required | — | — | — |
onOpenChange | (open: boolean) => void | Required | — | — | — |
open | false, true | Required | — | — | — |
padding | false, true | Not required | true | Attribute: data-dn-padding | — |
placeholder | string | Not required | "Type a command or search…" | — | — |
size | 2xs, xs, sm, md, lg, xl, 2xl, 3xl | Not required | — | Attribute: data-dn-size | — |
title | React.ReactNode | Not required | "Command palette" | — | — |
trigger | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Not required | — | — | — |