UNPKG

reakit

Version:

Toolkit for building accessible rich web apps with React

703 lines (600 loc) 29 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../_rollupPluginBabelHelpers-8f9a8751.js'); var createComponent = require('reakit-system/createComponent'); var createHook = require('reakit-system/createHook'); require('reakit-utils/shallowEqual'); var React = require('react'); var useForkRef = require('reakit-utils/useForkRef'); var isButton = require('reakit-utils/isButton'); var reakitWarning = require('reakit-warning'); var useLiveRef = require('reakit-utils/useLiveRef'); require('reakit-utils/isSelfTarget'); var useIsomorphicEffect = require('reakit-utils/useIsomorphicEffect'); var hasFocusWithin = require('reakit-utils/hasFocusWithin'); var tabbable = require('reakit-utils/tabbable'); require('../Role/Role.js'); var useUpdateEffect = require('reakit-utils/useUpdateEffect'); var useCreateElement = require('reakit-system/useCreateElement'); var getDocument = require('reakit-utils/getDocument'); require('reakit-utils/canUseDOM'); var getNextActiveElementOnBlur = require('reakit-utils/getNextActiveElementOnBlur'); var ensureFocus = require('reakit-utils/ensureFocus'); require('../__keys-f41a441b.js'); var Disclosure_DisclosureContent = require('../Disclosure/DisclosureContent.js'); require('react-dom'); var Portal_Portal = require('../Portal/Portal.js'); var removeItemFromArray = require('reakit-utils/removeItemFromArray'); var MenuContext = require('../MenuContext-2d32bb3e.js'); var bodyScrollLock = require('body-scroll-lock'); var closest = require('reakit-utils/closest'); var getActiveElement = require('reakit-utils/getActiveElement'); var contains = require('reakit-utils/contains'); var DialogBackdropContext = require('../DialogBackdropContext-b43e21d7.js'); var isEmpty = require('reakit-utils/isEmpty'); var __keys = require('../__keys-0c8e6398.js'); function useDisclosureRef(dialogRef, options) { var ref = React.useRef(null); var animating = !!(options.animated && options.animating); React.useEffect(function () { if (options.visible || animating) return undefined; // We get the last focused element before the dialog opens, so we can move // focus back to it when the dialog closes. var onFocus = function onFocus(event) { var target = event.target; if ("focus" in target) { ref.current = target; if (options.unstable_disclosureRef) { options.unstable_disclosureRef.current = target; } } }; var document = getDocument.getDocument(dialogRef.current); document.addEventListener("focusin", onFocus); return function () { return document.removeEventListener("focusin", onFocus); }; }, [options.visible, animating, options.unstable_disclosureRef, dialogRef]); React.useEffect(function () { var _options$unstable_dis; if (!options.visible || animating) return undefined; // Safari and Firefox on MacOS don't focus on buttons on mouse down. // Instead, they focus on the closest focusable parent (ultimately, the // body element). This works around that by preventing that behavior and // forcing focus on the disclosure button. Otherwise, we wouldn't be able // to close the dialog by clicking again on the disclosure. var onMouseDown = function onMouseDown(event) { var element = event.currentTarget; if (!isButton.isButton(element)) return; event.preventDefault(); element.focus(); }; var disclosure = ((_options$unstable_dis = options.unstable_disclosureRef) === null || _options$unstable_dis === void 0 ? void 0 : _options$unstable_dis.current) || ref.current; disclosure === null || disclosure === void 0 ? void 0 : disclosure.addEventListener("mousedown", onMouseDown); return function () { return disclosure === null || disclosure === void 0 ? void 0 : disclosure.removeEventListener("mousedown", onMouseDown); }; }, [options.visible, animating, options.unstable_disclosureRef]); return options.unstable_disclosureRef || ref; } function usePreventBodyScroll(targetRef, options) { var shouldPrevent = Boolean(options.preventBodyScroll && options.visible); React.useEffect(function () { var element = targetRef.current; if (!element || !shouldPrevent) return undefined; bodyScrollLock.disableBodyScroll(element, { reserveScrollBarGap: true }); return function () { return bodyScrollLock.enableBodyScroll(element); }; }, [targetRef, shouldPrevent]); } function useFocusOnShow(dialogRef, nestedDialogs, options) { var initialFocusRef = options.unstable_initialFocusRef; var shouldFocus = options.visible && options.unstable_autoFocusOnShow; var animating = !!(options.animated && options.animating); useUpdateEffect.useUpdateEffect(function () { var dialog = dialogRef.current; process.env.NODE_ENV !== "production" ? reakitWarning.warning(!!shouldFocus && !dialog, "[reakit/Dialog]", "Can't set initial focus on dialog because `ref` wasn't passed to the dialog element.", "See https://reakit.io/docs/dialog") : void 0; if (!shouldFocus) return; if (!dialog) return; if (animating) return; // If there're nested open dialogs, let them handle focus if (nestedDialogs.some(function (child) { return child.current && !child.current.hidden; })) { return; } if (initialFocusRef !== null && initialFocusRef !== void 0 && initialFocusRef.current) { initialFocusRef.current.focus({ preventScroll: true }); } else { var tabbable$1 = tabbable.getFirstTabbableIn(dialog, true); var isActive = function isActive() { return hasFocusWithin.hasFocusWithin(dialog); }; if (tabbable$1) { ensureFocus.ensureFocus(tabbable$1, { preventScroll: true, isActive: isActive }); } else { ensureFocus.ensureFocus(dialog, { preventScroll: true, isActive: isActive }); process.env.NODE_ENV !== "production" ? reakitWarning.warning(dialog.tabIndex === undefined || dialog.tabIndex < 0, "It's recommended to have at least one tabbable element inside dialog. The dialog element has been automatically focused.", "If this is the intended behavior, pass `tabIndex={0}` to the dialog element to disable this warning.", "See https://reakit.io/docs/dialog/#initial-focus", dialog) : void 0; } } }, [dialogRef, shouldFocus, animating, nestedDialogs, initialFocusRef]); } function usePortalRef(dialogRef, options) { var portalRef = React.useRef(null); React.useEffect(function () { var dialog = dialogRef.current; if (!dialog || !options.visible) return; portalRef.current = closest.closest(dialog, Portal_Portal.Portal.__selector); }, [dialogRef, options.visible]); return portalRef; } function removeFromDOM(element) { if (element.parentNode == null) return; element.parentNode.removeChild(element); } var focusTrapClassName = "__reakit-focus-trap"; function isFocusTrap(element) { var _element$classList; return (_element$classList = element.classList) === null || _element$classList === void 0 ? void 0 : _element$classList.contains(focusTrapClassName); } function useFocusTrap(dialogRef, visibleModals, options) { var portalRef = usePortalRef(dialogRef, options); var shouldTrap = options.visible && options.modal; var beforeElement = React.useRef(null); var afterElement = React.useRef(null); // Create before and after elements // https://github.com/w3c/aria-practices/issues/545 React.useEffect(function () { if (!shouldTrap) return undefined; var portal = portalRef.current; if (!portal) { process.env.NODE_ENV !== "production" ? reakitWarning.warning(true, "Can't trap focus within modal dialog because either `ref` wasn't passed to component or the component wasn't rendered within a portal", "See https://reakit.io/docs/dialog") : void 0; return undefined; } if (!beforeElement.current) { var document = getDocument.getDocument(portal); beforeElement.current = document.createElement("div"); beforeElement.current.className = focusTrapClassName; beforeElement.current.tabIndex = 0; beforeElement.current.style.position = "fixed"; beforeElement.current.setAttribute("aria-hidden", "true"); } if (!afterElement.current) { afterElement.current = beforeElement.current.cloneNode(); } portal.insertAdjacentElement("beforebegin", beforeElement.current); portal.insertAdjacentElement("afterend", afterElement.current); return function () { if (beforeElement.current) removeFromDOM(beforeElement.current); if (afterElement.current) removeFromDOM(afterElement.current); }; }, [portalRef, shouldTrap]); // Focus trap React.useEffect(function () { var before = beforeElement.current; var after = afterElement.current; if (!shouldTrap || !before || !after) return undefined; var handleFocus = function handleFocus(event) { var dialog = dialogRef.current; if (!dialog || visibleModals.length) return; event.preventDefault(); var isAfter = event.target === after; var tabbable$1 = isAfter ? tabbable.getFirstTabbableIn(dialog) : tabbable.getLastTabbableIn(dialog); if (tabbable$1) { tabbable$1.focus(); } else { // fallback to dialog dialog.focus(); } }; before.addEventListener("focus", handleFocus); after.addEventListener("focus", handleFocus); return function () { before.removeEventListener("focus", handleFocus); after.removeEventListener("focus", handleFocus); }; }, [dialogRef, visibleModals, shouldTrap]); } function hidByFocusingAnotherElement(dialogRef) { var dialog = dialogRef.current; if (!dialog) return false; var activeElement = getActiveElement.getActiveElement(dialog); if (!activeElement) return false; if (contains.contains(dialog, activeElement)) return false; if (tabbable.isTabbable(activeElement)) return true; if (activeElement.getAttribute("data-dialog") === "true") return true; return false; } function useFocusOnHide(dialogRef, disclosureRef, options) { var shouldFocus = options.unstable_autoFocusOnHide && !options.visible; var animating = !!(options.animated && options.animating); useUpdateEffect.useUpdateEffect(function () { var _options$unstable_fin; if (!shouldFocus) return; if (animating) return; // Hide was triggered by a click/focus on a tabbable element outside // the dialog or on another dialog. We won't change focus then. if (hidByFocusingAnotherElement(dialogRef)) { return; } var finalFocusEl = ((_options$unstable_fin = options.unstable_finalFocusRef) === null || _options$unstable_fin === void 0 ? void 0 : _options$unstable_fin.current) || disclosureRef.current; if (finalFocusEl) { if (finalFocusEl.id) { var document = getDocument.getDocument(finalFocusEl); var compositeElement = document.querySelector("[aria-activedescendant='" + finalFocusEl.id + "']"); if (compositeElement) { ensureFocus.ensureFocus(compositeElement); return; } } ensureFocus.ensureFocus(finalFocusEl); return; } process.env.NODE_ENV !== "production" ? reakitWarning.warning(true, "Can't return focus after closing dialog. Either render a disclosure component or provide a `unstable_finalFocusRef` prop.", "See https://reakit.io/docs/dialog", dialogRef.current) : void 0; }, [shouldFocus, animating, dialogRef, disclosureRef]); } var DialogContext = /*#__PURE__*/React.createContext({}); function useNestedDialogs(dialogRef, options) { var context = React.useContext(DialogContext); var _React$useState = React.useState([]), dialogs = _React$useState[0], setDialogs = _React$useState[1]; var _React$useState2 = React.useState(dialogs), visibleModals = _React$useState2[0], setVisibleModals = _React$useState2[1]; var addDialog = React.useCallback(function (ref) { var _context$addDialog; (_context$addDialog = context.addDialog) === null || _context$addDialog === void 0 ? void 0 : _context$addDialog.call(context, ref); setDialogs(function (prevDialogs) { return [].concat(prevDialogs, [ref]); }); }, [context.addDialog]); var removeDialog = React.useCallback(function (ref) { var _context$removeDialog; (_context$removeDialog = context.removeDialog) === null || _context$removeDialog === void 0 ? void 0 : _context$removeDialog.call(context, ref); setDialogs(function (prevDialogs) { return removeItemFromArray.removeItemFromArray(prevDialogs, ref); }); }, [context.removeDialog]); var showDialog = React.useCallback(function (ref) { var _context$showDialog; (_context$showDialog = context.showDialog) === null || _context$showDialog === void 0 ? void 0 : _context$showDialog.call(context, ref); setVisibleModals(function (prevDialogs) { return [].concat(prevDialogs, [ref]); }); }, [context.showDialog]); var hideDialog = React.useCallback(function (ref) { var _context$hideDialog; (_context$hideDialog = context.hideDialog) === null || _context$hideDialog === void 0 ? void 0 : _context$hideDialog.call(context, ref); setVisibleModals(function (prevDialogs) { return removeItemFromArray.removeItemFromArray(prevDialogs, ref); }); }, [context.hideDialog]); // If it's a nested dialog, add it to context React.useEffect(function () { var _context$addDialog2; if (options.unstable_orphan) return undefined; (_context$addDialog2 = context.addDialog) === null || _context$addDialog2 === void 0 ? void 0 : _context$addDialog2.call(context, dialogRef); return function () { var _context$removeDialog2; (_context$removeDialog2 = context.removeDialog) === null || _context$removeDialog2 === void 0 ? void 0 : _context$removeDialog2.call(context, dialogRef); }; }, [options.unstable_orphan, context.addDialog, dialogRef, context.removeDialog]); React.useEffect(function () { var _context$showDialog2; if (options.unstable_orphan) return undefined; if (!options.modal) return undefined; if (!options.visible) return undefined; (_context$showDialog2 = context.showDialog) === null || _context$showDialog2 === void 0 ? void 0 : _context$showDialog2.call(context, dialogRef); return function () { var _context$hideDialog2; (_context$hideDialog2 = context.hideDialog) === null || _context$hideDialog2 === void 0 ? void 0 : _context$hideDialog2.call(context, dialogRef); }; }, [options.unstable_orphan, options.modal, options.visible, context.showDialog, dialogRef, context.hideDialog]); // Close all nested dialogs when parent dialog closes React.useEffect(function () { if (context.visible === false && options.visible && !options.unstable_orphan) { var _options$hide; (_options$hide = options.hide) === null || _options$hide === void 0 ? void 0 : _options$hide.call(options); } }, [context.visible, options.visible, options.hide, options.unstable_orphan]); // Provider var providerValue = React.useMemo(function () { return { visible: options.visible, addDialog: addDialog, removeDialog: removeDialog, showDialog: showDialog, hideDialog: hideDialog }; }, [options.visible, addDialog, removeDialog, showDialog, hideDialog]); var wrap = React.useCallback(function (element) { return /*#__PURE__*/React.createElement(DialogContext.Provider, { value: providerValue }, element); }, [providerValue]); return { dialogs: dialogs, visibleModals: visibleModals, wrap: wrap }; } function dialogContains(target) { return function (dialogRef) { var dialog = dialogRef.current; if (!dialog) return false; if (contains.contains(dialog, target)) return true; var document = getDocument.getDocument(dialog); var backdrop = document.querySelector("[data-dialog-ref=\"" + dialog.id + "\"]"); if (backdrop) { return contains.contains(backdrop, target); } return false; }; } function isDisclosure(target, disclosure) { return contains.contains(disclosure, target); } function isInDocument(target) { var document = getDocument.getDocument(target); if (target.tagName === "HTML") { return true; } return contains.contains(document.body, target); } function useEventListenerOutside(containerRef, disclosureRef, nestedDialogs, eventType, listener, shouldListen, capture) { var listenerRef = useLiveRef.useLiveRef(listener); React.useEffect(function () { if (!shouldListen) return undefined; var onEvent = function onEvent(event) { if (!listenerRef.current) return; var container = containerRef.current; var disclosure = disclosureRef.current; var target = event.target; if (!container) { process.env.NODE_ENV !== "production" ? reakitWarning.warning(true, "Can't detect events outside dialog because `ref` wasn't passed to component.", "See https://reakit.io/docs/dialog") : void 0; return; } // When an element is unmounted right after it receives focus, the focus // event is triggered after that, when the element isn't part of the // current document anymore. So we ignore it. if (!isInDocument(target)) return; // Event inside dialog if (contains.contains(container, target)) return; // Event on disclosure if (disclosure && isDisclosure(target, disclosure)) return; // Event inside a nested dialog or focus trap if (isFocusTrap(target) || nestedDialogs.some(dialogContains(target))) { return; } listenerRef.current(event); }; var document = getDocument.getDocument(containerRef.current); document.addEventListener(eventType, onEvent, capture); return function () { return document.removeEventListener(eventType, onEvent, capture); }; }, [containerRef, disclosureRef, nestedDialogs, eventType, shouldListen, listenerRef]); } function useMouseDownRef(dialogRef, options) { var mouseDownRef = React.useRef(); React.useEffect(function () { if (!options.visible) return undefined; if (!options.hideOnClickOutside) return undefined; var document = getDocument.getDocument(dialogRef.current); var onMouseDown = function onMouseDown(event) { mouseDownRef.current = event.target; }; document.addEventListener("mousedown", onMouseDown); return function () { return document.removeEventListener("mousedown", onMouseDown); }; }, [options.visible, options.hideOnClickOutside, dialogRef]); return mouseDownRef; } function useHideOnClickOutside(dialogRef, disclosureRef, nestedDialogs, options) { var mouseDownRef = useMouseDownRef(dialogRef, options); useEventListenerOutside(dialogRef, disclosureRef, nestedDialogs, "click", function (event) { // Make sure the element that has been clicked is the same that last // triggered the mousedown event. This prevents the dialog from closing // by dragging the cursor (for example, selecting some text inside the // dialog and releasing the mouse outside of it). if (mouseDownRef.current === event.target) { var _options$hide; (_options$hide = options.hide) === null || _options$hide === void 0 ? void 0 : _options$hide.call(options); } }, options.visible && options.hideOnClickOutside); useEventListenerOutside(dialogRef, disclosureRef, nestedDialogs, "focusin", function (event) { var document = getDocument.getDocument(dialogRef.current); // Fix for https://github.com/reakit/reakit/issues/619 // On IE11, calling element.blur() triggers the focus event on // document.body, so we make sure to ignore it as well. if (event.target !== document && event.target !== document.body) { var _options$hide2; (_options$hide2 = options.hide) === null || _options$hide2 === void 0 ? void 0 : _options$hide2.call(options); } }, options.visible && options.hideOnClickOutside); } function useDisableHoverOutside(portalRef, nestedDialogs, options) { var useEvent = function useEvent(eventType) { return useEventListenerOutside(portalRef, { current: null }, nestedDialogs, eventType, function (event) { event.stopPropagation(); event.preventDefault(); }, options.visible && options.modal, true); }; useEvent("mouseover"); useEvent("mousemove"); useEvent("mouseout"); } /** * When the focused child gets removed from the DOM, we make sure to move focus * to the dialog. */ function useFocusOnChildUnmount(dialogRef, options) { React.useEffect(function () { var dialog = dialogRef.current; if (!options.visible || !dialog) return undefined; var observer = new MutationObserver(function (mutations) { var target = mutations[0].target; // If target is not this dialog, then this observer was triggered by a // nested dialog, so we just ignore it here and let the nested dialog // handle it there. if (target !== dialog) return; var document = getDocument.getDocument(dialog); var activeElement = getActiveElement.getActiveElement(dialog); // We can check if the current focused element is the document body. On // IE 11, it's an empty object when the current document is in a frame or // iframe. if (activeElement === document.body || isEmpty.isEmpty(activeElement)) { dialog.focus(); } }); observer.observe(dialog, { childList: true, subtree: true }); return function () { observer.disconnect(); }; }, [options.visible, dialogRef]); } function isActualElement(element) { return element && element.tagName && element.tagName !== "HTML" && element !== getDocument.getDocument(element).body; } function useFocusOnBlur(dialogRef, options) { var _React$useReducer = React.useReducer(function (n) { return n + 1; }, 0), blurred = _React$useReducer[0], scheduleFocus = _React$useReducer[1]; useIsomorphicEffect.useIsomorphicEffect(function () { var dialog = dialogRef.current; if (!options.visible) return; if (!blurred) return; // After blur, if the active element isn't an actual element, this probably // means that element.blur() was called on an element inside the dialog. // In this case, the browser will automatically focus the body element. // So we move focus back to the dialog. if (!isActualElement(getActiveElement.getActiveElement(dialog))) { process.env.NODE_ENV !== "production" ? reakitWarning.warning(!dialog, "Can't focus dialog after a nested element got blurred because `ref` wasn't passed to the component", "See https://reakit.io/docs/dialog") : void 0; dialog === null || dialog === void 0 ? void 0 : dialog.focus(); } }, [blurred, dialogRef]); var onBlur = React.useCallback(function (event) { if (!options.visible) return; var nextActiveElement = getNextActiveElementOnBlur.getNextActiveElementOnBlur(event); if (!isActualElement(nextActiveElement)) { scheduleFocus(); } }, [options.visible]); return onBlur; } var useDialog = createHook.createHook({ name: "Dialog", compose: Disclosure_DisclosureContent.useDisclosureContent, keys: __keys.DIALOG_KEYS, useOptions: function useOptions(_ref) { var _ref$modal = _ref.modal, modal = _ref$modal === void 0 ? true : _ref$modal, _ref$hideOnEsc = _ref.hideOnEsc, hideOnEsc = _ref$hideOnEsc === void 0 ? true : _ref$hideOnEsc, _ref$hideOnClickOutsi = _ref.hideOnClickOutside, hideOnClickOutside = _ref$hideOnClickOutsi === void 0 ? true : _ref$hideOnClickOutsi, _ref$preventBodyScrol = _ref.preventBodyScroll, preventBodyScroll = _ref$preventBodyScrol === void 0 ? modal : _ref$preventBodyScrol, _ref$unstable_autoFoc = _ref.unstable_autoFocusOnShow, unstable_autoFocusOnShow = _ref$unstable_autoFoc === void 0 ? true : _ref$unstable_autoFoc, _ref$unstable_autoFoc2 = _ref.unstable_autoFocusOnHide, unstable_autoFocusOnHide = _ref$unstable_autoFoc2 === void 0 ? true : _ref$unstable_autoFoc2, unstable_orphan = _ref.unstable_orphan, options = _rollupPluginBabelHelpers._objectWithoutPropertiesLoose(_ref, ["modal", "hideOnEsc", "hideOnClickOutside", "preventBodyScroll", "unstable_autoFocusOnShow", "unstable_autoFocusOnHide", "unstable_orphan"]); return _rollupPluginBabelHelpers._objectSpread2({ modal: modal, hideOnEsc: hideOnEsc, hideOnClickOutside: hideOnClickOutside, preventBodyScroll: modal && preventBodyScroll, unstable_autoFocusOnShow: unstable_autoFocusOnShow, unstable_autoFocusOnHide: unstable_autoFocusOnHide, unstable_orphan: modal && unstable_orphan }, options); }, useProps: function useProps(options, _ref2) { var htmlRef = _ref2.ref, htmlOnKeyDown = _ref2.onKeyDown, htmlOnBlur = _ref2.onBlur, htmlWrapElement = _ref2.wrapElement, tabIndex = _ref2.tabIndex, htmlProps = _rollupPluginBabelHelpers._objectWithoutPropertiesLoose(_ref2, ["ref", "onKeyDown", "onBlur", "wrapElement", "tabIndex"]); var dialog = React.useRef(null); var backdrop = React.useContext(DialogBackdropContext.DialogBackdropContext); var hasBackdrop = backdrop && backdrop === options.baseId; var disclosure = useDisclosureRef(dialog, options); var onKeyDownRef = useLiveRef.useLiveRef(htmlOnKeyDown); var onBlurRef = useLiveRef.useLiveRef(htmlOnBlur); var focusOnBlur = useFocusOnBlur(dialog, options); var _useNestedDialogs = useNestedDialogs(dialog, options), dialogs = _useNestedDialogs.dialogs, visibleModals = _useNestedDialogs.visibleModals, wrap = _useNestedDialogs.wrap; // VoiceOver/Safari accepts only one `aria-modal` container, so if there // are visible child modals, then we don't want to set aria-modal on the // parent modal (this component). var modal = options.modal && !visibleModals.length ? true : undefined; usePreventBodyScroll(dialog, options); useFocusTrap(dialog, visibleModals, options); useFocusOnChildUnmount(dialog, options); useFocusOnShow(dialog, dialogs, options); useFocusOnHide(dialog, disclosure, options); useHideOnClickOutside(dialog, disclosure, dialogs, options); useDisableHoverOutside(dialog, dialogs, options); var onKeyDown = React.useCallback(function (event) { var _onKeyDownRef$current; (_onKeyDownRef$current = onKeyDownRef.current) === null || _onKeyDownRef$current === void 0 ? void 0 : _onKeyDownRef$current.call(onKeyDownRef, event); if (event.defaultPrevented) return; if (event.key !== "Escape") return; if (!options.hideOnEsc) return; if (!options.hide) { process.env.NODE_ENV !== "production" ? reakitWarning.warning(true, "`hideOnEsc` prop is truthy, but `hide` prop wasn't provided.", "See https://reakit.io/docs/dialog", dialog.current) : void 0; return; } event.stopPropagation(); options.hide(); }, [options.hideOnEsc, options.hide]); var onBlur = React.useCallback(function (event) { var _onBlurRef$current; (_onBlurRef$current = onBlurRef.current) === null || _onBlurRef$current === void 0 ? void 0 : _onBlurRef$current.call(onBlurRef, event); focusOnBlur(event); }, [focusOnBlur]); var wrapElement = React.useCallback(function (element) { element = wrap(element); if (options.modal && !hasBackdrop) { element = /*#__PURE__*/React.createElement(Portal_Portal.Portal, null, element); } if (htmlWrapElement) { element = htmlWrapElement(element); } return ( /*#__PURE__*/ // Prevents Menu > Dialog > Menu to behave as a sub menu React.createElement(MenuContext.MenuContext.Provider, { value: null }, element) ); }, [wrap, options.modal, hasBackdrop, htmlWrapElement]); return _rollupPluginBabelHelpers._objectSpread2({ ref: useForkRef.useForkRef(dialog, htmlRef), role: "dialog", tabIndex: tabIndex != null ? tabIndex : -1, "aria-modal": modal, "data-dialog": true, onKeyDown: onKeyDown, onBlur: onBlur, wrapElement: wrapElement }, htmlProps); } }); var Dialog = createComponent.createComponent({ as: "div", useHook: useDialog, useCreateElement: function useCreateElement$1(type, props, children) { process.env.NODE_ENV !== "production" ? reakitWarning.useWarning(!props["aria-label"] && !props["aria-labelledby"], "You should provide either `aria-label` or `aria-labelledby` props.", "See https://reakit.io/docs/dialog") : void 0; return useCreateElement.useCreateElement(type, props, children); } }); exports.Dialog = Dialog; exports.useDialog = useDialog;