UNPKG

@react-aria/interactions

Version:
106 lines (97 loc) 4.91 kB
var $625cf83917e112ad$exports = require("./utils.main.js"); var $kDAhS$react = require("react"); var $kDAhS$reactariautils = require("@react-aria/utils"); function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } $parcel$export(module.exports, "useFocusWithin", () => $d16842bbd0359d1b$export$420e68273165f4ec); /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ // Portions of the code in this file are based on code from react. // Original licensing for the following can be found in the // NOTICE file in the root directory of this source tree. // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions function $d16842bbd0359d1b$export$420e68273165f4ec(props) { let { isDisabled: isDisabled, onBlurWithin: onBlurWithin, onFocusWithin: onFocusWithin, onFocusWithinChange: onFocusWithinChange } = props; let state = (0, $kDAhS$react.useRef)({ isFocusWithin: false }); let { addGlobalListener: addGlobalListener, removeAllGlobalListeners: removeAllGlobalListeners } = (0, $kDAhS$reactariautils.useGlobalListeners)(); let onBlur = (0, $kDAhS$react.useCallback)((e)=>{ // Ignore events bubbling through portals. if (!e.currentTarget.contains(e.target)) return; // We don't want to trigger onBlurWithin and then immediately onFocusWithin again // when moving focus inside the element. Only trigger if the currentTarget doesn't // include the relatedTarget (where focus is moving). if (state.current.isFocusWithin && !e.currentTarget.contains(e.relatedTarget)) { state.current.isFocusWithin = false; removeAllGlobalListeners(); if (onBlurWithin) onBlurWithin(e); if (onFocusWithinChange) onFocusWithinChange(false); } }, [ onBlurWithin, onFocusWithinChange, state, removeAllGlobalListeners ]); let onSyntheticFocus = (0, $625cf83917e112ad$exports.useSyntheticBlurEvent)(onBlur); let onFocus = (0, $kDAhS$react.useCallback)((e)=>{ // Ignore events bubbling through portals. if (!e.currentTarget.contains(e.target)) return; // Double check that document.activeElement actually matches e.target in case a previously chained // focus handler already moved focus somewhere else. const ownerDocument = (0, $kDAhS$reactariautils.getOwnerDocument)(e.target); const activeElement = (0, $kDAhS$reactariautils.getActiveElement)(ownerDocument); if (!state.current.isFocusWithin && activeElement === (0, $kDAhS$reactariautils.getEventTarget)(e.nativeEvent)) { if (onFocusWithin) onFocusWithin(e); if (onFocusWithinChange) onFocusWithinChange(true); state.current.isFocusWithin = true; onSyntheticFocus(e); // Browsers don't fire blur events when elements are removed from the DOM. // However, if a focus event occurs outside the element we're tracking, we // can manually fire onBlur. let currentTarget = e.currentTarget; addGlobalListener(ownerDocument, 'focus', (e)=>{ if (state.current.isFocusWithin && !(0, $kDAhS$reactariautils.nodeContains)(currentTarget, e.target)) { let nativeEvent = new ownerDocument.defaultView.FocusEvent('blur', { relatedTarget: e.target }); (0, $625cf83917e112ad$exports.setEventTarget)(nativeEvent, currentTarget); let event = (0, $625cf83917e112ad$exports.createSyntheticEvent)(nativeEvent); onBlur(event); } }, { capture: true }); } }, [ onFocusWithin, onFocusWithinChange, onSyntheticFocus, addGlobalListener, onBlur ]); if (isDisabled) return { focusWithinProps: { // These cannot be null, that would conflict in mergeProps onFocus: undefined, onBlur: undefined } }; return { focusWithinProps: { onFocus: onFocus, onBlur: onBlur } }; } //# sourceMappingURL=useFocusWithin.main.js.map