@oscarpalmer/oui 0.33.0 → 0.35.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/js/combobox/constants.combobox.d.mts +2 -0
- package/dist/js/combobox/constants.combobox.mjs +46 -0
- package/dist/js/combobox/data.combobox.d.mts +18 -0
- package/dist/js/combobox/data.combobox.mjs +2 -0
- package/dist/js/combobox/dom.combobox.d.mts +110 -0
- package/dist/js/combobox/dom.combobox.mjs +2 -0
- package/dist/js/combobox/event.combobox.d.mts +17 -0
- package/dist/js/combobox/event.combobox.mjs +2 -0
- package/dist/js/combobox/form.combobox.d.mts +6 -0
- package/dist/js/combobox/form.combobox.mjs +2 -0
- package/dist/js/combobox/index.d.mts +2 -0
- package/dist/js/combobox/index.mjs +195 -0
- package/dist/js/combobox/misc.combobox.d.mts +2 -0
- package/dist/js/combobox/misc.combobox.mjs +2 -0
- package/dist/js/combobox/models.combobox.d.mts +2 -0
- package/dist/js/combobox/models.combobox.mjs +1 -0
- package/dist/js/combobox/state.combobox.d.mts +13 -0
- package/dist/js/combobox/state.combobox.mjs +2 -0
- package/dist/js/constants.combobox-h_kyDegw.d.mts +248 -0
- package/dist/js/data.combobox-B8HMkDOh.mjs +1030 -0
- package/dist/js/dialog.mjs +3 -2
- package/dist/js/floatable/floatable.embedded.mjs +4 -4
- package/dist/js/focus-trap/focus-trap.embedded.mjs +3 -3
- package/dist/js/index.d.mts +14 -643
- package/dist/js/index.mjs +19 -4875
- package/dist/js/internal/draggable.mjs +6 -6
- package/dist/js/internal/navigable.mjs +3 -3
- package/dist/js/l10n.d.mts +20 -0
- package/dist/js/l10n.mjs +80 -0
- package/dist/js/menu.d.mts +1 -1
- package/dist/js/menu.mjs +3 -2
- package/dist/js/movable/movable.embedded.mjs +3 -3
- package/dist/js/popover.mjs +1 -1
- package/dist/js/resizable/resizable.embedded.mjs +7 -7
- package/dist/js/sortable/sortable.embedded.mjs +7 -6
- package/dist/js/splitter.mjs +7 -13
- package/dist/js/toolbar.d.mts +1 -1
- package/dist/js/tooltip.mjs +3 -3
- package/package.json +4 -4
- package/src/js/combobox/constants.combobox.ts +62 -0
- package/src/js/combobox/data.combobox.ts +236 -0
- package/src/js/combobox/dom.combobox.ts +825 -0
- package/src/js/combobox/event.combobox.ts +454 -0
- package/src/js/combobox/form.combobox.ts +116 -0
- package/src/js/combobox/index.ts +313 -0
- package/src/js/combobox/misc.combobox.ts +188 -0
- package/src/js/combobox/models.combobox.ts +94 -0
- package/src/js/combobox/state.combobox.ts +247 -0
- package/src/js/index.ts +1 -1
- package/src/js/internal/draggable.ts +3 -3
- package/src/js/l10n.ts +192 -0
- package/src/js/movable/movable.embedded.ts +2 -2
- package/src/js/resizable/resizable.embedded.ts +3 -3
- package/src/js/sortable/sortable.embedded.ts +2 -2
- package/src/js/splitter.ts +2 -2
- package/dist/js/combobox.d.mts +0 -91
- package/dist/js/combobox.mjs +0 -797
- package/src/js/combobox.ts +0 -2410
package/dist/js/index.mjs
CHANGED
|
@@ -1,4875 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Is the value an _HTML_ or _SVG_ element?
|
|
22
|
-
*
|
|
23
|
-
* @param value Value to check
|
|
24
|
-
* @returns `true` if it's an _HTML_ or _SVG_ element, otherwise `false`
|
|
25
|
-
*/
|
|
26
|
-
function isHTMLOrSVGElement(value) {
|
|
27
|
-
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Is the value an input element? _(`<input>`, `<select>`, or `<textarea>`)_
|
|
31
|
-
*
|
|
32
|
-
* @param value Value to check
|
|
33
|
-
* @returns `true` if it's an input element, otherwise `false`
|
|
34
|
-
*/
|
|
35
|
-
function isInputElement(value) {
|
|
36
|
-
return value instanceof HTMLInputElement || value instanceof HTMLSelectElement || value instanceof HTMLTextAreaElement;
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
40
|
-
/**
|
|
41
|
-
* Is the value a number?
|
|
42
|
-
*
|
|
43
|
-
* @param value Value to check
|
|
44
|
-
* @returns `true` if the value is a `number`, otherwise `false`
|
|
45
|
-
*/
|
|
46
|
-
function isNumber(value) {
|
|
47
|
-
return typeof value === "number" && !Number.isNaN(value);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Is the value a plain object?
|
|
51
|
-
*
|
|
52
|
-
* @param value Value to check
|
|
53
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
54
|
-
*/
|
|
55
|
-
function isPlainObject(value) {
|
|
56
|
-
if (value === null || typeof value !== "object") return false;
|
|
57
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
58
|
-
const prototype = Object.getPrototypeOf(value);
|
|
59
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
60
|
-
}
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
|
|
63
|
-
/**
|
|
64
|
-
* Get the string value from any value
|
|
65
|
-
*
|
|
66
|
-
* @param value Original value
|
|
67
|
-
* @returns String representation of the value
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```typescript
|
|
71
|
-
* getString(null) // => ''
|
|
72
|
-
* getString('foo') // => 'foo'
|
|
73
|
-
* getString(123) // => '123'
|
|
74
|
-
* getString(true) // => 'true'
|
|
75
|
-
* getString([1, 2, 3]) // => '1,2,3'
|
|
76
|
-
* getString({a: 1}) // => '{"a":1}'
|
|
77
|
-
* getString(() => 123) // => '123'
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
function getString(value) {
|
|
81
|
-
if (typeof value === "string") return value;
|
|
82
|
-
if (value == null) return "";
|
|
83
|
-
if (typeof value === "function") return getString(value());
|
|
84
|
-
if (typeof value !== "object") return String(value);
|
|
85
|
-
const asString = String(value.valueOf?.() ?? value);
|
|
86
|
-
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Join an array of values into a string _(while ignoring empty values)_
|
|
90
|
-
*
|
|
91
|
-
* _(`null`, `undefined`, and any values that become whitespace-only strings are considered empty)_
|
|
92
|
-
*
|
|
93
|
-
* @param array Array of values
|
|
94
|
-
* @param delimiter Delimiter to use between values
|
|
95
|
-
* @returns Joined string
|
|
96
|
-
*/
|
|
97
|
-
function join(array, delimiter) {
|
|
98
|
-
if (!Array.isArray(array)) return "";
|
|
99
|
-
const { length } = array;
|
|
100
|
-
if (length === 0) return "";
|
|
101
|
-
const values = [];
|
|
102
|
-
for (let index = 0; index < length; index += 1) {
|
|
103
|
-
const item = getString(array[index]);
|
|
104
|
-
if (item.length > 0) values.push(item);
|
|
105
|
-
}
|
|
106
|
-
return values.join(typeof delimiter === "string" ? delimiter : "");
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Split a string into words _(and other readable parts)_
|
|
110
|
-
*
|
|
111
|
-
* @param value Original string
|
|
112
|
-
* @returns Array of words found in the string
|
|
113
|
-
*/
|
|
114
|
-
function words(value) {
|
|
115
|
-
return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
|
|
116
|
-
}
|
|
117
|
-
const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
118
|
-
//#endregion
|
|
119
|
-
//#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
|
|
120
|
-
/**
|
|
121
|
-
* Parse a JSON string into its proper value _(or `undefined` if it fails)_
|
|
122
|
-
*
|
|
123
|
-
* @param value JSON string to parse
|
|
124
|
-
* @param reviver Reviver function to transform the parsed values
|
|
125
|
-
* @returns Parsed value or `undefined` if parsing fails
|
|
126
|
-
*/
|
|
127
|
-
function parse(value, reviver) {
|
|
128
|
-
try {
|
|
129
|
-
return JSON.parse(value, reviver);
|
|
130
|
-
} catch {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
136
|
-
/**
|
|
137
|
-
* Clamp a number between a minimum and maximum value
|
|
138
|
-
*
|
|
139
|
-
* @param value Value to clamp
|
|
140
|
-
* @param minimum Minimum value
|
|
141
|
-
* @param maximum Maximum value
|
|
142
|
-
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
143
|
-
* @returns Clamped value
|
|
144
|
-
*
|
|
145
|
-
* @example
|
|
146
|
-
* ```typescript
|
|
147
|
-
* clamp(10, 0, 5); // => 5
|
|
148
|
-
* clamp(10, 0, 5, true); // => 0
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
function clamp(value, minimum, maximum, loop) {
|
|
152
|
-
if (![
|
|
153
|
-
value,
|
|
154
|
-
minimum,
|
|
155
|
-
maximum
|
|
156
|
-
].every(isNumber)) return NaN;
|
|
157
|
-
if (value < minimum) return loop === true ? maximum : minimum;
|
|
158
|
-
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Get the number value from an unknown value
|
|
162
|
-
*
|
|
163
|
-
* _(Based on Lodash)_
|
|
164
|
-
*
|
|
165
|
-
* @param value Original value
|
|
166
|
-
* @returns Original value as a number, or `Number.NaN` if the value is unable to be parsed
|
|
167
|
-
*/
|
|
168
|
-
function getNumber(value) {
|
|
169
|
-
if (typeof value === "number") return value;
|
|
170
|
-
if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
|
|
171
|
-
if (value == null || typeof value === "symbol") return NaN;
|
|
172
|
-
if (typeof value === "function") return getNumber(value());
|
|
173
|
-
let parsed = value.valueOf();
|
|
174
|
-
if (typeof parsed === "object") parsed = parsed.toString();
|
|
175
|
-
if (typeof parsed !== "string") return getNumber(parsed);
|
|
176
|
-
const trimmed = parsed.trim();
|
|
177
|
-
if (trimmed.length === 0) return NaN;
|
|
178
|
-
if (EXPRESSION_ZEROISH.test(parsed)) return 0;
|
|
179
|
-
const isBinary = EXPRESSION_BINARY.test(trimmed);
|
|
180
|
-
if (isBinary || EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
|
|
181
|
-
return Number(trimmed);
|
|
182
|
-
}
|
|
183
|
-
const EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
184
|
-
const EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
185
|
-
const EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
186
|
-
const OCTAL_VALUE = 8;
|
|
187
|
-
//#endregion
|
|
188
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/sized.mjs
|
|
189
|
-
function getSizedMaximum(first, second) {
|
|
190
|
-
let actual;
|
|
191
|
-
if (typeof first === "number") actual = first;
|
|
192
|
-
else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
|
|
193
|
-
return clamp(actual, 1, MAXIMUM_ABSOLUTE);
|
|
194
|
-
}
|
|
195
|
-
const MAXIMUM_ABSOLUTE = 16777216;
|
|
196
|
-
const MAXIMUM_DEFAULT = 1048576;
|
|
197
|
-
//#endregion
|
|
198
|
-
//#region node_modules/@oscarpalmer/atoms/dist/sized/map.mjs
|
|
199
|
-
/**
|
|
200
|
-
* A _Map_ with a maximum size
|
|
201
|
-
*
|
|
202
|
-
* Behavior is similar to a _LRU_ cache, where the least recently used entries are removed
|
|
203
|
-
*/
|
|
204
|
-
var SizedMap = class extends Map {
|
|
205
|
-
/**
|
|
206
|
-
* The maximum size of the _Map_
|
|
207
|
-
*/
|
|
208
|
-
#maximumSize;
|
|
209
|
-
/**
|
|
210
|
-
* Is the _Map_ full?
|
|
211
|
-
*/
|
|
212
|
-
get full() {
|
|
213
|
-
return super.size >= this.#maximumSize;
|
|
214
|
-
}
|
|
215
|
-
get maximum() {
|
|
216
|
-
return this.#maximumSize;
|
|
217
|
-
}
|
|
218
|
-
constructor(first, second) {
|
|
219
|
-
const maximum = getSizedMaximum(first, second);
|
|
220
|
-
super();
|
|
221
|
-
this.#maximumSize = maximum;
|
|
222
|
-
if (Array.isArray(first)) {
|
|
223
|
-
const { length } = first;
|
|
224
|
-
if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
|
|
225
|
-
else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* @inheritdoc
|
|
230
|
-
*/
|
|
231
|
-
get(key) {
|
|
232
|
-
if (super.has(key)) {
|
|
233
|
-
const value = super.get(key);
|
|
234
|
-
this.#setValue(key, value, true);
|
|
235
|
-
return value;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* @inheritdoc
|
|
240
|
-
*/
|
|
241
|
-
set(key, value) {
|
|
242
|
-
return this.#setValue(key, value, super.has(key));
|
|
243
|
-
}
|
|
244
|
-
#setValue(key, value, has) {
|
|
245
|
-
if (has) super.delete(key);
|
|
246
|
-
else if (super.size >= this.#maximumSize) super.delete(super.keys().next().value);
|
|
247
|
-
super.set(key, value);
|
|
248
|
-
return this;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
//#endregion
|
|
252
|
-
//#region node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
|
|
253
|
-
/**
|
|
254
|
-
* A _Memoized_ function instance, caching and retrieving results based on the its parameters _(or a custom cache key)_
|
|
255
|
-
*/
|
|
256
|
-
var Memoized = class {
|
|
257
|
-
#state;
|
|
258
|
-
/**
|
|
259
|
-
* Maximum cache size
|
|
260
|
-
*
|
|
261
|
-
* @returns Maximum cache size _(or `Number.NaN` if the instance has been destroyed)_
|
|
262
|
-
*/
|
|
263
|
-
get maximum() {
|
|
264
|
-
return this.#state.cache?.maximum ?? NaN;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Current cache size
|
|
268
|
-
*
|
|
269
|
-
* @returns Current cache size _(or `Number.NaN` if the instance has been destroyed)_
|
|
270
|
-
*/
|
|
271
|
-
get size() {
|
|
272
|
-
return this.#state.cache?.size ?? NaN;
|
|
273
|
-
}
|
|
274
|
-
constructor(callback, options) {
|
|
275
|
-
const cache = new SizedMap(options.cacheSize);
|
|
276
|
-
const getter = (...parameters) => {
|
|
277
|
-
const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), SEPARATOR));
|
|
278
|
-
if (cache.has(key)) return cache.get(key);
|
|
279
|
-
const value = callback(...parameters);
|
|
280
|
-
cache.set(key, value);
|
|
281
|
-
return value;
|
|
282
|
-
};
|
|
283
|
-
this.#state = {
|
|
284
|
-
cache,
|
|
285
|
-
getter
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Clear the cache
|
|
290
|
-
*/
|
|
291
|
-
clear() {
|
|
292
|
-
this.#state.cache?.clear();
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Delete a result from the cache
|
|
296
|
-
*
|
|
297
|
-
* @param key Key to delete
|
|
298
|
-
* @returns `true` if the key existed and was removed, otherwise `false`
|
|
299
|
-
*/
|
|
300
|
-
delete(key) {
|
|
301
|
-
return this.#state.cache?.delete(key) ?? false;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Destroy the instance
|
|
305
|
-
*
|
|
306
|
-
* _(When a Memoized instance is destroyed, its cache and callback are removed, and calls to `run` will throw an error)_
|
|
307
|
-
*/
|
|
308
|
-
destroy() {
|
|
309
|
-
this.#state.cache?.clear();
|
|
310
|
-
this.#state.cache = void 0;
|
|
311
|
-
this.#state.getter = void 0;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Get a result from the cache
|
|
315
|
-
*
|
|
316
|
-
* @param key Key to get
|
|
317
|
-
* @returns Cached result or `undefined` if it does not exist
|
|
318
|
-
*/
|
|
319
|
-
get(key) {
|
|
320
|
-
return this.#state.cache?.get(key);
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Does the result exist?
|
|
324
|
-
*
|
|
325
|
-
* @param key Key to check
|
|
326
|
-
* @returns `true` if the result exists, otherwise `false`
|
|
327
|
-
*/
|
|
328
|
-
has(key) {
|
|
329
|
-
return this.#state.cache?.has(key) ?? false;
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Run the callback with the provided parameters
|
|
333
|
-
*
|
|
334
|
-
* @param parameters Parameters to pass to the callback
|
|
335
|
-
* @returns Cached or computed _(then cached)_ result
|
|
336
|
-
*/
|
|
337
|
-
run(...parameters) {
|
|
338
|
-
if (this.#state.cache == null || this.#state.getter == null) throw new Error(MEMOIZED_ERROR_DESTROYED);
|
|
339
|
-
return this.#state.getter(...parameters);
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
function getMemoizationOptions(input) {
|
|
343
|
-
const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
|
|
344
|
-
return {
|
|
345
|
-
cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
|
|
346
|
-
cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Memoize a function, caching and retrieving results based on the first parameter
|
|
351
|
-
*
|
|
352
|
-
* @param callback Callback to memoize
|
|
353
|
-
* @param options Memoization options
|
|
354
|
-
* @returns _Memoized_ instance
|
|
355
|
-
*/
|
|
356
|
-
function memoize(callback, options) {
|
|
357
|
-
if (typeof callback !== "function") throw new TypeError(MEMOIZED_ERROR_CALLBACK);
|
|
358
|
-
return new Memoized(callback, getMemoizationOptions(options));
|
|
359
|
-
}
|
|
360
|
-
const DEFAULT_CACHE_SIZE = 1024;
|
|
361
|
-
const MEMOIZED_ERROR_CALLBACK = "Memoized requires a callback function";
|
|
362
|
-
const MEMOIZED_ERROR_DESTROYED = "The Memoized instance has been destroyed";
|
|
363
|
-
const SEPARATOR = "_";
|
|
364
|
-
//#endregion
|
|
365
|
-
//#region node_modules/@oscarpalmer/atoms/dist/string/case.mjs
|
|
366
|
-
/**
|
|
367
|
-
* Convert a string to camel case _(thisIsCamelCase)_
|
|
368
|
-
*
|
|
369
|
-
* @param value String to convert
|
|
370
|
-
* @returns Camel-cased string
|
|
371
|
-
*/
|
|
372
|
-
function camelCase(value) {
|
|
373
|
-
return toCase(CASE_CAMEL, value, true, false);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
377
|
-
*
|
|
378
|
-
* @param value String to capitalize
|
|
379
|
-
* @returns Capitalized string
|
|
380
|
-
*/
|
|
381
|
-
function capitalize(value) {
|
|
382
|
-
if (typeof value !== "string" || value.length === 0) return "";
|
|
383
|
-
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
384
|
-
return memoizedCapitalize.run(value);
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
388
|
-
*
|
|
389
|
-
* @param value String to convert
|
|
390
|
-
* @returns Kebab-cased string
|
|
391
|
-
*/
|
|
392
|
-
function kebabCase(value) {
|
|
393
|
-
return toCase(CASE_KEBAB, value, false, false);
|
|
394
|
-
}
|
|
395
|
-
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
396
|
-
caseMemoizers[type] ??= memoize(toCaseCallback.bind({
|
|
397
|
-
type,
|
|
398
|
-
capitalizeAny,
|
|
399
|
-
capitalizeFirst
|
|
400
|
-
}));
|
|
401
|
-
return caseMemoizers[type].run(value);
|
|
402
|
-
}
|
|
403
|
-
function toCaseCallback(value) {
|
|
404
|
-
if (typeof value !== "string") return "";
|
|
405
|
-
if (value.length < 1) return value;
|
|
406
|
-
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
407
|
-
const parts = words(value);
|
|
408
|
-
const partsLength = parts.length;
|
|
409
|
-
const cased = [];
|
|
410
|
-
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
411
|
-
const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === S ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
|
|
412
|
-
const itemsLength = items.length;
|
|
413
|
-
const partResult = [];
|
|
414
|
-
let itemCount = 0;
|
|
415
|
-
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
416
|
-
const item = items[itemIndex];
|
|
417
|
-
if (item.length === 0) continue;
|
|
418
|
-
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
419
|
-
else partResult.push(capitalize(item));
|
|
420
|
-
itemCount += 1;
|
|
421
|
-
}
|
|
422
|
-
cased.push(join(partResult, delimiters[type]));
|
|
423
|
-
}
|
|
424
|
-
return join(cased, delimiters[type]);
|
|
425
|
-
}
|
|
426
|
-
const CASE_CAMEL = "camel";
|
|
427
|
-
const CASE_KEBAB = "kebab";
|
|
428
|
-
const CASE_PASCAL = "pascal";
|
|
429
|
-
const CASE_SNAKE = "snake";
|
|
430
|
-
const DELIMTER_EMPTY = "";
|
|
431
|
-
const DELIMITER_HYPHEN = "-";
|
|
432
|
-
const DELIMITER_UNDERSCORE = "_";
|
|
433
|
-
const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
434
|
-
const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
435
|
-
const REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
436
|
-
const S = "s";
|
|
437
|
-
const caseMemoizers = {};
|
|
438
|
-
const delimiters = {
|
|
439
|
-
[CASE_CAMEL]: DELIMTER_EMPTY,
|
|
440
|
-
[CASE_KEBAB]: DELIMITER_HYPHEN,
|
|
441
|
-
[CASE_PASCAL]: DELIMTER_EMPTY,
|
|
442
|
-
[CASE_SNAKE]: DELIMITER_UNDERSCORE
|
|
443
|
-
};
|
|
444
|
-
let memoizedCapitalize;
|
|
445
|
-
//#endregion
|
|
446
|
-
//#region node_modules/@oscarpalmer/toretto/dist/internal/property.mjs
|
|
447
|
-
function getPropertyValue(element, name, value) {
|
|
448
|
-
if (isInputElement(element) && name === "value") return getString(value);
|
|
449
|
-
return value;
|
|
450
|
-
}
|
|
451
|
-
function updateProperty(element, name, value, dispatch) {
|
|
452
|
-
let property = name;
|
|
453
|
-
if (!(property in element)) property = camelCase(name);
|
|
454
|
-
const next = getPropertyValue(element, name, value);
|
|
455
|
-
if (!(property in element) || Object.is(element[property], next)) return;
|
|
456
|
-
element[property] = next;
|
|
457
|
-
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
458
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
459
|
-
bubbles: true,
|
|
460
|
-
cancelable: true
|
|
461
|
-
}));
|
|
462
|
-
}
|
|
463
|
-
const elementEvents = {
|
|
464
|
-
DETAILS: { open: "toggle" },
|
|
465
|
-
INPUT: {
|
|
466
|
-
checked: "change",
|
|
467
|
-
value: "input"
|
|
468
|
-
},
|
|
469
|
-
SELECT: { value: "change" },
|
|
470
|
-
TEXTAREA: { value: "input" }
|
|
471
|
-
};
|
|
472
|
-
//#endregion
|
|
473
|
-
//#region node_modules/@oscarpalmer/atoms/dist/is.mjs
|
|
474
|
-
/**
|
|
475
|
-
* Is the value `undefined`, `null`, or stringified as a whitespace-only string?
|
|
476
|
-
*
|
|
477
|
-
* @param value Value to check
|
|
478
|
-
* @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
|
|
479
|
-
*/
|
|
480
|
-
function isNullableOrWhitespace(value) {
|
|
481
|
-
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
482
|
-
}
|
|
483
|
-
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
484
|
-
//#endregion
|
|
485
|
-
//#region node_modules/@oscarpalmer/toretto/dist/internal/attribute.mjs
|
|
486
|
-
function isAttribute(value) {
|
|
487
|
-
return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
|
|
488
|
-
}
|
|
489
|
-
function updateAttribute(element, name, value, dispatch) {
|
|
490
|
-
const lowerCaseName = name.toLowerCase();
|
|
491
|
-
const isBoolean = booleanAttributesSet.has(lowerCaseName);
|
|
492
|
-
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
|
|
493
|
-
if (isBoolean || dispatchedAttributes.has(name)) updateProperty(element, name, next, dispatch);
|
|
494
|
-
updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, false);
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* List of boolean attributes
|
|
498
|
-
*/
|
|
499
|
-
const booleanAttributes = Object.freeze([
|
|
500
|
-
"async",
|
|
501
|
-
"autofocus",
|
|
502
|
-
"autoplay",
|
|
503
|
-
"checked",
|
|
504
|
-
"controls",
|
|
505
|
-
"default",
|
|
506
|
-
"defer",
|
|
507
|
-
"disabled",
|
|
508
|
-
"formnovalidate",
|
|
509
|
-
"hidden",
|
|
510
|
-
"inert",
|
|
511
|
-
"ismap",
|
|
512
|
-
"itemscope",
|
|
513
|
-
"loop",
|
|
514
|
-
"multiple",
|
|
515
|
-
"muted",
|
|
516
|
-
"nomodule",
|
|
517
|
-
"novalidate",
|
|
518
|
-
"open",
|
|
519
|
-
"playsinline",
|
|
520
|
-
"readonly",
|
|
521
|
-
"required",
|
|
522
|
-
"reversed",
|
|
523
|
-
"selected"
|
|
524
|
-
]);
|
|
525
|
-
const booleanAttributesSet = new Set(booleanAttributes);
|
|
526
|
-
const dispatchedAttributes = /* @__PURE__ */ new Set([
|
|
527
|
-
"checked",
|
|
528
|
-
"open",
|
|
529
|
-
"value"
|
|
530
|
-
]);
|
|
531
|
-
document.createElement("form");
|
|
532
|
-
//#endregion
|
|
533
|
-
//#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
|
|
534
|
-
function getValueForAttribute(value, json) {
|
|
535
|
-
if (typeof value === "string") return value;
|
|
536
|
-
return json ? JSON.stringify(value) : getString(value);
|
|
537
|
-
}
|
|
538
|
-
function ignoreSetAttribute(element, name) {
|
|
539
|
-
if (element instanceof HTMLTextAreaElement && name === "value") return true;
|
|
540
|
-
return false;
|
|
541
|
-
}
|
|
542
|
-
function normalizeKey(key, style) {
|
|
543
|
-
return style && key.startsWith(CSS_VARIABLE_PREFIX$1) ? key : kebabCase(key);
|
|
544
|
-
}
|
|
545
|
-
function setElementValue(element, first, second, third, callback, style) {
|
|
546
|
-
if (!(element instanceof Element)) return;
|
|
547
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
|
|
548
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
|
|
549
|
-
}
|
|
550
|
-
function setElementValues(element, first, second, third, callback, style) {
|
|
551
|
-
if (!(element instanceof Element)) return;
|
|
552
|
-
const dispatch = third !== false;
|
|
553
|
-
if (typeof first === "string") {
|
|
554
|
-
callback(element, normalizeKey(first, style), second, dispatch);
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
const isArray = Array.isArray(first);
|
|
558
|
-
if (!isArray && !(typeof first === "object" && first !== null)) return;
|
|
559
|
-
const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
|
|
560
|
-
name,
|
|
561
|
-
value
|
|
562
|
-
}));
|
|
563
|
-
const { length } = entries;
|
|
564
|
-
for (let index = 0; index < length; index += 1) {
|
|
565
|
-
const entry = entries[index];
|
|
566
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
function updateElementValue(element, key, value, set, remove, json) {
|
|
570
|
-
if (value == null) remove.call(element, key);
|
|
571
|
-
else if (!ignoreSetAttribute(element, key)) set.call(element, key, getValueForAttribute(value, json));
|
|
572
|
-
}
|
|
573
|
-
const CSS_VARIABLE_PREFIX$1 = "--";
|
|
574
|
-
//#endregion
|
|
575
|
-
//#region node_modules/@oscarpalmer/toretto/dist/aria.mjs
|
|
576
|
-
function getAria(element, value) {
|
|
577
|
-
if (!(element instanceof Element)) return Array.isArray(value) ? {} : void 0;
|
|
578
|
-
if (!Array.isArray(value)) return typeof value === "string" ? getAriaValue(element, value) : void 0;
|
|
579
|
-
const arias = {};
|
|
580
|
-
const { length } = value;
|
|
581
|
-
for (let index = 0; index < length; index += 1) {
|
|
582
|
-
const attribute = value[index];
|
|
583
|
-
if (typeof attribute === "string") arias[attribute.replace(ATTRIBUTE_ARIA_PREFIX, "")] = getAriaValue(element, attribute);
|
|
584
|
-
}
|
|
585
|
-
return arias;
|
|
586
|
-
}
|
|
587
|
-
function getAriaValue(element, attribute) {
|
|
588
|
-
const name = getName$1(attribute);
|
|
589
|
-
const value = element.getAttribute(name) ?? void 0;
|
|
590
|
-
if (ariaBooleanAttributesSet.has(name) && typeof value === "string" && EXPRESSION_BOOLEAN.test(value)) return value.toLowerCase() === "true";
|
|
591
|
-
return value;
|
|
592
|
-
}
|
|
593
|
-
function getName$1(value) {
|
|
594
|
-
return EXPRESSION_ARIA_PREFIX.test(value) ? value : `${ATTRIBUTE_ARIA_PREFIX}${value}`;
|
|
595
|
-
}
|
|
596
|
-
function setAria(element, first, second) {
|
|
597
|
-
setElementValues(element, first, second, null, updateAriaAttribute);
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Set the role of an element
|
|
601
|
-
*
|
|
602
|
-
* @param element Element for role
|
|
603
|
-
* @param role Role to set _(or `undefined` to remove it)_
|
|
604
|
-
*/
|
|
605
|
-
function setRole(element, role) {
|
|
606
|
-
if (!(element instanceof Element)) return;
|
|
607
|
-
if (typeof role === "string") element.setAttribute("role", role);
|
|
608
|
-
else element.removeAttribute("role");
|
|
609
|
-
}
|
|
610
|
-
function updateAriaAttribute(element, key, value) {
|
|
611
|
-
const name = getName$1(key);
|
|
612
|
-
let actual = value;
|
|
613
|
-
if (ariaBooleanAttributesSet.has(name) && typeof value === "string" && EXPRESSION_BOOLEAN.test(value)) actual = value.toLowerCase() === "true";
|
|
614
|
-
updateElementValue(element, name, actual, element.setAttribute, element.removeAttribute, false);
|
|
615
|
-
}
|
|
616
|
-
const ATTRIBUTE_ARIA_PREFIX = "aria-";
|
|
617
|
-
const EXPRESSION_ARIA_PREFIX = /^aria-/i;
|
|
618
|
-
const EXPRESSION_BOOLEAN = /^(true|false)$/i;
|
|
619
|
-
/**
|
|
620
|
-
* List of _ARIA_ attributes that can be treated as boolean values
|
|
621
|
-
*/
|
|
622
|
-
const ariaBooleanAttributes = Object.freeze([
|
|
623
|
-
"aria-atomic",
|
|
624
|
-
"aria-busy",
|
|
625
|
-
"aria-checked",
|
|
626
|
-
"aria-current",
|
|
627
|
-
"aria-disabled",
|
|
628
|
-
"aria-expanded",
|
|
629
|
-
"aria-haspopup",
|
|
630
|
-
"aria-hidden",
|
|
631
|
-
"aria-invalid",
|
|
632
|
-
"aria-modal",
|
|
633
|
-
"aria-multiline",
|
|
634
|
-
"aria-multiselectable",
|
|
635
|
-
"aria-pressed",
|
|
636
|
-
"aria-readonly",
|
|
637
|
-
"aria-required",
|
|
638
|
-
"aria-selected"
|
|
639
|
-
]);
|
|
640
|
-
/**
|
|
641
|
-
* Set of _ARIA_ attributes that can be treated as boolean values
|
|
642
|
-
*/
|
|
643
|
-
const ariaBooleanAttributesSet = new Set(ariaBooleanAttributes);
|
|
644
|
-
//#endregion
|
|
645
|
-
//#region node_modules/@oscarpalmer/toretto/dist/internal/get-value.mjs
|
|
646
|
-
function getBoolean(value, defaultValue) {
|
|
647
|
-
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
648
|
-
}
|
|
649
|
-
function getAttributeValue$1(element, name, parseValue) {
|
|
650
|
-
const normalized = kebabCase(name);
|
|
651
|
-
const attribute = element.attributes[normalized];
|
|
652
|
-
const value = attribute instanceof Attr ? attribute.value : void 0;
|
|
653
|
-
return EXPRESSION_DATA_PREFIX.test(normalized) && typeof value === "string" && parseValue ? parse(value) ?? value : value;
|
|
654
|
-
}
|
|
655
|
-
function getStyleValue(element, property, computed) {
|
|
656
|
-
if (property.startsWith(CSS_VARIABLE_PREFIX)) return element.style.getPropertyValue(property);
|
|
657
|
-
const name = camelCase(property);
|
|
658
|
-
return computed ? getComputedStyle(element)[name] : element.style[name];
|
|
659
|
-
}
|
|
660
|
-
const EXPRESSION_DATA_PREFIX = /^data-/i;
|
|
661
|
-
const CSS_VARIABLE_PREFIX = "--";
|
|
662
|
-
//#endregion
|
|
663
|
-
//#region node_modules/@oscarpalmer/toretto/dist/attribute/get.attribute.mjs
|
|
664
|
-
function getAttribute(element, name, parseValues) {
|
|
665
|
-
if (element instanceof Element && typeof name === "string") return getAttributeValue$1(element, kebabCase(name), parseValues !== false);
|
|
666
|
-
}
|
|
667
|
-
//#endregion
|
|
668
|
-
//#region node_modules/@oscarpalmer/toretto/dist/attribute/set.attribute.mjs
|
|
669
|
-
function setAttribute(element, first, second, third) {
|
|
670
|
-
setElementValue(element, first, second, third, updateAttribute);
|
|
671
|
-
}
|
|
672
|
-
function setAttributes(element, attributes, dispatch) {
|
|
673
|
-
setElementValues(element, attributes, null, dispatch, updateAttribute);
|
|
674
|
-
}
|
|
675
|
-
//#endregion
|
|
676
|
-
//#region node_modules/@oscarpalmer/toretto/dist/event/delegation.mjs
|
|
677
|
-
function addDelegatedHandler(doc, type, name, passive) {
|
|
678
|
-
if (DELEGATED.has(name)) return;
|
|
679
|
-
DELEGATED.add(name);
|
|
680
|
-
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
681
|
-
}
|
|
682
|
-
function addDelegatedListener(target, type, name, listener, passive) {
|
|
683
|
-
target[name] ??= /* @__PURE__ */ new Set();
|
|
684
|
-
target[name].add(listener);
|
|
685
|
-
addDelegatedHandler(document, type, name, passive);
|
|
686
|
-
return () => {
|
|
687
|
-
removeDelegatedListener(target, name, listener);
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
function delegatedEventHandler(event) {
|
|
691
|
-
const key = `@${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
692
|
-
const items = event.composedPath();
|
|
693
|
-
const { length } = items;
|
|
694
|
-
let cancelled = false;
|
|
695
|
-
let target = items[0];
|
|
696
|
-
const originalStopPropagation = event.stopPropagation;
|
|
697
|
-
event.stopPropagation = function() {
|
|
698
|
-
cancelled = true;
|
|
699
|
-
originalStopPropagation.call(event);
|
|
700
|
-
};
|
|
701
|
-
event.stopImmediatePropagation = event.stopPropagation.bind(event);
|
|
702
|
-
Object.defineProperties(event, {
|
|
703
|
-
currentTarget: {
|
|
704
|
-
configurable: true,
|
|
705
|
-
get() {
|
|
706
|
-
return target;
|
|
707
|
-
}
|
|
708
|
-
},
|
|
709
|
-
target: {
|
|
710
|
-
configurable: true,
|
|
711
|
-
value: target
|
|
712
|
-
}
|
|
713
|
-
});
|
|
714
|
-
for (let index = 0; index < length; index += 1) {
|
|
715
|
-
const item = items[index];
|
|
716
|
-
const listeners = item[key];
|
|
717
|
-
if (item.disabled || listeners == null) continue;
|
|
718
|
-
target = item;
|
|
719
|
-
for (const listener of listeners) {
|
|
720
|
-
listener.call(item, event);
|
|
721
|
-
if (cancelled) return;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
function getDelegatedName(target, type, options) {
|
|
726
|
-
if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `@${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
727
|
-
}
|
|
728
|
-
function removeDelegatedListener(target, name, listener) {
|
|
729
|
-
const handlers = target[name];
|
|
730
|
-
if (handlers == null || !handlers.has(listener)) return false;
|
|
731
|
-
handlers.delete(listener);
|
|
732
|
-
if (handlers.size === 0) target[name] = void 0;
|
|
733
|
-
return true;
|
|
734
|
-
}
|
|
735
|
-
const DELEGATED = /* @__PURE__ */ new Set();
|
|
736
|
-
const EVENT_SUFFIX_ACTIVE = ":active";
|
|
737
|
-
const EVENT_SUFFIX_PASSIVE = ":passive";
|
|
738
|
-
const EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
739
|
-
"beforeinput",
|
|
740
|
-
"click",
|
|
741
|
-
"dblclick",
|
|
742
|
-
"contextmenu",
|
|
743
|
-
"focusin",
|
|
744
|
-
"focusout",
|
|
745
|
-
"input",
|
|
746
|
-
"keydown",
|
|
747
|
-
"keyup",
|
|
748
|
-
"mousedown",
|
|
749
|
-
"mousemove",
|
|
750
|
-
"mouseout",
|
|
751
|
-
"mouseover",
|
|
752
|
-
"mouseup",
|
|
753
|
-
"pointerdown",
|
|
754
|
-
"pointermove",
|
|
755
|
-
"pointerout",
|
|
756
|
-
"pointerover",
|
|
757
|
-
"pointerup",
|
|
758
|
-
"touchend",
|
|
759
|
-
"touchmove",
|
|
760
|
-
"touchstart"
|
|
761
|
-
]);
|
|
762
|
-
const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
763
|
-
const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
|
764
|
-
//#endregion
|
|
765
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
766
|
-
/**
|
|
767
|
-
* A function that does nothing, which can be useful, I guess…
|
|
768
|
-
*/
|
|
769
|
-
function noop() {}
|
|
770
|
-
//#endregion
|
|
771
|
-
//#region node_modules/@oscarpalmer/toretto/dist/event/index.mjs
|
|
772
|
-
function createDispatchOptions(options) {
|
|
773
|
-
return {
|
|
774
|
-
bubbles: getBoolean(options?.bubbles, true),
|
|
775
|
-
cancelable: getBoolean(options?.cancelable, true),
|
|
776
|
-
composed: getBoolean(options?.composed)
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
function createEvent(type, options) {
|
|
780
|
-
const hasOptions = isPlainObject(options);
|
|
781
|
-
if (hasOptions && "detail" in options) return new CustomEvent(type, {
|
|
782
|
-
...createDispatchOptions(options),
|
|
783
|
-
detail: options?.detail
|
|
784
|
-
});
|
|
785
|
-
return new Event(type, createDispatchOptions(hasOptions ? options : {}));
|
|
786
|
-
}
|
|
787
|
-
function createEventOptions(options) {
|
|
788
|
-
return {
|
|
789
|
-
capture: getBoolean(options?.capture),
|
|
790
|
-
once: getBoolean(options?.once),
|
|
791
|
-
passive: getBoolean(options?.passive, true),
|
|
792
|
-
signal: options?.signal instanceof AbortSignal ? options.signal : void 0
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
function dispatch(target, type, options) {
|
|
796
|
-
if (!isEventTarget(target) || typeof type !== "string") return;
|
|
797
|
-
const event = createEvent(type, options);
|
|
798
|
-
target.dispatchEvent(event);
|
|
799
|
-
return event;
|
|
800
|
-
}
|
|
801
|
-
/**
|
|
802
|
-
* Get the X- and Y-coordinates from a pointer event
|
|
803
|
-
*
|
|
804
|
-
* @param event Pointer event
|
|
805
|
-
* @returns X- and Y-coordinates
|
|
806
|
-
*/
|
|
807
|
-
function getPosition$1(event) {
|
|
808
|
-
let x;
|
|
809
|
-
let y;
|
|
810
|
-
if (event instanceof MouseEvent) {
|
|
811
|
-
x = event.clientX;
|
|
812
|
-
y = event.clientY;
|
|
813
|
-
} else if (event instanceof TouchEvent) {
|
|
814
|
-
x = event.touches[0]?.clientX;
|
|
815
|
-
y = event.touches[0]?.clientY;
|
|
816
|
-
}
|
|
817
|
-
return typeof x === "number" && typeof y === "number" ? {
|
|
818
|
-
x,
|
|
819
|
-
y
|
|
820
|
-
} : void 0;
|
|
821
|
-
}
|
|
822
|
-
function on(target, type, listener, options) {
|
|
823
|
-
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
824
|
-
const extended = createEventOptions(options);
|
|
825
|
-
const delegated = getDelegatedName(target, type, extended);
|
|
826
|
-
if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
|
|
827
|
-
target.addEventListener(type, listener, extended);
|
|
828
|
-
if (extended.once) return noop;
|
|
829
|
-
return () => {
|
|
830
|
-
target.removeEventListener(type, listener, extended);
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
//#endregion
|
|
834
|
-
//#region node_modules/@oscarpalmer/toretto/dist/find/relative.mjs
|
|
835
|
-
function findAncestor(origin, selector) {
|
|
836
|
-
const element = getElement(origin);
|
|
837
|
-
if (element == null || selector == null) return null;
|
|
838
|
-
if (typeof selector === "string") {
|
|
839
|
-
if (Element.prototype.matches.call(element, selector)) return element;
|
|
840
|
-
return Element.prototype.closest.call(element, selector);
|
|
841
|
-
}
|
|
842
|
-
if (typeof selector !== "function") return null;
|
|
843
|
-
if (selector(element)) return element;
|
|
844
|
-
let parent = element.parentElement;
|
|
845
|
-
while (parent != null && !selector(parent)) {
|
|
846
|
-
if (parent === document.body) return null;
|
|
847
|
-
parent = parent.parentElement;
|
|
848
|
-
}
|
|
849
|
-
return parent;
|
|
850
|
-
}
|
|
851
|
-
function getElement(origin) {
|
|
852
|
-
if (origin instanceof Element) return origin;
|
|
853
|
-
return origin instanceof Event && origin.target instanceof Element ? origin.target : void 0;
|
|
854
|
-
}
|
|
855
|
-
//#endregion
|
|
856
|
-
//#region node_modules/@oscarpalmer/toretto/dist/find/index.mjs
|
|
857
|
-
/**
|
|
858
|
-
* Get elements from an event position
|
|
859
|
-
*
|
|
860
|
-
* @param position Event position
|
|
861
|
-
* @returns Elements at the event position
|
|
862
|
-
*/
|
|
863
|
-
function getElementFromPosition(position) {
|
|
864
|
-
if (!isEventPosition(position) || typeof document.elementFromPoint !== "function") return [];
|
|
865
|
-
const { x, y } = position;
|
|
866
|
-
const elements = [];
|
|
867
|
-
const events = [];
|
|
868
|
-
let current;
|
|
869
|
-
while (true) {
|
|
870
|
-
current = document.elementFromPoint(x, y);
|
|
871
|
-
if (current == null || elements.indexOf(current) !== -1) break;
|
|
872
|
-
if (!(current instanceof HTMLElement)) continue;
|
|
873
|
-
elements.push(current);
|
|
874
|
-
events.push({
|
|
875
|
-
value: current.style.getPropertyValue(STYLE_POINTER_EVENTS),
|
|
876
|
-
priority: current.style.getPropertyPriority(STYLE_POINTER_EVENTS)
|
|
877
|
-
});
|
|
878
|
-
current.style.setProperty(STYLE_POINTER_EVENTS, STYLE_NONE$1, STYLE_IMPORTANT);
|
|
879
|
-
}
|
|
880
|
-
const { length } = elements;
|
|
881
|
-
for (let index = 0; index < length; index += 1) {
|
|
882
|
-
const element = elements[index];
|
|
883
|
-
const event = events[index];
|
|
884
|
-
if (element instanceof HTMLElement) element.style.setProperty(STYLE_POINTER_EVENTS, event.value ?? "", event.priority);
|
|
885
|
-
}
|
|
886
|
-
return elements;
|
|
887
|
-
}
|
|
888
|
-
const STYLE_IMPORTANT = "important";
|
|
889
|
-
const STYLE_NONE$1 = "none";
|
|
890
|
-
const STYLE_POINTER_EVENTS = "pointer-events";
|
|
891
|
-
Node.ELEMENT_NODE, Node.TEXT_NODE, Node.PROCESSING_INSTRUCTION_NODE, Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE;
|
|
892
|
-
//#endregion
|
|
893
|
-
//#region node_modules/@oscarpalmer/toretto/dist/style.mjs
|
|
894
|
-
/**
|
|
895
|
-
* Get styles from an element
|
|
896
|
-
*
|
|
897
|
-
* @param element Element to get the styles from
|
|
898
|
-
* @param names Styles to get
|
|
899
|
-
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
900
|
-
* @returns Style values
|
|
901
|
-
*/
|
|
902
|
-
function getStyles(element, names, computed) {
|
|
903
|
-
const styles = {};
|
|
904
|
-
if (!(element instanceof Element && Array.isArray(names))) return styles;
|
|
905
|
-
const { length } = names;
|
|
906
|
-
for (let index = 0; index < length; index += 1) {
|
|
907
|
-
const name = names[index];
|
|
908
|
-
if (typeof name === "string") styles[name] = getStyleValue(element, name, computed === true);
|
|
909
|
-
}
|
|
910
|
-
return styles;
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Set a style on an element
|
|
914
|
-
*
|
|
915
|
-
* @param element Element to set the style on
|
|
916
|
-
* @param name Style name
|
|
917
|
-
* @param value Style value
|
|
918
|
-
*/
|
|
919
|
-
function setStyle(element, name, value) {
|
|
920
|
-
setElementValues(element, name, value, null, updateStyleProperty, true);
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Set styles on an element
|
|
924
|
-
*
|
|
925
|
-
* @param element Element to set the styles on
|
|
926
|
-
* @param styles Styles to set
|
|
927
|
-
*/
|
|
928
|
-
function setStyles(element, styles) {
|
|
929
|
-
setElementValues(element, styles, null, null, updateStyleProperty, true);
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
* Toggle styles for an element
|
|
933
|
-
*
|
|
934
|
-
* @param element Element to style
|
|
935
|
-
* @param styles Styles to be set or removed
|
|
936
|
-
* @returns Style toggler
|
|
937
|
-
*/
|
|
938
|
-
function toggleStyles(element, styles) {
|
|
939
|
-
function toggle(set) {
|
|
940
|
-
hasSet = set;
|
|
941
|
-
let next;
|
|
942
|
-
if (set) {
|
|
943
|
-
values = getStyles(element, keys);
|
|
944
|
-
next = styles;
|
|
945
|
-
} else {
|
|
946
|
-
next = { ...values };
|
|
947
|
-
values = {};
|
|
948
|
-
for (let index = 0; index < length; index += 1) values[keys[index]] = void 0;
|
|
949
|
-
}
|
|
950
|
-
setStyles(element, next);
|
|
951
|
-
}
|
|
952
|
-
const keys = Object.keys(styles);
|
|
953
|
-
const { length } = keys;
|
|
954
|
-
let hasSet = false;
|
|
955
|
-
let values = {};
|
|
956
|
-
return {
|
|
957
|
-
set() {
|
|
958
|
-
if (!hasSet) toggle(true);
|
|
959
|
-
},
|
|
960
|
-
remove() {
|
|
961
|
-
if (hasSet) toggle(false);
|
|
962
|
-
}
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
|
-
function updateStyleProperty(element, key, value) {
|
|
966
|
-
updateElementValue(element, key, value, function(name, style) {
|
|
967
|
-
if (name.startsWith(VARIABLE_PREFIX)) this.style.setProperty(name, getString(style));
|
|
968
|
-
else this.style[name] = getString(style);
|
|
969
|
-
}, function(name) {
|
|
970
|
-
if (name.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(name);
|
|
971
|
-
else this.style[name] = "";
|
|
972
|
-
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
973
|
-
}, false);
|
|
974
|
-
}
|
|
975
|
-
const ATTRIBUTE_STYLE = "style";
|
|
976
|
-
const VARIABLE_PREFIX = "--";
|
|
977
|
-
//#endregion
|
|
978
|
-
//#region src/js/floatable/floatable.embedded.ts
|
|
979
|
-
var OuiFloatable = class {
|
|
980
|
-
#destroyed = false;
|
|
981
|
-
#state;
|
|
982
|
-
/**
|
|
983
|
-
* Is the floatable open?
|
|
984
|
-
*/
|
|
985
|
-
get open() {
|
|
986
|
-
return this.#state.content.checkVisibility();
|
|
987
|
-
}
|
|
988
|
-
/**
|
|
989
|
-
* Open or close the floatable
|
|
990
|
-
*/
|
|
991
|
-
set open(value) {
|
|
992
|
-
if (value === true) this.show();
|
|
993
|
-
else if (value === false) this.hide();
|
|
994
|
-
}
|
|
995
|
-
constructor(state, standalone) {
|
|
996
|
-
this.#state = state;
|
|
997
|
-
const { anchor, content } = state;
|
|
998
|
-
if (standalone) {
|
|
999
|
-
setAttribute(content, ATTRIBUTE_FLOATABLE, "");
|
|
1000
|
-
content.popover = "manual";
|
|
1001
|
-
} else content.popover ??= "auto";
|
|
1002
|
-
setStyle(anchor, "anchorName", state.name);
|
|
1003
|
-
setStyle(content, "positionAnchor", state.name);
|
|
1004
|
-
}
|
|
1005
|
-
/**
|
|
1006
|
-
* Destroy the floatable, removing it from the DOM and cleaning up references
|
|
1007
|
-
*/
|
|
1008
|
-
destroy() {
|
|
1009
|
-
if (this.#destroyed) return;
|
|
1010
|
-
this.#destroyed = true;
|
|
1011
|
-
removeFloatable(this.#state.content);
|
|
1012
|
-
this.#state.anchor = null;
|
|
1013
|
-
this.#state.content = null;
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Closes the floatable
|
|
1017
|
-
*/
|
|
1018
|
-
hide() {
|
|
1019
|
-
if (!this.#destroyed && this.open) this.#state.content.hidePopover();
|
|
1020
|
-
}
|
|
1021
|
-
/**
|
|
1022
|
-
* Opens the floatable
|
|
1023
|
-
*/
|
|
1024
|
-
show() {
|
|
1025
|
-
if (!this.#destroyed && !this.open) this.#state.content.showPopover();
|
|
1026
|
-
}
|
|
1027
|
-
/**
|
|
1028
|
-
* Update the position of the floatable, with an optional new position
|
|
1029
|
-
*
|
|
1030
|
-
* @param position Optional new position
|
|
1031
|
-
*/
|
|
1032
|
-
update(position) {
|
|
1033
|
-
if (!this.#destroyed) setPosition(this.#state, position);
|
|
1034
|
-
}
|
|
1035
|
-
};
|
|
1036
|
-
function getAnchorName(anchor) {
|
|
1037
|
-
let { anchorName } = anchor.style;
|
|
1038
|
-
if (anchorName.length > 0) return anchorName;
|
|
1039
|
-
index$4 += 1;
|
|
1040
|
-
return `--oui-floatable-anchor-${index$4}`;
|
|
1041
|
-
}
|
|
1042
|
-
function createEmbeddedFloatable(anchor, content, options) {
|
|
1043
|
-
return createInstance(anchor, content, options, false);
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* Create a _OuiFloatable_ for an anchor and content element
|
|
1047
|
-
*
|
|
1048
|
-
* @param anchor Anchor element
|
|
1049
|
-
* @param content Content element
|
|
1050
|
-
* @param options _OuiFloatable_ options
|
|
1051
|
-
* @returns _OuiFloatable_ instance
|
|
1052
|
-
*/
|
|
1053
|
-
function createFloatable(anchor, content, options) {
|
|
1054
|
-
const { open, position } = getOptions$1(options);
|
|
1055
|
-
const floatable = createInstance(anchor, content, {
|
|
1056
|
-
position,
|
|
1057
|
-
reusable: false
|
|
1058
|
-
}, true);
|
|
1059
|
-
floatable?.update(position);
|
|
1060
|
-
if (open) floatable?.show();
|
|
1061
|
-
return floatable;
|
|
1062
|
-
}
|
|
1063
|
-
function createInstance(anchor, content, options, standalone) {
|
|
1064
|
-
if (!isHTMLOrSVGElement(anchor) || !isHTMLOrSVGElement(content)) throw new TypeError(MESSAGE$6);
|
|
1065
|
-
let floatable = options.reusable ? void 0 : instances$2.get(content);
|
|
1066
|
-
if (floatable == null) {
|
|
1067
|
-
floatable = new OuiFloatable(getState$5(anchor, content, options), standalone);
|
|
1068
|
-
if (!options.reusable) instances$2.set(content, floatable);
|
|
1069
|
-
}
|
|
1070
|
-
return floatable;
|
|
1071
|
-
}
|
|
1072
|
-
function getOnBeforeToggleListener(element) {
|
|
1073
|
-
return on(element, "beforetoggle", (event) => {
|
|
1074
|
-
const { newState, source } = event;
|
|
1075
|
-
if (newState === "open" && source != null && getAria(source, "disabled") === "true") event.preventDefault();
|
|
1076
|
-
}, { passive: false });
|
|
1077
|
-
}
|
|
1078
|
-
function getOptions$1(input) {
|
|
1079
|
-
const object = isPlainObject(input) ? input : {};
|
|
1080
|
-
return {
|
|
1081
|
-
open: typeof object.open === "boolean" ? object.open : true,
|
|
1082
|
-
position: object.position != null && object.position in AREAS ? object.position : "below"
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
function getPosition(state, override) {
|
|
1086
|
-
if (override != null && override in AREAS) return override;
|
|
1087
|
-
const { anchor, options } = state;
|
|
1088
|
-
if (options.attribute == null) return options.position;
|
|
1089
|
-
const attribute = getAttribute(anchor, options.attribute);
|
|
1090
|
-
return attribute != null && attribute in AREAS ? attribute : options.position;
|
|
1091
|
-
}
|
|
1092
|
-
function getState$5(anchor, content, options) {
|
|
1093
|
-
return {
|
|
1094
|
-
anchor,
|
|
1095
|
-
content,
|
|
1096
|
-
name: getAnchorName(anchor),
|
|
1097
|
-
options
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
function removeFloatable(content) {
|
|
1101
|
-
instances$2.get(content)?.destroy();
|
|
1102
|
-
instances$2.delete(content);
|
|
1103
|
-
}
|
|
1104
|
-
function setPosition(state, override) {
|
|
1105
|
-
const position = getPosition(state, override);
|
|
1106
|
-
const area = AREAS[position];
|
|
1107
|
-
setAttribute(state.content, ATTRIBUTE_POSITION, POSITIONS[area]);
|
|
1108
|
-
setStyles(state.content, {
|
|
1109
|
-
positionAnchor: state.name,
|
|
1110
|
-
positionArea: area
|
|
1111
|
-
});
|
|
1112
|
-
}
|
|
1113
|
-
const AREAS = {
|
|
1114
|
-
above: "block-start",
|
|
1115
|
-
"above-end": "start span-start",
|
|
1116
|
-
"above-start": "start span-end",
|
|
1117
|
-
below: "block-end",
|
|
1118
|
-
"below-end": "end span-start",
|
|
1119
|
-
"below-start": "end span-end",
|
|
1120
|
-
end: "center end",
|
|
1121
|
-
"end-bottom": "span-start end",
|
|
1122
|
-
"end-top": "span-end end",
|
|
1123
|
-
start: "center start",
|
|
1124
|
-
"start-bottom": "span-start start",
|
|
1125
|
-
"start-top": "span-end start"
|
|
1126
|
-
};
|
|
1127
|
-
const ATTRIBUTE_FLOATABLE = "oui-floatable";
|
|
1128
|
-
const ATTRIBUTE_POSITION = "oui-position";
|
|
1129
|
-
const MESSAGE$6 = "Anchor and content must be an HTMLElement or SVGElement";
|
|
1130
|
-
const POSITIONS = Object.fromEntries(Object.entries(AREAS).map(([position, area]) => [area, position]));
|
|
1131
|
-
const instances$2 = /* @__PURE__ */ new WeakMap();
|
|
1132
|
-
let index$4 = 0;
|
|
1133
|
-
//#endregion
|
|
1134
|
-
//#region src/js/internal/attributable.ts
|
|
1135
|
-
function attributable(attribute, add, remove) {
|
|
1136
|
-
new MutationObserver((entries) => {
|
|
1137
|
-
const { length } = entries;
|
|
1138
|
-
for (let index = 0; index < length; index += 1) {
|
|
1139
|
-
const entry = entries[index];
|
|
1140
|
-
if (entry.type === "attributes" && entry.target instanceof Element) if (entry.target.hasAttribute(attribute)) handleAdded(attribute, [entry.target], add);
|
|
1141
|
-
else handleRemoved([entry.target], remove);
|
|
1142
|
-
else if (entry.type === "childList") {
|
|
1143
|
-
handleAdded(attribute, entry.addedNodes, add);
|
|
1144
|
-
handleRemoved(entry.removedNodes, remove);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
}).observe(document, {
|
|
1148
|
-
attributeFilter: [attribute],
|
|
1149
|
-
attributes: true,
|
|
1150
|
-
childList: true,
|
|
1151
|
-
subtree: true
|
|
1152
|
-
});
|
|
1153
|
-
requestAnimationFrame(() => {
|
|
1154
|
-
handleAdded(attribute, document.querySelectorAll(`[${attribute}]`), add);
|
|
1155
|
-
});
|
|
1156
|
-
}
|
|
1157
|
-
function handleAdded(attribute, nodes, add) {
|
|
1158
|
-
const elements = [...nodes].filter((node) => node instanceof Element);
|
|
1159
|
-
const { length } = elements;
|
|
1160
|
-
for (let index = 0; index < length; index += 1) {
|
|
1161
|
-
const element = elements[index];
|
|
1162
|
-
if (element.hasAttribute(attribute)) add(element);
|
|
1163
|
-
if (element.hasChildNodes()) handleAdded(attribute, element.childNodes, add);
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
function handleRemoved(nodes, remove) {
|
|
1167
|
-
const elements = [...nodes].filter((node) => node instanceof Element);
|
|
1168
|
-
const { length } = elements;
|
|
1169
|
-
for (let index = 0; index < length; index += 1) {
|
|
1170
|
-
const element = elements[index];
|
|
1171
|
-
remove(element);
|
|
1172
|
-
if (element.hasChildNodes()) handleRemoved(element.childNodes, remove);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
//#endregion
|
|
1176
|
-
//#region src/js/internal/navigable.ts
|
|
1177
|
-
var OuiNavigable = class {
|
|
1178
|
-
active = { index: 0 };
|
|
1179
|
-
element;
|
|
1180
|
-
listeners;
|
|
1181
|
-
options;
|
|
1182
|
-
orientation;
|
|
1183
|
-
constructor(element, options) {
|
|
1184
|
-
this.element = element;
|
|
1185
|
-
this.options = options;
|
|
1186
|
-
this.listeners = [on(element, "focusin", (event) => {
|
|
1187
|
-
onFocusin$1(this, event);
|
|
1188
|
-
}), on(element, "keydown", (event) => {
|
|
1189
|
-
onKeydown$5(this, event);
|
|
1190
|
-
}, { passive: false })];
|
|
1191
|
-
this.orientation = getOrientation(element, options);
|
|
1192
|
-
if (options.role != null) setRole(element, options.role);
|
|
1193
|
-
}
|
|
1194
|
-
destroy() {
|
|
1195
|
-
const listeners = this.listeners.splice(0);
|
|
1196
|
-
for (const listener of listeners) listener();
|
|
1197
|
-
this.active.element = void 0;
|
|
1198
|
-
this.element = void 0;
|
|
1199
|
-
}
|
|
1200
|
-
};
|
|
1201
|
-
function getItems(container, selector) {
|
|
1202
|
-
return [...container.querySelectorAll(selector)].filter(isValidItem);
|
|
1203
|
-
}
|
|
1204
|
-
function getNavigable(element, options) {
|
|
1205
|
-
return new OuiNavigable(element, options);
|
|
1206
|
-
}
|
|
1207
|
-
function getOrientation(element, options) {
|
|
1208
|
-
const attribute = getAria(element, "orientation");
|
|
1209
|
-
return ORIENTATIONS.has(attribute) ? attribute : options.vertical ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
|
|
1210
|
-
}
|
|
1211
|
-
function isValidItem(element) {
|
|
1212
|
-
return "disabled" in element ? element.disabled !== true : true;
|
|
1213
|
-
}
|
|
1214
|
-
function onFocusin$1(navigable, event) {
|
|
1215
|
-
const item = findAncestor(event, navigable.options.selector);
|
|
1216
|
-
if (!isHTMLOrSVGElement(item) || !isValidItem(item)) return;
|
|
1217
|
-
const items = getItems(navigable.element, navigable.options.selector);
|
|
1218
|
-
const index = items.indexOf(item);
|
|
1219
|
-
if (index === -1) return;
|
|
1220
|
-
navigable.active.element = item;
|
|
1221
|
-
navigable.active.index = index;
|
|
1222
|
-
updateNavigableFocus(navigable, false, items);
|
|
1223
|
-
}
|
|
1224
|
-
function onKeydown$5(navigable, event) {
|
|
1225
|
-
const escaped = event.key === "Escape";
|
|
1226
|
-
const stopPropagation = navigable.options.onShouldDeactivate?.(event, navigable);
|
|
1227
|
-
if (escaped || stopPropagation != null) {
|
|
1228
|
-
if (escaped || stopPropagation) event.stopPropagation();
|
|
1229
|
-
navigable.options.onDeactivate?.(event, navigable);
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
if (!KEYS_ALL$1.has(event.key)) return;
|
|
1233
|
-
const mustActivate = KEYS_ACTIVATE.has(event.key);
|
|
1234
|
-
const shouldActivate = navigable.options.onShouldActivate?.(event, navigable) === true;
|
|
1235
|
-
if (mustActivate || shouldActivate || navigable.options.onPreventNavigation?.(event, navigable) === true) event.stopPropagation();
|
|
1236
|
-
if (mustActivate || shouldActivate) return;
|
|
1237
|
-
const items = getItems(navigable.element, navigable.options.selector);
|
|
1238
|
-
const { length } = items;
|
|
1239
|
-
if (length === 0) return;
|
|
1240
|
-
let index;
|
|
1241
|
-
if (KEYS_ABSOLUTE$1.has(event.key)) index = event.key === "Home" ? 0 : items.length - 1;
|
|
1242
|
-
else {
|
|
1243
|
-
const direction = NAVIGABLE_KEYS_HORIZONTAL.has(event.key) ? ORIENTATION_HORIZONTAL : ORIENTATION_VERTICAL;
|
|
1244
|
-
if (navigable.orientation === direction) {
|
|
1245
|
-
if (navigable.active.element instanceof HTMLSelectElement) event.preventDefault();
|
|
1246
|
-
index = clamp(navigable.active.index + (KEYS_NEXT.has(event.key) ? 1 : -1), 0, length - 1, true);
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
if (index == null || index === navigable.active.index) return;
|
|
1250
|
-
navigable.active.element = items[index];
|
|
1251
|
-
navigable.active.index = index;
|
|
1252
|
-
updateNavigableFocus(navigable, true, items);
|
|
1253
|
-
}
|
|
1254
|
-
function updateNavigableFocus(navigable, focus, items) {
|
|
1255
|
-
const updated = items ?? getItems(navigable.element, navigable.options.selector);
|
|
1256
|
-
const { length } = updated;
|
|
1257
|
-
if (length === 0) return;
|
|
1258
|
-
for (let index = 0; index < length; index += 1) updated[index].tabIndex = index === navigable.active.index ? 0 : -1;
|
|
1259
|
-
navigable.active.element ??= updated[navigable.active.index];
|
|
1260
|
-
if (focus) navigable.active.element?.focus();
|
|
1261
|
-
dispatch(navigable.active.element, "navigable:change", { detail: { ...navigable.active } });
|
|
1262
|
-
}
|
|
1263
|
-
const KEYS_ABSOLUTE$1 = /* @__PURE__ */ new Set(["End", "Home"]);
|
|
1264
|
-
const KEYS_ACTIVATE = /* @__PURE__ */ new Set(["Enter", " "]);
|
|
1265
|
-
const NAVIGABLE_KEYS_HORIZONTAL = /* @__PURE__ */ new Set(["ArrowRight", "ArrowLeft"]);
|
|
1266
|
-
const NAVIGABLE_KEYS_VERTICAL = /* @__PURE__ */ new Set(["ArrowDown", "ArrowUp"]);
|
|
1267
|
-
const KEYS_ALL$1 = /* @__PURE__ */ new Set([
|
|
1268
|
-
...KEYS_ABSOLUTE$1,
|
|
1269
|
-
...KEYS_ACTIVATE,
|
|
1270
|
-
...NAVIGABLE_KEYS_HORIZONTAL,
|
|
1271
|
-
...NAVIGABLE_KEYS_VERTICAL
|
|
1272
|
-
]);
|
|
1273
|
-
const KEYS_NEXT = /* @__PURE__ */ new Set(["ArrowDown", "ArrowRight"]);
|
|
1274
|
-
const ORIENTATION_HORIZONTAL = "horizontal";
|
|
1275
|
-
const ORIENTATION_VERTICAL = "vertical";
|
|
1276
|
-
const ORIENTATIONS = /* @__PURE__ */ new Set([ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL]);
|
|
1277
|
-
//#endregion
|
|
1278
|
-
//#region src/js/menu.ts
|
|
1279
|
-
var OuiMenu = class {
|
|
1280
|
-
content;
|
|
1281
|
-
element;
|
|
1282
|
-
floatable;
|
|
1283
|
-
navigable;
|
|
1284
|
-
toggle;
|
|
1285
|
-
get open() {
|
|
1286
|
-
return this.floatable.open;
|
|
1287
|
-
}
|
|
1288
|
-
constructor(element, navigable) {
|
|
1289
|
-
this.element = element;
|
|
1290
|
-
this.navigable = navigable;
|
|
1291
|
-
this.content = navigable.element;
|
|
1292
|
-
this.toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
|
|
1293
|
-
this.floatable = createEmbeddedFloatable(this.toggle, this.content, {
|
|
1294
|
-
attribute: ATTRIBUTE_MENU_POSITION,
|
|
1295
|
-
position: findAncestor(element.parentElement, SELECTOR_MENU_CONTENT) == null ? "below-start" : "end-top",
|
|
1296
|
-
reusable: false
|
|
1297
|
-
});
|
|
1298
|
-
this.navigable.listeners.push(getOnBeforeToggleListener(this.content), on(this.content, "click", (event) => {
|
|
1299
|
-
event.stopPropagation();
|
|
1300
|
-
if (findAncestor(event, SELECTOR_MENU_TOGGLE) != null) return;
|
|
1301
|
-
const elements = document.querySelectorAll(SELECTOR_MENU_CONTENT);
|
|
1302
|
-
for (const element of elements) menus.get(element)?.floatable.hide();
|
|
1303
|
-
const menu = menus.get(elements[0]);
|
|
1304
|
-
if (menu != null && event.pointerId === -1) updateNavigableFocus(menu.navigable, true);
|
|
1305
|
-
}), on(this.content, "toggle", (event) => {
|
|
1306
|
-
const expanded = event.newState === "open";
|
|
1307
|
-
if (expanded) {
|
|
1308
|
-
this.floatable?.update();
|
|
1309
|
-
updateNavigableFocus(this.navigable, true);
|
|
1310
|
-
}
|
|
1311
|
-
setAria(this.toggle, "expanded", expanded);
|
|
1312
|
-
}));
|
|
1313
|
-
this.floatable.update();
|
|
1314
|
-
initializeMenu(this);
|
|
1315
|
-
updateNavigableFocus(this.navigable, false);
|
|
1316
|
-
}
|
|
1317
|
-
destroy() {
|
|
1318
|
-
this.floatable.destroy();
|
|
1319
|
-
this.navigable.destroy();
|
|
1320
|
-
this.floatable = void 0;
|
|
1321
|
-
this.navigable = void 0;
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
var OuiMenubar = class {
|
|
1325
|
-
element;
|
|
1326
|
-
navigable;
|
|
1327
|
-
constructor(element, navigable) {
|
|
1328
|
-
this.element = element;
|
|
1329
|
-
this.navigable = navigable;
|
|
1330
|
-
updateNavigableFocus(this.navigable, false);
|
|
1331
|
-
}
|
|
1332
|
-
destroy() {
|
|
1333
|
-
this.navigable.destroy();
|
|
1334
|
-
this.navigable = void 0;
|
|
1335
|
-
}
|
|
1336
|
-
};
|
|
1337
|
-
function addInstance(instances, ctor, element, content, options) {
|
|
1338
|
-
if (!instances.has(content)) instances.set(content, new ctor(element, getNavigable(content, {
|
|
1339
|
-
...options,
|
|
1340
|
-
onDeactivate,
|
|
1341
|
-
onPreventNavigation,
|
|
1342
|
-
onShouldActivate,
|
|
1343
|
-
onShouldDeactivate
|
|
1344
|
-
})));
|
|
1345
|
-
}
|
|
1346
|
-
function addMenu(element) {
|
|
1347
|
-
const content = element.querySelector(SELECTOR_MENU_CONTENT);
|
|
1348
|
-
const toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
|
|
1349
|
-
if (content != null && toggle != null) addInstance(menus, OuiMenu, element, content, {
|
|
1350
|
-
selector: SELECTOR_MENU_ITEM,
|
|
1351
|
-
vertical: true
|
|
1352
|
-
});
|
|
1353
|
-
}
|
|
1354
|
-
function addMenubar(element) {
|
|
1355
|
-
addInstance(menubars, OuiMenubar, element, element, {
|
|
1356
|
-
role: "menubar",
|
|
1357
|
-
selector: SELECTOR_MENUBAR_ITEM,
|
|
1358
|
-
vertical: false
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
function getId$2(element, value) {
|
|
1362
|
-
let { id } = element;
|
|
1363
|
-
if (id == null || id.trim().length === 0) {
|
|
1364
|
-
id = value == null ? `oui_menu_${++index$3}` : `${value}_toggle`;
|
|
1365
|
-
element.id = id;
|
|
1366
|
-
}
|
|
1367
|
-
return id;
|
|
1368
|
-
}
|
|
1369
|
-
function initializeMenu(menu) {
|
|
1370
|
-
const id = getId$2(menu.content);
|
|
1371
|
-
setAttribute(menu.toggle, "popovertarget", id);
|
|
1372
|
-
setAria(menu.toggle, {
|
|
1373
|
-
controls: id,
|
|
1374
|
-
expanded: "false",
|
|
1375
|
-
haspopup: "menu"
|
|
1376
|
-
});
|
|
1377
|
-
setAttributes(menu.content, {
|
|
1378
|
-
popover: "",
|
|
1379
|
-
tabindex: "-1"
|
|
1380
|
-
});
|
|
1381
|
-
setRole(menu.content, "menu");
|
|
1382
|
-
}
|
|
1383
|
-
function onDeactivate(_, navigable) {
|
|
1384
|
-
const menu = menus.get(navigable.element);
|
|
1385
|
-
if (menu == null) return;
|
|
1386
|
-
menu.floatable.hide();
|
|
1387
|
-
const element = findAncestor(menu.element.parentElement, SELECTORS);
|
|
1388
|
-
if (element == null) return;
|
|
1389
|
-
const instance = menubars.get(element) ?? menus.get(element);
|
|
1390
|
-
if (instance != null) updateNavigableFocus(instance.navigable, true);
|
|
1391
|
-
}
|
|
1392
|
-
function onPreventNavigation(_, navigable) {
|
|
1393
|
-
return findAncestor((menubars.get(navigable.element) ?? menus.get(navigable.element))?.element.parentElement, SELECTORS) != null;
|
|
1394
|
-
}
|
|
1395
|
-
function onShouldActivate(event, navigable) {
|
|
1396
|
-
let activate = false;
|
|
1397
|
-
if (menubars.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : NAVIGABLE_KEYS_HORIZONTAL.has(event.key);
|
|
1398
|
-
else if (menus.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : event.key === "ArrowRight";
|
|
1399
|
-
if (activate) {
|
|
1400
|
-
const target = event.target instanceof HTMLElement && event.target.matches(SELECTOR_MENU_TOGGLE) ? event.target : void 0;
|
|
1401
|
-
if (target == null) activate = false;
|
|
1402
|
-
else target.click();
|
|
1403
|
-
}
|
|
1404
|
-
return activate;
|
|
1405
|
-
}
|
|
1406
|
-
function onShouldDeactivate(event, navigable) {
|
|
1407
|
-
if (menubars.has(navigable.element)) return;
|
|
1408
|
-
const menu = menus.get(navigable.element);
|
|
1409
|
-
if (menu == null) return;
|
|
1410
|
-
const horizontal = navigable.orientation === "horizontal";
|
|
1411
|
-
const altKey = horizontal ? "ArrowDown" : "ArrowRight";
|
|
1412
|
-
const baseKey = horizontal ? "ArrowUp" : "ArrowLeft";
|
|
1413
|
-
if (event.key === baseKey) return findAncestor(menu.element.parentElement, SELECTOR_MENU_CONTENT) != null;
|
|
1414
|
-
if (event.key === altKey && event.target instanceof HTMLElement && !event.target.hasAttribute("popovertarget")) return false;
|
|
1415
|
-
}
|
|
1416
|
-
function removeInstance$1(instances, element) {
|
|
1417
|
-
instances.get(element)?.destroy();
|
|
1418
|
-
instances.delete(element);
|
|
1419
|
-
}
|
|
1420
|
-
function removeMenu(element) {
|
|
1421
|
-
removeInstance$1(menus, element);
|
|
1422
|
-
}
|
|
1423
|
-
function removeMenubar(element) {
|
|
1424
|
-
removeInstance$1(menubars, element);
|
|
1425
|
-
}
|
|
1426
|
-
const ATTRIBUTE_MENU = "oui-menu";
|
|
1427
|
-
const ATTRIBUTE_MENU_POSITION = "oui-menu-position";
|
|
1428
|
-
const ATTRIBUTE_MENUBAR = "oui-menubar";
|
|
1429
|
-
const SELECTOR_MENUBAR = `[${ATTRIBUTE_MENUBAR}]`;
|
|
1430
|
-
const SELECTOR_MENUBAR_ITEM = `:scope > [${ATTRIBUTE_MENUBAR}-item], :scope > * > [${ATTRIBUTE_MENUBAR}-item]`;
|
|
1431
|
-
const SELECTOR_MENU_CONTENT = `[${ATTRIBUTE_MENU}-content]`;
|
|
1432
|
-
const SELECTOR_MENU_ITEM = `:scope > [${ATTRIBUTE_MENU}-item], :scope > * > [${ATTRIBUTE_MENU}-item]`;
|
|
1433
|
-
const SELECTOR_MENU_TOGGLE = `[${ATTRIBUTE_MENU}-toggle]`;
|
|
1434
|
-
const SELECTORS = `${SELECTOR_MENUBAR}, ${SELECTOR_MENU_CONTENT}`;
|
|
1435
|
-
const menubars = /* @__PURE__ */ new WeakMap();
|
|
1436
|
-
const menus = /* @__PURE__ */ new WeakMap();
|
|
1437
|
-
let index$3 = 0;
|
|
1438
|
-
attributable(ATTRIBUTE_MENU, addMenu, removeMenu);
|
|
1439
|
-
attributable(ATTRIBUTE_MENUBAR, addMenubar, removeMenubar);
|
|
1440
|
-
//#endregion
|
|
1441
|
-
//#region src/js/toolbar.ts
|
|
1442
|
-
var OuiToolbar = class {
|
|
1443
|
-
#navigable;
|
|
1444
|
-
constructor(navigable) {
|
|
1445
|
-
this.#navigable = navigable;
|
|
1446
|
-
updateNavigableFocus(this.#navigable, false);
|
|
1447
|
-
}
|
|
1448
|
-
destroy() {
|
|
1449
|
-
this.#navigable.destroy();
|
|
1450
|
-
this.#navigable = void 0;
|
|
1451
|
-
}
|
|
1452
|
-
};
|
|
1453
|
-
function addToolbar(element) {
|
|
1454
|
-
if (!instances$1.has(element)) instances$1.set(element, new OuiToolbar(getNavigable(element, {
|
|
1455
|
-
role: "toolbar",
|
|
1456
|
-
selector: SELECTOR$5,
|
|
1457
|
-
vertical: false
|
|
1458
|
-
})));
|
|
1459
|
-
}
|
|
1460
|
-
function removeToolbar(element) {
|
|
1461
|
-
instances$1.get(element)?.destroy();
|
|
1462
|
-
instances$1.delete(element);
|
|
1463
|
-
}
|
|
1464
|
-
const ATTRIBUTE$4 = "oui-toolbar";
|
|
1465
|
-
const SELECTOR$5 = `[${ATTRIBUTE$4}-item]`;
|
|
1466
|
-
const instances$1 = /* @__PURE__ */ new WeakMap();
|
|
1467
|
-
attributable(ATTRIBUTE$4, addToolbar, removeToolbar);
|
|
1468
|
-
//#endregion
|
|
1469
|
-
//#region node_modules/@oscarpalmer/toretto/dist/data.mjs
|
|
1470
|
-
function getData(element, keys, parseValues) {
|
|
1471
|
-
if (!(element instanceof Element)) return;
|
|
1472
|
-
const noParse = parseValues === false;
|
|
1473
|
-
if (typeof keys === "string") return getDataValue(element, keys, noParse);
|
|
1474
|
-
const { length } = keys;
|
|
1475
|
-
const data = {};
|
|
1476
|
-
for (let index = 0; index < length; index += 1) {
|
|
1477
|
-
const key = keys[index];
|
|
1478
|
-
data[key] = getDataValue(element, key, noParse);
|
|
1479
|
-
}
|
|
1480
|
-
return data;
|
|
1481
|
-
}
|
|
1482
|
-
function getDataValue(element, key, noParse) {
|
|
1483
|
-
const value = element.dataset[camelCase(key)];
|
|
1484
|
-
if (value == null) return;
|
|
1485
|
-
if (noParse) return value;
|
|
1486
|
-
return parse(value) ?? value;
|
|
1487
|
-
}
|
|
1488
|
-
function getName(original) {
|
|
1489
|
-
return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original.replace(EXPRESSION_DATA_PREFIX, ""))}`;
|
|
1490
|
-
}
|
|
1491
|
-
function setData(element, first, second) {
|
|
1492
|
-
setElementValues(element, first, second, null, updateDataAttribute);
|
|
1493
|
-
}
|
|
1494
|
-
function updateDataAttribute(element, key, value) {
|
|
1495
|
-
updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, true);
|
|
1496
|
-
}
|
|
1497
|
-
const ATTRIBUTE_DATA_PREFIX = "data-";
|
|
1498
|
-
//#endregion
|
|
1499
|
-
//#region node_modules/@oscarpalmer/toretto/dist/property/set.property.mjs
|
|
1500
|
-
/**
|
|
1501
|
-
* Set the values of one or more properties on an element
|
|
1502
|
-
*
|
|
1503
|
-
* Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
|
|
1504
|
-
*
|
|
1505
|
-
* @param target Target element
|
|
1506
|
-
* @param properties Properties to set
|
|
1507
|
-
* @param dispatch Dispatch events for properties? _(defaults to `true`)_
|
|
1508
|
-
*/
|
|
1509
|
-
function setProperties$1(target, properties, dispatch) {
|
|
1510
|
-
if (!(target instanceof Element) || !isPlainObject(properties)) return;
|
|
1511
|
-
const shouldDispatch = dispatch !== false;
|
|
1512
|
-
const keys = Object.keys(properties);
|
|
1513
|
-
const { length } = keys;
|
|
1514
|
-
for (let index = 0; index < length; index += 1) setPropertyValue(target, keys[index], properties[keys[index]], shouldDispatch);
|
|
1515
|
-
}
|
|
1516
|
-
function setPropertyValue(element, property, value, dispatch) {
|
|
1517
|
-
if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(element, property, value, dispatch);
|
|
1518
|
-
else updateProperty(element, property, value, dispatch);
|
|
1519
|
-
}
|
|
1520
|
-
//#endregion
|
|
1521
|
-
//#region node_modules/@oscarpalmer/toretto/dist/create.mjs
|
|
1522
|
-
function createElement(tag, values) {
|
|
1523
|
-
if (typeof tag !== "string") throw new TypeError(MESSAGE$5);
|
|
1524
|
-
const element = document.createElement(tag);
|
|
1525
|
-
const { aria, attribute, data, property, style } = getElementValues(values);
|
|
1526
|
-
setAria(element, aria ?? {});
|
|
1527
|
-
setAttributes(element, attribute ?? {});
|
|
1528
|
-
setData(element, data ?? {});
|
|
1529
|
-
setProperties$1(element, property ?? {});
|
|
1530
|
-
setStyles(element, style ?? {});
|
|
1531
|
-
return element;
|
|
1532
|
-
}
|
|
1533
|
-
function getElementValues(input) {
|
|
1534
|
-
if (!isPlainObject(input)) return {};
|
|
1535
|
-
return {
|
|
1536
|
-
aria: isPlainObject(input.aria) ? input.aria : void 0,
|
|
1537
|
-
attribute: isPlainObject(input.attribute) ? input.attribute : void 0,
|
|
1538
|
-
data: isPlainObject(input.data) ? input.data : void 0,
|
|
1539
|
-
property: isPlainObject(input.property) ? input.property : void 0,
|
|
1540
|
-
style: isPlainObject(input.style) ? input.style : void 0
|
|
1541
|
-
};
|
|
1542
|
-
}
|
|
1543
|
-
const MESSAGE$5 = "Tag name must be a string";
|
|
1544
|
-
//#endregion
|
|
1545
|
-
//#region src/js/combobox.ts
|
|
1546
|
-
var OuiComboboxElement = class extends HTMLElement {
|
|
1547
|
-
static formAssociated = true;
|
|
1548
|
-
static observedAttributes = [
|
|
1549
|
-
"max",
|
|
1550
|
-
"min",
|
|
1551
|
-
"required",
|
|
1552
|
-
"value"
|
|
1553
|
-
];
|
|
1554
|
-
#internals;
|
|
1555
|
-
#restored;
|
|
1556
|
-
#state;
|
|
1557
|
-
/**
|
|
1558
|
-
* Is the combobox disabled?
|
|
1559
|
-
*/
|
|
1560
|
-
get disabled() {
|
|
1561
|
-
return this.#state?.disabled ?? false;
|
|
1562
|
-
}
|
|
1563
|
-
/**
|
|
1564
|
-
* Should the combobox be disabled?
|
|
1565
|
-
*/
|
|
1566
|
-
set disabled(value) {
|
|
1567
|
-
if (typeof value === "boolean" && value !== this.disabled) setDisabled$1(this.#state, value);
|
|
1568
|
-
}
|
|
1569
|
-
/**
|
|
1570
|
-
* Current filter value
|
|
1571
|
-
*/
|
|
1572
|
-
get filter() {
|
|
1573
|
-
return this.#state.filter.element.value;
|
|
1574
|
-
}
|
|
1575
|
-
/**
|
|
1576
|
-
* Set the filter value
|
|
1577
|
-
*/
|
|
1578
|
-
set filter(value) {
|
|
1579
|
-
setFilter(this.#state, value);
|
|
1580
|
-
}
|
|
1581
|
-
/**
|
|
1582
|
-
* Maximum number of selected options
|
|
1583
|
-
*/
|
|
1584
|
-
get max() {
|
|
1585
|
-
return this.#state?.max;
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* Set the maximum number of selected options
|
|
1589
|
-
*/
|
|
1590
|
-
set max(value) {
|
|
1591
|
-
setLimit("max", this.#state, value);
|
|
1592
|
-
}
|
|
1593
|
-
/**
|
|
1594
|
-
* Minimum number of selected options
|
|
1595
|
-
*/
|
|
1596
|
-
get min() {
|
|
1597
|
-
return this.#state?.min;
|
|
1598
|
-
}
|
|
1599
|
-
/**
|
|
1600
|
-
* Set the minimum number of selected options
|
|
1601
|
-
*/
|
|
1602
|
-
set min(value) {
|
|
1603
|
-
setLimit("min", this.#state, value);
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Does the combobox allow multiple values?
|
|
1607
|
-
*/
|
|
1608
|
-
get multiple() {
|
|
1609
|
-
return this.hasAttribute("multiple");
|
|
1610
|
-
}
|
|
1611
|
-
/**
|
|
1612
|
-
* Name of the combobox
|
|
1613
|
-
*/
|
|
1614
|
-
get name() {
|
|
1615
|
-
return getAttribute(this, "name") ?? "";
|
|
1616
|
-
}
|
|
1617
|
-
/**
|
|
1618
|
-
* Is the combobox readonly?
|
|
1619
|
-
*/
|
|
1620
|
-
get readonly() {
|
|
1621
|
-
return this.#state?.readonly ?? false;
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Should the combobox be readonly?
|
|
1625
|
-
*/
|
|
1626
|
-
set readonly(value) {
|
|
1627
|
-
if (typeof value === "boolean" && value !== this.readonly) setReadonly(this.#state, value);
|
|
1628
|
-
}
|
|
1629
|
-
/**
|
|
1630
|
-
* Is the combobox required?
|
|
1631
|
-
*/
|
|
1632
|
-
get required() {
|
|
1633
|
-
return this.#state?.required ?? false;
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* Should the combobox be required?
|
|
1637
|
-
*/
|
|
1638
|
-
set required(value) {
|
|
1639
|
-
if (typeof value === "boolean" && value !== this.required) setRequired(this.#state, value);
|
|
1640
|
-
}
|
|
1641
|
-
/**
|
|
1642
|
-
* Selected options
|
|
1643
|
-
*/
|
|
1644
|
-
get selected() {
|
|
1645
|
-
return this.#state.options.selected.slice();
|
|
1646
|
-
}
|
|
1647
|
-
/**
|
|
1648
|
-
* Type of combobox
|
|
1649
|
-
*/
|
|
1650
|
-
get type() {
|
|
1651
|
-
return this.#state.type;
|
|
1652
|
-
}
|
|
1653
|
-
/**
|
|
1654
|
-
* Current value
|
|
1655
|
-
*/
|
|
1656
|
-
get value() {
|
|
1657
|
-
return this.#state.values.current[0];
|
|
1658
|
-
}
|
|
1659
|
-
/**
|
|
1660
|
-
* Set the value
|
|
1661
|
-
*/
|
|
1662
|
-
set value(value) {
|
|
1663
|
-
setValue(this.#state, value);
|
|
1664
|
-
}
|
|
1665
|
-
/**
|
|
1666
|
-
* Current values
|
|
1667
|
-
*/
|
|
1668
|
-
get values() {
|
|
1669
|
-
return this.#state.values.current.slice();
|
|
1670
|
-
}
|
|
1671
|
-
/**
|
|
1672
|
-
* Set the values
|
|
1673
|
-
*/
|
|
1674
|
-
set values(value) {
|
|
1675
|
-
setValues(this.#state, value);
|
|
1676
|
-
}
|
|
1677
|
-
constructor() {
|
|
1678
|
-
super();
|
|
1679
|
-
this.#internals = this.attachInternals();
|
|
1680
|
-
}
|
|
1681
|
-
attributeChangedCallback(name, _, value) {
|
|
1682
|
-
if (this.#state == null) return;
|
|
1683
|
-
switch (name) {
|
|
1684
|
-
case "required":
|
|
1685
|
-
this[name] = this.hasAttribute(name);
|
|
1686
|
-
break;
|
|
1687
|
-
case "max":
|
|
1688
|
-
case "min":
|
|
1689
|
-
setLimit(name, this.#state, value);
|
|
1690
|
-
break;
|
|
1691
|
-
case "value":
|
|
1692
|
-
this.value = value ?? "";
|
|
1693
|
-
break;
|
|
1694
|
-
default: break;
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
/**
|
|
1698
|
-
* Clear all selected options
|
|
1699
|
-
*/
|
|
1700
|
-
clear() {
|
|
1701
|
-
setValues(this.#state, []);
|
|
1702
|
-
}
|
|
1703
|
-
connectedCallback() {
|
|
1704
|
-
if (this.#state == null) this.#initialize();
|
|
1705
|
-
else attachCombobox(this.#state);
|
|
1706
|
-
}
|
|
1707
|
-
disconnectedCallback() {
|
|
1708
|
-
if (this.#state != null) detachCombobox(this.#state);
|
|
1709
|
-
}
|
|
1710
|
-
formDisabledCallback(disabled) {
|
|
1711
|
-
this.disabled = disabled;
|
|
1712
|
-
}
|
|
1713
|
-
formResetCallback() {
|
|
1714
|
-
setValues(this.#state, this.#state.values.initial, false);
|
|
1715
|
-
}
|
|
1716
|
-
formStateRestoreCallback(state, reason) {
|
|
1717
|
-
if (reason !== "restore") return;
|
|
1718
|
-
const parsed = typeof state === "string" ? parse(state) : void 0;
|
|
1719
|
-
if (!Array.isArray(parsed)) return;
|
|
1720
|
-
if (this.#state == null) this.#restored = parsed;
|
|
1721
|
-
else setValues(this.#state, parsed);
|
|
1722
|
-
}
|
|
1723
|
-
setLocalizations(first, second) {
|
|
1724
|
-
updateLocalizations(typeof first === "string" ? { [first]: second } : first, this.#state.localizations);
|
|
1725
|
-
}
|
|
1726
|
-
#initialize() {
|
|
1727
|
-
this.tabIndex = -1;
|
|
1728
|
-
this.#state = createState(this, this.#internals);
|
|
1729
|
-
if (this.#restored != null) {
|
|
1730
|
-
setValues(this.#state, this.#restored, false);
|
|
1731
|
-
this.#restored = void 0;
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
|
-
};
|
|
1735
|
-
function applySelection(parameters) {
|
|
1736
|
-
const { added, emit, option, selected, state } = parameters;
|
|
1737
|
-
const { length } = state.options.all;
|
|
1738
|
-
for (let index = 0; index < length; index += 1) {
|
|
1739
|
-
const option = state.options.all[index];
|
|
1740
|
-
setAria(option, "selected", (selected ?? state.options.selected).includes(option));
|
|
1741
|
-
}
|
|
1742
|
-
const values = parameters.values ?? (state.autocomplete.none ? [state.filter.element.value] : (selected ?? state.options.selected).map((option) => getData(option, "value", false) ?? ""));
|
|
1743
|
-
if (values.length === 0) values.push("");
|
|
1744
|
-
if (selected != null) state.options.selected = selected;
|
|
1745
|
-
if (!(values.length === state.values.current.length ? values.some((value) => !state.values.current.includes(value)) : true)) return;
|
|
1746
|
-
updateForm(state, values, emit);
|
|
1747
|
-
updatePreview("set", state, option);
|
|
1748
|
-
updateSelection(state, option, added, selected);
|
|
1749
|
-
}
|
|
1750
|
-
function attachCombobox(state) {
|
|
1751
|
-
const { anchor, content, filter, label, listeners, select } = state;
|
|
1752
|
-
label.element.htmlFor = filter.element.id;
|
|
1753
|
-
label.element.id = `${state.id}_label`;
|
|
1754
|
-
select.hidden = true;
|
|
1755
|
-
select.insertAdjacentElement("afterend", anchor.container ?? anchor.element);
|
|
1756
|
-
(anchor.container ?? anchor.element).insertAdjacentElement("afterend", content);
|
|
1757
|
-
select.remove();
|
|
1758
|
-
state.floatable = createEmbeddedFloatable(anchor.container ?? anchor.element, content, {
|
|
1759
|
-
position: "below-start",
|
|
1760
|
-
reusable: false
|
|
1761
|
-
});
|
|
1762
|
-
state.floatable.update();
|
|
1763
|
-
listeners.push(on(state.host, "focusout", () => {
|
|
1764
|
-
setTimeout(() => {
|
|
1765
|
-
onFocusout$1(state);
|
|
1766
|
-
});
|
|
1767
|
-
}), on(content, "click", (event) => {
|
|
1768
|
-
onClickContent(event, content);
|
|
1769
|
-
}), on(content, "toggle", () => {
|
|
1770
|
-
setAria(anchor.element, "expanded", state.floatable.open);
|
|
1771
|
-
setAria(filter.element, "activedescendant", state.floatable.open ? state.active?.id : void 0);
|
|
1772
|
-
if (state.floatable.open) filter.element.focus();
|
|
1773
|
-
}));
|
|
1774
|
-
states$4.map.set(state.host, state);
|
|
1775
|
-
states$4.map.set(state.content, state);
|
|
1776
|
-
states$4.set.add(state);
|
|
1777
|
-
}
|
|
1778
|
-
function createAnchor(parameters) {
|
|
1779
|
-
const { autocomplete, id, label, select, type } = parameters;
|
|
1780
|
-
let container;
|
|
1781
|
-
let element;
|
|
1782
|
-
let selection;
|
|
1783
|
-
if (parameters.type === "autocomplete") element = createInput({
|
|
1784
|
-
id,
|
|
1785
|
-
label,
|
|
1786
|
-
type,
|
|
1787
|
-
autocomplete: autocomplete.value,
|
|
1788
|
-
value: select.selectedOptions[0]?.textContent ?? ""
|
|
1789
|
-
});
|
|
1790
|
-
else ({container, element, selection} = createButton(parameters));
|
|
1791
|
-
setAttribute(container ?? element, ATTRIBUTE_ANCHOR, "");
|
|
1792
|
-
return {
|
|
1793
|
-
container,
|
|
1794
|
-
element,
|
|
1795
|
-
selection
|
|
1796
|
-
};
|
|
1797
|
-
}
|
|
1798
|
-
function createButton(parameters) {
|
|
1799
|
-
const { id, label, multiple, select } = parameters;
|
|
1800
|
-
const element = createElement("button", {
|
|
1801
|
-
aria: {
|
|
1802
|
-
controls: `${id}_content`,
|
|
1803
|
-
expanded: false,
|
|
1804
|
-
haspopup: "listbox",
|
|
1805
|
-
labelledby: `${label.id} ${id}`
|
|
1806
|
-
},
|
|
1807
|
-
property: {
|
|
1808
|
-
id,
|
|
1809
|
-
textContent: multiple ? "" : select.selectedOptions[0]?.textContent ?? ""
|
|
1810
|
-
}
|
|
1811
|
-
});
|
|
1812
|
-
if (!multiple) return { element };
|
|
1813
|
-
const container = createElement("div");
|
|
1814
|
-
const selection = createSelection(id, select);
|
|
1815
|
-
container.append(selection.container, element);
|
|
1816
|
-
return {
|
|
1817
|
-
container,
|
|
1818
|
-
element,
|
|
1819
|
-
selection
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
function createContent(parameters) {
|
|
1823
|
-
const { autocomplete, id, label, multiple, select, type } = parameters;
|
|
1824
|
-
const element = createElement("div", {
|
|
1825
|
-
aria: { labelledby: label.id },
|
|
1826
|
-
attribute: {
|
|
1827
|
-
[ATTRIBUTE_CONTENT$1]: "",
|
|
1828
|
-
popover: ""
|
|
1829
|
-
},
|
|
1830
|
-
property: {
|
|
1831
|
-
id: `${id}_content`,
|
|
1832
|
-
tabIndex: -1
|
|
1833
|
-
}
|
|
1834
|
-
});
|
|
1835
|
-
const filter = createFilter({
|
|
1836
|
-
id,
|
|
1837
|
-
label,
|
|
1838
|
-
type,
|
|
1839
|
-
autocomplete: autocomplete.value
|
|
1840
|
-
});
|
|
1841
|
-
const list = createList({
|
|
1842
|
-
autocomplete,
|
|
1843
|
-
id,
|
|
1844
|
-
label,
|
|
1845
|
-
multiple,
|
|
1846
|
-
select
|
|
1847
|
-
});
|
|
1848
|
-
const message = createMessage();
|
|
1849
|
-
if (filter != null) element.append(filter.container);
|
|
1850
|
-
element.append(list.element, message);
|
|
1851
|
-
return {
|
|
1852
|
-
element,
|
|
1853
|
-
filter,
|
|
1854
|
-
list,
|
|
1855
|
-
message
|
|
1856
|
-
};
|
|
1857
|
-
}
|
|
1858
|
-
function createFilter(parameters) {
|
|
1859
|
-
const { autocomplete, id, label, type } = parameters;
|
|
1860
|
-
if (type === "autocomplete") return;
|
|
1861
|
-
const container = createElement("div", { attribute: { [ATTRIBUTE_FILTER]: "" } });
|
|
1862
|
-
const element = createInput({
|
|
1863
|
-
autocomplete,
|
|
1864
|
-
id,
|
|
1865
|
-
label,
|
|
1866
|
-
type,
|
|
1867
|
-
value: ""
|
|
1868
|
-
});
|
|
1869
|
-
setAttribute(element, ATTRIBUTE_FILTER_INPUT, "");
|
|
1870
|
-
container.append(element);
|
|
1871
|
-
return {
|
|
1872
|
-
container,
|
|
1873
|
-
element
|
|
1874
|
-
};
|
|
1875
|
-
}
|
|
1876
|
-
function createGroup(parameters) {
|
|
1877
|
-
const { autocomplete, group, groupOptions, selected } = parameters;
|
|
1878
|
-
const element = createElement("li", {
|
|
1879
|
-
aria: { label: group.label },
|
|
1880
|
-
property: { role: "group" }
|
|
1881
|
-
});
|
|
1882
|
-
const list = createElement("ul", { property: { role: "none" } });
|
|
1883
|
-
const header = createHeader(group);
|
|
1884
|
-
element.append(header, list);
|
|
1885
|
-
return {
|
|
1886
|
-
element,
|
|
1887
|
-
header,
|
|
1888
|
-
options: createOptions({
|
|
1889
|
-
autocomplete,
|
|
1890
|
-
list,
|
|
1891
|
-
selected,
|
|
1892
|
-
group: header.id,
|
|
1893
|
-
options: groupOptions
|
|
1894
|
-
})
|
|
1895
|
-
};
|
|
1896
|
-
}
|
|
1897
|
-
function createHeader(group) {
|
|
1898
|
-
return createElement("div", {
|
|
1899
|
-
aria: { hidden: true },
|
|
1900
|
-
attribute: { [ATTRIBUTE_HEADER]: "" },
|
|
1901
|
-
property: {
|
|
1902
|
-
id: group.id,
|
|
1903
|
-
textContent: group.label
|
|
1904
|
-
}
|
|
1905
|
-
});
|
|
1906
|
-
}
|
|
1907
|
-
function createInput(parameters) {
|
|
1908
|
-
const { autocomplete, id, label, type, value } = parameters;
|
|
1909
|
-
return createElement("input", {
|
|
1910
|
-
aria: {
|
|
1911
|
-
autocomplete,
|
|
1912
|
-
controls: `${id}_list`,
|
|
1913
|
-
expanded: type === "select",
|
|
1914
|
-
haspopup: "listbox",
|
|
1915
|
-
labelledby: label.id
|
|
1916
|
-
},
|
|
1917
|
-
attribute: {
|
|
1918
|
-
autocorrect: "off",
|
|
1919
|
-
autocomplete: "off",
|
|
1920
|
-
form: "",
|
|
1921
|
-
spellcheck: "false",
|
|
1922
|
-
type: "text"
|
|
1923
|
-
},
|
|
1924
|
-
property: {
|
|
1925
|
-
id,
|
|
1926
|
-
value,
|
|
1927
|
-
role: "combobox"
|
|
1928
|
-
}
|
|
1929
|
-
});
|
|
1930
|
-
}
|
|
1931
|
-
function createList(parameters) {
|
|
1932
|
-
const { autocomplete, id, label, multiple, select } = parameters;
|
|
1933
|
-
const element = createElement("ul", {
|
|
1934
|
-
aria: {
|
|
1935
|
-
labelledby: label.id,
|
|
1936
|
-
multiselectable: multiple
|
|
1937
|
-
},
|
|
1938
|
-
attribute: {
|
|
1939
|
-
[ATTRIBUTE_LIST]: "",
|
|
1940
|
-
tabindex: -1
|
|
1941
|
-
},
|
|
1942
|
-
property: {
|
|
1943
|
-
id: `${id}_list`,
|
|
1944
|
-
role: "listbox"
|
|
1945
|
-
}
|
|
1946
|
-
});
|
|
1947
|
-
const children = [...select.children];
|
|
1948
|
-
const childrenLength = children.length;
|
|
1949
|
-
const options = [];
|
|
1950
|
-
const selected = [];
|
|
1951
|
-
let groups;
|
|
1952
|
-
for (let childIndex = 0; childIndex < childrenLength; childIndex += 1) {
|
|
1953
|
-
const child = children[childIndex];
|
|
1954
|
-
if (child instanceof HTMLOptionElement) {
|
|
1955
|
-
const option = createOption({
|
|
1956
|
-
autocomplete,
|
|
1957
|
-
index: childIndex,
|
|
1958
|
-
option: child
|
|
1959
|
-
});
|
|
1960
|
-
element.append(option);
|
|
1961
|
-
options.push(option);
|
|
1962
|
-
if (child.selected) selected.push(option);
|
|
1963
|
-
continue;
|
|
1964
|
-
}
|
|
1965
|
-
if (!(child instanceof HTMLOptGroupElement)) continue;
|
|
1966
|
-
const group = createGroup({
|
|
1967
|
-
autocomplete,
|
|
1968
|
-
selected,
|
|
1969
|
-
group: child,
|
|
1970
|
-
groupOptions: [...child.children]
|
|
1971
|
-
});
|
|
1972
|
-
groups ??= [];
|
|
1973
|
-
element.append(group.element, ...group.options);
|
|
1974
|
-
groups.push(group);
|
|
1975
|
-
options.push(...group.options);
|
|
1976
|
-
}
|
|
1977
|
-
return {
|
|
1978
|
-
element,
|
|
1979
|
-
groups,
|
|
1980
|
-
options,
|
|
1981
|
-
selected
|
|
1982
|
-
};
|
|
1983
|
-
}
|
|
1984
|
-
function createMessage() {
|
|
1985
|
-
return createElement("div", {
|
|
1986
|
-
aria: { live: "polite" },
|
|
1987
|
-
attribute: { [ATTRIBUTE_MESSAGE]: "" },
|
|
1988
|
-
property: {
|
|
1989
|
-
hidden: true,
|
|
1990
|
-
role: "status"
|
|
1991
|
-
}
|
|
1992
|
-
});
|
|
1993
|
-
}
|
|
1994
|
-
function createOption(parameters) {
|
|
1995
|
-
const { autocomplete, group, option } = parameters;
|
|
1996
|
-
const item = createElement("li", {
|
|
1997
|
-
aria: { selected: !autocomplete.none && option.selected },
|
|
1998
|
-
attribute: { [ATTRIBUTE_OPTION]: "" },
|
|
1999
|
-
property: {
|
|
2000
|
-
id: option.id,
|
|
2001
|
-
role: "option",
|
|
2002
|
-
textContent: option.textContent
|
|
2003
|
-
}
|
|
2004
|
-
});
|
|
2005
|
-
setData(item, {
|
|
2006
|
-
group,
|
|
2007
|
-
value: option.value
|
|
2008
|
-
});
|
|
2009
|
-
return item;
|
|
2010
|
-
}
|
|
2011
|
-
function createOptions(parameters) {
|
|
2012
|
-
const { autocomplete, group, list, options, selected } = parameters;
|
|
2013
|
-
const items = [];
|
|
2014
|
-
for (let index = 0; index < options.length; index += 1) {
|
|
2015
|
-
const option = options[index];
|
|
2016
|
-
const item = createOption({
|
|
2017
|
-
autocomplete,
|
|
2018
|
-
group,
|
|
2019
|
-
index,
|
|
2020
|
-
option
|
|
2021
|
-
});
|
|
2022
|
-
items.push(item);
|
|
2023
|
-
if (option.selected) selected.push(item);
|
|
2024
|
-
list.append(item);
|
|
2025
|
-
}
|
|
2026
|
-
return items;
|
|
2027
|
-
}
|
|
2028
|
-
function createSelection(id, select) {
|
|
2029
|
-
const container = createElement("ul", {
|
|
2030
|
-
attribute: { [ATTRIBUTE_SELECTION]: "" },
|
|
2031
|
-
property: { id: `${id}_selection` }
|
|
2032
|
-
});
|
|
2033
|
-
const options = [...select.selectedOptions];
|
|
2034
|
-
const items = [];
|
|
2035
|
-
createSelectionItems({
|
|
2036
|
-
container,
|
|
2037
|
-
items,
|
|
2038
|
-
options
|
|
2039
|
-
});
|
|
2040
|
-
const { button } = items[0] ?? {};
|
|
2041
|
-
if (button != null) button.tabIndex = 0;
|
|
2042
|
-
return {
|
|
2043
|
-
items,
|
|
2044
|
-
container
|
|
2045
|
-
};
|
|
2046
|
-
}
|
|
2047
|
-
function createSelectionItem(option, state) {
|
|
2048
|
-
const element = createElement("li");
|
|
2049
|
-
const localization = state == null ? option.textContent : getLocalization("remove", state);
|
|
2050
|
-
const button = createElement("button", {
|
|
2051
|
-
aria: { label: typeof localization === "function" ? localization(option.textContent ?? "", getData(option, "value", false) ?? "") : localization },
|
|
2052
|
-
attribute: {
|
|
2053
|
-
[ATTRIBUTE_SELECTION_ITEM]: "",
|
|
2054
|
-
tabindex: -1
|
|
2055
|
-
},
|
|
2056
|
-
data: { option: option.id }
|
|
2057
|
-
});
|
|
2058
|
-
const icon = createElement("span", {
|
|
2059
|
-
aria: { hidden: true },
|
|
2060
|
-
property: { innerHTML: "×" }
|
|
2061
|
-
});
|
|
2062
|
-
const label = createElement("span", { property: { textContent: option.textContent } });
|
|
2063
|
-
button.append(icon, label);
|
|
2064
|
-
element.append(button);
|
|
2065
|
-
return {
|
|
2066
|
-
button,
|
|
2067
|
-
element
|
|
2068
|
-
};
|
|
2069
|
-
}
|
|
2070
|
-
function createSelectionItems(parameters) {
|
|
2071
|
-
const { container, items, options, state } = parameters;
|
|
2072
|
-
const { length } = options;
|
|
2073
|
-
for (let index = 0; index < length; index += 1) {
|
|
2074
|
-
const option = options[index];
|
|
2075
|
-
const item = createSelectionItem(option, state);
|
|
2076
|
-
container.append(item.element);
|
|
2077
|
-
items.push(item);
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
function createState(element, internals) {
|
|
2081
|
-
const select = element.querySelector("select");
|
|
2082
|
-
if (select == null || select.id === "") throw new Error(MESSAGE_SELECT);
|
|
2083
|
-
const label = element.querySelector(`label[for="${select.id}"]`);
|
|
2084
|
-
if (label == null) throw new Error(MESSAGE_LABEL);
|
|
2085
|
-
element.id = select.id;
|
|
2086
|
-
setAttribute(element, "name", select.name === "" ? select.id : select.name);
|
|
2087
|
-
const disabled = getBooleanAria(element, "disabled") || select.disabled;
|
|
2088
|
-
const multiple = element.multiple || select.multiple;
|
|
2089
|
-
const readonly = getBooleanAria(element, "readonly");
|
|
2090
|
-
const required = getBooleanAria(element, "required") || select.required;
|
|
2091
|
-
const id = getId$1();
|
|
2092
|
-
const type = multiple ? "select" : getAttributeValue(element, "type", TYPES, "select");
|
|
2093
|
-
const autocomplete = getAutoComplete(element, type === "select");
|
|
2094
|
-
const labelId = label.id;
|
|
2095
|
-
label.htmlFor = id;
|
|
2096
|
-
label.id = `${id}_label`;
|
|
2097
|
-
generateIds(id, select);
|
|
2098
|
-
const anchor = createAnchor({
|
|
2099
|
-
autocomplete,
|
|
2100
|
-
id,
|
|
2101
|
-
label,
|
|
2102
|
-
multiple,
|
|
2103
|
-
select,
|
|
2104
|
-
type
|
|
2105
|
-
});
|
|
2106
|
-
const content = createContent({
|
|
2107
|
-
autocomplete,
|
|
2108
|
-
id,
|
|
2109
|
-
label,
|
|
2110
|
-
multiple,
|
|
2111
|
-
select,
|
|
2112
|
-
type
|
|
2113
|
-
});
|
|
2114
|
-
const values = content.list.selected.length === 0 ? [""] : content.list.selected.map((option) => getData(option, "value", false) ?? "");
|
|
2115
|
-
const state = {
|
|
2116
|
-
autocomplete,
|
|
2117
|
-
disabled,
|
|
2118
|
-
id,
|
|
2119
|
-
internals,
|
|
2120
|
-
multiple,
|
|
2121
|
-
readonly,
|
|
2122
|
-
required,
|
|
2123
|
-
select,
|
|
2124
|
-
type,
|
|
2125
|
-
anchor: {
|
|
2126
|
-
container: anchor.container,
|
|
2127
|
-
element: anchor.element
|
|
2128
|
-
},
|
|
2129
|
-
active: content.list.selected[0],
|
|
2130
|
-
content: content.element,
|
|
2131
|
-
filter: {
|
|
2132
|
-
element: content.filter?.element ?? anchor.element,
|
|
2133
|
-
value: ""
|
|
2134
|
-
},
|
|
2135
|
-
floatable: void 0,
|
|
2136
|
-
groups: content.list.groups,
|
|
2137
|
-
host: element,
|
|
2138
|
-
label: {
|
|
2139
|
-
element: label,
|
|
2140
|
-
id: labelId
|
|
2141
|
-
},
|
|
2142
|
-
listeners: [],
|
|
2143
|
-
localizations: {},
|
|
2144
|
-
message: content.message,
|
|
2145
|
-
name: element.name,
|
|
2146
|
-
options: {
|
|
2147
|
-
all: content.list.options,
|
|
2148
|
-
selected: content.list.selected
|
|
2149
|
-
},
|
|
2150
|
-
selection: anchor.selection,
|
|
2151
|
-
values: {
|
|
2152
|
-
current: values.slice(),
|
|
2153
|
-
initial: values.slice()
|
|
2154
|
-
}
|
|
2155
|
-
};
|
|
2156
|
-
attachCombobox(state);
|
|
2157
|
-
setDisabled$1(state, disabled);
|
|
2158
|
-
setLimit("max", state, getAttribute(element, "max"));
|
|
2159
|
-
setLimit("min", state, getAttribute(element, "min"));
|
|
2160
|
-
setReadonly(state, readonly);
|
|
2161
|
-
setRequired(state, required);
|
|
2162
|
-
filterOptions(state);
|
|
2163
|
-
if (content.list.selected.length > 0) updatePreview("set", state, content.list.selected[0]);
|
|
2164
|
-
updateForm(state, state.values.current, false);
|
|
2165
|
-
updateMessage(state, getVisible(state).length);
|
|
2166
|
-
return state;
|
|
2167
|
-
}
|
|
2168
|
-
function detachCombobox(state) {
|
|
2169
|
-
const { content, floatable, host, label, select } = state;
|
|
2170
|
-
const listeners = state.listeners.splice(0);
|
|
2171
|
-
const { length } = listeners;
|
|
2172
|
-
for (let index = 0; index < length; index += 1) listeners[index]();
|
|
2173
|
-
floatable.destroy();
|
|
2174
|
-
const anchor = state.anchor.container ?? state.anchor.element;
|
|
2175
|
-
anchor.insertAdjacentElement("beforebegin", select);
|
|
2176
|
-
anchor.remove();
|
|
2177
|
-
content.remove();
|
|
2178
|
-
label.element.htmlFor = select.id;
|
|
2179
|
-
label.element.id = state.label.id;
|
|
2180
|
-
select.hidden = false;
|
|
2181
|
-
states$4.map.delete(host);
|
|
2182
|
-
states$4.map.delete(content);
|
|
2183
|
-
states$4.set.delete(state);
|
|
2184
|
-
}
|
|
2185
|
-
function filterOptions(state) {
|
|
2186
|
-
function filter(options) {
|
|
2187
|
-
const { length } = options;
|
|
2188
|
-
let count = 0;
|
|
2189
|
-
for (let index = 0; index < length; index += 1) {
|
|
2190
|
-
const option = options[index];
|
|
2191
|
-
option.hidden = !state.autocomplete.none && !option.textContent.toLocaleLowerCase().includes(value);
|
|
2192
|
-
if (!option.hidden) {
|
|
2193
|
-
count += 1;
|
|
2194
|
-
visible.push(option);
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
return count === 0;
|
|
2198
|
-
}
|
|
2199
|
-
const value = state.filter.element.value.toLocaleLowerCase();
|
|
2200
|
-
const visible = [];
|
|
2201
|
-
if (state.groups == null) filter(state.options.all);
|
|
2202
|
-
else {
|
|
2203
|
-
const groupsLength = state.groups.length;
|
|
2204
|
-
for (let groupIndex = 0; groupIndex < groupsLength; groupIndex += 1) {
|
|
2205
|
-
const { element, options } = state.groups[groupIndex];
|
|
2206
|
-
element.hidden = filter(options);
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2209
|
-
updateMessage(state, visible.length);
|
|
2210
|
-
return state.active != null && visible.includes(state.active) ? state.active : visible[0];
|
|
2211
|
-
}
|
|
2212
|
-
function filterOption(state, value, textContent) {
|
|
2213
|
-
const filterTextContent = textContent ?? false;
|
|
2214
|
-
const filter = getString(value).toLocaleLowerCase();
|
|
2215
|
-
filterOptions(state);
|
|
2216
|
-
const { length } = state.options.all;
|
|
2217
|
-
let match;
|
|
2218
|
-
for (let index = 0; index < length; index += 1) {
|
|
2219
|
-
const option = state.options.all[index];
|
|
2220
|
-
if ((filterTextContent ? option.textContent : getData(option, "value", false) ?? "").toLocaleLowerCase() === filter) {
|
|
2221
|
-
match = option;
|
|
2222
|
-
break;
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
return match;
|
|
2226
|
-
}
|
|
2227
|
-
function generateIds(prefix, select) {
|
|
2228
|
-
const elements = [...select.children].flatMap((child) => child instanceof HTMLOptGroupElement ? [child, ...[...child.children].filter((groupChild) => groupChild instanceof HTMLOptionElement)] : child instanceof HTMLOptionElement ? [child] : []);
|
|
2229
|
-
const { length } = elements;
|
|
2230
|
-
for (let index = 0; index < length; index += 1) {
|
|
2231
|
-
const element = elements[index];
|
|
2232
|
-
if (element.id === "") element.id = `${prefix}${element instanceof HTMLOptGroupElement ? "_group_" : "_option_"}${index}`;
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
function getAttributeValue(element, attribute, possible, defaultValue) {
|
|
2236
|
-
const value = getAttribute(element, attribute);
|
|
2237
|
-
return possible.has(value) ? value : defaultValue;
|
|
2238
|
-
}
|
|
2239
|
-
function getAutoComplete(element, select) {
|
|
2240
|
-
let value;
|
|
2241
|
-
if (select) value = "list";
|
|
2242
|
-
else value = getAttributeValue(element, "autocomplete", AUTOCOMPLETES, "none");
|
|
2243
|
-
return {
|
|
2244
|
-
value,
|
|
2245
|
-
both: value === "both",
|
|
2246
|
-
inline: value === "inline",
|
|
2247
|
-
list: value === "list",
|
|
2248
|
-
none: value === "none"
|
|
2249
|
-
};
|
|
2250
|
-
}
|
|
2251
|
-
function getBooleanAria(element, attribute) {
|
|
2252
|
-
const value = getAria(element, attribute);
|
|
2253
|
-
return value === true || value === "true";
|
|
2254
|
-
}
|
|
2255
|
-
function getId$1() {
|
|
2256
|
-
index$2 += 1;
|
|
2257
|
-
return `oui_combobox_${index$2}`;
|
|
2258
|
-
}
|
|
2259
|
-
function getLanguage(state) {
|
|
2260
|
-
return (state.host.closest("[lang]")?.getAttribute("lang") ?? document.documentElement.lang).toLowerCase();
|
|
2261
|
-
}
|
|
2262
|
-
function getLocalization(key, state) {
|
|
2263
|
-
const language = getLanguage(state);
|
|
2264
|
-
const allLocalizations = [state.localizations, LOCALIZATIONS.globals];
|
|
2265
|
-
const { length } = allLocalizations;
|
|
2266
|
-
let localization;
|
|
2267
|
-
let shortLanguage;
|
|
2268
|
-
for (let index = 0; index < length; index += 1) {
|
|
2269
|
-
const localizations = allLocalizations[index];
|
|
2270
|
-
localization = localizations?.[language]?.[key];
|
|
2271
|
-
if (localization != null) break;
|
|
2272
|
-
shortLanguage ??= language.split("-")[0];
|
|
2273
|
-
if (shortLanguage === language) continue;
|
|
2274
|
-
localization = localizations?.[shortLanguage]?.[key];
|
|
2275
|
-
if (localization != null) break;
|
|
2276
|
-
}
|
|
2277
|
-
return localization ?? LOCALIZATIONS.defaults[key];
|
|
2278
|
-
}
|
|
2279
|
-
function getVisible(state) {
|
|
2280
|
-
return state.options.all.filter((option) => !option.hidden);
|
|
2281
|
-
}
|
|
2282
|
-
function hasTextSelection(element) {
|
|
2283
|
-
return element instanceof HTMLInputElement && element.selectionStart !== element.selectionEnd;
|
|
2284
|
-
}
|
|
2285
|
-
function onClickContent(event, content) {
|
|
2286
|
-
const state = states$4.map.get(content);
|
|
2287
|
-
if (state == null) return;
|
|
2288
|
-
if (state.disabled) return;
|
|
2289
|
-
const option = findAncestor(event, SELECTOR_OPTION);
|
|
2290
|
-
if (!(option instanceof HTMLElement)) state.filter.element.focus();
|
|
2291
|
-
else if (state.readonly) updatePreview("set", state, option);
|
|
2292
|
-
else toggleOption(state, option);
|
|
2293
|
-
}
|
|
2294
|
-
function onClickDocument(event) {
|
|
2295
|
-
const combobox = findAncestor(event, TAGNAME$1);
|
|
2296
|
-
const state = states$4.map.get(combobox);
|
|
2297
|
-
if (combobox == null || state == null) return;
|
|
2298
|
-
const label = findAncestor(event, "label");
|
|
2299
|
-
if (label != null) {
|
|
2300
|
-
if (label === state.label.element && combobox.type === "select") {
|
|
2301
|
-
state.anchor.element.focus();
|
|
2302
|
-
if (!state.disabled) state.floatable.show();
|
|
2303
|
-
}
|
|
2304
|
-
return;
|
|
2305
|
-
}
|
|
2306
|
-
const selection = findAncestor(event, `[${ATTRIBUTE_SELECTION_ITEM}]`);
|
|
2307
|
-
if (selection != null) {
|
|
2308
|
-
const option = state.options.selected.find((option) => option.id === getData(selection, "option", false));
|
|
2309
|
-
if (state.disabled) state.anchor.element.focus();
|
|
2310
|
-
else if (state.readonly) updateTabindices(state, option);
|
|
2311
|
-
else toggleOption(state, option);
|
|
2312
|
-
return;
|
|
2313
|
-
}
|
|
2314
|
-
if (findAncestor(event, SELECTOR_ANCHOR) != null && !state.disabled) {
|
|
2315
|
-
state.floatable.show();
|
|
2316
|
-
return;
|
|
2317
|
-
}
|
|
2318
|
-
}
|
|
2319
|
-
function onEnter(state) {
|
|
2320
|
-
if (state.disabled || state.readonly) return;
|
|
2321
|
-
if (hasTextSelection(state.anchor.element)) onSelection(state);
|
|
2322
|
-
else toggleOption(state, state.active);
|
|
2323
|
-
}
|
|
2324
|
-
function onEscape$1(state) {
|
|
2325
|
-
state.floatable.hide();
|
|
2326
|
-
}
|
|
2327
|
-
function onFilter(type, state, manual, emit) {
|
|
2328
|
-
if (state.disabled || state.readonly) return;
|
|
2329
|
-
const diff = state.filter.value !== state.filter.element.value;
|
|
2330
|
-
if (!state.autocomplete.inline && state.filter.element.value.length > 0 && !(manual ?? false)) state.floatable.show();
|
|
2331
|
-
const option = state.autocomplete.none ? state.active ?? state.options.all[0] : filterOptions(state);
|
|
2332
|
-
let update;
|
|
2333
|
-
if (type.includes("delete")) update = "none";
|
|
2334
|
-
else if (type.includes("insert")) update = "typed";
|
|
2335
|
-
if (update != null) if (state.autocomplete.none) applySelection({
|
|
2336
|
-
state,
|
|
2337
|
-
added: false,
|
|
2338
|
-
emit: (emit ?? true) && diff
|
|
2339
|
-
});
|
|
2340
|
-
else updatePreview(update, state, option);
|
|
2341
|
-
if (diff) {
|
|
2342
|
-
state.filter.value = state.filter.element.value;
|
|
2343
|
-
dispatch(state.host, "input");
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
function onFocusout$1(state) {
|
|
2347
|
-
if (state.disabled || state.readonly || state.type === "select" || state.host === document.activeElement || state.host.contains(document.activeElement)) return;
|
|
2348
|
-
const option = filterOption(state, state.filter.element.value, true);
|
|
2349
|
-
applySelection({
|
|
2350
|
-
option,
|
|
2351
|
-
state,
|
|
2352
|
-
added: false,
|
|
2353
|
-
selected: option == null ? [] : [option]
|
|
2354
|
-
});
|
|
2355
|
-
}
|
|
2356
|
-
function onInput(event) {
|
|
2357
|
-
const combobox = findAncestor(event, TAGNAME$1);
|
|
2358
|
-
const state = states$4.map.get(combobox);
|
|
2359
|
-
if (combobox != null && state != null && event.target === state.filter.element) onFilter(event.inputType, state);
|
|
2360
|
-
}
|
|
2361
|
-
function onKeydown$4(event) {
|
|
2362
|
-
const combobox = findAncestor(event, TAGNAME$1);
|
|
2363
|
-
const state = states$4.map.get(combobox);
|
|
2364
|
-
if (combobox == null || state == null) return;
|
|
2365
|
-
const item = findAncestor(event, SELECTOR_SELECTION_ITEM);
|
|
2366
|
-
if (item instanceof HTMLElement) {
|
|
2367
|
-
onKeydownSelection(event, state, item);
|
|
2368
|
-
return;
|
|
2369
|
-
}
|
|
2370
|
-
onKeydownFilter(event, state);
|
|
2371
|
-
}
|
|
2372
|
-
function onKeydownFilter(event, state) {
|
|
2373
|
-
const ignore = state.disabled || state.readonly;
|
|
2374
|
-
const isSelect = state.type === "select";
|
|
2375
|
-
let preventDefault = ignore;
|
|
2376
|
-
switch (true) {
|
|
2377
|
-
case event.key === " ":
|
|
2378
|
-
if (!state.disabled) state.floatable.show();
|
|
2379
|
-
break;
|
|
2380
|
-
case event.key === "Enter":
|
|
2381
|
-
preventDefault = state.floatable.open;
|
|
2382
|
-
if (preventDefault) onEnter(state);
|
|
2383
|
-
else if (!ignore && state.type === "select") state.floatable.show();
|
|
2384
|
-
else if (!ignore) state.internals.form?.requestSubmit();
|
|
2385
|
-
break;
|
|
2386
|
-
case event.key === "Escape":
|
|
2387
|
-
preventDefault = false;
|
|
2388
|
-
onEscape$1(state);
|
|
2389
|
-
break;
|
|
2390
|
-
case !isSelect && KEYS_SELECTION.has(event.key):
|
|
2391
|
-
if (!ignore && hasTextSelection(state.anchor.element)) onSelection(state);
|
|
2392
|
-
break;
|
|
2393
|
-
case KEYS_NAVIGATION.has(event.key):
|
|
2394
|
-
if (!state.disabled) onNavigation(event, state);
|
|
2395
|
-
break;
|
|
2396
|
-
default:
|
|
2397
|
-
preventDefault = false;
|
|
2398
|
-
if (event.key === "Tab") onTab$1(state);
|
|
2399
|
-
break;
|
|
2400
|
-
}
|
|
2401
|
-
if (preventDefault) {
|
|
2402
|
-
event.preventDefault();
|
|
2403
|
-
event.stopPropagation();
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
function onKeydownSelection(event, state, item) {
|
|
2407
|
-
if (KEYS_ACTIVATION.has(event.key)) {
|
|
2408
|
-
event.preventDefault();
|
|
2409
|
-
onRemoveSelection(state, item);
|
|
2410
|
-
return;
|
|
2411
|
-
}
|
|
2412
|
-
if (state.disabled || state.selection == null) return;
|
|
2413
|
-
const { length } = state.selection.items;
|
|
2414
|
-
const index = state.selection.items.findIndex((selection) => selection.button === item);
|
|
2415
|
-
let next;
|
|
2416
|
-
switch (event.key) {
|
|
2417
|
-
case "ArrowDown":
|
|
2418
|
-
state.anchor.element.focus();
|
|
2419
|
-
state.anchor.element.click();
|
|
2420
|
-
return;
|
|
2421
|
-
case "ArrowRight":
|
|
2422
|
-
case "ArrowLeft":
|
|
2423
|
-
next = clamp(index + (event.key === "ArrowRight" ? 1 : -1), 0, length - 1, true);
|
|
2424
|
-
break;
|
|
2425
|
-
case "End":
|
|
2426
|
-
next = length - 1;
|
|
2427
|
-
break;
|
|
2428
|
-
case "Home":
|
|
2429
|
-
next = 0;
|
|
2430
|
-
break;
|
|
2431
|
-
default: break;
|
|
2432
|
-
}
|
|
2433
|
-
if (next == null) return;
|
|
2434
|
-
event.preventDefault();
|
|
2435
|
-
for (let index = 0; index < length; index += 1) {
|
|
2436
|
-
const { button } = state.selection.items[index];
|
|
2437
|
-
const selected = index === next;
|
|
2438
|
-
button.tabIndex = selected ? 0 : -1;
|
|
2439
|
-
if (selected) button.focus();
|
|
2440
|
-
}
|
|
2441
|
-
}
|
|
2442
|
-
function onNavigation(event, state) {
|
|
2443
|
-
let skip = false;
|
|
2444
|
-
if (!state.floatable.open) {
|
|
2445
|
-
skip = true;
|
|
2446
|
-
state.floatable.show();
|
|
2447
|
-
}
|
|
2448
|
-
const visible = getVisible(state);
|
|
2449
|
-
if (visible.length === 0) return;
|
|
2450
|
-
let next;
|
|
2451
|
-
if (skip || state.active == null) next = state.active ?? visible.at(event.key === "ArrowDown" ? 0 : -1);
|
|
2452
|
-
else {
|
|
2453
|
-
const current = visible.findIndex((option) => option.id === state.active?.id);
|
|
2454
|
-
let index;
|
|
2455
|
-
switch (event.key) {
|
|
2456
|
-
case "ArrowDown":
|
|
2457
|
-
case "ArrowUp":
|
|
2458
|
-
index = clamp(current + (event.key === "ArrowDown" ? 1 : -1), 0, visible.length - 1, true);
|
|
2459
|
-
break;
|
|
2460
|
-
case "End":
|
|
2461
|
-
index = visible.length - 1;
|
|
2462
|
-
break;
|
|
2463
|
-
case "Home":
|
|
2464
|
-
index = 0;
|
|
2465
|
-
break;
|
|
2466
|
-
case "PageDown":
|
|
2467
|
-
case "PageUp":
|
|
2468
|
-
index = clamp(current + (event.key === "PageDown" ? 10 : -10), 0, visible.length - 1);
|
|
2469
|
-
break;
|
|
2470
|
-
default: break;
|
|
2471
|
-
}
|
|
2472
|
-
if (index != null) next = visible[index];
|
|
2473
|
-
}
|
|
2474
|
-
let preview;
|
|
2475
|
-
if (state.type === "autocomplete" && (state.autocomplete.both || state.autocomplete.inline)) preview = "set";
|
|
2476
|
-
else preview = "none";
|
|
2477
|
-
updatePreview(preview, state, next ?? state.active ?? visible[0]);
|
|
2478
|
-
}
|
|
2479
|
-
function onRemoveSelection(state, item) {
|
|
2480
|
-
if (state.disabled || state.readonly) return;
|
|
2481
|
-
const option = state.options.selected.find((option) => option.id === getData(item, "option", false));
|
|
2482
|
-
if (option != null) toggleOption(state, option);
|
|
2483
|
-
}
|
|
2484
|
-
function onSelection(state) {
|
|
2485
|
-
state.filter.value = state.anchor.element === state.filter.element ? state.filter.element.value : "";
|
|
2486
|
-
filterOptions(state);
|
|
2487
|
-
toggleOption(state, state.active);
|
|
2488
|
-
}
|
|
2489
|
-
function onTab$1(state) {
|
|
2490
|
-
setTimeout(() => {
|
|
2491
|
-
if (state.host === document.activeElement) return;
|
|
2492
|
-
if (state.selection?.container.contains(document.activeElement) || !state.host.contains(document.activeElement)) state.floatable.hide();
|
|
2493
|
-
});
|
|
2494
|
-
}
|
|
2495
|
-
function setDisabled$1(state, value) {
|
|
2496
|
-
state.filter.element.readOnly = state.readonly || value;
|
|
2497
|
-
setProperties("disabled", state, value);
|
|
2498
|
-
}
|
|
2499
|
-
function setFilter(state, value) {
|
|
2500
|
-
if (typeof value !== "string") return;
|
|
2501
|
-
const type = value.length < state.filter.element.value.length ? "deleteContentBackward" : "insertText";
|
|
2502
|
-
state.filter.element.value = value;
|
|
2503
|
-
onFilter(type, state);
|
|
2504
|
-
}
|
|
2505
|
-
function setLimit(type, state, value) {
|
|
2506
|
-
let actual = value;
|
|
2507
|
-
if (typeof actual === "string") actual = Number.parseInt(actual, 10);
|
|
2508
|
-
if (typeof actual === "number" && !Number.isNaN(actual) && actual >= 0 ? actual !== state[type] : actual == null) {
|
|
2509
|
-
state[type] = actual;
|
|
2510
|
-
setAttribute(state.host, type, actual);
|
|
2511
|
-
updateValidity(state);
|
|
2512
|
-
}
|
|
2513
|
-
}
|
|
2514
|
-
function setLocalizations(first, second) {
|
|
2515
|
-
updateLocalizations(typeof first === "string" ? { [first]: second } : first);
|
|
2516
|
-
}
|
|
2517
|
-
function setProperties(key, state, value) {
|
|
2518
|
-
state[key] = value;
|
|
2519
|
-
const elements = [
|
|
2520
|
-
state.host,
|
|
2521
|
-
state.anchor.element,
|
|
2522
|
-
state.filter.element
|
|
2523
|
-
];
|
|
2524
|
-
const { length } = elements;
|
|
2525
|
-
for (let index = 0; index < length; index += 1) {
|
|
2526
|
-
const element = elements[index];
|
|
2527
|
-
setAria(element, key, key !== "readonly" || !(element instanceof HTMLButtonElement) ? value : void 0);
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
function setReadonly(state, value) {
|
|
2531
|
-
state.filter.element.readOnly = state.disabled || value;
|
|
2532
|
-
setProperties("readonly", state, value);
|
|
2533
|
-
}
|
|
2534
|
-
function setRequired(state, value) {
|
|
2535
|
-
setProperties("required", state, value);
|
|
2536
|
-
updateValidity(state);
|
|
2537
|
-
}
|
|
2538
|
-
function setValue(state, value, emit) {
|
|
2539
|
-
if (state.autocomplete.none) {
|
|
2540
|
-
state.filter.element.value = getString(value);
|
|
2541
|
-
onFilter("insertText", state, true, emit);
|
|
2542
|
-
return;
|
|
2543
|
-
}
|
|
2544
|
-
if (filterOption(state, value) != null) setValues(state, [value], emit);
|
|
2545
|
-
}
|
|
2546
|
-
function setValues(state, value, emit) {
|
|
2547
|
-
if (!Array.isArray(value)) return;
|
|
2548
|
-
const values = (state.multiple ? value : value.slice(0, 1)).map((value) => getString(value).toLocaleLowerCase());
|
|
2549
|
-
if (values.length === 0) values.push("");
|
|
2550
|
-
if (state.autocomplete.none) {
|
|
2551
|
-
setValue(state, values[0], emit);
|
|
2552
|
-
return;
|
|
2553
|
-
}
|
|
2554
|
-
const { length } = state.options.all;
|
|
2555
|
-
const selected = [];
|
|
2556
|
-
for (let index = 0; index < length; index += 1) {
|
|
2557
|
-
const option = state.options.all[index];
|
|
2558
|
-
if (values.includes(getData(option, "value", false)?.toLocaleLowerCase() ?? "")) selected.push(option);
|
|
2559
|
-
}
|
|
2560
|
-
applySelection({
|
|
2561
|
-
emit,
|
|
2562
|
-
selected,
|
|
2563
|
-
state,
|
|
2564
|
-
added: true,
|
|
2565
|
-
option: selected[0] ?? state.options.all[0],
|
|
2566
|
-
values: state.autocomplete.none ? values : void 0
|
|
2567
|
-
});
|
|
2568
|
-
}
|
|
2569
|
-
function toggleOption(state, option) {
|
|
2570
|
-
if (option == null || !state.multiple && state.options.selected.includes(option)) {
|
|
2571
|
-
state.floatable.hide();
|
|
2572
|
-
return;
|
|
2573
|
-
}
|
|
2574
|
-
const selected = state.options.selected.slice();
|
|
2575
|
-
let added = true;
|
|
2576
|
-
if (state.multiple) {
|
|
2577
|
-
const index = selected.indexOf(option);
|
|
2578
|
-
if (index === -1) selected.push(option);
|
|
2579
|
-
else {
|
|
2580
|
-
added = false;
|
|
2581
|
-
selected.splice(index, 1);
|
|
2582
|
-
}
|
|
2583
|
-
} else selected.splice(0, selected.length, option);
|
|
2584
|
-
applySelection({
|
|
2585
|
-
added,
|
|
2586
|
-
option,
|
|
2587
|
-
selected,
|
|
2588
|
-
state,
|
|
2589
|
-
values: state.autocomplete.none && option != null ? [option.textContent] : void 0
|
|
2590
|
-
});
|
|
2591
|
-
if (!state.multiple) state.floatable.hide();
|
|
2592
|
-
}
|
|
2593
|
-
function updateAnchor(state) {
|
|
2594
|
-
if (!state.multiple) return;
|
|
2595
|
-
const localization = getLocalization("selected", state);
|
|
2596
|
-
setAria(state.anchor.element, "label", typeof localization === "function" ? localization(state.options.selected.length) : localization.replace("{amount}", state.options.selected.length.toString()));
|
|
2597
|
-
}
|
|
2598
|
-
function updateAutocomplete(preview, state, active) {
|
|
2599
|
-
if (state.multiple) return;
|
|
2600
|
-
const content = active?.textContent ?? state.filter.element.value;
|
|
2601
|
-
if (preview === "typed" && !content.toLocaleLowerCase().startsWith(state.filter.element.value.toLocaleLowerCase())) return;
|
|
2602
|
-
if (state.anchor.element instanceof HTMLInputElement) {
|
|
2603
|
-
const contentLength = content.length;
|
|
2604
|
-
const filterLength = state.filter.element.value.length;
|
|
2605
|
-
if (preview === "set" || preview === "typed") {
|
|
2606
|
-
state.anchor.element.value = content;
|
|
2607
|
-
state.anchor.element.setSelectionRange(preview === "typed" ? filterLength : contentLength, contentLength);
|
|
2608
|
-
}
|
|
2609
|
-
} else state.anchor.element.textContent = content;
|
|
2610
|
-
}
|
|
2611
|
-
function updateForm(state, values, emit) {
|
|
2612
|
-
let value;
|
|
2613
|
-
if (state.multiple) {
|
|
2614
|
-
const { length } = values;
|
|
2615
|
-
value = new FormData();
|
|
2616
|
-
for (let index = 0; index < length; index += 1) value.append(state.name, values[index]);
|
|
2617
|
-
} else value = values[0];
|
|
2618
|
-
state.values.current = values;
|
|
2619
|
-
state.internals.setFormValue(value, JSON.stringify(values));
|
|
2620
|
-
updateAnchor(state);
|
|
2621
|
-
updateValidity(state);
|
|
2622
|
-
if (emit ?? true) dispatch(state.host, "change");
|
|
2623
|
-
}
|
|
2624
|
-
function updateLocalizations(values, destination) {
|
|
2625
|
-
if (typeof values !== "object" || values == null) return;
|
|
2626
|
-
const localizations = destination ?? LOCALIZATIONS.globals;
|
|
2627
|
-
const languages = Object.keys(values);
|
|
2628
|
-
const languagesLength = languages.length;
|
|
2629
|
-
let updated = false;
|
|
2630
|
-
for (let languagesIndex = 0; languagesIndex < languagesLength; languagesIndex += 1) {
|
|
2631
|
-
const language = languages[languagesIndex];
|
|
2632
|
-
const languageValue = values[language];
|
|
2633
|
-
if (typeof languageValue !== "object" || languageValue == null) continue;
|
|
2634
|
-
const normalizedLanguage = language.toLowerCase();
|
|
2635
|
-
localizations[normalizedLanguage] ??= {};
|
|
2636
|
-
const keys = Object.keys(languageValue);
|
|
2637
|
-
const keysLength = keys.length;
|
|
2638
|
-
for (let keysIndex = 0; keysIndex < keysLength; keysIndex += 1) {
|
|
2639
|
-
const key = keys[keysIndex];
|
|
2640
|
-
const keyValue = languageValue[key];
|
|
2641
|
-
const normalizedKey = key.toLowerCase();
|
|
2642
|
-
if (LOCALIZATIONS.keys.has(normalizedKey) && (typeof keyValue === "string" || typeof keyValue === "function")) {
|
|
2643
|
-
updated = true;
|
|
2644
|
-
localizations[normalizedLanguage][normalizedKey] = keyValue;
|
|
2645
|
-
}
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
if (!updated) return;
|
|
2649
|
-
for (const state of states$4.set) {
|
|
2650
|
-
updateAnchor(state);
|
|
2651
|
-
updateMessage(state, getVisible(state).length);
|
|
2652
|
-
updateSelectionItems(state);
|
|
2653
|
-
}
|
|
2654
|
-
}
|
|
2655
|
-
function updateMessage(state, visible) {
|
|
2656
|
-
setAttribute(state.message, ATTRIBUTE_HIDDEN, visible > 0 ? "" : void 0);
|
|
2657
|
-
if (visible === 0) {
|
|
2658
|
-
const localization = getLocalization("empty", state);
|
|
2659
|
-
state.message.textContent = typeof localization === "function" ? localization() : localization;
|
|
2660
|
-
} else {
|
|
2661
|
-
const localization = getLocalization("results", state);
|
|
2662
|
-
state.message.textContent = typeof localization === "function" ? localization(visible) : localization.replace("{amount}", visible.toString());
|
|
2663
|
-
}
|
|
2664
|
-
state.message.hidden = false;
|
|
2665
|
-
}
|
|
2666
|
-
function updatePreview(preview, state, active) {
|
|
2667
|
-
const { length } = state.options.all;
|
|
2668
|
-
for (let index = 0; index < length; index += 1) {
|
|
2669
|
-
const option = state.options.all[index];
|
|
2670
|
-
setAttribute(option, ATTRIBUTE_OPTION_ACTIVE, option === active ? "" : void 0);
|
|
2671
|
-
}
|
|
2672
|
-
state.active = active;
|
|
2673
|
-
setAria(state.filter.element, "activedescendant", state.floatable.open ? active?.id : void 0);
|
|
2674
|
-
if (state.floatable.open) active?.scrollIntoView(scrollOptions);
|
|
2675
|
-
if (preview !== "none") updateAutocomplete(preview, state, active);
|
|
2676
|
-
}
|
|
2677
|
-
function updateSelection(state, active, added, selected) {
|
|
2678
|
-
if (state.selection == null) return;
|
|
2679
|
-
let options = active == null ? [] : [active];
|
|
2680
|
-
if (selected != null) {
|
|
2681
|
-
options = selected;
|
|
2682
|
-
const { length } = state.selection.items;
|
|
2683
|
-
for (let index = 0; index < length; index += 1) state.selection.items[index].element.remove();
|
|
2684
|
-
state.selection.items.splice(0);
|
|
2685
|
-
}
|
|
2686
|
-
if (added) {
|
|
2687
|
-
createSelectionItems({
|
|
2688
|
-
options,
|
|
2689
|
-
state,
|
|
2690
|
-
container: state.selection.container,
|
|
2691
|
-
items: state.selection.items
|
|
2692
|
-
});
|
|
2693
|
-
return;
|
|
2694
|
-
}
|
|
2695
|
-
let current = state.selection.items.findIndex((item) => getData(item.button, "option", false) === active?.id);
|
|
2696
|
-
if (current === -1) return;
|
|
2697
|
-
state.selection.items[current].element.remove();
|
|
2698
|
-
state.selection.items.splice(current, 1);
|
|
2699
|
-
if (state.selection.items.length === 0) {
|
|
2700
|
-
state.anchor.element.focus();
|
|
2701
|
-
return;
|
|
2702
|
-
}
|
|
2703
|
-
const { length } = state.selection.items;
|
|
2704
|
-
if (current < 0) current = 0;
|
|
2705
|
-
else if (current >= length) current = length - 1;
|
|
2706
|
-
for (let index = 0; index < length; index += 1) {
|
|
2707
|
-
const { button } = state.selection.items[index];
|
|
2708
|
-
button.tabIndex = index === current ? 0 : -1;
|
|
2709
|
-
}
|
|
2710
|
-
state.selection.items[current].button.focus();
|
|
2711
|
-
}
|
|
2712
|
-
function updateSelectionItems(state) {
|
|
2713
|
-
if (state.selection == null) return;
|
|
2714
|
-
const localization = getLocalization("remove", state);
|
|
2715
|
-
const { length } = state.selection.items;
|
|
2716
|
-
for (let index = 0; index < length; index += 1) {
|
|
2717
|
-
const item = state.selection.items[index];
|
|
2718
|
-
const option = state.options.selected.find((option) => option.id === getData(item.button, "option", false));
|
|
2719
|
-
if (option == null) continue;
|
|
2720
|
-
setAria(item.button, "label", typeof localization === "function" ? localization(option?.textContent ?? "", getData(option, "value", false) ?? "") : localization.replace("{label}", option?.textContent ?? ""));
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
function updateTabindices(state, active) {
|
|
2724
|
-
if (active == null || state.selection == null) return;
|
|
2725
|
-
const next = state.selection.items.find((item) => getData(item.button, "option", false) === active.id);
|
|
2726
|
-
if (next == null) return;
|
|
2727
|
-
const { length } = state.selection.items;
|
|
2728
|
-
for (let index = 0; index < length; index += 1) {
|
|
2729
|
-
const item = state.selection.items[index];
|
|
2730
|
-
item.button.tabIndex = item === next ? 0 : -1;
|
|
2731
|
-
}
|
|
2732
|
-
next.button.focus();
|
|
2733
|
-
}
|
|
2734
|
-
function updateValidity(state) {
|
|
2735
|
-
if (state.autocomplete.none) {
|
|
2736
|
-
const valueMissing = state.required && state.filter.element.value.length === 0;
|
|
2737
|
-
const localization = getLocalization("input", state);
|
|
2738
|
-
state.internals.setValidity({ valueMissing }, typeof localization === "function" ? localization() : localization);
|
|
2739
|
-
state.internals.checkValidity();
|
|
2740
|
-
return;
|
|
2741
|
-
}
|
|
2742
|
-
let error;
|
|
2743
|
-
let message;
|
|
2744
|
-
switch (true) {
|
|
2745
|
-
case state.required && state.options.selected.length === 0: {
|
|
2746
|
-
error = "badInput";
|
|
2747
|
-
const localization = getLocalization("input", state);
|
|
2748
|
-
message = typeof localization === "function" ? localization() : localization;
|
|
2749
|
-
break;
|
|
2750
|
-
}
|
|
2751
|
-
case state.multiple && typeof state.max === "number" && state.options.selected.length > state.max: {
|
|
2752
|
-
error = "rangeOverflow";
|
|
2753
|
-
const localization = getLocalization("max", state);
|
|
2754
|
-
message = typeof localization === "function" ? localization(state.max) : localization.replace("{max}", state.max.toString());
|
|
2755
|
-
break;
|
|
2756
|
-
}
|
|
2757
|
-
case state.multiple && typeof state.min === "number" && state.options.selected.length < state.min: {
|
|
2758
|
-
error = "rangeUnderflow";
|
|
2759
|
-
const localization = getLocalization("min", state);
|
|
2760
|
-
message = typeof localization === "function" ? localization(state.min) : localization.replace("{min}", state.min.toString());
|
|
2761
|
-
break;
|
|
2762
|
-
}
|
|
2763
|
-
default: break;
|
|
2764
|
-
}
|
|
2765
|
-
state.internals.setValidity(error == null ? {} : { [error]: true }, message);
|
|
2766
|
-
state.internals.checkValidity();
|
|
2767
|
-
}
|
|
2768
|
-
const TAGNAME$1 = "oui-combobox";
|
|
2769
|
-
const ATTRIBUTE_ANCHOR = `${TAGNAME$1}-anchor`;
|
|
2770
|
-
const ATTRIBUTE_CONTENT$1 = `${TAGNAME$1}-content`;
|
|
2771
|
-
const ATTRIBUTE_FILTER = `${TAGNAME$1}-filter`;
|
|
2772
|
-
const ATTRIBUTE_FILTER_INPUT = `${ATTRIBUTE_FILTER}-input`;
|
|
2773
|
-
const ATTRIBUTE_HEADER = `${TAGNAME$1}-header`;
|
|
2774
|
-
const ATTRIBUTE_HIDDEN = `${TAGNAME$1}-hidden`;
|
|
2775
|
-
const ATTRIBUTE_LIST = `${TAGNAME$1}-list`;
|
|
2776
|
-
const ATTRIBUTE_MESSAGE = `${TAGNAME$1}-message`;
|
|
2777
|
-
const ATTRIBUTE_OPTION = `${TAGNAME$1}-option`;
|
|
2778
|
-
const ATTRIBUTE_OPTION_ACTIVE = `${TAGNAME$1}-option-active`;
|
|
2779
|
-
const ATTRIBUTE_SELECTION = `${TAGNAME$1}-selection`;
|
|
2780
|
-
const ATTRIBUTE_SELECTION_ITEM = `${TAGNAME$1}-selection-item`;
|
|
2781
|
-
const AUTOCOMPLETES = /* @__PURE__ */ new Set([
|
|
2782
|
-
"both",
|
|
2783
|
-
"inline",
|
|
2784
|
-
"list",
|
|
2785
|
-
"none"
|
|
2786
|
-
]);
|
|
2787
|
-
const KEYS_ACTIVATION = /* @__PURE__ */ new Set([
|
|
2788
|
-
" ",
|
|
2789
|
-
"Backspace",
|
|
2790
|
-
"Delete",
|
|
2791
|
-
"Enter"
|
|
2792
|
-
]);
|
|
2793
|
-
const KEYS_NAVIGATION = /* @__PURE__ */ new Set([
|
|
2794
|
-
"ArrowDown",
|
|
2795
|
-
"ArrowUp",
|
|
2796
|
-
"PageDown",
|
|
2797
|
-
"PageUp"
|
|
2798
|
-
]);
|
|
2799
|
-
const KEYS_SELECTION = /* @__PURE__ */ new Set(["ArrowRight", "End"]);
|
|
2800
|
-
const LOCALIZATIONS = {
|
|
2801
|
-
defaults: {
|
|
2802
|
-
empty: "No results found",
|
|
2803
|
-
input: "Please enter a value",
|
|
2804
|
-
invalid: "Please select an option from the list",
|
|
2805
|
-
max: (max) => `Please select fewer options (maximum is ${max})`,
|
|
2806
|
-
min: (min) => `Please select more options (minimum is ${min})`,
|
|
2807
|
-
remove: (label) => `Remove ${label}`,
|
|
2808
|
-
results: (amount) => `${amount} results available`,
|
|
2809
|
-
selected: (amount) => `${amount} selected`
|
|
2810
|
-
},
|
|
2811
|
-
globals: {},
|
|
2812
|
-
keys: /* @__PURE__ */ new Set([
|
|
2813
|
-
"empty",
|
|
2814
|
-
"input",
|
|
2815
|
-
"invalid",
|
|
2816
|
-
"max",
|
|
2817
|
-
"min",
|
|
2818
|
-
"remove",
|
|
2819
|
-
"results",
|
|
2820
|
-
"selected"
|
|
2821
|
-
])
|
|
2822
|
-
};
|
|
2823
|
-
const MESSAGE_LABEL = `<${TAGNAME$1}> must contain a <label> element for the <select> element`;
|
|
2824
|
-
const MESSAGE_SELECT = `<${TAGNAME$1}> must contain a valid <select> element`;
|
|
2825
|
-
const SELECTOR_ANCHOR = `[${ATTRIBUTE_ANCHOR}]`;
|
|
2826
|
-
const SELECTOR_SELECTION_ITEM = `[${ATTRIBUTE_SELECTION_ITEM}]`;
|
|
2827
|
-
const SELECTOR_OPTION = `[${ATTRIBUTE_OPTION}]`;
|
|
2828
|
-
const TYPES = /* @__PURE__ */ new Set(["autocomplete", "select"]);
|
|
2829
|
-
const scrollOptions = {
|
|
2830
|
-
behavior: "auto",
|
|
2831
|
-
block: "nearest",
|
|
2832
|
-
inline: "nearest"
|
|
2833
|
-
};
|
|
2834
|
-
const states$4 = {
|
|
2835
|
-
map: /* @__PURE__ */ new WeakMap(),
|
|
2836
|
-
set: /* @__PURE__ */ new Set()
|
|
2837
|
-
};
|
|
2838
|
-
let index$2 = 0;
|
|
2839
|
-
on(document, "click", onClickDocument);
|
|
2840
|
-
on(document, "input", onInput, { passive: false });
|
|
2841
|
-
on(document, "keydown", onKeydown$4, { passive: false });
|
|
2842
|
-
customElements.define(TAGNAME$1, OuiComboboxElement);
|
|
2843
|
-
//#endregion
|
|
2844
|
-
//#region node_modules/@oscarpalmer/toretto/dist/touch.mjs
|
|
2845
|
-
function getSupport() {
|
|
2846
|
-
if (window == null || navigator == null) return false;
|
|
2847
|
-
if ("matchMedia" in window) {
|
|
2848
|
-
const media = matchMedia?.("(pointer: coarse)");
|
|
2849
|
-
if (typeof media?.matches === "boolean" && media.matches) return true;
|
|
2850
|
-
}
|
|
2851
|
-
if ("ontouchstart" in window) return true;
|
|
2852
|
-
if (typeof navigator.maxTouchPoints === "number" && navigator.maxTouchPoints > 0) return true;
|
|
2853
|
-
if (typeof navigator.msMaxTouchPoints === "number" && navigator.msMaxTouchPoints > 0) return true;
|
|
2854
|
-
return false;
|
|
2855
|
-
}
|
|
2856
|
-
/**
|
|
2857
|
-
* Does the device support touch events?
|
|
2858
|
-
*/
|
|
2859
|
-
const supportsTouch = (() => {
|
|
2860
|
-
let support = getSupport();
|
|
2861
|
-
const instance = Object.create({
|
|
2862
|
-
get() {
|
|
2863
|
-
return support;
|
|
2864
|
-
},
|
|
2865
|
-
update() {
|
|
2866
|
-
support = getSupport();
|
|
2867
|
-
return support;
|
|
2868
|
-
}
|
|
2869
|
-
});
|
|
2870
|
-
Object.defineProperty(instance, "value", { get() {
|
|
2871
|
-
return support;
|
|
2872
|
-
} });
|
|
2873
|
-
return instance;
|
|
2874
|
-
})();
|
|
2875
|
-
//#endregion
|
|
2876
|
-
//#region src/js/internal/draggable.ts
|
|
2877
|
-
var OuiDraggable = class {
|
|
2878
|
-
#destroyed = false;
|
|
2879
|
-
#state;
|
|
2880
|
-
get element() {
|
|
2881
|
-
return this.#state.element;
|
|
2882
|
-
}
|
|
2883
|
-
constructor(name, event, attribute, element, options, extras) {
|
|
2884
|
-
this.#state = {
|
|
2885
|
-
...extras,
|
|
2886
|
-
attribute,
|
|
2887
|
-
element,
|
|
2888
|
-
event,
|
|
2889
|
-
name,
|
|
2890
|
-
options,
|
|
2891
|
-
horizontal: true,
|
|
2892
|
-
vertical: true,
|
|
2893
|
-
styling: toggleStyles(element, styles$1)
|
|
2894
|
-
};
|
|
2895
|
-
const item = {
|
|
2896
|
-
instance: this,
|
|
2897
|
-
state: this.#state
|
|
2898
|
-
};
|
|
2899
|
-
setContainer(item);
|
|
2900
|
-
setDirection(item);
|
|
2901
|
-
setAttribute(element, attribute, "");
|
|
2902
|
-
let states = globals.states.get(element);
|
|
2903
|
-
states ??= {};
|
|
2904
|
-
states[this.#state.name] = this.#state;
|
|
2905
|
-
globals.states.set(element, states);
|
|
2906
|
-
}
|
|
2907
|
-
destroy() {
|
|
2908
|
-
if (this.#destroyed) return;
|
|
2909
|
-
this.#destroyed = true;
|
|
2910
|
-
destroyInstance(this, this.#state);
|
|
2911
|
-
}
|
|
2912
|
-
};
|
|
2913
|
-
function addDraggable(element, options) {
|
|
2914
|
-
let instances = globals.instances.get(element);
|
|
2915
|
-
if (instances == null) {
|
|
2916
|
-
instances = {};
|
|
2917
|
-
globals.instances.set(element, instances);
|
|
2918
|
-
}
|
|
2919
|
-
instances[this.property] ??= new this.constructor(element, options);
|
|
2920
|
-
return instances[this.property];
|
|
2921
|
-
}
|
|
2922
|
-
function cancelDrag(item) {
|
|
2923
|
-
if (item == null) return;
|
|
2924
|
-
item.state.options.drag.onCancel?.(globals, item);
|
|
2925
|
-
dispatch(item.state.element, `${item.state.name}:cancel`, { detail: { element: item.state.options.getOrigin() } });
|
|
2926
|
-
reset();
|
|
2927
|
-
}
|
|
2928
|
-
function destroyInstance(instance, state) {
|
|
2929
|
-
unsetContainer({
|
|
2930
|
-
instance,
|
|
2931
|
-
state
|
|
2932
|
-
});
|
|
2933
|
-
state.element.removeAttribute(state.attribute);
|
|
2934
|
-
state.styling.remove();
|
|
2935
|
-
state.container = void 0;
|
|
2936
|
-
state.element = void 0;
|
|
2937
|
-
state.options = void 0;
|
|
2938
|
-
state.styling = void 0;
|
|
2939
|
-
}
|
|
2940
|
-
function getDraggableStates(element) {
|
|
2941
|
-
return globals.states.get(element);
|
|
2942
|
-
}
|
|
2943
|
-
function getHandle(event, isMovable) {
|
|
2944
|
-
return findAncestor(event, isMovable ? SELECTOR_MOVABLE_HANDLE : SELECTOR_SORTABLE_HANDLE);
|
|
2945
|
-
}
|
|
2946
|
-
function getNextPosition(item, position) {
|
|
2947
|
-
let x = globals.original?.x ?? 0;
|
|
2948
|
-
let y = globals.original?.y ?? 0;
|
|
2949
|
-
if (item.state.horizontal) {
|
|
2950
|
-
x = position.x - (globals.offset?.x ?? 0);
|
|
2951
|
-
if (globals.container != null && globals.element != null) x = clamp(x, globals.container.left, globals.container.right - globals.element.rectangle.width);
|
|
2952
|
-
}
|
|
2953
|
-
if (item.state.vertical) {
|
|
2954
|
-
y = position.y - (globals.offset?.y ?? 0);
|
|
2955
|
-
if (globals.container != null && globals.element != null) y = clamp(y, globals.container.top, globals.container.bottom - globals.element.rectangle.height);
|
|
2956
|
-
}
|
|
2957
|
-
return {
|
|
2958
|
-
x,
|
|
2959
|
-
y
|
|
2960
|
-
};
|
|
2961
|
-
}
|
|
2962
|
-
function onKeydown$3(event) {
|
|
2963
|
-
if (current$1 != null && event.key === KEY_ESCAPE) cancelDrag(current$1);
|
|
2964
|
-
}
|
|
2965
|
-
function onPointerdown$4(event) {
|
|
2966
|
-
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
|
|
2967
|
-
const container = findAncestor(event, SELECTOR$4);
|
|
2968
|
-
const instances = globals.instances.get(container);
|
|
2969
|
-
const states = globals.states.get(container);
|
|
2970
|
-
if (instances == null || states == null) return;
|
|
2971
|
-
const isMovable = container.hasAttribute(ATTRIBUTE_MOVABLE$1);
|
|
2972
|
-
const item = {
|
|
2973
|
-
instance: isMovable ? instances.movable : instances.sortable,
|
|
2974
|
-
state: isMovable ? states.movable : states.sortable
|
|
2975
|
-
};
|
|
2976
|
-
if (item.instance == null || item.state == null) return;
|
|
2977
|
-
if (supportsTouch.value) event.preventDefault();
|
|
2978
|
-
let element = container;
|
|
2979
|
-
if (!isMovable) {
|
|
2980
|
-
element = findAncestor(event, SELECTOR_SORTABLE_ITEM);
|
|
2981
|
-
if (element == null || element.parentElement !== container) return;
|
|
2982
|
-
}
|
|
2983
|
-
let handle = element;
|
|
2984
|
-
item.state.hasHandles ??= element.querySelector(SELECTOR_SORTABLE_HANDLE) != null;
|
|
2985
|
-
if (item.state.hasHandles) handle = getHandle(event, isMovable);
|
|
2986
|
-
if (handle == null) return;
|
|
2987
|
-
const dragged = item.state.options.getDragged();
|
|
2988
|
-
const rectangle = dragged.getBoundingClientRect();
|
|
2989
|
-
const position = getPosition$1(event) ?? {
|
|
2990
|
-
x: 0,
|
|
2991
|
-
y: 0
|
|
2992
|
-
};
|
|
2993
|
-
current$1 = item;
|
|
2994
|
-
globals.container = item.state.container?.getBoundingClientRect();
|
|
2995
|
-
globals.element = {
|
|
2996
|
-
rectangle,
|
|
2997
|
-
node: dragged
|
|
2998
|
-
};
|
|
2999
|
-
globals.offset = item.state.options.position.getOffset(globals, item, element, position);
|
|
3000
|
-
globals.original = item.state.options.position.getOriginal(globals, item, position);
|
|
3001
|
-
const dispatched = dispatch(item.state.element, `${item.state.name}:begin`, { detail: {
|
|
3002
|
-
element,
|
|
3003
|
-
position: { ...globals.original }
|
|
3004
|
-
} });
|
|
3005
|
-
setTimeout(() => {
|
|
3006
|
-
if (dispatched.defaultPrevented) {
|
|
3007
|
-
item.state.options.drag.onCancel?.(globals, item);
|
|
3008
|
-
reset();
|
|
3009
|
-
return;
|
|
3010
|
-
}
|
|
3011
|
-
const next = getNextPosition(item, position);
|
|
3012
|
-
setStyles(dragged, {
|
|
3013
|
-
position: "fixed",
|
|
3014
|
-
inset: `${next.y}px auto auto ${next.x}px`,
|
|
3015
|
-
transform: "translate3d(0, 0, 0)"
|
|
3016
|
-
});
|
|
3017
|
-
item.state.options.drag.onBegin?.(event, globals, item, element, handle, next);
|
|
3018
|
-
item.state.styling.set();
|
|
3019
|
-
styleToggler$1.set();
|
|
3020
|
-
});
|
|
3021
|
-
}
|
|
3022
|
-
function onPointermove$3(event) {
|
|
3023
|
-
if (current$1 == null) return;
|
|
3024
|
-
const position = getPosition$1(event);
|
|
3025
|
-
if (position == null) return;
|
|
3026
|
-
const next = getNextPosition(current$1, position);
|
|
3027
|
-
if (globals.element != null) setStyle(globals.element.node, "inset", `${next.y}px auto auto ${next.x}px`);
|
|
3028
|
-
const detail = current$1.state.options.drag.onMove(event, globals, current$1, {
|
|
3029
|
-
calculated: next,
|
|
3030
|
-
original: position
|
|
3031
|
-
});
|
|
3032
|
-
const dispatched = dispatch(current$1.state.element, `${current$1.state.name}:move`, { detail });
|
|
3033
|
-
setTimeout(() => {
|
|
3034
|
-
if (dispatched.defaultPrevented) cancelDrag(current$1);
|
|
3035
|
-
});
|
|
3036
|
-
}
|
|
3037
|
-
function onPointerup$2(event) {
|
|
3038
|
-
current$1?.state.options.drag.onEnd?.(event, globals, current$1, reset);
|
|
3039
|
-
}
|
|
3040
|
-
function removeDraggable(element) {
|
|
3041
|
-
const { property } = this;
|
|
3042
|
-
removeInstance(globals.instances, property, element);
|
|
3043
|
-
removeInstance(globals.states, property, element);
|
|
3044
|
-
}
|
|
3045
|
-
function removeInstance(map, name, element) {
|
|
3046
|
-
const instances = map.get(element);
|
|
3047
|
-
if (instances == null || instances[name] == null) return;
|
|
3048
|
-
if (typeof instances[name].destroy === "function") instances[name].destroy();
|
|
3049
|
-
instances[name] = void 0;
|
|
3050
|
-
if (instances[properties[name]] == null) map.delete(element);
|
|
3051
|
-
}
|
|
3052
|
-
function reset() {
|
|
3053
|
-
current$1?.state.styling.remove();
|
|
3054
|
-
styleToggler$1.remove();
|
|
3055
|
-
current$1 = void 0;
|
|
3056
|
-
globals.container = void 0;
|
|
3057
|
-
globals.element = void 0;
|
|
3058
|
-
globals.offset = void 0;
|
|
3059
|
-
globals.original = void 0;
|
|
3060
|
-
}
|
|
3061
|
-
function setContainer(item) {
|
|
3062
|
-
const { container } = item.state.options.input ?? {};
|
|
3063
|
-
if (isHTMLOrSVGElement(container)) {
|
|
3064
|
-
setContainerElement(item, container);
|
|
3065
|
-
return;
|
|
3066
|
-
}
|
|
3067
|
-
const selector = container ?? getAttribute(item.instance.element, item.state.options.container.attribute);
|
|
3068
|
-
if (typeof selector !== "string") return;
|
|
3069
|
-
const element = containers.has(selector) ? item.state.element.ownerDocument.body : document.querySelector(selector) ?? void 0;
|
|
3070
|
-
if (isHTMLOrSVGElement(element)) setContainerElement(item, element);
|
|
3071
|
-
}
|
|
3072
|
-
function setContainerElement(item, element) {
|
|
3073
|
-
item.state.container = element;
|
|
3074
|
-
const set = item.state.options.container.map.get(element);
|
|
3075
|
-
if (set == null) item.state.options.container.map.set(element, /* @__PURE__ */ new Set([item.instance]));
|
|
3076
|
-
else set.add(item.instance);
|
|
3077
|
-
item.state.options.container.onInitialize?.(item);
|
|
3078
|
-
}
|
|
3079
|
-
function setDirection(item) {
|
|
3080
|
-
const direction = getAttribute(item.state.element, item.state.options.direction.attribute);
|
|
3081
|
-
if (horizontals.has(direction)) item.state.vertical = false;
|
|
3082
|
-
else if (verticals.has(direction)) item.state.horizontal = false;
|
|
3083
|
-
item.state.options.direction.onAfter?.(item);
|
|
3084
|
-
}
|
|
3085
|
-
function unsetContainer(item) {
|
|
3086
|
-
const { container } = item.state;
|
|
3087
|
-
if (container == null) return;
|
|
3088
|
-
const set = item.state.options.container.map.get(container);
|
|
3089
|
-
let empty = false;
|
|
3090
|
-
if (set != null) {
|
|
3091
|
-
set.delete(item.instance);
|
|
3092
|
-
if (set.size === 0) {
|
|
3093
|
-
empty = true;
|
|
3094
|
-
item.state.options.container.map.delete(container);
|
|
3095
|
-
}
|
|
3096
|
-
}
|
|
3097
|
-
item.state.options.container.onDestroy?.(item, container, empty);
|
|
3098
|
-
}
|
|
3099
|
-
const ATTRIBUTE_MOVABLE$1 = "oui-movable";
|
|
3100
|
-
const ATTRIBUTE_SORTABLE = "oui-sortable";
|
|
3101
|
-
const KEY_ESCAPE = "Escape";
|
|
3102
|
-
const SELECTOR$4 = `[${ATTRIBUTE_MOVABLE$1}], [${ATTRIBUTE_SORTABLE}]`;
|
|
3103
|
-
const SELECTOR_MOVABLE_HANDLE = `[${ATTRIBUTE_MOVABLE$1}-handle]`;
|
|
3104
|
-
const SELECTOR_SORTABLE_HANDLE = `[${ATTRIBUTE_SORTABLE}-handle]`;
|
|
3105
|
-
const SELECTOR_SORTABLE_ITEM = `[${ATTRIBUTE_SORTABLE}] > *`;
|
|
3106
|
-
const containers = /* @__PURE__ */ new Set([
|
|
3107
|
-
"body",
|
|
3108
|
-
"document",
|
|
3109
|
-
"window"
|
|
3110
|
-
]);
|
|
3111
|
-
const horizontals = /* @__PURE__ */ new Set(["horizontal", "x"]);
|
|
3112
|
-
const properties = {
|
|
3113
|
-
movable: "sortable",
|
|
3114
|
-
sortable: "movable"
|
|
3115
|
-
};
|
|
3116
|
-
const globals = {
|
|
3117
|
-
container: void 0,
|
|
3118
|
-
element: void 0,
|
|
3119
|
-
instances: /* @__PURE__ */ new WeakMap(),
|
|
3120
|
-
offset: void 0,
|
|
3121
|
-
original: void 0,
|
|
3122
|
-
states: /* @__PURE__ */ new WeakMap()
|
|
3123
|
-
};
|
|
3124
|
-
const styles$1 = {
|
|
3125
|
-
touchAction: "none",
|
|
3126
|
-
userSelect: "none",
|
|
3127
|
-
webkitUserSelect: "none"
|
|
3128
|
-
};
|
|
3129
|
-
const styleToggler$1 = toggleStyles(document.body, styles$1);
|
|
3130
|
-
const verticals = /* @__PURE__ */ new Set(["vertical", "y"]);
|
|
3131
|
-
let current$1;
|
|
3132
|
-
on(document, "keydown", onKeydown$3);
|
|
3133
|
-
on(document, "mousedown", onPointerdown$4);
|
|
3134
|
-
on(document, "pointermove", onPointermove$3);
|
|
3135
|
-
on(document, "pointerup", onPointerup$2);
|
|
3136
|
-
on(document, "touchcancel", onPointerup$2);
|
|
3137
|
-
on(document, "touchstart", onPointerdown$4, { passive: false });
|
|
3138
|
-
//#endregion
|
|
3139
|
-
//#region src/js/movable/movable.embedded.ts
|
|
3140
|
-
var OuiMovable = class extends OuiDraggable {
|
|
3141
|
-
#element;
|
|
3142
|
-
#style;
|
|
3143
|
-
constructor(element, options) {
|
|
3144
|
-
const style = getStyles(element, ["inset", "position"]);
|
|
3145
|
-
super("movable", "move", ATTRIBUTE_MOVABLE, element, {
|
|
3146
|
-
container: {
|
|
3147
|
-
attribute: ATTRIBUTE_CONTAINER$2,
|
|
3148
|
-
map: CONTAINERS$1,
|
|
3149
|
-
onDestroy: destroyContainer,
|
|
3150
|
-
onInitialize: initializeContainer
|
|
3151
|
-
},
|
|
3152
|
-
direction: {
|
|
3153
|
-
attribute: ATTRIBUTE_DIRECTION$1,
|
|
3154
|
-
onAfter: afterDirection
|
|
3155
|
-
},
|
|
3156
|
-
drag: {
|
|
3157
|
-
onBegin: onBegin$1,
|
|
3158
|
-
onCancel: onCancel$1,
|
|
3159
|
-
onEnd: onEnd$2,
|
|
3160
|
-
onMove: onMove$1
|
|
3161
|
-
},
|
|
3162
|
-
input: options,
|
|
3163
|
-
position: {
|
|
3164
|
-
getOffset: getOffsetPosition$1,
|
|
3165
|
-
getOriginal: getOriginalPosition$1
|
|
3166
|
-
},
|
|
3167
|
-
getDragged() {
|
|
3168
|
-
return element;
|
|
3169
|
-
},
|
|
3170
|
-
getOrigin() {
|
|
3171
|
-
return element;
|
|
3172
|
-
}
|
|
3173
|
-
}, {
|
|
3174
|
-
style,
|
|
3175
|
-
hasHandles: element.querySelector(SELECTOR_HANDLE$2) != null,
|
|
3176
|
-
moved: false
|
|
3177
|
-
});
|
|
3178
|
-
this.#element = element;
|
|
3179
|
-
this.#style = style;
|
|
3180
|
-
}
|
|
3181
|
-
/**
|
|
3182
|
-
* Destroys the _Movable_
|
|
3183
|
-
*/
|
|
3184
|
-
destroy() {
|
|
3185
|
-
MOVED.delete(this);
|
|
3186
|
-
setStyles(this.#element, this.#style);
|
|
3187
|
-
this.#element = void 0;
|
|
3188
|
-
this.#style = void 0;
|
|
3189
|
-
super.destroy();
|
|
3190
|
-
}
|
|
3191
|
-
};
|
|
3192
|
-
function afterDirection(item) {
|
|
3193
|
-
const container = item.state.container?.getBoundingClientRect();
|
|
3194
|
-
if (container != null) setOffset(item.state, container);
|
|
3195
|
-
}
|
|
3196
|
-
/**
|
|
3197
|
-
* Creates _(or retrieves)_ a _OuiMovable_ instance for an element
|
|
3198
|
-
*
|
|
3199
|
-
* @param element Element to make movable
|
|
3200
|
-
* @returns _OuiMovable_ instance
|
|
3201
|
-
*/
|
|
3202
|
-
function createMovable(element, options) {
|
|
3203
|
-
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE$4);
|
|
3204
|
-
return addMovable(element, options);
|
|
3205
|
-
}
|
|
3206
|
-
function destroyContainer(_, container, empty) {
|
|
3207
|
-
if (empty) resizer.unobserve(container);
|
|
3208
|
-
}
|
|
3209
|
-
function getOffsetPosition$1(globals, _, __, position) {
|
|
3210
|
-
return {
|
|
3211
|
-
x: position.x - (globals.element?.rectangle.left ?? 0),
|
|
3212
|
-
y: position.y - (globals.element?.rectangle.top ?? 0)
|
|
3213
|
-
};
|
|
3214
|
-
}
|
|
3215
|
-
function getOriginalPosition$1(globals) {
|
|
3216
|
-
return {
|
|
3217
|
-
x: globals.element?.rectangle.left ?? 0,
|
|
3218
|
-
y: globals.element?.rectangle.top ?? 0
|
|
3219
|
-
};
|
|
3220
|
-
}
|
|
3221
|
-
function initializeContainer(item) {
|
|
3222
|
-
resizer.observe(item.state.container);
|
|
3223
|
-
}
|
|
3224
|
-
function onBegin$1() {}
|
|
3225
|
-
function onCancel$1(globals, item) {
|
|
3226
|
-
const { element, moved, style } = item.state;
|
|
3227
|
-
const { x, y } = globals.original ?? {
|
|
3228
|
-
x: 0,
|
|
3229
|
-
y: 0
|
|
3230
|
-
};
|
|
3231
|
-
if (moved) setStyle(element, "inset", `${y}px auto auto ${x}px`);
|
|
3232
|
-
else setStyles(element, style);
|
|
3233
|
-
element.removeAttribute(ATTRIBUTE_MOVING);
|
|
3234
|
-
}
|
|
3235
|
-
function onEnd$2(event, globals, item, reset) {
|
|
3236
|
-
const movable = item.instance;
|
|
3237
|
-
const state = item.state;
|
|
3238
|
-
state.element.removeAttribute(ATTRIBUTE_MOVING);
|
|
3239
|
-
if (!state.moved) {
|
|
3240
|
-
state.moved = true;
|
|
3241
|
-
if (state.container != null) MOVED.add(movable);
|
|
3242
|
-
}
|
|
3243
|
-
const container = state.container?.getBoundingClientRect();
|
|
3244
|
-
if (container != null) setOffset(state, container);
|
|
3245
|
-
const dispatched = dispatch(state.element, "movable:end", { detail: {
|
|
3246
|
-
from: { ...globals.original },
|
|
3247
|
-
to: getPosition$1(event)
|
|
3248
|
-
} });
|
|
3249
|
-
setTimeout(() => {
|
|
3250
|
-
if (dispatched.defaultPrevented) onCancel$1(globals, item);
|
|
3251
|
-
reset();
|
|
3252
|
-
});
|
|
3253
|
-
}
|
|
3254
|
-
function onMove$1(_, globals, __, position) {
|
|
3255
|
-
setAttribute(globals.element?.node, ATTRIBUTE_MOVING, "");
|
|
3256
|
-
return {
|
|
3257
|
-
from: { ...globals.original },
|
|
3258
|
-
to: { ...position.calculated }
|
|
3259
|
-
};
|
|
3260
|
-
}
|
|
3261
|
-
function onResize(entries) {
|
|
3262
|
-
const { length } = entries;
|
|
3263
|
-
for (let index = 0; index < length; index += 1) {
|
|
3264
|
-
const entry = entries[index];
|
|
3265
|
-
const set = CONTAINERS$1.get(entry.target);
|
|
3266
|
-
if (set == null) continue;
|
|
3267
|
-
for (const movable of set) reposition(movable);
|
|
3268
|
-
}
|
|
3269
|
-
}
|
|
3270
|
-
function onScroll() {
|
|
3271
|
-
for (const moved of MOVED) reposition(moved);
|
|
3272
|
-
}
|
|
3273
|
-
function reposition(movable) {
|
|
3274
|
-
const state = getDraggableStates(movable.element)?.movable;
|
|
3275
|
-
if (state == null || !state.moved || state.container == null) return;
|
|
3276
|
-
const container = state.container.getBoundingClientRect();
|
|
3277
|
-
const x = container.left + (state.offset?.x ?? 0);
|
|
3278
|
-
const y = container.top + (state.offset?.y ?? 0);
|
|
3279
|
-
setStyle(state.element, "inset", `${y}px auto auto ${x}px`);
|
|
3280
|
-
}
|
|
3281
|
-
function setOffset(state, container) {
|
|
3282
|
-
state.offset = {};
|
|
3283
|
-
const element = state.element.getBoundingClientRect();
|
|
3284
|
-
state.offset.y = element.top - container.top;
|
|
3285
|
-
state.offset.x = element.left - container.left;
|
|
3286
|
-
}
|
|
3287
|
-
const ATTRIBUTE_MOVABLE = "oui-movable";
|
|
3288
|
-
const ATTRIBUTE_CONTAINER$2 = `${ATTRIBUTE_MOVABLE}-container`;
|
|
3289
|
-
const ATTRIBUTE_DIRECTION$1 = `${ATTRIBUTE_MOVABLE}-direction`;
|
|
3290
|
-
const ATTRIBUTE_MOVABLE_HANDLE = `${ATTRIBUTE_MOVABLE}-handle`;
|
|
3291
|
-
const ATTRIBUTE_MOVING = `${ATTRIBUTE_MOVABLE}-moving`;
|
|
3292
|
-
const CONTAINERS$1 = /* @__PURE__ */ new Map();
|
|
3293
|
-
const MESSAGE$4 = "The element must be an instance of HTMLElement or SVGElement";
|
|
3294
|
-
const MOVED = /* @__PURE__ */ new Set();
|
|
3295
|
-
const SELECTOR_HANDLE$2 = `[${ATTRIBUTE_MOVABLE_HANDLE}]`;
|
|
3296
|
-
const bound$1 = {
|
|
3297
|
-
constructor: OuiMovable,
|
|
3298
|
-
property: "movable"
|
|
3299
|
-
};
|
|
3300
|
-
const resizer = new ResizeObserver(onResize);
|
|
3301
|
-
const addMovable = addDraggable.bind(bound$1);
|
|
3302
|
-
const removeMovable = removeDraggable.bind(bound$1);
|
|
3303
|
-
on(document, "scroll", onScroll);
|
|
3304
|
-
attributable(ATTRIBUTE_MOVABLE, addMovable, removeMovable);
|
|
3305
|
-
//#endregion
|
|
3306
|
-
//#region src/js/resizable/resizable.embedded.ts
|
|
3307
|
-
var OuiResizable = class {
|
|
3308
|
-
#state;
|
|
3309
|
-
constructor(state) {
|
|
3310
|
-
this.#state = state;
|
|
3311
|
-
}
|
|
3312
|
-
destroy() {
|
|
3313
|
-
destroyResizable(this.#state);
|
|
3314
|
-
}
|
|
3315
|
-
set() {
|
|
3316
|
-
const [width, height] = getAndSetDimensions(this.#state.element, this.#state.options);
|
|
3317
|
-
this.#state.width = width;
|
|
3318
|
-
this.#state.height = height;
|
|
3319
|
-
}
|
|
3320
|
-
reset() {
|
|
3321
|
-
setStyles(this.#state.element, {
|
|
3322
|
-
height: "",
|
|
3323
|
-
width: ""
|
|
3324
|
-
});
|
|
3325
|
-
}
|
|
3326
|
-
};
|
|
3327
|
-
function addResizable(element, options) {
|
|
3328
|
-
let item = items.get(element);
|
|
3329
|
-
if (item == null) {
|
|
3330
|
-
const handle = element.querySelector(SELECTOR_HANDLE_SCOPED);
|
|
3331
|
-
if (!isHTMLOrSVGElement(handle)) return;
|
|
3332
|
-
const state = getState$4(element, handle, options);
|
|
3333
|
-
item = {
|
|
3334
|
-
instance: new OuiResizable(state),
|
|
3335
|
-
state
|
|
3336
|
-
};
|
|
3337
|
-
items.set(element, item);
|
|
3338
|
-
}
|
|
3339
|
-
return item?.instance;
|
|
3340
|
-
}
|
|
3341
|
-
function cancelResize(item) {
|
|
3342
|
-
if (item == null) return;
|
|
3343
|
-
setStyles(item.state.element, {
|
|
3344
|
-
height: `${item.state.height}px`,
|
|
3345
|
-
width: `${item.state.width}px`
|
|
3346
|
-
});
|
|
3347
|
-
resetResizable();
|
|
3348
|
-
dispatch(item.state.element, "resizable:cancel");
|
|
3349
|
-
}
|
|
3350
|
-
/**
|
|
3351
|
-
* Creates _(or retrieves)_ a _OuiResizable_ instance for an element
|
|
3352
|
-
*
|
|
3353
|
-
* @param element Element to make resizable
|
|
3354
|
-
* @returns _OuiResizable_ instance
|
|
3355
|
-
*/
|
|
3356
|
-
function createResizable(element, options) {
|
|
3357
|
-
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE_ELEMENT);
|
|
3358
|
-
if (!isHTMLOrSVGElement(element.querySelector(SELECTOR_HANDLE_SCOPED))) throw new Error(MESSAGE_HANDLE);
|
|
3359
|
-
return addResizable(element, options ?? {});
|
|
3360
|
-
}
|
|
3361
|
-
function destroyResizable(state) {
|
|
3362
|
-
state.element = void 0;
|
|
3363
|
-
state.handle = void 0;
|
|
3364
|
-
}
|
|
3365
|
-
function getAndSetDimensions(element, options, input) {
|
|
3366
|
-
let { height, width } = input ?? element.getBoundingClientRect();
|
|
3367
|
-
if (options.maximumWidth > -1 && width > options.maximumWidth) width = options.maximumWidth;
|
|
3368
|
-
else if (options.minimumWidth > -1 && width < options.minimumWidth) width = options.minimumWidth;
|
|
3369
|
-
if (options.maximumHeight > -1 && height > options.maximumHeight) height = options.maximumHeight;
|
|
3370
|
-
else if (options.minimumHeight > -1 && height < options.minimumHeight) height = options.minimumHeight;
|
|
3371
|
-
if (element.checkVisibility()) setStyles(element, {
|
|
3372
|
-
height: `${height}px`,
|
|
3373
|
-
width: `${width}px`
|
|
3374
|
-
});
|
|
3375
|
-
return [width, height];
|
|
3376
|
-
}
|
|
3377
|
-
function getProperties(element, widthProperty, heightProperty) {
|
|
3378
|
-
const computed = getComputedStyle(element);
|
|
3379
|
-
return [computed[widthProperty], computed[heightProperty]];
|
|
3380
|
-
}
|
|
3381
|
-
function getRestrictions(maximum, minimum) {
|
|
3382
|
-
const [maximumWidth, maximumHeight] = getXAndY.apply(null, typeof maximum === "string" ? [maximum] : maximum);
|
|
3383
|
-
const [minimumWidth, minimumHeight] = getXAndY.apply(null, typeof minimum === "string" ? [minimum] : minimum);
|
|
3384
|
-
if (maximumWidth > -1 && minimumWidth > -1 && maximumWidth <= minimumWidth) throw new Error(MESSAGE_WIDTH);
|
|
3385
|
-
if (maximumHeight > -1 && minimumHeight > -1 && maximumHeight <= minimumHeight) throw new Error(MESSAGE_HEIGHT);
|
|
3386
|
-
return {
|
|
3387
|
-
maximumHeight,
|
|
3388
|
-
maximumWidth,
|
|
3389
|
-
minimumHeight,
|
|
3390
|
-
minimumWidth
|
|
3391
|
-
};
|
|
3392
|
-
}
|
|
3393
|
-
function getState$4(element, handle, input) {
|
|
3394
|
-
setAttribute(element, RESIZABLE_ATTRIBUTE, "");
|
|
3395
|
-
const options = getValidOptions(element, input);
|
|
3396
|
-
const [width, height] = getAndSetDimensions(element, options);
|
|
3397
|
-
return {
|
|
3398
|
-
element,
|
|
3399
|
-
handle,
|
|
3400
|
-
height,
|
|
3401
|
-
options,
|
|
3402
|
-
width,
|
|
3403
|
-
styles: toggleStyles(element, styles)
|
|
3404
|
-
};
|
|
3405
|
-
}
|
|
3406
|
-
function getValidOptions(element, input) {
|
|
3407
|
-
const original = isPlainObject(input) ? input : {};
|
|
3408
|
-
return { ...getRestrictions(input == null ? getAttribute(element, ATTRIBUTE_MAXIMUM) ?? getProperties(element, "maxWidth", "maxHeight") : [original.maximumWidth, original.maximumHeight], input == null ? getAttribute(element, ATTRIBUTE_MINIMUM) ?? getProperties(element, "minWidth", "minHeight") : [original.minimumWidth, original.minimumHeight]) };
|
|
3409
|
-
}
|
|
3410
|
-
function getXAndY(first, second) {
|
|
3411
|
-
const [x, y] = typeof first === "string" && second == null ? first.split(",") : [first, second];
|
|
3412
|
-
let xAsNumber = typeof x === "string" ? Number.parseFloat(x) : getNumber(x);
|
|
3413
|
-
let yAsNumber = typeof y === "string" ? Number.parseFloat(y) : getNumber(y);
|
|
3414
|
-
if (Number.isNaN(xAsNumber) || xAsNumber <= 0) xAsNumber = -1;
|
|
3415
|
-
if (Number.isNaN(yAsNumber) || yAsNumber <= 0) yAsNumber = -1;
|
|
3416
|
-
return [xAsNumber, yAsNumber];
|
|
3417
|
-
}
|
|
3418
|
-
function onKeydown$2(event) {
|
|
3419
|
-
if (current != null && event.key === "Escape") cancelResize(current);
|
|
3420
|
-
}
|
|
3421
|
-
function onPointerdown$3(event) {
|
|
3422
|
-
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
|
|
3423
|
-
const handle = findAncestor(event, SELECTOR_HANDLE$1);
|
|
3424
|
-
const element = handle && findAncestor(handle, SELECTOR$3);
|
|
3425
|
-
const stored = element && items.get(element);
|
|
3426
|
-
const position = getPosition$1(event);
|
|
3427
|
-
if (stored == null || position == null) return;
|
|
3428
|
-
if (supportsTouch.value) event.preventDefault();
|
|
3429
|
-
const dispatched = dispatch(element, "resizable:begin");
|
|
3430
|
-
setTimeout(() => {
|
|
3431
|
-
if (dispatched.defaultPrevented) return;
|
|
3432
|
-
current = stored;
|
|
3433
|
-
start = position;
|
|
3434
|
-
current.state.styles.set();
|
|
3435
|
-
styleToggler.set();
|
|
3436
|
-
});
|
|
3437
|
-
}
|
|
3438
|
-
function onPointermove$2(event) {
|
|
3439
|
-
if (current == null) return;
|
|
3440
|
-
const { x, y } = getPosition$1(event) ?? {};
|
|
3441
|
-
if (x == null || y == null) return;
|
|
3442
|
-
const width = current.state.width + (x - (start?.x ?? 0));
|
|
3443
|
-
const height = current.state.height + (y - (start?.y ?? 0));
|
|
3444
|
-
getAndSetDimensions(current.state.element, current.state.options, {
|
|
3445
|
-
height,
|
|
3446
|
-
width
|
|
3447
|
-
});
|
|
3448
|
-
const dispatched = dispatch(current.state.element, "resizable:resize", { detail: {
|
|
3449
|
-
height,
|
|
3450
|
-
width
|
|
3451
|
-
} });
|
|
3452
|
-
setTimeout(() => {
|
|
3453
|
-
if (dispatched.defaultPrevented) cancelResize(current);
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
|
-
function onPointerup$1() {
|
|
3457
|
-
if (current == null) return;
|
|
3458
|
-
const dispatched = dispatch(current.state.element, "resizable:end");
|
|
3459
|
-
setTimeout(() => {
|
|
3460
|
-
if (current == null || dispatched.defaultPrevented) {
|
|
3461
|
-
cancelResize(current);
|
|
3462
|
-
return;
|
|
3463
|
-
}
|
|
3464
|
-
const { height, width } = current.state.element.getBoundingClientRect();
|
|
3465
|
-
current.state.height = height;
|
|
3466
|
-
current.state.width = width;
|
|
3467
|
-
resetResizable();
|
|
3468
|
-
});
|
|
3469
|
-
}
|
|
3470
|
-
function removeResizable(element) {
|
|
3471
|
-
items.get(element)?.instance.destroy();
|
|
3472
|
-
items.delete(element);
|
|
3473
|
-
}
|
|
3474
|
-
function resetResizable() {
|
|
3475
|
-
current?.state.styles.remove();
|
|
3476
|
-
styleToggler.remove();
|
|
3477
|
-
current = void 0;
|
|
3478
|
-
start = void 0;
|
|
3479
|
-
}
|
|
3480
|
-
const RESIZABLE_ATTRIBUTE = "oui-resizable";
|
|
3481
|
-
const RESIZABLE_ATTRIBUTE_HANDLE = `${RESIZABLE_ATTRIBUTE}-handle`;
|
|
3482
|
-
const ATTRIBUTE_MAXIMUM = `${RESIZABLE_ATTRIBUTE}-maximum`;
|
|
3483
|
-
const ATTRIBUTE_MINIMUM = `${RESIZABLE_ATTRIBUTE}-minimum`;
|
|
3484
|
-
const MESSAGE_ELEMENT = "The element must be an instance of HTMLElement or SVGElement";
|
|
3485
|
-
const MESSAGE_HEIGHT = "The maximum height must be greater than the minimum height";
|
|
3486
|
-
const MESSAGE_HANDLE = `The element must contain a child with the attribute "${RESIZABLE_ATTRIBUTE_HANDLE}"`;
|
|
3487
|
-
const MESSAGE_WIDTH = "The maximum width must be greater than the minimum width";
|
|
3488
|
-
const SELECTOR$3 = `[${RESIZABLE_ATTRIBUTE}]`;
|
|
3489
|
-
const SELECTOR_HANDLE$1 = `[${RESIZABLE_ATTRIBUTE_HANDLE}]`;
|
|
3490
|
-
const SELECTOR_HANDLE_SCOPED = `:scope > ${SELECTOR_HANDLE$1}`;
|
|
3491
|
-
const items = /* @__PURE__ */ new WeakMap();
|
|
3492
|
-
const styles = {
|
|
3493
|
-
touchAction: "none",
|
|
3494
|
-
userSelect: "none",
|
|
3495
|
-
webkitUserSelect: "none"
|
|
3496
|
-
};
|
|
3497
|
-
const styleToggler = toggleStyles(document.body, styles);
|
|
3498
|
-
let current;
|
|
3499
|
-
let start;
|
|
3500
|
-
on(document, "keydown", onKeydown$2);
|
|
3501
|
-
on(document, "mousedown", onPointerdown$3);
|
|
3502
|
-
on(document, "pointermove", onPointermove$2);
|
|
3503
|
-
on(document, "pointerup", onPointerup$1);
|
|
3504
|
-
on(document, "touchcancel", onPointerup$1);
|
|
3505
|
-
on(document, "touchstart", onPointerdown$3, { passive: false });
|
|
3506
|
-
attributable(RESIZABLE_ATTRIBUTE, addResizable, removeResizable);
|
|
3507
|
-
//#endregion
|
|
3508
|
-
//#region src/js/dialog.ts
|
|
3509
|
-
var OuiDialog = class {
|
|
3510
|
-
#state;
|
|
3511
|
-
/**
|
|
3512
|
-
* Is the dialog open?
|
|
3513
|
-
*/
|
|
3514
|
-
get open() {
|
|
3515
|
-
return this.#state.element.open;
|
|
3516
|
-
}
|
|
3517
|
-
/**
|
|
3518
|
-
* Open or close the dialog
|
|
3519
|
-
*/
|
|
3520
|
-
set open(value) {
|
|
3521
|
-
if (value === true) this.show();
|
|
3522
|
-
else if (value === false) this.hide();
|
|
3523
|
-
}
|
|
3524
|
-
constructor(state) {
|
|
3525
|
-
this.#state = state;
|
|
3526
|
-
}
|
|
3527
|
-
hide(first, second) {
|
|
3528
|
-
if (!this.#state.element.open) return;
|
|
3529
|
-
if (first === true) this.#state.element.requestClose(typeof second === "string" ? second : void 0);
|
|
3530
|
-
else this.#state.element.close(typeof first === "string" ? first : void 0);
|
|
3531
|
-
}
|
|
3532
|
-
/**
|
|
3533
|
-
* Opens the dialog
|
|
3534
|
-
*/
|
|
3535
|
-
show(modal) {
|
|
3536
|
-
const { element } = this.#state;
|
|
3537
|
-
if (element == null || element.open) return;
|
|
3538
|
-
const isModal = modal !== false;
|
|
3539
|
-
setAria(element, "modal", isModal);
|
|
3540
|
-
if (isModal) element.showModal();
|
|
3541
|
-
else element.show();
|
|
3542
|
-
}
|
|
3543
|
-
};
|
|
3544
|
-
function addDialog(element) {
|
|
3545
|
-
if (!(element instanceof HTMLDialogElement)) throw new TypeError(MESSAGE$3);
|
|
3546
|
-
if (!states$3.has(element)) states$3.set(element, getState$3(element));
|
|
3547
|
-
}
|
|
3548
|
-
function destroyDialog(state) {
|
|
3549
|
-
state.element.close();
|
|
3550
|
-
setAria(state.element, "modal", state.modal);
|
|
3551
|
-
state.element.removeAttribute(ATTRIBUTE_OPEN$1);
|
|
3552
|
-
for (const listener of state.listeners) listener();
|
|
3553
|
-
state.movable?.destroy();
|
|
3554
|
-
state.resizable?.destroy();
|
|
3555
|
-
state.dialog = void 0;
|
|
3556
|
-
state.element = void 0;
|
|
3557
|
-
state.listeners = void 0;
|
|
3558
|
-
state.movable = void 0;
|
|
3559
|
-
state.resizable = void 0;
|
|
3560
|
-
}
|
|
3561
|
-
/**
|
|
3562
|
-
* Get the _OuiDialog_ for an element
|
|
3563
|
-
*
|
|
3564
|
-
* @param element Element to get _OuiDialog_ for
|
|
3565
|
-
* @returns _OuiDialog_ instance
|
|
3566
|
-
*/
|
|
3567
|
-
function getDialog(element) {
|
|
3568
|
-
return states$3.get(element)?.dialog;
|
|
3569
|
-
}
|
|
3570
|
-
function getMovable(element) {
|
|
3571
|
-
const handles = element.querySelectorAll(SELECTOR_MOVER);
|
|
3572
|
-
if (handles.length === 0) return;
|
|
3573
|
-
for (const handle of handles) setAttribute(handle, ATTRIBUTE_MOVABLE_HANDLE, "");
|
|
3574
|
-
return createMovable(element, { container: getAttribute(element, ATTRIBUTE_CONTAINER$1) });
|
|
3575
|
-
}
|
|
3576
|
-
function getResizable(element) {
|
|
3577
|
-
const handle = element.querySelector(SELECTOR_RESIZER);
|
|
3578
|
-
if (handle == null) return;
|
|
3579
|
-
setAttribute(handle, RESIZABLE_ATTRIBUTE_HANDLE, "");
|
|
3580
|
-
return createResizable(element);
|
|
3581
|
-
}
|
|
3582
|
-
function getState$3(element) {
|
|
3583
|
-
const state = {
|
|
3584
|
-
element,
|
|
3585
|
-
dialog: void 0,
|
|
3586
|
-
listeners: [getOnBeforeToggleListener(element), on(element, "toggle", (event) => {
|
|
3587
|
-
const { source } = event;
|
|
3588
|
-
if (element.open) {
|
|
3589
|
-
setAria(element, "modal", source instanceof HTMLButtonElement && source.command === "show-modal" || element.matches(":modal"));
|
|
3590
|
-
setAttribute(element, ATTRIBUTE_OPEN$1, "");
|
|
3591
|
-
element.focus();
|
|
3592
|
-
setTimeout(() => {
|
|
3593
|
-
state.resizable?.set();
|
|
3594
|
-
}, 500);
|
|
3595
|
-
} else {
|
|
3596
|
-
setAttribute(element, ATTRIBUTE_OPEN$1);
|
|
3597
|
-
setAria(element, "modal", state.modal);
|
|
3598
|
-
setStyles(element, {
|
|
3599
|
-
inset: "",
|
|
3600
|
-
position: "",
|
|
3601
|
-
transform: ""
|
|
3602
|
-
});
|
|
3603
|
-
state.resizable?.reset();
|
|
3604
|
-
}
|
|
3605
|
-
})],
|
|
3606
|
-
modal: getAria(element, "modal") === "true" || element.matches(":modal")
|
|
3607
|
-
};
|
|
3608
|
-
state.dialog = new OuiDialog(state);
|
|
3609
|
-
state.movable = getMovable(element);
|
|
3610
|
-
state.resizable = getResizable(element);
|
|
3611
|
-
return state;
|
|
3612
|
-
}
|
|
3613
|
-
function removeDialog(element) {
|
|
3614
|
-
const state = states$3.get(element);
|
|
3615
|
-
if (state == null) return;
|
|
3616
|
-
destroyDialog(state);
|
|
3617
|
-
states$3.delete(element);
|
|
3618
|
-
}
|
|
3619
|
-
const ATTRIBUTE$3 = "oui-dialog";
|
|
3620
|
-
const ATTRIBUTE_CONTAINER$1 = `${ATTRIBUTE$3}-container`;
|
|
3621
|
-
const ATTRIBUTE_OPEN$1 = `${ATTRIBUTE$3}-open`;
|
|
3622
|
-
const MESSAGE$3 = "The element must be an instance of HTMLDialogElement";
|
|
3623
|
-
const SELECTOR_MOVER = `[${ATTRIBUTE$3}-mover]`;
|
|
3624
|
-
const SELECTOR_RESIZER = `[${ATTRIBUTE$3}-resizer]`;
|
|
3625
|
-
const states$3 = /* @__PURE__ */ new WeakMap();
|
|
3626
|
-
attributable(ATTRIBUTE$3, addDialog, removeDialog);
|
|
3627
|
-
//#endregion
|
|
3628
|
-
//#region node_modules/@oscarpalmer/toretto/dist/focusable.mjs
|
|
3629
|
-
/**
|
|
3630
|
-
* Get a list of focusable elements within a parent element
|
|
3631
|
-
*
|
|
3632
|
-
* @param parent Parent element
|
|
3633
|
-
* @returns Focusable elements
|
|
3634
|
-
*/
|
|
3635
|
-
function getFocusable(parent) {
|
|
3636
|
-
return getValidElements(parent, FILTERS_FOCUSABLE, false);
|
|
3637
|
-
}
|
|
3638
|
-
function getItem(element, tabbable) {
|
|
3639
|
-
return {
|
|
3640
|
-
element,
|
|
3641
|
-
tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
|
|
3642
|
-
};
|
|
3643
|
-
}
|
|
3644
|
-
function getTabIndex(element) {
|
|
3645
|
-
const tabIndex = element?.tabIndex ?? TABINDEX_DEFAULT;
|
|
3646
|
-
if (tabIndex < TABINDEX_BASE && (EXPRESSION_SPECIAL_TABINDEX.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) return TABINDEX_BASE;
|
|
3647
|
-
return tabIndex;
|
|
3648
|
-
}
|
|
3649
|
-
function getValidElements(parent, filters, tabbable) {
|
|
3650
|
-
if (!(parent instanceof Element)) return [];
|
|
3651
|
-
const elements = [...parent.querySelectorAll(SELECTOR_FULL)];
|
|
3652
|
-
const items = [];
|
|
3653
|
-
let { length } = elements;
|
|
3654
|
-
for (let index = 0; index < length; index += 1) {
|
|
3655
|
-
const item = getItem(elements[index], tabbable);
|
|
3656
|
-
if (!filters.some((filter) => filter(item))) items.push(item);
|
|
3657
|
-
}
|
|
3658
|
-
if (!tabbable) return items.map((item) => item.element);
|
|
3659
|
-
const indiced = [];
|
|
3660
|
-
const zeroed = [];
|
|
3661
|
-
length = items.length;
|
|
3662
|
-
for (let index = 0; index < length; index += 1) {
|
|
3663
|
-
const item = items[index];
|
|
3664
|
-
if (item.tabIndex === TABINDEX_BASE) zeroed.push(item.element);
|
|
3665
|
-
else indiced[item.tabIndex] = [...indiced[item.tabIndex] ?? [], item.element];
|
|
3666
|
-
}
|
|
3667
|
-
return [...indiced.flat(), ...zeroed];
|
|
3668
|
-
}
|
|
3669
|
-
function hasTabIndex(element) {
|
|
3670
|
-
return !Number.isNaN(Number.parseInt(element.getAttribute(ATTRIBUTE_TABINDEX), 10));
|
|
3671
|
-
}
|
|
3672
|
-
function isDisabled(item) {
|
|
3673
|
-
if (EXPRESSION_DISABLEABLE.test(item.element.tagName) && isDisabledFromFieldset(item.element)) return true;
|
|
3674
|
-
return item.element.disabled ?? false;
|
|
3675
|
-
}
|
|
3676
|
-
function isDisabledFromFieldset(element) {
|
|
3677
|
-
let parent = element.parentElement;
|
|
3678
|
-
while (parent != null) {
|
|
3679
|
-
if (parent instanceof HTMLFieldSetElement && parent.disabled) {
|
|
3680
|
-
const children = Array.from(parent.children);
|
|
3681
|
-
const { length } = children;
|
|
3682
|
-
for (let index = 0; index < length; index += 1) {
|
|
3683
|
-
const child = children[index];
|
|
3684
|
-
if (child instanceof HTMLLegendElement) return parent.matches(SELECTOR_FIELDSET_DISABLED) || !child.contains(element);
|
|
3685
|
-
}
|
|
3686
|
-
return true;
|
|
3687
|
-
}
|
|
3688
|
-
parent = parent.parentElement;
|
|
3689
|
-
}
|
|
3690
|
-
return false;
|
|
3691
|
-
}
|
|
3692
|
-
function isEditable(element) {
|
|
3693
|
-
return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
|
|
3694
|
-
}
|
|
3695
|
-
function isHidden(item) {
|
|
3696
|
-
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === STYLE_HIDDEN) return true;
|
|
3697
|
-
if ((item.element.matches(SELECTOR_SUMMARY_FIRST) ? item.element.parentElement : item.element)?.matches(SELECTOR_DETAILS_CLOSED_CHILDREN) ?? false) return true;
|
|
3698
|
-
const style = getComputedStyle(item.element);
|
|
3699
|
-
if (style.display === STYLE_NONE || style.visibility === STYLE_HIDDEN) return true;
|
|
3700
|
-
const { height, width } = item.element.getBoundingClientRect();
|
|
3701
|
-
return height === 0 && width === 0;
|
|
3702
|
-
}
|
|
3703
|
-
function isInert(item) {
|
|
3704
|
-
return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
|
|
3705
|
-
element: item.element.parentElement,
|
|
3706
|
-
tabIndex: TABINDEX_DEFAULT
|
|
3707
|
-
});
|
|
3708
|
-
}
|
|
3709
|
-
function isSummarised(item) {
|
|
3710
|
-
return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
|
|
3711
|
-
}
|
|
3712
|
-
const ATTRIBUTE_CONTENTEDITABLE = "contenteditable";
|
|
3713
|
-
const ATTRIBUTE_INERT = "inert";
|
|
3714
|
-
const ATTRIBUTE_TABINDEX = "tabindex";
|
|
3715
|
-
const EXPRESSION_DISABLEABLE = /^(button|input|select|textarea)$/i;
|
|
3716
|
-
const EXPRESSION_SPECIAL_TABINDEX = /^(audio|details|video)$/i;
|
|
3717
|
-
const EXPRESSION_SUMMARY = /^summary$/i;
|
|
3718
|
-
const EXPRESSION_TRUEISH = /^(|true)$/i;
|
|
3719
|
-
const FILTERS_FOCUSABLE = [
|
|
3720
|
-
isDisabled,
|
|
3721
|
-
isInert,
|
|
3722
|
-
isHidden,
|
|
3723
|
-
isSummarised
|
|
3724
|
-
];
|
|
3725
|
-
[...FILTERS_FOCUSABLE];
|
|
3726
|
-
const SELECTOR_DETAILS_CLOSED_CHILDREN = "details:not([open]) *";
|
|
3727
|
-
const SELECTOR_FIELDSET_DISABLED = "fieldset[disabled] *";
|
|
3728
|
-
const SELECTOR_SUMMARY_FIRST = "details > summary:first-of-type";
|
|
3729
|
-
const SELECTOR_FULL = [
|
|
3730
|
-
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
3731
|
-
"[tabindex]:not(slot)",
|
|
3732
|
-
"a[href]",
|
|
3733
|
-
"audio[controls]",
|
|
3734
|
-
"button",
|
|
3735
|
-
"details",
|
|
3736
|
-
SELECTOR_SUMMARY_FIRST,
|
|
3737
|
-
"input",
|
|
3738
|
-
"select",
|
|
3739
|
-
"textarea",
|
|
3740
|
-
"video[controls]"
|
|
3741
|
-
].map((selector) => `${selector}:not([inert])`).join(",");
|
|
3742
|
-
const STYLE_HIDDEN = "hidden";
|
|
3743
|
-
const STYLE_NONE = "none";
|
|
3744
|
-
const TABINDEX_BASE = 0;
|
|
3745
|
-
const TABINDEX_DEFAULT = -1;
|
|
3746
|
-
//#endregion
|
|
3747
|
-
//#region src/js/focus-trap/focus-trap.embedded.ts
|
|
3748
|
-
var OuiFocusTrap = class {
|
|
3749
|
-
#destroyed = false;
|
|
3750
|
-
#tabIndex;
|
|
3751
|
-
#state;
|
|
3752
|
-
/**
|
|
3753
|
-
* Is focused maintained within the _focus trap_ when clicking outside of it?
|
|
3754
|
-
*/
|
|
3755
|
-
get contain() {
|
|
3756
|
-
return this.#state.element.hasAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
|
|
3757
|
-
}
|
|
3758
|
-
/**
|
|
3759
|
-
* Should focus be maintained within the _focus trap_ when clicking outside of it?
|
|
3760
|
-
*/
|
|
3761
|
-
set contain(value) {
|
|
3762
|
-
if (value === true) setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_CONTAIN, "");
|
|
3763
|
-
else if (value === false) setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_CONTAIN, void 0);
|
|
3764
|
-
}
|
|
3765
|
-
/**
|
|
3766
|
-
* Is the _focus trap_ disabled?
|
|
3767
|
-
*/
|
|
3768
|
-
get disabled() {
|
|
3769
|
-
return this.#state.disabled;
|
|
3770
|
-
}
|
|
3771
|
-
/**
|
|
3772
|
-
* Should the _focus trap_ be disabled?
|
|
3773
|
-
*/
|
|
3774
|
-
set disabled(value) {
|
|
3775
|
-
if (value === true) this.disable();
|
|
3776
|
-
else if (value === false) this.enable();
|
|
3777
|
-
}
|
|
3778
|
-
/**
|
|
3779
|
-
* Is focus allowed to escape when pressing _Escape_ within the _focus trap_?
|
|
3780
|
-
*/
|
|
3781
|
-
get noescape() {
|
|
3782
|
-
return this.#state.element.hasAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
|
|
3783
|
-
}
|
|
3784
|
-
/**
|
|
3785
|
-
* Should the _focus trap_ allow focus to escape when pressing _Escape_?
|
|
3786
|
-
*/
|
|
3787
|
-
set noescape(value) {
|
|
3788
|
-
if (value === true) setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_NOESCAPE, "");
|
|
3789
|
-
else if (value === false) setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_NOESCAPE, void 0);
|
|
3790
|
-
}
|
|
3791
|
-
constructor(state) {
|
|
3792
|
-
this.#state = state;
|
|
3793
|
-
this.#tabIndex = state.element.tabIndex;
|
|
3794
|
-
state.element.tabIndex = -1;
|
|
3795
|
-
setAttribute(state.element, ATTRIBUTE_FOCUSTRAP, "");
|
|
3796
|
-
this.contain = state.options.contain;
|
|
3797
|
-
this.noescape = state.options.noescape;
|
|
3798
|
-
states$2.set(this, state);
|
|
3799
|
-
}
|
|
3800
|
-
/**
|
|
3801
|
-
* Destroys the _focus trap_
|
|
3802
|
-
*/
|
|
3803
|
-
destroy() {
|
|
3804
|
-
if (this.#destroyed) return;
|
|
3805
|
-
this.#destroyed = true;
|
|
3806
|
-
disabled.delete(this);
|
|
3807
|
-
instances.delete(this.#state.element);
|
|
3808
|
-
states$2.delete(this);
|
|
3809
|
-
this.#state.element.tabIndex = this.#tabIndex;
|
|
3810
|
-
this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP);
|
|
3811
|
-
this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
|
|
3812
|
-
this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
|
|
3813
|
-
this.#state.element = void 0;
|
|
3814
|
-
}
|
|
3815
|
-
/**
|
|
3816
|
-
* Disables the _focus trap_
|
|
3817
|
-
*/
|
|
3818
|
-
disable() {
|
|
3819
|
-
if (!this.#destroyed && !(this.disabled || this.#state.options.noescape)) setDisabled(this, this.#state, true);
|
|
3820
|
-
}
|
|
3821
|
-
/**
|
|
3822
|
-
* Enables the _focus trap_
|
|
3823
|
-
*/
|
|
3824
|
-
enable() {
|
|
3825
|
-
if (!this.#destroyed && this.disabled) setDisabled(this, this.#state, false);
|
|
3826
|
-
}
|
|
3827
|
-
/**
|
|
3828
|
-
* Focuses the _focus trap_
|
|
3829
|
-
*
|
|
3830
|
-
* @param last When `true`, focuses the last focusable element within the _focus trap_ instead of the first
|
|
3831
|
-
*/
|
|
3832
|
-
focus(last) {
|
|
3833
|
-
if (!this.#destroyed && !this.disabled) tabToTrap(this, getFocusable(this.#state.element), this.#state.element, last ? -1 : 0);
|
|
3834
|
-
}
|
|
3835
|
-
};
|
|
3836
|
-
/**
|
|
3837
|
-
* Creates _(or retrieves)_ a _focus trap_ for an element
|
|
3838
|
-
*
|
|
3839
|
-
* @param element Element to trap focus within
|
|
3840
|
-
* @param options _Focus trap_ options
|
|
3841
|
-
* @returns _Focus trap_ instance
|
|
3842
|
-
*/
|
|
3843
|
-
function createFocusTrap(element, options) {
|
|
3844
|
-
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE$2);
|
|
3845
|
-
let instance = instances.get(element);
|
|
3846
|
-
if (instance == null) {
|
|
3847
|
-
instance = new OuiFocusTrap(getState$2(element, options));
|
|
3848
|
-
instances.set(element, instance);
|
|
3849
|
-
}
|
|
3850
|
-
return instance;
|
|
3851
|
-
}
|
|
3852
|
-
function getOptions(element, input) {
|
|
3853
|
-
const options = isPlainObject(input) ? input : {};
|
|
3854
|
-
return {
|
|
3855
|
-
contain: typeof options.contain === "boolean" ? options.contain : element.hasAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN),
|
|
3856
|
-
noescape: typeof options.noescape === "boolean" ? options.noescape : element.hasAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE)
|
|
3857
|
-
};
|
|
3858
|
-
}
|
|
3859
|
-
function getState$2(element, options) {
|
|
3860
|
-
return {
|
|
3861
|
-
element,
|
|
3862
|
-
disabled: false,
|
|
3863
|
-
options: getOptions(element, options)
|
|
3864
|
-
};
|
|
3865
|
-
}
|
|
3866
|
-
function onEscape(event) {
|
|
3867
|
-
let element = findAncestor(event, SELECTOR$2);
|
|
3868
|
-
let instance = instances.get(element);
|
|
3869
|
-
let state = states$2.get(instance);
|
|
3870
|
-
if (element == null || instance == null || state == null) return;
|
|
3871
|
-
while (state.disabled) {
|
|
3872
|
-
element = findAncestor(state.element.parentElement, SELECTOR$2);
|
|
3873
|
-
instance = instances.get(element);
|
|
3874
|
-
state = states$2.get(instance);
|
|
3875
|
-
if (element == null || instance == null || state == null) return;
|
|
3876
|
-
if (!state.disabled) break;
|
|
3877
|
-
}
|
|
3878
|
-
instance?.disable();
|
|
3879
|
-
}
|
|
3880
|
-
function onFocusIn(event) {
|
|
3881
|
-
lastTarget = instances.get(findAncestor(event, SELECTOR$2)) == null ? void 0 : event.target;
|
|
3882
|
-
}
|
|
3883
|
-
function onKeydown$1(event) {
|
|
3884
|
-
switch (event.key) {
|
|
3885
|
-
case "Escape":
|
|
3886
|
-
onEscape(event);
|
|
3887
|
-
break;
|
|
3888
|
-
case "Tab":
|
|
3889
|
-
onTab(event);
|
|
3890
|
-
break;
|
|
3891
|
-
default: return;
|
|
3892
|
-
}
|
|
3893
|
-
}
|
|
3894
|
-
function onPointerdown$2(event) {
|
|
3895
|
-
const last = findAncestor(lastTarget, SELECTOR$2);
|
|
3896
|
-
const next = findAncestor(event, SELECTOR$2);
|
|
3897
|
-
if (last != null && next !== last) {
|
|
3898
|
-
if (states$2.get(instances.get(last))?.options.contain ?? false) {
|
|
3899
|
-
event.preventDefault();
|
|
3900
|
-
lastTarget?.focus();
|
|
3901
|
-
}
|
|
3902
|
-
}
|
|
3903
|
-
if (disabled.size === 0) return;
|
|
3904
|
-
for (const focusTrap of disabled) {
|
|
3905
|
-
const state = states$2.get(focusTrap);
|
|
3906
|
-
if (state != null && state.element !== next) focusTrap.enable();
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
function onTab(event) {
|
|
3910
|
-
const element = findAncestor(event, SELECTOR$2);
|
|
3911
|
-
const instance = instances.get(element);
|
|
3912
|
-
if (instance == null) return;
|
|
3913
|
-
const dispatched = dispatch(element, "focus-trap");
|
|
3914
|
-
setTimeout(() => {
|
|
3915
|
-
if (dispatched.defaultPrevented) return;
|
|
3916
|
-
if (!instance.disabled) event.preventDefault();
|
|
3917
|
-
const elements = getFocusable(element);
|
|
3918
|
-
const index = elements.indexOf(event.target);
|
|
3919
|
-
if (index === -1 || elements.length === 0) tabToTrap(instance, elements, element);
|
|
3920
|
-
else tabToElement(instance, elements, index, event.shiftKey ? -1 : 1);
|
|
3921
|
-
});
|
|
3922
|
-
}
|
|
3923
|
-
function removeFocusTrap(element) {
|
|
3924
|
-
instances.get(element)?.destroy();
|
|
3925
|
-
instances.delete(element);
|
|
3926
|
-
}
|
|
3927
|
-
function setDisabled(focusTrap, state, value) {
|
|
3928
|
-
state.disabled = value;
|
|
3929
|
-
if (value) disabled.add(focusTrap);
|
|
3930
|
-
else disabled.delete(focusTrap);
|
|
3931
|
-
}
|
|
3932
|
-
function tabToElement(instance, elements, index, modifier) {
|
|
3933
|
-
const { length } = elements;
|
|
3934
|
-
const next = clamp(index + modifier, 0, length - 1, true);
|
|
3935
|
-
if (instance.disabled) {
|
|
3936
|
-
if (index === length - 1 && next === 0 || index === 0 && next === length - 1) {
|
|
3937
|
-
lastTarget = void 0;
|
|
3938
|
-
instance.enable();
|
|
3939
|
-
}
|
|
3940
|
-
return;
|
|
3941
|
-
}
|
|
3942
|
-
const element = elements[next];
|
|
3943
|
-
const elementFocusTrap = instances.get(element);
|
|
3944
|
-
if (elementFocusTrap != null) elementFocusTrap.focus(modifier === -1);
|
|
3945
|
-
else {
|
|
3946
|
-
elements[next].focus();
|
|
3947
|
-
lastTarget = elements[next];
|
|
3948
|
-
}
|
|
3949
|
-
}
|
|
3950
|
-
function tabToTrap(instance, elements, element, index) {
|
|
3951
|
-
if (instance.disabled) {
|
|
3952
|
-
lastTarget = void 0;
|
|
3953
|
-
instance.enable();
|
|
3954
|
-
} else {
|
|
3955
|
-
const next = elements.length === 0 ? element : elements.at(index ?? 0);
|
|
3956
|
-
next.focus();
|
|
3957
|
-
lastTarget = next;
|
|
3958
|
-
}
|
|
3959
|
-
}
|
|
3960
|
-
const ATTRIBUTE_FOCUSTRAP = "oui-focus-trap";
|
|
3961
|
-
const ATTRIBUTE_FOCUSTRAP_CONTAIN = `${ATTRIBUTE_FOCUSTRAP}-contain`;
|
|
3962
|
-
const ATTRIBUTE_FOCUSTRAP_NOESCAPE = `${ATTRIBUTE_FOCUSTRAP}-noescape`;
|
|
3963
|
-
const EVENT_OPTIONS = {
|
|
3964
|
-
capture: true,
|
|
3965
|
-
passive: false
|
|
3966
|
-
};
|
|
3967
|
-
const MESSAGE$2 = "Element must be an HTMLElement or SVGElement";
|
|
3968
|
-
const SELECTOR$2 = `[${ATTRIBUTE_FOCUSTRAP}]`;
|
|
3969
|
-
const disabled = /* @__PURE__ */ new Set();
|
|
3970
|
-
const instances = /* @__PURE__ */ new WeakMap();
|
|
3971
|
-
const states$2 = /* @__PURE__ */ new WeakMap();
|
|
3972
|
-
let lastTarget;
|
|
3973
|
-
attributable(ATTRIBUTE_FOCUSTRAP, createFocusTrap, removeFocusTrap);
|
|
3974
|
-
on(document, "focusin", onFocusIn, EVENT_OPTIONS);
|
|
3975
|
-
on(document, "keydown", onKeydown$1, EVENT_OPTIONS);
|
|
3976
|
-
on(document, "mousedown", onPointerdown$2, EVENT_OPTIONS);
|
|
3977
|
-
on(document, "touchstart", onPointerdown$2, EVENT_OPTIONS);
|
|
3978
|
-
//#endregion
|
|
3979
|
-
//#region src/js/popover.ts
|
|
3980
|
-
var OuiPopover = class {
|
|
3981
|
-
#state;
|
|
3982
|
-
/**
|
|
3983
|
-
* Is the popover open?
|
|
3984
|
-
*/
|
|
3985
|
-
get open() {
|
|
3986
|
-
return this.#state.content.checkVisibility();
|
|
3987
|
-
}
|
|
3988
|
-
set open(value) {
|
|
3989
|
-
if (value === true) this.show();
|
|
3990
|
-
else if (value === false) this.hide();
|
|
3991
|
-
}
|
|
3992
|
-
constructor(state) {
|
|
3993
|
-
this.#state = state;
|
|
3994
|
-
initialize(state);
|
|
3995
|
-
this.#state.floatable.update();
|
|
3996
|
-
}
|
|
3997
|
-
/**
|
|
3998
|
-
* Closes the popover
|
|
3999
|
-
*/
|
|
4000
|
-
hide() {
|
|
4001
|
-
this.#state.floatable.hide();
|
|
4002
|
-
}
|
|
4003
|
-
/**
|
|
4004
|
-
* Opens the popover
|
|
4005
|
-
*/
|
|
4006
|
-
show() {
|
|
4007
|
-
this.#state.floatable.show();
|
|
4008
|
-
}
|
|
4009
|
-
};
|
|
4010
|
-
function addPopover(element) {
|
|
4011
|
-
if (states$1.has(element) || element.hasAttribute("oui-floatable")) return;
|
|
4012
|
-
const anchor = element.ownerDocument.querySelector(`[popovertarget="${element.id}"]`);
|
|
4013
|
-
if (isHTMLOrSVGElement(anchor)) states$1.set(element, getState$1(anchor, element));
|
|
4014
|
-
}
|
|
4015
|
-
function destroyPopover(state) {
|
|
4016
|
-
state.floatable.destroy();
|
|
4017
|
-
state.focusTrap?.destroy();
|
|
4018
|
-
for (const listener of state.listeners) listener();
|
|
4019
|
-
state.anchor = void 0;
|
|
4020
|
-
state.content = void 0;
|
|
4021
|
-
state.floatable = void 0;
|
|
4022
|
-
state.focusTrap = void 0;
|
|
4023
|
-
state.listeners = void 0;
|
|
4024
|
-
state.popover = void 0;
|
|
4025
|
-
}
|
|
4026
|
-
function getId(element, value) {
|
|
4027
|
-
let { id } = element;
|
|
4028
|
-
if (id == null || id.trim().length === 0) {
|
|
4029
|
-
id = value == null ? `oui_popover_${++index$1}` : `${value}_toggle`;
|
|
4030
|
-
element.id = id;
|
|
4031
|
-
}
|
|
4032
|
-
return id;
|
|
4033
|
-
}
|
|
4034
|
-
/**
|
|
4035
|
-
* Get the _OuiPopover_ for an element
|
|
4036
|
-
*
|
|
4037
|
-
* @param element Element to get _OuiPopover_ for
|
|
4038
|
-
* @returns _OuiPopover_ instance
|
|
4039
|
-
*/
|
|
4040
|
-
function getPopover(element) {
|
|
4041
|
-
return states$1.get(element)?.popover;
|
|
4042
|
-
}
|
|
4043
|
-
function getState$1(anchor, content) {
|
|
4044
|
-
const state = {
|
|
4045
|
-
anchor,
|
|
4046
|
-
content,
|
|
4047
|
-
floatable: createEmbeddedFloatable(anchor, content, options$1),
|
|
4048
|
-
focusTrap: getAria(content, "modal") === "true" ? createFocusTrap(content, { noescape: true }) : void 0,
|
|
4049
|
-
listeners: [getOnBeforeToggleListener(content), on(content, "toggle", (event) => {
|
|
4050
|
-
const expanded = event.newState === "open";
|
|
4051
|
-
if (expanded) {
|
|
4052
|
-
ignoreFocus = false;
|
|
4053
|
-
state.floatable?.update();
|
|
4054
|
-
content.focus();
|
|
4055
|
-
} else if (!ignoreFocus) anchor?.focus();
|
|
4056
|
-
setAria(anchor, "expanded", expanded);
|
|
4057
|
-
setAttribute(content, ATTRIBUTE_OPEN, expanded ? "" : void 0);
|
|
4058
|
-
})],
|
|
4059
|
-
popover: void 0
|
|
4060
|
-
};
|
|
4061
|
-
state.popover = new OuiPopover(state);
|
|
4062
|
-
return state;
|
|
4063
|
-
}
|
|
4064
|
-
function initialize(state) {
|
|
4065
|
-
const id = getId(state.content);
|
|
4066
|
-
setAria(state.anchor, {
|
|
4067
|
-
controls: id,
|
|
4068
|
-
expanded: "false"
|
|
4069
|
-
});
|
|
4070
|
-
if ((getAria(state.content, "label") ?? getAria(state.content, "labelledby")) == null) setAria(state.content, "labelledby", getId(state.anchor, id));
|
|
4071
|
-
}
|
|
4072
|
-
function onPointerdown$1() {
|
|
4073
|
-
ignoreFocus = true;
|
|
4074
|
-
}
|
|
4075
|
-
function removePopover(element) {
|
|
4076
|
-
const state = states$1.get(element);
|
|
4077
|
-
if (state == null) return;
|
|
4078
|
-
destroyPopover(state);
|
|
4079
|
-
states$1.delete(element);
|
|
4080
|
-
}
|
|
4081
|
-
const ATTRIBUTE$2 = "oui-popover";
|
|
4082
|
-
const ATTRIBUTE_OPEN = `${ATTRIBUTE$2}-open`;
|
|
4083
|
-
const options$1 = {
|
|
4084
|
-
attribute: `${ATTRIBUTE$2}-position`,
|
|
4085
|
-
position: "below-start",
|
|
4086
|
-
reusable: false
|
|
4087
|
-
};
|
|
4088
|
-
const states$1 = /* @__PURE__ */ new WeakMap();
|
|
4089
|
-
let ignoreFocus = false;
|
|
4090
|
-
let index$1 = 0;
|
|
4091
|
-
on(document, "pointerdown", onPointerdown$1, { capture: true });
|
|
4092
|
-
attributable(ATTRIBUTE$2, addPopover, removePopover);
|
|
4093
|
-
//#endregion
|
|
4094
|
-
//#region src/js/sortable/sortable.embedded.ts
|
|
4095
|
-
var OuiSortable = class extends OuiDraggable {
|
|
4096
|
-
constructor(element, options) {
|
|
4097
|
-
super("sortable", "sort", ATTRIBUTE$1, element, {
|
|
4098
|
-
container: {
|
|
4099
|
-
attribute: ATTRIBUTE_CONTAINER,
|
|
4100
|
-
map: CONTAINERS
|
|
4101
|
-
},
|
|
4102
|
-
direction: { attribute: ATTRIBUTE_DIRECTION },
|
|
4103
|
-
drag: {
|
|
4104
|
-
onBegin,
|
|
4105
|
-
onCancel,
|
|
4106
|
-
onEnd: onEnd$1,
|
|
4107
|
-
onMove
|
|
4108
|
-
},
|
|
4109
|
-
input: options,
|
|
4110
|
-
position: {
|
|
4111
|
-
getOffset: getOffsetPosition,
|
|
4112
|
-
getOriginal: getOriginalPosition
|
|
4113
|
-
},
|
|
4114
|
-
getDragged: getDragPlaceholder,
|
|
4115
|
-
getOrigin: () => (getDraggableStates(element)?.sortable)?.origin
|
|
4116
|
-
}, { connections: getAttribute(element, ATTRIBUTE_CONNECTIONS) });
|
|
4117
|
-
}
|
|
4118
|
-
};
|
|
4119
|
-
function afterEnd(insert, from, events, elements, position, valid) {
|
|
4120
|
-
elements.origin?.removeAttribute(ATTRIBUTE_ORIGIN);
|
|
4121
|
-
from.state.origin = void 0;
|
|
4122
|
-
resetPlaceholders();
|
|
4123
|
-
if (!valid || events.some((event) => event?.defaultPrevented)) return;
|
|
4124
|
-
if (insert !== "insert") {
|
|
4125
|
-
elements.target.append(elements.origin);
|
|
4126
|
-
return;
|
|
4127
|
-
}
|
|
4128
|
-
if (position == null) return;
|
|
4129
|
-
const { height, top } = elements.target.getBoundingClientRect();
|
|
4130
|
-
let insertion;
|
|
4131
|
-
if (position.y < top + height / 2) insertion = "beforebegin";
|
|
4132
|
-
else insertion = "afterend";
|
|
4133
|
-
elements.target?.insertAdjacentElement(insertion, elements.origin);
|
|
4134
|
-
document.body.removeAttribute(ATTRIBUTE_ACTIVE$1);
|
|
4135
|
-
}
|
|
4136
|
-
/**
|
|
4137
|
-
* Creates _(or retrieves)_ a _OuiSortable_ instance for an element
|
|
4138
|
-
*
|
|
4139
|
-
* @param element Element to make sortable
|
|
4140
|
-
* @returns _OuiSortable_ instance
|
|
4141
|
-
*/
|
|
4142
|
-
function createSortable(element, options) {
|
|
4143
|
-
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE$1);
|
|
4144
|
-
return addSortable(element, options);
|
|
4145
|
-
}
|
|
4146
|
-
function getDragPlaceholder() {
|
|
4147
|
-
placeholder.drag.default ??= createElement("div");
|
|
4148
|
-
return placeholder.drag.custom ?? placeholder.drag.default;
|
|
4149
|
-
}
|
|
4150
|
-
function getOffsetPosition(_, item, element, position) {
|
|
4151
|
-
const rectangle = element.getBoundingClientRect();
|
|
4152
|
-
return {
|
|
4153
|
-
x: item.state.horizontal ? 0 : position.x - rectangle.left,
|
|
4154
|
-
y: item.state.vertical ? 0 : position.y - rectangle.top
|
|
4155
|
-
};
|
|
4156
|
-
}
|
|
4157
|
-
function getOriginalPosition(_, __, position) {
|
|
4158
|
-
return position;
|
|
4159
|
-
}
|
|
4160
|
-
function getPositionPlaceholder(item) {
|
|
4161
|
-
placeholder.position ??= createElement("div");
|
|
4162
|
-
setAttribute(placeholder.position, ATTRIBUTE_PLACEHOLDER_POSITION, "");
|
|
4163
|
-
if (item.state.origin != null) setStyle(placeholder.position, "--placeholder-height", `${item.state.origin.getBoundingClientRect().height}px`);
|
|
4164
|
-
return placeholder.position;
|
|
4165
|
-
}
|
|
4166
|
-
function onBegin(_, globals, item, element) {
|
|
4167
|
-
item.state.origin = element;
|
|
4168
|
-
setPlaceholder(globals, item, element);
|
|
4169
|
-
setAttribute(element, ATTRIBUTE_ORIGIN, "");
|
|
4170
|
-
setAttribute(document.body, ATTRIBUTE_ACTIVE$1, "");
|
|
4171
|
-
}
|
|
4172
|
-
function onCancel(_, item) {
|
|
4173
|
-
item.state.origin?.removeAttribute(ATTRIBUTE_ORIGIN);
|
|
4174
|
-
document.body.removeAttribute(ATTRIBUTE_ACTIVE$1);
|
|
4175
|
-
resetPlaceholders();
|
|
4176
|
-
item.state.origin = void 0;
|
|
4177
|
-
}
|
|
4178
|
-
function onEnd$1(event, globals, item, reset) {
|
|
4179
|
-
const { origin } = item.state;
|
|
4180
|
-
const position = getPosition$1(event) ?? {
|
|
4181
|
-
x: 0,
|
|
4182
|
-
y: 0
|
|
4183
|
-
};
|
|
4184
|
-
const target = getElementFromPosition(position)[0];
|
|
4185
|
-
let element = findAncestor(target, SELECTOR_ITEM);
|
|
4186
|
-
if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (getAttribute(element, ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
|
|
4187
|
-
else element = element.nextElementSibling;
|
|
4188
|
-
let insert = "insert";
|
|
4189
|
-
let toInstance;
|
|
4190
|
-
let toState;
|
|
4191
|
-
if (element == null) {
|
|
4192
|
-
element = findAncestor(target, SELECTOR$1);
|
|
4193
|
-
toInstance = globals.instances.get(element)?.sortable;
|
|
4194
|
-
toState = globals.states.get(element)?.sortable;
|
|
4195
|
-
insert = element == null ? void 0 : element.children.length === 0 ? "append" : "prepend";
|
|
4196
|
-
} else {
|
|
4197
|
-
toInstance = globals.instances.get(element.parentElement)?.sortable;
|
|
4198
|
-
toState = globals.states.get(element.parentElement)?.sortable;
|
|
4199
|
-
}
|
|
4200
|
-
const valid = insert != null && validatePosition(globals, item, {
|
|
4201
|
-
instance: toInstance,
|
|
4202
|
-
state: toState
|
|
4203
|
-
}, position);
|
|
4204
|
-
const options = {
|
|
4205
|
-
detail: valid ? {
|
|
4206
|
-
from: {
|
|
4207
|
-
element: origin,
|
|
4208
|
-
position: { ...globals.original }
|
|
4209
|
-
},
|
|
4210
|
-
to: {
|
|
4211
|
-
element,
|
|
4212
|
-
position: { ...position }
|
|
4213
|
-
}
|
|
4214
|
-
} : void 0,
|
|
4215
|
-
bubbles: false,
|
|
4216
|
-
cancelable: true
|
|
4217
|
-
};
|
|
4218
|
-
const dispatchedFrom = dispatch(item.instance.element, "sortable:end", options);
|
|
4219
|
-
let dispatchedTo;
|
|
4220
|
-
if (item.instance !== toInstance && toInstance != null) dispatchedTo = dispatch(toInstance.element, "sortable:end", options);
|
|
4221
|
-
setTimeout(() => {
|
|
4222
|
-
afterEnd(insert, item, [dispatchedFrom, dispatchedTo], {
|
|
4223
|
-
origin,
|
|
4224
|
-
target: element
|
|
4225
|
-
}, position, valid);
|
|
4226
|
-
reset();
|
|
4227
|
-
});
|
|
4228
|
-
}
|
|
4229
|
-
function onMove(event, globals, item, position) {
|
|
4230
|
-
const fromElement = item.state.origin;
|
|
4231
|
-
const toElement = findAncestor(event, SELECTOR_ITEM);
|
|
4232
|
-
let toInstance;
|
|
4233
|
-
let toState;
|
|
4234
|
-
if (toElement == null) {
|
|
4235
|
-
const element = findAncestor(event, SELECTOR$1);
|
|
4236
|
-
toInstance = globals.instances.get(element)?.sortable;
|
|
4237
|
-
toState = globals.states.get(element)?.sortable;
|
|
4238
|
-
} else {
|
|
4239
|
-
toInstance = globals.instances.get(toElement.parentElement)?.sortable;
|
|
4240
|
-
toState = globals.states.get(toElement.parentElement)?.sortable;
|
|
4241
|
-
}
|
|
4242
|
-
if (toInstance == null || !validatePosition(globals, item, {
|
|
4243
|
-
instance: toInstance,
|
|
4244
|
-
state: toState
|
|
4245
|
-
}, position.original)) return;
|
|
4246
|
-
const placeholder = getPositionPlaceholder(item);
|
|
4247
|
-
if (toElement != null && toElement !== fromElement) {
|
|
4248
|
-
const { height, top } = toElement.getBoundingClientRect();
|
|
4249
|
-
let place;
|
|
4250
|
-
if (position.calculated.y < top + height / 2) {
|
|
4251
|
-
place = "before";
|
|
4252
|
-
toElement.insertAdjacentElement("beforebegin", placeholder);
|
|
4253
|
-
} else {
|
|
4254
|
-
place = "after";
|
|
4255
|
-
toElement.insertAdjacentElement("afterend", placeholder);
|
|
4256
|
-
}
|
|
4257
|
-
setAttribute(placeholder, ATTRIBUTE_PLACEHOLDER_POSITION, place);
|
|
4258
|
-
} else placeholder.remove();
|
|
4259
|
-
return {
|
|
4260
|
-
from: {
|
|
4261
|
-
element: fromElement,
|
|
4262
|
-
position: { ...globals.original }
|
|
4263
|
-
},
|
|
4264
|
-
to: {
|
|
4265
|
-
element: toElement,
|
|
4266
|
-
position: { ...position.calculated }
|
|
4267
|
-
}
|
|
4268
|
-
};
|
|
4269
|
-
}
|
|
4270
|
-
function resetPlaceholders() {
|
|
4271
|
-
placeholder.drag.custom?.remove();
|
|
4272
|
-
placeholder.drag.default?.remove();
|
|
4273
|
-
placeholder.position?.remove();
|
|
4274
|
-
placeholder.drag.custom = void 0;
|
|
4275
|
-
}
|
|
4276
|
-
function setPlaceholder(state, item, origin) {
|
|
4277
|
-
const element = getDragPlaceholder();
|
|
4278
|
-
placeholder.drag.default.innerHTML = "";
|
|
4279
|
-
updatePlaceholder(item, element);
|
|
4280
|
-
const dispatched = dispatch(item.instance.element, "sortable:placeholder", { detail: {
|
|
4281
|
-
origin,
|
|
4282
|
-
parent: item.state.element,
|
|
4283
|
-
placeholder: element,
|
|
4284
|
-
create: (value) => {
|
|
4285
|
-
if (!isHTMLOrSVGElement(value)) return;
|
|
4286
|
-
const element = value;
|
|
4287
|
-
placeholder.drag.custom = element;
|
|
4288
|
-
updatePlaceholder(item, element);
|
|
4289
|
-
state.element = {
|
|
4290
|
-
rectangle: element.getBoundingClientRect(),
|
|
4291
|
-
node: element
|
|
4292
|
-
};
|
|
4293
|
-
}
|
|
4294
|
-
} });
|
|
4295
|
-
setTimeout(() => {
|
|
4296
|
-
if (!dispatched.defaultPrevented && placeholder.drag.custom == null) placeholder.drag.default?.append(element.cloneNode(true));
|
|
4297
|
-
document.body.append(placeholder.drag.custom ?? placeholder.drag.default ?? "");
|
|
4298
|
-
});
|
|
4299
|
-
}
|
|
4300
|
-
function updatePlaceholder(item, element) {
|
|
4301
|
-
setAttribute(element, ATTRIBUTE_PLACEHOLDER_DRAG, "");
|
|
4302
|
-
setStyle(element, "position", "fixed");
|
|
4303
|
-
const state = getDraggableStates(item.state.element)?.sortable;
|
|
4304
|
-
if (state == null) return;
|
|
4305
|
-
setAttributes(element, {
|
|
4306
|
-
[ATTRIBUTE_HORIZONTAL$1]: state.horizontal ? "" : void 0,
|
|
4307
|
-
[ATTRIBUTE_VERTICAL]: state.vertical ? "" : void 0
|
|
4308
|
-
});
|
|
4309
|
-
}
|
|
4310
|
-
function validatePosition(_, from, to, position) {
|
|
4311
|
-
let valid = true;
|
|
4312
|
-
const rectangle = from.state.origin?.getBoundingClientRect();
|
|
4313
|
-
const fromState = getDraggableStates(from.state.element)?.sortable;
|
|
4314
|
-
if (rectangle != null && !(fromState?.horizontal ?? true)) valid = position.x >= rectangle.left && position.x <= rectangle.right;
|
|
4315
|
-
if (valid && rectangle != null && !(fromState?.vertical ?? true)) valid = position.y >= rectangle.top && position.y <= rectangle.bottom;
|
|
4316
|
-
if (valid && from.state.connections != null) valid = to?.state.element.matches(from.state.connections) ?? true;
|
|
4317
|
-
if (valid && to?.state.connections != null) valid = from.state.element.matches(to.state.connections);
|
|
4318
|
-
return valid;
|
|
4319
|
-
}
|
|
4320
|
-
const ATTRIBUTE$1 = "oui-sortable";
|
|
4321
|
-
const ATTRIBUTE_ACTIVE$1 = `${ATTRIBUTE$1}-active`;
|
|
4322
|
-
const ATTRIBUTE_CONNECTIONS = `${ATTRIBUTE$1}-connections`;
|
|
4323
|
-
const ATTRIBUTE_CONTAINER = `${ATTRIBUTE$1}-container`;
|
|
4324
|
-
const ATTRIBUTE_DIRECTION = `${ATTRIBUTE$1}-direction`;
|
|
4325
|
-
const ATTRIBUTE_HORIZONTAL$1 = `${ATTRIBUTE$1}-horizontal`;
|
|
4326
|
-
const ATTRIBUTE_ORIGIN = `${ATTRIBUTE$1}-origin`;
|
|
4327
|
-
const ATTRIBUTE_PLACEHOLDER_DRAG = `${ATTRIBUTE$1}-placeholder-drag`;
|
|
4328
|
-
const ATTRIBUTE_PLACEHOLDER_POSITION = `${ATTRIBUTE$1}-placeholder-position`;
|
|
4329
|
-
const ATTRIBUTE_VERTICAL = `${ATTRIBUTE$1}-vertical`;
|
|
4330
|
-
const CONTAINERS = /* @__PURE__ */ new Map();
|
|
4331
|
-
const MESSAGE$1 = "The element must be an instance of HTMLElement or SVGElement";
|
|
4332
|
-
const SELECTOR$1 = `[${ATTRIBUTE$1}]`;
|
|
4333
|
-
const SELECTOR_ITEM = `[${ATTRIBUTE$1}] > *`;
|
|
4334
|
-
const bound = {
|
|
4335
|
-
constructor: OuiSortable,
|
|
4336
|
-
property: "sortable"
|
|
4337
|
-
};
|
|
4338
|
-
const placeholder = {
|
|
4339
|
-
drag: {
|
|
4340
|
-
custom: void 0,
|
|
4341
|
-
default: void 0
|
|
4342
|
-
},
|
|
4343
|
-
position: void 0
|
|
4344
|
-
};
|
|
4345
|
-
const addSortable = addDraggable.bind(bound);
|
|
4346
|
-
attributable(ATTRIBUTE$1, addSortable, removeDraggable.bind(bound));
|
|
4347
|
-
//#endregion
|
|
4348
|
-
//#region node_modules/@oscarpalmer/atoms/dist/math.mjs
|
|
4349
|
-
/**
|
|
4350
|
-
* Round a number
|
|
4351
|
-
*
|
|
4352
|
-
* @param value Number to round
|
|
4353
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
4354
|
-
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
4355
|
-
*/
|
|
4356
|
-
function round(value, decimals) {
|
|
4357
|
-
return roundNumber(Math.round, value, decimals);
|
|
4358
|
-
}
|
|
4359
|
-
function roundNumber(callback, value, decimals) {
|
|
4360
|
-
if (typeof value !== "number") return NaN;
|
|
4361
|
-
if (typeof decimals !== "number" || decimals < 1) return callback(value);
|
|
4362
|
-
const mod = 10 ** decimals;
|
|
4363
|
-
return callback((value + Number.EPSILON) * mod) / mod;
|
|
4364
|
-
}
|
|
4365
|
-
//#endregion
|
|
4366
|
-
//#region src/js/splitter.ts
|
|
4367
|
-
const ATTRIBUTE_MAX = "max";
|
|
4368
|
-
const ATTRIBUTE_MIN = "min";
|
|
4369
|
-
const ATTRIBUTE_SIZE = "size";
|
|
4370
|
-
const ATTRIBUTE_TYPE = "type";
|
|
4371
|
-
var OuiSplitter = class {
|
|
4372
|
-
element;
|
|
4373
|
-
handle;
|
|
4374
|
-
panels;
|
|
4375
|
-
rectangle;
|
|
4376
|
-
separator;
|
|
4377
|
-
types;
|
|
4378
|
-
values;
|
|
4379
|
-
constructor(element, panels) {
|
|
4380
|
-
this.element = element;
|
|
4381
|
-
this.panels = panels;
|
|
4382
|
-
if (isNullableOrWhitespace(element.id)) element.id = `oui_splitter_${++index}`;
|
|
4383
|
-
this.values = getValues(element);
|
|
4384
|
-
this.handle = createHandle();
|
|
4385
|
-
this.rectangle = element.getBoundingClientRect();
|
|
4386
|
-
this.separator = createSeparator(this);
|
|
4387
|
-
this.separator.append(this.handle);
|
|
4388
|
-
panels[0].insertAdjacentElement("afterend", this.separator);
|
|
4389
|
-
this.updateOrientation();
|
|
4390
|
-
this.updateValues();
|
|
4391
|
-
}
|
|
4392
|
-
updateConnections(add) {
|
|
4393
|
-
const method = METHODS_CONNECT[add];
|
|
4394
|
-
MAPPED_ELEMENTS[method](this.element, this);
|
|
4395
|
-
MAPPED_ELEMENTS[method](this.handle, this);
|
|
4396
|
-
MAPPED_ELEMENTS[method](this.separator, this);
|
|
4397
|
-
if (this.types.auto) RESIZE_OBSERVER[METHODS_OBSERVE[add]](this.element);
|
|
4398
|
-
}
|
|
4399
|
-
updateOrientation() {
|
|
4400
|
-
this.types = getTypes(this);
|
|
4401
|
-
if (this.types.auto) RESIZE_OBSERVER.observe(this.element);
|
|
4402
|
-
else RESIZE_OBSERVER.unobserve(this.element);
|
|
4403
|
-
setAttribute(this.element, ATTRIBUTE_HORIZONTAL, this.types.horizontal ? "" : void 0);
|
|
4404
|
-
setAriaOrientation(this);
|
|
4405
|
-
}
|
|
4406
|
-
updateValues() {
|
|
4407
|
-
this.values = getValues(this.element);
|
|
4408
|
-
requestAnimationFrame(() => {
|
|
4409
|
-
setSize(this, this.values.now.current);
|
|
4410
|
-
setAriaValue(this);
|
|
4411
|
-
});
|
|
4412
|
-
}
|
|
4413
|
-
};
|
|
4414
|
-
var OuiSplitterElement = class extends HTMLElement {
|
|
4415
|
-
static observedAttributes = [
|
|
4416
|
-
ATTRIBUTE_MAX,
|
|
4417
|
-
ATTRIBUTE_MIN,
|
|
4418
|
-
ATTRIBUTE_SIZE,
|
|
4419
|
-
ATTRIBUTE_TYPE
|
|
4420
|
-
];
|
|
4421
|
-
#splitter;
|
|
4422
|
-
/**
|
|
4423
|
-
* Maximum size for the first panel
|
|
4424
|
-
*/
|
|
4425
|
-
get max() {
|
|
4426
|
-
return this.#splitter.values.max;
|
|
4427
|
-
}
|
|
4428
|
-
/**
|
|
4429
|
-
* Maximum size for the first panel
|
|
4430
|
-
*/
|
|
4431
|
-
set max(value) {
|
|
4432
|
-
if (typeof value === "number") setAttribute(this, ATTRIBUTE_MAX, value.toString());
|
|
4433
|
-
}
|
|
4434
|
-
/**
|
|
4435
|
-
* Minimum size for the first panel
|
|
4436
|
-
*/
|
|
4437
|
-
get min() {
|
|
4438
|
-
return this.#splitter.values.min;
|
|
4439
|
-
}
|
|
4440
|
-
/**
|
|
4441
|
-
* Minimum size for the first panel
|
|
4442
|
-
*/
|
|
4443
|
-
set min(value) {
|
|
4444
|
-
if (typeof value === "number") setAttribute(this, ATTRIBUTE_MIN, value.toString());
|
|
4445
|
-
}
|
|
4446
|
-
/**
|
|
4447
|
-
* Current size for the first panel
|
|
4448
|
-
*/
|
|
4449
|
-
get size() {
|
|
4450
|
-
return this.#splitter.values.now.current;
|
|
4451
|
-
}
|
|
4452
|
-
/**
|
|
4453
|
-
* Current size for the first panel
|
|
4454
|
-
*/
|
|
4455
|
-
set size(value) {
|
|
4456
|
-
if (typeof value === "number") setAttribute(this, ATTRIBUTE_SIZE, value.toString());
|
|
4457
|
-
}
|
|
4458
|
-
/**
|
|
4459
|
-
* Orientation of the splitter
|
|
4460
|
-
*/
|
|
4461
|
-
get type() {
|
|
4462
|
-
return getAttribute(this, ATTRIBUTE_TYPE) ?? "vertical";
|
|
4463
|
-
}
|
|
4464
|
-
/**
|
|
4465
|
-
* Orientation of the splitter
|
|
4466
|
-
*/
|
|
4467
|
-
set type(value) {
|
|
4468
|
-
setAttribute(this, ATTRIBUTE_TYPE, value);
|
|
4469
|
-
}
|
|
4470
|
-
constructor() {
|
|
4471
|
-
super();
|
|
4472
|
-
const panels = [...this.children].filter((child) => child instanceof Element);
|
|
4473
|
-
if (panels.length !== 2) throw new Error(MESSAGE);
|
|
4474
|
-
this.#splitter = new OuiSplitter(this, panels);
|
|
4475
|
-
}
|
|
4476
|
-
connectedCallback() {
|
|
4477
|
-
this.#splitter.updateConnections(1);
|
|
4478
|
-
}
|
|
4479
|
-
disconnectedCallback() {
|
|
4480
|
-
this.#splitter.updateConnections(0);
|
|
4481
|
-
}
|
|
4482
|
-
attributeChangedCallback(name) {
|
|
4483
|
-
switch (name) {
|
|
4484
|
-
case ATTRIBUTE_MAX:
|
|
4485
|
-
case ATTRIBUTE_MIN:
|
|
4486
|
-
case ATTRIBUTE_SIZE:
|
|
4487
|
-
this.#splitter.updateValues();
|
|
4488
|
-
break;
|
|
4489
|
-
case ATTRIBUTE_TYPE:
|
|
4490
|
-
this.#splitter.updateOrientation();
|
|
4491
|
-
break;
|
|
4492
|
-
default: break;
|
|
4493
|
-
}
|
|
4494
|
-
}
|
|
4495
|
-
};
|
|
4496
|
-
function createHandle() {
|
|
4497
|
-
const handle = document.createElement("span");
|
|
4498
|
-
setAria(handle, "hidden", "true");
|
|
4499
|
-
setAttribute(handle, ATTRIBUTE_HANDLE, "");
|
|
4500
|
-
return handle;
|
|
4501
|
-
}
|
|
4502
|
-
function createSeparator(splitter) {
|
|
4503
|
-
const separator = document.createElement("div");
|
|
4504
|
-
separator.role = "separator";
|
|
4505
|
-
separator.tabIndex = 0;
|
|
4506
|
-
setAria(separator, {
|
|
4507
|
-
controls: splitter.element.id,
|
|
4508
|
-
label: "Resize panels"
|
|
4509
|
-
});
|
|
4510
|
-
setAttribute(separator, ATTRIBUTE_SEPARATOR, "");
|
|
4511
|
-
return separator;
|
|
4512
|
-
}
|
|
4513
|
-
function getContained(min, value, max) {
|
|
4514
|
-
return round(clamp(value, min, max), VALUE_DECIMALS);
|
|
4515
|
-
}
|
|
4516
|
-
function getSize(splitter, value) {
|
|
4517
|
-
const { height, left, top, width } = splitter.rectangle;
|
|
4518
|
-
const fraction = (value - (splitter.types.horizontal ? top : left)) / (splitter.types.horizontal ? height : width);
|
|
4519
|
-
return getContained(splitter.values.min, fraction, splitter.values.max);
|
|
4520
|
-
}
|
|
4521
|
-
function getTypes(splitter, width, height) {
|
|
4522
|
-
const type = getAttribute(splitter.element, "type");
|
|
4523
|
-
if (type === "horizontal") return {
|
|
4524
|
-
auto: false,
|
|
4525
|
-
horizontal: true
|
|
4526
|
-
};
|
|
4527
|
-
if (type === "auto") return {
|
|
4528
|
-
auto: true,
|
|
4529
|
-
horizontal: (height ?? splitter.rectangle.height) > (width ?? splitter.rectangle.width)
|
|
4530
|
-
};
|
|
4531
|
-
return {
|
|
4532
|
-
auto: false,
|
|
4533
|
-
horizontal: false
|
|
4534
|
-
};
|
|
4535
|
-
}
|
|
4536
|
-
function getValue(element, name, defaultValue) {
|
|
4537
|
-
const value = getAttribute(element, name);
|
|
4538
|
-
if (isNullableOrWhitespace(value)) return defaultValue;
|
|
4539
|
-
const parsed = Number.parseFloat(value);
|
|
4540
|
-
if (Number.isNaN(parsed)) return defaultValue;
|
|
4541
|
-
if (parsed < 0) return defaultValue;
|
|
4542
|
-
return parsed > 1 ? parsed / NAVIGATION_MAXIMUM_TOTAL : parsed;
|
|
4543
|
-
}
|
|
4544
|
-
function getValues(element) {
|
|
4545
|
-
const values = {
|
|
4546
|
-
max: getValue(element, ATTRIBUTE_MAX, NAVIGATION_MAXIMUM_PERCENTAGE),
|
|
4547
|
-
min: getValue(element, ATTRIBUTE_MIN, NAVIGATION_MINIMUM_PERCENTAGE),
|
|
4548
|
-
now: {
|
|
4549
|
-
current: .5,
|
|
4550
|
-
previous: .5
|
|
4551
|
-
}
|
|
4552
|
-
};
|
|
4553
|
-
const value = getContained(values.min, getValue(element, ATTRIBUTE_SIZE, values.now.current), values.max);
|
|
4554
|
-
values.now.current = value;
|
|
4555
|
-
values.now.previous = value;
|
|
4556
|
-
return values;
|
|
4557
|
-
}
|
|
4558
|
-
function onEnd(reset) {
|
|
4559
|
-
if (splitter == null) return;
|
|
4560
|
-
splitter.handle.removeAttribute(ATTRIBUTE_ACTIVE);
|
|
4561
|
-
splitter.separator.removeAttribute(ATTRIBUTE_ACTIVE);
|
|
4562
|
-
if (reset) setSize(splitter, splitter.values.now.previous);
|
|
4563
|
-
else splitter.values.now.previous = splitter.values.now.current;
|
|
4564
|
-
splitter = void 0;
|
|
4565
|
-
STYLING_TOGGLER.remove();
|
|
4566
|
-
}
|
|
4567
|
-
function onKeydown(event) {
|
|
4568
|
-
switch (true) {
|
|
4569
|
-
case KEYS_ALL.has(event.key):
|
|
4570
|
-
onNavigate(event);
|
|
4571
|
-
break;
|
|
4572
|
-
case event.key === "Escape":
|
|
4573
|
-
onEnd(true);
|
|
4574
|
-
break;
|
|
4575
|
-
default: break;
|
|
4576
|
-
}
|
|
4577
|
-
}
|
|
4578
|
-
function onNavigate(event) {
|
|
4579
|
-
const splitter = MAPPED_ELEMENTS.get(findAncestor(event, "[oui-splitter-separator]"));
|
|
4580
|
-
if (splitter == null) return;
|
|
4581
|
-
const { types, values } = splitter;
|
|
4582
|
-
if (KEYS_ABSOLUTE.has(event.key)) {
|
|
4583
|
-
setSize(splitter, event.key === "End" ? values.max : values.min, true);
|
|
4584
|
-
return;
|
|
4585
|
-
}
|
|
4586
|
-
if (types.horizontal && !KEYS_HORIZONTAL.has(event.key) || !(types.horizontal || KEYS_VERTICAL.has(event.key))) return;
|
|
4587
|
-
const offset = KEYS_NEGATIVE.has(event.key) ? -1 : 1;
|
|
4588
|
-
setSize(splitter, getContained(values.min, values.now.current + offset * NAVIGATION_MODIFIER, values.max), true);
|
|
4589
|
-
}
|
|
4590
|
-
function onObservation(entries) {
|
|
4591
|
-
if (frame != null) cancelAnimationFrame(frame);
|
|
4592
|
-
frame = requestAnimationFrame(() => {
|
|
4593
|
-
for (const entry of entries) {
|
|
4594
|
-
const splitter = MAPPED_ELEMENTS.get(entry.target);
|
|
4595
|
-
if (splitter == null) return;
|
|
4596
|
-
splitter.types = getTypes(splitter, entry.contentRect.width, entry.contentRect.height);
|
|
4597
|
-
setAttribute(splitter.element, ATTRIBUTE_HORIZONTAL, splitter.types.horizontal ? "" : void 0);
|
|
4598
|
-
setAriaOrientation(splitter);
|
|
4599
|
-
}
|
|
4600
|
-
frame = void 0;
|
|
4601
|
-
});
|
|
4602
|
-
}
|
|
4603
|
-
function onPointerdown(event) {
|
|
4604
|
-
if (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart") return;
|
|
4605
|
-
splitter = MAPPED_ELEMENTS.get(findAncestor(event, SELECTOR_HANDLE));
|
|
4606
|
-
if (splitter == null) return;
|
|
4607
|
-
if (supportsTouch.value) event.preventDefault();
|
|
4608
|
-
setAttribute(splitter.handle, ATTRIBUTE_ACTIVE, "");
|
|
4609
|
-
setAttribute(splitter.separator, ATTRIBUTE_ACTIVE, "");
|
|
4610
|
-
splitter.rectangle = splitter.element.getBoundingClientRect();
|
|
4611
|
-
STYLING_TOGGLER.set();
|
|
4612
|
-
}
|
|
4613
|
-
function onPointermove$1(event) {
|
|
4614
|
-
if (splitter == null) return;
|
|
4615
|
-
const position = getPosition$1(event);
|
|
4616
|
-
if (position != null) {
|
|
4617
|
-
splitter.values.now.current = getSize(splitter, splitter.types.horizontal ? position.y : position.x);
|
|
4618
|
-
setSize(splitter, splitter.values.now.current);
|
|
4619
|
-
}
|
|
4620
|
-
}
|
|
4621
|
-
function onPointerup() {
|
|
4622
|
-
if (splitter != null) onEnd(false);
|
|
4623
|
-
}
|
|
4624
|
-
function setAriaOrientation(splitter) {
|
|
4625
|
-
setAria(splitter.separator, "orientation", splitter.types.horizontal ? "horizontal" : "vertical");
|
|
4626
|
-
}
|
|
4627
|
-
function setAriaValue(splitter) {
|
|
4628
|
-
setAria(splitter.separator, {
|
|
4629
|
-
valuemax: splitter.values.max,
|
|
4630
|
-
valuemin: splitter.values.min,
|
|
4631
|
-
valuenow: splitter.values.now.current
|
|
4632
|
-
});
|
|
4633
|
-
}
|
|
4634
|
-
function setSize(splitter, size, previous) {
|
|
4635
|
-
splitter.values.now.current = size;
|
|
4636
|
-
if (previous) splitter.values.now.previous = size;
|
|
4637
|
-
setStyle(splitter.element, "--oui-splitter-size", `${size}`);
|
|
4638
|
-
setAriaValue(splitter);
|
|
4639
|
-
}
|
|
4640
|
-
const TAGNAME = "oui-splitter";
|
|
4641
|
-
const ATTRIBUTE_ACTIVE = `${TAGNAME}-active`;
|
|
4642
|
-
const ATTRIBUTE_HANDLE = `${TAGNAME}-handle`;
|
|
4643
|
-
const ATTRIBUTE_HORIZONTAL = `${TAGNAME}-horizontal`;
|
|
4644
|
-
const ATTRIBUTE_SEPARATOR = `${TAGNAME}-separator`;
|
|
4645
|
-
const KEYS_ABSOLUTE = /* @__PURE__ */ new Set(["End", "Home"]);
|
|
4646
|
-
const KEYS_HORIZONTAL = /* @__PURE__ */ new Set(["ArrowDown", "ArrowUp"]);
|
|
4647
|
-
const KEYS_NEGATIVE = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowUp"]);
|
|
4648
|
-
const KEYS_VERTICAL = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight"]);
|
|
4649
|
-
const KEYS_ALL = /* @__PURE__ */ new Set([
|
|
4650
|
-
...KEYS_ABSOLUTE,
|
|
4651
|
-
...KEYS_HORIZONTAL,
|
|
4652
|
-
...KEYS_VERTICAL
|
|
4653
|
-
]);
|
|
4654
|
-
const MAPPED_ELEMENTS = /* @__PURE__ */ new WeakMap();
|
|
4655
|
-
const MESSAGE = `<${TAGNAME}> must have exactly two panels.`;
|
|
4656
|
-
const METHODS_CONNECT = ["delete", "set"];
|
|
4657
|
-
const METHODS_OBSERVE = ["unobserve", "observe"];
|
|
4658
|
-
const NAVIGATION_MAXIMUM_PERCENTAGE = .9;
|
|
4659
|
-
const NAVIGATION_MAXIMUM_TOTAL = 100;
|
|
4660
|
-
const NAVIGATION_MINIMUM_PERCENTAGE = .1;
|
|
4661
|
-
const NAVIGATION_MODIFIER = .05;
|
|
4662
|
-
const RESIZE_OBSERVER = new ResizeObserver(onObservation);
|
|
4663
|
-
const SELECTOR_HANDLE = `[${ATTRIBUTE_HANDLE}]`;
|
|
4664
|
-
const STYLING_TOGGLER = toggleStyles(document.body, {
|
|
4665
|
-
touchAction: "none",
|
|
4666
|
-
userSelect: "none",
|
|
4667
|
-
webkitUserSelect: "none"
|
|
4668
|
-
});
|
|
4669
|
-
const VALUE_DECIMALS = 6;
|
|
4670
|
-
let index = 0;
|
|
4671
|
-
let frame;
|
|
4672
|
-
let splitter;
|
|
4673
|
-
on(document, "keydown", onKeydown);
|
|
4674
|
-
on(document, "mousedown", onPointerdown);
|
|
4675
|
-
on(document, "pointermove", onPointermove$1);
|
|
4676
|
-
on(document, "pointerup", onPointerup);
|
|
4677
|
-
on(document, "touchcancel", onPointerup);
|
|
4678
|
-
on(document, "touchstart", onPointerdown, { passive: false });
|
|
4679
|
-
customElements.define(TAGNAME, OuiSplitterElement);
|
|
4680
|
-
//#endregion
|
|
4681
|
-
//#region src/js/tooltip.ts
|
|
4682
|
-
var OuiTooltip = class {
|
|
4683
|
-
#state;
|
|
4684
|
-
/**
|
|
4685
|
-
* Is the tooltip open?
|
|
4686
|
-
*/
|
|
4687
|
-
get open() {
|
|
4688
|
-
return this === activeTooltip && content.checkVisibility();
|
|
4689
|
-
}
|
|
4690
|
-
/**
|
|
4691
|
-
* Open or close the tooltip
|
|
4692
|
-
*/
|
|
4693
|
-
set open(value) {
|
|
4694
|
-
if (value === true) this.show();
|
|
4695
|
-
else if (value === false) this.hide();
|
|
4696
|
-
}
|
|
4697
|
-
constructor(state) {
|
|
4698
|
-
this.#state = state;
|
|
4699
|
-
state.floatable.update();
|
|
4700
|
-
}
|
|
4701
|
-
/**
|
|
4702
|
-
* Closes the tooltip
|
|
4703
|
-
*/
|
|
4704
|
-
hide() {
|
|
4705
|
-
this.#state.floatable.hide();
|
|
4706
|
-
}
|
|
4707
|
-
/**
|
|
4708
|
-
* Opens the tooltip
|
|
4709
|
-
*/
|
|
4710
|
-
show() {
|
|
4711
|
-
this.#state.floatable.show();
|
|
4712
|
-
}
|
|
4713
|
-
};
|
|
4714
|
-
function activate(event, focus) {
|
|
4715
|
-
const targetAnchor = findAncestor(event, SELECTOR);
|
|
4716
|
-
const targetContent = findAncestor(event, SELECTOR_CONTENT);
|
|
4717
|
-
if (targetAnchor == null && targetContent == null) {
|
|
4718
|
-
if (!focused) {
|
|
4719
|
-
closeTooltip(true, activeState);
|
|
4720
|
-
activeState = void 0;
|
|
4721
|
-
activeTooltip = void 0;
|
|
4722
|
-
}
|
|
4723
|
-
return;
|
|
4724
|
-
}
|
|
4725
|
-
const state = states.get(targetAnchor ?? targetContent);
|
|
4726
|
-
if (state == null || state.tooltip === activeTooltip) return;
|
|
4727
|
-
const shouldDelay = activeTooltip == null;
|
|
4728
|
-
closeTooltip(false, activeState);
|
|
4729
|
-
activeState = state;
|
|
4730
|
-
activeTooltip = state.tooltip;
|
|
4731
|
-
focused = focus;
|
|
4732
|
-
state.timer = setTimeout(() => {
|
|
4733
|
-
content.innerHTML = "";
|
|
4734
|
-
content.append(...state.elements);
|
|
4735
|
-
state.floatable.show();
|
|
4736
|
-
setTimeout(() => {
|
|
4737
|
-
state.floatable.update();
|
|
4738
|
-
});
|
|
4739
|
-
}, shouldDelay ? delay : 0);
|
|
4740
|
-
}
|
|
4741
|
-
function addTooltip(element) {
|
|
4742
|
-
if (!states.has(element)) createTooltip(element);
|
|
4743
|
-
}
|
|
4744
|
-
function closeTooltip(clear, state) {
|
|
4745
|
-
if (state == null) return;
|
|
4746
|
-
if (state.timer != null) clearTimeout(state.timer);
|
|
4747
|
-
if (clear) content?.hidePopover();
|
|
4748
|
-
}
|
|
4749
|
-
function createTooltip(anchor) {
|
|
4750
|
-
const elements = getElements(anchor);
|
|
4751
|
-
if (elements == null) return;
|
|
4752
|
-
states.set(anchor, getState(anchor, elements));
|
|
4753
|
-
}
|
|
4754
|
-
function destroyTooltip(state) {
|
|
4755
|
-
clearTimeout(state.timer);
|
|
4756
|
-
state.floatable.destroy();
|
|
4757
|
-
state.anchor = void 0;
|
|
4758
|
-
state.elements = void 0;
|
|
4759
|
-
state.floatable = void 0;
|
|
4760
|
-
state.tooltip = void 0;
|
|
4761
|
-
}
|
|
4762
|
-
function findElements(attribute) {
|
|
4763
|
-
if (attribute == null) return;
|
|
4764
|
-
const ids = attribute?.split(EXPRESSION_WHITESPACE) ?? [];
|
|
4765
|
-
const elements = [];
|
|
4766
|
-
for (const id of ids) {
|
|
4767
|
-
if (isNullableOrWhitespace(id)) continue;
|
|
4768
|
-
const element = document.querySelector(`#${id}`);
|
|
4769
|
-
if (element != null) {
|
|
4770
|
-
const cloned = element.cloneNode(true);
|
|
4771
|
-
cloned.hidden = false;
|
|
4772
|
-
elements.push(cloned);
|
|
4773
|
-
}
|
|
4774
|
-
}
|
|
4775
|
-
return elements;
|
|
4776
|
-
}
|
|
4777
|
-
function getContent() {
|
|
4778
|
-
const content = createElement("div", {
|
|
4779
|
-
popover: "hint",
|
|
4780
|
-
role: "tooltip",
|
|
4781
|
-
tabIndex: -1
|
|
4782
|
-
});
|
|
4783
|
-
setAttribute(content, ATTRIBUTE_CONTENT, "");
|
|
4784
|
-
return content;
|
|
4785
|
-
}
|
|
4786
|
-
function getElements(anchor) {
|
|
4787
|
-
let elements = findElements(getAria(anchor, "labelledby"));
|
|
4788
|
-
if (elements == null || elements.length === 0) elements = findElements(getAria(anchor, "describedby"));
|
|
4789
|
-
if (elements != null && elements.length > 0) return elements;
|
|
4790
|
-
let text = getAria(anchor, "label");
|
|
4791
|
-
if (isNullableOrWhitespace(text)) text = getAria(anchor, "description");
|
|
4792
|
-
if (isNullableOrWhitespace(text)) return;
|
|
4793
|
-
const paragraph = document.createElement("p");
|
|
4794
|
-
paragraph.textContent = text;
|
|
4795
|
-
return [paragraph];
|
|
4796
|
-
}
|
|
4797
|
-
function getState(anchor, elements) {
|
|
4798
|
-
const state = {
|
|
4799
|
-
anchor,
|
|
4800
|
-
elements,
|
|
4801
|
-
floatable: createEmbeddedFloatable(anchor, content, options),
|
|
4802
|
-
tooltip: null
|
|
4803
|
-
};
|
|
4804
|
-
state.tooltip = new OuiTooltip(state);
|
|
4805
|
-
return state;
|
|
4806
|
-
}
|
|
4807
|
-
/**
|
|
4808
|
-
* Get the _OuiTooltip_ for an element
|
|
4809
|
-
*
|
|
4810
|
-
* @param element Element to get _OuiTooltip_ for
|
|
4811
|
-
* @returns _OuiTooltip_ instance
|
|
4812
|
-
*/
|
|
4813
|
-
function getTooltip(element) {
|
|
4814
|
-
return states.get(element)?.tooltip;
|
|
4815
|
-
}
|
|
4816
|
-
function onFocusin(event) {
|
|
4817
|
-
activate(event, true);
|
|
4818
|
-
}
|
|
4819
|
-
function onFocusout() {
|
|
4820
|
-
if (activeTooltip == null) return;
|
|
4821
|
-
if (focusTimer != null) clearTimeout(focusTimer);
|
|
4822
|
-
focusTimer = setTimeout(() => {
|
|
4823
|
-
if (activeTooltip == null || document.activeElement == null || findAncestor(document.activeElement, SELECTOR) != null) return;
|
|
4824
|
-
closeTooltip(true, activeState);
|
|
4825
|
-
activeState = void 0;
|
|
4826
|
-
activeTooltip = void 0;
|
|
4827
|
-
});
|
|
4828
|
-
}
|
|
4829
|
-
function onPointermove(event) {
|
|
4830
|
-
activate(event, false);
|
|
4831
|
-
}
|
|
4832
|
-
function onToggle(event) {
|
|
4833
|
-
setAttribute(content, ATTRIBUTE_CONTENT_OPEN, event.newState === "open" ? "" : void 0);
|
|
4834
|
-
}
|
|
4835
|
-
function removeTooltip(element) {
|
|
4836
|
-
const state = states.get(element);
|
|
4837
|
-
if (state == null) return;
|
|
4838
|
-
destroyTooltip(state);
|
|
4839
|
-
states.delete(element);
|
|
4840
|
-
}
|
|
4841
|
-
/**
|
|
4842
|
-
* Set the delay before showing the tooltip, in milliseconds
|
|
4843
|
-
*
|
|
4844
|
-
* _(Default delay is half a second, or 500 milliseconds)_
|
|
4845
|
-
* @param value Delay in milliseconds
|
|
4846
|
-
*/
|
|
4847
|
-
function setTooltipDelay(value) {
|
|
4848
|
-
if (typeof value === "number" && !Number.isNaN(value) && value >= 0) delay = value;
|
|
4849
|
-
}
|
|
4850
|
-
const EXPRESSION_WHITESPACE = /\s+/;
|
|
4851
|
-
const ATTRIBUTE = "oui-tooltip";
|
|
4852
|
-
const ATTRIBUTE_CONTENT = `${ATTRIBUTE}-content`;
|
|
4853
|
-
const ATTRIBUTE_CONTENT_OPEN = `${ATTRIBUTE_CONTENT}-open`;
|
|
4854
|
-
const SELECTOR = `[${ATTRIBUTE}]`;
|
|
4855
|
-
const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
|
|
4856
|
-
const content = getContent();
|
|
4857
|
-
const states = /* @__PURE__ */ new WeakMap();
|
|
4858
|
-
const options = {
|
|
4859
|
-
attribute: `${ATTRIBUTE}-position`,
|
|
4860
|
-
position: "above",
|
|
4861
|
-
reusable: true
|
|
4862
|
-
};
|
|
4863
|
-
let delay = 500;
|
|
4864
|
-
let focused = false;
|
|
4865
|
-
let activeState;
|
|
4866
|
-
let activeTooltip;
|
|
4867
|
-
let focusTimer;
|
|
4868
|
-
document.body.append(content);
|
|
4869
|
-
on(content, "toggle", onToggle);
|
|
4870
|
-
on(document, "focusin", onFocusin);
|
|
4871
|
-
on(document, "focusout", onFocusout);
|
|
4872
|
-
on(document, "pointermove", onPointermove);
|
|
4873
|
-
attributable(ATTRIBUTE, addTooltip, removeTooltip);
|
|
4874
|
-
//#endregion
|
|
4875
|
-
export { OuiComboboxElement, OuiSplitterElement, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setLocalizations, setTooltipDelay };
|
|
1
|
+
import { createFloatable } from "./floatable/floatable.embedded.mjs";
|
|
2
|
+
import { createMovable } from "./movable/movable.embedded.mjs";
|
|
3
|
+
import "./movable/movable.standalone.mjs";
|
|
4
|
+
import { createResizable } from "./resizable/resizable.embedded.mjs";
|
|
5
|
+
import { getDialog } from "./dialog.mjs";
|
|
6
|
+
import "./menu.mjs";
|
|
7
|
+
import "./toolbar.mjs";
|
|
8
|
+
import { ot as setComboboxLocalizations } from "./data.combobox-B8HMkDOh.mjs";
|
|
9
|
+
import { OuiComboboxElement } from "./combobox/index.mjs";
|
|
10
|
+
import "./floatable/floatable.standalone.mjs";
|
|
11
|
+
import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
|
|
12
|
+
import "./focus-trap/focus-trap.standalone.mjs";
|
|
13
|
+
import { getPopover } from "./popover.mjs";
|
|
14
|
+
import "./resizable/resizable.standalone.mjs";
|
|
15
|
+
import { createSortable } from "./sortable/sortable.embedded.mjs";
|
|
16
|
+
import "./sortable/sortable.standalone.mjs";
|
|
17
|
+
import { OuiSplitterElement } from "./splitter.mjs";
|
|
18
|
+
import { getTooltip, setTooltipDelay } from "./tooltip.mjs";
|
|
19
|
+
export { OuiComboboxElement, OuiSplitterElement, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setComboboxLocalizations, setTooltipDelay };
|