Open donovan-fintool opened 3 weeks ago
I had a similar situation where I wanted to perform a different action depending if an item was selected with "Enter". After looking at the implementation, I ended up with this solution:
<Command
onKeyDown={(e) => {
// You can also add another condition if (e.key === 'Enter' && e.metaKey) to tackle cmd + enter
if (e.key === 'Enter') {
// Prevents "onSelect" from being called"
e.preventDefault();
// item that is currently on focused (selected) either by mouse hover or keyboard navigation
const item = getSelectedItem(listInnerRef);
// you can do
if (item) {
// this will dispatch an event that the cmdk library will listen to (then onSelect) will be executed
const event = new Event(SELECT_EVENT);
item.dispatchEvent(event);
}
}
}}
>
Then your utility functions
export const ITEM_SELECTOR = `[cmdk-item=""]`;
export const SELECT_EVENT = `cmdk-item-select`;
export function getSelectedItem(listInnerRef: React.RefObject<HTMLDivElement>) {
return listInnerRef.current?.querySelector(`${ITEM_SELECTOR}[aria-selected="true"]`);
}
listInnerRef
is a reference to your list/group of items.
I had a similar situation where I wanted to perform a different action depending if an item was selected with "Enter". After looking at the implementation, I ended up with this solution:
<Command onKeyDown={(e) => { // You can also add another condition if (e.key === 'Enter' && e.metaKey) to tackle cmd + enter if (e.key === 'Enter') { // Prevents "onSelect" from being called" e.preventDefault(); // item that is currently on focused (selected) either by mouse hover or keyboard navigation const item = getSelectedItem(listInnerRef); // you can do if (item) { // this will dispatch an event that the cmdk library will listen to (then onSelect) will be executed const event = new Event(SELECT_EVENT); item.dispatchEvent(event); } } }} >
Then your utility functions
export const ITEM_SELECTOR = `[cmdk-item=""]`; export const SELECT_EVENT = `cmdk-item-select`; export function getSelectedItem(listInnerRef: React.RefObject<HTMLDivElement>) { return listInnerRef.current?.querySelector(`${ITEM_SELECTOR}[aria-selected="true"]`); }
listInnerRef
is a reference to your list/group of items.
Amazing, that's much cleaner than my method. Thanks!
I have a use case where I want to perform different actions on
enter
and oncmd+enter
. In my use case, I'm using cmdk as a multi select, so users can check / uncheck each item in the list, then hitcmd+enter
to submit their selections.onSelect
triggers on both onenter
and oncmd+enter
, which causes issues for me. My workaround is to create a different React state that tracks if the cmd key is currently being pressed, which is kind of hacky and a lot of boilerplate.My question is - is there a better way of doing it? If not, could we pass an
event
to onSelect so I can handle it myself?Thanks!