@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
package/dist/esm/focus/focus.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* restrict which focusable elements are included.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { getDocument } from '@atlaskit/browser-apis';
|
|
13
14
|
var selectors = function () {
|
|
14
15
|
// Common exclusion filter applied to every selector.
|
|
15
16
|
var not = ':not([tabindex="-1"]):not([aria-disabled="true"]):not([aria-hidden="true"])';
|
|
@@ -17,9 +18,54 @@ var selectors = function () {
|
|
|
17
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)];
|
|
18
19
|
return {
|
|
19
20
|
focusable: focusable.join(','),
|
|
20
|
-
|
|
21
|
+
// Build the `:focus` selector
|
|
22
|
+
focused: focusable.map(function (selector) {
|
|
23
|
+
return "".concat(selector, ":focus");
|
|
24
|
+
}).join(',')
|
|
21
25
|
};
|
|
22
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
|
+
}
|
|
23
69
|
|
|
24
70
|
/**
|
|
25
71
|
* An optional callback to restrict which focusable elements are included.
|
|
@@ -29,17 +75,21 @@ var selectors = function () {
|
|
|
29
75
|
/**
|
|
30
76
|
* Returns all focusable HTMLElements within the container, optionally filtered.
|
|
31
77
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* is
|
|
36
|
-
* assumption changes, this would need to be scoped to the current layer.
|
|
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.
|
|
37
82
|
*/
|
|
38
|
-
function getFocusables(
|
|
39
|
-
var container =
|
|
40
|
-
filter =
|
|
83
|
+
function getFocusables(_ref3) {
|
|
84
|
+
var container = _ref3.container,
|
|
85
|
+
filter = _ref3.filter;
|
|
41
86
|
return Array.from(container.querySelectorAll(selectors.focusable)).filter(function (element) {
|
|
42
87
|
return element instanceof HTMLElement;
|
|
88
|
+
}).filter(function (element) {
|
|
89
|
+
return isInSameLayer({
|
|
90
|
+
element: element,
|
|
91
|
+
container: container
|
|
92
|
+
});
|
|
43
93
|
}).filter(function (element) {
|
|
44
94
|
return !filter || filter(element, container);
|
|
45
95
|
});
|
|
@@ -48,9 +98,10 @@ function getFocusables(_ref) {
|
|
|
48
98
|
/**
|
|
49
99
|
* Returns the first focusable element within the container.
|
|
50
100
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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;
|
|
54
105
|
var items = getFocusables({
|
|
55
106
|
container: container,
|
|
56
107
|
filter: filter
|
|
@@ -61,9 +112,10 @@ export function getFirstFocusable(_ref2) {
|
|
|
61
112
|
/**
|
|
62
113
|
* Returns the last focusable element within the container.
|
|
63
114
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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;
|
|
67
119
|
var items = getFocusables({
|
|
68
120
|
container: container,
|
|
69
121
|
filter: filter
|
|
@@ -78,11 +130,12 @@ export function getLastFocusable(_ref3) {
|
|
|
78
130
|
* Returns `null` if there is no focused element within the container or if
|
|
79
131
|
* the focused element is not in the list of focusable elements.
|
|
80
132
|
*/
|
|
81
|
-
|
|
133
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
134
|
+
export function getNextFocusable(_ref6) {
|
|
82
135
|
var _all$nextIndex;
|
|
83
|
-
var container =
|
|
84
|
-
direction =
|
|
85
|
-
filter =
|
|
136
|
+
var container = _ref6.container,
|
|
137
|
+
direction = _ref6.direction,
|
|
138
|
+
filter = _ref6.filter;
|
|
86
139
|
var all = getFocusables({
|
|
87
140
|
container: container,
|
|
88
141
|
filter: filter
|
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// This file exists for module resolution purposes.
|
|
2
2
|
// Not exporting anything from the root entry point.
|
|
3
|
-
// Please use individual entry points for minimum bundle size:
|
|
4
3
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// Use individual entry points for minimum bundle size - the full list of
|
|
5
|
+
// available subpaths is the `"exports"` field in this package's
|
|
6
|
+
// `package.json`. The README documents the most common ones.
|
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
var elementCaches = new WeakMap();
|
|
2
|
+
function canCacheResolvedLength(value) {
|
|
3
|
+
// Custom-property values can be retargeted by inline overrides on the
|
|
4
|
+
// consumer's wrapper, so we cannot prove a cached pixel value is still valid.
|
|
5
|
+
return !value.includes('var(');
|
|
6
|
+
}
|
|
7
|
+
function getCachedResolvedLength(_ref) {
|
|
8
|
+
var _cacheForElement$get;
|
|
9
|
+
var element = _ref.element,
|
|
10
|
+
value = _ref.value;
|
|
11
|
+
if (!canCacheResolvedLength(value)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
var cacheForElement = elementCaches.get(element);
|
|
15
|
+
return (_cacheForElement$get = cacheForElement === null || cacheForElement === void 0 ? void 0 : cacheForElement.get(value)) !== null && _cacheForElement$get !== void 0 ? _cacheForElement$get : null;
|
|
16
|
+
}
|
|
17
|
+
function cacheResolvedLength(_ref2) {
|
|
18
|
+
var _elementCaches$get;
|
|
19
|
+
var element = _ref2.element,
|
|
20
|
+
value = _ref2.value,
|
|
21
|
+
result = _ref2.result;
|
|
22
|
+
if (!canCacheResolvedLength(value)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
var cacheForElement = (_elementCaches$get = elementCaches.get(element)) !== null && _elementCaches$get !== void 0 ? _elementCaches$get : new Map();
|
|
26
|
+
cacheForElement.set(value, result);
|
|
27
|
+
elementCaches.set(element, cacheForElement);
|
|
28
|
+
}
|
|
29
|
+
|
|
1
30
|
/**
|
|
2
31
|
* Resolves a CSS length value to a pixel number using a hidden DOM probe.
|
|
3
32
|
*
|
|
@@ -8,27 +37,39 @@
|
|
|
8
37
|
* the browser do the math.
|
|
9
38
|
*
|
|
10
39
|
* The probe is appended to `container` so it inherits the same containing
|
|
11
|
-
* block, font size, and custom-property scope as the popover.
|
|
12
|
-
* because it accepts any CSS length, including negative `calc()` results
|
|
13
|
-
* (negative widths are clamped to 0 — see note below).
|
|
40
|
+
* block, font size, and custom-property scope as the popover.
|
|
14
41
|
*
|
|
15
|
-
* Cost: one synchronous reflow
|
|
16
|
-
*
|
|
17
|
-
*
|
|
42
|
+
* Cost: one synchronous reflow on first cacheable resolution per
|
|
43
|
+
* (container, value) pair, then a `WeakMap` lookup. Resolutions involving
|
|
44
|
+
* `var(` are intentionally not cached.
|
|
18
45
|
*/
|
|
19
|
-
export function resolveCssLengthToPixels(
|
|
20
|
-
var value =
|
|
21
|
-
container =
|
|
46
|
+
export function resolveCssLengthToPixels(_ref3) {
|
|
47
|
+
var value = _ref3.value,
|
|
48
|
+
container = _ref3.container;
|
|
22
49
|
if (typeof value === 'number') {
|
|
23
50
|
return value;
|
|
24
51
|
}
|
|
25
52
|
|
|
53
|
+
// Fast path: unitless zero is universally zero pixels - accept `'0'` and
|
|
54
|
+
// `'-0'` without a probe. (Consumers occasionally pass `'0'` instead of
|
|
55
|
+
// the number `0`.)
|
|
56
|
+
if (value === '0' || value === '-0') {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
26
60
|
// Fast path: bare `${n}px` strings come from the consumer normalisation
|
|
27
61
|
// in `getPlacement`. Avoid a reflow when we can.
|
|
28
62
|
var pxMatch = value.match(/^(-?\d+(?:\.\d+)?)px$/);
|
|
29
63
|
if (pxMatch) {
|
|
30
64
|
return Number(pxMatch[1]);
|
|
31
65
|
}
|
|
66
|
+
var cached = getCachedResolvedLength({
|
|
67
|
+
element: container,
|
|
68
|
+
value: value
|
|
69
|
+
});
|
|
70
|
+
if (cached !== null) {
|
|
71
|
+
return cached;
|
|
72
|
+
}
|
|
32
73
|
var probe = container.ownerDocument.createElement('div');
|
|
33
74
|
probe.style.position = 'absolute';
|
|
34
75
|
probe.style.visibility = 'hidden';
|
|
@@ -40,8 +81,18 @@ export function resolveCssLengthToPixels(_ref) {
|
|
|
40
81
|
// preserved. `getComputedStyle` returns the resolved pixel value for
|
|
41
82
|
// margin-* properties even when the source was a token / calc / var.
|
|
42
83
|
probe.style.marginLeft = value;
|
|
84
|
+
// Hide the probe from assistive tech and event targeting; defensive
|
|
85
|
+
// against `getElementsByTagName('div')` walks in consumer code.
|
|
86
|
+
probe.setAttribute('aria-hidden', 'true');
|
|
87
|
+
probe.setAttribute('inert', '');
|
|
43
88
|
container.appendChild(probe);
|
|
44
89
|
var resolved = parseFloat(getComputedStyle(probe).marginLeft);
|
|
45
90
|
container.removeChild(probe);
|
|
46
|
-
|
|
91
|
+
var result = Number.isFinite(resolved) ? resolved : 0;
|
|
92
|
+
cacheResolvedLength({
|
|
93
|
+
element: container,
|
|
94
|
+
value: value,
|
|
95
|
+
result: result
|
|
96
|
+
});
|
|
97
|
+
return result;
|
|
47
98
|
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Valid values for the `aria-haspopup` attribute.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Derived from the HTML spec - maps popover roles to what the trigger
|
|
5
|
+
* announces. `undefined` means the attribute is omitted entirely (used for
|
|
6
|
+
* non-popup roles like `tooltip`/`status`/`alert`/`note`/`log` where
|
|
7
|
+
* `aria-haspopup` would be misleading).
|
|
8
|
+
*
|
|
9
|
+
* `true` is intentionally NOT in the union - the runtime only ever produces
|
|
10
|
+
* the explicit string forms, so widening the type would invite consumers to
|
|
11
|
+
* pass `true` and get an `aria-haspopup="true"` serialisation that the
|
|
12
|
+
* runtime no longer emits.
|
|
4
13
|
*/
|
|
5
14
|
|
|
6
15
|
/**
|
|
@@ -22,21 +31,27 @@
|
|
|
22
31
|
/**
|
|
23
32
|
* ARIA role props where a role is always required.
|
|
24
33
|
*
|
|
25
|
-
* Used by `TPopupContentProps
|
|
34
|
+
* Used by `TPopupContentProps`. Popup content must always declare
|
|
26
35
|
* its role so assistive technology can identify the layer.
|
|
27
36
|
*/
|
|
28
37
|
|
|
29
38
|
/**
|
|
30
39
|
* ARIA role props where a role is optional.
|
|
31
40
|
*
|
|
32
|
-
* Used by `TPopoverProps
|
|
41
|
+
* Used by `TPopoverProps`. The low-level primitive allows omitting
|
|
33
42
|
* the role for cases where it is set externally or not needed.
|
|
34
43
|
*/
|
|
35
44
|
|
|
36
45
|
/**
|
|
37
46
|
* Maps a popover content role to the correct `aria-haspopup` value
|
|
38
47
|
* for its trigger element.
|
|
48
|
+
*
|
|
49
|
+
* Returns `undefined` for roles that are not popups in the ARIA sense
|
|
50
|
+
* (`tooltip`, `note`, `status`, `alert`, `log`). Triggers for those roles
|
|
51
|
+
* should not announce a popup at all - emitting `aria-haspopup="dialog"`
|
|
52
|
+
* on a tooltip trigger would mislead assistive technology.
|
|
39
53
|
*/
|
|
54
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
40
55
|
export function roleToAriaHasPopup(_ref) {
|
|
41
56
|
var role = _ref.role;
|
|
42
57
|
if (role === 'menu') {
|
|
@@ -51,10 +66,25 @@ export function roleToAriaHasPopup(_ref) {
|
|
|
51
66
|
if (role === 'grid') {
|
|
52
67
|
return 'grid';
|
|
53
68
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
|
|
69
|
+
if (role === 'dialog' || role === 'alertdialog') {
|
|
70
|
+
return 'dialog';
|
|
71
|
+
}
|
|
72
|
+
// Non-popup roles (tooltip, note, status, alert, log) and the
|
|
73
|
+
// no-role case: omit `aria-haspopup` entirely. React drops the
|
|
74
|
+
// attribute when the value is `undefined`.
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
var rolesThatMoveFocus = new Set(['dialog', 'alertdialog', 'menu', 'listbox', 'tree', 'grid']);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns `true` when the given popover role moves focus into the popover
|
|
81
|
+
* on open, and `false` otherwise (including when `role` is `undefined`).
|
|
82
|
+
*/
|
|
83
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
84
|
+
export function shouldFocusIntoPopover(_ref2) {
|
|
85
|
+
var role = _ref2.role;
|
|
86
|
+
if (!role) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return rolesThatMoveFocus.has(role);
|
|
60
90
|
}
|
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Sets inline styles on an element and returns a cleanup function
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Uses `style.setProperty()` / `style.removeProperty()` so that
|
|
6
|
-
* hyphenated CSS property names (e.g. `position-area`, `anchor-name`)
|
|
7
|
-
* work correctly. These newer properties do not have camelCase
|
|
8
|
-
* mappings in `CSSStyleDeclaration` yet.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```ts
|
|
12
|
-
* const cleanup = setStyle({ el: popover, styles: [
|
|
13
|
-
* { property: 'position-anchor', value: '--my-anchor' },
|
|
14
|
-
* { property: 'position-area', value: 'block-end' },
|
|
15
|
-
* { property: 'margin', value: '0' },
|
|
16
|
-
* ] });
|
|
17
|
-
*
|
|
18
|
-
* // Later: removes all three properties
|
|
19
|
-
* cleanup();
|
|
20
|
-
* ```
|
|
2
|
+
* Sets inline styles on an element and returns a cleanup function that
|
|
3
|
+
* restores the prior inline values (so we do not stomp consumer styles).
|
|
21
4
|
*/
|
|
22
5
|
export function setStyle(_ref) {
|
|
23
6
|
var el = _ref.el,
|
|
24
7
|
styles = _ref.styles;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
// Snapshot the prior inline value (NOT the computed style - we only want
|
|
9
|
+
// to restore values that the consumer/our previous run inlined). An empty
|
|
10
|
+
// string means "no inline value", in which case cleanup uses removeProperty.
|
|
11
|
+
var priorValues = styles.map(function (_ref2) {
|
|
12
|
+
var property = _ref2.property;
|
|
13
|
+
return {
|
|
14
|
+
property: property,
|
|
15
|
+
value: el.style.getPropertyValue(property)
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
styles.forEach(function (_ref3) {
|
|
19
|
+
var property = _ref3.property,
|
|
20
|
+
value = _ref3.value;
|
|
28
21
|
el.style.setProperty(property, value);
|
|
29
22
|
});
|
|
30
23
|
return function cleanup() {
|
|
31
|
-
|
|
32
|
-
var property =
|
|
33
|
-
|
|
24
|
+
priorValues.forEach(function (_ref4) {
|
|
25
|
+
var property = _ref4.property,
|
|
26
|
+
value = _ref4.value;
|
|
27
|
+
if (value === '') {
|
|
28
|
+
el.style.removeProperty(property);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
el.style.setProperty(property, value);
|
|
34
32
|
});
|
|
35
33
|
};
|
|
36
34
|
}
|