UNPKG

@wordpress/compose

Version:
88 lines (83 loc) 2.47 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useFocusOnMount; var _element = require("@wordpress/element"); var _dom = require("@wordpress/dom"); var _useRefEffect = _interopRequireDefault(require("../use-ref-effect")); /** * WordPress dependencies */ /** * Internal dependencies */ /** * Hook used to focus the first tabbable element on mount. * * @param {boolean | 'firstElement'} focusOnMount Focus on mount mode. * @return {import('react').RefCallback<HTMLElement>} Ref callback. * * @example * ```js * import { useFocusOnMount } from '@wordpress/compose'; * * const WithFocusOnMount = () => { * const ref = useFocusOnMount() * return ( * <div ref={ ref }> * <Button /> * <Button /> * </div> * ); * } * ``` */ function useFocusOnMount(focusOnMount = 'firstElement') { const focusOnMountRef = (0, _element.useRef)(focusOnMount); /** * Sets focus on a DOM element. * * @param {HTMLElement} target The DOM element to set focus to. * @return {void} */ const setFocus = target => { target.focus({ // When focusing newly mounted dialogs, // the position of the popover is often not right on the first render // This prevents the layout shifts when focusing the dialogs. preventScroll: true }); }; /** @type {import('react').MutableRefObject<ReturnType<setTimeout> | undefined>} */ const timerIdRef = (0, _element.useRef)(); (0, _element.useEffect)(() => { focusOnMountRef.current = focusOnMount; }, [focusOnMount]); return (0, _useRefEffect.default)(node => { var _node$ownerDocument$a; if (!node || focusOnMountRef.current === false) { return; } if (node.contains((_node$ownerDocument$a = node.ownerDocument?.activeElement) !== null && _node$ownerDocument$a !== void 0 ? _node$ownerDocument$a : null)) { return; } if (focusOnMountRef.current !== 'firstElement') { setFocus(node); return; } timerIdRef.current = setTimeout(() => { const firstTabbable = _dom.focus.tabbable.find(node)[0]; if (firstTabbable) { setFocus(firstTabbable); } }, 0); return () => { if (timerIdRef.current) { clearTimeout(timerIdRef.current); } }; }, []); } //# sourceMappingURL=index.js.map