{"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;CAUC,GAED,kEAAkE;AAClE,2DAA2D;AAC3D,yDAAyD;AACzD,kHAAkH;;;;;;AA4B3G,SAAS,0CAAe,KAAuB;IACpD,IAAI,cAAC,UAAU,gBAAE,YAAY,iBAAE,aAAa,uBAAE,mBAAmB,EAAC,GAAG;IACrE,IAAI,QAAQ,CAAA,GAAA,mBAAK,EAAE;QACjB,eAAe;IACjB;IAEA,IAAI,qBAAC,iBAAiB,4BAAE,wBAAwB,EAAC,GAAG,CAAA,GAAA,4CAAiB;IAErE,IAAI,SAAS,CAAA,GAAA,wBAAU,EACrB,CAAC;QACC,0CAA0C;QAC1C,IAAI,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,wCAAa,EAAE,KAChD;QAGF,iFAAiF;QACjF,kFAAkF;QAClF,qDAAqD;QACrD,IACE,MAAM,OAAO,CAAC,aAAa,IAC3B,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAa,EAAE,aAAa,GACzD;YACA,MAAM,OAAO,CAAC,aAAa,GAAG;YAC9B;YAEA,IAAI,cACF,aAAa;YAGf,IAAI,qBACF,oBAAoB;QAExB;IACF,GACA;QAAC;QAAc;QAAqB;QAAO;KAAyB;IAGtE,IAAI,mBAAmB,CAAA,GAAA,+CAAoB,EAAE;IAC7C,IAAI,UAAU,CAAA,GAAA,wBAAU,EACtB,CAAC;QACC,0CAA0C;QAC1C,IAAI,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,wCAAa,EAAE,KAChD;QAGF,kGAAkG;QAClG,oDAAoD;QACpD,IAAI,cAAc,CAAA,GAAA,wCAAa,EAAE;QACjC,MAAM,gBAAgB,CAAA,GAAA,0CAAe,EAAE;QACvC,MAAM,gBAAgB,CAAA,GAAA,0CAAe,EAAE;QACvC,IAAI,CAAC,MAAM,OAAO,CAAC,aAAa,IAAI,kBAAkB,aAAa;YACjE,IAAI,eACF,cAAc;YAGhB,IAAI,qBACF,oBAAoB;YAGtB,MAAM,OAAO,CAAC,aAAa,GAAG;YAC9B,iBAAiB;YAEjB,0EAA0E;YAC1E,0EAA0E;YAC1E,4BAA4B;YAC5B,IAAI,gBAAgB,EAAE,aAAa;YACnC,kBACE,eACA,SACA,CAAA;gBACE,IAAI,cAAc,CAAA,GAAA,wCAAa,EAAE;gBACjC,IACE,MAAM,OAAO,CAAC,aAAa,IAC3B,CAAC,CAAA,GAAA,sCAAW,EAAE,eAAe,cAC7B;oBACA,IAAI,cAAc,IAAI,cAAc,WAAW,CAAE,UAAU,CAAC,QAAQ;wBAClE,eAAe;oBACjB;oBACA,CAAA,GAAA,wCAAa,EAAE,aAAa;oBAC5B,IAAI,QAAQ,CAAA,GAAA,8CAAmB,EAAc;oBAC7C,OAAO;gBACT;YACF,GACA;gBAAC,SAAS;YAAI;QAElB;IACF,GACA;QAAC;QAAe;QAAqB;QAAkB;QAAmB;KAAO;IAGnF,IAAI,YACF,OAAO;QACL,kBAAkB;YAChB,0DAA0D;YAC1D,SAAS;YACT,QAAQ;QACV;IACF;IAGF,OAAO;QACL,kBAAkB;qBAChB;oBACA;QACF;IACF;AACF","sources":["packages/react-aria/src/interactions/useFocusWithin.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\n// Portions of the code in this file are based on code from react.\n// Original licensing for the following can be found in the\n// NOTICE file in the root directory of this source tree.\n// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions\n\nimport {createSyntheticEvent, setEventTarget, useSyntheticBlurEvent} from './utils';\nimport {DOMAttributes} from '@react-types/shared';\nimport {FocusEvent, useCallback, useRef} from 'react';\nimport {getActiveElement, getEventTarget, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport {getOwnerDocument} from '../utils/domHelpers';\nimport {useGlobalListeners} from '../utils/useGlobalListeners';\n\nexport interface FocusWithinProps {\n  /** Whether the focus within events should be disabled. */\n  isDisabled?: boolean;\n  /** Handler that is called when the target element or a descendant receives focus. */\n  onFocusWithin?: (e: FocusEvent) => void;\n  /** Handler that is called when the target element and all descendants lose focus. */\n  onBlurWithin?: (e: FocusEvent) => void;\n  /** Handler that is called when the the focus within state changes. */\n  onFocusWithinChange?: (isFocusWithin: boolean) => void;\n}\n\nexport interface FocusWithinResult {\n  /** Props to spread onto the target element. */\n  focusWithinProps: DOMAttributes;\n}\n\n/**\n * Handles focus events for the target and its descendants.\n */\nexport function useFocusWithin(props: FocusWithinProps): FocusWithinResult {\n  let {isDisabled, onBlurWithin, onFocusWithin, onFocusWithinChange} = props;\n  let state = useRef({\n    isFocusWithin: false\n  });\n\n  let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners();\n\n  let onBlur = useCallback(\n    (e: FocusEvent) => {\n      // Ignore events bubbling through portals.\n      if (!nodeContains(e.currentTarget, getEventTarget(e))) {\n        return;\n      }\n\n      // We don't want to trigger onBlurWithin and then immediately onFocusWithin again\n      // when moving focus inside the element. Only trigger if the currentTarget doesn't\n      // include the relatedTarget (where focus is moving).\n      if (\n        state.current.isFocusWithin &&\n        !nodeContains(e.currentTarget as Element, e.relatedTarget as Element)\n      ) {\n        state.current.isFocusWithin = false;\n        removeAllGlobalListeners();\n\n        if (onBlurWithin) {\n          onBlurWithin(e);\n        }\n\n        if (onFocusWithinChange) {\n          onFocusWithinChange(false);\n        }\n      }\n    },\n    [onBlurWithin, onFocusWithinChange, state, removeAllGlobalListeners]\n  );\n\n  let onSyntheticFocus = useSyntheticBlurEvent(onBlur);\n  let onFocus = useCallback(\n    (e: FocusEvent) => {\n      // Ignore events bubbling through portals.\n      if (!nodeContains(e.currentTarget, getEventTarget(e))) {\n        return;\n      }\n\n      // Double check that document.activeElement actually matches e.target in case a previously chained\n      // focus handler already moved focus somewhere else.\n      let eventTarget = getEventTarget(e);\n      const ownerDocument = getOwnerDocument(eventTarget);\n      const activeElement = getActiveElement(ownerDocument);\n      if (!state.current.isFocusWithin && activeElement === eventTarget) {\n        if (onFocusWithin) {\n          onFocusWithin(e);\n        }\n\n        if (onFocusWithinChange) {\n          onFocusWithinChange(true);\n        }\n\n        state.current.isFocusWithin = true;\n        onSyntheticFocus(e);\n\n        // Browsers don't fire blur events when elements are removed from the DOM.\n        // However, if a focus event occurs outside the element we're tracking, we\n        // can manually fire onBlur.\n        let currentTarget = e.currentTarget;\n        addGlobalListener(\n          ownerDocument,\n          'focus',\n          e => {\n            let eventTarget = getEventTarget(e);\n            if (\n              state.current.isFocusWithin &&\n              !nodeContains(currentTarget, eventTarget as Element)\n            ) {\n              let nativeEvent = new ownerDocument.defaultView!.FocusEvent('blur', {\n                relatedTarget: eventTarget\n              });\n              setEventTarget(nativeEvent, currentTarget);\n              let event = createSyntheticEvent<FocusEvent>(nativeEvent);\n              onBlur(event);\n            }\n          },\n          {capture: true}\n        );\n      }\n    },\n    [onFocusWithin, onFocusWithinChange, onSyntheticFocus, addGlobalListener, onBlur]\n  );\n\n  if (isDisabled) {\n    return {\n      focusWithinProps: {\n        // These cannot be null, that would conflict in mergeProps\n        onFocus: undefined,\n        onBlur: undefined\n      }\n    };\n  }\n\n  return {\n    focusWithinProps: {\n      onFocus,\n      onBlur\n    }\n  };\n}\n"],"names":[],"version":3,"file":"useFocusWithin.cjs.map"}