1ab51d41aa
# Replace hotkey scopes by focus stack (Part 2 - Record Table, Rows and Cells) This PR is the second part of a refactoring aiming to deprecate the hotkey scopes api in favor of the new focus stack api which is more robust. Part 1: https://github.com/twentyhq/twenty/pull/12673 The record table shortcuts are no longer centralized in the record table, they now split and the focused element is in charge of applying the desired shortcuts. (For instance: The rows are in charge of the row navigation and the cells of the cells navigation). ## Video QA: https://github.com/user-attachments/assets/f0bb9eed-8a2a-4b6d-a82f-1998e929f122 ## Bugfixes: ### Fix record table click outside not working after opening and closing a cell Introduced by https://github.com/twentyhq/twenty/pull/11644 #### Before https://github.com/user-attachments/assets/d28deda8-15e9-4ffe-b60a-e8b54625f8e5 #### After https://github.com/user-attachments/assets/3f7e1ffc-15d9-4336-aeb0-bebd8ae0cbe0 ### Fix ObjectFilterDropdownFilterInput hotkeys Introduced by https://github.com/twentyhq/twenty/pull/12673 #### Before https://github.com/user-attachments/assets/ab2039bd-ebe1-49ba-8377-a6b300664469 #### After https://github.com/user-attachments/assets/90597453-dab2-426b-a134-0a24b0de0a6b
99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
import { useRecoilCallback, useRecoilState } from 'recoil';
|
|
|
|
import { useDropdownStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownStates';
|
|
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
|
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
|
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
|
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
|
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
|
import { useCallback } from 'react';
|
|
|
|
export const useDropdown = (dropdownId?: string) => {
|
|
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
|
const { removeFocusItemFromFocusStackById } =
|
|
useRemoveFocusItemFromFocusStackById();
|
|
|
|
const { scopeId, isDropdownOpenState, dropdownPlacementState } =
|
|
useDropdownStates({ dropdownScopeId: dropdownId });
|
|
|
|
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
|
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
|
|
|
const { goBackToPreviousDropdownFocusId } =
|
|
useGoBackToPreviousDropdownFocusId();
|
|
|
|
const [isDropdownOpen, setIsDropdownOpen] =
|
|
useRecoilState(isDropdownOpenState);
|
|
|
|
const [dropdownPlacement, setDropdownPlacement] = useRecoilState(
|
|
dropdownPlacementState,
|
|
);
|
|
|
|
const closeDropdown = useCallback(() => {
|
|
if (isDropdownOpen) {
|
|
setIsDropdownOpen(false);
|
|
goBackToPreviousDropdownFocusId();
|
|
removeFocusItemFromFocusStackById({
|
|
focusId: dropdownId ?? scopeId,
|
|
});
|
|
}
|
|
}, [
|
|
isDropdownOpen,
|
|
setIsDropdownOpen,
|
|
goBackToPreviousDropdownFocusId,
|
|
removeFocusItemFromFocusStackById,
|
|
dropdownId,
|
|
scopeId,
|
|
]);
|
|
|
|
const openDropdown = useRecoilCallback(
|
|
() => (globalHotkeysConfig?: Partial<GlobalHotkeysConfig>) => {
|
|
if (!isDropdownOpen) {
|
|
setIsDropdownOpen(true);
|
|
setActiveDropdownFocusIdAndMemorizePrevious(dropdownId ?? scopeId);
|
|
|
|
pushFocusItemToFocusStack({
|
|
focusId: dropdownId ?? scopeId,
|
|
component: {
|
|
type: FocusComponentType.DROPDOWN,
|
|
instanceId: dropdownId ?? scopeId,
|
|
},
|
|
globalHotkeysConfig,
|
|
// TODO: Remove this once we've fully migrated away from hotkey scopes
|
|
hotkeyScope: { scope: 'dropdown' } as HotkeyScope,
|
|
});
|
|
}
|
|
},
|
|
[
|
|
isDropdownOpen,
|
|
setIsDropdownOpen,
|
|
setActiveDropdownFocusIdAndMemorizePrevious,
|
|
pushFocusItemToFocusStack,
|
|
dropdownId,
|
|
scopeId,
|
|
],
|
|
);
|
|
|
|
const toggleDropdown = (
|
|
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>,
|
|
) => {
|
|
if (isDropdownOpen) {
|
|
closeDropdown();
|
|
} else {
|
|
openDropdown(globalHotkeysConfig);
|
|
}
|
|
};
|
|
|
|
return {
|
|
scopeId,
|
|
isDropdownOpen,
|
|
closeDropdown,
|
|
toggleDropdown,
|
|
openDropdown,
|
|
dropdownPlacement,
|
|
setDropdownPlacement,
|
|
};
|
|
};
|