@wordpress/compose
Version:
WordPress higher-order components (HOCs).
80 lines (75 loc) • 2.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@wordpress/element");
/**
* WordPress dependencies
*/
/** @type {Element|null} */
let origin = null;
/**
* Adds the unmount behavior of returning focus to the element which had it
* previously as is expected for roles like menus or dialogs.
*
* @param {() => void} [onFocusReturn] Overrides the default return behavior.
* @return {import('react').RefCallback<HTMLElement>} Element Ref.
*
* @example
* ```js
* import { useFocusReturn } from '@wordpress/compose';
*
* const WithFocusReturn = () => {
* const ref = useFocusReturn()
* return (
* <div ref={ ref }>
* <Button />
* <Button />
* </div>
* );
* }
* ```
*/
function useFocusReturn(onFocusReturn) {
/** @type {import('react').MutableRefObject<null | HTMLElement>} */
const ref = (0, _element.useRef)(null);
/** @type {import('react').MutableRefObject<null | Element>} */
const focusedBeforeMount = (0, _element.useRef)(null);
const onFocusReturnRef = (0, _element.useRef)(onFocusReturn);
(0, _element.useEffect)(() => {
onFocusReturnRef.current = onFocusReturn;
}, [onFocusReturn]);
return (0, _element.useCallback)(node => {
if (node) {
var _activeDocument$activ;
// Set ref to be used when unmounting.
ref.current = node;
// Only set when the node mounts.
if (focusedBeforeMount.current) {
return;
}
const activeDocument = node.ownerDocument.activeElement instanceof window.HTMLIFrameElement ? node.ownerDocument.activeElement.contentDocument : node.ownerDocument;
focusedBeforeMount.current = (_activeDocument$activ = activeDocument?.activeElement) !== null && _activeDocument$activ !== void 0 ? _activeDocument$activ : null;
} else if (focusedBeforeMount.current) {
const isFocused = ref.current?.contains(ref.current?.ownerDocument.activeElement);
if (ref.current?.isConnected && !isFocused) {
var _origin;
(_origin = origin) !== null && _origin !== void 0 ? _origin : origin = focusedBeforeMount.current;
return;
}
// Defer to the component's own explicit focus return behavior, if
// specified. This allows for support that the `onFocusReturn`
// decides to allow the default behavior to occur under some
// conditions.
if (onFocusReturnRef.current) {
onFocusReturnRef.current();
} else {
/** @type {null|HTMLElement} */(!focusedBeforeMount.current.isConnected ? origin : focusedBeforeMount.current)?.focus();
}
origin = null;
}
}, []);
}
var _default = exports.default = useFocusReturn;
//# sourceMappingURL=index.js.map