Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes 🫳🎤) (#13127)
# Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes) This PR is the last 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 Part 2: https://github.com/twentyhq/twenty/pull/12798 Part 3: https://github.com/twentyhq/twenty/pull/12910 Part 4: https://github.com/twentyhq/twenty/pull/12933 Part 5: https://github.com/twentyhq/twenty/pull/13106 In this part, we completely remove the hotkey scopes.
This commit is contained in:
@@ -11,7 +11,6 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
|
||||
import { useRef } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { DialogHotkeyScope } from '../types/DialogHotkeyScope';
|
||||
|
||||
const StyledDialogOverlay = styled(motion.div)`
|
||||
align-items: center;
|
||||
@@ -116,7 +115,6 @@ export const Dialog = ({
|
||||
keys: [Key.Enter],
|
||||
callback: handleEnter,
|
||||
focusId: DIALOG_FOCUS_ID,
|
||||
scope: DialogHotkeyScope.Dialog,
|
||||
dependencies: [buttons],
|
||||
});
|
||||
|
||||
@@ -124,7 +122,6 @@ export const Dialog = ({
|
||||
keys: [Key.Escape],
|
||||
callback: handleEscape,
|
||||
focusId: DIALOG_FOCUS_ID,
|
||||
scope: DialogHotkeyScope.Dialog,
|
||||
dependencies: [handleEscape],
|
||||
});
|
||||
|
||||
|
||||
-6
@@ -1,8 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { DIALOG_FOCUS_ID } from '@/ui/feedback/dialog-manager/constants/DialogFocusId';
|
||||
import { DIALOG_MANAGER_HOTKEY_SCOPE_MEMOIZE_KEY } from '@/ui/feedback/dialog-manager/constants/DialogManagerHotkeyScopeMemoizeKey';
|
||||
import { DialogHotkeyScope } from '@/ui/feedback/dialog-manager/types/DialogHotkeyScope';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { useDialogManagerScopedStates } from '../hooks/internal/useDialogManagerScopedStates';
|
||||
@@ -23,10 +21,6 @@ export const DialogManagerEffect = () => {
|
||||
type: FocusComponentType.DIALOG,
|
||||
instanceId: DIALOG_FOCUS_ID,
|
||||
},
|
||||
hotkeyScope: {
|
||||
scope: DialogHotkeyScope.Dialog,
|
||||
},
|
||||
memoizeKey: DIALOG_MANAGER_HOTKEY_SCOPE_MEMOIZE_KEY,
|
||||
});
|
||||
}, [dialogInternal.queue, pushFocusItemToFocusStack]);
|
||||
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export enum DialogHotkeyScope {
|
||||
Dialog = 'dialog',
|
||||
}
|
||||
@@ -57,7 +57,6 @@ export type AddressInputProps = {
|
||||
event: MouseEvent | TouchEvent,
|
||||
newAddress: FieldAddressDraftValue,
|
||||
) => void;
|
||||
hotkeyScope: string;
|
||||
clearable?: boolean;
|
||||
onChange?: (updatedValue: FieldAddressDraftValue) => void;
|
||||
};
|
||||
@@ -65,7 +64,6 @@ export type AddressInputProps = {
|
||||
export const AddressInput = ({
|
||||
instanceId,
|
||||
value,
|
||||
hotkeyScope,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
onEnter,
|
||||
@@ -154,7 +152,6 @@ export const AddressInput = ({
|
||||
useHotkeysOnFocusedElement({
|
||||
keys: ['tab'],
|
||||
callback: handleTab,
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [handleTab],
|
||||
});
|
||||
@@ -162,7 +159,6 @@ export const AddressInput = ({
|
||||
useHotkeysOnFocusedElement({
|
||||
keys: ['shift+tab'],
|
||||
callback: handleShiftTab,
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [handleShiftTab],
|
||||
});
|
||||
@@ -172,7 +168,6 @@ export const AddressInput = ({
|
||||
callback: () => {
|
||||
onEnter(internalValue);
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [onEnter, internalValue],
|
||||
});
|
||||
@@ -182,7 +177,6 @@ export const AddressInput = ({
|
||||
callback: () => {
|
||||
onEscape(internalValue);
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [onEscape, internalValue],
|
||||
});
|
||||
|
||||
@@ -49,7 +49,6 @@ export type CurrencyInputProps = {
|
||||
onClickOutside: (event: MouseEvent | TouchEvent, inputValue: string) => void;
|
||||
onChange?: (newText: string) => void;
|
||||
onSelect?: (newText: string) => void;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
export const CurrencyInput = ({
|
||||
@@ -65,7 +64,6 @@ export const CurrencyInput = ({
|
||||
onClickOutside,
|
||||
onChange,
|
||||
onSelect,
|
||||
hotkeyScope,
|
||||
}: CurrencyInputProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -91,7 +89,6 @@ export const CurrencyInput = ({
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
hotkeyScope,
|
||||
});
|
||||
|
||||
const currency = CURRENCIES.find(({ value }) => value === currencyCode);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import { useRegisterInputEvents } from '@/object-record/record-field/meta-types/input/hooks/useRegisterInputEvents';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import {
|
||||
DateTimePicker,
|
||||
MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
|
||||
MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
|
||||
} from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { Nullable } from 'twenty-ui/utilities';
|
||||
|
||||
@@ -27,7 +26,6 @@ export type DateInputProps = {
|
||||
onClear?: () => void;
|
||||
onSubmit?: (newDate: Nullable<Date>) => void;
|
||||
hideHeaderInput?: boolean;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
export const DateInput = ({
|
||||
@@ -42,7 +40,6 @@ export const DateInput = ({
|
||||
onClear,
|
||||
onSubmit,
|
||||
hideHeaderInput,
|
||||
hotkeyScope,
|
||||
}: DateInputProps) => {
|
||||
const [internalValue, setInternalValue] = useState(value);
|
||||
|
||||
@@ -83,17 +80,18 @@ export const DateInput = ({
|
||||
const handleClickOutside = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(event: MouseEvent | TouchEvent) => {
|
||||
const hotkeyScope = snapshot
|
||||
.getLoadable(currentHotkeyScopeState)
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
|
||||
if (hotkeyScope?.scope === TableHotkeyScope.CellEditMode) {
|
||||
if (currentFocusId === instanceId) {
|
||||
closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
|
||||
closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
|
||||
onClickOutside(event, internalValue);
|
||||
}
|
||||
},
|
||||
[
|
||||
instanceId,
|
||||
closeDropdownYearSelect,
|
||||
closeDropdownMonthSelect,
|
||||
onClickOutside,
|
||||
@@ -108,7 +106,6 @@ export const DateInput = ({
|
||||
onEnter: handleEnter,
|
||||
onEscape: handleEscape,
|
||||
onClickOutside: handleClickOutside,
|
||||
hotkeyScope: hotkeyScope,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -34,7 +34,6 @@ type DoubleTextInputProps = {
|
||||
secondValue: string;
|
||||
firstValuePlaceholder: string;
|
||||
secondValuePlaceholder: string;
|
||||
hotkeyScope: string;
|
||||
onEnter: (newDoubleTextValue: FieldDoubleText) => void;
|
||||
onEscape: (newDoubleTextValue: FieldDoubleText) => void;
|
||||
onTab?: (newDoubleTextValue: FieldDoubleText) => void;
|
||||
@@ -53,7 +52,6 @@ export const DoubleTextInput = ({
|
||||
secondValue,
|
||||
firstValuePlaceholder,
|
||||
secondValuePlaceholder,
|
||||
hotkeyScope,
|
||||
onClickOutside,
|
||||
onEnter,
|
||||
onEscape,
|
||||
@@ -97,7 +95,6 @@ export const DoubleTextInput = ({
|
||||
secondValue: secondInternalValue,
|
||||
});
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [onEnter, firstInternalValue, secondInternalValue],
|
||||
});
|
||||
@@ -110,7 +107,6 @@ export const DoubleTextInput = ({
|
||||
secondValue: secondInternalValue,
|
||||
});
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [onEscape, firstInternalValue, secondInternalValue],
|
||||
});
|
||||
@@ -128,7 +124,6 @@ export const DoubleTextInput = ({
|
||||
});
|
||||
}
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [
|
||||
onTab,
|
||||
@@ -151,7 +146,6 @@ export const DoubleTextInput = ({
|
||||
});
|
||||
}
|
||||
},
|
||||
scope: hotkeyScope,
|
||||
focusId: instanceId,
|
||||
dependencies: [
|
||||
onShiftTab,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useRef, useState } from 'react';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { FieldMultiSelectValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { DEFAULT_CELL_SCOPE } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
@@ -81,7 +80,6 @@ export const MultiSelectInput = ({
|
||||
resetSelectedItem();
|
||||
},
|
||||
focusId,
|
||||
scope: DEFAULT_CELL_SCOPE.scope,
|
||||
dependencies: [onCancel, resetSelectedItem],
|
||||
});
|
||||
|
||||
@@ -109,7 +107,6 @@ export const MultiSelectInput = ({
|
||||
selectableListInstanceId={selectableListComponentInstanceId}
|
||||
selectableItemIdArray={optionIds}
|
||||
focusId={focusId}
|
||||
hotkeyScope={DEFAULT_CELL_SCOPE.scope}
|
||||
>
|
||||
<DropdownContent
|
||||
ref={containerRef}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { DEFAULT_CELL_SCOPE } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2';
|
||||
import { SelectInput as SelectBaseInput } from '@/ui/input/components/SelectInput';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectOption } from 'twenty-ui/input';
|
||||
@@ -34,7 +33,6 @@ export const SelectInput = ({
|
||||
selectableListInstanceId={selectableListComponentInstanceId}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
focusId={focusId}
|
||||
hotkeyScope={DEFAULT_CELL_SCOPE.scope}
|
||||
>
|
||||
<SelectBaseInput
|
||||
onOptionSelected={onOptionSelected}
|
||||
|
||||
@@ -20,7 +20,6 @@ export type TextAreaInputProps = {
|
||||
onTab?: (newText: string) => void;
|
||||
onShiftTab?: (newText: string) => void;
|
||||
onClickOutside: (event: MouseEvent | TouchEvent, inputValue: string) => void;
|
||||
hotkeyScope: string;
|
||||
onChange?: (newText: string) => void;
|
||||
maxRows?: number;
|
||||
copyButton?: boolean;
|
||||
@@ -53,7 +52,6 @@ export const TextAreaInput = ({
|
||||
placeholder,
|
||||
autoFocus,
|
||||
value,
|
||||
hotkeyScope,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onTab,
|
||||
@@ -94,7 +92,6 @@ export const TextAreaInput = ({
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
hotkeyScope,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -25,7 +25,6 @@ type TextInputProps = {
|
||||
onTab?: (newText: string) => void;
|
||||
onShiftTab?: (newText: string) => void;
|
||||
onClickOutside?: (event: MouseEvent | TouchEvent, inputValue: string) => void;
|
||||
hotkeyScope: string;
|
||||
onChange?: (newText: string) => void;
|
||||
copyButton?: boolean;
|
||||
shouldTrim?: boolean;
|
||||
@@ -45,7 +44,6 @@ export const TextInput = ({
|
||||
placeholder,
|
||||
autoFocus,
|
||||
value,
|
||||
hotkeyScope,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onTab,
|
||||
@@ -79,7 +77,6 @@ export const TextInput = ({
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
hotkeyScope,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
+9
-17
@@ -1,6 +1,4 @@
|
||||
import { FieldMultiSelectValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { DEFAULT_CELL_SCOPE } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
@@ -80,6 +78,12 @@ const priorityOptions: SelectOption[] = [
|
||||
{ value: 'urgent', label: 'Urgent', color: 'red' },
|
||||
];
|
||||
|
||||
const instanceId = getRecordFieldInputInstanceId({
|
||||
recordId: '123',
|
||||
fieldName: 'Relation',
|
||||
prefix: 'multi-select-story',
|
||||
});
|
||||
|
||||
const Render = ({
|
||||
values,
|
||||
options,
|
||||
@@ -94,23 +98,11 @@ const Render = ({
|
||||
|
||||
useEffect(() => {
|
||||
pushFocusItemToFocusStack({
|
||||
focusId: TableHotkeyScope.CellEditMode,
|
||||
focusId: instanceId,
|
||||
component: {
|
||||
type: FocusComponentType.DROPDOWN,
|
||||
instanceId: getRecordFieldInputInstanceId({
|
||||
recordId: '123',
|
||||
fieldName: 'Relation',
|
||||
prefix: 'multi-select-story',
|
||||
}),
|
||||
instanceId,
|
||||
},
|
||||
hotkeyScope: {
|
||||
scope: TableHotkeyScope.CellEditMode,
|
||||
},
|
||||
memoizeKey: getRecordFieldInputInstanceId({
|
||||
recordId: '123',
|
||||
fieldName: 'Relation',
|
||||
prefix: 'multi-select-story',
|
||||
}),
|
||||
});
|
||||
}, [pushFocusItemToFocusStack]);
|
||||
|
||||
@@ -125,7 +117,7 @@ const Render = ({
|
||||
selectableListComponentInstanceId="multi-select-story"
|
||||
values={currentValues}
|
||||
options={options}
|
||||
focusId={DEFAULT_CELL_SCOPE.scope}
|
||||
focusId={instanceId}
|
||||
onCancel={onCancel}
|
||||
onOptionSelected={handleOptionSelected}
|
||||
dropdownWidth={dropdownWidth}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { arrayToChunks } from '~/utils/array/arrayToChunks';
|
||||
|
||||
import { ICON_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/ui/input/components/constants/IconPickerDropdownContentWidth';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
@@ -223,7 +222,6 @@ export const IconPicker = ({
|
||||
selectableListInstanceId={selectableListInstanceId}
|
||||
selectableItemIdMatrix={iconKeys2d}
|
||||
focusId={dropdownId}
|
||||
hotkeyScope={DropdownHotkeyScope.Dropdown}
|
||||
>
|
||||
<DropdownMenuSearchInput
|
||||
placeholder={t`Search icon`}
|
||||
|
||||
@@ -9,7 +9,6 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import { SelectValue } from '@/ui/input/components/internal/select/types';
|
||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||
@@ -186,7 +185,6 @@ export const Select = <Value extends SelectValue>({
|
||||
selectableListInstanceId={dropdownId}
|
||||
focusId={dropdownId}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
hotkeyScope={DropdownHotkeyScope.Dropdown}
|
||||
>
|
||||
{filteredOptions.map((option) => (
|
||||
<SelectableListItem
|
||||
|
||||
@@ -2,7 +2,6 @@ import styled from '@emotion/styled';
|
||||
import { FocusEventHandler, useId } from 'react';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
||||
import { InputHotkeyScope } from '@/ui/input/types/InputHotkeyScope';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
@@ -101,7 +100,6 @@ export const TextArea = ({
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
hotkeyScope: { scope: InputHotkeyScope.TextInput },
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
TextInputV2,
|
||||
TextInputV2ComponentProps,
|
||||
} from '@/ui/input/components/TextInputV2';
|
||||
import { InputHotkeyScope } from '@/ui/input/types/InputHotkeyScope';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
@@ -67,7 +66,6 @@ export const TextInput = ({
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
hotkeyScope: { scope: InputHotkeyScope.TextInput },
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -105,7 +103,6 @@ export const TextInput = ({
|
||||
keys: [Key.Escape],
|
||||
callback: handleEscape,
|
||||
focusId: instanceId,
|
||||
scope: InputHotkeyScope.TextInput,
|
||||
dependencies: [handleEscape],
|
||||
options: {
|
||||
preventDefault: false,
|
||||
@@ -116,7 +113,6 @@ export const TextInput = ({
|
||||
keys: [Key.Enter],
|
||||
callback: handleEnter,
|
||||
focusId: instanceId,
|
||||
scope: InputHotkeyScope.TextInput,
|
||||
dependencies: [handleEnter],
|
||||
options: {
|
||||
preventDefault: false,
|
||||
|
||||
@@ -17,7 +17,6 @@ type InputProps = {
|
||||
value?: string;
|
||||
onChange: (value: string) => void;
|
||||
placeholder?: string;
|
||||
hotkeyScope?: string;
|
||||
onEnter?: () => void;
|
||||
onEscape?: () => void;
|
||||
onClickOutside?: () => void;
|
||||
@@ -63,7 +62,6 @@ const Input = ({
|
||||
value,
|
||||
onChange,
|
||||
placeholder,
|
||||
hotkeyScope = 'title-input',
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
@@ -115,7 +113,6 @@ const Input = ({
|
||||
handleLeaveFocus();
|
||||
onShiftTab?.();
|
||||
},
|
||||
hotkeyScope: hotkeyScope,
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -143,7 +140,6 @@ export const TitleInput = ({
|
||||
sizeVariant = 'md',
|
||||
onChange,
|
||||
placeholder,
|
||||
hotkeyScope = 'title-input',
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
@@ -163,7 +159,6 @@ export const TitleInput = ({
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
placeholder={placeholder}
|
||||
hotkeyScope={hotkeyScope}
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
@@ -187,7 +182,6 @@ export const TitleInput = ({
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
hotkeyScope: { scope: hotkeyScope },
|
||||
});
|
||||
}
|
||||
}}
|
||||
|
||||
-2
@@ -9,11 +9,9 @@ const meta: Meta<typeof TitleInput> = {
|
||||
decorators: [ComponentDecorator],
|
||||
args: {
|
||||
placeholder: 'Enter title',
|
||||
hotkeyScope: 'titleInput',
|
||||
sizeVariant: 'md',
|
||||
},
|
||||
argTypes: {
|
||||
hotkeyScope: { control: false },
|
||||
sizeVariant: { control: false },
|
||||
},
|
||||
};
|
||||
|
||||
+2
-4
@@ -4,8 +4,6 @@ import styled from '@emotion/styled';
|
||||
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
|
||||
import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope';
|
||||
|
||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||
import { Currency } from '@/ui/input/components/internal/types/Currency';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
@@ -52,7 +50,7 @@ export const CurrencyPickerDropdownButton = ({
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const dropdownId = CurrencyPickerHotkeyScope.CurrencyPicker;
|
||||
const dropdownId = 'currency-picker-dropdown-id';
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
@@ -69,7 +67,7 @@ export const CurrencyPickerDropdownButton = ({
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId="currency-picker-dropdown-id"
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<StyledDropdownButtonContainer>
|
||||
<StyledIconContainer>
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export enum CurrencyPickerHotkeyScope {
|
||||
CurrencyPicker = 'currency-picker-dropdown-id',
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export enum CountryPickerHotkeyScope {
|
||||
CountryPicker = 'country-picker',
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export enum InputHotkeyScope {
|
||||
TextInput = 'text-input',
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export enum TitleInputHotkeyScope {
|
||||
TitleInput = 'title-input',
|
||||
}
|
||||
@@ -53,7 +53,6 @@ type HTMLInputProps = InputHTMLAttributes<HTMLInputElement>;
|
||||
|
||||
export type DropdownMenuInputProps = HTMLInputProps & {
|
||||
instanceId: string;
|
||||
hotkeyScope?: string;
|
||||
onClickOutside?: () => void;
|
||||
onEnter?: () => void;
|
||||
onEscape?: () => void;
|
||||
@@ -81,7 +80,6 @@ export const DropdownMenuInput = forwardRef<
|
||||
value,
|
||||
placeholder,
|
||||
instanceId,
|
||||
hotkeyScope = 'dropdown-menu-input',
|
||||
onChange,
|
||||
onClickOutside,
|
||||
onEnter = () => {},
|
||||
@@ -107,7 +105,6 @@ export const DropdownMenuInput = forwardRef<
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
hotkeyScope,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
-15
@@ -9,12 +9,9 @@ import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||
import { internalHotkeysEnabledScopesState } from '@/ui/utilities/hotkey/states/internal/internalHotkeysEnabledScopesState';
|
||||
import { SetRecoilState } from 'recoil';
|
||||
import { Avatar, IconChevronLeft } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
@@ -377,17 +374,6 @@ const initializeModalState = ({ set }: { set: SetRecoilState }) => {
|
||||
true,
|
||||
);
|
||||
|
||||
set(currentHotkeyScopeState, {
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
customScopes: {
|
||||
commandMenu: true,
|
||||
goto: false,
|
||||
keyboardShortcutMenu: false,
|
||||
},
|
||||
});
|
||||
|
||||
set(internalHotkeysEnabledScopesState, [ModalHotkeyScope.ModalFocus]);
|
||||
|
||||
set(focusStackState, [
|
||||
{
|
||||
focusId: modalId,
|
||||
@@ -399,7 +385,6 @@ const initializeModalState = ({ set }: { set: SetRecoilState }) => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { DropdownMenuInput } from '../DropdownMenuInput';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { DropdownMenuInput } from '../DropdownMenuInput';
|
||||
|
||||
const meta: Meta<typeof DropdownMenuInput> = {
|
||||
title: 'UI/Layout/Dropdown/DropdownMenuInput',
|
||||
component: DropdownMenuInput,
|
||||
decorators: [ComponentDecorator],
|
||||
args: { value: 'Lorem ipsum' },
|
||||
args: { value: 'Lorem ipsum', instanceId: 'dropdown-menu-input' },
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
-2
@@ -1,5 +1,4 @@
|
||||
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
|
||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
@@ -127,7 +126,6 @@ export const DropdownInternalContainer = ({
|
||||
}
|
||||
},
|
||||
focusId: dropdownId,
|
||||
scope: DropdownHotkeyScope.Dropdown,
|
||||
dependencies: [
|
||||
closeDropdown,
|
||||
isDropdownOpen,
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export enum DropdownHotkeyScope {
|
||||
Dropdown = 'dropdown',
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDrop
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
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 { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -52,9 +51,6 @@ export const useOpenDropdown = () => {
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
},
|
||||
globalHotkeysConfig: args?.globalHotkeysConfig ?? undefined,
|
||||
// TODO: Remove this once we've fully migrated away from hotkey scopes
|
||||
hotkeyScope: { scope: 'dropdown' } as HotkeyScope,
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
},
|
||||
[
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
|
||||
import { ModalHotkeysAndClickOutsideEffect } from '@/ui/layout/modal/components/ModalHotkeysAndClickOutsideEffect';
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { ModalComponentInstanceContext } from '@/ui/layout/modal/contexts/ModalComponentInstanceContext';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
|
||||
@@ -191,7 +190,6 @@ export type ModalProps = React.PropsWithChildren & {
|
||||
size?: ModalSize;
|
||||
padding?: ModalPadding;
|
||||
className?: string;
|
||||
hotkeyScope?: ModalHotkeyScope;
|
||||
onEnter?: () => void;
|
||||
modalVariant?: ModalVariants;
|
||||
dataGloballyPreventClickOutside?: boolean;
|
||||
|
||||
-5
@@ -1,5 +1,4 @@
|
||||
import { DIALOG_CLICK_OUTSIDE_ID } from '@/ui/feedback/dialog-manager/constants/DialogClickOutsideId';
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { MODAL_CLICK_OUTSIDE_LISTENER_EXCLUDED_ID } from '@/ui/layout/modal/constants/ModalClickOutsideListenerExcludedClassName';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
@@ -26,8 +25,6 @@ export const ModalHotkeysAndClickOutsideEffect = ({
|
||||
onEnter?.();
|
||||
},
|
||||
focusId: modalId,
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
dependencies: [onEnter],
|
||||
});
|
||||
|
||||
@@ -39,8 +36,6 @@ export const ModalHotkeysAndClickOutsideEffect = ({
|
||||
}
|
||||
},
|
||||
focusId: modalId,
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
dependencies: [isClosable, onClose],
|
||||
});
|
||||
|
||||
|
||||
-15
@@ -1,11 +1,8 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
||||
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||
import { internalHotkeysEnabledScopesState } from '@/ui/utilities/hotkey/states/internal/internalHotkeysEnabledScopesState';
|
||||
import { SetRecoilState } from 'recoil';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
@@ -22,17 +19,6 @@ const initializeState = ({ set }: { set: SetRecoilState }) => {
|
||||
true,
|
||||
);
|
||||
|
||||
set(currentHotkeyScopeState, {
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
customScopes: {
|
||||
commandMenu: true,
|
||||
goto: false,
|
||||
keyboardShortcutMenu: false,
|
||||
},
|
||||
});
|
||||
|
||||
set(internalHotkeysEnabledScopesState, [ModalHotkeyScope.ModalFocus]);
|
||||
|
||||
set(focusStackState, [
|
||||
{
|
||||
focusId: 'confirmation-modal',
|
||||
@@ -44,7 +30,6 @@ const initializeState = ({ set }: { set: SetRecoilState }) => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
-15
@@ -1,11 +1,8 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
||||
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||
import { internalHotkeysEnabledScopesState } from '@/ui/utilities/hotkey/states/internal/internalHotkeysEnabledScopesState';
|
||||
import { SetRecoilState } from 'recoil';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
@@ -22,17 +19,6 @@ const initializeState = ({ set }: { set: SetRecoilState }) => {
|
||||
true,
|
||||
);
|
||||
|
||||
set(currentHotkeyScopeState, {
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
customScopes: {
|
||||
commandMenu: true,
|
||||
goto: false,
|
||||
keyboardShortcutMenu: false,
|
||||
},
|
||||
});
|
||||
|
||||
set(internalHotkeysEnabledScopesState, [ModalHotkeyScope.ModalFocus]);
|
||||
|
||||
set(focusStackState, [
|
||||
{
|
||||
focusId: 'modal-id',
|
||||
@@ -44,7 +30,6 @@ const initializeState = ({ set }: { set: SetRecoilState }) => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export enum ModalHotkeyScope {
|
||||
ModalFocus = 'modal-focus',
|
||||
}
|
||||
@@ -3,24 +3,13 @@ import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { act } from 'react';
|
||||
|
||||
jest.mock('@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope');
|
||||
|
||||
const mockSetHotkeyScopeAndMemorizePreviousScope = jest.fn();
|
||||
const mockGoBackToPreviousHotkeyScope = jest.fn();
|
||||
|
||||
const modalId = 'test-modal-id';
|
||||
|
||||
describe('useModal', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
(usePreviousHotkeyScope as jest.Mock).mockReturnValue({
|
||||
setHotkeyScopeAndMemorizePreviousScope:
|
||||
mockSetHotkeyScopeAndMemorizePreviousScope,
|
||||
goBackToPreviousHotkeyScope: mockGoBackToPreviousHotkeyScope,
|
||||
});
|
||||
});
|
||||
|
||||
it('should open a modal', () => {
|
||||
@@ -68,7 +57,6 @@ describe('useModal', () => {
|
||||
});
|
||||
|
||||
expect(result.current.isModalOpened).toBe(false);
|
||||
expect(mockGoBackToPreviousHotkeyScope).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should toggle a modal (open when closed)', () => {
|
||||
@@ -118,6 +106,5 @@ describe('useModal', () => {
|
||||
});
|
||||
|
||||
expect(result.current.isModalOpened).toBe(false);
|
||||
expect(mockGoBackToPreviousHotkeyScope).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
@@ -63,17 +62,6 @@ export const useModal = () => {
|
||||
enableGlobalHotkeysWithModifiers: false,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
hotkeyScope: {
|
||||
scope: ModalHotkeyScope.ModalFocus,
|
||||
customScopes: {
|
||||
goto: false,
|
||||
commandMenu: false,
|
||||
commandMenuOpen: false,
|
||||
keyboardShortcutMenu: false,
|
||||
},
|
||||
},
|
||||
memoizeKey: modalId,
|
||||
});
|
||||
},
|
||||
[pushFocusItemToFocusStack],
|
||||
|
||||
+2
-9
@@ -15,7 +15,6 @@ type SelectableListProps = {
|
||||
onSelect?: (selected: string) => void;
|
||||
selectableListInstanceId: string;
|
||||
focusId: string;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
export const SelectableList = ({
|
||||
@@ -25,14 +24,8 @@ export const SelectableList = ({
|
||||
selectableListInstanceId,
|
||||
onSelect,
|
||||
focusId,
|
||||
hotkeyScope,
|
||||
}: SelectableListProps) => {
|
||||
useSelectableListHotKeys(
|
||||
selectableListInstanceId,
|
||||
hotkeyScope,
|
||||
focusId,
|
||||
onSelect,
|
||||
);
|
||||
useSelectableListHotKeys(selectableListInstanceId, focusId, onSelect);
|
||||
|
||||
const setSelectableItemIds = useSetRecoilComponentStateV2(
|
||||
selectableItemIdsComponentState,
|
||||
@@ -61,7 +54,7 @@ export const SelectableList = ({
|
||||
instanceId: selectableListInstanceId,
|
||||
}}
|
||||
>
|
||||
<SelectableListContextProvider value={{ focusId, hotkeyScope }}>
|
||||
<SelectableListContextProvider value={{ focusId }}>
|
||||
{children}
|
||||
</SelectableListContextProvider>
|
||||
</SelectableListComponentInstanceContext.Provider>
|
||||
|
||||
+1
-2
@@ -8,13 +8,12 @@ export const SelectableListItemHotkeyEffect = ({
|
||||
itemId: string;
|
||||
onEnter: () => void;
|
||||
}) => {
|
||||
const { focusId, hotkeyScope } = useSelectableListContextOrThrow();
|
||||
const { focusId } = useSelectableListContextOrThrow();
|
||||
|
||||
useSelectableListListenToEnterHotkeyOnItem({
|
||||
focusId,
|
||||
itemId,
|
||||
onEnter,
|
||||
hotkeyScope,
|
||||
});
|
||||
|
||||
return null;
|
||||
|
||||
-6
@@ -12,8 +12,6 @@ type Direction = 'up' | 'down' | 'left' | 'right';
|
||||
|
||||
export const useSelectableListHotKeys = (
|
||||
instanceId: string,
|
||||
// TODO: Remove this after migration to focus stack
|
||||
hotkeyScope: string,
|
||||
focusId: string,
|
||||
onSelect?: (itemId: string) => void,
|
||||
) => {
|
||||
@@ -140,7 +138,6 @@ export const useSelectableListHotKeys = (
|
||||
keys: Key.ArrowUp,
|
||||
callback: () => handleSelect('up'),
|
||||
focusId,
|
||||
scope: hotkeyScope,
|
||||
dependencies: [handleSelect],
|
||||
});
|
||||
|
||||
@@ -148,7 +145,6 @@ export const useSelectableListHotKeys = (
|
||||
keys: Key.ArrowDown,
|
||||
callback: () => handleSelect('down'),
|
||||
focusId,
|
||||
scope: hotkeyScope,
|
||||
dependencies: [handleSelect],
|
||||
});
|
||||
|
||||
@@ -156,7 +152,6 @@ export const useSelectableListHotKeys = (
|
||||
keys: Key.ArrowLeft,
|
||||
callback: () => handleSelect('left'),
|
||||
focusId,
|
||||
scope: hotkeyScope,
|
||||
dependencies: [handleSelect],
|
||||
});
|
||||
|
||||
@@ -164,7 +159,6 @@ export const useSelectableListHotKeys = (
|
||||
keys: Key.ArrowRight,
|
||||
callback: () => handleSelect('right'),
|
||||
focusId,
|
||||
scope: hotkeyScope,
|
||||
dependencies: [handleSelect],
|
||||
});
|
||||
};
|
||||
|
||||
-4
@@ -11,13 +11,10 @@ export const useSelectableListListenToEnterHotkeyOnItem = ({
|
||||
focusId,
|
||||
itemId,
|
||||
onEnter,
|
||||
hotkeyScope,
|
||||
}: {
|
||||
focusId: string;
|
||||
itemId: string;
|
||||
onEnter: () => void;
|
||||
// TODO: Remove this after migration to focus stack
|
||||
hotkeyScope: string;
|
||||
}) => {
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
SelectableListComponentInstanceContext,
|
||||
@@ -42,7 +39,6 @@ export const useSelectableListListenToEnterHotkeyOnItem = ({
|
||||
[instanceId, itemId, onEnter],
|
||||
),
|
||||
focusId,
|
||||
scope: hotkeyScope,
|
||||
dependencies: [itemId, onEnter],
|
||||
});
|
||||
};
|
||||
|
||||
-1
@@ -2,7 +2,6 @@ import { createRequiredContext } from '~/utils/createRequiredContext';
|
||||
|
||||
export type SelectableListContextValue = {
|
||||
focusId: string;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
export const [SelectableListContextProvider, useSelectableListContextOrThrow] =
|
||||
|
||||
+3
-5
@@ -18,7 +18,6 @@ type NavigationDrawerInputProps = {
|
||||
onSubmit: (value: string) => void;
|
||||
onCancel: (value: string) => void;
|
||||
onClickOutside: (event: MouseEvent | TouchEvent, value: string) => void;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
const NAVIGATION_DRAWER_INPUT_FOCUS_ID = 'navigation-drawer-input';
|
||||
@@ -32,7 +31,6 @@ export const NavigationDrawerInput = ({
|
||||
onSubmit,
|
||||
onCancel,
|
||||
onClickOutside,
|
||||
hotkeyScope,
|
||||
}: NavigationDrawerInputProps) => {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -45,7 +43,6 @@ export const NavigationDrawerInput = ({
|
||||
});
|
||||
},
|
||||
focusId: NAVIGATION_DRAWER_INPUT_FOCUS_ID,
|
||||
scope: hotkeyScope,
|
||||
});
|
||||
|
||||
useHotkeysOnFocusedElement({
|
||||
@@ -57,7 +54,6 @@ export const NavigationDrawerInput = ({
|
||||
});
|
||||
},
|
||||
focusId: NAVIGATION_DRAWER_INPUT_FOCUS_ID,
|
||||
scope: hotkeyScope,
|
||||
});
|
||||
|
||||
useListenClickOutside({
|
||||
@@ -86,7 +82,9 @@ export const NavigationDrawerInput = ({
|
||||
type: FocusComponentType.TEXT_INPUT,
|
||||
instanceId: NAVIGATION_DRAWER_INPUT_FOCUS_ID,
|
||||
},
|
||||
hotkeyScope: { scope: hotkeyScope },
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export enum NavigationDrawerHotKeyScope {
|
||||
MultiWorkspaceDropdownButton = 'multi-workspace-dropdown',
|
||||
}
|
||||
@@ -1,3 +1 @@
|
||||
import { DEBUG_HOTKEY_SCOPE } from '@/ui/utilities/hotkey/constants/DebugHotkeyScope';
|
||||
|
||||
export const DEBUG_FOCUS_STACK = DEBUG_HOTKEY_SCOPE;
|
||||
export const DEBUG_FOCUS_STACK = false;
|
||||
|
||||
-6
@@ -43,7 +43,6 @@ describe('usePushFocusItemToFocusStack', () => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
@@ -53,8 +52,6 @@ describe('usePushFocusItemToFocusStack', () => {
|
||||
type: focusItem.componentInstance.componentType,
|
||||
instanceId: focusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,7 +68,6 @@ describe('usePushFocusItemToFocusStack', () => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
@@ -81,8 +77,6 @@ describe('usePushFocusItemToFocusStack', () => {
|
||||
type: anotherFocusItem.componentInstance.componentType,
|
||||
instanceId: anotherFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
-10
@@ -41,7 +41,6 @@ const firstFocusItem = {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
const secondFocusItem = {
|
||||
@@ -54,7 +53,6 @@ const secondFocusItem = {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
describe('useRemoveFocusItemFromFocusStackById', () => {
|
||||
@@ -68,8 +66,6 @@ describe('useRemoveFocusItemFromFocusStackById', () => {
|
||||
type: firstFocusItem.componentInstance.componentType,
|
||||
instanceId: firstFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: firstFocusItem.memoizeKey,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -80,8 +76,6 @@ describe('useRemoveFocusItemFromFocusStackById', () => {
|
||||
type: secondFocusItem.componentInstance.componentType,
|
||||
instanceId: secondFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: secondFocusItem.memoizeKey,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,8 +105,6 @@ describe('useRemoveFocusItemFromFocusStackById', () => {
|
||||
type: firstFocusItem.componentInstance.componentType,
|
||||
instanceId: firstFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -123,8 +115,6 @@ describe('useRemoveFocusItemFromFocusStackById', () => {
|
||||
type: secondFocusItem.componentInstance.componentType,
|
||||
instanceId: secondFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
-3
@@ -44,7 +44,6 @@ describe('useResetFocusStack', () => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
@@ -54,8 +53,6 @@ describe('useResetFocusStack', () => {
|
||||
type: focusItem.componentInstance.componentType,
|
||||
instanceId: focusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: 'global',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
-8
@@ -44,7 +44,6 @@ describe('useResetFocusStackToFocusItem', () => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
const secondFocusItem = {
|
||||
@@ -57,7 +56,6 @@ describe('useResetFocusStackToFocusItem', () => {
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: true,
|
||||
},
|
||||
memoizeKey: 'global',
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
@@ -67,8 +65,6 @@ describe('useResetFocusStackToFocusItem', () => {
|
||||
type: firstFocusItem.componentInstance.componentType,
|
||||
instanceId: firstFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: firstFocusItem.memoizeKey,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,8 +75,6 @@ describe('useResetFocusStackToFocusItem', () => {
|
||||
type: secondFocusItem.componentInstance.componentType,
|
||||
instanceId: secondFocusItem.componentInstance.componentInstanceId,
|
||||
},
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: secondFocusItem.memoizeKey,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -93,8 +87,6 @@ describe('useResetFocusStackToFocusItem', () => {
|
||||
await act(async () => {
|
||||
result.current.resetFocusStackToFocusItem({
|
||||
focusStackItem: firstFocusItem,
|
||||
hotkeyScope: { scope: 'test-scope' },
|
||||
memoizeKey: firstFocusItem.memoizeKey,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+1
-19
@@ -2,9 +2,7 @@ import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStac
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { FocusStackItem } from '@/ui/utilities/focus/types/FocusStackItem';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
|
||||
@@ -23,15 +21,11 @@ const addOrMoveItemToTheTopOfTheStack = ({
|
||||
];
|
||||
|
||||
export const usePushFocusItemToFocusStack = () => {
|
||||
const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope();
|
||||
|
||||
const pushFocusItemToFocusStack = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({
|
||||
focusId,
|
||||
component,
|
||||
hotkeyScope,
|
||||
memoizeKey = 'global',
|
||||
globalHotkeysConfig,
|
||||
}: {
|
||||
focusId: string;
|
||||
@@ -40,9 +34,6 @@ export const usePushFocusItemToFocusStack = () => {
|
||||
instanceId: string;
|
||||
};
|
||||
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>;
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
hotkeyScope: HotkeyScope;
|
||||
memoizeKey?: string;
|
||||
}) => {
|
||||
const focusStackItem: FocusStackItem = {
|
||||
focusId,
|
||||
@@ -57,8 +48,6 @@ export const usePushFocusItemToFocusStack = () => {
|
||||
globalHotkeysConfig?.enableGlobalHotkeysConflictingWithKeyboard ??
|
||||
true,
|
||||
},
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
memoizeKey,
|
||||
};
|
||||
|
||||
const currentFocusStack = snapshot
|
||||
@@ -78,15 +67,8 @@ export const usePushFocusItemToFocusStack = () => {
|
||||
newFocusStack,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
setHotkeyScopeAndMemorizePreviousScope({
|
||||
scope: hotkeyScope.scope,
|
||||
customScopes: hotkeyScope.customScopes,
|
||||
memoizeKey,
|
||||
});
|
||||
},
|
||||
[setHotkeyScopeAndMemorizePreviousScope],
|
||||
[],
|
||||
);
|
||||
|
||||
return { pushFocusItemToFocusStack };
|
||||
|
||||
+1
-7
@@ -1,13 +1,10 @@
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
|
||||
export const useRemoveLastFocusItemFromFocusStackByComponentType = () => {
|
||||
const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope();
|
||||
|
||||
const removeLastFocusItemFromFocusStackByComponentType = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({ componentType }: { componentType: FocusComponentType }) => {
|
||||
@@ -44,11 +41,8 @@ export const useRemoveLastFocusItemFromFocusStackByComponentType = () => {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
goBackToPreviousHotkeyScope(removedFocusItem.memoizeKey);
|
||||
},
|
||||
[goBackToPreviousHotkeyScope],
|
||||
[],
|
||||
);
|
||||
|
||||
return { removeLastFocusItemFromFocusStackByComponentType };
|
||||
|
||||
+1
-7
@@ -1,12 +1,9 @@
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
|
||||
export const useRemoveFocusItemFromFocusStackById = () => {
|
||||
const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope();
|
||||
|
||||
const removeFocusItemFromFocusStackById = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({ focusId }: { focusId: string }) => {
|
||||
@@ -31,11 +28,8 @@ export const useRemoveFocusItemFromFocusStackById = () => {
|
||||
newFocusStack,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
goBackToPreviousHotkeyScope(removedFocusItem.memoizeKey);
|
||||
},
|
||||
[goBackToPreviousHotkeyScope],
|
||||
[],
|
||||
);
|
||||
|
||||
return { removeFocusItemFromFocusStackById };
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||
import { previousHotkeyScopeFamilyState } from '@/ui/utilities/hotkey/states/internal/previousHotkeyScopeFamilyState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
|
||||
export const useResetFocusStack = () => {
|
||||
const resetFocusStack = useRecoilCallback(
|
||||
({ reset }) =>
|
||||
(memoizeKey = 'global') => {
|
||||
() => {
|
||||
reset(focusStackState);
|
||||
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(`DEBUG: reset focus stack`);
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
reset(previousHotkeyScopeFamilyState(memoizeKey as string));
|
||||
reset(currentHotkeyScopeState);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
+2
-19
@@ -1,26 +1,13 @@
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
|
||||
import { FocusStackItem } from '@/ui/utilities/focus/types/FocusStackItem';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { previousHotkeyScopeFamilyState } from '@/ui/utilities/hotkey/states/internal/previousHotkeyScopeFamilyState';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
|
||||
export const useResetFocusStackToFocusItem = () => {
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const resetFocusStackToFocusItem = useRecoilCallback(
|
||||
({ set }) =>
|
||||
({
|
||||
focusStackItem,
|
||||
hotkeyScope,
|
||||
memoizeKey = 'global',
|
||||
}: {
|
||||
focusStackItem: FocusStackItem;
|
||||
hotkeyScope: HotkeyScope;
|
||||
memoizeKey?: string;
|
||||
}) => {
|
||||
({ focusStackItem }: { focusStackItem: FocusStackItem }) => {
|
||||
set(focusStackState, [focusStackItem]);
|
||||
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
@@ -28,12 +15,8 @@ export const useResetFocusStackToFocusItem = () => {
|
||||
focusStackItem,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
set(previousHotkeyScopeFamilyState(memoizeKey), null);
|
||||
setHotkeyScope(hotkeyScope.scope, hotkeyScope.customScopes);
|
||||
},
|
||||
[setHotkeyScope],
|
||||
[],
|
||||
);
|
||||
|
||||
return { resetFocusStackToFocusItem };
|
||||
|
||||
@@ -5,5 +5,4 @@ export type FocusStackItem = {
|
||||
focusId: string;
|
||||
componentInstance: FocusComponentInstance;
|
||||
globalHotkeysConfig: GlobalHotkeysConfig;
|
||||
memoizeKey: string;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Keys } from 'react-hotkeys-hook';
|
||||
|
||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
|
||||
type HotkeyEffectProps = {
|
||||
@@ -20,7 +19,6 @@ export const HotkeyEffect = ({
|
||||
keys: hotkey.key,
|
||||
callback: onHotkeyTriggered,
|
||||
focusId,
|
||||
scope: DropdownHotkeyScope.Dropdown,
|
||||
dependencies: [onHotkeyTriggered],
|
||||
});
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const DEBUG_HOTKEY_SCOPE = false;
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
import { CustomHotkeyScopes } from '@/ui/utilities/hotkey/types/CustomHotkeyScope';
|
||||
|
||||
export const DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES: CustomHotkeyScopes = {
|
||||
commandMenu: true,
|
||||
goto: false,
|
||||
keyboardShortcutMenu: false,
|
||||
};
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
||||
import { HotkeyScope } from '../types/HotkeyScope';
|
||||
|
||||
export const INITIAL_HOTKEYS_SCOPE: HotkeyScope = {
|
||||
scope: AppHotkeyScope.App,
|
||||
customScopes: {
|
||||
commandMenu: true,
|
||||
goto: true,
|
||||
keyboardShortcutMenu: true,
|
||||
},
|
||||
};
|
||||
-7
@@ -2,9 +2,6 @@ import { act, fireEvent, renderHook } from '@testing-library/react';
|
||||
import { MemoryRouter, useLocation } from 'react-router-dom';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||
|
||||
import { useGoToHotkeys } from '../useGoToHotkeys';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
@@ -24,10 +21,6 @@ describe('useGoToHotkeys', () => {
|
||||
const { result } = renderHook(() => {
|
||||
useGoToHotkeys({ key: 'a', location: '/three' });
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
setHotkeyScope(AppHotkeyScope.App, { goto: true });
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
return {
|
||||
|
||||
@@ -11,8 +11,6 @@ export const useGlobalHotkeys = (
|
||||
keys: Keys,
|
||||
callback: HotkeyCallback,
|
||||
containsModifier: boolean,
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
scope: string,
|
||||
dependencies?: unknown[],
|
||||
options?: UseHotkeysOptionsWithoutBuggyOptions,
|
||||
) => {
|
||||
@@ -59,7 +57,6 @@ export const useGlobalHotkeys = (
|
||||
callback: () => {
|
||||
handleCallback(keyboardEvent, hotkeysEvent);
|
||||
},
|
||||
scope,
|
||||
preventDefault,
|
||||
containsModifier,
|
||||
});
|
||||
|
||||
+4
-40
@@ -1,12 +1,11 @@
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import { currentGlobalHotkeysConfigSelector } from '@/ui/utilities/focus/states/currentGlobalHotkeysConfigSelector';
|
||||
import { internalHotkeysEnabledScopesState } from '@/ui/utilities/hotkey/states/internal/internalHotkeysEnabledScopesState';
|
||||
import {
|
||||
Hotkey,
|
||||
OptionsOrDependencyArray,
|
||||
} from 'react-hotkeys-hook/dist/types';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
import { DEBUG_HOTKEY_SCOPE } from '../constants/DebugHotkeyScope';
|
||||
|
||||
export const useGlobalHotkeysCallback = (
|
||||
dependencies?: OptionsOrDependencyArray,
|
||||
@@ -21,20 +20,13 @@ export const useGlobalHotkeysCallback = (
|
||||
hotkeysEvent,
|
||||
keyboardEvent,
|
||||
preventDefault,
|
||||
scope,
|
||||
}: {
|
||||
keyboardEvent: KeyboardEvent;
|
||||
hotkeysEvent: Hotkey;
|
||||
containsModifier: boolean;
|
||||
callback: (keyboardEvent: KeyboardEvent, hotkeysEvent: Hotkey) => void;
|
||||
preventDefault?: boolean;
|
||||
scope: string;
|
||||
}) => {
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
const currentHotkeyScopes = snapshot
|
||||
.getLoadable(internalHotkeysEnabledScopesState)
|
||||
.getValue();
|
||||
|
||||
const currentGlobalHotkeysConfig = snapshot
|
||||
.getLoadable(currentGlobalHotkeysConfigSelector)
|
||||
.getValue();
|
||||
@@ -43,7 +35,7 @@ export const useGlobalHotkeysCallback = (
|
||||
containsModifier &&
|
||||
!currentGlobalHotkeysConfig.enableGlobalHotkeysWithModifiers
|
||||
) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can't call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
@@ -59,7 +51,7 @@ export const useGlobalHotkeysCallback = (
|
||||
!containsModifier &&
|
||||
!currentGlobalHotkeysConfig.enableGlobalHotkeysConflictingWithKeyboard
|
||||
) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can't call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
@@ -70,36 +62,8 @@ export const useGlobalHotkeysCallback = (
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
if (!currentHotkeyScopes.includes(scope)) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can't call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
}) because I'm in scope [${scope}] and the active scopes are : [${currentHotkeyScopes.join(
|
||||
', ',
|
||||
)}]`,
|
||||
'color: gray; ',
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
}) because I'm in scope [${scope}] and the active scopes are : [${currentHotkeyScopes.join(
|
||||
', ',
|
||||
)}]`,
|
||||
'color: green;',
|
||||
);
|
||||
}
|
||||
|
||||
if (preventDefault === true) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI prevent default for hotkey (${hotkeysEvent.keys})`,
|
||||
'color: gray;',
|
||||
|
||||
+2
-5
@@ -11,7 +11,6 @@ export const useGlobalHotkeysSequence = (
|
||||
firstKey: Keys,
|
||||
secondKey: Keys,
|
||||
sequenceCallback: () => void,
|
||||
scope: string,
|
||||
options: Options = {
|
||||
enableOnContentEditable: true,
|
||||
enableOnFormTags: true,
|
||||
@@ -33,7 +32,6 @@ export const useGlobalHotkeysSequence = (
|
||||
callback: () => {
|
||||
setPendingHotkey(firstKey);
|
||||
},
|
||||
scope,
|
||||
preventDefault: !!options.preventDefault,
|
||||
});
|
||||
},
|
||||
@@ -41,7 +39,7 @@ export const useGlobalHotkeysSequence = (
|
||||
enableOnContentEditable: options.enableOnContentEditable,
|
||||
enableOnFormTags: options.enableOnFormTags,
|
||||
},
|
||||
[setPendingHotkey, scope],
|
||||
[setPendingHotkey],
|
||||
);
|
||||
|
||||
useHotkeys(
|
||||
@@ -66,7 +64,6 @@ export const useGlobalHotkeysSequence = (
|
||||
|
||||
sequenceCallback();
|
||||
},
|
||||
scope,
|
||||
preventDefault: false,
|
||||
});
|
||||
},
|
||||
@@ -74,6 +71,6 @@ export const useGlobalHotkeysSequence = (
|
||||
enableOnContentEditable: options.enableOnContentEditable,
|
||||
enableOnFormTags: options.enableOnFormTags,
|
||||
},
|
||||
[pendingHotkey, setPendingHotkey, scope, ...deps],
|
||||
[pendingHotkey, setPendingHotkey, ...deps],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Keys } from 'react-hotkeys-hook/dist/types';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { useGlobalHotkeysSequence } from '@/ui/utilities/hotkey/hooks/useGlobalHotkeysSequence';
|
||||
import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
||||
|
||||
type GoToHotkeysProps = {
|
||||
key: Keys;
|
||||
@@ -24,7 +23,6 @@ export const useGoToHotkeys = ({
|
||||
preNavigateFunction?.();
|
||||
navigate(location);
|
||||
},
|
||||
AppHotkeyScope.Goto,
|
||||
{
|
||||
enableOnContentEditable: true,
|
||||
enableOnFormTags: true,
|
||||
|
||||
-5
@@ -11,16 +11,12 @@ export const useHotkeysOnFocusedElement = ({
|
||||
keys,
|
||||
callback,
|
||||
focusId,
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
scope,
|
||||
dependencies,
|
||||
options,
|
||||
}: {
|
||||
keys: Keys;
|
||||
callback: HotkeyCallback;
|
||||
focusId: string;
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
scope: string;
|
||||
dependencies?: unknown[];
|
||||
options?: UseHotkeysOptionsWithoutBuggyOptions;
|
||||
}) => {
|
||||
@@ -59,7 +55,6 @@ export const useHotkeysOnFocusedElement = ({
|
||||
setPendingHotkey(null);
|
||||
},
|
||||
focusId,
|
||||
scope,
|
||||
preventDefault,
|
||||
});
|
||||
},
|
||||
|
||||
+7
-22
@@ -1,4 +1,4 @@
|
||||
import { internalHotkeysEnabledScopesState } from '@/ui/utilities/hotkey/states/internal/internalHotkeysEnabledScopesState';
|
||||
import { DEBUG_FOCUS_STACK } from '@/ui/utilities/focus/constants/DebugFocusStack';
|
||||
import {
|
||||
Hotkey,
|
||||
OptionsOrDependencyArray,
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
import { currentFocusIdSelector } from '../../focus/states/currentFocusIdSelector';
|
||||
import { DEBUG_HOTKEY_SCOPE } from '../constants/DebugHotkeyScope';
|
||||
|
||||
export const useHotkeysOnFocusedElementCallback = (
|
||||
dependencies?: OptionsOrDependencyArray,
|
||||
@@ -20,36 +19,24 @@ export const useHotkeysOnFocusedElementCallback = (
|
||||
hotkeysEvent,
|
||||
keyboardEvent,
|
||||
focusId,
|
||||
scope,
|
||||
preventDefault,
|
||||
}: {
|
||||
keyboardEvent: KeyboardEvent;
|
||||
hotkeysEvent: Hotkey;
|
||||
callback: (keyboardEvent: KeyboardEvent, hotkeysEvent: Hotkey) => void;
|
||||
focusId: string;
|
||||
scope: string;
|
||||
preventDefault?: boolean;
|
||||
}) => {
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
|
||||
// TODO: Remove this once we've migrated hotkey scopes to the new api
|
||||
const currentHotkeyScopes = snapshot
|
||||
.getLoadable(internalHotkeysEnabledScopesState)
|
||||
.getValue();
|
||||
|
||||
if (
|
||||
currentFocusId !== focusId ||
|
||||
!currentHotkeyScopes.includes(scope)
|
||||
) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (currentFocusId !== focusId) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can't call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
}) because I'm in scope [${scope}] and the active scopes are : [${currentHotkeyScopes.join(
|
||||
', ',
|
||||
)}] and the current focus identifier is [${currentFocusId}], and the focusId is [${focusId}]`,
|
||||
}) because I'm in [${focusId}] and the current focus identifier is [${currentFocusId}]`,
|
||||
'color: gray; ',
|
||||
);
|
||||
}
|
||||
@@ -57,19 +44,17 @@ export const useHotkeysOnFocusedElementCallback = (
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI can call hotkey (${
|
||||
hotkeysEvent.keys
|
||||
}) because I'm in scope [${scope}] and the active scopes are : [${currentHotkeyScopes.join(
|
||||
', ',
|
||||
)}], and the current focus identifier is [${currentFocusId}], and the focusId is [${focusId}]`,
|
||||
}) because I'm in [${focusId}] and the current focus identifier is [${currentFocusId}]`,
|
||||
'color: green;',
|
||||
);
|
||||
}
|
||||
|
||||
if (preventDefault === true) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
if (DEBUG_FOCUS_STACK) {
|
||||
logDebug(
|
||||
`DEBUG: %cI prevent default for hotkey (${hotkeysEvent.keys})`,
|
||||
'color: gray;',
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
import { DEBUG_HOTKEY_SCOPE } from '../constants/DebugHotkeyScope';
|
||||
|
||||
import { currentHotkeyScopeState } from '../states/internal/currentHotkeyScopeState';
|
||||
import { previousHotkeyScopeFamilyState } from '../states/internal/previousHotkeyScopeFamilyState';
|
||||
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||
|
||||
import { useSetHotkeyScope } from './useSetHotkeyScope';
|
||||
|
||||
export const usePreviousHotkeyScope = () => {
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const goBackToPreviousHotkeyScope = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(memoizeKey = 'global') => {
|
||||
const previousHotkeyScope = snapshot
|
||||
.getLoadable(previousHotkeyScopeFamilyState(memoizeKey as string))
|
||||
.getValue();
|
||||
|
||||
if (!previousHotkeyScope) {
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug(`DEBUG: no previous hotkey scope ${memoizeKey}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug(
|
||||
`DEBUG: goBackToPreviousHotkeyScope ${previousHotkeyScope.scope}`,
|
||||
previousHotkeyScope,
|
||||
);
|
||||
}
|
||||
|
||||
setHotkeyScope(
|
||||
previousHotkeyScope.scope,
|
||||
previousHotkeyScope.customScopes,
|
||||
);
|
||||
|
||||
set(previousHotkeyScopeFamilyState(memoizeKey as string), null);
|
||||
},
|
||||
[setHotkeyScope],
|
||||
);
|
||||
|
||||
const setHotkeyScopeAndMemorizePreviousScope = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({
|
||||
scope,
|
||||
customScopes,
|
||||
memoizeKey = 'global',
|
||||
}: {
|
||||
scope: string;
|
||||
customScopes?: CustomHotkeyScopes;
|
||||
memoizeKey?: string;
|
||||
}) => {
|
||||
const currentHotkeyScope = snapshot
|
||||
.getLoadable(currentHotkeyScopeState)
|
||||
.getValue();
|
||||
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug('DEBUG: setHotkeyScopeAndMemorizePreviousScope', {
|
||||
currentHotkeyScope,
|
||||
scope,
|
||||
customScopes,
|
||||
});
|
||||
}
|
||||
|
||||
setHotkeyScope(scope, customScopes);
|
||||
|
||||
set(previousHotkeyScopeFamilyState(memoizeKey), currentHotkeyScope);
|
||||
},
|
||||
[setHotkeyScope],
|
||||
);
|
||||
|
||||
return {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
goBackToPreviousHotkeyScope,
|
||||
};
|
||||
};
|
||||
@@ -1,104 +0,0 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { DEBUG_HOTKEY_SCOPE } from '../constants/DebugHotkeyScope';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { logDebug } from '~/utils/logDebug';
|
||||
import { DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES } from '../constants/DefaultHotkeysScopeCustomScopes';
|
||||
import { currentHotkeyScopeState } from '../states/internal/currentHotkeyScopeState';
|
||||
import { internalHotkeysEnabledScopesState } from '../states/internal/internalHotkeysEnabledScopesState';
|
||||
import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
||||
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||
import { HotkeyScope } from '../types/HotkeyScope';
|
||||
|
||||
const areCustomScopesEqual = (
|
||||
customScopesA: CustomHotkeyScopes | undefined,
|
||||
customScopesB: CustomHotkeyScopes | undefined,
|
||||
) => {
|
||||
return (
|
||||
customScopesA?.commandMenu === customScopesB?.commandMenu &&
|
||||
customScopesA?.commandMenuOpen === customScopesB?.commandMenuOpen &&
|
||||
customScopesA?.goto === customScopesB?.goto &&
|
||||
customScopesA?.keyboardShortcutMenu ===
|
||||
customScopesB?.keyboardShortcutMenu &&
|
||||
customScopesA?.searchRecords === customScopesB?.searchRecords
|
||||
);
|
||||
};
|
||||
|
||||
export const useSetHotkeyScope = () =>
|
||||
useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async (hotkeyScopeToSet: string, customScopes?: CustomHotkeyScopes) => {
|
||||
const currentHotkeyScope = snapshot
|
||||
.getLoadable(currentHotkeyScopeState)
|
||||
.getValue();
|
||||
|
||||
if (currentHotkeyScope.scope === hotkeyScopeToSet) {
|
||||
if (!isDefined(customScopes)) {
|
||||
if (
|
||||
areCustomScopesEqual(
|
||||
currentHotkeyScope?.customScopes,
|
||||
DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
areCustomScopesEqual(
|
||||
currentHotkeyScope?.customScopes,
|
||||
customScopes,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newHotkeyScope: HotkeyScope = {
|
||||
scope: hotkeyScopeToSet,
|
||||
customScopes: {
|
||||
commandMenu: customScopes?.commandMenu ?? true,
|
||||
commandMenuOpen: customScopes?.commandMenuOpen ?? true,
|
||||
goto: customScopes?.goto ?? false,
|
||||
keyboardShortcutMenu: customScopes?.keyboardShortcutMenu ?? false,
|
||||
searchRecords: customScopes?.searchRecords ?? false,
|
||||
},
|
||||
};
|
||||
|
||||
const scopesToSet: string[] = [];
|
||||
|
||||
if (newHotkeyScope.customScopes?.commandMenu === true) {
|
||||
scopesToSet.push(AppHotkeyScope.CommandMenu);
|
||||
}
|
||||
|
||||
if (newHotkeyScope.customScopes?.commandMenuOpen === true) {
|
||||
scopesToSet.push(AppHotkeyScope.CommandMenuOpen);
|
||||
}
|
||||
|
||||
if (newHotkeyScope?.customScopes?.goto === true) {
|
||||
scopesToSet.push(AppHotkeyScope.Goto);
|
||||
}
|
||||
|
||||
if (newHotkeyScope?.customScopes?.keyboardShortcutMenu === true) {
|
||||
scopesToSet.push(AppHotkeyScope.KeyboardShortcutMenu);
|
||||
}
|
||||
|
||||
if (newHotkeyScope?.customScopes?.searchRecords === true) {
|
||||
scopesToSet.push(AppHotkeyScope.SearchRecords);
|
||||
}
|
||||
|
||||
scopesToSet.push(newHotkeyScope.scope);
|
||||
|
||||
if (DEBUG_HOTKEY_SCOPE) {
|
||||
logDebug(`DEBUG: set new hotkey scope : ${newHotkeyScope.scope}`, {
|
||||
scopesToSet,
|
||||
newHotkeyScope,
|
||||
});
|
||||
}
|
||||
|
||||
set(internalHotkeysEnabledScopesState, scopesToSet);
|
||||
set(currentHotkeyScopeState, newHotkeyScope);
|
||||
},
|
||||
[],
|
||||
);
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { createState } from 'twenty-ui/utilities';
|
||||
import { INITIAL_HOTKEYS_SCOPE } from '../../constants/InitialHotkeysScope';
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
export const currentHotkeyScopeState = createState<HotkeyScope>({
|
||||
key: 'currentHotkeyScopeState',
|
||||
defaultValue: INITIAL_HOTKEYS_SCOPE,
|
||||
});
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { createState } from 'twenty-ui/utilities';
|
||||
export const internalHotkeysEnabledScopesState = createState<string[]>({
|
||||
key: 'internalHotkeysEnabledScopesState',
|
||||
defaultValue: [],
|
||||
});
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
export const previousHotkeyScopeFamilyState = createFamilyState<
|
||||
HotkeyScope | null,
|
||||
string
|
||||
>({
|
||||
key: 'previousHotkeyScopeFamilyState',
|
||||
defaultValue: null,
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
export enum AppHotkeyScope {
|
||||
App = 'app',
|
||||
Goto = 'goto',
|
||||
CommandMenu = 'command-menu',
|
||||
CommandMenuOpen = 'command-menu-open',
|
||||
SearchRecords = 'search-records',
|
||||
KeyboardShortcutMenu = 'keyboard-shortcut-menu',
|
||||
KeyboardShortcutMenuOpen = 'keyboard-shortcut-menu-open',
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export type CustomHotkeyScopes = {
|
||||
goto?: boolean;
|
||||
commandMenu?: boolean;
|
||||
commandMenuOpen?: boolean;
|
||||
keyboardShortcutMenu?: boolean;
|
||||
searchRecords?: boolean;
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
import { CustomHotkeyScopes } from './CustomHotkeyScope';
|
||||
|
||||
export type HotkeyScope = {
|
||||
scope: string;
|
||||
customScopes?: CustomHotkeyScopes;
|
||||
};
|
||||
Reference in New Issue
Block a user