UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

84 lines (80 loc) 2.82 kB
"use client"; import { useUpdateEffect } from "../../utils/effect.js"; import { isRefObject } from "../../utils/ref.js"; import { utils_exports } from "../../utils/index.js"; import { useEventListener } from "../use-event-listener/index.js"; import { useCallback, useRef } from "react"; //#region src/hooks/use-focus/index.ts /** * `useFocusOnShow` is a custom hook that focuses on the target element when it is shown. * * @see https://yamada-ui.com/docs/hooks/use-focus-on-show */ const useFocusOnShow = (refOrEl, { focusTarget: focusRefOrEl, preventScroll, shouldFocus, visible } = { preventScroll: true, shouldFocus: false }) => { const trulyShouldFocus = shouldFocus && visible; const focused = useRef(false); const getTarget = useCallback(() => { return isRefObject(refOrEl) ? refOrEl.current : refOrEl; }, [refOrEl]); const getFocusTarget = useCallback(() => { return isRefObject(focusRefOrEl) ? focusRefOrEl.current : focusRefOrEl; }, [focusRefOrEl]); const onFocus = useCallback(() => { const target = getTarget(); if (!target || !trulyShouldFocus || focused.current) return; if (target.contains(document.activeElement)) return; const focusTarget = getFocusTarget(); if (focusTarget) requestAnimationFrame(() => { focusTarget.focus({ preventScroll }); focused.current = true; }); else { const firstFocusable = (0, utils_exports.getFirstFocusableElement)(target); if (firstFocusable) requestAnimationFrame(() => { firstFocusable.focus({ preventScroll }); focused.current = true; }); else requestAnimationFrame(() => { target.focus({ preventScroll }); focused.current = true; }); } }, [ getTarget, trulyShouldFocus, getFocusTarget, preventScroll ]); useUpdateEffect(() => { focused.current = !trulyShouldFocus; }, [trulyShouldFocus]); useUpdateEffect(() => { requestAnimationFrame(onFocus); }, [onFocus]); useEventListener(getTarget, "transitionend", onFocus); }; /** * `useFocusOnPointerDown` is a custom hook that focuses on the target element when it is clicked. * * @see https://yamada-ui.com/docs/hooks/use-focus-on-pointer-down */ const useFocusOnPointerDown = ({ ref, elements, enabled }) => { useEventListener(() => (0, utils_exports.getDocument)(ref.current), "pointerdown", (ev) => { if (!(0, utils_exports.isSafari)() || !enabled) return; const target = ev.target; const validTarget = (elements ?? [ref]).some((elOrRef) => { const el = isRefObject(elOrRef) ? elOrRef.current : elOrRef; return el?.contains(target) || el === target; }); if ((0, utils_exports.getActiveElement)((0, utils_exports.getDocument)(ref.current)) !== target && validTarget) { ev.preventDefault(); target.focus(); } }); }; //#endregion export { useFocusOnPointerDown, useFocusOnShow }; //# sourceMappingURL=index.js.map