From effb893211fe5f13aaa5ef12ac2d62e3a962fc42 Mon Sep 17 00:00:00 2001 From: jpveooys <66470099+jpveooys@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:22:27 +0000 Subject: [PATCH] fix(DatePicker): Fix compatibility with strict mode This stops using the onDeactivate callback in focus-trap due to its incompatibility with strict mode: https://github.com/focus-trap/focus-trap-react?tab=readme-ov-file#%EF%B8%8F%EF%B8%8F-react-18-strict-mode-%EF%B8%8F%EF%B8%8F Instead, the click and escape callbacks are used. Additionally, the DATEPICKER_ACTION.TOGGLE_OPEN reducer action was removed as the reduce functions are called twice when strict mode is enabled, so that action doesn't work as expected. Strict mode hasn't been enabled in Storybook as there seemed to be some unrelated end-to-end tests still failing with it enabled. --- .../src/components/DatePicker/Input.tsx | 10 ++++++++-- .../src/components/DatePicker/types.ts | 6 ------ .../DatePicker/useDatePickerContext.tsx | 5 ----- .../DatePicker/useFocusTrapOptions.ts | 17 ++++++++++++++--- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/react-component-library/src/components/DatePicker/Input.tsx b/packages/react-component-library/src/components/DatePicker/Input.tsx index 3fc997300c..ab4ba20a6b 100644 --- a/packages/react-component-library/src/components/DatePicker/Input.tsx +++ b/packages/react-component-library/src/components/DatePicker/Input.tsx @@ -120,9 +120,15 @@ export const Input = memo( const handleInputClick = useCallback(() => { if (isRange) { - dispatch({ type: DATEPICKER_ACTION.TOGGLE_OPEN }) + dispatch({ + type: DATEPICKER_ACTION.UPDATE, + data: { + calendarTableVariant: CALENDAR_TABLE_VARIANT.HIDE, + isOpen: !isOpen, + }, + }) } - }, [isRange, dispatch]) + }, [isOpen, isRange, dispatch]) const handleShowHideClick = useCallback(() => { dispatch({ diff --git a/packages/react-component-library/src/components/DatePicker/types.ts b/packages/react-component-library/src/components/DatePicker/types.ts index 4c42f1658d..b28a94acab 100644 --- a/packages/react-component-library/src/components/DatePicker/types.ts +++ b/packages/react-component-library/src/components/DatePicker/types.ts @@ -16,7 +16,6 @@ export const DATEPICKER_ACTION = { UPDATE: 'UPDATE', REFRESH_HAS_ERROR: 'REFRESH_HAS_ERROR', REFRESH_INPUT_VALUE: 'REFRESH_INPUT_VALUE', - TOGGLE_OPEN: 'TOGGLE_OPEN', } as const interface ResetAction { @@ -39,11 +38,6 @@ interface RefreshInputValueAction { data?: never } -interface ToggleOpenAction { - type: typeof DATEPICKER_ACTION.TOGGLE_OPEN - data?: never -} - export type DatePickerAction = | ResetAction | UpdateAction diff --git a/packages/react-component-library/src/components/DatePicker/useDatePickerContext.tsx b/packages/react-component-library/src/components/DatePicker/useDatePickerContext.tsx index e3461b8a12..0abfa3c4d6 100644 --- a/packages/react-component-library/src/components/DatePicker/useDatePickerContext.tsx +++ b/packages/react-component-library/src/components/DatePicker/useDatePickerContext.tsx @@ -81,11 +81,6 @@ function reducer( state.datePickerFormat ), } - case DATEPICKER_ACTION.TOGGLE_OPEN: - return { - ...state, - isOpen: !state.isOpen, - } default: throw new Error('Unknown reducer action type') } diff --git a/packages/react-component-library/src/components/DatePicker/useFocusTrapOptions.ts b/packages/react-component-library/src/components/DatePicker/useFocusTrapOptions.ts index 4f6d9bbed5..0f5d7bc9d5 100644 --- a/packages/react-component-library/src/components/DatePicker/useFocusTrapOptions.ts +++ b/packages/react-component-library/src/components/DatePicker/useFocusTrapOptions.ts @@ -19,10 +19,21 @@ export function useFocusTrapOptions( () => ({ allowOutsideClick: (event) => isEventTargetDescendantOf(event, clickAllowedElementRefs), - clickOutsideDeactivates: (event) => - !isEventTargetDescendantOf(event, clickAllowedElementRefs), + clickOutsideDeactivates: (event) => { + const shouldDeactivate = !isEventTargetDescendantOf( + event, + clickAllowedElementRefs + ) + if (shouldDeactivate) { + close() + } + return shouldDeactivate + }, + escapeDeactivates: () => { + close() + return true + }, initialFocus: false, - onDeactivate: close, }), [clickAllowedElementRefs, close] )