@atlaskit/top-layer 0.12.2 → 0.14.0
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/CHANGELOG.md +31 -0
- package/README.md +61 -34
- package/dist/cjs/animations/presets.js +4 -4
- package/dist/cjs/entry-points/focus.js +6 -4
- package/dist/cjs/entry-points/get-aria-for-trigger.js +12 -0
- package/dist/cjs/entry-points/popover-surface.js +12 -0
- package/dist/cjs/entry-points/use-anchor-position-at-point.js +12 -0
- package/dist/cjs/entry-points/use-popover-id.js +21 -0
- package/dist/cjs/focus/get-first-focusable.js +19 -0
- package/dist/cjs/focus/get-focusables.js +30 -0
- package/dist/cjs/focus/get-last-focusable.js +19 -0
- package/dist/cjs/focus/get-next-focusable.js +43 -0
- package/dist/cjs/focus/is-in-same-layer.js +23 -0
- package/dist/cjs/focus/is-nested-layer-focused.js +32 -0
- package/dist/cjs/focus/selectors.js +19 -0
- package/dist/cjs/focus/types.js +1 -0
- package/dist/cjs/internal/get-aria-for-trigger.js +88 -0
- package/dist/cjs/internal/role-to-aria-has-popup.js +37 -0
- package/dist/cjs/internal/role-types.js +2 -35
- package/dist/cjs/internal/should-focus-into-popover.js +19 -0
- package/dist/cjs/internal/slot.js +1 -1
- package/dist/cjs/internal/use-anchor-position-at-point.js +127 -0
- package/dist/cjs/internal/use-anchor-position.js +36 -16
- package/dist/cjs/internal/use-focus-wrap.js +8 -5
- package/dist/cjs/internal/use-initial-focus.js +4 -4
- package/dist/cjs/placement-map/index.js +2 -2
- package/dist/cjs/placement-map/legacy-placements.js +2 -101
- package/dist/cjs/placement-map/placement-mapping.js +103 -0
- package/dist/cjs/popover/popover.js +79 -80
- package/dist/cjs/popover-surface/index.js +12 -0
- package/dist/cjs/{popup/popup-surface.js → popover-surface/popover-surface.js} +9 -12
- package/dist/cjs/testing/polyfill.js +9 -6
- package/dist/cjs/use-arrow-navigation/use-arrow-navigation.js +7 -5
- package/dist/es2019/animations/presets.js +4 -4
- package/dist/es2019/entry-points/focus.js +3 -1
- package/dist/es2019/entry-points/get-aria-for-trigger.js +1 -0
- package/dist/es2019/entry-points/popover-surface.js +1 -0
- package/dist/es2019/entry-points/use-anchor-position-at-point.js +1 -0
- package/dist/es2019/entry-points/use-popover-id.js +15 -0
- package/dist/es2019/focus/get-first-focusable.js +14 -0
- package/dist/es2019/focus/get-focusables.js +19 -0
- package/dist/es2019/focus/get-last-focusable.js +14 -0
- package/dist/es2019/focus/get-next-focusable.js +38 -0
- package/dist/es2019/focus/is-in-same-layer.js +18 -0
- package/dist/es2019/focus/is-nested-layer-focused.js +28 -0
- package/dist/es2019/focus/selectors.js +11 -0
- package/dist/es2019/focus/types.js +0 -0
- package/dist/es2019/internal/get-aria-for-trigger.js +84 -0
- package/dist/es2019/internal/role-to-aria-has-popup.js +32 -0
- package/dist/es2019/internal/role-types.js +0 -33
- package/dist/es2019/internal/should-focus-into-popover.js +14 -0
- package/dist/es2019/internal/slot.js +1 -1
- package/dist/es2019/internal/use-anchor-position-at-point.js +122 -0
- package/dist/es2019/internal/use-anchor-position.js +21 -14
- package/dist/es2019/internal/use-focus-wrap.js +4 -1
- package/dist/es2019/internal/use-initial-focus.js +1 -1
- package/dist/es2019/placement-map/index.js +1 -1
- package/dist/es2019/placement-map/legacy-placements.js +1 -100
- package/dist/es2019/placement-map/placement-mapping.js +97 -0
- package/dist/es2019/popover/popover.js +79 -80
- package/dist/es2019/popover-surface/index.js +1 -0
- package/dist/es2019/popover-surface/popover-surface.js +27 -0
- package/dist/es2019/testing/polyfill.js +9 -6
- package/dist/es2019/use-arrow-navigation/use-arrow-navigation.js +3 -1
- package/dist/esm/animations/presets.js +4 -4
- package/dist/esm/entry-points/focus.js +3 -1
- package/dist/esm/entry-points/get-aria-for-trigger.js +1 -0
- package/dist/esm/entry-points/popover-surface.js +1 -0
- package/dist/esm/entry-points/use-anchor-position-at-point.js +1 -0
- package/dist/esm/entry-points/use-popover-id.js +15 -0
- package/dist/esm/focus/get-first-focusable.js +13 -0
- package/dist/esm/focus/get-focusables.js +24 -0
- package/dist/esm/focus/get-last-focusable.js +13 -0
- package/dist/esm/focus/get-next-focusable.js +37 -0
- package/dist/esm/focus/is-in-same-layer.js +17 -0
- package/dist/esm/focus/is-nested-layer-focused.js +27 -0
- package/dist/esm/focus/selectors.js +13 -0
- package/dist/esm/focus/types.js +0 -0
- package/dist/esm/internal/get-aria-for-trigger.js +83 -0
- package/dist/esm/internal/role-to-aria-has-popup.js +31 -0
- package/dist/esm/internal/role-types.js +2 -34
- package/dist/esm/internal/should-focus-into-popover.js +13 -0
- package/dist/esm/internal/slot.js +1 -1
- package/dist/esm/internal/use-anchor-position-at-point.js +122 -0
- package/dist/esm/internal/use-anchor-position.js +36 -16
- package/dist/esm/internal/use-focus-wrap.js +4 -1
- package/dist/esm/internal/use-initial-focus.js +1 -1
- package/dist/esm/placement-map/index.js +1 -1
- package/dist/esm/placement-map/legacy-placements.js +1 -100
- package/dist/esm/placement-map/placement-mapping.js +97 -0
- package/dist/esm/popover/popover.js +79 -80
- package/dist/esm/popover-surface/index.js +1 -0
- package/dist/esm/popover-surface/popover-surface.js +26 -0
- package/dist/esm/testing/polyfill.js +9 -6
- package/dist/esm/use-arrow-navigation/use-arrow-navigation.js +3 -1
- package/dist/types/animations/presets.d.ts +4 -4
- package/dist/types/animations/types.d.ts +1 -1
- package/dist/types/dialog/types.d.ts +0 -8
- package/dist/types/entry-points/focus.d.ts +4 -2
- package/dist/types/entry-points/get-aria-for-trigger.d.ts +1 -0
- package/dist/types/entry-points/popover-surface.d.ts +2 -0
- package/dist/types/entry-points/popover.d.ts +1 -1
- package/dist/types/entry-points/use-anchor-position-at-point.d.ts +1 -0
- package/dist/types/entry-points/use-popover-id.d.ts +11 -0
- package/dist/types/focus/get-first-focusable.d.ts +8 -0
- package/dist/types/focus/get-focusables.d.ts +13 -0
- package/dist/types/focus/get-last-focusable.d.ts +8 -0
- package/dist/types/focus/get-next-focusable.d.ts +13 -0
- package/dist/types/focus/is-in-same-layer.d.ts +8 -0
- package/dist/types/focus/is-nested-layer-focused.d.ts +8 -0
- package/dist/types/focus/selectors.d.ts +4 -0
- package/dist/types/focus/types.d.ts +5 -0
- package/dist/types/internal/get-aria-for-trigger.d.ts +86 -0
- package/dist/types/internal/role-to-aria-has-popup.d.ts +13 -0
- package/dist/types/internal/role-types.d.ts +0 -12
- package/dist/types/internal/should-focus-into-popover.d.ts +8 -0
- package/dist/types/internal/slot.d.ts +2 -2
- package/dist/types/internal/use-anchor-position-at-point.d.ts +62 -0
- package/dist/types/internal/use-anchor-position.d.ts +6 -1
- package/dist/types/placement-map/index.d.ts +1 -1
- package/dist/types/placement-map/legacy-placements.d.ts +0 -12
- package/dist/types/placement-map/placement-mapping.d.ts +13 -0
- package/dist/types/popover/index.d.ts +1 -1
- package/dist/types/popover/popover.d.ts +6 -13
- package/dist/types/popover/types.d.ts +6 -5
- package/dist/types/popover-surface/index.d.ts +2 -0
- package/dist/types/popover-surface/popover-surface.d.ts +21 -0
- package/dist/types/use-arrow-navigation/use-arrow-navigation.d.ts +1 -1
- package/dist/types-ts4.5/animations/presets.d.ts +4 -4
- package/dist/types-ts4.5/animations/types.d.ts +1 -1
- package/dist/types-ts4.5/dialog/types.d.ts +0 -8
- package/dist/types-ts4.5/entry-points/focus.d.ts +4 -2
- package/dist/types-ts4.5/entry-points/get-aria-for-trigger.d.ts +1 -0
- package/dist/types-ts4.5/entry-points/popover-surface.d.ts +2 -0
- package/dist/types-ts4.5/entry-points/popover.d.ts +1 -1
- package/dist/types-ts4.5/entry-points/use-anchor-position-at-point.d.ts +1 -0
- package/dist/types-ts4.5/entry-points/use-popover-id.d.ts +11 -0
- package/dist/types-ts4.5/focus/get-first-focusable.d.ts +8 -0
- package/dist/types-ts4.5/focus/get-focusables.d.ts +13 -0
- package/dist/types-ts4.5/focus/get-last-focusable.d.ts +8 -0
- package/dist/types-ts4.5/focus/get-next-focusable.d.ts +13 -0
- package/dist/types-ts4.5/focus/is-in-same-layer.d.ts +8 -0
- package/dist/types-ts4.5/focus/is-nested-layer-focused.d.ts +8 -0
- package/dist/types-ts4.5/focus/selectors.d.ts +4 -0
- package/dist/types-ts4.5/focus/types.d.ts +5 -0
- package/dist/types-ts4.5/internal/get-aria-for-trigger.d.ts +86 -0
- package/dist/types-ts4.5/internal/role-to-aria-has-popup.d.ts +13 -0
- package/dist/types-ts4.5/internal/role-types.d.ts +0 -12
- package/dist/types-ts4.5/internal/should-focus-into-popover.d.ts +8 -0
- package/dist/types-ts4.5/internal/slot.d.ts +2 -2
- package/dist/types-ts4.5/internal/use-anchor-position-at-point.d.ts +62 -0
- package/dist/types-ts4.5/internal/use-anchor-position.d.ts +6 -1
- package/dist/types-ts4.5/placement-map/index.d.ts +1 -1
- package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +0 -12
- package/dist/types-ts4.5/placement-map/placement-mapping.d.ts +13 -0
- package/dist/types-ts4.5/popover/index.d.ts +1 -1
- package/dist/types-ts4.5/popover/popover.d.ts +6 -13
- package/dist/types-ts4.5/popover/types.d.ts +6 -5
- package/dist/types-ts4.5/popover-surface/index.d.ts +2 -0
- package/dist/types-ts4.5/popover-surface/popover-surface.d.ts +21 -0
- package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +1 -1
- package/get-aria-for-trigger/package.json +17 -0
- package/package.json +3 -3
- package/popover-surface/package.json +17 -0
- package/use-anchor-position-at-point/package.json +17 -0
- package/use-popover-id/package.json +17 -0
- package/dist/cjs/entry-points/popup-surface.js +0 -12
- package/dist/cjs/entry-points/popup.js +0 -12
- package/dist/cjs/focus/focus.js +0 -169
- package/dist/cjs/focus/index.js +0 -24
- package/dist/cjs/popup/index.js +0 -37
- package/dist/cjs/popup/popup-content.js +0 -214
- package/dist/cjs/popup/popup-context.js +0 -25
- package/dist/cjs/popup/popup-provider.js +0 -15
- package/dist/cjs/popup/popup-trigger-function.js +0 -80
- package/dist/cjs/popup/popup-trigger.js +0 -66
- package/dist/cjs/popup/popup.js +0 -81
- package/dist/cjs/popup/types.js +0 -5
- package/dist/cjs/popup/use-maybe-popup-context.js +0 -17
- package/dist/cjs/popup/use-popup-context.js +0 -20
- package/dist/es2019/entry-points/popup-surface.js +0 -1
- package/dist/es2019/entry-points/popup.js +0 -1
- package/dist/es2019/focus/focus.js +0 -158
- package/dist/es2019/focus/index.js +0 -1
- package/dist/es2019/popup/index.js +0 -33
- package/dist/es2019/popup/popup-content.js +0 -206
- package/dist/es2019/popup/popup-context.js +0 -20
- package/dist/es2019/popup/popup-provider.js +0 -10
- package/dist/es2019/popup/popup-surface.js +0 -30
- package/dist/es2019/popup/popup-trigger-function.js +0 -75
- package/dist/es2019/popup/popup-trigger.js +0 -61
- package/dist/es2019/popup/popup.js +0 -67
- package/dist/es2019/popup/types.js +0 -1
- package/dist/es2019/popup/use-maybe-popup-context.js +0 -12
- package/dist/es2019/popup/use-popup-context.js +0 -15
- package/dist/esm/entry-points/popup-surface.js +0 -1
- package/dist/esm/entry-points/popup.js +0 -1
- package/dist/esm/focus/focus.js +0 -160
- package/dist/esm/focus/index.js +0 -1
- package/dist/esm/popup/index.js +0 -33
- package/dist/esm/popup/popup-content.js +0 -206
- package/dist/esm/popup/popup-context.js +0 -20
- package/dist/esm/popup/popup-provider.js +0 -10
- package/dist/esm/popup/popup-surface.js +0 -29
- package/dist/esm/popup/popup-trigger-function.js +0 -75
- package/dist/esm/popup/popup-trigger.js +0 -59
- package/dist/esm/popup/popup.js +0 -72
- package/dist/esm/popup/types.js +0 -1
- package/dist/esm/popup/use-maybe-popup-context.js +0 -12
- package/dist/esm/popup/use-popup-context.js +0 -15
- package/dist/types/entry-points/popup-surface.d.ts +0 -2
- package/dist/types/entry-points/popup.d.ts +0 -2
- package/dist/types/focus/focus.d.ts +0 -50
- package/dist/types/focus/index.d.ts +0 -2
- package/dist/types/popup/index.d.ts +0 -34
- package/dist/types/popup/popup-content.d.ts +0 -14
- package/dist/types/popup/popup-context.d.ts +0 -96
- package/dist/types/popup/popup-provider.d.ts +0 -10
- package/dist/types/popup/popup-surface.d.ts +0 -22
- package/dist/types/popup/popup-trigger-function.d.ts +0 -112
- package/dist/types/popup/popup-trigger.d.ts +0 -14
- package/dist/types/popup/popup.d.ts +0 -14
- package/dist/types/popup/types.d.ts +0 -321
- package/dist/types/popup/use-maybe-popup-context.d.ts +0 -8
- package/dist/types/popup/use-popup-context.d.ts +0 -7
- package/dist/types-ts4.5/entry-points/popup-surface.d.ts +0 -2
- package/dist/types-ts4.5/entry-points/popup.d.ts +0 -2
- package/dist/types-ts4.5/focus/focus.d.ts +0 -50
- package/dist/types-ts4.5/focus/index.d.ts +0 -2
- package/dist/types-ts4.5/popup/index.d.ts +0 -34
- package/dist/types-ts4.5/popup/popup-content.d.ts +0 -14
- package/dist/types-ts4.5/popup/popup-context.d.ts +0 -96
- package/dist/types-ts4.5/popup/popup-provider.d.ts +0 -10
- package/dist/types-ts4.5/popup/popup-surface.d.ts +0 -22
- package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +0 -112
- package/dist/types-ts4.5/popup/popup-trigger.d.ts +0 -14
- package/dist/types-ts4.5/popup/popup.d.ts +0 -14
- package/dist/types-ts4.5/popup/types.d.ts +0 -321
- package/dist/types-ts4.5/popup/use-maybe-popup-context.d.ts +0 -8
- package/dist/types-ts4.5/popup/use-popup-context.d.ts +0 -7
- package/popup/package.json +0 -17
- package/popup-surface/package.json +0 -17
- /package/dist/cjs/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
- /package/dist/es2019/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
- /package/dist/esm/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { PopupContext } from './popup-context';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns the popup context if available, or `null` when used outside `<Popup>`.
|
|
6
|
-
*
|
|
7
|
-
* Used by `PopupContent` to support standalone usage (e.g. tooltip)
|
|
8
|
-
* where values are passed as props instead of coming from a compound component.
|
|
9
|
-
*/
|
|
10
|
-
export function useMaybePopupContext() {
|
|
11
|
-
return useContext(PopupContext);
|
|
12
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { PopupContext } from './popup-context';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns the nearest `Popup` context value.
|
|
6
|
-
*
|
|
7
|
-
* Throws if called outside of a `<Popup>` compound component.
|
|
8
|
-
*/
|
|
9
|
-
export function usePopupContext() {
|
|
10
|
-
const ctx = useContext(PopupContext);
|
|
11
|
-
if (ctx === null) {
|
|
12
|
-
throw new Error('@atlaskit/top-layer: Popup compound components must be used within <Popup>.');
|
|
13
|
-
}
|
|
14
|
-
return ctx;
|
|
15
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { PopupSurface } from '../popup/popup-surface';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Popup } from '../popup';
|
package/dist/esm/focus/focus.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Focusable element selectors and navigation helpers.
|
|
3
|
-
*
|
|
4
|
-
* Uses CSS selectors to discover focusable elements within a container,
|
|
5
|
-
* avoiding the need for a manual registration system. Disabled elements
|
|
6
|
-
* (both HTML `disabled` attribute and `aria-disabled="true"`) and elements
|
|
7
|
-
* with `tabindex="-1"` are excluded automatically.
|
|
8
|
-
*
|
|
9
|
-
* All public functions accept an optional `filter` callback to further
|
|
10
|
-
* restrict which focusable elements are included.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { getDocument } from '@atlaskit/browser-apis';
|
|
14
|
-
var selectors = function () {
|
|
15
|
-
// Common exclusion filter applied to every selector.
|
|
16
|
-
var not = ':not([tabindex="-1"]):not([aria-disabled="true"]):not([aria-hidden="true"])';
|
|
17
|
-
var notDisabled = ":not([disabled])".concat(not);
|
|
18
|
-
var focusable = ["a[href]".concat(not), "area[href]".concat(not), "input".concat(notDisabled, ":not([type=\"hidden\"])"), "select".concat(notDisabled), "textarea".concat(notDisabled), "button".concat(notDisabled), "iframe".concat(not), "audio[controls]".concat(not), "video[controls]".concat(not), "[contenteditable]:not([contenteditable=\"false\"])".concat(not), "[tabindex]".concat(notDisabled).concat(not)];
|
|
19
|
-
return {
|
|
20
|
-
focusable: focusable.join(','),
|
|
21
|
-
// Build the `:focus` selector
|
|
22
|
-
focused: focusable.map(function (selector) {
|
|
23
|
-
return "".concat(selector, ":focus");
|
|
24
|
-
}).join(',')
|
|
25
|
-
};
|
|
26
|
-
}();
|
|
27
|
-
var topLayerSelector = '[popover], dialog, [role="dialog"], [role="alertdialog"]';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Returns true when `element` and `container` resolve to the same nearest
|
|
31
|
-
* top-layer host (or both resolve to `null`, meaning the document layer).
|
|
32
|
-
*/
|
|
33
|
-
function isInSameLayer(_ref) {
|
|
34
|
-
var element = _ref.element,
|
|
35
|
-
container = _ref.container;
|
|
36
|
-
var elementLayer = element.closest(topLayerSelector);
|
|
37
|
-
var containerLayer = container.closest(topLayerSelector);
|
|
38
|
-
// Both elements are in the "document" layer
|
|
39
|
-
if (!elementLayer && !containerLayer) {
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
return elementLayer === containerLayer;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Returns `true` when `document.activeElement` is inside a nested top-layer
|
|
47
|
-
* descendant of `container` (a `[popover]`, `<dialog>`, `[role="dialog"]` or
|
|
48
|
-
* `[role="alertdialog"]` that is itself a descendant of `container`).
|
|
49
|
-
*/
|
|
50
|
-
export function isNestedLayerFocused(_ref2) {
|
|
51
|
-
var _getDocument;
|
|
52
|
-
var container = _ref2.container;
|
|
53
|
-
var focused = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.activeElement;
|
|
54
|
-
if (!(focused instanceof HTMLElement)) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Cannot be in a nested layer if it is not in the container
|
|
59
|
-
if (!container.contains(focused)) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// If not in the same layer, must be in a nested layer
|
|
64
|
-
return !isInSameLayer({
|
|
65
|
-
element: focused,
|
|
66
|
-
container: container
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* An optional callback to restrict which focusable elements are included.
|
|
72
|
-
* Return `true` to include the element, `false` to skip it.
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Returns all focusable HTMLElements within the container, optionally filtered.
|
|
77
|
-
*
|
|
78
|
-
* Focusables that belong to a nested top-layer scope (a `[popover]` or
|
|
79
|
-
* `<dialog>` descendant of the container) are excluded - those elements
|
|
80
|
-
* are owned by the inner layer's focus management. The container itself
|
|
81
|
-
* is allowed to be a popover/dialog; only nested ones are filtered.
|
|
82
|
-
*/
|
|
83
|
-
function getFocusables(_ref3) {
|
|
84
|
-
var container = _ref3.container,
|
|
85
|
-
filter = _ref3.filter;
|
|
86
|
-
return Array.from(container.querySelectorAll(selectors.focusable)).filter(function (element) {
|
|
87
|
-
return element instanceof HTMLElement;
|
|
88
|
-
}).filter(function (element) {
|
|
89
|
-
return isInSameLayer({
|
|
90
|
-
element: element,
|
|
91
|
-
container: container
|
|
92
|
-
});
|
|
93
|
-
}).filter(function (element) {
|
|
94
|
-
return !filter || filter(element, container);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Returns the first focusable element within the container.
|
|
100
|
-
*/
|
|
101
|
-
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
102
|
-
export function getFirstFocusable(_ref4) {
|
|
103
|
-
var container = _ref4.container,
|
|
104
|
-
filter = _ref4.filter;
|
|
105
|
-
var items = getFocusables({
|
|
106
|
-
container: container,
|
|
107
|
-
filter: filter
|
|
108
|
-
});
|
|
109
|
-
return items.length > 0 ? items[0] : null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Returns the last focusable element within the container.
|
|
114
|
-
*/
|
|
115
|
-
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
116
|
-
export function getLastFocusable(_ref5) {
|
|
117
|
-
var container = _ref5.container,
|
|
118
|
-
filter = _ref5.filter;
|
|
119
|
-
var items = getFocusables({
|
|
120
|
-
container: container,
|
|
121
|
-
filter: filter
|
|
122
|
-
});
|
|
123
|
-
return items.length > 0 ? items[items.length - 1] : null;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Returns the next focusable element in the given direction relative to the
|
|
128
|
-
* currently focused element within the container. Wraps around at both ends.
|
|
129
|
-
*
|
|
130
|
-
* Returns `null` if there is no focused element within the container or if
|
|
131
|
-
* the focused element is not in the list of focusable elements.
|
|
132
|
-
*/
|
|
133
|
-
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
134
|
-
export function getNextFocusable(_ref6) {
|
|
135
|
-
var _all$nextIndex;
|
|
136
|
-
var container = _ref6.container,
|
|
137
|
-
direction = _ref6.direction,
|
|
138
|
-
filter = _ref6.filter;
|
|
139
|
-
var all = getFocusables({
|
|
140
|
-
container: container,
|
|
141
|
-
filter: filter
|
|
142
|
-
});
|
|
143
|
-
var current = container.querySelector(selectors.focused);
|
|
144
|
-
if (!(current instanceof HTMLElement)) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
var index = all.indexOf(current);
|
|
148
|
-
if (index === -1) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
var nextIndex = function () {
|
|
152
|
-
if (direction === 'forwards') {
|
|
153
|
-
return (index + 1) % all.length;
|
|
154
|
-
}
|
|
155
|
-
var proposed = index - 1;
|
|
156
|
-
// if going into negative numbers, loop back to the last item
|
|
157
|
-
return proposed < 0 ? all.length - 1 : proposed;
|
|
158
|
-
}();
|
|
159
|
-
return (_all$nextIndex = all[nextIndex]) !== null && _all$nextIndex !== void 0 ? _all$nextIndex : null;
|
|
160
|
-
}
|
package/dist/esm/focus/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { getFirstFocusable, getLastFocusable, getNextFocusable } from './focus';
|
package/dist/esm/popup/index.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { PopupRoot } from './popup';
|
|
2
|
-
import { PopupContent } from './popup-content';
|
|
3
|
-
import { PopupSurface } from './popup-surface';
|
|
4
|
-
import { PopupTrigger } from './popup-trigger';
|
|
5
|
-
import { PopupTriggerFunction } from './popup-trigger-function';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Compound component for rendering content in the browser's top layer
|
|
9
|
-
* using the native Popover API (`popover="auto"`).
|
|
10
|
-
* Placement is owned by this compound: root provides it via context, Content applies it
|
|
11
|
-
* (CSS Anchor Positioning or JS fallback).
|
|
12
|
-
*
|
|
13
|
-
* For default overlay styling (background, shadow, border-radius), see `PopupSurface` in the package examples.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```tsx
|
|
17
|
-
* <Popup placement={{ edge: 'end' }} onClose={handleClose}>
|
|
18
|
-
* <Popup.Trigger>
|
|
19
|
-
* <button>Open</button>
|
|
20
|
-
* </Popup.Trigger>
|
|
21
|
-
* <Popup.Content role="dialog" label="My popup">
|
|
22
|
-
* Content goes here
|
|
23
|
-
* </Popup.Content>
|
|
24
|
-
* </Popup>
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
var Popup = Object.assign(PopupRoot, {
|
|
28
|
-
Trigger: PopupTrigger,
|
|
29
|
-
TriggerFunction: PopupTriggerFunction,
|
|
30
|
-
Content: PopupContent,
|
|
31
|
-
Surface: PopupSurface
|
|
32
|
-
});
|
|
33
|
-
export { Popup };
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
/* popup-content.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
-
import { ax, ix } from "@compiled/react/runtime";
|
|
4
|
-
import React, { forwardRef, useCallback, useLayoutEffect, useRef } from 'react';
|
|
5
|
-
import mergeRefs from '@atlaskit/ds-lib/merge-refs';
|
|
6
|
-
import { prefersReducedMotion } from '../internal/reduced-motion';
|
|
7
|
-
import { roleToAriaHasPopup, shouldFocusIntoPopover } from '../internal/role-types';
|
|
8
|
-
import { useAnchorPosition } from '../internal/use-anchor-position';
|
|
9
|
-
import { useWidthFromAnchor } from '../internal/use-width-from-anchor';
|
|
10
|
-
import { Popover } from '../popover/popover';
|
|
11
|
-
import { useMaybePopupContext } from './use-maybe-popup-context';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Thin context wrapper that composes `Popover` + `useAnchorPosition`.
|
|
15
|
-
*
|
|
16
|
-
* Used inside the `<Popup>` compound - reads triggerRef, placement, isOpen,
|
|
17
|
-
* and onClose from context. For standalone usage (tooltip, spotlight, flag),
|
|
18
|
-
* use `Popover` + `useAnchorPosition` directly.
|
|
19
|
-
*/
|
|
20
|
-
export var PopupContent = /*#__PURE__*/forwardRef(function PopupContent(_ref, ref) {
|
|
21
|
-
var _ref2, _ctx$popoverRef;
|
|
22
|
-
var children = _ref.children,
|
|
23
|
-
role = _ref.role,
|
|
24
|
-
label = _ref.label,
|
|
25
|
-
labelledBy = _ref.labelledBy,
|
|
26
|
-
animate = _ref.animate,
|
|
27
|
-
mode = _ref.mode,
|
|
28
|
-
_ref$widthFromAnchor = _ref.widthFromAnchor,
|
|
29
|
-
widthFromAnchor = _ref$widthFromAnchor === void 0 ? 'none' : _ref$widthFromAnchor,
|
|
30
|
-
xcss = _ref.xcss,
|
|
31
|
-
isOpenProp = _ref.isOpen,
|
|
32
|
-
triggerRefProp = _ref.triggerRef,
|
|
33
|
-
placementProp = _ref.placement,
|
|
34
|
-
onCloseProp = _ref.onClose,
|
|
35
|
-
testIdProp = _ref.testId,
|
|
36
|
-
forceFallbackPositioningProp = _ref.forceFallbackPositioning,
|
|
37
|
-
idProp = _ref.id,
|
|
38
|
-
onEnterFinish = _ref.onEnterFinish,
|
|
39
|
-
onExitFinish = _ref.onExitFinish;
|
|
40
|
-
// When inside <Popup>, context provides defaults. Props always win.
|
|
41
|
-
var ctx = useMaybePopupContext();
|
|
42
|
-
var triggerRef = triggerRefProp !== null && triggerRefProp !== void 0 ? triggerRefProp : ctx === null || ctx === void 0 ? void 0 : ctx.triggerRef;
|
|
43
|
-
var placement = (_ref2 = placementProp !== null && placementProp !== void 0 ? placementProp : ctx === null || ctx === void 0 ? void 0 : ctx.placement) !== null && _ref2 !== void 0 ? _ref2 : {};
|
|
44
|
-
var onClose = onCloseProp !== null && onCloseProp !== void 0 ? onCloseProp : ctx === null || ctx === void 0 ? void 0 : ctx.onClose;
|
|
45
|
-
var testId = testIdProp !== null && testIdProp !== void 0 ? testIdProp : ctx === null || ctx === void 0 ? void 0 : ctx.testId;
|
|
46
|
-
var forceFallbackPositioning = forceFallbackPositioningProp !== null && forceFallbackPositioningProp !== void 0 ? forceFallbackPositioningProp : ctx === null || ctx === void 0 ? void 0 : ctx.forceFallbackPositioning;
|
|
47
|
-
|
|
48
|
-
// isOpen: prop wins, otherwise derive from context popupState.
|
|
49
|
-
// 'animating-open' counts as open so <Popover> stays visible during entry animation.
|
|
50
|
-
var isOpen = isOpenProp !== null && isOpenProp !== void 0 ? isOpenProp : ctx !== null ? ctx.popupState === 'open' || ctx.popupState === 'animating-open' : false;
|
|
51
|
-
var setPopupState = ctx === null || ctx === void 0 ? void 0 : ctx.setPopupState;
|
|
52
|
-
var consumerOnOpenChange = ctx === null || ctx === void 0 ? void 0 : ctx.onOpenChange;
|
|
53
|
-
|
|
54
|
-
// ── TPopupState ──
|
|
55
|
-
//
|
|
56
|
-
// popupState is driven by handleOpenChange (below), which fires on every browser
|
|
57
|
-
// toggle event (showPopover / hidePopover / light-dismiss).
|
|
58
|
-
//
|
|
59
|
-
// Exception — initial mount with isOpen=true (prop-controlled usage):
|
|
60
|
-
// handleOpenChange only fires from the Popover's toggle event listener, which
|
|
61
|
-
// is registered in a useEffect. On the first render, useEffect hasn't run yet,
|
|
62
|
-
// so handleOpenChange never fires. We sync popupState here instead.
|
|
63
|
-
//
|
|
64
|
-
// Transitions when animations are active:
|
|
65
|
-
// closed → animating-open → open (enter)
|
|
66
|
-
// open → animating-closed → closed (exit, via onExitFinish)
|
|
67
|
-
//
|
|
68
|
-
// Without animation: closed ↔ open directly.
|
|
69
|
-
var willAnimate = Boolean(animate) && !prefersReducedMotion();
|
|
70
|
-
var hasMountedRef = useRef(false);
|
|
71
|
-
useLayoutEffect(function () {
|
|
72
|
-
if (hasMountedRef.current) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
hasMountedRef.current = true;
|
|
76
|
-
if (isOpen) {
|
|
77
|
-
setPopupState === null || setPopupState === void 0 || setPopupState(willAnimate ? 'animating-open' : 'open');
|
|
78
|
-
}
|
|
79
|
-
}, [isOpen, setPopupState, willAnimate]);
|
|
80
|
-
var handleEnterFinish = useCallback(function () {
|
|
81
|
-
setPopupState === null || setPopupState === void 0 || setPopupState('open');
|
|
82
|
-
onEnterFinish === null || onEnterFinish === void 0 || onEnterFinish();
|
|
83
|
-
}, [setPopupState, onEnterFinish]);
|
|
84
|
-
var handleExitFinish = useCallback(function () {
|
|
85
|
-
setPopupState === null || setPopupState === void 0 || setPopupState('closed');
|
|
86
|
-
onExitFinish === null || onExitFinish === void 0 || onExitFinish();
|
|
87
|
-
}, [setPopupState, onExitFinish]);
|
|
88
|
-
|
|
89
|
-
// Note: onOpenChange composition is handled by handleOpenChange below,
|
|
90
|
-
// which also adds nested-popover focus restoration.
|
|
91
|
-
|
|
92
|
-
// Sync aria-haspopup on the trigger with the content's role
|
|
93
|
-
var setAriaHasPopup = ctx === null || ctx === void 0 ? void 0 : ctx.setAriaHasPopup;
|
|
94
|
-
useLayoutEffect(function () {
|
|
95
|
-
setAriaHasPopup === null || setAriaHasPopup === void 0 || setAriaHasPopup(roleToAriaHasPopup({
|
|
96
|
-
role: role
|
|
97
|
-
}));
|
|
98
|
-
}, [role, setAriaHasPopup]);
|
|
99
|
-
|
|
100
|
-
// Focus restoration
|
|
101
|
-
// The native Popover API handles focus restoration automatically for
|
|
102
|
-
// popover="auto" and popover="hint":
|
|
103
|
-
// - Escape → restores focus to the previously focused element (the trigger)
|
|
104
|
-
// - Click-outside → does NOT restore (correct: the user clicked deliberately)
|
|
105
|
-
// - hidePopover() → restores focus to the previously focused element
|
|
106
|
-
//
|
|
107
|
-
// However, for **nested** popover="auto" popovers, the browser only captures
|
|
108
|
-
// `previouslyFocusedElement` for the outermost popover in the auto stack.
|
|
109
|
-
// Inner popovers have `shouldRestoreFocus=false` per the spec, so the browser
|
|
110
|
-
// does not restore focus when they close.
|
|
111
|
-
//
|
|
112
|
-
// To handle this, we listen for the close transition via `onOpenChange` and
|
|
113
|
-
// restore focus to the trigger if the browser did not. This runs after the
|
|
114
|
-
// browser's native restoration (which happens synchronously during hidePopover),
|
|
115
|
-
// so it only takes effect when the browser skipped restoration (nested case).
|
|
116
|
-
//
|
|
117
|
-
// See: notes/architecture/focus-restoration.md
|
|
118
|
-
var handleOpenChange = useCallback(function (args) {
|
|
119
|
-
// Sync compound state
|
|
120
|
-
if (args.isOpen) {
|
|
121
|
-
setPopupState === null || setPopupState === void 0 || setPopupState(willAnimate ? 'animating-open' : 'open');
|
|
122
|
-
} else {
|
|
123
|
-
setPopupState === null || setPopupState === void 0 || setPopupState(willAnimate ? 'animating-closed' : 'closed');
|
|
124
|
-
}
|
|
125
|
-
consumerOnOpenChange === null || consumerOnOpenChange === void 0 || consumerOnOpenChange(args);
|
|
126
|
-
|
|
127
|
-
// Nested popover focus restoration fallback
|
|
128
|
-
// The browser only captures `previouslyFocusedElement` for the
|
|
129
|
-
// outermost popover="auto" in the stack. Inner (nested) popovers
|
|
130
|
-
// have shouldRestoreFocus=false, so the browser will not restore
|
|
131
|
-
// focus when they close.
|
|
132
|
-
//
|
|
133
|
-
// We detect this case by checking if focus is still inside the
|
|
134
|
-
// closing popover element. If it is, the browser did not restore,
|
|
135
|
-
// and we need to move focus to the trigger ourselves.
|
|
136
|
-
//
|
|
137
|
-
// This does NOT fire for:
|
|
138
|
-
// - Outermost popovers (browser already restored to trigger)
|
|
139
|
-
// - Click-outside (focus is on the clicked element, not in popover)
|
|
140
|
-
if (!args.isOpen) {
|
|
141
|
-
var trigger = triggerRef === null || triggerRef === void 0 ? void 0 : triggerRef.current;
|
|
142
|
-
var focusStillInPopover = trigger && args.element.contains(document.activeElement);
|
|
143
|
-
// Single source of truth for "this role moves focus on open
|
|
144
|
-
// and therefore needs to be restored on close" - see
|
|
145
|
-
// `shouldFocusIntoPopover` in `internal/role-types.tsx`.
|
|
146
|
-
if (focusStillInPopover && shouldFocusIntoPopover({
|
|
147
|
-
role: role
|
|
148
|
-
})) {
|
|
149
|
-
trigger.focus({
|
|
150
|
-
preventScroll: true
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}, [consumerOnOpenChange, triggerRef, role, setPopupState, willAnimate]);
|
|
155
|
-
|
|
156
|
-
// Anchor positioning
|
|
157
|
-
// Compose useAnchorPosition with Popover. The hook positions the popover
|
|
158
|
-
// relative to the trigger element via CSS Anchor Positioning (with JS fallback).
|
|
159
|
-
// Use ctx.popoverRef when inside the compound (so the trigger can also
|
|
160
|
-
// reach the same DOM element for togglePopover). Otherwise use a local ref.
|
|
161
|
-
var localRef = useRef(null);
|
|
162
|
-
var popoverRef = (_ctx$popoverRef = ctx === null || ctx === void 0 ? void 0 : ctx.popoverRef) !== null && _ctx$popoverRef !== void 0 ? _ctx$popoverRef : localRef;
|
|
163
|
-
useAnchorPosition({
|
|
164
|
-
anchorRef: triggerRef !== null && triggerRef !== void 0 ? triggerRef : {
|
|
165
|
-
current: null
|
|
166
|
-
},
|
|
167
|
-
popoverRef: popoverRef,
|
|
168
|
-
placement: placement,
|
|
169
|
-
forceFallbackPositioning: forceFallbackPositioning
|
|
170
|
-
});
|
|
171
|
-
useWidthFromAnchor({
|
|
172
|
-
mode: widthFromAnchor,
|
|
173
|
-
popoverRef: popoverRef,
|
|
174
|
-
anchorRef: triggerRef
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// Merge: the popoverRef (shared with trigger + positioning) and the forwarded ref.
|
|
178
|
-
var combinedRef = mergeRefs([popoverRef, ref]);
|
|
179
|
-
|
|
180
|
-
// TPopupContentProps already validates the discriminated union (role + label,
|
|
181
|
-
// mode + onClose) at its API boundary. Popover accepts TPopoverForwardedProps
|
|
182
|
-
// internally so individual prop forwarding does not need to re-prove the union.
|
|
183
|
-
var popoverProps = {
|
|
184
|
-
isOpen: isOpen,
|
|
185
|
-
animate: animate,
|
|
186
|
-
placement: placement,
|
|
187
|
-
mode: mode,
|
|
188
|
-
role: role,
|
|
189
|
-
label: label,
|
|
190
|
-
labelledBy: labelledBy,
|
|
191
|
-
onClose: onClose !== null && onClose !== void 0 ? onClose : undefined,
|
|
192
|
-
onOpenChange: handleOpenChange,
|
|
193
|
-
onEnterFinish: handleEnterFinish,
|
|
194
|
-
onExitFinish: handleExitFinish,
|
|
195
|
-
testId: testId,
|
|
196
|
-
children: children,
|
|
197
|
-
// Standalone consumers can pass an explicit `id` - used by their own
|
|
198
|
-
// trigger to wire `aria-controls`. Inside the `<Popup>` compound, the
|
|
199
|
-
// id flows from context (`ctx.popoverId`).
|
|
200
|
-
id: idProp !== null && idProp !== void 0 ? idProp : ctx === null || ctx === void 0 ? void 0 : ctx.popoverId,
|
|
201
|
-
xcss: xcss
|
|
202
|
-
};
|
|
203
|
-
return /*#__PURE__*/React.createElement(Popover, _extends({
|
|
204
|
-
ref: combinedRef
|
|
205
|
-
}, popoverProps));
|
|
206
|
-
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createContext } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents the lifecycle state of the popup.
|
|
5
|
-
*
|
|
6
|
-
* - `'closed'`: fully closed, not visible, no animation playing.
|
|
7
|
-
* - `'animating-open'`: entry animation is playing (popup is opening but not yet settled).
|
|
8
|
-
* - `'open'`: fully open, browser popover is showing, entry animation complete.
|
|
9
|
-
* - `'animating-closed'`: exit animation is playing (popup is closing but still visible).
|
|
10
|
-
*
|
|
11
|
-
* Used to derive `aria-expanded` on the trigger:
|
|
12
|
-
* - `aria-expanded` is `true` in `'animating-open'`, `'open'`, and `'animating-closed'`.
|
|
13
|
-
*
|
|
14
|
-
* This avoids screen readers announcing the popup as closed while it is
|
|
15
|
-
* still visually present on screen during animations, and prevents consumers
|
|
16
|
-
* that conditionally show/hide trigger UI based on `aria-expanded` from hiding
|
|
17
|
-
* the trigger (and thus the popup anchor) mid-animation.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export var PopupContext = /*#__PURE__*/createContext(null);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { PopupContext } from './popup-context';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* __Popup provider__
|
|
5
|
-
*
|
|
6
|
-
* Provides shared popup state (placement, popoverId, triggerRef,
|
|
7
|
-
* isOpen, onClose) to compound child components such as `Popup.Trigger` and
|
|
8
|
-
* `Popup.Content`.
|
|
9
|
-
*/
|
|
10
|
-
export var PopupProvider = PopupContext.Provider;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/* popup-surface.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
-
import "./popup-surface.compiled.css";
|
|
3
|
-
import { ax, ix } from "@compiled/react/runtime";
|
|
4
|
-
import React from 'react';
|
|
5
|
-
var styles = {
|
|
6
|
-
root: "_2rkofajl _1reo1wug _18m91wug _bfhk1bhr _16qs130s"
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Optional styled wrapper for popup content.
|
|
11
|
-
*
|
|
12
|
-
* Adds default visual styling (background, border-radius, box-shadow)
|
|
13
|
-
* using design tokens. Consumers who want fully custom styling
|
|
14
|
-
* should use `Popup.Content` without wrapping in `PopupSurface`.
|
|
15
|
-
*
|
|
16
|
-
* Exposed as `Popup.Surface` on the compound component.
|
|
17
|
-
*
|
|
18
|
-
* **Presentational primitive - `children`-only by design.** This component
|
|
19
|
-
* intentionally exposes no `style`, `className`, `xcss`, `id`, or `ref`
|
|
20
|
-
* props. If you need any of those, render your own wrapper element inside
|
|
21
|
-
* `Popup.Content` instead - `PopupSurface` is the no-config "give me the
|
|
22
|
-
* default ADS overlay look" surface, nothing more.
|
|
23
|
-
*/
|
|
24
|
-
export function PopupSurface(_ref) {
|
|
25
|
-
var children = _ref.children;
|
|
26
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
27
|
-
className: ax([styles.root])
|
|
28
|
-
}, children);
|
|
29
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { usePopupContext } from './use-popup-context';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Props passed to the `TriggerFunction` render-prop child.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Render-prop alternative to `Popup.Trigger`.
|
|
10
|
-
*
|
|
11
|
-
* Use when you need full control over the trigger element. For example,
|
|
12
|
-
* to compose your own trigger with custom event handlers, wrap a third-party
|
|
13
|
-
* component, or build a trigger from multiple elements.
|
|
14
|
-
*
|
|
15
|
-
* `Popup.Trigger` uses `cloneElement` internally, which limits composability.
|
|
16
|
-
* `Popup.TriggerFunction` hands you the raw props and lets you wire them up.
|
|
17
|
-
*
|
|
18
|
-
* **Note:** This sub-component uses a render-prop pattern and is not
|
|
19
|
-
* compatible with React Server Components (RSC). It must be used inside
|
|
20
|
-
* a client component boundary (`'use client'`).
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```tsx
|
|
24
|
-
* <Popup placement={{ edge: 'end' }} onClose={handleClose}>
|
|
25
|
-
* <Popup.TriggerFunction>
|
|
26
|
-
* {({ ref, toggle, ariaAttributes }) => (
|
|
27
|
-
* <button ref={ref} onClick={toggle} {...ariaAttributes}>
|
|
28
|
-
* Open
|
|
29
|
-
* </button>
|
|
30
|
-
* )}
|
|
31
|
-
* </Popup.TriggerFunction>
|
|
32
|
-
* <Popup.Content role="dialog" label="My popup">
|
|
33
|
-
* Content
|
|
34
|
-
* </Popup.Content>
|
|
35
|
-
* </Popup>
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function PopupTriggerFunction(_ref) {
|
|
39
|
-
var children = _ref.children;
|
|
40
|
-
var _usePopupContext = usePopupContext(),
|
|
41
|
-
triggerRef = _usePopupContext.triggerRef,
|
|
42
|
-
popoverRef = _usePopupContext.popoverRef,
|
|
43
|
-
popoverId = _usePopupContext.popoverId,
|
|
44
|
-
popupState = _usePopupContext.popupState,
|
|
45
|
-
ariaHasPopup = _usePopupContext.ariaHasPopup;
|
|
46
|
-
var ref = useCallback(function (node) {
|
|
47
|
-
triggerRef.current = node;
|
|
48
|
-
}, [triggerRef]);
|
|
49
|
-
var toggle = useCallback(function () {
|
|
50
|
-
var popoverEl = popoverRef.current;
|
|
51
|
-
if (popoverEl) {
|
|
52
|
-
// Defensive: element may be disconnected or in an unexpected state.
|
|
53
|
-
try {
|
|
54
|
-
popoverEl.togglePopover();
|
|
55
|
-
} catch (_unused) {}
|
|
56
|
-
}
|
|
57
|
-
}, [popoverRef]);
|
|
58
|
-
var ariaAttributes = useMemo(function () {
|
|
59
|
-
return {
|
|
60
|
-
// aria-expanded stays true throughout entry and exit animations so screen readers
|
|
61
|
-
// don't announce the popup as closed while it's still visible, and consumers
|
|
62
|
-
// relying on aria-expanded to show/hide trigger UI don't lose the anchor mid-animation.
|
|
63
|
-
'aria-expanded': popupState === 'open' || popupState === 'animating-open' || popupState === 'animating-closed',
|
|
64
|
-
'aria-controls': popoverId,
|
|
65
|
-
'aria-haspopup': ariaHasPopup
|
|
66
|
-
};
|
|
67
|
-
}, [popupState, popoverId, ariaHasPopup]);
|
|
68
|
-
return children({
|
|
69
|
-
ref: ref,
|
|
70
|
-
isOpen: popupState === 'open' || popupState === 'animating-open',
|
|
71
|
-
popoverId: popoverId,
|
|
72
|
-
toggle: toggle,
|
|
73
|
-
ariaAttributes: ariaAttributes
|
|
74
|
-
});
|
|
75
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import React, { isValidElement, useCallback } from 'react';
|
|
2
|
-
import { Slot } from '../internal/slot';
|
|
3
|
-
import { usePopupContext } from './use-popup-context';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Wraps a single trigger element via `cloneElement`. Attaches aria
|
|
7
|
-
* attributes, the toggle handler, and the anchor-name. `aria-haspopup`
|
|
8
|
-
* is derived from `Popup.Content`'s role via context.
|
|
9
|
-
*
|
|
10
|
-
* Child constraints: must be a single ref-forwarding element. The child's
|
|
11
|
-
* `onClick` is composed (runs after); other event handlers are NOT.
|
|
12
|
-
* Children using Compiled's `css` prop swallow injected props - use
|
|
13
|
-
* `Popup.TriggerFunction` for these cases or any time you need handler
|
|
14
|
-
* composition.
|
|
15
|
-
*/
|
|
16
|
-
export function PopupTrigger(_ref) {
|
|
17
|
-
var children = _ref.children;
|
|
18
|
-
var _usePopupContext = usePopupContext(),
|
|
19
|
-
triggerRef = _usePopupContext.triggerRef,
|
|
20
|
-
popoverRef = _usePopupContext.popoverRef,
|
|
21
|
-
popoverId = _usePopupContext.popoverId,
|
|
22
|
-
popupState = _usePopupContext.popupState,
|
|
23
|
-
ariaHasPopup = _usePopupContext.ariaHasPopup;
|
|
24
|
-
var childOnClick = /*#__PURE__*/isValidElement(children) ? children.props.onClick : undefined;
|
|
25
|
-
|
|
26
|
-
// Use a ref to track the latest isOpen value so the click handler
|
|
27
|
-
// does not need isOpen in its dependency array (which would recreate
|
|
28
|
-
// the handler on every open/close, breaking cloneElement identity).
|
|
29
|
-
var isOpenRef = React.useRef(popupState === 'open' || popupState === 'animating-open');
|
|
30
|
-
isOpenRef.current = popupState === 'open' || popupState === 'animating-open';
|
|
31
|
-
var handleClick = useCallback(function (event) {
|
|
32
|
-
var popoverEl = popoverRef.current;
|
|
33
|
-
if (popoverEl) {
|
|
34
|
-
// `popover="auto"` light-dismiss can close the popover BEFORE
|
|
35
|
-
// our click handler runs, so trust React's isOpen rather than
|
|
36
|
-
// DOM state. If React still thinks it is closed, open it; if
|
|
37
|
-
// it was open, the browser already closed it.
|
|
38
|
-
if (!isOpenRef.current) {
|
|
39
|
-
try {
|
|
40
|
-
popoverEl.showPopover();
|
|
41
|
-
} catch (_unused) {
|
|
42
|
-
// Element may be disconnected; ignore.
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
childOnClick === null || childOnClick === void 0 || childOnClick(event);
|
|
47
|
-
}, [popoverRef, childOnClick]);
|
|
48
|
-
return /*#__PURE__*/React.createElement(Slot, {
|
|
49
|
-
ref: triggerRef,
|
|
50
|
-
onClick: handleClick
|
|
51
|
-
// aria-expanded stays true throughout entry and exit animations so screen readers
|
|
52
|
-
// don't announce the popup as closed while it's still visible, and consumers
|
|
53
|
-
// relying on aria-expanded to show/hide trigger UI don't lose the anchor mid-animation.
|
|
54
|
-
,
|
|
55
|
-
"aria-expanded": popupState === 'open' || popupState === 'animating-open' || popupState === 'animating-closed',
|
|
56
|
-
"aria-controls": popoverId,
|
|
57
|
-
"aria-haspopup": ariaHasPopup
|
|
58
|
-
}, children);
|
|
59
|
-
}
|