UNPKG

@yamada-ui/focus-lock

Version:

Yamada UI focus lock component

1 lines 4.18 kB
{"version":3,"sources":["../src/focus-lock.tsx"],"sourcesContent":["import type { FC } from \"@yamada-ui/core\"\nimport type { FocusableElement } from \"@yamada-ui/utils\"\nimport type { ReactNode, RefObject } from \"react\"\nimport { getAllFocusable, interopDefault } from \"@yamada-ui/utils\"\nimport { useCallback } from \"react\"\nimport ReactFocusLock from \"react-focus-lock\"\n\nconst InternalFocusLock = interopDefault(ReactFocusLock)\n\nexport interface FocusLockProps {\n children: ReactNode\n /**\n * If `true`, the first focusable element within the `children` will auto-focused once `FocusLock` mounts.\n *\n * @default false\n */\n autoFocus?: boolean\n /**\n * The `ref` of the wrapper for which the focus-lock wraps.\n */\n contentRef?: RefObject<HTMLElement>\n /**\n * If `true`, focus trapping will be disabled.\n *\n * @default false\n */\n disabled?: boolean\n /**\n * `ref` of the element to return focus to when `FocusLock` unmounts.\n */\n finalFocusRef?: RefObject<FocusableElement>\n /**\n * `ref` of the element to receive focus initially.\n */\n initialFocusRef?: RefObject<FocusableElement>\n /**\n * If `true`, focus trapping will be disabled.\n *\n * @default false\n *\n * @deprecated Use `disabled` instead.\n */\n isDisabled?: boolean\n /**\n * Enables aggressive focus capturing within iframes.\n * - If `true`: keep focus in the lock, no matter where lock is active.\n * - If `false`: allows focus to move outside of iframe.\n *\n * @default false\n */\n lockFocusAcrossFrames?: boolean\n /**\n * If `true`, disables text selections inside, and outside focus lock.\n *\n * @default false\n */\n persistentFocus?: boolean\n /**\n * If `true`, focus will be restored to the element that triggered the `FocusLock` once it unmounts.\n *\n * @default false\n */\n restoreFocus?: boolean\n}\n\n/**\n * `FocusLock` is a component that improves accessibility by restricting focus within elements such as modals and dialogs, and locking the focus within that range.\n *\n * @see Docs https://yamada-ui.com/components/other/focus-lock\n */\n\nexport const FocusLock: FC<FocusLockProps> = ({\n autoFocus,\n children,\n contentRef,\n isDisabled,\n disabled = isDisabled,\n finalFocusRef,\n initialFocusRef,\n lockFocusAcrossFrames,\n persistentFocus,\n restoreFocus,\n}) => {\n const returnFocus = restoreFocus && !finalFocusRef\n\n const onActivation = useCallback(() => {\n if (initialFocusRef?.current) {\n initialFocusRef.current.focus()\n } else if (contentRef?.current) {\n const focusables = getAllFocusable(contentRef.current)\n\n if (focusables.length === 0)\n requestAnimationFrame(() => {\n contentRef.current?.focus()\n })\n }\n }, [initialFocusRef, contentRef])\n\n const onDeactivation = useCallback(() => {\n finalFocusRef?.current?.focus()\n }, [finalFocusRef])\n\n return (\n <InternalFocusLock\n autoFocus={autoFocus}\n crossFrame={lockFocusAcrossFrames}\n disabled={disabled}\n persistentFocus={persistentFocus}\n returnFocus={returnFocus}\n onActivation={onActivation}\n onDeactivation={onDeactivation}\n >\n {children}\n </InternalFocusLock>\n )\n}\n\nFocusLock.displayName = \"FocusLock\"\nFocusLock.__ui__ = \"FocusLock\"\n"],"mappings":";;;AAGA,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,mBAAmB;AAC5B,OAAO,oBAAoB;AAkGvB;AAhGJ,IAAM,oBAAoB,eAAe,cAAc;AAgEhD,IAAM,YAAgC,CAAC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,cAAc,gBAAgB,CAAC;AAErC,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,mDAAiB,SAAS;AAC5B,sBAAgB,QAAQ,MAAM;AAAA,IAChC,WAAW,yCAAY,SAAS;AAC9B,YAAM,aAAa,gBAAgB,WAAW,OAAO;AAErD,UAAI,WAAW,WAAW;AACxB,8BAAsB,MAAM;AA5FpC;AA6FU,2BAAW,YAAX,mBAAoB;AAAA,QACtB,CAAC;AAAA,IACL;AAAA,EACF,GAAG,CAAC,iBAAiB,UAAU,CAAC;AAEhC,QAAM,iBAAiB,YAAY,MAAM;AAlG3C;AAmGI,yDAAe,YAAf,mBAAwB;AAAA,EAC1B,GAAG,CAAC,aAAa,CAAC;AAElB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,UAAU,cAAc;AACxB,UAAU,SAAS;","names":[]}