The Command component from pol-ui is a component that provides a way to navigate through a list of items using the keyboard. It is a combination of a list and an input, where the input is used to filter the list of items.
import { Command } from "pol-ui";
Default Command
Default
import { Modal, Command, useBoolean } from "pol-ui";
import React from "react";
export const CommandMenu = () => {
const { value, toggle } = useBoolean(false);
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
toggle();
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
return (
<>
<p className="text-sm text-muted-foreground">
Press{" "}
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
<span className="text-xs">⌘</span>J
</kbd>
</p>
<Modal
open={value}
onOpenChange={toggle}
contentClassName="p-0 bg-secondary-100 shadow-lg "
>
<Command>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item onSelect={() => toast({ title: "Calendar" })}>
Calendar
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Emoji" })}>
Search Emoji
</Command.Item>
<Command.Item onSelect={() => toast({ title: "calculator" })}>
Calculator
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item
value="profile"
onSelect={() => toast({ title: "Profile" })}
className="flex gap-2 items-center"
>
<TbUser />
Profile
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Billing" })}>
Billing
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Settings" })}>
Settings
</Command.Item>
</Command.Group>
</Command.List>
</Command>
</Modal>
<Button onClick={toggle}>Open Command</Button>
</>
);
};
Props
The Command component has the following props:
Prop name | Type | Default | Description |
---|---|---|---|
label | string | Accessible label for this command menu. Not shown visibly. | |
shouldFilter | boolean | true | Optionally set to false to turn off the automatic filtering and sorting. If false, you must conditionally render valid items based on the search query yourself. |
filter | (value, search, keywords) => number | Custom filter function for whether each command menu item should matches the given search query. It should return a number between 0 and 1. | |
defaultValue | string | Optional default item value when it is initially rendered. | |
value | string | Optional controlled state of the selected command menu item. | |
onValueChange | (value: string) => void | Event handler called when the selected item of the menu changes. | |
loop | boolean | Optionally set to true to turn on looping around when using the arrow keys. | |
disablePointerSelection | boolean | Optionally set to true to disable selection via pointer events. | |
vimBindings | boolean | true | Set to false to disable ctrl+n/j/p/k shortcuts. Defaults to true. |
theme | CommandTheme | Theme for the command component. | |
children | React.ReactNode | The children of the command component. |
💡
You can also provide any prop comming from the HTML div tag
Examples
Inline variation
Inline variation
import { Command } from "pol-ui";
import React from "react";
export const CommandMenu = () => {
return (
<Command
label="Command Menu"
className="bg-white rounded-xl p-2 shadow-xl flex justify-center max-w-[500px]"
>
<Command.Input />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Letters">
<Command.Item>a</Command.Item>
<Command.Item>b</Command.Item>
<Command.Separator />
<Command.Item>c</Command.Item>
</Command.Group>
<Command.Item>Apple</Command.Item>
</Command.List>
</Command>
);
};
Dark Mode Support
Dark Mode Support
import { Command, useBoolean, Modal, toast, Kbd } from "pol-ui";
import React from "react";
export const DarkMode = () => {
const { value, toggle } = useBoolean(false);
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
toggle();
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
return (
<section className="dark bg-secondary-900 w-full min-h-[400px] gap-4 flex flex-col justify-center items-center text-white">
<p className="text-sm">
Press <Kbd>⌘J</Kbd>
</p>
<Modal
open={value}
onOpenChange={toggle}
contentClassName="p-0 dark bg-secondary-800 border border-secondary-800 shadow-lg "
>
<Command>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item onSelect={() => toast({ title: "Calendar" })}>
Calendar
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Emoji" })}>
Search Emoji
</Command.Item>
<Command.Item onSelect={() => toast({ title: "calculator" })}>
Calculator
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item
value="profile"
onSelect={() => toast({ title: "Profile" })}
className="flex gap-2 items-center"
>
<TbUser />
Profile
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Billing" })}>
Billing
</Command.Item>
<Command.Item onSelect={() => toast({ title: "Settings" })}>
Settings
</Command.Item>
</Command.Group>
</Command.List>
</Command>
</Modal>
<Button onClick={toggle}>Open Command</Button>
</section>
);
};
Theme
To learn more about how to customize the appearance of components, please see the Theme docs.
interface CommandTheme {
root: {
base: string;
};
empty: {
base: string;
};
group: {
base: string;
header: string;
};
list: {
base: string;
};
input: {
base: string;
icon: string;
input: string;
};
separator: {
base: string;
};
}