Command menu refactoring (#9257)
Refactored the `CommandMenu` component to make it more readable and easier to refactor. The file was way too big so I introduced a few hooks and eliminated code duplication. Introduced: - `useMatchCommands` hook to match commands with the search - `useCommandMenuCommands` which returns all command menu commands - `useMatchingCommandMenuCommands` to return the commands matched with the search - `CommandMenuContainer` to simplify the `DefaultLayout` - Unmounted the `CommandMenu` when it wasn't opened to improve performances I also introduced a new behavior: Automatically select the first item when opening the command menu: https://github.com/user-attachments/assets/4b683d49-570e-47c9-8939-99f42ed8691c
This commit is contained in:
@ -0,0 +1,37 @@
|
||||
import { Command } from '@/command-menu/types/Command';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
|
||||
export const useMatchCommands = ({
|
||||
commandMenuSearch,
|
||||
}: {
|
||||
commandMenuSearch: string;
|
||||
}) => {
|
||||
const [deferredCommandMenuSearch] = useDebounce(commandMenuSearch, 300); // 200ms - 500ms
|
||||
|
||||
const checkInShortcuts = (cmd: Command, search: string) => {
|
||||
return (cmd.firstHotKey + (cmd.secondHotKey ?? ''))
|
||||
.toLowerCase()
|
||||
.includes(search.toLowerCase());
|
||||
};
|
||||
|
||||
const checkInLabels = (cmd: Command, search: string) => {
|
||||
if (isNonEmptyString(cmd.label)) {
|
||||
return cmd.label.toLowerCase().includes(search.toLowerCase());
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const matchCommands = (commands: Command[]) => {
|
||||
return commands.filter((cmd) =>
|
||||
deferredCommandMenuSearch.length > 0
|
||||
? checkInShortcuts(cmd, deferredCommandMenuSearch) ||
|
||||
checkInLabels(cmd, deferredCommandMenuSearch)
|
||||
: true,
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
matchCommands,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user