@atlaskit/top-layer 0.8.0 → 0.10.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 +41 -0
- package/README.md +5 -1
- package/dialog/create-close-event/package.json +17 -0
- package/dist/cjs/animations/presets.js +11 -4
- package/dist/cjs/arrow/index.js +131 -0
- package/dist/cjs/arrow/types.js +5 -0
- package/dist/cjs/dialog/dialog-content.js +23 -6
- package/dist/cjs/entry-points/dialog/create-close-event.js +12 -0
- package/dist/cjs/entry-points/placement-map.js +6 -5
- package/dist/cjs/entry-points/popover/create-close-event.js +12 -0
- package/dist/cjs/focus/focus.js +73 -19
- package/dist/cjs/index.js +3 -4
- package/dist/cjs/internal/resolve-css-length-to-pixels.js +61 -10
- package/dist/cjs/internal/role-types.js +40 -9
- package/dist/cjs/internal/set-style.js +23 -25
- package/dist/cjs/internal/use-anchor-position.js +109 -68
- package/dist/cjs/internal/use-focus-wrap.js +13 -2
- package/dist/cjs/internal/use-initial-focus.js +31 -10
- package/dist/cjs/placement-map/index.js +9 -110
- package/dist/cjs/placement-map/legacy-placements.js +113 -0
- package/dist/cjs/popover/popover.js +44 -11
- package/dist/cjs/popup/popup-content.js +19 -13
- package/dist/cjs/popup/popup-context.js +2 -0
- package/dist/cjs/popup/popup-surface.js +6 -0
- package/dist/cjs/popup/popup-trigger-function.js +1 -1
- package/dist/cjs/popup/popup-trigger.js +17 -37
- package/dist/cjs/popup/popup.js +21 -10
- package/dist/cjs/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/es2019/animations/presets.js +10 -3
- package/dist/es2019/arrow/index.js +269 -0
- package/dist/es2019/arrow/types.js +1 -0
- package/dist/es2019/dialog/dialog-content.js +23 -6
- package/dist/es2019/entry-points/create-close-event.js +7 -0
- package/dist/es2019/entry-points/dialog/create-close-event.js +1 -0
- package/dist/es2019/entry-points/placement-map.js +2 -1
- package/dist/es2019/entry-points/popover/create-close-event.js +1 -0
- package/dist/es2019/focus/focus.js +58 -7
- package/dist/es2019/index.js +3 -4
- package/dist/es2019/internal/resolve-css-length-to-pixels.js +60 -7
- package/dist/es2019/internal/role-types.js +40 -9
- package/dist/es2019/internal/set-style.js +19 -22
- package/dist/es2019/internal/use-anchor-position.js +97 -54
- package/dist/es2019/internal/use-focus-wrap.js +14 -3
- package/dist/es2019/internal/use-initial-focus.js +32 -11
- package/dist/es2019/placement-map/index.js +8 -108
- package/dist/es2019/placement-map/legacy-placements.js +107 -0
- package/dist/es2019/popover/popover.js +44 -10
- package/dist/es2019/popup/popup-content.js +20 -14
- package/dist/es2019/popup/popup-context.js +2 -0
- package/dist/es2019/popup/popup-surface.js +6 -0
- package/dist/es2019/popup/popup-trigger-function.js +1 -1
- package/dist/es2019/popup/popup-trigger.js +17 -37
- package/dist/es2019/popup/popup.js +20 -9
- package/dist/es2019/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/esm/animations/presets.js +10 -3
- package/dist/esm/arrow/index.js +124 -0
- package/dist/esm/arrow/types.js +1 -0
- package/dist/esm/dialog/dialog-content.js +23 -6
- package/dist/esm/entry-points/create-close-event.js +7 -0
- package/dist/esm/entry-points/dialog/create-close-event.js +1 -0
- package/dist/esm/entry-points/placement-map.js +2 -1
- package/dist/esm/entry-points/popover/create-close-event.js +1 -0
- package/dist/esm/focus/focus.js +72 -19
- package/dist/esm/index.js +3 -4
- package/dist/esm/internal/resolve-css-length-to-pixels.js +61 -10
- package/dist/esm/internal/role-types.js +39 -9
- package/dist/esm/internal/set-style.js +23 -25
- package/dist/esm/internal/use-anchor-position.js +110 -64
- package/dist/esm/internal/use-focus-wrap.js +14 -3
- package/dist/esm/internal/use-initial-focus.js +32 -11
- package/dist/esm/placement-map/index.js +8 -108
- package/dist/esm/placement-map/legacy-placements.js +107 -0
- package/dist/esm/popover/popover.js +44 -11
- package/dist/esm/popup/popup-content.js +20 -14
- package/dist/esm/popup/popup-context.js +2 -0
- package/dist/esm/popup/popup-surface.js +6 -0
- package/dist/esm/popup/popup-trigger-function.js +1 -1
- package/dist/esm/popup/popup-trigger.js +17 -37
- package/dist/esm/popup/popup.js +21 -10
- package/dist/esm/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/types/arrow/index.d.ts +24 -0
- package/dist/types/arrow/types.d.ts +29 -0
- package/dist/types/dialog/dialog-content.d.ts +5 -1
- package/dist/types/dialog/types.d.ts +50 -24
- package/dist/types/entry-points/create-close-event.d.ts +7 -0
- package/dist/types/entry-points/dialog/create-close-event.d.ts +2 -0
- package/dist/types/entry-points/placement-map.d.ts +2 -1
- package/dist/types/entry-points/popover/create-close-event.d.ts +2 -0
- package/dist/types/focus/focus.d.ts +8 -0
- package/dist/types/internal/resolve-css-length-to-pixels.d.ts +4 -6
- package/dist/types/internal/role-types.d.ts +25 -4
- package/dist/types/internal/set-style.d.ts +2 -19
- package/dist/types/internal/use-anchor-position.d.ts +2 -3
- package/dist/types/internal/use-initial-focus.d.ts +5 -4
- package/dist/types/placement-map/index.d.ts +8 -21
- package/dist/types/placement-map/legacy-placements.d.ts +21 -0
- package/dist/types/popover/popover.d.ts +1 -1
- package/dist/types/popover/types.d.ts +20 -19
- package/dist/types/popup/popup-surface.d.ts +6 -0
- package/dist/types/popup/popup-trigger-function.d.ts +10 -6
- package/dist/types/popup/popup-trigger.d.ts +8 -17
- package/dist/types/popup/popup.d.ts +2 -2
- package/dist/types/popup/types.d.ts +68 -22
- package/dist/types/use-arrow-navigation/use-arrow-navigation.d.ts +19 -5
- package/dist/types-ts4.5/arrow/index.d.ts +24 -0
- package/dist/types-ts4.5/arrow/types.d.ts +29 -0
- package/dist/types-ts4.5/dialog/dialog-content.d.ts +5 -1
- package/dist/types-ts4.5/dialog/types.d.ts +50 -24
- package/dist/types-ts4.5/entry-points/create-close-event.d.ts +7 -0
- package/dist/types-ts4.5/entry-points/dialog/create-close-event.d.ts +2 -0
- package/dist/types-ts4.5/entry-points/placement-map.d.ts +2 -1
- package/dist/types-ts4.5/entry-points/popover/create-close-event.d.ts +2 -0
- package/dist/types-ts4.5/focus/focus.d.ts +8 -0
- package/dist/types-ts4.5/internal/resolve-css-length-to-pixels.d.ts +4 -6
- package/dist/types-ts4.5/internal/role-types.d.ts +25 -4
- package/dist/types-ts4.5/internal/set-style.d.ts +2 -19
- package/dist/types-ts4.5/internal/use-anchor-position.d.ts +2 -3
- package/dist/types-ts4.5/internal/use-initial-focus.d.ts +5 -4
- package/dist/types-ts4.5/placement-map/index.d.ts +8 -21
- package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +39 -0
- package/dist/types-ts4.5/popover/popover.d.ts +1 -1
- package/dist/types-ts4.5/popover/types.d.ts +20 -19
- package/dist/types-ts4.5/popup/popup-surface.d.ts +6 -0
- package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +10 -6
- package/dist/types-ts4.5/popup/popup-trigger.d.ts +8 -17
- package/dist/types-ts4.5/popup/popup.d.ts +2 -2
- package/dist/types-ts4.5/popup/types.d.ts +68 -22
- package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +19 -5
- package/package.json +3 -1
- package/popover/create-close-event/package.json +17 -0
|
@@ -4,6 +4,35 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.resolveCssLengthToPixels = resolveCssLengthToPixels;
|
|
7
|
+
var elementCaches = new WeakMap();
|
|
8
|
+
function canCacheResolvedLength(value) {
|
|
9
|
+
// Custom-property values can be retargeted by inline overrides on the
|
|
10
|
+
// consumer's wrapper, so we cannot prove a cached pixel value is still valid.
|
|
11
|
+
return !value.includes('var(');
|
|
12
|
+
}
|
|
13
|
+
function getCachedResolvedLength(_ref) {
|
|
14
|
+
var _cacheForElement$get;
|
|
15
|
+
var element = _ref.element,
|
|
16
|
+
value = _ref.value;
|
|
17
|
+
if (!canCacheResolvedLength(value)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
var cacheForElement = elementCaches.get(element);
|
|
21
|
+
return (_cacheForElement$get = cacheForElement === null || cacheForElement === void 0 ? void 0 : cacheForElement.get(value)) !== null && _cacheForElement$get !== void 0 ? _cacheForElement$get : null;
|
|
22
|
+
}
|
|
23
|
+
function cacheResolvedLength(_ref2) {
|
|
24
|
+
var _elementCaches$get;
|
|
25
|
+
var element = _ref2.element,
|
|
26
|
+
value = _ref2.value,
|
|
27
|
+
result = _ref2.result;
|
|
28
|
+
if (!canCacheResolvedLength(value)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
var cacheForElement = (_elementCaches$get = elementCaches.get(element)) !== null && _elementCaches$get !== void 0 ? _elementCaches$get : new Map();
|
|
32
|
+
cacheForElement.set(value, result);
|
|
33
|
+
elementCaches.set(element, cacheForElement);
|
|
34
|
+
}
|
|
35
|
+
|
|
7
36
|
/**
|
|
8
37
|
* Resolves a CSS length value to a pixel number using a hidden DOM probe.
|
|
9
38
|
*
|
|
@@ -14,27 +43,39 @@ exports.resolveCssLengthToPixels = resolveCssLengthToPixels;
|
|
|
14
43
|
* the browser do the math.
|
|
15
44
|
*
|
|
16
45
|
* The probe is appended to `container` so it inherits the same containing
|
|
17
|
-
* block, font size, and custom-property scope as the popover.
|
|
18
|
-
* because it accepts any CSS length, including negative `calc()` results
|
|
19
|
-
* (negative widths are clamped to 0 — see note below).
|
|
46
|
+
* block, font size, and custom-property scope as the popover.
|
|
20
47
|
*
|
|
21
|
-
* Cost: one synchronous reflow
|
|
22
|
-
*
|
|
23
|
-
*
|
|
48
|
+
* Cost: one synchronous reflow on first cacheable resolution per
|
|
49
|
+
* (container, value) pair, then a `WeakMap` lookup. Resolutions involving
|
|
50
|
+
* `var(` are intentionally not cached.
|
|
24
51
|
*/
|
|
25
|
-
function resolveCssLengthToPixels(
|
|
26
|
-
var value =
|
|
27
|
-
container =
|
|
52
|
+
function resolveCssLengthToPixels(_ref3) {
|
|
53
|
+
var value = _ref3.value,
|
|
54
|
+
container = _ref3.container;
|
|
28
55
|
if (typeof value === 'number') {
|
|
29
56
|
return value;
|
|
30
57
|
}
|
|
31
58
|
|
|
59
|
+
// Fast path: unitless zero is universally zero pixels - accept `'0'` and
|
|
60
|
+
// `'-0'` without a probe. (Consumers occasionally pass `'0'` instead of
|
|
61
|
+
// the number `0`.)
|
|
62
|
+
if (value === '0' || value === '-0') {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
// Fast path: bare `${n}px` strings come from the consumer normalisation
|
|
33
67
|
// in `getPlacement`. Avoid a reflow when we can.
|
|
34
68
|
var pxMatch = value.match(/^(-?\d+(?:\.\d+)?)px$/);
|
|
35
69
|
if (pxMatch) {
|
|
36
70
|
return Number(pxMatch[1]);
|
|
37
71
|
}
|
|
72
|
+
var cached = getCachedResolvedLength({
|
|
73
|
+
element: container,
|
|
74
|
+
value: value
|
|
75
|
+
});
|
|
76
|
+
if (cached !== null) {
|
|
77
|
+
return cached;
|
|
78
|
+
}
|
|
38
79
|
var probe = container.ownerDocument.createElement('div');
|
|
39
80
|
probe.style.position = 'absolute';
|
|
40
81
|
probe.style.visibility = 'hidden';
|
|
@@ -46,8 +87,18 @@ function resolveCssLengthToPixels(_ref) {
|
|
|
46
87
|
// preserved. `getComputedStyle` returns the resolved pixel value for
|
|
47
88
|
// margin-* properties even when the source was a token / calc / var.
|
|
48
89
|
probe.style.marginLeft = value;
|
|
90
|
+
// Hide the probe from assistive tech and event targeting; defensive
|
|
91
|
+
// against `getElementsByTagName('div')` walks in consumer code.
|
|
92
|
+
probe.setAttribute('aria-hidden', 'true');
|
|
93
|
+
probe.setAttribute('inert', '');
|
|
49
94
|
container.appendChild(probe);
|
|
50
95
|
var resolved = parseFloat(getComputedStyle(probe).marginLeft);
|
|
51
96
|
container.removeChild(probe);
|
|
52
|
-
|
|
97
|
+
var result = Number.isFinite(resolved) ? resolved : 0;
|
|
98
|
+
cacheResolvedLength({
|
|
99
|
+
element: container,
|
|
100
|
+
value: value,
|
|
101
|
+
result: result
|
|
102
|
+
});
|
|
103
|
+
return result;
|
|
53
104
|
}
|
|
@@ -4,9 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.roleToAriaHasPopup = roleToAriaHasPopup;
|
|
7
|
+
exports.shouldFocusIntoPopover = shouldFocusIntoPopover;
|
|
7
8
|
/**
|
|
8
9
|
* Valid values for the `aria-haspopup` attribute.
|
|
9
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* Derived from the HTML spec - maps popover roles to what the trigger
|
|
12
|
+
* announces. `undefined` means the attribute is omitted entirely (used for
|
|
13
|
+
* non-popup roles like `tooltip`/`status`/`alert`/`note`/`log` where
|
|
14
|
+
* `aria-haspopup` would be misleading).
|
|
15
|
+
*
|
|
16
|
+
* `true` is intentionally NOT in the union - the runtime only ever produces
|
|
17
|
+
* the explicit string forms, so widening the type would invite consumers to
|
|
18
|
+
* pass `true` and get an `aria-haspopup="true"` serialisation that the
|
|
19
|
+
* runtime no longer emits.
|
|
10
20
|
*/
|
|
11
21
|
|
|
12
22
|
/**
|
|
@@ -28,21 +38,27 @@ exports.roleToAriaHasPopup = roleToAriaHasPopup;
|
|
|
28
38
|
/**
|
|
29
39
|
* ARIA role props where a role is always required.
|
|
30
40
|
*
|
|
31
|
-
* Used by `TPopupContentProps
|
|
41
|
+
* Used by `TPopupContentProps`. Popup content must always declare
|
|
32
42
|
* its role so assistive technology can identify the layer.
|
|
33
43
|
*/
|
|
34
44
|
|
|
35
45
|
/**
|
|
36
46
|
* ARIA role props where a role is optional.
|
|
37
47
|
*
|
|
38
|
-
* Used by `TPopoverProps
|
|
48
|
+
* Used by `TPopoverProps`. The low-level primitive allows omitting
|
|
39
49
|
* the role for cases where it is set externally or not needed.
|
|
40
50
|
*/
|
|
41
51
|
|
|
42
52
|
/**
|
|
43
53
|
* Maps a popover content role to the correct `aria-haspopup` value
|
|
44
54
|
* for its trigger element.
|
|
55
|
+
*
|
|
56
|
+
* Returns `undefined` for roles that are not popups in the ARIA sense
|
|
57
|
+
* (`tooltip`, `note`, `status`, `alert`, `log`). Triggers for those roles
|
|
58
|
+
* should not announce a popup at all - emitting `aria-haspopup="dialog"`
|
|
59
|
+
* on a tooltip trigger would mislead assistive technology.
|
|
45
60
|
*/
|
|
61
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
46
62
|
function roleToAriaHasPopup(_ref) {
|
|
47
63
|
var role = _ref.role;
|
|
48
64
|
if (role === 'menu') {
|
|
@@ -57,10 +73,25 @@ function roleToAriaHasPopup(_ref) {
|
|
|
57
73
|
if (role === 'grid') {
|
|
58
74
|
return 'grid';
|
|
59
75
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
76
|
+
if (role === 'dialog' || role === 'alertdialog') {
|
|
77
|
+
return 'dialog';
|
|
78
|
+
}
|
|
79
|
+
// Non-popup roles (tooltip, note, status, alert, log) and the
|
|
80
|
+
// no-role case: omit `aria-haspopup` entirely. React drops the
|
|
81
|
+
// attribute when the value is `undefined`.
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
var rolesThatMoveFocus = new Set(['dialog', 'alertdialog', 'menu', 'listbox', 'tree', 'grid']);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns `true` when the given popover role moves focus into the popover
|
|
88
|
+
* on open, and `false` otherwise (including when `role` is `undefined`).
|
|
89
|
+
*/
|
|
90
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
91
|
+
function shouldFocusIntoPopover(_ref2) {
|
|
92
|
+
var role = _ref2.role;
|
|
93
|
+
if (!role) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
return rolesThatMoveFocus.has(role);
|
|
66
97
|
}
|
|
@@ -5,38 +5,36 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.setStyle = setStyle;
|
|
7
7
|
/**
|
|
8
|
-
* Sets inline styles on an element and returns a cleanup function
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* Uses `style.setProperty()` / `style.removeProperty()` so that
|
|
12
|
-
* hyphenated CSS property names (e.g. `position-area`, `anchor-name`)
|
|
13
|
-
* work correctly. These newer properties do not have camelCase
|
|
14
|
-
* mappings in `CSSStyleDeclaration` yet.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* const cleanup = setStyle({ el: popover, styles: [
|
|
19
|
-
* { property: 'position-anchor', value: '--my-anchor' },
|
|
20
|
-
* { property: 'position-area', value: 'block-end' },
|
|
21
|
-
* { property: 'margin', value: '0' },
|
|
22
|
-
* ] });
|
|
23
|
-
*
|
|
24
|
-
* // Later: removes all three properties
|
|
25
|
-
* cleanup();
|
|
26
|
-
* ```
|
|
8
|
+
* Sets inline styles on an element and returns a cleanup function that
|
|
9
|
+
* restores the prior inline values (so we do not stomp consumer styles).
|
|
27
10
|
*/
|
|
28
11
|
function setStyle(_ref) {
|
|
29
12
|
var el = _ref.el,
|
|
30
13
|
styles = _ref.styles;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
// Snapshot the prior inline value (NOT the computed style - we only want
|
|
15
|
+
// to restore values that the consumer/our previous run inlined). An empty
|
|
16
|
+
// string means "no inline value", in which case cleanup uses removeProperty.
|
|
17
|
+
var priorValues = styles.map(function (_ref2) {
|
|
18
|
+
var property = _ref2.property;
|
|
19
|
+
return {
|
|
20
|
+
property: property,
|
|
21
|
+
value: el.style.getPropertyValue(property)
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
styles.forEach(function (_ref3) {
|
|
25
|
+
var property = _ref3.property,
|
|
26
|
+
value = _ref3.value;
|
|
34
27
|
el.style.setProperty(property, value);
|
|
35
28
|
});
|
|
36
29
|
return function cleanup() {
|
|
37
|
-
|
|
38
|
-
var property =
|
|
39
|
-
|
|
30
|
+
priorValues.forEach(function (_ref4) {
|
|
31
|
+
var property = _ref4.property,
|
|
32
|
+
value = _ref4.value;
|
|
33
|
+
if (value === '') {
|
|
34
|
+
el.style.removeProperty(property);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
el.style.setProperty(property, value);
|
|
40
38
|
});
|
|
41
39
|
};
|
|
42
40
|
}
|
|
@@ -4,15 +4,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
Object.defineProperty(exports, "getPlacement", {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
get: function get() {
|
|
10
|
-
return _resolvePlacement.getPlacement;
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
7
|
exports.placementToPositionArea = placementToPositionArea;
|
|
14
8
|
exports.placementToTryFallbacks = placementToTryFallbacks;
|
|
15
9
|
exports.useAnchorPosition = useAnchorPosition;
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
16
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
17
12
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
18
13
|
var _react = require("react");
|
|
@@ -39,6 +34,30 @@ var _setStyle = require("./set-style");
|
|
|
39
34
|
* is never painted at the wrong location.
|
|
40
35
|
*/
|
|
41
36
|
|
|
37
|
+
// `getPlacement` is intentionally NOT re-exported here - import it directly
|
|
38
|
+
// from `./resolve-placement` so search-and-jump lands at the source of truth.
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Module-scope no-op `ResizeObserver` used in non-DOM jest environments where
|
|
42
|
+
* `ResizeObserver` is `undefined`. Hoisted out of the effect to avoid
|
|
43
|
+
* allocating a new class declaration on every run.
|
|
44
|
+
*/
|
|
45
|
+
var NoopResizeObserver = /*#__PURE__*/function () {
|
|
46
|
+
function NoopResizeObserver() {
|
|
47
|
+
(0, _classCallCheck2.default)(this, NoopResizeObserver);
|
|
48
|
+
}
|
|
49
|
+
return (0, _createClass2.default)(NoopResizeObserver, [{
|
|
50
|
+
key: "observe",
|
|
51
|
+
value: function observe() {}
|
|
52
|
+
}, {
|
|
53
|
+
key: "unobserve",
|
|
54
|
+
value: function unobserve() {}
|
|
55
|
+
}, {
|
|
56
|
+
key: "disconnect",
|
|
57
|
+
value: function disconnect() {}
|
|
58
|
+
}]);
|
|
59
|
+
}();
|
|
60
|
+
|
|
42
61
|
/**
|
|
43
62
|
* Resolves placement options to CSS `position-area` syntax.
|
|
44
63
|
*
|
|
@@ -100,7 +119,7 @@ function placementToPositionArea(_ref) {
|
|
|
100
119
|
* top-right), flipping only the primary axis (`flip-inline`) moves the popup
|
|
101
120
|
* to the left but keeps the same cross-axis span direction (e.g. upward),
|
|
102
121
|
* which is still off-screen. The combined keyword `flip-inline flip-block`
|
|
103
|
-
* mirrors the popup diagonally
|
|
122
|
+
* mirrors the popup diagonally. It flips BOTH the position-area AND both
|
|
104
123
|
* inline and block margins simultaneously, placing the popup at the
|
|
105
124
|
* diagonally opposite corner where there is always space.
|
|
106
125
|
*
|
|
@@ -108,6 +127,7 @@ function placementToPositionArea(_ref) {
|
|
|
108
127
|
* `position-try-fallbacks` do NOT update margins, so only the `flip-*`
|
|
109
128
|
* tactic keywords correctly flip the gap margin along with the position.
|
|
110
129
|
*/
|
|
130
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
111
131
|
function placementToTryFallbacks(_ref2) {
|
|
112
132
|
var placement = _ref2.placement;
|
|
113
133
|
var _getPlacement2 = (0, _resolvePlacement.getPlacement)({
|
|
@@ -118,19 +138,36 @@ function placementToTryFallbacks(_ref2) {
|
|
|
118
138
|
align = _getPlacement2.align;
|
|
119
139
|
var crossAxis = axis === 'block' ? 'inline' : 'block';
|
|
120
140
|
var flippedEdge = edge === 'start' ? 'end' : 'start';
|
|
121
|
-
if (align !== 'center') {
|
|
122
|
-
var _sameEdge = "".concat(axis, "-").concat(edge);
|
|
123
|
-
var _oppositeEdge = "".concat(axis, "-").concat(flippedEdge);
|
|
124
|
-
var _flipKeyword = axis === 'block' ? 'flip-block' : 'flip-inline';
|
|
125
|
-
var flipCrossKeyword = axis === 'block' ? 'flip-inline' : 'flip-block';
|
|
126
|
-
// Try same-edge shifts first; two flip entries cover single-edge then corner overflow.
|
|
127
|
-
// Legacy Popper fallbacks for e.g. bottom-start: [bottom, bottom-end, top-start, top, top-end, auto].
|
|
128
|
-
return ["".concat(_sameEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'end' : 'start'), _sameEdge, "".concat(_sameEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'start' : 'end'), _flipKeyword, "".concat(_flipKeyword, " ").concat(flipCrossKeyword), "".concat(_oppositeEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'end' : 'start'), _oppositeEdge, "".concat(_oppositeEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'start' : 'end')].join(', ');
|
|
129
|
-
}
|
|
130
141
|
var sameEdge = "".concat(axis, "-").concat(edge);
|
|
131
142
|
var oppositeEdge = "".concat(axis, "-").concat(flippedEdge);
|
|
132
143
|
var flipKeyword = axis === 'block' ? 'flip-block' : 'flip-inline';
|
|
133
|
-
|
|
144
|
+
var flipCrossKeyword = axis === 'block' ? 'flip-inline' : 'flip-block';
|
|
145
|
+
|
|
146
|
+
// Single algorithm: produce the shift list against any base alignment.
|
|
147
|
+
// For `align: 'start'` the "near" shift expands toward `end`; for
|
|
148
|
+
// `align: 'end'` it expands toward `start`; for `align: 'center'`
|
|
149
|
+
// either order is symmetric (we use end-then-start to match the
|
|
150
|
+
// historical fallback list).
|
|
151
|
+
function shifts(baseAlign, edgeKey) {
|
|
152
|
+
if (baseAlign === 'center') {
|
|
153
|
+
return ["".concat(edgeKey, " span-").concat(crossAxis, "-end"), "".concat(edgeKey, " span-").concat(crossAxis, "-start")];
|
|
154
|
+
}
|
|
155
|
+
var near = baseAlign === 'start' ? 'end' : 'start';
|
|
156
|
+
var far = baseAlign === 'start' ? 'start' : 'end';
|
|
157
|
+
return ["".concat(edgeKey, " span-").concat(crossAxis, "-").concat(near), edgeKey, "".concat(edgeKey, " span-").concat(crossAxis, "-").concat(far)];
|
|
158
|
+
}
|
|
159
|
+
if (align !== 'center') {
|
|
160
|
+
// Aligned (start/end): try same-edge shifts, then single-axis flip,
|
|
161
|
+
// then diagonal flip for corner overflow, then opposite-edge shifts.
|
|
162
|
+
// Legacy Popper fallback ordering for e.g. bottom-start:
|
|
163
|
+
// [bottom, bottom-end, top-start, top, top-end, auto].
|
|
164
|
+
return [].concat((0, _toConsumableArray2.default)(shifts(align, sameEdge)), [flipKeyword, "".concat(flipKeyword, " ").concat(flipCrossKeyword)], (0, _toConsumableArray2.default)(shifts(align, oppositeEdge))).join(', ');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Centered: same-edge shifts, single-axis flip, opposite-edge shifts.
|
|
168
|
+
// Diagonal flip is unnecessary because centered placements expand
|
|
169
|
+
// equally in both cross-axis directions.
|
|
170
|
+
return [].concat((0, _toConsumableArray2.default)(shifts('center', sameEdge)), [flipKeyword], (0, _toConsumableArray2.default)(shifts('center', oppositeEdge))).join(', ');
|
|
134
171
|
}
|
|
135
172
|
|
|
136
173
|
/**
|
|
@@ -148,7 +185,7 @@ function isPopoverOpen(popover) {
|
|
|
148
185
|
|
|
149
186
|
/**
|
|
150
187
|
* Detects whether the browser supports CSS Anchor Positioning.
|
|
151
|
-
* Uses `once()` for lazy evaluation
|
|
188
|
+
* Uses `once()` for lazy evaluation: safe for SSR and avoids hydration mismatches.
|
|
152
189
|
*/
|
|
153
190
|
var supportsAnchorPositioning = (0, _once.default)(function () {
|
|
154
191
|
if (typeof window === 'undefined' || typeof CSS === 'undefined' || typeof CSS.supports !== 'function') {
|
|
@@ -228,34 +265,51 @@ function crossAxisShiftMargin(_ref4) {
|
|
|
228
265
|
}
|
|
229
266
|
|
|
230
267
|
/**
|
|
231
|
-
* Returns a referentially-stable, fully-resolved `TPlacement
|
|
232
|
-
*
|
|
233
|
-
* does not
|
|
268
|
+
* Returns a referentially-stable, fully-resolved `TPlacement`. `useMemo` is
|
|
269
|
+
* keyed on the primitive fields of the input so a fresh inline `placement`
|
|
270
|
+
* object on every render does not produce a fresh resolved object. Both
|
|
271
|
+
* `getPlacement` and the equality check are skipped when the inputs are
|
|
272
|
+
* unchanged.
|
|
234
273
|
*/
|
|
235
274
|
function useStablePlacement(placement) {
|
|
275
|
+
// Resolve to the fully-defaulted primitives BEFORE the memo so the deps
|
|
276
|
+
// array sees the same key for `{}`, `undefined` fields, and explicit
|
|
277
|
+
// defaults. Otherwise `axis: undefined` and `axis: 'block'` would be
|
|
278
|
+
// treated as different inputs and re-run the downstream effect.
|
|
236
279
|
var resolved = (0, _resolvePlacement.getPlacement)({
|
|
237
280
|
placement: placement
|
|
238
281
|
});
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
282
|
+
var axis = resolved.axis;
|
|
283
|
+
var edge = resolved.edge;
|
|
284
|
+
var align = resolved.align;
|
|
285
|
+
var gap = resolved.offset.gap;
|
|
286
|
+
var shiftValue = resolved.offset.crossAxisShift.value;
|
|
287
|
+
var shiftDirection = resolved.offset.crossAxisShift.direction;
|
|
288
|
+
// Rebuild the placement object inside the memo from the resolved primitive
|
|
289
|
+
// deps so the factory does not close over the (potentially fresh) outer
|
|
290
|
+
// `resolved` reference, and `react-hooks/exhaustive-deps` can verify the
|
|
291
|
+
// deps array.
|
|
292
|
+
return (0, _react.useMemo)(function () {
|
|
293
|
+
return {
|
|
294
|
+
axis: axis,
|
|
295
|
+
edge: edge,
|
|
296
|
+
align: align,
|
|
297
|
+
offset: {
|
|
298
|
+
gap: gap,
|
|
299
|
+
crossAxisShift: {
|
|
300
|
+
value: shiftValue,
|
|
301
|
+
direction: shiftDirection
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
}, [axis, edge, align, gap, shiftValue, shiftDirection]);
|
|
252
306
|
}
|
|
253
307
|
|
|
254
308
|
/**
|
|
255
309
|
* Hook that positions an element relative to an anchor element using
|
|
256
310
|
* CSS Anchor Positioning (with a JS fallback for older browsers).
|
|
257
311
|
*
|
|
258
|
-
* This hook is the positioning primitive
|
|
312
|
+
* This hook is the positioning primitive. It has no knowledge of popovers,
|
|
259
313
|
* visibility, or animation. Compose it with `Popover` for anchor-positioned
|
|
260
314
|
* top-layer content.
|
|
261
315
|
*
|
|
@@ -271,6 +325,7 @@ function isResolvedPlacementEqual(a, b) {
|
|
|
271
325
|
* comparison is used internally so re-runs are skipped when the resolved
|
|
272
326
|
* placement shape is unchanged.
|
|
273
327
|
*/
|
|
328
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
274
329
|
function useAnchorPosition(_ref5) {
|
|
275
330
|
var anchorRef = _ref5.anchorRef,
|
|
276
331
|
popoverRef = _ref5.popoverRef,
|
|
@@ -299,6 +354,9 @@ function useAnchorPosition(_ref5) {
|
|
|
299
354
|
placement: stablePlacement,
|
|
300
355
|
offset: gapCssValue
|
|
301
356
|
});
|
|
357
|
+
// Hoist crossAxisShift to a single computation; reused below to
|
|
358
|
+
// populate the active `--ds-cross-axis-shift-margin-*` custom
|
|
359
|
+
// property for the named arrow @position-try rules.
|
|
302
360
|
var crossAxisShift = crossAxisShiftMargin({
|
|
303
361
|
placement: stablePlacement,
|
|
304
362
|
crossAxisShiftCssValue: crossAxisShiftCssValue,
|
|
@@ -358,11 +416,8 @@ function useAnchorPosition(_ref5) {
|
|
|
358
416
|
property: '--ds-cross-axis-shift-margin-block-end',
|
|
359
417
|
value: '0px'
|
|
360
418
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
crossAxisShiftCssValue: crossAxisShiftCssValue,
|
|
364
|
-
direction: stablePlacement.offset.crossAxisShift.direction
|
|
365
|
-
});
|
|
419
|
+
// `crossAxisShift` IS the active margin - reuse instead of recomputing.
|
|
420
|
+
var crossAxisShiftActive = crossAxisShift;
|
|
366
421
|
// Map margin property to its corresponding custom property name.
|
|
367
422
|
var customPropertyByMarginProperty = {
|
|
368
423
|
'margin-inline-start': '--ds-cross-axis-shift-margin-start',
|
|
@@ -387,7 +442,7 @@ function useAnchorPosition(_ref5) {
|
|
|
387
442
|
* - Sometimes the `useAnchorPosition` hook and `Popover`
|
|
388
443
|
* are not in the same component.
|
|
389
444
|
* - There can be times when, even with reference counting, we
|
|
390
|
-
* could remove the anchor-name while it
|
|
445
|
+
* could remove the anchor-name while it is still being used
|
|
391
446
|
* by something else - especially with async react updates
|
|
392
447
|
* which can cause tearing
|
|
393
448
|
*
|
|
@@ -418,7 +473,6 @@ function useAnchorPosition(_ref5) {
|
|
|
418
473
|
}]
|
|
419
474
|
});
|
|
420
475
|
function update() {
|
|
421
|
-
var _popover$parentElemen;
|
|
422
476
|
if (!trigger || !popover) {
|
|
423
477
|
return;
|
|
424
478
|
}
|
|
@@ -429,19 +483,19 @@ function useAnchorPosition(_ref5) {
|
|
|
429
483
|
};
|
|
430
484
|
|
|
431
485
|
// Resolve consumer-supplied CSS length strings (tokens, calc, var,
|
|
432
|
-
// px, rem, etc) to pixels. The probe is mounted
|
|
433
|
-
// so
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
437
|
-
|
|
486
|
+
// px, rem, etc) to pixels. The probe is mounted INSIDE the popover
|
|
487
|
+
// itself so the resolved length matches the scope a token would
|
|
488
|
+
// resolve against from inside the popover content. (The popover
|
|
489
|
+
// lives in the top layer, not the trigger's DOM tree, so probing
|
|
490
|
+
// at `popover.parentElement` would resolve in a different scope
|
|
491
|
+
// than the consumer's token authoring expects.)
|
|
438
492
|
var gapPx = (0, _resolveCssLengthToPixels.resolveCssLengthToPixels)({
|
|
439
493
|
value: gapCssValue,
|
|
440
|
-
container:
|
|
494
|
+
container: popover
|
|
441
495
|
});
|
|
442
496
|
var crossAxisShiftPx = (0, _resolveCssLengthToPixels.resolveCssLengthToPixels)({
|
|
443
497
|
value: crossAxisShiftCssValue,
|
|
444
|
-
container:
|
|
498
|
+
container: popover
|
|
445
499
|
});
|
|
446
500
|
var _computeFallbackPosit = (0, _anchorPositioningFallback.computeFallbackPosition)({
|
|
447
501
|
triggerRect: triggerRect,
|
|
@@ -474,25 +528,12 @@ function useAnchorPosition(_ref5) {
|
|
|
474
528
|
// scroll/resize is handled by the window listeners below.
|
|
475
529
|
// `ResizeObserver` is missing in some non-DOM jest environments
|
|
476
530
|
// (e.g. post-office's `node` environment). Fall back to a no-op
|
|
477
|
-
// observer there
|
|
531
|
+
// observer there. The scroll/resize listeners below still keep
|
|
478
532
|
// the popover positioned in the rare case the consumer also
|
|
479
533
|
// polyfilled `showPopover` but not `ResizeObserver`. Real
|
|
480
|
-
// browsers always have it.
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
(0, _classCallCheck2.default)(this, NoopResizeObserver);
|
|
484
|
-
}
|
|
485
|
-
return (0, _createClass2.default)(NoopResizeObserver, [{
|
|
486
|
-
key: "observe",
|
|
487
|
-
value: function observe() {}
|
|
488
|
-
}, {
|
|
489
|
-
key: "unobserve",
|
|
490
|
-
value: function unobserve() {}
|
|
491
|
-
}, {
|
|
492
|
-
key: "disconnect",
|
|
493
|
-
value: function disconnect() {}
|
|
494
|
-
}]);
|
|
495
|
-
}();
|
|
534
|
+
// browsers always have it. The `NoopResizeObserver` class is
|
|
535
|
+
// hoisted to module scope (see top of file) so we do not allocate
|
|
536
|
+
// a new constructor on every effect run.
|
|
496
537
|
var ResizeObserverImpl = typeof ResizeObserver !== 'undefined' ? ResizeObserver : NoopResizeObserver;
|
|
497
538
|
var resizeObserver = new ResizeObserverImpl(function () {
|
|
498
539
|
if (popover.offsetWidth > 0 && popover.offsetHeight > 0) {
|
|
@@ -515,7 +556,7 @@ function useAnchorPosition(_ref5) {
|
|
|
515
556
|
// the UA-default position, then re-observe for a fresh
|
|
516
557
|
// measurement. We use `opacity: 0` rather than
|
|
517
558
|
// `visibility: hidden` because Firefox skips visibility-hidden
|
|
518
|
-
// elements during `<dialog>` initial-focus traversal
|
|
559
|
+
// elements during `<dialog>` initial-focus traversal. See
|
|
519
560
|
// `form-in-popup.spec.tsx` on `desktop-firefox`.
|
|
520
561
|
(0, _bindEventListener.bind)(popover, {
|
|
521
562
|
type: 'toggle',
|
|
@@ -19,7 +19,7 @@ var _focus = require("../focus/focus");
|
|
|
19
19
|
* not Tab. Tab/Shift+Tab should move focus OUT of a menu entirely.
|
|
20
20
|
*
|
|
21
21
|
* Menu keyboard behavior (arrow keys, Home/End, type-ahead, Enter/Space)
|
|
22
|
-
* is context-dependent
|
|
22
|
+
* is context-dependent. It varies by orientation, nesting depth, item
|
|
23
23
|
* type, and control pattern (menu button vs menubar). This makes it
|
|
24
24
|
* impossible to implement generically here. The consumer component
|
|
25
25
|
* (e.g. `dropdown-menu`) owns all menu keyboard navigation.
|
|
@@ -59,6 +59,17 @@ function useFocusWrap(_ref) {
|
|
|
59
59
|
if (event.key !== 'Tab') {
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
// If focus is already in a nested layer, then
|
|
64
|
+
// we continue to let that nested layer own focus
|
|
65
|
+
if ((0, _focus.isNestedLayerFocused)({
|
|
66
|
+
container: element
|
|
67
|
+
})) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Prevent the browser giving focus to where it wants to
|
|
72
|
+
// (we will be handling it, including with wrapping)
|
|
62
73
|
event.preventDefault();
|
|
63
74
|
var direction = event.shiftKey ? 'backwards' : 'forwards';
|
|
64
75
|
|
|
@@ -74,7 +85,7 @@ function useFocusWrap(_ref) {
|
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
// Nothing is currently focused inside the container (or the
|
|
77
|
-
// focused element
|
|
88
|
+
// focused element is not in the focusable list). Fall back to
|
|
78
89
|
// the first or last focusable element depending on direction.
|
|
79
90
|
var fallback = direction === 'forwards' ? (0, _focus.getFirstFocusable)({
|
|
80
91
|
container: element
|