cmdk
cmdk copied to clipboard
Idea: `shouldFilter` per `Group`/`Item`
I have some items which I'm fetching from TypeSense and don't need filtering. Others are statically-defined. It would be useful to define shouldFilter
at the Item/Group level, rather than only the parent. I believe cmdk is built in a way where this would be possible, but I haven't peaked at the source in a while, so I'm not totally sure. Figured I'd mention it!
@nandorojo One way around this I found, is to use the searchFilter
prop and assign something common to the <Command.Group>
value
prop to ensure that these items dont get filtered like so:
<Command
filter={(value, search) => {
if (value.includes(search) || value.includes("doNotFilter-")) return 1; // ensures items arent filtered
return 0;
}}
>
<Command.Group>
{unfilteredItem.map((item) => (
<Command.Item value={`doNotFilter-${item.name}`} />
)}
</Command.Group>
<Command.Group>
{filtered.map((item) => (
<Command.Item value={item.name} />
)}
</Command.Group>
</Command>
I've also ran into a very similar use case to you, where my command consists of static data, such as links to pages, but also has dynamic data which has been fetching and searched via an API.
For example:
const Page = () => {
const [searchTerm, setSearchTerm] = React.useState<string>('');
const { data: itemsA } = useSearchItemsA({
query: {
search: searchTerm,
},
enabled: !!searchTerm,
});
const { data: itemsB } = useSearchItemsB({
query: {
search: searchTerm,
},
enabled: !!searchTerm,
});
return (
<div>
<Command>
<Command.Input placeholder="Search…" onValueChange={setSearchTerm} />
<Command.List>
<Command.Empty>No results.</Command.Empty>
<Command.Group heading="Links">
<Command.Item>Link A</Command.Item>
<Command.Item>Link B</Command.Item>
<Command.Item>Link C</Command.Item>
</Command.Group>
{/* This data has already been filtered by an external source, do not apply additional filtering */}
<Command.Group heading="Items A">
{itemsA.map((item) => (
<Command.Item key={item.id}>{item.name}</Command.Item>
))}
</Command.Group>
{/* This data has already been filtered by an external source, do not apply additional filtering */}
<Command.Group heading="Items B">
{itemsB.map((item) => (
<Command.Item key={item.id}>{item.name}</Command.Item>
))}
</Command.Group>
</Command.List>
</Command>
</div>
);
};
I've opened a PR, which adds shouldFilter
to the Command.Item
component so these items can be skipped during any filtering.