@react-aria/overlays 3.25.0 → 3.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Overlay.main.js +1 -1
- package/dist/Overlay.main.js.map +1 -1
- package/dist/Overlay.mjs +1 -1
- package/dist/Overlay.module.js +1 -1
- package/dist/Overlay.module.js.map +1 -1
- package/dist/ariaHideOutside.main.js +12 -0
- package/dist/ariaHideOutside.main.js.map +1 -1
- package/dist/ariaHideOutside.mjs +12 -1
- package/dist/ariaHideOutside.module.js +12 -1
- package/dist/ariaHideOutside.module.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/useOverlay.main.js +7 -5
- package/dist/useOverlay.main.js.map +1 -1
- package/dist/useOverlay.mjs +7 -5
- package/dist/useOverlay.module.js +7 -5
- package/dist/useOverlay.module.js.map +1 -1
- package/dist/usePopover.main.js +15 -10
- package/dist/usePopover.main.js.map +1 -1
- package/dist/usePopover.mjs +16 -11
- package/dist/usePopover.module.js +16 -11
- package/dist/usePopover.module.js.map +1 -1
- package/package.json +11 -11
- package/src/Overlay.tsx +5 -1
- package/src/ariaHideOutside.ts +14 -0
- package/src/useOverlay.ts +7 -8
- package/src/usePopover.ts +21 -9
package/dist/Overlay.main.js
CHANGED
|
@@ -52,7 +52,7 @@ function $745edbb83ab4296f$export$c6fdb837b070b4ff(props) {
|
|
|
52
52
|
let contents = props.children;
|
|
53
53
|
if (!props.disableFocusManagement) contents = /*#__PURE__*/ (0, ($parcel$interopDefault($kxJqT$react))).createElement((0, $kxJqT$reactariafocus.FocusScope), {
|
|
54
54
|
restoreFocus: true,
|
|
55
|
-
contain: contain && !isExiting
|
|
55
|
+
contain: (props.shouldContainFocus || contain) && !isExiting
|
|
56
56
|
}, contents);
|
|
57
57
|
contents = /*#__PURE__*/ (0, ($parcel$interopDefault($kxJqT$react))).createElement($745edbb83ab4296f$export$a2200b96afd16271.Provider, {
|
|
58
58
|
value: contextValue
|
package/dist/Overlay.main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;AAmCM,MAAM,0DAAiB,CAAA,GAAA,sCAAI,EAAE,aAAa,CAAuF;AAMjI,SAAS,0CAAQ,KAAmB;IACzC,IAAI,QAAQ,CAAA,GAAA,4BAAO;IACnB,IAAI,mBAAC,kBAAkB,QAAQ,OAAO,SAAS,IAAI,aAAE,SAAS,EAAC,GAAG;IAClE,IAAI,CAAC,SAAS,WAAW,GAAG,CAAA,GAAA,qBAAO,EAAE;IACrC,IAAI,eAAe,CAAA,GAAA,oBAAM,EAAE,IAAO,CAAA;qBAAC;wBAAS;QAAU,CAAA,GAAI;QAAC;QAAS;KAAW;IAE/E,IAAI,gBAAC,YAAY,EAAC,GAAG,CAAA,GAAA,mDAAwB;IAC7C,IAAK,CAAC,MAAM,eAAe,IAAI,cAC7B,kBAAkB;IAGpB,IAAI,CAAC,iBACH,OAAO;IAGT,IAAI,WAAW,MAAM,QAAQ;IAC7B,IAAI,CAAC,MAAM,sBAAsB,EAC/B,yBACE,0DAAC,CAAA,GAAA,gCAAS;QAAE,cAAA;QAAa,SAAS,AAAC,CAAA,MAAM,kBAAkB,IAAI,OAAM,KAAM,CAAC;OACzE;IAKP,yBACE,0DAAC,0CAAe,QAAQ;QAAC,OAAO;qBAC9B,0DAAC,CAAA,GAAA,gDAAkB,SAChB;IAKP,qBAAO,CAAA,GAAA,yCAAO,EAAE,YAAY,CAAC,UAAU;AACzC;AAGO,SAAS;IACd,IAAI,MAAM,CAAA,GAAA,uBAAS,EAAE;IACrB,IAAI,aAAa,gBAAA,0BAAA,IAAK,UAAU;IAChC,CAAA,GAAA,qCAAc,EAAE;QACd,uBAAA,iCAAA,WAAa;IACf,GAAG;QAAC;KAAW;AACjB","sources":["packages/@react-aria/overlays/src/Overlay.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 {ClearPressResponder} from '@react-aria/interactions';\nimport {FocusScope} from '@react-aria/focus';\nimport React, {ReactNode, useContext, useMemo, useState} from 'react';\nimport ReactDOM from 'react-dom';\nimport {useIsSSR} from '@react-aria/ssr';\nimport {useLayoutEffect} from '@react-aria/utils';\nimport {useUNSTABLE_PortalContext} from './PortalProvider';\n\nexport interface OverlayProps {\n /**\n * The container element in which the overlay portal will be placed.\n * @default document.body\n */\n portalContainer?: Element,\n /** The overlay to render in the portal. */\n children: ReactNode,\n /**\n * Disables default focus management for the overlay, including containment and restoration.\n * This option should be used very carefully. When focus management is disabled, you must\n * implement focus containment and restoration to ensure the overlay is keyboard accessible.\n */\n disableFocusManagement?: boolean,\n /**\n * Whether to contain focus within the overlay.\n */\n shouldContainFocus?: boolean,\n /**\n * Whether the overlay is currently performing an exit animation. When true,\n * focus is allowed to move outside.\n */\n isExiting?: boolean\n}\n\nexport const OverlayContext = React.createContext<{contain: boolean, setContain: React.Dispatch<React.SetStateAction<boolean>>} | null>(null);\n\n/**\n * A container which renders an overlay such as a popover or modal in a portal,\n * and provides a focus scope for the child elements.\n */\nexport function Overlay(props: OverlayProps) {\n let isSSR = useIsSSR();\n let {portalContainer = isSSR ? null : document.body, isExiting} = props;\n let [contain, setContain] = useState(false);\n let contextValue = useMemo(() => ({contain, setContain}), [contain, setContain]);\n\n let {getContainer} = useUNSTABLE_PortalContext();\n if (!props.portalContainer && getContainer) {\n portalContainer = getContainer();\n }\n\n if (!portalContainer) {\n return null;\n }\n\n let contents = props.children;\n if (!props.disableFocusManagement) {\n contents = (\n <FocusScope restoreFocus contain={(props.shouldContainFocus || contain) && !isExiting}>\n {contents}\n </FocusScope>\n );\n }\n\n contents = (\n <OverlayContext.Provider value={contextValue}>\n <ClearPressResponder>\n {contents}\n </ClearPressResponder>\n </OverlayContext.Provider>\n );\n\n return ReactDOM.createPortal(contents, portalContainer);\n}\n\n/** @private */\nexport function useOverlayFocusContain() {\n let ctx = useContext(OverlayContext);\n let setContain = ctx?.setContain;\n useLayoutEffect(() => {\n setContain?.(true);\n }, [setContain]);\n}\n"],"names":[],"version":3,"file":"Overlay.main.js.map"}
|
package/dist/Overlay.mjs
CHANGED
|
@@ -41,7 +41,7 @@ function $337b884510726a0d$export$c6fdb837b070b4ff(props) {
|
|
|
41
41
|
let contents = props.children;
|
|
42
42
|
if (!props.disableFocusManagement) contents = /*#__PURE__*/ (0, $1CM7W$react).createElement((0, $1CM7W$FocusScope), {
|
|
43
43
|
restoreFocus: true,
|
|
44
|
-
contain: contain && !isExiting
|
|
44
|
+
contain: (props.shouldContainFocus || contain) && !isExiting
|
|
45
45
|
}, contents);
|
|
46
46
|
contents = /*#__PURE__*/ (0, $1CM7W$react).createElement($337b884510726a0d$export$a2200b96afd16271.Provider, {
|
|
47
47
|
value: contextValue
|
package/dist/Overlay.module.js
CHANGED
|
@@ -41,7 +41,7 @@ function $337b884510726a0d$export$c6fdb837b070b4ff(props) {
|
|
|
41
41
|
let contents = props.children;
|
|
42
42
|
if (!props.disableFocusManagement) contents = /*#__PURE__*/ (0, $1CM7W$react).createElement((0, $1CM7W$FocusScope), {
|
|
43
43
|
restoreFocus: true,
|
|
44
|
-
contain: contain && !isExiting
|
|
44
|
+
contain: (props.shouldContainFocus || contain) && !isExiting
|
|
45
45
|
}, contents);
|
|
46
46
|
contents = /*#__PURE__*/ (0, $1CM7W$react).createElement($337b884510726a0d$export$a2200b96afd16271.Provider, {
|
|
47
47
|
value: contextValue
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;
|
|
1
|
+
{"mappings":";;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;AAmCM,MAAM,0DAAiB,CAAA,GAAA,YAAI,EAAE,aAAa,CAAuF;AAMjI,SAAS,0CAAQ,KAAmB;IACzC,IAAI,QAAQ,CAAA,GAAA,eAAO;IACnB,IAAI,mBAAC,kBAAkB,QAAQ,OAAO,SAAS,IAAI,aAAE,SAAS,EAAC,GAAG;IAClE,IAAI,CAAC,SAAS,WAAW,GAAG,CAAA,GAAA,eAAO,EAAE;IACrC,IAAI,eAAe,CAAA,GAAA,cAAM,EAAE,IAAO,CAAA;qBAAC;wBAAS;QAAU,CAAA,GAAI;QAAC;QAAS;KAAW;IAE/E,IAAI,gBAAC,YAAY,EAAC,GAAG,CAAA,GAAA,yCAAwB;IAC7C,IAAK,CAAC,MAAM,eAAe,IAAI,cAC7B,kBAAkB;IAGpB,IAAI,CAAC,iBACH,OAAO;IAGT,IAAI,WAAW,MAAM,QAAQ;IAC7B,IAAI,CAAC,MAAM,sBAAsB,EAC/B,yBACE,gCAAC,CAAA,GAAA,iBAAS;QAAE,cAAA;QAAa,SAAS,AAAC,CAAA,MAAM,kBAAkB,IAAI,OAAM,KAAM,CAAC;OACzE;IAKP,yBACE,gCAAC,0CAAe,QAAQ;QAAC,OAAO;qBAC9B,gCAAC,CAAA,GAAA,0BAAkB,SAChB;IAKP,qBAAO,CAAA,GAAA,eAAO,EAAE,YAAY,CAAC,UAAU;AACzC;AAGO,SAAS;IACd,IAAI,MAAM,CAAA,GAAA,iBAAS,EAAE;IACrB,IAAI,aAAa,gBAAA,0BAAA,IAAK,UAAU;IAChC,CAAA,GAAA,sBAAc,EAAE;QACd,uBAAA,iCAAA,WAAa;IACf,GAAG;QAAC;KAAW;AACjB","sources":["packages/@react-aria/overlays/src/Overlay.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 {ClearPressResponder} from '@react-aria/interactions';\nimport {FocusScope} from '@react-aria/focus';\nimport React, {ReactNode, useContext, useMemo, useState} from 'react';\nimport ReactDOM from 'react-dom';\nimport {useIsSSR} from '@react-aria/ssr';\nimport {useLayoutEffect} from '@react-aria/utils';\nimport {useUNSTABLE_PortalContext} from './PortalProvider';\n\nexport interface OverlayProps {\n /**\n * The container element in which the overlay portal will be placed.\n * @default document.body\n */\n portalContainer?: Element,\n /** The overlay to render in the portal. */\n children: ReactNode,\n /**\n * Disables default focus management for the overlay, including containment and restoration.\n * This option should be used very carefully. When focus management is disabled, you must\n * implement focus containment and restoration to ensure the overlay is keyboard accessible.\n */\n disableFocusManagement?: boolean,\n /**\n * Whether to contain focus within the overlay.\n */\n shouldContainFocus?: boolean,\n /**\n * Whether the overlay is currently performing an exit animation. When true,\n * focus is allowed to move outside.\n */\n isExiting?: boolean\n}\n\nexport const OverlayContext = React.createContext<{contain: boolean, setContain: React.Dispatch<React.SetStateAction<boolean>>} | null>(null);\n\n/**\n * A container which renders an overlay such as a popover or modal in a portal,\n * and provides a focus scope for the child elements.\n */\nexport function Overlay(props: OverlayProps) {\n let isSSR = useIsSSR();\n let {portalContainer = isSSR ? null : document.body, isExiting} = props;\n let [contain, setContain] = useState(false);\n let contextValue = useMemo(() => ({contain, setContain}), [contain, setContain]);\n\n let {getContainer} = useUNSTABLE_PortalContext();\n if (!props.portalContainer && getContainer) {\n portalContainer = getContainer();\n }\n\n if (!portalContainer) {\n return null;\n }\n\n let contents = props.children;\n if (!props.disableFocusManagement) {\n contents = (\n <FocusScope restoreFocus contain={(props.shouldContainFocus || contain) && !isExiting}>\n {contents}\n </FocusScope>\n );\n }\n\n contents = (\n <OverlayContext.Provider value={contextValue}>\n <ClearPressResponder>\n {contents}\n </ClearPressResponder>\n </OverlayContext.Provider>\n );\n\n return ReactDOM.createPortal(contents, portalContainer);\n}\n\n/** @private */\nexport function useOverlayFocusContain() {\n let ctx = useContext(OverlayContext);\n let setContain = ctx?.setContain;\n useLayoutEffect(() => {\n setContain?.(true);\n }, [setContain]);\n}\n"],"names":[],"version":3,"file":"Overlay.module.js.map"}
|
|
@@ -4,6 +4,7 @@ function $parcel$export(e, n, v, s) {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
$parcel$export(module.exports, "ariaHideOutside", () => $08ef1685902b6011$export$1c3ebcada18427bf);
|
|
7
|
+
$parcel$export(module.exports, "keepVisible", () => $08ef1685902b6011$export$1020fa7f77e17884);
|
|
7
8
|
/*
|
|
8
9
|
* Copyright 2020 Adobe. All rights reserved.
|
|
9
10
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -89,6 +90,8 @@ function $08ef1685902b6011$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
89
90
|
subtree: true
|
|
90
91
|
});
|
|
91
92
|
let observerWrapper = {
|
|
93
|
+
visibleNodes: visibleNodes,
|
|
94
|
+
hiddenNodes: hiddenNodes,
|
|
92
95
|
observe () {
|
|
93
96
|
observer.observe(root, {
|
|
94
97
|
childList: true,
|
|
@@ -117,6 +120,15 @@ function $08ef1685902b6011$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
117
120
|
} else $08ef1685902b6011$var$observerStack.splice($08ef1685902b6011$var$observerStack.indexOf(observerWrapper), 1);
|
|
118
121
|
};
|
|
119
122
|
}
|
|
123
|
+
function $08ef1685902b6011$export$1020fa7f77e17884(element) {
|
|
124
|
+
let observer = $08ef1685902b6011$var$observerStack[$08ef1685902b6011$var$observerStack.length - 1];
|
|
125
|
+
if (observer && !observer.visibleNodes.has(element)) {
|
|
126
|
+
observer.visibleNodes.add(element);
|
|
127
|
+
return ()=>{
|
|
128
|
+
observer.visibleNodes.delete(element);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
120
132
|
|
|
121
133
|
|
|
122
134
|
//# sourceMappingURL=ariaHideOutside.main.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/overlays/src/ariaHideOutside.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// Keeps a ref count of all hidden elements. Added to when hiding an element, and\n// subtracted from when showing it again. When it reaches zero, aria-hidden is removed.\nlet refCountMap = new WeakMap<Element, number>();\ninterface ObserverWrapper {\n visibleNodes: Set<Element>,\n hiddenNodes: Set<Element>,\n observe: () => void,\n disconnect: () => void\n}\nlet observerStack: Array<ObserverWrapper> = [];\n\n/**\n * Hides all elements in the DOM outside the given targets from screen readers using aria-hidden,\n * and returns a function to revert these changes. In addition, changes to the DOM are watched\n * and new elements outside the targets are automatically hidden.\n * @param targets - The elements that should remain visible.\n * @param root - Nothing will be hidden above this element.\n * @returns - A function to restore all hidden elements.\n */\nexport function ariaHideOutside(targets: Element[], root = document.body) {\n let visibleNodes = new Set<Element>(targets);\n let hiddenNodes = new Set<Element>();\n\n let walk = (root: Element) => {\n // Keep live announcer and top layer elements (e.g. toasts) visible.\n for (let element of root.querySelectorAll('[data-live-announcer], [data-react-aria-top-layer]')) {\n visibleNodes.add(element);\n }\n\n let acceptNode = (node: Element) => {\n // Skip this node and its children if it is one of the target nodes, or a live announcer.\n // Also skip children of already hidden nodes, as aria-hidden is recursive. An exception is\n // made for elements with role=\"row\" since VoiceOver on iOS has issues hiding elements with role=\"row\".\n // For that case we want to hide the cells inside as well (https://bugs.webkit.org/show_bug.cgi?id=222623).\n if (\n visibleNodes.has(node) ||\n (node.parentElement && hiddenNodes.has(node.parentElement) && node.parentElement.getAttribute('role') !== 'row')\n ) {\n return NodeFilter.FILTER_REJECT;\n }\n\n // Skip this node but continue to children if one of the targets is inside the node.\n for (let target of visibleNodes) {\n if (node.contains(target)) {\n return NodeFilter.FILTER_SKIP;\n }\n }\n\n return NodeFilter.FILTER_ACCEPT;\n };\n\n let walker = document.createTreeWalker(\n root,\n NodeFilter.SHOW_ELEMENT,\n {acceptNode}\n );\n\n // TreeWalker does not include the root.\n let acceptRoot = acceptNode(root);\n if (acceptRoot === NodeFilter.FILTER_ACCEPT) {\n hide(root);\n }\n\n if (acceptRoot !== NodeFilter.FILTER_REJECT) {\n let node = walker.nextNode() as Element;\n while (node != null) {\n hide(node);\n node = walker.nextNode() as Element;\n }\n }\n };\n\n let hide = (node: Element) => {\n let refCount = refCountMap.get(node) ?? 0;\n\n // If already aria-hidden, and the ref count is zero, then this element\n // was already hidden and there's nothing for us to do.\n if (node.getAttribute('aria-hidden') === 'true' && refCount === 0) {\n return;\n }\n\n if (refCount === 0) {\n node.setAttribute('aria-hidden', 'true');\n }\n\n hiddenNodes.add(node);\n refCountMap.set(node, refCount + 1);\n };\n\n // If there is already a MutationObserver listening from a previous call,\n // disconnect it so the new on takes over.\n if (observerStack.length) {\n observerStack[observerStack.length - 1].disconnect();\n }\n\n walk(root);\n\n let observer = new MutationObserver(changes => {\n for (let change of changes) {\n if (change.type !== 'childList' || change.addedNodes.length === 0) {\n continue;\n }\n\n // If the parent element of the added nodes is not within one of the targets,\n // and not already inside a hidden node, hide all of the new children.\n if (![...visibleNodes, ...hiddenNodes].some(node => node.contains(change.target))) {\n for (let node of change.removedNodes) {\n if (node instanceof Element) {\n visibleNodes.delete(node);\n hiddenNodes.delete(node);\n }\n }\n\n for (let node of change.addedNodes) {\n if (\n (node instanceof HTMLElement || node instanceof SVGElement) &&\n (node.dataset.liveAnnouncer === 'true' || node.dataset.reactAriaTopLayer === 'true')\n ) {\n visibleNodes.add(node);\n } else if (node instanceof Element) {\n walk(node);\n }\n }\n }\n }\n });\n\n observer.observe(root, {childList: true, subtree: true});\n\n let observerWrapper: ObserverWrapper = {\n visibleNodes,\n hiddenNodes,\n observe() {\n observer.observe(root, {childList: true, subtree: true});\n },\n disconnect() {\n observer.disconnect();\n }\n };\n\n observerStack.push(observerWrapper);\n\n return () => {\n observer.disconnect();\n\n for (let node of hiddenNodes) {\n let count = refCountMap.get(node);\n if (count == null) {\n continue;\n }\n if (count === 1) {\n node.removeAttribute('aria-hidden');\n refCountMap.delete(node);\n } else {\n refCountMap.set(node, count - 1);\n }\n }\n\n // Remove this observer from the stack, and start the previous one.\n if (observerWrapper === observerStack[observerStack.length - 1]) {\n observerStack.pop();\n if (observerStack.length) {\n observerStack[observerStack.length - 1].observe();\n }\n } else {\n observerStack.splice(observerStack.indexOf(observerWrapper), 1);\n }\n };\n}\n\nexport function keepVisible(element: Element) {\n let observer = observerStack[observerStack.length - 1];\n if (observer && !observer.visibleNodes.has(element)) {\n observer.visibleNodes.add(element);\n return () => {\n observer.visibleNodes.delete(element);\n };\n }\n}\n"],"names":[],"version":3,"file":"ariaHideOutside.main.js.map"}
|
package/dist/ariaHideOutside.mjs
CHANGED
|
@@ -83,6 +83,8 @@ function $5e3802645cc19319$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
83
83
|
subtree: true
|
|
84
84
|
});
|
|
85
85
|
let observerWrapper = {
|
|
86
|
+
visibleNodes: visibleNodes,
|
|
87
|
+
hiddenNodes: hiddenNodes,
|
|
86
88
|
observe () {
|
|
87
89
|
observer.observe(root, {
|
|
88
90
|
childList: true,
|
|
@@ -111,7 +113,16 @@ function $5e3802645cc19319$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
111
113
|
} else $5e3802645cc19319$var$observerStack.splice($5e3802645cc19319$var$observerStack.indexOf(observerWrapper), 1);
|
|
112
114
|
};
|
|
113
115
|
}
|
|
116
|
+
function $5e3802645cc19319$export$1020fa7f77e17884(element) {
|
|
117
|
+
let observer = $5e3802645cc19319$var$observerStack[$5e3802645cc19319$var$observerStack.length - 1];
|
|
118
|
+
if (observer && !observer.visibleNodes.has(element)) {
|
|
119
|
+
observer.visibleNodes.add(element);
|
|
120
|
+
return ()=>{
|
|
121
|
+
observer.visibleNodes.delete(element);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
114
125
|
|
|
115
126
|
|
|
116
|
-
export {$5e3802645cc19319$export$1c3ebcada18427bf as ariaHideOutside};
|
|
127
|
+
export {$5e3802645cc19319$export$1c3ebcada18427bf as ariaHideOutside, $5e3802645cc19319$export$1020fa7f77e17884 as keepVisible};
|
|
117
128
|
//# sourceMappingURL=ariaHideOutside.module.js.map
|
|
@@ -83,6 +83,8 @@ function $5e3802645cc19319$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
83
83
|
subtree: true
|
|
84
84
|
});
|
|
85
85
|
let observerWrapper = {
|
|
86
|
+
visibleNodes: visibleNodes,
|
|
87
|
+
hiddenNodes: hiddenNodes,
|
|
86
88
|
observe () {
|
|
87
89
|
observer.observe(root, {
|
|
88
90
|
childList: true,
|
|
@@ -111,7 +113,16 @@ function $5e3802645cc19319$export$1c3ebcada18427bf(targets, root = document.body
|
|
|
111
113
|
} else $5e3802645cc19319$var$observerStack.splice($5e3802645cc19319$var$observerStack.indexOf(observerWrapper), 1);
|
|
112
114
|
};
|
|
113
115
|
}
|
|
116
|
+
function $5e3802645cc19319$export$1020fa7f77e17884(element) {
|
|
117
|
+
let observer = $5e3802645cc19319$var$observerStack[$5e3802645cc19319$var$observerStack.length - 1];
|
|
118
|
+
if (observer && !observer.visibleNodes.has(element)) {
|
|
119
|
+
observer.visibleNodes.add(element);
|
|
120
|
+
return ()=>{
|
|
121
|
+
observer.visibleNodes.delete(element);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
114
125
|
|
|
115
126
|
|
|
116
|
-
export {$5e3802645cc19319$export$1c3ebcada18427bf as ariaHideOutside};
|
|
127
|
+
export {$5e3802645cc19319$export$1c3ebcada18427bf as ariaHideOutside, $5e3802645cc19319$export$1020fa7f77e17884 as keepVisible};
|
|
117
128
|
//# sourceMappingURL=ariaHideOutside.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA;;;;;;;;;;CAUC,GAED,iFAAiF;AACjF,uFAAuF;AACvF,IAAI,oCAAc,IAAI;
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/overlays/src/ariaHideOutside.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// Keeps a ref count of all hidden elements. Added to when hiding an element, and\n// subtracted from when showing it again. When it reaches zero, aria-hidden is removed.\nlet refCountMap = new WeakMap<Element, number>();\ninterface ObserverWrapper {\n visibleNodes: Set<Element>,\n hiddenNodes: Set<Element>,\n observe: () => void,\n disconnect: () => void\n}\nlet observerStack: Array<ObserverWrapper> = [];\n\n/**\n * Hides all elements in the DOM outside the given targets from screen readers using aria-hidden,\n * and returns a function to revert these changes. In addition, changes to the DOM are watched\n * and new elements outside the targets are automatically hidden.\n * @param targets - The elements that should remain visible.\n * @param root - Nothing will be hidden above this element.\n * @returns - A function to restore all hidden elements.\n */\nexport function ariaHideOutside(targets: Element[], root = document.body) {\n let visibleNodes = new Set<Element>(targets);\n let hiddenNodes = new Set<Element>();\n\n let walk = (root: Element) => {\n // Keep live announcer and top layer elements (e.g. toasts) visible.\n for (let element of root.querySelectorAll('[data-live-announcer], [data-react-aria-top-layer]')) {\n visibleNodes.add(element);\n }\n\n let acceptNode = (node: Element) => {\n // Skip this node and its children if it is one of the target nodes, or a live announcer.\n // Also skip children of already hidden nodes, as aria-hidden is recursive. An exception is\n // made for elements with role=\"row\" since VoiceOver on iOS has issues hiding elements with role=\"row\".\n // For that case we want to hide the cells inside as well (https://bugs.webkit.org/show_bug.cgi?id=222623).\n if (\n visibleNodes.has(node) ||\n (node.parentElement && hiddenNodes.has(node.parentElement) && node.parentElement.getAttribute('role') !== 'row')\n ) {\n return NodeFilter.FILTER_REJECT;\n }\n\n // Skip this node but continue to children if one of the targets is inside the node.\n for (let target of visibleNodes) {\n if (node.contains(target)) {\n return NodeFilter.FILTER_SKIP;\n }\n }\n\n return NodeFilter.FILTER_ACCEPT;\n };\n\n let walker = document.createTreeWalker(\n root,\n NodeFilter.SHOW_ELEMENT,\n {acceptNode}\n );\n\n // TreeWalker does not include the root.\n let acceptRoot = acceptNode(root);\n if (acceptRoot === NodeFilter.FILTER_ACCEPT) {\n hide(root);\n }\n\n if (acceptRoot !== NodeFilter.FILTER_REJECT) {\n let node = walker.nextNode() as Element;\n while (node != null) {\n hide(node);\n node = walker.nextNode() as Element;\n }\n }\n };\n\n let hide = (node: Element) => {\n let refCount = refCountMap.get(node) ?? 0;\n\n // If already aria-hidden, and the ref count is zero, then this element\n // was already hidden and there's nothing for us to do.\n if (node.getAttribute('aria-hidden') === 'true' && refCount === 0) {\n return;\n }\n\n if (refCount === 0) {\n node.setAttribute('aria-hidden', 'true');\n }\n\n hiddenNodes.add(node);\n refCountMap.set(node, refCount + 1);\n };\n\n // If there is already a MutationObserver listening from a previous call,\n // disconnect it so the new on takes over.\n if (observerStack.length) {\n observerStack[observerStack.length - 1].disconnect();\n }\n\n walk(root);\n\n let observer = new MutationObserver(changes => {\n for (let change of changes) {\n if (change.type !== 'childList' || change.addedNodes.length === 0) {\n continue;\n }\n\n // If the parent element of the added nodes is not within one of the targets,\n // and not already inside a hidden node, hide all of the new children.\n if (![...visibleNodes, ...hiddenNodes].some(node => node.contains(change.target))) {\n for (let node of change.removedNodes) {\n if (node instanceof Element) {\n visibleNodes.delete(node);\n hiddenNodes.delete(node);\n }\n }\n\n for (let node of change.addedNodes) {\n if (\n (node instanceof HTMLElement || node instanceof SVGElement) &&\n (node.dataset.liveAnnouncer === 'true' || node.dataset.reactAriaTopLayer === 'true')\n ) {\n visibleNodes.add(node);\n } else if (node instanceof Element) {\n walk(node);\n }\n }\n }\n }\n });\n\n observer.observe(root, {childList: true, subtree: true});\n\n let observerWrapper: ObserverWrapper = {\n visibleNodes,\n hiddenNodes,\n observe() {\n observer.observe(root, {childList: true, subtree: true});\n },\n disconnect() {\n observer.disconnect();\n }\n };\n\n observerStack.push(observerWrapper);\n\n return () => {\n observer.disconnect();\n\n for (let node of hiddenNodes) {\n let count = refCountMap.get(node);\n if (count == null) {\n continue;\n }\n if (count === 1) {\n node.removeAttribute('aria-hidden');\n refCountMap.delete(node);\n } else {\n refCountMap.set(node, count - 1);\n }\n }\n\n // Remove this observer from the stack, and start the previous one.\n if (observerWrapper === observerStack[observerStack.length - 1]) {\n observerStack.pop();\n if (observerStack.length) {\n observerStack[observerStack.length - 1].observe();\n }\n } else {\n observerStack.splice(observerStack.indexOf(observerWrapper), 1);\n }\n };\n}\n\nexport function keepVisible(element: Element) {\n let observer = observerStack[observerStack.length - 1];\n if (observer && !observer.visibleNodes.has(element)) {\n observer.visibleNodes.add(element);\n return () => {\n observer.visibleNodes.delete(element);\n };\n }\n}\n"],"names":[],"version":3,"file":"ariaHideOutside.module.js.map"}
|
package/dist/types.d.ts
CHANGED
|
@@ -215,6 +215,12 @@ export interface AriaPopoverProps extends Omit<AriaPositionProps, 'isOpen' | 'on
|
|
|
215
215
|
* The ref for the popover element.
|
|
216
216
|
*/
|
|
217
217
|
popoverRef: RefObject<Element | null>;
|
|
218
|
+
/**
|
|
219
|
+
* An optional ref for a group of popovers, e.g. submenus.
|
|
220
|
+
* When provided, this element is used to detect outside interactions
|
|
221
|
+
* and hiding elements from assistive technologies instead of the popoverRef.
|
|
222
|
+
*/
|
|
223
|
+
groupRef?: RefObject<Element | null>;
|
|
218
224
|
/**
|
|
219
225
|
* Whether the popover is non-modal, i.e. elements outside the popover may be
|
|
220
226
|
* interacted with by assistive technologies.
|
|
@@ -277,6 +283,10 @@ export interface OverlayProps {
|
|
|
277
283
|
* implement focus containment and restoration to ensure the overlay is keyboard accessible.
|
|
278
284
|
*/
|
|
279
285
|
disableFocusManagement?: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Whether to contain focus within the overlay.
|
|
288
|
+
*/
|
|
289
|
+
shouldContainFocus?: boolean;
|
|
280
290
|
/**
|
|
281
291
|
* Whether the overlay is currently performing an exit animation. When true,
|
|
282
292
|
* focus is allowed to move outside.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;AEoBA,kCAAmC,SAAQ,aAAa;IACtD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,SAAS,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC,CAAC;IACrC;;OAEG;IACH,UAAU,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;IACE,+CAA+C;IAC/C,YAAY,EAAE,aAAa,CAAC;IAC5B,8CAA8C;IAC9C,UAAU,EAAE,aAAa,CAAC;IAC1B,oEAAoE;IACpE,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,2CAA2C;IAC3C,cAAc,IAAI,IAAI,CAAA;CACvB;AASD;;;GAGG;AACH,mCAAmC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAsNzE;AC1RD;IACE,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;CAC7D;AAED;IACE,uDAAuD;IACvD,YAAY,EAAE,aAAa,CAAC;IAC5B,sDAAsD;IACtD,aAAa,EAAE,aAAa,CAAA;CAC7B;AAID;;;;GAIG;AACH,2BAA2B,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC,GAAG,WAAW,
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/calculatePosition.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useCloseOnScroll.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useOverlayPosition.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useOverlay.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useOverlayTrigger.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/usePreventScroll.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useModal.tsx","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/DismissButton.tsx","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/ariaHideOutside.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/usePopover.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/PortalProvider.tsx","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/Overlay.tsx","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/useModalOverlay.ts","packages/@react-aria/overlays/src/packages/@react-aria/overlays/src/index.ts","packages/@react-aria/overlays/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/*\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 */\nexport {useOverlayPosition} from './useOverlayPosition';\nexport {useOverlay} from './useOverlay';\nexport {useOverlayTrigger} from './useOverlayTrigger';\nexport {usePreventScroll} from './usePreventScroll';\nexport {ModalProvider, useModalProvider, OverlayProvider, OverlayContainer, useModal} from './useModal';\nexport {DismissButton} from './DismissButton';\nexport {ariaHideOutside} from './ariaHideOutside';\nexport {usePopover} from './usePopover';\nexport {useModalOverlay} from './useModalOverlay';\nexport {Overlay, useOverlayFocusContain} from './Overlay';\nexport {UNSTABLE_PortalProvider, useUNSTABLE_PortalContext} from './PortalProvider';\n\nexport type {AriaPositionProps, PositionAria} from './useOverlayPosition';\nexport type {AriaOverlayProps, OverlayAria} from './useOverlay';\nexport type {OverlayTriggerAria, OverlayTriggerProps} from './useOverlayTrigger';\nexport type {AriaModalOptions, ModalAria, ModalProviderAria, ModalProviderProps, OverlayContainerProps} from './useModal';\nexport type {DismissButtonProps} from './DismissButton';\nexport type {AriaPopoverProps, PopoverAria} from './usePopover';\nexport type {AriaModalOverlayProps, ModalOverlayAria} from './useModalOverlay';\nexport type {OverlayProps} from './Overlay';\nexport type {Placement, PlacementAxis, PositionProps} from '@react-types/overlays';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
|
package/dist/useOverlay.main.js
CHANGED
|
@@ -26,11 +26,13 @@ function $82711f9cb668ecdb$export$ea8f71083e90600f(props, ref) {
|
|
|
26
26
|
let { onClose: onClose, shouldCloseOnBlur: shouldCloseOnBlur, isOpen: isOpen, isDismissable: isDismissable = false, isKeyboardDismissDisabled: isKeyboardDismissDisabled = false, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside } = props;
|
|
27
27
|
// Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.
|
|
28
28
|
(0, $eQbp7$react.useEffect)(()=>{
|
|
29
|
-
if (isOpen
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
if (isOpen && !$82711f9cb668ecdb$var$visibleOverlays.includes(ref)) {
|
|
30
|
+
$82711f9cb668ecdb$var$visibleOverlays.push(ref);
|
|
31
|
+
return ()=>{
|
|
32
|
+
let index = $82711f9cb668ecdb$var$visibleOverlays.indexOf(ref);
|
|
33
|
+
if (index >= 0) $82711f9cb668ecdb$var$visibleOverlays.splice(index, 1);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
34
36
|
}, [
|
|
35
37
|
isOpen,
|
|
36
38
|
ref
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AA6CD,MAAM,wCAA+C,EAAE;AAOhD,SAAS,0CAAW,KAAuB,EAAE,GAA8B;IAChF,IAAI,WACF,OAAO,qBACP,iBAAiB,UACjB,MAAM,iBACN,gBAAgB,kCAChB,4BAA4B,qCAC5B,4BAA4B,EAC7B,GAAG;IAEJ,wFAAwF;IACxF,CAAA,GAAA,sBAAQ,EAAE;QACR,IAAI,
|
|
1
|
+
{"mappings":";;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AA6CD,MAAM,wCAA+C,EAAE;AAOhD,SAAS,0CAAW,KAAuB,EAAE,GAA8B;IAChF,IAAI,WACF,OAAO,qBACP,iBAAiB,UACjB,MAAM,iBACN,gBAAgB,kCAChB,4BAA4B,qCAC5B,4BAA4B,EAC7B,GAAG;IAEJ,wFAAwF;IACxF,CAAA,GAAA,sBAAQ,EAAE;QACR,IAAI,UAAU,CAAC,sCAAgB,QAAQ,CAAC,MAAM;YAC5C,sCAAgB,IAAI,CAAC;YACrB,OAAO;gBACL,IAAI,QAAQ,sCAAgB,OAAO,CAAC;gBACpC,IAAI,SAAS,GACX,sCAAgB,MAAM,CAAC,OAAO;YAElC;QACF;IACF,GAAG;QAAC;QAAQ;KAAI;IAEhB,4EAA4E;IAC5E,IAAI,SAAS;QACX,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,OAAO,SACzD;IAEJ;IAEA,IAAI,yBAAyB,CAAC;QAC5B,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,MAAM,GACxE;YAAA,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,KAAK;gBACvD,EAAE,eAAe;gBACjB,EAAE,cAAc;YAClB;QAAA;IAEJ;IAEA,IAAI,oBAAoB,CAAC;QACvB,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,MAAM,GAAc;YACtF,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,KAAK;gBACvD,EAAE,eAAe;gBACjB,EAAE,cAAc;YAClB;YACA;QACF;IACF;IAEA,wBAAwB;IACxB,IAAI,YAAY,CAAC;QACf,IAAI,EAAE,GAAG,KAAK,YAAY,CAAC,6BAA6B,CAAC,EAAE,WAAW,CAAC,WAAW,EAAE;YAClF,EAAE,eAAe;YACjB,EAAE,cAAc;YAChB;QACF;IACF;IAEA,kDAAkD;IAClD,CAAA,GAAA,+CAAiB,EAAE;aAAC;QAAK,mBAAmB,iBAAiB,SAAS,oBAAoB;gCAAW;IAAsB;IAE3H,IAAI,oBAAC,gBAAgB,EAAC,GAAG,CAAA,GAAA,2CAAa,EAAE;QACtC,YAAY,CAAC;QACb,cAAc,CAAC;YACb,gFAAgF;YAChF,8GAA8G;YAC9G,6FAA6F;YAC7F,sDAAsD;YACtD,sDAAsD;YACtD,EAAE;YACF,2EAA2E;YAC3E,yEAAyE;YACzE,kEAAkE;YAClE,IAAI,CAAC,EAAE,aAAa,IAAI,CAAA,GAAA,mDAA4B,EAAE,EAAE,aAAa,GACnE;YAGF,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,aAAa,GAC/E,oBAAA,8BAAA;QAEJ;IACF;IAEA,IAAI,wBAAwB,CAAA;QAC1B,wGAAwG;QACxG,IAAI,EAAE,MAAM,KAAK,EAAE,aAAa,EAC9B,EAAE,cAAc;IAEpB;IAEA,OAAO;QACL,cAAc;uBACZ;YACA,GAAG,gBAAgB;QACrB;QACA,eAAe;YACb,eAAe;QACjB;IACF;AACF","sources":["packages/@react-aria/overlays/src/useOverlay.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 {DOMAttributes, RefObject} from '@react-types/shared';\nimport {isElementInChildOfActiveScope} from '@react-aria/focus';\nimport {useEffect} from 'react';\nimport {useFocusWithin, useInteractOutside} from '@react-aria/interactions';\n\nexport interface AriaOverlayProps {\n /** Whether the overlay is currently open. */\n isOpen?: boolean,\n\n /** Handler that is called when the overlay should close. */\n onClose?: () => void,\n\n /**\n * Whether to close the overlay when the user interacts outside it.\n * @default false\n */\n isDismissable?: boolean,\n\n /** Whether the overlay should close when focus is lost or moves outside it. */\n shouldCloseOnBlur?: boolean,\n\n /**\n * Whether pressing the escape key to close the overlay should be disabled.\n * @default false\n */\n isKeyboardDismissDisabled?: boolean,\n\n /**\n * When user interacts with the argument element outside of the overlay ref,\n * return true if onClose should be called. This gives you a chance to filter\n * out interaction with elements that should not dismiss the overlay.\n * By default, onClose will always be called on interaction outside the overlay ref.\n */\n shouldCloseOnInteractOutside?: (element: Element) => boolean\n}\n\nexport interface OverlayAria {\n /** Props to apply to the overlay container element. */\n overlayProps: DOMAttributes,\n /** Props to apply to the underlay element, if any. */\n underlayProps: DOMAttributes\n}\n\nconst visibleOverlays: RefObject<Element | null>[] = [];\n\n/**\n * Provides the behavior for overlays such as dialogs, popovers, and menus.\n * Hides the overlay when the user interacts outside it, when the Escape key is pressed,\n * or optionally, on blur. Only the top-most overlay will close at once.\n */\nexport function useOverlay(props: AriaOverlayProps, ref: RefObject<Element | null>): OverlayAria {\n let {\n onClose,\n shouldCloseOnBlur,\n isOpen,\n isDismissable = false,\n isKeyboardDismissDisabled = false,\n shouldCloseOnInteractOutside\n } = props;\n\n // Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.\n useEffect(() => {\n if (isOpen && !visibleOverlays.includes(ref)) {\n visibleOverlays.push(ref);\n return () => {\n let index = visibleOverlays.indexOf(ref);\n if (index >= 0) {\n visibleOverlays.splice(index, 1);\n }\n };\n }\n }, [isOpen, ref]);\n\n // Only hide the overlay when it is the topmost visible overlay in the stack\n let onHide = () => {\n if (visibleOverlays[visibleOverlays.length - 1] === ref && onClose) {\n onClose();\n }\n };\n\n let onInteractOutsideStart = (e: PointerEvent) => {\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.target as Element)) {\n if (visibleOverlays[visibleOverlays.length - 1] === ref) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n };\n\n let onInteractOutside = (e: PointerEvent) => {\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.target as Element)) {\n if (visibleOverlays[visibleOverlays.length - 1] === ref) {\n e.stopPropagation();\n e.preventDefault();\n }\n onHide();\n }\n };\n\n // Handle the escape key\n let onKeyDown = (e) => {\n if (e.key === 'Escape' && !isKeyboardDismissDisabled && !e.nativeEvent.isComposing) {\n e.stopPropagation();\n e.preventDefault();\n onHide();\n }\n };\n\n // Handle clicking outside the overlay to close it\n useInteractOutside({ref, onInteractOutside: isDismissable && isOpen ? onInteractOutside : undefined, onInteractOutsideStart});\n\n let {focusWithinProps} = useFocusWithin({\n isDisabled: !shouldCloseOnBlur,\n onBlurWithin: (e) => {\n // Do not close if relatedTarget is null, which means focus is lost to the body.\n // That can happen when switching tabs, or due to a VoiceOver/Chrome bug with Control+Option+Arrow navigation.\n // Clicking on the body to close the overlay should already be handled by useInteractOutside.\n // https://github.com/adobe/react-spectrum/issues/4130\n // https://github.com/adobe/react-spectrum/issues/4922\n //\n // If focus is moving into a child focus scope (e.g. menu inside a dialog),\n // do not close the outer overlay. At this point, the active scope should\n // still be the outer overlay, since blur events run before focus.\n if (!e.relatedTarget || isElementInChildOfActiveScope(e.relatedTarget)) {\n return;\n }\n\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.relatedTarget as Element)) {\n onClose?.();\n }\n }\n });\n\n let onPointerDownUnderlay = e => {\n // fixes a firefox issue that starts text selection https://bugzilla.mozilla.org/show_bug.cgi?id=1675846\n if (e.target === e.currentTarget) {\n e.preventDefault();\n }\n };\n\n return {\n overlayProps: {\n onKeyDown,\n ...focusWithinProps\n },\n underlayProps: {\n onPointerDown: onPointerDownUnderlay\n }\n };\n}\n"],"names":[],"version":3,"file":"useOverlay.main.js.map"}
|
package/dist/useOverlay.mjs
CHANGED
|
@@ -20,11 +20,13 @@ function $a11501f3d1d39e6c$export$ea8f71083e90600f(props, ref) {
|
|
|
20
20
|
let { onClose: onClose, shouldCloseOnBlur: shouldCloseOnBlur, isOpen: isOpen, isDismissable: isDismissable = false, isKeyboardDismissDisabled: isKeyboardDismissDisabled = false, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside } = props;
|
|
21
21
|
// Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.
|
|
22
22
|
(0, $jtpZv$useEffect)(()=>{
|
|
23
|
-
if (isOpen
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if (isOpen && !$a11501f3d1d39e6c$var$visibleOverlays.includes(ref)) {
|
|
24
|
+
$a11501f3d1d39e6c$var$visibleOverlays.push(ref);
|
|
25
|
+
return ()=>{
|
|
26
|
+
let index = $a11501f3d1d39e6c$var$visibleOverlays.indexOf(ref);
|
|
27
|
+
if (index >= 0) $a11501f3d1d39e6c$var$visibleOverlays.splice(index, 1);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
28
30
|
}, [
|
|
29
31
|
isOpen,
|
|
30
32
|
ref
|
|
@@ -20,11 +20,13 @@ function $a11501f3d1d39e6c$export$ea8f71083e90600f(props, ref) {
|
|
|
20
20
|
let { onClose: onClose, shouldCloseOnBlur: shouldCloseOnBlur, isOpen: isOpen, isDismissable: isDismissable = false, isKeyboardDismissDisabled: isKeyboardDismissDisabled = false, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside } = props;
|
|
21
21
|
// Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.
|
|
22
22
|
(0, $jtpZv$useEffect)(()=>{
|
|
23
|
-
if (isOpen
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if (isOpen && !$a11501f3d1d39e6c$var$visibleOverlays.includes(ref)) {
|
|
24
|
+
$a11501f3d1d39e6c$var$visibleOverlays.push(ref);
|
|
25
|
+
return ()=>{
|
|
26
|
+
let index = $a11501f3d1d39e6c$var$visibleOverlays.indexOf(ref);
|
|
27
|
+
if (index >= 0) $a11501f3d1d39e6c$var$visibleOverlays.splice(index, 1);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
28
30
|
}, [
|
|
29
31
|
isOpen,
|
|
30
32
|
ref
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AA6CD,MAAM,wCAA+C,EAAE;AAOhD,SAAS,0CAAW,KAAuB,EAAE,GAA8B;IAChF,IAAI,WACF,OAAO,qBACP,iBAAiB,UACjB,MAAM,iBACN,gBAAgB,kCAChB,4BAA4B,qCAC5B,4BAA4B,EAC7B,GAAG;IAEJ,wFAAwF;IACxF,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,
|
|
1
|
+
{"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AA6CD,MAAM,wCAA+C,EAAE;AAOhD,SAAS,0CAAW,KAAuB,EAAE,GAA8B;IAChF,IAAI,WACF,OAAO,qBACP,iBAAiB,UACjB,MAAM,iBACN,gBAAgB,kCAChB,4BAA4B,qCAC5B,4BAA4B,EAC7B,GAAG;IAEJ,wFAAwF;IACxF,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,UAAU,CAAC,sCAAgB,QAAQ,CAAC,MAAM;YAC5C,sCAAgB,IAAI,CAAC;YACrB,OAAO;gBACL,IAAI,QAAQ,sCAAgB,OAAO,CAAC;gBACpC,IAAI,SAAS,GACX,sCAAgB,MAAM,CAAC,OAAO;YAElC;QACF;IACF,GAAG;QAAC;QAAQ;KAAI;IAEhB,4EAA4E;IAC5E,IAAI,SAAS;QACX,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,OAAO,SACzD;IAEJ;IAEA,IAAI,yBAAyB,CAAC;QAC5B,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,MAAM,GACxE;YAAA,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,KAAK;gBACvD,EAAE,eAAe;gBACjB,EAAE,cAAc;YAClB;QAAA;IAEJ;IAEA,IAAI,oBAAoB,CAAC;QACvB,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,MAAM,GAAc;YACtF,IAAI,qCAAe,CAAC,sCAAgB,MAAM,GAAG,EAAE,KAAK,KAAK;gBACvD,EAAE,eAAe;gBACjB,EAAE,cAAc;YAClB;YACA;QACF;IACF;IAEA,wBAAwB;IACxB,IAAI,YAAY,CAAC;QACf,IAAI,EAAE,GAAG,KAAK,YAAY,CAAC,6BAA6B,CAAC,EAAE,WAAW,CAAC,WAAW,EAAE;YAClF,EAAE,eAAe;YACjB,EAAE,cAAc;YAChB;QACF;IACF;IAEA,kDAAkD;IAClD,CAAA,GAAA,yBAAiB,EAAE;aAAC;QAAK,mBAAmB,iBAAiB,SAAS,oBAAoB;gCAAW;IAAsB;IAE3H,IAAI,oBAAC,gBAAgB,EAAC,GAAG,CAAA,GAAA,qBAAa,EAAE;QACtC,YAAY,CAAC;QACb,cAAc,CAAC;YACb,gFAAgF;YAChF,8GAA8G;YAC9G,6FAA6F;YAC7F,sDAAsD;YACtD,sDAAsD;YACtD,EAAE;YACF,2EAA2E;YAC3E,yEAAyE;YACzE,kEAAkE;YAClE,IAAI,CAAC,EAAE,aAAa,IAAI,CAAA,GAAA,oCAA4B,EAAE,EAAE,aAAa,GACnE;YAGF,IAAI,CAAC,gCAAgC,6BAA6B,EAAE,aAAa,GAC/E,oBAAA,8BAAA;QAEJ;IACF;IAEA,IAAI,wBAAwB,CAAA;QAC1B,wGAAwG;QACxG,IAAI,EAAE,MAAM,KAAK,EAAE,aAAa,EAC9B,EAAE,cAAc;IAEpB;IAEA,OAAO;QACL,cAAc;uBACZ;YACA,GAAG,gBAAgB;QACrB;QACA,eAAe;YACb,eAAe;QACjB;IACF;AACF","sources":["packages/@react-aria/overlays/src/useOverlay.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 {DOMAttributes, RefObject} from '@react-types/shared';\nimport {isElementInChildOfActiveScope} from '@react-aria/focus';\nimport {useEffect} from 'react';\nimport {useFocusWithin, useInteractOutside} from '@react-aria/interactions';\n\nexport interface AriaOverlayProps {\n /** Whether the overlay is currently open. */\n isOpen?: boolean,\n\n /** Handler that is called when the overlay should close. */\n onClose?: () => void,\n\n /**\n * Whether to close the overlay when the user interacts outside it.\n * @default false\n */\n isDismissable?: boolean,\n\n /** Whether the overlay should close when focus is lost or moves outside it. */\n shouldCloseOnBlur?: boolean,\n\n /**\n * Whether pressing the escape key to close the overlay should be disabled.\n * @default false\n */\n isKeyboardDismissDisabled?: boolean,\n\n /**\n * When user interacts with the argument element outside of the overlay ref,\n * return true if onClose should be called. This gives you a chance to filter\n * out interaction with elements that should not dismiss the overlay.\n * By default, onClose will always be called on interaction outside the overlay ref.\n */\n shouldCloseOnInteractOutside?: (element: Element) => boolean\n}\n\nexport interface OverlayAria {\n /** Props to apply to the overlay container element. */\n overlayProps: DOMAttributes,\n /** Props to apply to the underlay element, if any. */\n underlayProps: DOMAttributes\n}\n\nconst visibleOverlays: RefObject<Element | null>[] = [];\n\n/**\n * Provides the behavior for overlays such as dialogs, popovers, and menus.\n * Hides the overlay when the user interacts outside it, when the Escape key is pressed,\n * or optionally, on blur. Only the top-most overlay will close at once.\n */\nexport function useOverlay(props: AriaOverlayProps, ref: RefObject<Element | null>): OverlayAria {\n let {\n onClose,\n shouldCloseOnBlur,\n isOpen,\n isDismissable = false,\n isKeyboardDismissDisabled = false,\n shouldCloseOnInteractOutside\n } = props;\n\n // Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.\n useEffect(() => {\n if (isOpen && !visibleOverlays.includes(ref)) {\n visibleOverlays.push(ref);\n return () => {\n let index = visibleOverlays.indexOf(ref);\n if (index >= 0) {\n visibleOverlays.splice(index, 1);\n }\n };\n }\n }, [isOpen, ref]);\n\n // Only hide the overlay when it is the topmost visible overlay in the stack\n let onHide = () => {\n if (visibleOverlays[visibleOverlays.length - 1] === ref && onClose) {\n onClose();\n }\n };\n\n let onInteractOutsideStart = (e: PointerEvent) => {\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.target as Element)) {\n if (visibleOverlays[visibleOverlays.length - 1] === ref) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n };\n\n let onInteractOutside = (e: PointerEvent) => {\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.target as Element)) {\n if (visibleOverlays[visibleOverlays.length - 1] === ref) {\n e.stopPropagation();\n e.preventDefault();\n }\n onHide();\n }\n };\n\n // Handle the escape key\n let onKeyDown = (e) => {\n if (e.key === 'Escape' && !isKeyboardDismissDisabled && !e.nativeEvent.isComposing) {\n e.stopPropagation();\n e.preventDefault();\n onHide();\n }\n };\n\n // Handle clicking outside the overlay to close it\n useInteractOutside({ref, onInteractOutside: isDismissable && isOpen ? onInteractOutside : undefined, onInteractOutsideStart});\n\n let {focusWithinProps} = useFocusWithin({\n isDisabled: !shouldCloseOnBlur,\n onBlurWithin: (e) => {\n // Do not close if relatedTarget is null, which means focus is lost to the body.\n // That can happen when switching tabs, or due to a VoiceOver/Chrome bug with Control+Option+Arrow navigation.\n // Clicking on the body to close the overlay should already be handled by useInteractOutside.\n // https://github.com/adobe/react-spectrum/issues/4130\n // https://github.com/adobe/react-spectrum/issues/4922\n //\n // If focus is moving into a child focus scope (e.g. menu inside a dialog),\n // do not close the outer overlay. At this point, the active scope should\n // still be the outer overlay, since blur events run before focus.\n if (!e.relatedTarget || isElementInChildOfActiveScope(e.relatedTarget)) {\n return;\n }\n\n if (!shouldCloseOnInteractOutside || shouldCloseOnInteractOutside(e.relatedTarget as Element)) {\n onClose?.();\n }\n }\n });\n\n let onPointerDownUnderlay = e => {\n // fixes a firefox issue that starts text selection https://bugzilla.mozilla.org/show_bug.cgi?id=1675846\n if (e.target === e.currentTarget) {\n e.preventDefault();\n }\n };\n\n return {\n overlayProps: {\n onKeyDown,\n ...focusWithinProps\n },\n underlayProps: {\n onPointerDown: onPointerDownUnderlay\n }\n };\n}\n"],"names":[],"version":3,"file":"useOverlay.module.js.map"}
|
package/dist/usePopover.main.js
CHANGED
|
@@ -26,34 +26,39 @@ $parcel$export(module.exports, "usePopover", () => $6c2dfcdee3e15e20$export$542a
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
function $6c2dfcdee3e15e20$export$542a6fd13ac93354(props, state) {
|
|
29
|
-
let { triggerRef: triggerRef, popoverRef: popoverRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
29
|
+
let { triggerRef: triggerRef, popoverRef: popoverRef, groupRef: groupRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
30
|
+
let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';
|
|
30
31
|
let { overlayProps: overlayProps, underlayProps: underlayProps } = (0, $82711f9cb668ecdb$exports.useOverlay)({
|
|
31
|
-
|
|
32
|
-
isOpen: state.isOpen && !otherProps['data-react-aria-top-layer'],
|
|
32
|
+
isOpen: state.isOpen,
|
|
33
33
|
onClose: state.close,
|
|
34
34
|
shouldCloseOnBlur: true,
|
|
35
|
-
isDismissable: !isNonModal,
|
|
35
|
+
isDismissable: !isNonModal || isSubmenu,
|
|
36
36
|
isKeyboardDismissDisabled: isKeyboardDismissDisabled,
|
|
37
37
|
shouldCloseOnInteractOutside: shouldCloseOnInteractOutside
|
|
38
|
-
}, popoverRef);
|
|
38
|
+
}, groupRef !== null && groupRef !== void 0 ? groupRef : popoverRef);
|
|
39
39
|
let { overlayProps: positionProps, arrowProps: arrowProps, placement: placement } = (0, $cd94b4896dd97759$exports.useOverlayPosition)({
|
|
40
40
|
...otherProps,
|
|
41
41
|
targetRef: triggerRef,
|
|
42
42
|
overlayRef: popoverRef,
|
|
43
43
|
isOpen: state.isOpen,
|
|
44
|
-
onClose: isNonModal ? state.close : null
|
|
44
|
+
onClose: isNonModal && !isSubmenu ? state.close : null
|
|
45
45
|
});
|
|
46
46
|
(0, $5c2f5cd01815d369$exports.usePreventScroll)({
|
|
47
47
|
isDisabled: isNonModal || !state.isOpen
|
|
48
48
|
});
|
|
49
49
|
(0, $jkVOI$reactariautils.useLayoutEffect)(()=>{
|
|
50
|
-
if (state.isOpen &&
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
if (state.isOpen && popoverRef.current) {
|
|
51
|
+
var _groupRef_current, _groupRef_current1;
|
|
52
|
+
if (isNonModal) return (0, $08ef1685902b6011$exports.keepVisible)((_groupRef_current = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current !== void 0 ? _groupRef_current : popoverRef.current);
|
|
53
|
+
else return (0, $08ef1685902b6011$exports.ariaHideOutside)([
|
|
54
|
+
(_groupRef_current1 = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current1 !== void 0 ? _groupRef_current1 : popoverRef.current
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
53
57
|
}, [
|
|
54
58
|
isNonModal,
|
|
55
59
|
state.isOpen,
|
|
56
|
-
popoverRef
|
|
60
|
+
popoverRef,
|
|
61
|
+
groupRef
|
|
57
62
|
]);
|
|
58
63
|
return {
|
|
59
64
|
popoverProps: (0, $jkVOI$reactariautils.mergeProps)(overlayProps, positionProps),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;
|
|
1
|
+
{"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;AAoEM,SAAS,0CAAW,KAAuB,EAAE,KAA0B;IAC5E,IAAI,cACF,UAAU,cACV,UAAU,YACV,QAAQ,cACR,UAAU,6BACV,yBAAyB,gCACzB,4BAA4B,EAC5B,GAAG,YACJ,GAAG;IAEJ,IAAI,YAAY,UAAU,CAAC,UAAU,KAAK;IAE1C,IAAI,gBAAC,YAAY,iBAAE,aAAa,EAAC,GAAG,CAAA,GAAA,oCAAS,EAC3C;QACE,QAAQ,MAAM,MAAM;QACpB,SAAS,MAAM,KAAK;QACpB,mBAAmB;QACnB,eAAe,CAAC,cAAc;mCAC9B;sCACA;IACF,GACA,qBAAA,sBAAA,WAAY;IAGd,IAAI,EAAC,cAAc,aAAa,cAAE,UAAU,aAAE,SAAS,EAAC,GAAG,CAAA,GAAA,4CAAiB,EAAE;QAC5E,GAAG,UAAU;QACb,WAAW;QACX,YAAY;QACZ,QAAQ,MAAM,MAAM;QACpB,SAAS,cAAc,CAAC,YAAY,MAAM,KAAK,GAAG;IACpD;IAEA,CAAA,GAAA,0CAAe,EAAE;QACf,YAAY,cAAc,CAAC,MAAM,MAAM;IACzC;IAEA,CAAA,GAAA,qCAAc,EAAE;QACd,IAAI,MAAM,MAAM,IAAI,WAAW,OAAO,EAAE;gBAEjB,mBAEK;YAH1B,IAAI,YACF,OAAO,CAAA,GAAA,qCAAU,EAAE,CAAA,oBAAA,qBAAA,+BAAA,SAAU,OAAO,cAAjB,+BAAA,oBAAqB,WAAW,OAAO;iBAE1D,OAAO,CAAA,GAAA,yCAAc,EAAE;gBAAC,CAAA,qBAAA,qBAAA,+BAAA,SAAU,OAAO,cAAjB,gCAAA,qBAAqB,WAAW,OAAO;aAAC;QAEpE;IACF,GAAG;QAAC;QAAY,MAAM,MAAM;QAAE;QAAY;KAAS;IAEnD,OAAO;QACL,cAAc,CAAA,GAAA,gCAAS,EAAE,cAAc;oBACvC;uBACA;mBACA;IACF;AACF","sources":["packages/@react-aria/overlays/src/usePopover.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {ariaHideOutside, keepVisible} from './ariaHideOutside';\nimport {AriaPositionProps, useOverlayPosition} from './useOverlayPosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {mergeProps, useLayoutEffect} from '@react-aria/utils';\nimport {OverlayTriggerState} from '@react-stately/overlays';\nimport {PlacementAxis} from '@react-types/overlays';\nimport {useOverlay} from './useOverlay';\nimport {usePreventScroll} from './usePreventScroll';\n\nexport interface AriaPopoverProps extends Omit<AriaPositionProps, 'isOpen' | 'onClose' | 'targetRef' | 'overlayRef'> {\n /**\n * The ref for the element which the popover positions itself with respect to.\n */\n triggerRef: RefObject<Element | null>,\n /**\n * The ref for the popover element.\n */\n popoverRef: RefObject<Element | null>,\n /**\n * An optional ref for a group of popovers, e.g. submenus.\n * When provided, this element is used to detect outside interactions\n * and hiding elements from assistive technologies instead of the popoverRef.\n */\n groupRef?: RefObject<Element | null>,\n /**\n * Whether the popover is non-modal, i.e. elements outside the popover may be\n * interacted with by assistive technologies.\n *\n * Most popovers should not use this option as it may negatively impact the screen\n * reader experience. Only use with components such as combobox, which are designed\n * to handle this situation carefully.\n */\n isNonModal?: boolean,\n /**\n * Whether pressing the escape key to close the popover should be disabled.\n *\n * Most popovers should not use this option. When set to true, an alternative\n * way to close the popover with a keyboard must be provided.\n *\n * @default false\n */\n isKeyboardDismissDisabled?: boolean,\n /**\n * When user interacts with the argument element outside of the popover ref,\n * return true if onClose should be called. This gives you a chance to filter\n * out interaction with elements that should not dismiss the popover.\n * By default, onClose will always be called on interaction outside the popover ref.\n */\n shouldCloseOnInteractOutside?: (element: Element) => boolean\n}\n\nexport interface PopoverAria {\n /** Props for the popover element. */\n popoverProps: DOMAttributes,\n /** Props for the popover tip arrow if any. */\n arrowProps: DOMAttributes,\n /** Props to apply to the underlay element, if any. */\n underlayProps: DOMAttributes,\n /** Placement of the popover with respect to the trigger. */\n placement: PlacementAxis | null\n}\n\n/**\n * Provides the behavior and accessibility implementation for a popover component.\n * A popover is an overlay element positioned relative to a trigger.\n */\nexport function usePopover(props: AriaPopoverProps, state: OverlayTriggerState): PopoverAria {\n let {\n triggerRef,\n popoverRef,\n groupRef,\n isNonModal,\n isKeyboardDismissDisabled,\n shouldCloseOnInteractOutside,\n ...otherProps\n } = props;\n\n let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';\n\n let {overlayProps, underlayProps} = useOverlay(\n {\n isOpen: state.isOpen,\n onClose: state.close,\n shouldCloseOnBlur: true,\n isDismissable: !isNonModal || isSubmenu,\n isKeyboardDismissDisabled,\n shouldCloseOnInteractOutside\n },\n groupRef ?? popoverRef\n );\n\n let {overlayProps: positionProps, arrowProps, placement} = useOverlayPosition({\n ...otherProps,\n targetRef: triggerRef,\n overlayRef: popoverRef,\n isOpen: state.isOpen,\n onClose: isNonModal && !isSubmenu ? state.close : null\n });\n\n usePreventScroll({\n isDisabled: isNonModal || !state.isOpen\n });\n\n useLayoutEffect(() => {\n if (state.isOpen && popoverRef.current) {\n if (isNonModal) {\n return keepVisible(groupRef?.current ?? popoverRef.current);\n } else {\n return ariaHideOutside([groupRef?.current ?? popoverRef.current]);\n }\n }\n }, [isNonModal, state.isOpen, popoverRef, groupRef]);\n\n return {\n popoverProps: mergeProps(overlayProps, positionProps),\n arrowProps,\n underlayProps,\n placement\n };\n}\n"],"names":[],"version":3,"file":"usePopover.main.js.map"}
|
package/dist/usePopover.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {ariaHideOutside as $5e3802645cc19319$export$1c3ebcada18427bf} from "./ariaHideOutside.mjs";
|
|
1
|
+
import {ariaHideOutside as $5e3802645cc19319$export$1c3ebcada18427bf, keepVisible as $5e3802645cc19319$export$1020fa7f77e17884} from "./ariaHideOutside.mjs";
|
|
2
2
|
import {useOverlayPosition as $2a41e45df1593e64$export$d39e1813b3bdd0e1} from "./useOverlayPosition.mjs";
|
|
3
3
|
import {useOverlay as $a11501f3d1d39e6c$export$ea8f71083e90600f} from "./useOverlay.mjs";
|
|
4
4
|
import {usePreventScroll as $49c51c25361d4cd2$export$ee0f7cc6afcd1c18} from "./usePreventScroll.mjs";
|
|
@@ -20,34 +20,39 @@ import {useLayoutEffect as $m0yab$useLayoutEffect, mergeProps as $m0yab$mergePro
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
function $f2f8a6077418541e$export$542a6fd13ac93354(props, state) {
|
|
23
|
-
let { triggerRef: triggerRef, popoverRef: popoverRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
23
|
+
let { triggerRef: triggerRef, popoverRef: popoverRef, groupRef: groupRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
24
|
+
let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';
|
|
24
25
|
let { overlayProps: overlayProps, underlayProps: underlayProps } = (0, $a11501f3d1d39e6c$export$ea8f71083e90600f)({
|
|
25
|
-
|
|
26
|
-
isOpen: state.isOpen && !otherProps['data-react-aria-top-layer'],
|
|
26
|
+
isOpen: state.isOpen,
|
|
27
27
|
onClose: state.close,
|
|
28
28
|
shouldCloseOnBlur: true,
|
|
29
|
-
isDismissable: !isNonModal,
|
|
29
|
+
isDismissable: !isNonModal || isSubmenu,
|
|
30
30
|
isKeyboardDismissDisabled: isKeyboardDismissDisabled,
|
|
31
31
|
shouldCloseOnInteractOutside: shouldCloseOnInteractOutside
|
|
32
|
-
}, popoverRef);
|
|
32
|
+
}, groupRef !== null && groupRef !== void 0 ? groupRef : popoverRef);
|
|
33
33
|
let { overlayProps: positionProps, arrowProps: arrowProps, placement: placement } = (0, $2a41e45df1593e64$export$d39e1813b3bdd0e1)({
|
|
34
34
|
...otherProps,
|
|
35
35
|
targetRef: triggerRef,
|
|
36
36
|
overlayRef: popoverRef,
|
|
37
37
|
isOpen: state.isOpen,
|
|
38
|
-
onClose: isNonModal ? state.close : null
|
|
38
|
+
onClose: isNonModal && !isSubmenu ? state.close : null
|
|
39
39
|
});
|
|
40
40
|
(0, $49c51c25361d4cd2$export$ee0f7cc6afcd1c18)({
|
|
41
41
|
isDisabled: isNonModal || !state.isOpen
|
|
42
42
|
});
|
|
43
43
|
(0, $m0yab$useLayoutEffect)(()=>{
|
|
44
|
-
if (state.isOpen &&
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
if (state.isOpen && popoverRef.current) {
|
|
45
|
+
var _groupRef_current, _groupRef_current1;
|
|
46
|
+
if (isNonModal) return (0, $5e3802645cc19319$export$1020fa7f77e17884)((_groupRef_current = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current !== void 0 ? _groupRef_current : popoverRef.current);
|
|
47
|
+
else return (0, $5e3802645cc19319$export$1c3ebcada18427bf)([
|
|
48
|
+
(_groupRef_current1 = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current1 !== void 0 ? _groupRef_current1 : popoverRef.current
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
47
51
|
}, [
|
|
48
52
|
isNonModal,
|
|
49
53
|
state.isOpen,
|
|
50
|
-
popoverRef
|
|
54
|
+
popoverRef,
|
|
55
|
+
groupRef
|
|
51
56
|
]);
|
|
52
57
|
return {
|
|
53
58
|
popoverProps: (0, $m0yab$mergeProps)(overlayProps, positionProps),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {ariaHideOutside as $5e3802645cc19319$export$1c3ebcada18427bf} from "./ariaHideOutside.module.js";
|
|
1
|
+
import {ariaHideOutside as $5e3802645cc19319$export$1c3ebcada18427bf, keepVisible as $5e3802645cc19319$export$1020fa7f77e17884} from "./ariaHideOutside.module.js";
|
|
2
2
|
import {useOverlayPosition as $2a41e45df1593e64$export$d39e1813b3bdd0e1} from "./useOverlayPosition.module.js";
|
|
3
3
|
import {useOverlay as $a11501f3d1d39e6c$export$ea8f71083e90600f} from "./useOverlay.module.js";
|
|
4
4
|
import {usePreventScroll as $49c51c25361d4cd2$export$ee0f7cc6afcd1c18} from "./usePreventScroll.module.js";
|
|
@@ -20,34 +20,39 @@ import {useLayoutEffect as $m0yab$useLayoutEffect, mergeProps as $m0yab$mergePro
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
function $f2f8a6077418541e$export$542a6fd13ac93354(props, state) {
|
|
23
|
-
let { triggerRef: triggerRef, popoverRef: popoverRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
23
|
+
let { triggerRef: triggerRef, popoverRef: popoverRef, groupRef: groupRef, isNonModal: isNonModal, isKeyboardDismissDisabled: isKeyboardDismissDisabled, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, ...otherProps } = props;
|
|
24
|
+
let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';
|
|
24
25
|
let { overlayProps: overlayProps, underlayProps: underlayProps } = (0, $a11501f3d1d39e6c$export$ea8f71083e90600f)({
|
|
25
|
-
|
|
26
|
-
isOpen: state.isOpen && !otherProps['data-react-aria-top-layer'],
|
|
26
|
+
isOpen: state.isOpen,
|
|
27
27
|
onClose: state.close,
|
|
28
28
|
shouldCloseOnBlur: true,
|
|
29
|
-
isDismissable: !isNonModal,
|
|
29
|
+
isDismissable: !isNonModal || isSubmenu,
|
|
30
30
|
isKeyboardDismissDisabled: isKeyboardDismissDisabled,
|
|
31
31
|
shouldCloseOnInteractOutside: shouldCloseOnInteractOutside
|
|
32
|
-
}, popoverRef);
|
|
32
|
+
}, groupRef !== null && groupRef !== void 0 ? groupRef : popoverRef);
|
|
33
33
|
let { overlayProps: positionProps, arrowProps: arrowProps, placement: placement } = (0, $2a41e45df1593e64$export$d39e1813b3bdd0e1)({
|
|
34
34
|
...otherProps,
|
|
35
35
|
targetRef: triggerRef,
|
|
36
36
|
overlayRef: popoverRef,
|
|
37
37
|
isOpen: state.isOpen,
|
|
38
|
-
onClose: isNonModal ? state.close : null
|
|
38
|
+
onClose: isNonModal && !isSubmenu ? state.close : null
|
|
39
39
|
});
|
|
40
40
|
(0, $49c51c25361d4cd2$export$ee0f7cc6afcd1c18)({
|
|
41
41
|
isDisabled: isNonModal || !state.isOpen
|
|
42
42
|
});
|
|
43
43
|
(0, $m0yab$useLayoutEffect)(()=>{
|
|
44
|
-
if (state.isOpen &&
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
if (state.isOpen && popoverRef.current) {
|
|
45
|
+
var _groupRef_current, _groupRef_current1;
|
|
46
|
+
if (isNonModal) return (0, $5e3802645cc19319$export$1020fa7f77e17884)((_groupRef_current = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current !== void 0 ? _groupRef_current : popoverRef.current);
|
|
47
|
+
else return (0, $5e3802645cc19319$export$1c3ebcada18427bf)([
|
|
48
|
+
(_groupRef_current1 = groupRef === null || groupRef === void 0 ? void 0 : groupRef.current) !== null && _groupRef_current1 !== void 0 ? _groupRef_current1 : popoverRef.current
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
47
51
|
}, [
|
|
48
52
|
isNonModal,
|
|
49
53
|
state.isOpen,
|
|
50
|
-
popoverRef
|
|
54
|
+
popoverRef,
|
|
55
|
+
groupRef
|
|
51
56
|
]);
|
|
52
57
|
return {
|
|
53
58
|
popoverProps: (0, $m0yab$mergeProps)(overlayProps, positionProps),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;AAAA;;;;;;;;;;CAUC;;;;;
|
|
1
|
+
{"mappings":";;;;;;AAAA;;;;;;;;;;CAUC;;;;;AAoEM,SAAS,0CAAW,KAAuB,EAAE,KAA0B;IAC5E,IAAI,cACF,UAAU,cACV,UAAU,YACV,QAAQ,cACR,UAAU,6BACV,yBAAyB,gCACzB,4BAA4B,EAC5B,GAAG,YACJ,GAAG;IAEJ,IAAI,YAAY,UAAU,CAAC,UAAU,KAAK;IAE1C,IAAI,gBAAC,YAAY,iBAAE,aAAa,EAAC,GAAG,CAAA,GAAA,yCAAS,EAC3C;QACE,QAAQ,MAAM,MAAM;QACpB,SAAS,MAAM,KAAK;QACpB,mBAAmB;QACnB,eAAe,CAAC,cAAc;mCAC9B;sCACA;IACF,GACA,qBAAA,sBAAA,WAAY;IAGd,IAAI,EAAC,cAAc,aAAa,cAAE,UAAU,aAAE,SAAS,EAAC,GAAG,CAAA,GAAA,yCAAiB,EAAE;QAC5E,GAAG,UAAU;QACb,WAAW;QACX,YAAY;QACZ,QAAQ,MAAM,MAAM;QACpB,SAAS,cAAc,CAAC,YAAY,MAAM,KAAK,GAAG;IACpD;IAEA,CAAA,GAAA,yCAAe,EAAE;QACf,YAAY,cAAc,CAAC,MAAM,MAAM;IACzC;IAEA,CAAA,GAAA,sBAAc,EAAE;QACd,IAAI,MAAM,MAAM,IAAI,WAAW,OAAO,EAAE;gBAEjB,mBAEK;YAH1B,IAAI,YACF,OAAO,CAAA,GAAA,yCAAU,EAAE,CAAA,oBAAA,qBAAA,+BAAA,SAAU,OAAO,cAAjB,+BAAA,oBAAqB,WAAW,OAAO;iBAE1D,OAAO,CAAA,GAAA,yCAAc,EAAE;gBAAC,CAAA,qBAAA,qBAAA,+BAAA,SAAU,OAAO,cAAjB,gCAAA,qBAAqB,WAAW,OAAO;aAAC;QAEpE;IACF,GAAG;QAAC;QAAY,MAAM,MAAM;QAAE;QAAY;KAAS;IAEnD,OAAO;QACL,cAAc,CAAA,GAAA,iBAAS,EAAE,cAAc;oBACvC;uBACA;mBACA;IACF;AACF","sources":["packages/@react-aria/overlays/src/usePopover.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {ariaHideOutside, keepVisible} from './ariaHideOutside';\nimport {AriaPositionProps, useOverlayPosition} from './useOverlayPosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {mergeProps, useLayoutEffect} from '@react-aria/utils';\nimport {OverlayTriggerState} from '@react-stately/overlays';\nimport {PlacementAxis} from '@react-types/overlays';\nimport {useOverlay} from './useOverlay';\nimport {usePreventScroll} from './usePreventScroll';\n\nexport interface AriaPopoverProps extends Omit<AriaPositionProps, 'isOpen' | 'onClose' | 'targetRef' | 'overlayRef'> {\n /**\n * The ref for the element which the popover positions itself with respect to.\n */\n triggerRef: RefObject<Element | null>,\n /**\n * The ref for the popover element.\n */\n popoverRef: RefObject<Element | null>,\n /**\n * An optional ref for a group of popovers, e.g. submenus.\n * When provided, this element is used to detect outside interactions\n * and hiding elements from assistive technologies instead of the popoverRef.\n */\n groupRef?: RefObject<Element | null>,\n /**\n * Whether the popover is non-modal, i.e. elements outside the popover may be\n * interacted with by assistive technologies.\n *\n * Most popovers should not use this option as it may negatively impact the screen\n * reader experience. Only use with components such as combobox, which are designed\n * to handle this situation carefully.\n */\n isNonModal?: boolean,\n /**\n * Whether pressing the escape key to close the popover should be disabled.\n *\n * Most popovers should not use this option. When set to true, an alternative\n * way to close the popover with a keyboard must be provided.\n *\n * @default false\n */\n isKeyboardDismissDisabled?: boolean,\n /**\n * When user interacts with the argument element outside of the popover ref,\n * return true if onClose should be called. This gives you a chance to filter\n * out interaction with elements that should not dismiss the popover.\n * By default, onClose will always be called on interaction outside the popover ref.\n */\n shouldCloseOnInteractOutside?: (element: Element) => boolean\n}\n\nexport interface PopoverAria {\n /** Props for the popover element. */\n popoverProps: DOMAttributes,\n /** Props for the popover tip arrow if any. */\n arrowProps: DOMAttributes,\n /** Props to apply to the underlay element, if any. */\n underlayProps: DOMAttributes,\n /** Placement of the popover with respect to the trigger. */\n placement: PlacementAxis | null\n}\n\n/**\n * Provides the behavior and accessibility implementation for a popover component.\n * A popover is an overlay element positioned relative to a trigger.\n */\nexport function usePopover(props: AriaPopoverProps, state: OverlayTriggerState): PopoverAria {\n let {\n triggerRef,\n popoverRef,\n groupRef,\n isNonModal,\n isKeyboardDismissDisabled,\n shouldCloseOnInteractOutside,\n ...otherProps\n } = props;\n\n let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';\n\n let {overlayProps, underlayProps} = useOverlay(\n {\n isOpen: state.isOpen,\n onClose: state.close,\n shouldCloseOnBlur: true,\n isDismissable: !isNonModal || isSubmenu,\n isKeyboardDismissDisabled,\n shouldCloseOnInteractOutside\n },\n groupRef ?? popoverRef\n );\n\n let {overlayProps: positionProps, arrowProps, placement} = useOverlayPosition({\n ...otherProps,\n targetRef: triggerRef,\n overlayRef: popoverRef,\n isOpen: state.isOpen,\n onClose: isNonModal && !isSubmenu ? state.close : null\n });\n\n usePreventScroll({\n isDisabled: isNonModal || !state.isOpen\n });\n\n useLayoutEffect(() => {\n if (state.isOpen && popoverRef.current) {\n if (isNonModal) {\n return keepVisible(groupRef?.current ?? popoverRef.current);\n } else {\n return ariaHideOutside([groupRef?.current ?? popoverRef.current]);\n }\n }\n }, [isNonModal, state.isOpen, popoverRef, groupRef]);\n\n return {\n popoverProps: mergeProps(overlayProps, positionProps),\n arrowProps,\n underlayProps,\n placement\n };\n}\n"],"names":[],"version":3,"file":"usePopover.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-aria/overlays",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.26.1",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@react-aria/focus": "^3.
|
|
26
|
-
"@react-aria/i18n": "^3.12.
|
|
27
|
-
"@react-aria/interactions": "^3.
|
|
25
|
+
"@react-aria/focus": "^3.20.1",
|
|
26
|
+
"@react-aria/i18n": "^3.12.7",
|
|
27
|
+
"@react-aria/interactions": "^3.24.1",
|
|
28
28
|
"@react-aria/ssr": "^3.9.7",
|
|
29
|
-
"@react-aria/utils": "^3.
|
|
30
|
-
"@react-aria/visually-hidden": "^3.8.
|
|
31
|
-
"@react-stately/overlays": "^3.6.
|
|
32
|
-
"@react-types/button": "^3.
|
|
33
|
-
"@react-types/overlays": "^3.8.
|
|
34
|
-
"@react-types/shared": "^3.
|
|
29
|
+
"@react-aria/utils": "^3.28.1",
|
|
30
|
+
"@react-aria/visually-hidden": "^3.8.21",
|
|
31
|
+
"@react-stately/overlays": "^3.6.14",
|
|
32
|
+
"@react-types/button": "^3.11.0",
|
|
33
|
+
"@react-types/overlays": "^3.8.13",
|
|
34
|
+
"@react-types/shared": "^3.28.0",
|
|
35
35
|
"@swc/helpers": "^0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "9c4ebbc0c1972cc880febc29de995ca58caa3ba4"
|
|
45
45
|
}
|
package/src/Overlay.tsx
CHANGED
|
@@ -32,6 +32,10 @@ export interface OverlayProps {
|
|
|
32
32
|
* implement focus containment and restoration to ensure the overlay is keyboard accessible.
|
|
33
33
|
*/
|
|
34
34
|
disableFocusManagement?: boolean,
|
|
35
|
+
/**
|
|
36
|
+
* Whether to contain focus within the overlay.
|
|
37
|
+
*/
|
|
38
|
+
shouldContainFocus?: boolean,
|
|
35
39
|
/**
|
|
36
40
|
* Whether the overlay is currently performing an exit animation. When true,
|
|
37
41
|
* focus is allowed to move outside.
|
|
@@ -63,7 +67,7 @@ export function Overlay(props: OverlayProps) {
|
|
|
63
67
|
let contents = props.children;
|
|
64
68
|
if (!props.disableFocusManagement) {
|
|
65
69
|
contents = (
|
|
66
|
-
<FocusScope restoreFocus contain={contain && !isExiting}>
|
|
70
|
+
<FocusScope restoreFocus contain={(props.shouldContainFocus || contain) && !isExiting}>
|
|
67
71
|
{contents}
|
|
68
72
|
</FocusScope>
|
|
69
73
|
);
|
package/src/ariaHideOutside.ts
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
// subtracted from when showing it again. When it reaches zero, aria-hidden is removed.
|
|
15
15
|
let refCountMap = new WeakMap<Element, number>();
|
|
16
16
|
interface ObserverWrapper {
|
|
17
|
+
visibleNodes: Set<Element>,
|
|
18
|
+
hiddenNodes: Set<Element>,
|
|
17
19
|
observe: () => void,
|
|
18
20
|
disconnect: () => void
|
|
19
21
|
}
|
|
@@ -138,6 +140,8 @@ export function ariaHideOutside(targets: Element[], root = document.body) {
|
|
|
138
140
|
observer.observe(root, {childList: true, subtree: true});
|
|
139
141
|
|
|
140
142
|
let observerWrapper: ObserverWrapper = {
|
|
143
|
+
visibleNodes,
|
|
144
|
+
hiddenNodes,
|
|
141
145
|
observe() {
|
|
142
146
|
observer.observe(root, {childList: true, subtree: true});
|
|
143
147
|
},
|
|
@@ -175,3 +179,13 @@ export function ariaHideOutside(targets: Element[], root = document.body) {
|
|
|
175
179
|
}
|
|
176
180
|
};
|
|
177
181
|
}
|
|
182
|
+
|
|
183
|
+
export function keepVisible(element: Element) {
|
|
184
|
+
let observer = observerStack[observerStack.length - 1];
|
|
185
|
+
if (observer && !observer.visibleNodes.has(element)) {
|
|
186
|
+
observer.visibleNodes.add(element);
|
|
187
|
+
return () => {
|
|
188
|
+
observer.visibleNodes.delete(element);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
package/src/useOverlay.ts
CHANGED
|
@@ -72,16 +72,15 @@ export function useOverlay(props: AriaOverlayProps, ref: RefObject<Element | nul
|
|
|
72
72
|
|
|
73
73
|
// Add the overlay ref to the stack of visible overlays on mount, and remove on unmount.
|
|
74
74
|
useEffect(() => {
|
|
75
|
-
if (isOpen) {
|
|
75
|
+
if (isOpen && !visibleOverlays.includes(ref)) {
|
|
76
76
|
visibleOverlays.push(ref);
|
|
77
|
+
return () => {
|
|
78
|
+
let index = visibleOverlays.indexOf(ref);
|
|
79
|
+
if (index >= 0) {
|
|
80
|
+
visibleOverlays.splice(index, 1);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
77
83
|
}
|
|
78
|
-
|
|
79
|
-
return () => {
|
|
80
|
-
let index = visibleOverlays.indexOf(ref);
|
|
81
|
-
if (index >= 0) {
|
|
82
|
-
visibleOverlays.splice(index, 1);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
84
|
}, [isOpen, ref]);
|
|
86
85
|
|
|
87
86
|
// Only hide the overlay when it is the topmost visible overlay in the stack
|
package/src/usePopover.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {ariaHideOutside} from './ariaHideOutside';
|
|
13
|
+
import {ariaHideOutside, keepVisible} from './ariaHideOutside';
|
|
14
14
|
import {AriaPositionProps, useOverlayPosition} from './useOverlayPosition';
|
|
15
15
|
import {DOMAttributes, RefObject} from '@react-types/shared';
|
|
16
16
|
import {mergeProps, useLayoutEffect} from '@react-aria/utils';
|
|
@@ -28,6 +28,12 @@ export interface AriaPopoverProps extends Omit<AriaPositionProps, 'isOpen' | 'on
|
|
|
28
28
|
* The ref for the popover element.
|
|
29
29
|
*/
|
|
30
30
|
popoverRef: RefObject<Element | null>,
|
|
31
|
+
/**
|
|
32
|
+
* An optional ref for a group of popovers, e.g. submenus.
|
|
33
|
+
* When provided, this element is used to detect outside interactions
|
|
34
|
+
* and hiding elements from assistive technologies instead of the popoverRef.
|
|
35
|
+
*/
|
|
36
|
+
groupRef?: RefObject<Element | null>,
|
|
31
37
|
/**
|
|
32
38
|
* Whether the popover is non-modal, i.e. elements outside the popover may be
|
|
33
39
|
* interacted with by assistive technologies.
|
|
@@ -74,23 +80,25 @@ export function usePopover(props: AriaPopoverProps, state: OverlayTriggerState):
|
|
|
74
80
|
let {
|
|
75
81
|
triggerRef,
|
|
76
82
|
popoverRef,
|
|
83
|
+
groupRef,
|
|
77
84
|
isNonModal,
|
|
78
85
|
isKeyboardDismissDisabled,
|
|
79
86
|
shouldCloseOnInteractOutside,
|
|
80
87
|
...otherProps
|
|
81
88
|
} = props;
|
|
82
89
|
|
|
90
|
+
let isSubmenu = otherProps['trigger'] === 'SubmenuTrigger';
|
|
91
|
+
|
|
83
92
|
let {overlayProps, underlayProps} = useOverlay(
|
|
84
93
|
{
|
|
85
|
-
|
|
86
|
-
isOpen: state.isOpen && !otherProps['data-react-aria-top-layer'],
|
|
94
|
+
isOpen: state.isOpen,
|
|
87
95
|
onClose: state.close,
|
|
88
96
|
shouldCloseOnBlur: true,
|
|
89
|
-
isDismissable: !isNonModal,
|
|
97
|
+
isDismissable: !isNonModal || isSubmenu,
|
|
90
98
|
isKeyboardDismissDisabled,
|
|
91
99
|
shouldCloseOnInteractOutside
|
|
92
100
|
},
|
|
93
|
-
popoverRef
|
|
101
|
+
groupRef ?? popoverRef
|
|
94
102
|
);
|
|
95
103
|
|
|
96
104
|
let {overlayProps: positionProps, arrowProps, placement} = useOverlayPosition({
|
|
@@ -98,7 +106,7 @@ export function usePopover(props: AriaPopoverProps, state: OverlayTriggerState):
|
|
|
98
106
|
targetRef: triggerRef,
|
|
99
107
|
overlayRef: popoverRef,
|
|
100
108
|
isOpen: state.isOpen,
|
|
101
|
-
onClose: isNonModal ? state.close : null
|
|
109
|
+
onClose: isNonModal && !isSubmenu ? state.close : null
|
|
102
110
|
});
|
|
103
111
|
|
|
104
112
|
usePreventScroll({
|
|
@@ -106,10 +114,14 @@ export function usePopover(props: AriaPopoverProps, state: OverlayTriggerState):
|
|
|
106
114
|
});
|
|
107
115
|
|
|
108
116
|
useLayoutEffect(() => {
|
|
109
|
-
if (state.isOpen &&
|
|
110
|
-
|
|
117
|
+
if (state.isOpen && popoverRef.current) {
|
|
118
|
+
if (isNonModal) {
|
|
119
|
+
return keepVisible(groupRef?.current ?? popoverRef.current);
|
|
120
|
+
} else {
|
|
121
|
+
return ariaHideOutside([groupRef?.current ?? popoverRef.current]);
|
|
122
|
+
}
|
|
111
123
|
}
|
|
112
|
-
}, [isNonModal, state.isOpen, popoverRef]);
|
|
124
|
+
}, [isNonModal, state.isOpen, popoverRef, groupRef]);
|
|
113
125
|
|
|
114
126
|
return {
|
|
115
127
|
popoverProps: mergeProps(overlayProps, positionProps),
|