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:
Raphaël Bosi
2024-12-30 15:22:49 +01:00
committed by GitHub
parent 0fa59d7718
commit 1091bc657d
24 changed files with 827 additions and 980 deletions

View File

@ -0,0 +1,54 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';
export const useCommandMenuHotKeys = () => {
const { closeCommandMenu } = useCommandMenu();
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
const setContextStoreTargetedRecordsRule = useSetRecoilComponentStateV2(
contextStoreTargetedRecordsRuleComponentState,
'command-menu',
);
const setContextStoreNumberOfSelectedRecords = useSetRecoilComponentStateV2(
contextStoreNumberOfSelectedRecordsComponentState,
'command-menu',
);
useScopedHotkeys(
[Key.Escape],
() => {
closeCommandMenu();
},
AppHotkeyScope.CommandMenuOpen,
[closeCommandMenu],
);
useScopedHotkeys(
[Key.Backspace, Key.Delete],
() => {
if (!isNonEmptyString(commandMenuSearch)) {
setContextStoreTargetedRecordsRule({
mode: 'selection',
selectedRecordIds: [],
});
setContextStoreNumberOfSelectedRecords(0);
}
},
AppHotkeyScope.CommandMenuOpen,
[closeCommandMenu],
{
preventDefault: false,
},
);
};