UNPKG

@gechiui/compose

Version:
99 lines (80 loc) 3.49 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@gechiui/element"); var _keycodes = require("@gechiui/keycodes"); var _useConstrainedTabbing = _interopRequireDefault(require("../use-constrained-tabbing")); var _useFocusOnMount = _interopRequireDefault(require("../use-focus-on-mount")); var _useFocusReturn = _interopRequireDefault(require("../use-focus-return")); var _useFocusOutside = _interopRequireDefault(require("../use-focus-outside")); var _useMergeRefs = _interopRequireDefault(require("../use-merge-refs")); /** * GeChiUI dependencies */ /** * Internal dependencies */ /* eslint-disable jsdoc/valid-types */ /** * @typedef DialogOptions * @property {Parameters<useFocusOnMount>[0]} focusOnMount Focus on mount arguments. * @property {() => void} onClose Function to call when the dialog is closed. */ /* eslint-enable jsdoc/valid-types */ /** * Returns a ref and props to apply to a dialog wrapper to enable the following behaviors: * - constrained tabbing. * - focus on mount. * - return focus on unmount. * - focus outside. * * @param {DialogOptions} options Dialog Options. */ function useDialog(options) { /** * @type {import('react').MutableRefObject<DialogOptions | undefined>} */ const currentOptions = (0, _element.useRef)(); (0, _element.useEffect)(() => { currentOptions.current = options; }, Object.values(options)); const constrainedTabbingRef = (0, _useConstrainedTabbing.default)(); const focusOnMountRef = (0, _useFocusOnMount.default)(options.focusOnMount); const focusReturnRef = (0, _useFocusReturn.default)(); const focusOutsideProps = (0, _useFocusOutside.default)(event => { var _currentOptions$curre, _currentOptions$curre2; // This unstable prop is here only to manage backward compatibility // for the Popover component otherwise, the onClose should be enough. // @ts-ignore unstable property if ((_currentOptions$curre = currentOptions.current) !== null && _currentOptions$curre !== void 0 && _currentOptions$curre.__unstableOnClose) { // @ts-ignore unstable property currentOptions.current.__unstableOnClose('focus-outside', event); } else if ((_currentOptions$curre2 = currentOptions.current) !== null && _currentOptions$curre2 !== void 0 && _currentOptions$curre2.onClose) { currentOptions.current.onClose(); } }); const closeOnEscapeRef = (0, _element.useCallback)(node => { if (!node) { return; } node.addEventListener('keydown', ( /** @type {KeyboardEvent} */ event) => { var _currentOptions$curre3; // Close on escape if (event.keyCode === _keycodes.ESCAPE && !event.defaultPrevented && (_currentOptions$curre3 = currentOptions.current) !== null && _currentOptions$curre3 !== void 0 && _currentOptions$curre3.onClose) { event.preventDefault(); currentOptions.current.onClose(); } }); }, []); return [(0, _useMergeRefs.default)([options.focusOnMount !== false ? constrainedTabbingRef : null, options.focusOnMount !== false ? focusReturnRef : null, options.focusOnMount !== false ? focusOnMountRef : null, closeOnEscapeRef]), { ...focusOutsideProps, tabIndex: '-1' }]; } var _default = useDialog; exports.default = _default; //# sourceMappingURL=index.js.map