UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

50 lines (49 loc) 2.05 kB
import React from 'react'; import { createElemPropsHook, useMountLayout } from '@workday/canvas-kit-react/common'; import { orientationKeyMap } from './keyUtils'; import { useListModel } from './useListModel'; /** * This elemProps hook resets the cursor when the list looses focus. By default, * [useListItemRovingFocus](#use-list-item-roving-focus) will leave the last focused item as the * focusable item in the list. Sometimes it is desireable to reset the cursor to the last selected * item. For example, `Tabs.Item` uses this hook to reset the tab stop to the currently selected tab. * * ```ts * const useMyItem = composeHooks( * useListResetCursorOnBlur, // adds the cursor reset to selected for roving tabindex * useListItemRovingFocus, * useListItemRegister * ); ``` */ export const useListResetCursorOnBlur = createElemPropsHook(useListModel)(({ state, events }) => { const programmaticFocusRef = React.useRef(false); const requestAnimationFrameRef = React.useRef(0); useMountLayout(() => { return () => { // Cancelling the animation frame prevents React unmount errors cancelAnimationFrame(requestAnimationFrameRef.current); }; }); return { onKeyDown(event) { // Programmatic focus only on any focus change via keyboard if (Object.keys(orientationKeyMap[state.orientation]).indexOf(event.key) !== -1) { programmaticFocusRef.current = true; } }, onFocus() { programmaticFocusRef.current = false; }, onBlur() { if (!programmaticFocusRef.current) { // use an animation frame to wait for any other model changes that may happen on a blur requestAnimationFrameRef.current = requestAnimationFrame(() => { if (state.selectedIds[0] !== state.cursorId) { events.goTo({ id: state.selectedIds[0] }); } }); } }, }; });