pacocoursey / cmdk

Fast, unstyled command menu React component.
https://cmdk.paco.me
MIT License
9.68k stars 279 forks source link

Custom keywords in filter #146

Closed honzatmn closed 8 months ago

honzatmn commented 1 year ago

Hey, thanks for a great library, it is such a time saver for us.

We'd like to filter also by synonyms (and additional keywords), not just by a value. One way to solve this would be to completely take over the filtering and write our own filter function, but I imagine that this could be something useful also to others (e.g. showing "Remove" item when "delete" or "trash" words are searched.

I'd imagine some additional property keywords: string[] on Command.Item and the search would take those into consideration too.

<Command.Item keywords={"delete", "trash"}>Remove item</Command.Item>
<Command.Item keywords={"add", "new"}>Create item</Command.Item>

Thanks for consideration and all your great work on cmdk library.

joaom00 commented 1 year ago

You can already do this

<Command.Item value="delete trash">Remove item</Command.Item>
<Command.Item value="add new">Create item</Command.Item>
honzatmn commented 1 year ago

@joaom00 While it seems to work, it feels wrong to assign this to value, especially because value is used also for assigning aria-selected/data-selected attribute for keyboard navigation. So we need to have it unique so matching works flawlessly.

So in our case, we'd like to use a different prop for filtering if possible (hence the keywords or filterKeywords prop).

I proposed it here since it feels like it could be a common use case (I might be wrong though).

andrewdoro commented 1 year ago

I also think the keywords prop approach should be implemented. In my example I am using a list of categories and I am only selecting their values by their id. I am also using i18n for translation and I only want the translation value to be searchable.

const categories = [1,2,3];
...

const { t } = useTranslation();
const searchValues = getTranslationById(t, props.value);

<MultiSelectItemWrapper
      {...props}
      value={`${props.value} ${searchValue}`}
      onSelect={() => toggleValue(props.value)}
    >
pacocoursey commented 1 year ago

I'm in favor of adding the keywords prop that is not returned from onSelect but influences the sorting and filtering logic.

joaom00 commented 1 year ago

I think it will be confusing to have two props that do almost the same thing. Or would it be worth making the value behave like an id and addressing https://github.com/pacocoursey/cmdk/issues/150?

itaikeren commented 1 year ago

@pacocoursey @honzatmn I opened a PR adding this prop #158