@oscarpalmer/oui 0.29.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/combobox.css +26 -0
- package/dist/js/combobox.d.mts +27 -0
- package/dist/js/combobox.mjs +474 -0
- package/dist/js/dialog.d.mts +4 -3
- package/dist/js/dialog.mjs +1 -1
- package/dist/js/{draggable-fIYXd8eO.d.mts → draggable-a6w0J1OD.d.mts} +1 -2
- package/dist/js/floatable/floatable.embedded.d.mts +1 -1
- package/dist/js/floatable/floatable.embedded.mjs +2 -2
- package/dist/js/floatable/floatable.standalone.d.mts +1 -1
- package/dist/js/{floatable.embedded-DUR8bQBK.d.mts → floatable.embedded-Bct4U5Dm.d.mts} +0 -1
- package/dist/js/focus-trap/focus-trap.embedded.mjs +13 -8
- package/dist/js/index.d.mts +9 -4
- package/dist/js/index.mjs +2 -1
- package/dist/js/internal/draggable.d.mts +1 -1
- package/dist/js/internal/draggable.mjs +24 -15
- package/dist/js/internal/navigable.d.mts +0 -1
- package/dist/js/internal/navigable.mjs +4 -3
- package/dist/js/menu.mjs +1 -1
- package/dist/js/movable/movable.embedded.d.mts +1 -1
- package/dist/js/movable/movable.embedded.mjs +3 -4
- package/dist/js/movable/movable.standalone.d.mts +1 -1
- package/dist/js/popover.d.mts +1 -2
- package/dist/js/popover.mjs +1 -1
- package/dist/js/resizable/resizable.embedded.d.mts +1 -1
- package/dist/js/resizable/resizable.embedded.mjs +47 -19
- package/dist/js/resizable/resizable.standalone.d.mts +1 -1
- package/dist/js/{resizable.embedded-CXrUVPzR.d.mts → resizable.embedded-3qoR0Bjm.d.mts} +0 -1
- package/dist/js/sortable/sortable.embedded.d.mts +1 -1
- package/dist/js/sortable/sortable.embedded.mjs +11 -15
- package/dist/js/sortable/sortable.standalone.d.mts +1 -1
- package/dist/js/splitter.d.mts +2 -2
- package/dist/js/splitter.mjs +11 -11
- package/dist/js/tooltip.d.mts +1 -2
- package/dist/js/tooltip.mjs +3 -3
- package/package.json +6 -2
- package/src/css/combobox.scss +26 -0
- package/src/js/combobox.ts +917 -0
- package/src/js/focus-trap/focus-trap.embedded.ts +22 -10
- package/src/js/index.ts +1 -0
- package/src/js/internal/draggable.ts +37 -29
- package/src/js/internal/navigable.ts +5 -1
- package/src/js/movable/movable.embedded.ts +1 -3
- package/src/js/resizable/resizable.embedded.ts +68 -18
- package/src/js/sortable/sortable.embedded.ts +7 -15
- package/src/js/splitter.ts +37 -23
|
@@ -289,19 +289,31 @@ function onTab(event: KeyboardEvent): void {
|
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
292
|
+
const dispatch = new CustomEvent('focus-trap:tab', {
|
|
293
|
+
cancelable: true,
|
|
294
|
+
});
|
|
295
295
|
|
|
296
|
-
|
|
296
|
+
element.dispatchEvent(dispatch);
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
if (dispatch.defaultPrevented) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
299
302
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
if (!instance.disabled) {
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const elements = getFocusable(element);
|
|
308
|
+
|
|
309
|
+
const index = elements.indexOf(event.target as HTMLElement);
|
|
310
|
+
|
|
311
|
+
if (index === -1 || elements.length === 0) {
|
|
312
|
+
tabToTrap(instance, elements, element);
|
|
313
|
+
} else {
|
|
314
|
+
tabToElement(instance, elements, index, event.shiftKey ? -1 : 1);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
305
317
|
}
|
|
306
318
|
|
|
307
319
|
export function removeFocusTrap(element: HTMLElement): void {
|
package/src/js/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {EventPosition, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {clamp} from '@oscarpalmer/atoms/number';
|
|
3
3
|
import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
4
|
-
import {getPosition, on} from '@oscarpalmer/toretto/event';
|
|
4
|
+
import {dispatch, getPosition, on} from '@oscarpalmer/toretto/event';
|
|
5
5
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
6
6
|
import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
|
|
7
7
|
import {setStyle, setStyles, toggleStyles, type StyleToggler} from '@oscarpalmer/toretto/style';
|
|
@@ -27,8 +27,6 @@ type OuiDraggableDirection = 'horizontal' | 'vertical' | 'x' | 'y';
|
|
|
27
27
|
export abstract class OuiDraggable<ExtraState extends PlainObject = PlainObject> {
|
|
28
28
|
#destroyed = false;
|
|
29
29
|
|
|
30
|
-
#name: keyof OuiDraggableStates;
|
|
31
|
-
|
|
32
30
|
readonly #state: OuiDraggableState & ExtraState;
|
|
33
31
|
|
|
34
32
|
get element(): HTMLElement {
|
|
@@ -43,13 +41,12 @@ export abstract class OuiDraggable<ExtraState extends PlainObject = PlainObject>
|
|
|
43
41
|
options: OuiDraggableOptions<ExtraState>,
|
|
44
42
|
extras: ExtraState,
|
|
45
43
|
) {
|
|
46
|
-
this.#name = name;
|
|
47
|
-
|
|
48
44
|
this.#state = {
|
|
49
45
|
...extras,
|
|
50
46
|
attribute,
|
|
51
47
|
element,
|
|
52
48
|
event,
|
|
49
|
+
name,
|
|
53
50
|
options,
|
|
54
51
|
horizontal: true,
|
|
55
52
|
vertical: true,
|
|
@@ -70,7 +67,7 @@ export abstract class OuiDraggable<ExtraState extends PlainObject = PlainObject>
|
|
|
70
67
|
|
|
71
68
|
states ??= {};
|
|
72
69
|
|
|
73
|
-
states[this.#name] = this.#state;
|
|
70
|
+
states[this.#state.name] = this.#state;
|
|
74
71
|
|
|
75
72
|
globals.states.set(element, states);
|
|
76
73
|
}
|
|
@@ -216,9 +213,9 @@ export type OuiDraggableState = {
|
|
|
216
213
|
attribute: string;
|
|
217
214
|
container?: HTMLElement;
|
|
218
215
|
element: HTMLElement;
|
|
219
|
-
event: string;
|
|
220
216
|
hasHandles?: boolean;
|
|
221
217
|
horizontal: boolean;
|
|
218
|
+
name: keyof OuiDraggableStates;
|
|
222
219
|
options: OuiDraggableOptions;
|
|
223
220
|
styling: StyleToggler;
|
|
224
221
|
vertical: boolean;
|
|
@@ -254,6 +251,22 @@ export function addDraggable<
|
|
|
254
251
|
return instances[this.property] as Instance;
|
|
255
252
|
}
|
|
256
253
|
|
|
254
|
+
function cancelDrag(item?: OuiDraggableItem): void {
|
|
255
|
+
if (item == null) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
item.state.options.drag.onCancel?.(globals, item);
|
|
260
|
+
|
|
261
|
+
dispatch(item.state.element, `${item.state.name}:cancel`, {
|
|
262
|
+
detail: {
|
|
263
|
+
element: item.state.options.getOrigin(),
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
reset();
|
|
268
|
+
}
|
|
269
|
+
|
|
257
270
|
function destroyInstance(instance: OuiDraggable, state: OuiDraggableState): void {
|
|
258
271
|
unsetContainer({
|
|
259
272
|
instance,
|
|
@@ -312,21 +325,9 @@ function getNextPosition(item: OuiDraggableItem, position: EventPosition): Event
|
|
|
312
325
|
}
|
|
313
326
|
|
|
314
327
|
function onKeydown(event: KeyboardEvent): void {
|
|
315
|
-
if (current
|
|
316
|
-
|
|
328
|
+
if (current != null && event.key === KEY_ESCAPE) {
|
|
329
|
+
cancelDrag(current);
|
|
317
330
|
}
|
|
318
|
-
|
|
319
|
-
current.state.options.drag.onCancel?.(globals, current);
|
|
320
|
-
|
|
321
|
-
current.state.element.dispatchEvent(
|
|
322
|
-
new CustomEvent(`${current.state.event}:cancel`, {
|
|
323
|
-
detail: {
|
|
324
|
-
element: current.state.options.getOrigin(),
|
|
325
|
-
},
|
|
326
|
-
}),
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
reset();
|
|
330
331
|
}
|
|
331
332
|
|
|
332
333
|
function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
@@ -405,7 +406,7 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
|
405
406
|
globals.offset = item.state.options.position.getOffset(globals, item, element, position);
|
|
406
407
|
globals.original = item.state.options.position.getOriginal(globals, item, position);
|
|
407
408
|
|
|
408
|
-
const
|
|
409
|
+
const dispatch = new CustomEvent(`${item.state.name}:begin`, {
|
|
409
410
|
detail: {
|
|
410
411
|
element,
|
|
411
412
|
position: {...globals.original},
|
|
@@ -413,10 +414,10 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
|
413
414
|
cancelable: true,
|
|
414
415
|
});
|
|
415
416
|
|
|
416
|
-
item.state.element.dispatchEvent(
|
|
417
|
+
item.state.element.dispatchEvent(dispatch);
|
|
417
418
|
|
|
418
419
|
setTimeout(() => {
|
|
419
|
-
if (
|
|
420
|
+
if (dispatch.defaultPrevented) {
|
|
420
421
|
item.state.options.drag.onCancel?.(globals, item);
|
|
421
422
|
|
|
422
423
|
reset();
|
|
@@ -461,11 +462,18 @@ function onPointermove(event: MouseEvent | TouchEvent): void {
|
|
|
461
462
|
original: position,
|
|
462
463
|
});
|
|
463
464
|
|
|
464
|
-
current.state.
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
465
|
+
const dispatch = new CustomEvent(`${current.state.name}:move`, {
|
|
466
|
+
detail,
|
|
467
|
+
cancelable: true,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
current.state.element.dispatchEvent(dispatch);
|
|
471
|
+
|
|
472
|
+
setTimeout(() => {
|
|
473
|
+
if (dispatch.defaultPrevented) {
|
|
474
|
+
cancelDrag(current);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
469
477
|
}
|
|
470
478
|
|
|
471
479
|
function onPointerup(event: MouseEvent | TouchEvent): void {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {clamp} from '@oscarpalmer/atoms/number';
|
|
2
2
|
import {getAria, setRole} from '@oscarpalmer/toretto/aria';
|
|
3
|
-
import {on} from '@oscarpalmer/toretto/event';
|
|
3
|
+
import {dispatch, on} from '@oscarpalmer/toretto/event';
|
|
4
4
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
5
5
|
import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
|
|
6
6
|
import type {AriaRole, RemovableEventListener} from '@oscarpalmer/toretto/models';
|
|
@@ -212,6 +212,10 @@ export function updateNavigableFocus(
|
|
|
212
212
|
if (focus) {
|
|
213
213
|
navigable.active.element?.focus();
|
|
214
214
|
}
|
|
215
|
+
|
|
216
|
+
dispatch(navigable.active.element, 'navigable:change', {
|
|
217
|
+
detail: {...navigable.active},
|
|
218
|
+
});
|
|
215
219
|
}
|
|
216
220
|
|
|
217
221
|
// #endregion
|
|
@@ -199,7 +199,7 @@ function onEnd(
|
|
|
199
199
|
setOffset(state, container);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
const end = new CustomEvent(
|
|
202
|
+
const end = new CustomEvent('movable:end', {
|
|
203
203
|
detail: {
|
|
204
204
|
from: {...globals.original},
|
|
205
205
|
to: getPosition(event),
|
|
@@ -295,8 +295,6 @@ const ATTRIBUTE_MOVING = `${ATTRIBUTE_MOVABLE}-moving`;
|
|
|
295
295
|
|
|
296
296
|
const CONTAINERS = new Map<HTMLElement, Set<OuiMovable>>();
|
|
297
297
|
|
|
298
|
-
const EVENT_END = 'move:end';
|
|
299
|
-
|
|
300
298
|
const MESSAGE = 'The element must be an instance of HTMLElement or SVGElement';
|
|
301
299
|
|
|
302
300
|
const MOVED = new Set<OuiMovable>();
|
|
@@ -2,7 +2,7 @@ import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
|
2
2
|
import type {EventPosition} from '@oscarpalmer/atoms/models';
|
|
3
3
|
import {getNumber} from '@oscarpalmer/atoms/number';
|
|
4
4
|
import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
5
|
-
import {getPosition, on} from '@oscarpalmer/toretto/event';
|
|
5
|
+
import {dispatch, getPosition, on} from '@oscarpalmer/toretto/event';
|
|
6
6
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
7
7
|
import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
|
|
8
8
|
import {setStyles, toggleStyles, type StyleToggler} from '@oscarpalmer/toretto/style';
|
|
@@ -91,6 +91,21 @@ function addResizable(
|
|
|
91
91
|
return item?.instance;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function cancelResize(item?: OuiResizableItem): void {
|
|
95
|
+
if (item == null) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setStyles(item.state.element, {
|
|
100
|
+
height: `${item.state.height}px`,
|
|
101
|
+
width: `${item.state.width}px`,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
resetResizable();
|
|
105
|
+
|
|
106
|
+
dispatch(item.state.element, 'resizable:cancel');
|
|
107
|
+
}
|
|
108
|
+
|
|
94
109
|
/**
|
|
95
110
|
* Creates _(or retrieves)_ a _OuiResizable_ instance for an element
|
|
96
111
|
*
|
|
@@ -245,16 +260,9 @@ function getXAndY(first: unknown, second?: unknown): [number, number] {
|
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
function onKeydown(event: KeyboardEvent): void {
|
|
248
|
-
if (current
|
|
249
|
-
|
|
263
|
+
if (current != null && event.key === 'Escape') {
|
|
264
|
+
cancelResize(current);
|
|
250
265
|
}
|
|
251
|
-
|
|
252
|
-
setStyles(current.state.element, {
|
|
253
|
-
height: `${current.state.height}px`,
|
|
254
|
-
width: `${current.state.width}px`,
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
resetResizable();
|
|
258
266
|
}
|
|
259
267
|
|
|
260
268
|
function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
@@ -283,11 +291,23 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
|
283
291
|
event.preventDefault();
|
|
284
292
|
}
|
|
285
293
|
|
|
286
|
-
|
|
287
|
-
|
|
294
|
+
const dispatch = new CustomEvent('resizable:begin', {
|
|
295
|
+
cancelable: true,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
element!.dispatchEvent(dispatch);
|
|
288
299
|
|
|
289
|
-
|
|
290
|
-
|
|
300
|
+
setTimeout(() => {
|
|
301
|
+
if (dispatch.defaultPrevented) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
current = stored;
|
|
306
|
+
start = position;
|
|
307
|
+
|
|
308
|
+
current.state.styles.set();
|
|
309
|
+
styleToggler.set();
|
|
310
|
+
});
|
|
291
311
|
}
|
|
292
312
|
|
|
293
313
|
function onPointermove(event: MouseEvent | TouchEvent): void {
|
|
@@ -305,6 +325,22 @@ function onPointermove(event: MouseEvent | TouchEvent): void {
|
|
|
305
325
|
const height = current.state.height + (y - (start?.y ?? 0));
|
|
306
326
|
|
|
307
327
|
getAndSetDimensions(current.state.element, current.state.options, {height, width});
|
|
328
|
+
|
|
329
|
+
const dispatch = new CustomEvent('resizable:resize', {
|
|
330
|
+
cancelable: true,
|
|
331
|
+
detail: {
|
|
332
|
+
height,
|
|
333
|
+
width,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
current.state.element.dispatchEvent(dispatch);
|
|
338
|
+
|
|
339
|
+
setTimeout(() => {
|
|
340
|
+
if (dispatch.defaultPrevented) {
|
|
341
|
+
cancelResize(current);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
308
344
|
}
|
|
309
345
|
|
|
310
346
|
function onPointerup(): void {
|
|
@@ -312,12 +348,26 @@ function onPointerup(): void {
|
|
|
312
348
|
return;
|
|
313
349
|
}
|
|
314
350
|
|
|
315
|
-
const
|
|
351
|
+
const dispatch = new CustomEvent('resizable:end', {
|
|
352
|
+
cancelable: true,
|
|
353
|
+
});
|
|
316
354
|
|
|
317
|
-
current.state.
|
|
318
|
-
current.state.width = width;
|
|
355
|
+
current.state.element.dispatchEvent(dispatch);
|
|
319
356
|
|
|
320
|
-
|
|
357
|
+
setTimeout(() => {
|
|
358
|
+
if (current == null || dispatch.defaultPrevented) {
|
|
359
|
+
cancelResize(current);
|
|
360
|
+
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const {height, width} = current.state.element.getBoundingClientRect();
|
|
365
|
+
|
|
366
|
+
current.state.height = height;
|
|
367
|
+
current.state.width = width;
|
|
368
|
+
|
|
369
|
+
resetResizable();
|
|
370
|
+
});
|
|
321
371
|
}
|
|
322
372
|
|
|
323
373
|
function removeResizable(element: HTMLElement): void {
|
|
@@ -110,9 +110,9 @@ function afterEnd(
|
|
|
110
110
|
let insertion: 'afterend' | 'beforebegin';
|
|
111
111
|
|
|
112
112
|
if (position.y < top + height / 2) {
|
|
113
|
-
insertion =
|
|
113
|
+
insertion = 'beforebegin';
|
|
114
114
|
} else {
|
|
115
|
-
insertion =
|
|
115
|
+
insertion = 'afterend';
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
elements.target?.insertAdjacentElement(insertion, elements.origin!);
|
|
@@ -277,8 +277,8 @@ function onEnd(
|
|
|
277
277
|
cancelable: true,
|
|
278
278
|
};
|
|
279
279
|
|
|
280
|
-
const fromEvent = new CustomEvent(
|
|
281
|
-
const toEvent = new CustomEvent(
|
|
280
|
+
const fromEvent = new CustomEvent('sortable:end', options);
|
|
281
|
+
const toEvent = new CustomEvent('sortable:end', options);
|
|
282
282
|
|
|
283
283
|
item.instance.element.dispatchEvent(fromEvent);
|
|
284
284
|
|
|
@@ -340,11 +340,11 @@ function onMove(
|
|
|
340
340
|
if (position.calculated.y < top + height / 2) {
|
|
341
341
|
place = 'before';
|
|
342
342
|
|
|
343
|
-
toElement.insertAdjacentElement(
|
|
343
|
+
toElement.insertAdjacentElement('beforebegin', placeholder);
|
|
344
344
|
} else {
|
|
345
345
|
place = 'after';
|
|
346
346
|
|
|
347
|
-
toElement.insertAdjacentElement(
|
|
347
|
+
toElement.insertAdjacentElement('afterend', placeholder);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
setAttribute(placeholder, ATTRIBUTE_PLACEHOLDER_POSITION, place);
|
|
@@ -383,7 +383,7 @@ function setPlaceholder(
|
|
|
383
383
|
|
|
384
384
|
updatePlaceholder(item, element);
|
|
385
385
|
|
|
386
|
-
const event = new CustomEvent(
|
|
386
|
+
const event = new CustomEvent('sortable:placeholder', {
|
|
387
387
|
cancelable: true,
|
|
388
388
|
detail: {
|
|
389
389
|
origin,
|
|
@@ -492,14 +492,6 @@ const ATTRIBUTE_VERTICAL = `${ATTRIBUTE}-vertical`;
|
|
|
492
492
|
|
|
493
493
|
const CONTAINERS = new Map<HTMLElement, Set<OuiSortable>>();
|
|
494
494
|
|
|
495
|
-
const EVENT_END = 'sort:end';
|
|
496
|
-
|
|
497
|
-
const EVENT_PLACEHOLDER = 'sort:placeholder';
|
|
498
|
-
|
|
499
|
-
const INSERT_AFTER = 'afterend';
|
|
500
|
-
|
|
501
|
-
const INSERT_BEFORE = 'beforebegin';
|
|
502
|
-
|
|
503
495
|
const MESSAGE = 'The element must be an instance of HTMLElement or SVGElement';
|
|
504
496
|
|
|
505
497
|
const SELECTOR = `[${ATTRIBUTE}]`;
|
package/src/js/splitter.ts
CHANGED
|
@@ -5,14 +5,10 @@ import {setAria} from '@oscarpalmer/toretto/aria';
|
|
|
5
5
|
import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
6
6
|
import {getPosition, on} from '@oscarpalmer/toretto/event';
|
|
7
7
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
8
|
-
import {setStyle,
|
|
8
|
+
import {setStyle, toggleStyles} from '@oscarpalmer/toretto/style';
|
|
9
9
|
import supportsTouch from '@oscarpalmer/toretto/touch';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
interface HTMLElementTagNameMap {
|
|
13
|
-
[SELECTOR]: OuiSplitterElement;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
11
|
+
// #region Special variables
|
|
16
12
|
|
|
17
13
|
const ATTRIBUTE_MAX = 'max';
|
|
18
14
|
|
|
@@ -22,6 +18,16 @@ const ATTRIBUTE_SIZE = 'size';
|
|
|
22
18
|
|
|
23
19
|
const ATTRIBUTE_TYPE = 'type';
|
|
24
20
|
|
|
21
|
+
// #endregion
|
|
22
|
+
|
|
23
|
+
// #region Types
|
|
24
|
+
|
|
25
|
+
declare global {
|
|
26
|
+
interface HTMLElementTagNameMap {
|
|
27
|
+
[TAGNAME]: OuiSplitterElement;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
class OuiSplitter {
|
|
26
32
|
element: OuiSplitterElement;
|
|
27
33
|
|
|
@@ -227,7 +233,9 @@ type OuiSplitterValuesNow = {
|
|
|
227
233
|
previous: number;
|
|
228
234
|
};
|
|
229
235
|
|
|
230
|
-
//
|
|
236
|
+
// #endregion
|
|
237
|
+
|
|
238
|
+
// #region Functions
|
|
231
239
|
|
|
232
240
|
function createHandle(): HTMLSpanElement {
|
|
233
241
|
const handle = document.createElement('span');
|
|
@@ -498,31 +506,33 @@ function setSize(splitter: OuiSplitter, size: number, previous?: boolean): void
|
|
|
498
506
|
setAriaValue(splitter);
|
|
499
507
|
}
|
|
500
508
|
|
|
501
|
-
//
|
|
509
|
+
// #endregion
|
|
502
510
|
|
|
503
|
-
|
|
511
|
+
// #region Variables
|
|
504
512
|
|
|
505
|
-
const
|
|
513
|
+
const TAGNAME = 'oui-splitter';
|
|
506
514
|
|
|
507
|
-
const
|
|
515
|
+
const ATTRIBUTE_ACTIVE = `${TAGNAME}-active`;
|
|
508
516
|
|
|
509
|
-
const
|
|
517
|
+
const ATTRIBUTE_HANDLE = `${TAGNAME}-handle`;
|
|
510
518
|
|
|
511
|
-
const
|
|
519
|
+
const ATTRIBUTE_HORIZONTAL = `${TAGNAME}-horizontal`;
|
|
512
520
|
|
|
513
|
-
const
|
|
521
|
+
const ATTRIBUTE_SEPARATOR = `${TAGNAME}-separator`;
|
|
514
522
|
|
|
515
|
-
const
|
|
523
|
+
const KEYS_ABSOLUTE = new Set(['End', 'Home']);
|
|
516
524
|
|
|
517
|
-
const
|
|
525
|
+
const KEYS_HORIZONTAL = new Set(['ArrowDown', 'ArrowUp']);
|
|
518
526
|
|
|
519
|
-
const
|
|
527
|
+
const KEYS_NEGATIVE = new Set(['ArrowLeft', 'ArrowUp']);
|
|
520
528
|
|
|
521
|
-
const
|
|
529
|
+
const KEYS_VERTICAL = new Set(['ArrowLeft', 'ArrowRight']);
|
|
522
530
|
|
|
523
|
-
const
|
|
531
|
+
const KEYS_ALL = new Set([...KEYS_ABSOLUTE, ...KEYS_HORIZONTAL, ...KEYS_VERTICAL]);
|
|
524
532
|
|
|
525
|
-
const
|
|
533
|
+
const MAPPED_ELEMENTS = new WeakMap<HTMLElement, OuiSplitter>();
|
|
534
|
+
|
|
535
|
+
const MESSAGE = `<${TAGNAME}> must have exactly two panels.`;
|
|
526
536
|
|
|
527
537
|
const METHODS_CONNECT = ['delete', 'set'] as const;
|
|
528
538
|
|
|
@@ -540,7 +550,7 @@ const RESIZE_OBSERVER: ResizeObserver = new ResizeObserver(onObservation);
|
|
|
540
550
|
|
|
541
551
|
const SELECTOR_HANDLE = `[${ATTRIBUTE_HANDLE}]`;
|
|
542
552
|
|
|
543
|
-
const STYLING_TOGGLER
|
|
553
|
+
const STYLING_TOGGLER = toggleStyles(document.body, {
|
|
544
554
|
touchAction: 'none',
|
|
545
555
|
userSelect: 'none',
|
|
546
556
|
webkitUserSelect: 'none',
|
|
@@ -554,9 +564,9 @@ let frame: DOMHighResTimeStamp | undefined;
|
|
|
554
564
|
|
|
555
565
|
let splitter: OuiSplitter | undefined;
|
|
556
566
|
|
|
557
|
-
//
|
|
567
|
+
// #endregion
|
|
558
568
|
|
|
559
|
-
|
|
569
|
+
// #region Initialization
|
|
560
570
|
|
|
561
571
|
on(document, 'keydown', onKeydown);
|
|
562
572
|
on(document, 'mousedown', onPointerdown);
|
|
@@ -564,3 +574,7 @@ on(document, 'pointermove', onPointermove);
|
|
|
564
574
|
on(document, 'pointerup', onPointerup);
|
|
565
575
|
on(document, 'touchcancel', onPointerup);
|
|
566
576
|
on(document, 'touchstart', onPointerdown, {passive: false});
|
|
577
|
+
|
|
578
|
+
customElements.define(TAGNAME, OuiSplitterElement);
|
|
579
|
+
|
|
580
|
+
// #endregion
|