Closed bizmich closed 3 months ago
@bizmich @IlirEdis have you tried the keywords feature? 🤔
<Command.Item keywords={['fruit', 'apple']}>Apple</Command.Item>
If not you can always write custom logic for filtering/searching
import { matchSorter } from 'match-sorter';
export function useMatchByLabelAndValue(data, query) {
return useMemo(
() => matchSorter(data, query, { keys: ['label', 'value'] }),
[data, query],
);
}
function CustomCmdk({ data }) {
const [searchQuery, setSearchQuery] = useState('');
const matches = useMatchByLabelAndValue(data, searchQuery);
return (
<Command shouldFilter={false}>
<CommandInput
value={searchQuery}
onValueChange={(value) =>
startTransition(() => setSearchQuery(value))
}
/>
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
{matches.map((item) => (
<CommandItem
key={item.value}
onSelect={() => {
startTransition(() => setSearchQuery(''));
}}
>
<span>
{item.label} {item.value}
</span>
</CommandItem>
))}
</CommandList>
</Command>
)}
Use the custom filter option and combine value
and label
as value for the CommandItem(s).
<Command
filter={(value, search) => {
if (value.includes(search)) return 1;
return 0;
}}
>
<CommandItem value={`${option.value} ${option.label}`}>
https://github.com/pacocoursey/cmdk/tree/v1.0.0?tab=readme-ov-file#parts-and-styling
I also noticed that if you don't provide a value
prop it uses the "label" from inside the <CommandItem>
tag.
Also @najdic & @shomyx thanks a lot for these valuable informations! Its my second time using cmdk and i will use these to make searching experience better.
@bizmich @IlirEdis have you tried the keywords feature? 🤔
<Command.Item keywords={['fruit', 'apple']}>Apple</Command.Item>
If not you can always write custom logic for filtering/searching
import { matchSorter } from 'match-sorter'; export function useMatchByLabelAndValue(data, query) { return useMemo( () => matchSorter(data, query, { keys: ['label', 'value'] }), [data, query], ); } function CustomCmdk({ data }) { const [searchQuery, setSearchQuery] = useState(''); const matches = useMatchByLabelAndValue(data, searchQuery); return ( <Command shouldFilter={false}> <CommandInput value={searchQuery} onValueChange={(value) => startTransition(() => setSearchQuery(value)) } /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> {matches.map((item) => ( <CommandItem key={item.value} onSelect={() => { startTransition(() => setSearchQuery('')); }} > <span> {item.label} {item.value} </span> </CommandItem> ))} </CommandList> </Command> )}
Doesn't it seem illogical to have a filter based on a value that the user cannot see? What's the purpose behind this design?
Use the custom filter option and combine
value
andlabel
as value for the CommandItem(s).<Command filter={(value, search) => { if (value.includes(search)) return 1; return 0; }} >
<CommandItem value={`${option.value} ${option.label}`}>
https://github.com/pacocoursey/cmdk/tree/v1.0.0?tab=readme-ov-file#parts-and-styling
After combining label and value, I get both results. This makes me filter the output again. Is there a more efficient way to do this?
need this also!