{"mappings":";;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;AA8BM,SAAS,0CAAU,KAAsB,EAAE,GAAuC;IACvF,IAAI,QACF,OAAO,UACR,GAAG;IACJ,IAAI,UAA8B,CAAA,GAAA,mCAAQ;IAC1C,UAAU,KAAK,CAAC,aAAa,GAAG,YAAY;IAE5C,IAAI,eAAe,CAAA,GAAA,mBAAK,EAAE;IAE1B,+EAA+E;IAC/E,CAAA,GAAA,sBAAQ,EAAE;QACR,IAAI,IAAI,OAAO,IAAI,CAAC,CAAA,GAAA,uCAAY,EAAE,IAAI,OAAO,GAAG;YAC9C,CAAA,GAAA,qCAAU,EAAE,IAAI,OAAO;YAEvB,iEAAiE;YACjE,qEAAqE;YACrE,mEAAmE;YACnE,IAAI,UAAU,WAAW;gBACvB,2EAA2E;gBAC3E,IAAI,CAAA,GAAA,0CAAe,QAAQ,IAAI,OAAO,IAAI,CAAA,GAAA,0CAAe,QAAQ,SAAS,IAAI,EAAE;oBAC9E,aAAa,OAAO,GAAG;oBACvB,IAAI,IAAI,OAAO,EAAE;wBACf,IAAI,OAAO,CAAC,IAAI;wBAChB,CAAA,GAAA,qCAAU,EAAE,IAAI,OAAO;oBACzB;oBACA,aAAa,OAAO,GAAG;gBACzB;YACF,GAAG;YAEH,OAAO;gBACL,aAAa;YACf;QACF;IACF,GAAG;QAAC;KAAI;IAER,CAAA,GAAA,gDAAqB;IAErB,0DAA0D;IAC1D,2EAA2E;IAC3E,sEAAsE;IACtE,4CAA4C;IAC5C,uEAAuE;IACvE,sEAAsE;IACtE,IAAI,YAAY,CAAA,GAAA,mBAAK,EAAE;IACvB,CAAA,GAAA,sBAAQ,EAAE;QACR,IAAI,QAAQ,GAAG,CAAC,QAAQ,KAAK,gBAAgB,CAAC,UAAU,OAAO,IAAI,IAAI,OAAO,EAAE;YAC9E,IAAI,KAAK,IAAI,OAAO;YACpB,IAAI,eAAe,GAAG,YAAY,CAAC;YACnC,IAAI,oBAAoB,GAAG,YAAY,CAAC;YACxC,IAAI,CAAC,gBAAgB,CAAC,mBAAmB;gBACvC,QAAQ,IAAI,CACV;gBAGF,UAAU,OAAO,GAAG;YACtB;QACF;IACF;IAEA,sGAAsG;IACtG,qFAAqF;IACrF,sDAAsD;IACtD,qGAAqG;IACrG,gDAAgD;IAChD,OAAO;QACL,aAAa;YACX,GAAG,CAAA,GAAA,wCAAa,EAAE,OAAO;gBAAC,WAAW;YAAI,EAAE;kBAC3C;YACA,UAAU;YACV,mBAAmB,KAAK,CAAC,kBAAkB,IAAI;YAC/C,gEAAgE;YAChE,iEAAiE;YACjE,0DAA0D;YAC1D,QAAQ,CAAA;gBACN,IAAI,aAAa,OAAO,EACtB,EAAE,eAAe;YAErB;QACF;QACA,YAAY;YACV,IAAI;QACN;IACF;AACF","sources":["packages/react-aria/src/dialog/useDialog.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaLabelingProps, DOMAttributes, DOMProps, FocusableElement, RefObject} from '@react-types/shared';\nimport {filterDOMProps} from '../utils/filterDOMProps';\nimport {focusSafely} from '../interactions/focusSafely';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useEffect, useRef} from 'react';\nimport {useOverlayFocusContain} from '../overlays/Overlay';\nimport {useSlotId} from '../utils/useId';\n\nexport interface AriaDialogProps extends DOMProps, AriaLabelingProps {\n  /**\n   * The accessibility role for the dialog.\n   * @default 'dialog'\n   */\n  role?: 'dialog' | 'alertdialog'\n}\n\nexport interface DialogAria {\n  /** Props for the dialog container element. */\n  dialogProps: DOMAttributes,\n\n  /** Props for the dialog title element. */\n  titleProps: DOMAttributes\n}\n\n/**\n * Provides the behavior and accessibility implementation for a dialog component.\n * A dialog is an overlay shown above other content in an application.\n */\nexport function useDialog(props: AriaDialogProps, ref: RefObject<FocusableElement | null>): DialogAria {\n  let {\n    role = 'dialog'\n  } = props;\n  let titleId: string | undefined = useSlotId();\n  titleId = props['aria-label'] ? undefined : titleId;\n\n  let isRefocusing = useRef(false);\n\n  // Focus the dialog itself on mount, unless a child element is already focused.\n  useEffect(() => {\n    if (ref.current && !isFocusWithin(ref.current)) {\n      focusSafely(ref.current);\n\n      // Safari on iOS does not move the VoiceOver cursor to the dialog\n      // or announce that it has opened until it has rendered. A workaround\n      // is to wait for half a second, then blur and re-focus the dialog.\n      let timeout = setTimeout(() => {\n        // Check that the dialog is still focused, or focused was lost to the body.\n        if (getActiveElement() === ref.current || getActiveElement() === document.body) {\n          isRefocusing.current = true;\n          if (ref.current) {\n            ref.current.blur();\n            focusSafely(ref.current);\n          }\n          isRefocusing.current = false;\n        }\n      }, 500);\n\n      return () => {\n        clearTimeout(timeout);\n      };\n    }\n  }, [ref]);\n\n  useOverlayFocusContain();\n\n  // Warn in dev mode if the dialog has no accessible title.\n  // This catches a common mistake where useDialog and useOverlayTriggerState\n  // are used in the same component, causing the title element to not be\n  // in the DOM when useSlotId queries for it.\n  // Check the DOM element directly since aria-labelledby may be added by\n  // wrapper components (e.g. RAC Dialog uses trigger ID as a fallback).\n  let hasWarned = useRef(false);\n  useEffect(() => {\n    if (process.env.NODE_ENV !== 'production' && !hasWarned.current && ref.current) {\n      let el = ref.current;\n      let hasAriaLabel = el.hasAttribute('aria-label');\n      let hasAriaLabelledby = el.hasAttribute('aria-labelledby');\n      if (!hasAriaLabel && !hasAriaLabelledby) {\n        console.warn(\n          'A dialog must have a title for accessibility. ' +\n          'Either provide an aria-label or aria-labelledby prop, or render a heading element inside the dialog.'\n        );\n        hasWarned.current = true;\n      }\n    }\n  });\n\n  // We do not use aria-modal due to a Safari bug which forces the first focusable element to be focused\n  // on mount when inside an iframe, no matter which element we programmatically focus.\n  // See https://bugs.webkit.org/show_bug.cgi?id=211934.\n  // useModal sets aria-hidden on all elements outside the dialog, so the dialog will behave as a modal\n  // even without aria-modal on the dialog itself.\n  return {\n    dialogProps: {\n      ...filterDOMProps(props, {labelable: true}),\n      role,\n      tabIndex: -1,\n      'aria-labelledby': props['aria-labelledby'] || titleId,\n      // Prevent blur events from reaching useOverlay, which may cause\n      // popovers to close. Since focus is contained within the dialog,\n      // we don't want this to occur due to the above useEffect.\n      onBlur: e => {\n        if (isRefocusing.current) {\n          e.stopPropagation();\n        }\n      }\n    },\n    titleProps: {\n      id: titleId\n    }\n  };\n}\n"],"names":[],"version":3,"file":"useDialog.cjs.map"}