@primer/behaviors 0.0.0-20260106153830 → 0.0.0-20260108040347
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.
|
@@ -12,9 +12,9 @@ const alternateAlignments = {
|
|
|
12
12
|
center: ['end', 'start'],
|
|
13
13
|
};
|
|
14
14
|
function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
|
|
15
|
-
const parentElement =
|
|
16
|
-
const clippingRect = getClippingRect(
|
|
17
|
-
const parentElementStyle = getComputedStyle(parentElement);
|
|
15
|
+
const { positionedParent: parentElement, clippingNode, positionedParentStyle, clippingNodeStyle, } = getPositionedParentAndClippingNode(floatingElement);
|
|
16
|
+
const clippingRect = getClippingRect(clippingNode, clippingNodeStyle);
|
|
17
|
+
const parentElementStyle = positionedParentStyle || getComputedStyle(parentElement);
|
|
18
18
|
const parentElementRect = parentElement.getBoundingClientRect();
|
|
19
19
|
const [borderTop, borderLeft] = [parentElementStyle.borderTopWidth, parentElementStyle.borderLeftWidth].map(v => parseInt(v, 10) || 0);
|
|
20
20
|
const relativeRect = {
|
|
@@ -23,19 +23,43 @@ function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
|
|
|
23
23
|
};
|
|
24
24
|
return pureCalculateAnchoredPosition(clippingRect, relativeRect, floatingElement.getBoundingClientRect(), anchorElement instanceof Element ? anchorElement.getBoundingClientRect() : anchorElement, getDefaultSettings(settings));
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
if (isOnTopLayer(element))
|
|
28
|
-
return
|
|
26
|
+
function getPositionedParentAndClippingNode(element) {
|
|
27
|
+
if (isOnTopLayer(element)) {
|
|
28
|
+
return {
|
|
29
|
+
positionedParent: document.body,
|
|
30
|
+
clippingNode: document.body,
|
|
31
|
+
positionedParentStyle: null,
|
|
32
|
+
clippingNodeStyle: null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
let positionedParent = null;
|
|
36
|
+
let clippingNode = null;
|
|
37
|
+
let positionedParentStyle = null;
|
|
38
|
+
let clippingNodeStyle = null;
|
|
29
39
|
let parentNode = element.parentNode;
|
|
30
40
|
while (parentNode !== null && parentNode !== document.body) {
|
|
31
41
|
if (parentNode instanceof HTMLElement) {
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
const style = getComputedStyle(parentNode);
|
|
43
|
+
if (!positionedParent && style.position !== 'static') {
|
|
44
|
+
positionedParent = parentNode;
|
|
45
|
+
positionedParentStyle = style;
|
|
46
|
+
}
|
|
47
|
+
if (!clippingNode && style.overflow !== 'visible') {
|
|
48
|
+
clippingNode = parentNode;
|
|
49
|
+
clippingNodeStyle = style;
|
|
50
|
+
}
|
|
51
|
+
if (positionedParent && clippingNode) {
|
|
52
|
+
break;
|
|
34
53
|
}
|
|
35
54
|
}
|
|
36
55
|
parentNode = parentNode.parentNode;
|
|
37
56
|
}
|
|
38
|
-
return
|
|
57
|
+
return {
|
|
58
|
+
positionedParent: positionedParent !== null && positionedParent !== void 0 ? positionedParent : document.body,
|
|
59
|
+
clippingNode: clippingNode !== null && clippingNode !== void 0 ? clippingNode : document.body,
|
|
60
|
+
positionedParentStyle,
|
|
61
|
+
clippingNodeStyle,
|
|
62
|
+
};
|
|
39
63
|
}
|
|
40
64
|
function isOnTopLayer(element) {
|
|
41
65
|
var _a;
|
|
@@ -52,21 +76,9 @@ function isOnTopLayer(element) {
|
|
|
52
76
|
}
|
|
53
77
|
return false;
|
|
54
78
|
}
|
|
55
|
-
function getClippingRect(
|
|
56
|
-
let clippingNode = document.body;
|
|
57
|
-
let parentNode = element;
|
|
58
|
-
while (parentNode !== null && parentNode !== document.body) {
|
|
59
|
-
if (parentNode instanceof HTMLElement) {
|
|
60
|
-
const overflow = getComputedStyle(parentNode).overflow;
|
|
61
|
-
if (overflow !== 'visible') {
|
|
62
|
-
clippingNode = parentNode;
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
parentNode = parentNode.parentNode;
|
|
67
|
-
}
|
|
79
|
+
function getClippingRect(clippingNode, cachedStyle = null) {
|
|
68
80
|
const elemRect = clippingNode.getBoundingClientRect();
|
|
69
|
-
const elemStyle = getComputedStyle(clippingNode);
|
|
81
|
+
const elemStyle = cachedStyle || getComputedStyle(clippingNode);
|
|
70
82
|
const borderTop = parseInt(elemStyle.borderTopWidth, 10) || 0;
|
|
71
83
|
const borderLeft = parseInt(elemStyle.borderLeftWidth, 10) || 0;
|
|
72
84
|
const borderRight = parseInt(elemStyle.borderRightWidth, 10) || 0;
|
package/dist/cjs/focus-zone.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export type FocusZoneSettings = IterateFocusableElements & {
|
|
|
28
28
|
focusInStrategy?: 'first' | 'closest' | 'previous' | 'initial' | ((previousFocusedElement: Element) => HTMLElement | undefined);
|
|
29
29
|
preventScroll?: boolean;
|
|
30
30
|
ignoreHoverEvents?: boolean;
|
|
31
|
-
focusPrependedElements?: boolean;
|
|
32
31
|
};
|
|
33
32
|
export declare const isActiveDescendantAttribute = "data-is-active-descendant";
|
|
34
33
|
export declare const activeDescendantActivatedDirectly = "activated-directly";
|
package/dist/cjs/focus-zone.js
CHANGED
|
@@ -131,7 +131,7 @@ const activeDescendantActivatedDirectly = 'activated-directly';
|
|
|
131
131
|
const activeDescendantActivatedIndirectly = 'activated-indirectly';
|
|
132
132
|
const hasActiveDescendantAttribute = 'data-has-active-descendant';
|
|
133
133
|
function focusZone(container, settings) {
|
|
134
|
-
var _a, _b, _c, _d, _e, _f
|
|
134
|
+
var _a, _b, _c, _d, _e, _f;
|
|
135
135
|
const focusableElements = new indexedSet.IndexedSet();
|
|
136
136
|
const savedTabIndex = new WeakMap();
|
|
137
137
|
const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? exports.FocusKeys.ArrowAll : exports.FocusKeys.ArrowVertical) | exports.FocusKeys.HomeAndEnd;
|
|
@@ -140,10 +140,8 @@ function focusZone(container, settings) {
|
|
|
140
140
|
const activeDescendantControl = settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl;
|
|
141
141
|
const activeDescendantCallback = settings === null || settings === void 0 ? void 0 : settings.onActiveDescendantChanged;
|
|
142
142
|
const ignoreHoverEvents = (_d = settings === null || settings === void 0 ? void 0 : settings.ignoreHoverEvents) !== null && _d !== void 0 ? _d : false;
|
|
143
|
-
const focusPrependedElements = (_e = settings === null || settings === void 0 ? void 0 : settings.focusPrependedElements) !== null && _e !== void 0 ? _e : false;
|
|
144
143
|
let currentFocusedElement;
|
|
145
|
-
|
|
146
|
-
const preventScroll = (_f = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _f !== void 0 ? _f : false;
|
|
144
|
+
const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
|
|
147
145
|
const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
|
|
148
146
|
function getFirstFocusableElement() {
|
|
149
147
|
return focusableElements.get(0);
|
|
@@ -154,7 +152,6 @@ function focusZone(container, settings) {
|
|
|
154
152
|
function updateFocusedElement(to, directlyActivated = false) {
|
|
155
153
|
const from = currentFocusedElement;
|
|
156
154
|
currentFocusedElement = to;
|
|
157
|
-
wasDirectlyActivated = directlyActivated;
|
|
158
155
|
if (activeDescendantControl) {
|
|
159
156
|
if (to && isActiveDescendantInputFocused()) {
|
|
160
157
|
setActiveDescendant(from, to, directlyActivated);
|
|
@@ -205,16 +202,14 @@ function focusZone(container, settings) {
|
|
|
205
202
|
if (filteredElements.length === 0) {
|
|
206
203
|
return;
|
|
207
204
|
}
|
|
208
|
-
|
|
209
|
-
focusableElements.insertAt(insertionIndex, ...filteredElements);
|
|
205
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
210
206
|
for (const element of filteredElements) {
|
|
211
207
|
if (!savedTabIndex.has(element)) {
|
|
212
208
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
213
209
|
}
|
|
214
210
|
element.setAttribute('tabindex', '-1');
|
|
215
211
|
}
|
|
216
|
-
|
|
217
|
-
if (!preventInitialFocus && (!currentFocusedElement || shouldFocusPrepended)) {
|
|
212
|
+
if (!currentFocusedElement && !preventInitialFocus) {
|
|
218
213
|
updateFocusedElement(getFirstFocusableElement());
|
|
219
214
|
}
|
|
220
215
|
}
|
|
@@ -332,7 +327,7 @@ function focusZone(container, settings) {
|
|
|
332
327
|
attributeOldValue: true,
|
|
333
328
|
});
|
|
334
329
|
const controller = new AbortController();
|
|
335
|
-
const signal = (
|
|
330
|
+
const signal = (_f = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _f !== void 0 ? _f : controller.signal;
|
|
336
331
|
signal.addEventListener('abort', () => {
|
|
337
332
|
observer.disconnect();
|
|
338
333
|
endFocusManagement(...focusableElements);
|
|
@@ -10,9 +10,9 @@ const alternateAlignments = {
|
|
|
10
10
|
center: ['end', 'start'],
|
|
11
11
|
};
|
|
12
12
|
function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
|
|
13
|
-
const parentElement =
|
|
14
|
-
const clippingRect = getClippingRect(
|
|
15
|
-
const parentElementStyle = getComputedStyle(parentElement);
|
|
13
|
+
const { positionedParent: parentElement, clippingNode, positionedParentStyle, clippingNodeStyle, } = getPositionedParentAndClippingNode(floatingElement);
|
|
14
|
+
const clippingRect = getClippingRect(clippingNode, clippingNodeStyle);
|
|
15
|
+
const parentElementStyle = positionedParentStyle || getComputedStyle(parentElement);
|
|
16
16
|
const parentElementRect = parentElement.getBoundingClientRect();
|
|
17
17
|
const [borderTop, borderLeft] = [parentElementStyle.borderTopWidth, parentElementStyle.borderLeftWidth].map(v => parseInt(v, 10) || 0);
|
|
18
18
|
const relativeRect = {
|
|
@@ -21,19 +21,43 @@ function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
|
|
|
21
21
|
};
|
|
22
22
|
return pureCalculateAnchoredPosition(clippingRect, relativeRect, floatingElement.getBoundingClientRect(), anchorElement instanceof Element ? anchorElement.getBoundingClientRect() : anchorElement, getDefaultSettings(settings));
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
if (isOnTopLayer(element))
|
|
26
|
-
return
|
|
24
|
+
function getPositionedParentAndClippingNode(element) {
|
|
25
|
+
if (isOnTopLayer(element)) {
|
|
26
|
+
return {
|
|
27
|
+
positionedParent: document.body,
|
|
28
|
+
clippingNode: document.body,
|
|
29
|
+
positionedParentStyle: null,
|
|
30
|
+
clippingNodeStyle: null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
let positionedParent = null;
|
|
34
|
+
let clippingNode = null;
|
|
35
|
+
let positionedParentStyle = null;
|
|
36
|
+
let clippingNodeStyle = null;
|
|
27
37
|
let parentNode = element.parentNode;
|
|
28
38
|
while (parentNode !== null && parentNode !== document.body) {
|
|
29
39
|
if (parentNode instanceof HTMLElement) {
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
const style = getComputedStyle(parentNode);
|
|
41
|
+
if (!positionedParent && style.position !== 'static') {
|
|
42
|
+
positionedParent = parentNode;
|
|
43
|
+
positionedParentStyle = style;
|
|
44
|
+
}
|
|
45
|
+
if (!clippingNode && style.overflow !== 'visible') {
|
|
46
|
+
clippingNode = parentNode;
|
|
47
|
+
clippingNodeStyle = style;
|
|
48
|
+
}
|
|
49
|
+
if (positionedParent && clippingNode) {
|
|
50
|
+
break;
|
|
32
51
|
}
|
|
33
52
|
}
|
|
34
53
|
parentNode = parentNode.parentNode;
|
|
35
54
|
}
|
|
36
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
positionedParent: positionedParent !== null && positionedParent !== void 0 ? positionedParent : document.body,
|
|
57
|
+
clippingNode: clippingNode !== null && clippingNode !== void 0 ? clippingNode : document.body,
|
|
58
|
+
positionedParentStyle,
|
|
59
|
+
clippingNodeStyle,
|
|
60
|
+
};
|
|
37
61
|
}
|
|
38
62
|
function isOnTopLayer(element) {
|
|
39
63
|
var _a;
|
|
@@ -50,21 +74,9 @@ function isOnTopLayer(element) {
|
|
|
50
74
|
}
|
|
51
75
|
return false;
|
|
52
76
|
}
|
|
53
|
-
function getClippingRect(
|
|
54
|
-
let clippingNode = document.body;
|
|
55
|
-
let parentNode = element;
|
|
56
|
-
while (parentNode !== null && parentNode !== document.body) {
|
|
57
|
-
if (parentNode instanceof HTMLElement) {
|
|
58
|
-
const overflow = getComputedStyle(parentNode).overflow;
|
|
59
|
-
if (overflow !== 'visible') {
|
|
60
|
-
clippingNode = parentNode;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
parentNode = parentNode.parentNode;
|
|
65
|
-
}
|
|
77
|
+
function getClippingRect(clippingNode, cachedStyle = null) {
|
|
66
78
|
const elemRect = clippingNode.getBoundingClientRect();
|
|
67
|
-
const elemStyle = getComputedStyle(clippingNode);
|
|
79
|
+
const elemStyle = cachedStyle || getComputedStyle(clippingNode);
|
|
68
80
|
const borderTop = parseInt(elemStyle.borderTopWidth, 10) || 0;
|
|
69
81
|
const borderLeft = parseInt(elemStyle.borderLeftWidth, 10) || 0;
|
|
70
82
|
const borderRight = parseInt(elemStyle.borderRightWidth, 10) || 0;
|
package/dist/esm/focus-zone.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export type FocusZoneSettings = IterateFocusableElements & {
|
|
|
28
28
|
focusInStrategy?: 'first' | 'closest' | 'previous' | 'initial' | ((previousFocusedElement: Element) => HTMLElement | undefined);
|
|
29
29
|
preventScroll?: boolean;
|
|
30
30
|
ignoreHoverEvents?: boolean;
|
|
31
|
-
focusPrependedElements?: boolean;
|
|
32
31
|
};
|
|
33
32
|
export declare const isActiveDescendantAttribute = "data-is-active-descendant";
|
|
34
33
|
export declare const activeDescendantActivatedDirectly = "activated-directly";
|
package/dist/esm/focus-zone.mjs
CHANGED
|
@@ -129,7 +129,7 @@ const activeDescendantActivatedDirectly = 'activated-directly';
|
|
|
129
129
|
const activeDescendantActivatedIndirectly = 'activated-indirectly';
|
|
130
130
|
const hasActiveDescendantAttribute = 'data-has-active-descendant';
|
|
131
131
|
function focusZone(container, settings) {
|
|
132
|
-
var _a, _b, _c, _d, _e, _f
|
|
132
|
+
var _a, _b, _c, _d, _e, _f;
|
|
133
133
|
const focusableElements = new IndexedSet();
|
|
134
134
|
const savedTabIndex = new WeakMap();
|
|
135
135
|
const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? FocusKeys.ArrowAll : FocusKeys.ArrowVertical) | FocusKeys.HomeAndEnd;
|
|
@@ -138,10 +138,8 @@ function focusZone(container, settings) {
|
|
|
138
138
|
const activeDescendantControl = settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl;
|
|
139
139
|
const activeDescendantCallback = settings === null || settings === void 0 ? void 0 : settings.onActiveDescendantChanged;
|
|
140
140
|
const ignoreHoverEvents = (_d = settings === null || settings === void 0 ? void 0 : settings.ignoreHoverEvents) !== null && _d !== void 0 ? _d : false;
|
|
141
|
-
const focusPrependedElements = (_e = settings === null || settings === void 0 ? void 0 : settings.focusPrependedElements) !== null && _e !== void 0 ? _e : false;
|
|
142
141
|
let currentFocusedElement;
|
|
143
|
-
|
|
144
|
-
const preventScroll = (_f = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _f !== void 0 ? _f : false;
|
|
142
|
+
const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
|
|
145
143
|
const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
|
|
146
144
|
function getFirstFocusableElement() {
|
|
147
145
|
return focusableElements.get(0);
|
|
@@ -152,7 +150,6 @@ function focusZone(container, settings) {
|
|
|
152
150
|
function updateFocusedElement(to, directlyActivated = false) {
|
|
153
151
|
const from = currentFocusedElement;
|
|
154
152
|
currentFocusedElement = to;
|
|
155
|
-
wasDirectlyActivated = directlyActivated;
|
|
156
153
|
if (activeDescendantControl) {
|
|
157
154
|
if (to && isActiveDescendantInputFocused()) {
|
|
158
155
|
setActiveDescendant(from, to, directlyActivated);
|
|
@@ -203,16 +200,14 @@ function focusZone(container, settings) {
|
|
|
203
200
|
if (filteredElements.length === 0) {
|
|
204
201
|
return;
|
|
205
202
|
}
|
|
206
|
-
|
|
207
|
-
focusableElements.insertAt(insertionIndex, ...filteredElements);
|
|
203
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
208
204
|
for (const element of filteredElements) {
|
|
209
205
|
if (!savedTabIndex.has(element)) {
|
|
210
206
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
211
207
|
}
|
|
212
208
|
element.setAttribute('tabindex', '-1');
|
|
213
209
|
}
|
|
214
|
-
|
|
215
|
-
if (!preventInitialFocus && (!currentFocusedElement || shouldFocusPrepended)) {
|
|
210
|
+
if (!currentFocusedElement && !preventInitialFocus) {
|
|
216
211
|
updateFocusedElement(getFirstFocusableElement());
|
|
217
212
|
}
|
|
218
213
|
}
|
|
@@ -330,7 +325,7 @@ function focusZone(container, settings) {
|
|
|
330
325
|
attributeOldValue: true,
|
|
331
326
|
});
|
|
332
327
|
const controller = new AbortController();
|
|
333
|
-
const signal = (
|
|
328
|
+
const signal = (_f = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _f !== void 0 ? _f : controller.signal;
|
|
334
329
|
signal.addEventListener('abort', () => {
|
|
335
330
|
observer.disconnect();
|
|
336
331
|
endFocusManagement(...focusableElements);
|