@oscarpalmer/oui 0.18.0 → 0.19.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/dist/css/badge.css +10 -10
- package/dist/css/button.css +9 -9
- package/dist/css/color.css +99 -99
- package/dist/css/content.css +1 -1
- package/dist/css/flex.css +39 -39
- package/dist/css/form.css +29 -56
- package/dist/css/message.css +6 -6
- package/dist/css/reset.css +3 -2
- package/dist/css/table.css +4 -4
- package/dist/css/tooltip.css +18 -1
- package/dist/js/attributable.full.js +29 -41
- package/dist/js/floatable.full.js +322 -337
- package/dist/js/focus-trap/embedded.full.js +252 -195
- package/dist/js/focus-trap/standalone.full.js +283 -238
- package/dist/js/index.js +3 -3
- package/dist/js/oui.full.js +1170 -1193
- package/dist/js/popover.full.js +568 -630
- package/dist/js/popover.js +1 -1
- package/dist/js/splitter.full.js +533 -369
- package/dist/js/splitter.js +2 -2
- package/dist/js/tooltip.full.js +488 -554
- package/dist/js/tooltip.js +1 -1
- package/package.json +19 -19
- package/src/css/a11y.scss +1 -1
- package/src/css/badge.scss +23 -19
- package/src/css/button.scss +9 -9
- package/src/css/color.scss +99 -99
- package/src/css/content.scss +6 -8
- package/src/css/flex.scss +21 -20
- package/src/css/form.scss +37 -60
- package/src/css/message.scss +8 -12
- package/src/css/mixins.scss +11 -12
- package/src/css/popover.scss +2 -2
- package/src/css/reset.scss +14 -14
- package/src/css/splitter.scss +15 -13
- package/src/css/table.scss +11 -11
- package/src/css/tooltip.scss +25 -4
- package/src/js/attributable.ts +3 -10
- package/src/js/floatable.ts +7 -25
- package/src/js/focus-trap/embedded.ts +6 -24
- package/src/js/popover.ts +3 -3
- package/src/js/splitter.ts +9 -39
- package/src/js/tooltip.ts +5 -17
- package/dist/css/value.css +0 -1
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
function isNumber(value) {
|
|
2
2
|
return typeof value === "number" && !Number.isNaN(value);
|
|
3
3
|
}
|
|
4
|
-
|
|
5
4
|
function clamp(value, minimum, maximum, loop) {
|
|
6
5
|
if (![
|
|
7
6
|
value,
|
|
8
7
|
minimum,
|
|
9
8
|
maximum
|
|
10
9
|
].every(isNumber)) return NaN;
|
|
11
|
-
if (value < minimum) return maximum ;
|
|
12
|
-
return value > maximum ? minimum
|
|
10
|
+
if (value < minimum) return loop === true ? maximum : minimum;
|
|
11
|
+
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
function isEventTarget(value) {
|
|
16
|
-
return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getBoolean(value, defaultValue) {
|
|
20
|
-
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
21
|
-
}
|
|
22
|
-
|
|
13
|
+
function noop() {}
|
|
23
14
|
function calculate() {
|
|
24
15
|
return new Promise((resolve) => {
|
|
25
16
|
const values = [];
|
|
@@ -27,37 +18,122 @@ function calculate() {
|
|
|
27
18
|
function step(now) {
|
|
28
19
|
if (last != null) values.push(now - last);
|
|
29
20
|
last = now;
|
|
30
|
-
if (values.length >=
|
|
31
|
-
|
|
32
|
-
resolve(median);
|
|
33
|
-
} else requestAnimationFrame(step);
|
|
21
|
+
if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
|
|
22
|
+
else requestAnimationFrame(step);
|
|
34
23
|
}
|
|
35
24
|
requestAnimationFrame(step);
|
|
36
25
|
});
|
|
37
26
|
}
|
|
38
|
-
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
calculate()
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
var TOTAL = 10;
|
|
28
|
+
var TRIM_PART = 2;
|
|
29
|
+
var TRIM_TOTAL = 4;
|
|
30
|
+
await calculate();
|
|
31
|
+
function getBoolean(value, defaultValue) {
|
|
32
|
+
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
33
|
+
}
|
|
34
|
+
function isEventTarget(value) {
|
|
35
|
+
return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
|
|
36
|
+
}
|
|
37
|
+
function addDelegatedHandler(doc, type, name, passive) {
|
|
38
|
+
if (DELEGATED.has(name)) return;
|
|
39
|
+
DELEGATED.add(name);
|
|
40
|
+
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
41
|
+
}
|
|
42
|
+
function addDelegatedListener(target, type, name, listener, passive) {
|
|
43
|
+
target[name] ??= /* @__PURE__ */ new Set();
|
|
44
|
+
target[name].add(listener);
|
|
45
|
+
addDelegatedHandler(document, type, name, passive);
|
|
46
|
+
return () => {
|
|
47
|
+
removeDelegatedListener(target, name, listener);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function delegatedEventHandler(event) {
|
|
51
|
+
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
52
|
+
const items = event.composedPath();
|
|
53
|
+
const { length } = items;
|
|
54
|
+
let target = items[0];
|
|
55
|
+
Object.defineProperties(event, {
|
|
56
|
+
currentTarget: {
|
|
57
|
+
configurable: true,
|
|
58
|
+
get() {
|
|
59
|
+
return target;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
target: {
|
|
63
|
+
configurable: true,
|
|
64
|
+
value: target
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
for (let index = 0; index < length; index += 1) {
|
|
68
|
+
const item = items[index];
|
|
69
|
+
const listeners = item[key];
|
|
70
|
+
if (item.disabled || listeners == null) continue;
|
|
71
|
+
target = item;
|
|
72
|
+
for (const listener of listeners) {
|
|
73
|
+
listener.call(item, event);
|
|
74
|
+
if (event.cancelBubble) return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function getDelegatedName(target, type, options) {
|
|
79
|
+
if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
80
|
+
}
|
|
81
|
+
function removeDelegatedListener(target, name, listener) {
|
|
82
|
+
const handlers = target[name];
|
|
83
|
+
if (handlers == null || !handlers.has(listener)) return false;
|
|
84
|
+
handlers.delete(listener);
|
|
85
|
+
if (handlers.size === 0) target[name] = void 0;
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
var DELEGATED = /* @__PURE__ */ new Set();
|
|
89
|
+
var EVENT_PREFIX = "@";
|
|
90
|
+
var EVENT_SUFFIX_ACTIVE = ":active";
|
|
91
|
+
var EVENT_SUFFIX_PASSIVE = ":passive";
|
|
92
|
+
var EVENT_TYPES = new Set([
|
|
93
|
+
"beforeinput",
|
|
94
|
+
"click",
|
|
95
|
+
"dblclick",
|
|
96
|
+
"contextmenu",
|
|
97
|
+
"focusin",
|
|
98
|
+
"focusout",
|
|
99
|
+
"input",
|
|
100
|
+
"keydown",
|
|
101
|
+
"keyup",
|
|
102
|
+
"mousedown",
|
|
103
|
+
"mousemove",
|
|
104
|
+
"mouseout",
|
|
105
|
+
"mouseover",
|
|
106
|
+
"mouseup",
|
|
107
|
+
"pointerdown",
|
|
108
|
+
"pointermove",
|
|
109
|
+
"pointerout",
|
|
110
|
+
"pointerover",
|
|
111
|
+
"pointerup",
|
|
112
|
+
"touchend",
|
|
113
|
+
"touchmove",
|
|
114
|
+
"touchstart"
|
|
115
|
+
]);
|
|
116
|
+
var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
117
|
+
var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
|
44
118
|
function createEventOptions(options) {
|
|
45
119
|
return {
|
|
46
120
|
capture: getBoolean(options?.capture),
|
|
47
121
|
once: getBoolean(options?.once),
|
|
48
122
|
passive: getBoolean(options?.passive, true),
|
|
49
|
-
signal: options?.signal
|
|
123
|
+
signal: options?.signal instanceof AbortSignal ? options.signal : void 0
|
|
50
124
|
};
|
|
51
125
|
}
|
|
52
126
|
function on(target, type, listener, options) {
|
|
53
127
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
54
128
|
const extended = createEventOptions(options);
|
|
129
|
+
const delegated = getDelegatedName(target, type, extended);
|
|
130
|
+
if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
|
|
55
131
|
target.addEventListener(type, listener, extended);
|
|
132
|
+
if (extended.once) return noop;
|
|
56
133
|
return () => {
|
|
57
134
|
target.removeEventListener(type, listener, extended);
|
|
58
135
|
};
|
|
59
136
|
}
|
|
60
|
-
|
|
61
137
|
function findAncestor(origin, selector) {
|
|
62
138
|
if (!(origin instanceof Element) || selector == null) return null;
|
|
63
139
|
if (typeof selector === "string") {
|
|
@@ -73,26 +149,42 @@ function findAncestor(origin, selector) {
|
|
|
73
149
|
}
|
|
74
150
|
return parent;
|
|
75
151
|
}
|
|
76
|
-
|
|
77
152
|
function getFocusable(parent) {
|
|
78
|
-
return getValidElements(parent, FILTERS_FOCUSABLE);
|
|
153
|
+
return getValidElements(parent, FILTERS_FOCUSABLE, false);
|
|
79
154
|
}
|
|
80
155
|
function getItem(element, tabbable) {
|
|
81
156
|
return {
|
|
82
157
|
element,
|
|
83
|
-
tabIndex: TABINDEX_DEFAULT
|
|
158
|
+
tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
|
|
84
159
|
};
|
|
85
160
|
}
|
|
161
|
+
function getTabIndex(element) {
|
|
162
|
+
const tabIndex = element?.tabIndex ?? TABINDEX_DEFAULT;
|
|
163
|
+
if (tabIndex < TABINDEX_BASE && (EXPRESSION_SPECIAL_TABINDEX.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) return TABINDEX_BASE;
|
|
164
|
+
return tabIndex;
|
|
165
|
+
}
|
|
86
166
|
function getValidElements(parent, filters, tabbable) {
|
|
87
167
|
if (!(parent instanceof Element)) return [];
|
|
88
168
|
const elements = [...parent.querySelectorAll(SELECTOR_FULL)];
|
|
89
169
|
const items = [];
|
|
90
170
|
let { length } = elements;
|
|
91
171
|
for (let index = 0; index < length; index += 1) {
|
|
92
|
-
const item = getItem(elements[index]);
|
|
172
|
+
const item = getItem(elements[index], tabbable);
|
|
93
173
|
if (!filters.some((filter) => filter(item))) items.push(item);
|
|
94
174
|
}
|
|
95
|
-
return items.map((item) => item.element);
|
|
175
|
+
if (!tabbable) return items.map((item) => item.element);
|
|
176
|
+
const indiced = [];
|
|
177
|
+
const zeroed = [];
|
|
178
|
+
length = items.length;
|
|
179
|
+
for (let index = 0; index < length; index += 1) {
|
|
180
|
+
const item = items[index];
|
|
181
|
+
if (item.tabIndex === TABINDEX_BASE) zeroed.push(item.element);
|
|
182
|
+
else indiced[item.tabIndex] = [...indiced[item.tabIndex] ?? [], item.element];
|
|
183
|
+
}
|
|
184
|
+
return [...indiced.flat(), ...zeroed];
|
|
185
|
+
}
|
|
186
|
+
function hasTabIndex(element) {
|
|
187
|
+
return !Number.isNaN(Number.parseInt(element.getAttribute(ATTRIBUTE_TABINDEX), 10));
|
|
96
188
|
}
|
|
97
189
|
function isDisabled(item) {
|
|
98
190
|
if (EXPRESSION_DISABLEABLE.test(item.element.tagName) && isDisabledFromFieldset(item.element)) return true;
|
|
@@ -114,6 +206,9 @@ function isDisabledFromFieldset(element) {
|
|
|
114
206
|
}
|
|
115
207
|
return false;
|
|
116
208
|
}
|
|
209
|
+
function isEditable(element) {
|
|
210
|
+
return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
|
|
211
|
+
}
|
|
117
212
|
function isHidden(item) {
|
|
118
213
|
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === STYLE_HIDDEN) return true;
|
|
119
214
|
if ((item.element.matches(SELECTOR_SUMMARY_FIRST) ? item.element.parentElement : item.element)?.matches(SELECTOR_DETAILS_CLOSED_CHILDREN) ?? false) return true;
|
|
@@ -124,13 +219,18 @@ function isHidden(item) {
|
|
|
124
219
|
}
|
|
125
220
|
function isInert(item) {
|
|
126
221
|
return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
|
|
127
|
-
element: item.element.parentElement
|
|
222
|
+
element: item.element.parentElement,
|
|
223
|
+
tabIndex: TABINDEX_DEFAULT
|
|
224
|
+
});
|
|
128
225
|
}
|
|
129
226
|
function isSummarised(item) {
|
|
130
227
|
return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
|
|
131
228
|
}
|
|
229
|
+
var ATTRIBUTE_CONTENTEDITABLE = "contenteditable";
|
|
132
230
|
var ATTRIBUTE_INERT = "inert";
|
|
231
|
+
var ATTRIBUTE_TABINDEX = "tabindex";
|
|
133
232
|
var EXPRESSION_DISABLEABLE = /^(button|input|select|textarea)$/i;
|
|
233
|
+
var EXPRESSION_SPECIAL_TABINDEX = /^(audio|details|video)$/i;
|
|
134
234
|
var EXPRESSION_SUMMARY = /^summary$/i;
|
|
135
235
|
var EXPRESSION_TRUEISH = /^(|true)$/i;
|
|
136
236
|
var FILTERS_FOCUSABLE = [
|
|
@@ -139,6 +239,7 @@ var FILTERS_FOCUSABLE = [
|
|
|
139
239
|
isHidden,
|
|
140
240
|
isSummarised
|
|
141
241
|
];
|
|
242
|
+
[...FILTERS_FOCUSABLE];
|
|
142
243
|
var SELECTOR_DETAILS_CLOSED_CHILDREN = "details:not([open]) *";
|
|
143
244
|
var SELECTOR_FIELDSET_DISABLED = "fieldset[disabled] *";
|
|
144
245
|
var SELECTOR_SUMMARY_FIRST = "details > summary:first-of-type";
|
|
@@ -157,195 +258,151 @@ var SELECTOR_FULL = [
|
|
|
157
258
|
].map((selector) => `${selector}:not([inert])`).join(",");
|
|
158
259
|
var STYLE_HIDDEN = "hidden";
|
|
159
260
|
var STYLE_NONE = "none";
|
|
261
|
+
var TABINDEX_BASE = 0;
|
|
160
262
|
var TABINDEX_DEFAULT = -1;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
enable() {
|
|
199
|
-
if (this.disabled) {
|
|
200
|
-
setDisabled(this, false);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
focus(last) {
|
|
204
|
-
tabToTrap(this, getFocusable(this.element), this.element, last ? -1 : 0);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
//
|
|
263
|
+
var FocusTrap = class {
|
|
264
|
+
disabled = false;
|
|
265
|
+
connected = true;
|
|
266
|
+
element;
|
|
267
|
+
embedded;
|
|
268
|
+
get contain() {
|
|
269
|
+
return this.element.hasAttribute(FOCUS_TRAP_CONTAIN);
|
|
270
|
+
}
|
|
271
|
+
get noescape() {
|
|
272
|
+
return this.element.hasAttribute(FOCUS_TRAP_NOESCAPE);
|
|
273
|
+
}
|
|
274
|
+
constructor(element, options) {
|
|
275
|
+
this.element = element;
|
|
276
|
+
this.embedded = options != null;
|
|
277
|
+
element.setAttribute("tabindex", "-1");
|
|
278
|
+
if (options != null) element.setAttribute(FOCUS_TRAP_SELECTOR, "");
|
|
279
|
+
if (options?.noescape) element.setAttribute(FOCUS_TRAP_NOESCAPE, "");
|
|
280
|
+
}
|
|
281
|
+
connect() {
|
|
282
|
+
setConnected(this, true);
|
|
283
|
+
}
|
|
284
|
+
destroy() {
|
|
285
|
+
this.element = void 0;
|
|
286
|
+
}
|
|
287
|
+
disable() {
|
|
288
|
+
if (!(this.disabled || this.noescape)) setDisabled(this, true);
|
|
289
|
+
}
|
|
290
|
+
disconnect() {
|
|
291
|
+
setConnected(this, false);
|
|
292
|
+
}
|
|
293
|
+
enable() {
|
|
294
|
+
if (this.disabled) setDisabled(this, false);
|
|
295
|
+
}
|
|
296
|
+
focus(last) {
|
|
297
|
+
tabToTrap(this, getFocusable(this.element), this.element, last ? -1 : 0);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
208
300
|
function createFocusTrap(element, options) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
301
|
+
let focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
302
|
+
if (focusTrap == null) {
|
|
303
|
+
focusTrap = new FocusTrap(element, options);
|
|
304
|
+
FOCUSTRAPS_ALL.set(element, focusTrap);
|
|
305
|
+
}
|
|
306
|
+
return focusTrap;
|
|
215
307
|
}
|
|
216
308
|
function onEscape(event) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
if (!focusTrap.disabled) {
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
focusTrap?.disable();
|
|
309
|
+
let element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
|
|
310
|
+
let focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
311
|
+
if (element == null || focusTrap == null) return;
|
|
312
|
+
while (focusTrap.disabled) {
|
|
313
|
+
element = findAncestor(focusTrap.element.parentElement, ATTRIBUTE_SELECTOR);
|
|
314
|
+
focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
315
|
+
if (element == null || focusTrap == null) return;
|
|
316
|
+
if (!focusTrap.disabled) break;
|
|
317
|
+
}
|
|
318
|
+
focusTrap?.disable();
|
|
233
319
|
}
|
|
234
320
|
function onFocusIn(event) {
|
|
235
|
-
|
|
236
|
-
lastTarget = focusTrap == null ? undefined : event.target;
|
|
321
|
+
lastTarget = FOCUSTRAPS_ALL.get(findAncestor(event.target, ATTRIBUTE_SELECTOR)) == null ? void 0 : event.target;
|
|
237
322
|
}
|
|
238
323
|
function onKeydown(event) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
324
|
+
switch (event.key) {
|
|
325
|
+
case "Escape":
|
|
326
|
+
onEscape(event);
|
|
327
|
+
break;
|
|
328
|
+
case "Tab":
|
|
329
|
+
onTab(event);
|
|
330
|
+
break;
|
|
331
|
+
default: return;
|
|
332
|
+
}
|
|
249
333
|
}
|
|
250
334
|
function onPointerdown(event) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
for (const focusTrap of FOCUSTRAPS_DISABLED) {
|
|
263
|
-
if (focusTrap.element !== nextFocusTrap) {
|
|
264
|
-
focusTrap.enable();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
335
|
+
const lastFocusTrap = findAncestor(lastTarget, ATTRIBUTE_SELECTOR);
|
|
336
|
+
const nextFocusTrap = findAncestor(event.target, ATTRIBUTE_SELECTOR);
|
|
337
|
+
if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
|
|
338
|
+
if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
|
|
339
|
+
event.preventDefault();
|
|
340
|
+
lastTarget?.focus();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (FOCUSTRAPS_DISABLED.size === 0) return;
|
|
344
|
+
for (const focusTrap of FOCUSTRAPS_DISABLED) if (focusTrap.element !== nextFocusTrap) focusTrap.enable();
|
|
267
345
|
}
|
|
268
346
|
function onTab(event) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const elements = getFocusable(element);
|
|
278
|
-
const index = elements.indexOf(event.target);
|
|
279
|
-
if (index === -1 || elements.length === 0) {
|
|
280
|
-
tabToTrap(focusTrap, elements, element);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
tabToElement(focusTrap, elements, index, event.shiftKey ? -1 : 1);
|
|
284
|
-
}
|
|
347
|
+
const element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
|
|
348
|
+
const focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
349
|
+
if (focusTrap == null) return;
|
|
350
|
+
if (!focusTrap.disabled) event.preventDefault();
|
|
351
|
+
const elements = getFocusable(element);
|
|
352
|
+
const index = elements.indexOf(event.target);
|
|
353
|
+
if (index === -1 || elements.length === 0) tabToTrap(focusTrap, elements, element);
|
|
354
|
+
else tabToElement(focusTrap, elements, index, event.shiftKey ? -1 : 1);
|
|
285
355
|
}
|
|
286
356
|
function setConnected(focusTrap, value) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
focusTrap.connected = value;
|
|
357
|
+
if (!focusTrap.embedded || focusTrap.connected === value) return;
|
|
358
|
+
focusTrap.connected = value;
|
|
291
359
|
}
|
|
292
360
|
function setDisabled(focusTrap, value) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
FOCUSTRAPS_DISABLED.delete(focusTrap);
|
|
299
|
-
}
|
|
361
|
+
focusTrap.disabled = value;
|
|
362
|
+
if (value) FOCUSTRAPS_DISABLED.add(focusTrap);
|
|
363
|
+
else FOCUSTRAPS_DISABLED.delete(focusTrap);
|
|
300
364
|
}
|
|
301
365
|
function tabToElement(focusTrap, elements, index, modifier) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
elements[next].focus();
|
|
319
|
-
lastTarget = elements[next];
|
|
320
|
-
}
|
|
366
|
+
const { length } = elements;
|
|
367
|
+
const next = clamp(index + modifier, 0, length - 1, true);
|
|
368
|
+
if (focusTrap.disabled) {
|
|
369
|
+
if (index === length - 1 && next === 0 || index === 0 && next === length - 1) {
|
|
370
|
+
lastTarget = void 0;
|
|
371
|
+
focusTrap.enable();
|
|
372
|
+
}
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const element = elements[next];
|
|
376
|
+
const elementFocusTrap = FOCUSTRAPS_ALL.get(element);
|
|
377
|
+
if (elementFocusTrap != null) elementFocusTrap.focus(modifier === -1);
|
|
378
|
+
else {
|
|
379
|
+
elements[next].focus();
|
|
380
|
+
lastTarget = elements[next];
|
|
381
|
+
}
|
|
321
382
|
}
|
|
322
383
|
function tabToTrap(focusTrap, elements, element, index) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
//
|
|
334
|
-
const FOCUS_TRAP_SELECTOR = 'oui-focus-trap';
|
|
384
|
+
if (focusTrap.disabled) {
|
|
385
|
+
lastTarget = void 0;
|
|
386
|
+
focusTrap.enable();
|
|
387
|
+
} else {
|
|
388
|
+
const next = elements.length === 0 ? element : elements.at(index ?? 0);
|
|
389
|
+
next.focus();
|
|
390
|
+
lastTarget = next;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const FOCUS_TRAP_SELECTOR = "oui-focus-trap";
|
|
335
394
|
const ATTRIBUTE_SELECTOR = `[${FOCUS_TRAP_SELECTOR}]`;
|
|
336
395
|
const EVENT_OPTIONS = {
|
|
337
|
-
|
|
338
|
-
|
|
396
|
+
capture: true,
|
|
397
|
+
passive: false
|
|
339
398
|
};
|
|
340
399
|
const FOCUS_TRAP_CONTAIN = `${FOCUS_TRAP_SELECTOR}-contain`;
|
|
341
400
|
const FOCUS_TRAP_NOESCAPE = `${FOCUS_TRAP_SELECTOR}-noescape`;
|
|
342
|
-
const FOCUSTRAPS_ALL = new WeakMap();
|
|
343
|
-
const FOCUSTRAPS_DISABLED = new Set();
|
|
401
|
+
const FOCUSTRAPS_ALL = /* @__PURE__ */ new WeakMap();
|
|
402
|
+
const FOCUSTRAPS_DISABLED = /* @__PURE__ */ new Set();
|
|
344
403
|
let lastTarget;
|
|
345
|
-
|
|
346
|
-
on(document,
|
|
347
|
-
on(document,
|
|
348
|
-
on(document,
|
|
349
|
-
on(document, 'touchstart', onPointerdown, EVENT_OPTIONS);
|
|
350
|
-
|
|
404
|
+
on(document, "focusin", onFocusIn, EVENT_OPTIONS);
|
|
405
|
+
on(document, "keydown", onKeydown, EVENT_OPTIONS);
|
|
406
|
+
on(document, "mousedown", onPointerdown, EVENT_OPTIONS);
|
|
407
|
+
on(document, "touchstart", onPointerdown, EVENT_OPTIONS);
|
|
351
408
|
export { FOCUSTRAPS_ALL, FOCUS_TRAP_CONTAIN, FOCUS_TRAP_NOESCAPE, FOCUS_TRAP_SELECTOR, FocusTrap, createFocusTrap };
|