@oscarpalmer/oui 0.37.0 → 0.39.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/a11y.css +1 -0
- package/dist/css/badge.css +12 -8
- package/dist/css/button.css +111 -14
- package/dist/css/color-picker.css +859 -0
- package/dist/css/color.css +86 -87
- package/dist/css/combobox.css +105 -4
- package/dist/css/content.css +8 -6
- package/dist/css/floatable.css +3 -3
- package/dist/css/form.css +106 -6
- package/dist/css/icon.css +99 -0
- package/dist/css/listbox.css +5 -0
- package/dist/css/message.css +6 -3
- package/dist/css/mixins/badge.mixins.css +2 -0
- package/dist/css/mixins/button.mixins.css +3 -0
- package/dist/css/mixins/message.mixins.css +1 -0
- package/dist/css/mixins/misc.mixins.css +2 -0
- package/dist/css/mixins/shadow.mixins.css +1 -0
- package/dist/css/reset.css +3 -3
- package/dist/css/splitter.css +1 -1
- package/dist/css/tabs.css +115 -23
- package/dist/css/typography.css +90 -0
- package/dist/js/color-picker/constants.color-picker.d.mts +2 -0
- package/dist/js/color-picker/constants.color-picker.mjs +59 -0
- package/dist/js/color-picker/dom.color-picker.d.mts +8 -0
- package/dist/js/color-picker/dom.color-picker.mjs +191 -0
- package/dist/js/color-picker/event.color-picker.d.mts +9 -0
- package/dist/js/color-picker/event.color-picker.mjs +2 -0
- package/dist/js/color-picker/form.color-picker.d.mts +5 -0
- package/dist/js/color-picker/form.color-picker.mjs +24 -0
- package/dist/js/color-picker/index.d.mts +2 -0
- package/dist/js/color-picker/index.mjs +303 -0
- package/dist/js/color-picker/misc.color-picker.d.mts +2 -0
- package/dist/js/color-picker/misc.color-picker.mjs +2 -0
- package/dist/js/color-picker/models.color-picker.d.mts +2 -0
- package/dist/js/color-picker/models.color-picker.mjs +24 -0
- package/dist/js/color-picker/output.color-picker.d.mts +8 -0
- package/dist/js/color-picker/output.color-picker.mjs +233 -0
- package/dist/js/color-picker/state.color-picker.d.mts +8 -0
- package/dist/js/color-picker/state.color-picker.mjs +2 -0
- package/dist/js/combobox/constants.combobox.d.mts +1 -1
- package/dist/js/combobox/dom.combobox.d.mts +12 -13
- package/dist/js/combobox/dom.combobox.mjs +12 -5
- package/dist/js/combobox/event.combobox.d.mts +20 -21
- package/dist/js/combobox/event.combobox.mjs +1 -1
- package/dist/js/combobox/index.d.mts +1 -1
- package/dist/js/combobox/index.mjs +56 -2
- package/dist/js/combobox/misc.combobox.d.mts +1 -1
- package/dist/js/combobox/misc.combobox.mjs +1 -1
- package/dist/js/combobox/models.combobox.d.mts +12 -13
- package/dist/js/combobox/state.combobox.d.mts +8 -9
- package/dist/js/combobox/state.combobox.mjs +1 -1
- package/dist/js/constants.color-picker-B-gFjL8m.d.mts +364 -0
- package/dist/js/constants.combobox-8EMRmv09.d.mts +18 -0
- package/dist/js/constants.listbox-DGnX32kv.d.mts +8 -0
- package/dist/js/dialog.d.mts +2 -2
- package/dist/js/dialog.mjs +1 -1
- package/dist/js/{draggable-a6w0J1OD.d.mts → draggable-B5-70SZm.d.mts} +5 -4
- package/dist/js/event.color-picker-BEpq0Adu.mjs +485 -0
- package/dist/js/floatable/floatable.embedded.d.mts +1 -1
- package/dist/js/floatable/floatable.embedded.mjs +11 -8
- package/dist/js/floatable/floatable.standalone.d.mts +1 -1
- package/dist/js/{floatable.embedded-Bct4U5Dm.d.mts → floatable.embedded-DQYkXt8X.d.mts} +1 -1
- package/dist/js/focus-trap/focus-trap.embedded.d.mts +1 -1
- package/dist/js/focus-trap/focus-trap.standalone.d.mts +1 -1
- package/dist/js/{focus-trap.embedded-DR8NpZfr.d.mts → focus-trap.embedded-CjyFQYow.d.mts} +2 -2
- package/dist/js/{index-EfkUSals.d.mts → index-C5D3-oiI.d.mts} +41 -3
- package/dist/js/index.d.mts +8 -7
- package/dist/js/index.mjs +6 -3
- package/dist/js/internal/attributable.d.mts +2 -3
- package/dist/js/internal/draggable.d.mts +1 -1
- package/dist/js/internal/draggable.mjs +1 -1
- package/dist/js/internal/listbox/listbox.constants.d.mts +7 -10
- package/dist/js/internal/listbox/listbox.constants.mjs +15 -16
- package/dist/js/internal/listbox/listbox.data.d.mts +9 -10
- package/dist/js/internal/listbox/listbox.data.mjs +1 -1
- package/dist/js/internal/listbox/listbox.dom.d.mts +19 -20
- package/dist/js/internal/listbox/listbox.dom.mjs +1 -1
- package/dist/js/internal/listbox/listbox.event.d.mts +3 -4
- package/dist/js/internal/listbox/listbox.event.mjs +4 -4
- package/dist/js/internal/listbox/listbox.form.d.mts +4 -5
- package/dist/js/internal/listbox/listbox.form.mjs +16 -15
- package/dist/js/internal/listbox/listbox.misc.d.mts +10 -11
- package/dist/js/internal/listbox/listbox.misc.mjs +1 -1
- package/dist/js/internal/listbox/listbox.model.d.mts +1 -1
- package/dist/js/internal/listbox/listbox.state.d.mts +5 -6
- package/dist/js/internal/listbox/listbox.state.mjs +3 -3
- package/dist/js/internal/misc.d.mts +4 -4
- package/dist/js/internal/misc.mjs +9 -1
- package/dist/js/internal/navigable.d.mts +9 -10
- package/dist/js/internal/navigable.mjs +1 -0
- package/dist/js/listbox/constants.listbox.d.mts +1 -1
- package/dist/js/listbox/event.listbox.d.mts +6 -7
- package/dist/js/listbox/event.listbox.mjs +1 -1
- package/dist/js/listbox/index.d.mts +43 -5
- package/dist/js/listbox/index.mjs +56 -2
- package/dist/js/listbox/misc.listbox.d.mts +1 -1
- package/dist/js/listbox/misc.listbox.mjs +1 -1
- package/dist/js/listbox/state.listbox.d.mts +7 -8
- package/dist/js/listbox/state.listbox.mjs +1 -1
- package/dist/js/{listbox.data-BWd0PCy7.mjs → listbox.data-DQ7-x2uY.mjs} +8 -7
- package/dist/js/{listbox.model-CRReGOmu.d.mts → listbox.model-BHPA7GM4.d.mts} +3 -3
- package/dist/js/menu.mjs +1 -1
- package/dist/js/{misc.listbox-BI-XsTOf.mjs → misc.listbox-DKB-j0UK.mjs} +4 -5
- package/dist/js/{misc.listbox-gnoJhrTr.d.mts → misc.listbox-mZMuYOxg.d.mts} +1 -1
- package/dist/js/movable/movable.embedded.d.mts +1 -1
- package/dist/js/movable/movable.standalone.d.mts +1 -1
- package/dist/js/popover.d.mts +2 -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 +1 -1
- package/dist/js/resizable/resizable.standalone.d.mts +1 -1
- package/dist/js/{resizable.embedded-3qoR0Bjm.d.mts → resizable.embedded-dvhdfQgt.d.mts} +1 -1
- package/dist/js/sortable/sortable.embedded.d.mts +1 -1
- package/dist/js/sortable/sortable.standalone.d.mts +1 -1
- package/dist/js/splitter.d.mts +2 -3
- package/dist/js/splitter.mjs +2 -2
- package/dist/js/{state.combobox-4xq0FPCF.mjs → state.combobox-BWDFHwoi.mjs} +9 -9
- package/dist/js/tabs.d.mts +4 -5
- package/dist/js/tabs.mjs +4 -7
- package/dist/js/tooltip.d.mts +1 -1
- package/package.json +24 -22
- package/dist/js/constants.combobox-DmRAMC64.d.mts +0 -26
- package/dist/js/constants.listbox-DRsXUxd3.d.mts +0 -14
- package/src/css/a11y.scss +0 -13
- package/src/css/badge.scss +0 -62
- package/src/css/button.scss +0 -50
- package/src/css/color.scss +0 -115
- package/src/css/combobox.scss +0 -252
- package/src/css/content.scss +0 -180
- package/src/css/flex.scss +0 -107
- package/src/css/floatable.scss +0 -152
- package/src/css/form.scss +0 -573
- package/src/css/listbox.scss +0 -120
- package/src/css/message.scss +0 -73
- package/src/css/mixins.scss +0 -419
- package/src/css/reset.scss +0 -392
- package/src/css/splitter.scss +0 -89
- package/src/css/table.scss +0 -107
- package/src/css/tabs.scss +0 -85
- package/src/js/combobox/constants.combobox.ts +0 -83
- package/src/js/combobox/dom.combobox.ts +0 -407
- package/src/js/combobox/event.combobox.ts +0 -365
- package/src/js/combobox/index.ts +0 -320
- package/src/js/combobox/misc.combobox.ts +0 -104
- package/src/js/combobox/models.combobox.ts +0 -54
- package/src/js/combobox/state.combobox.ts +0 -246
- package/src/js/dialog.ts +0 -255
- package/src/js/floatable/floatable.embedded.ts +0 -332
- package/src/js/floatable/floatable.standalone.ts +0 -6
- package/src/js/focus-trap/focus-trap.embedded.ts +0 -411
- package/src/js/focus-trap/focus-trap.standalone.ts +0 -1
- package/src/js/index.ts +0 -15
- package/src/js/internal/attributable.ts +0 -73
- package/src/js/internal/draggable.ts +0 -657
- package/src/js/internal/listbox/listbox.constants.ts +0 -25
- package/src/js/internal/listbox/listbox.data.ts +0 -287
- package/src/js/internal/listbox/listbox.dom.ts +0 -445
- package/src/js/internal/listbox/listbox.event.ts +0 -129
- package/src/js/internal/listbox/listbox.form.ts +0 -115
- package/src/js/internal/listbox/listbox.misc.ts +0 -135
- package/src/js/internal/listbox/listbox.model.ts +0 -169
- package/src/js/internal/listbox/listbox.state.ts +0 -82
- package/src/js/internal/misc.ts +0 -27
- package/src/js/internal/navigable.ts +0 -315
- package/src/js/l10n.ts +0 -192
- package/src/js/listbox/constants.listbox.ts +0 -61
- package/src/js/listbox/event.listbox.ts +0 -106
- package/src/js/listbox/index.ts +0 -302
- package/src/js/listbox/misc.listbox.ts +0 -70
- package/src/js/listbox/state.listbox.ts +0 -196
- package/src/js/menu.ts +0 -348
- package/src/js/movable/movable.embedded.ts +0 -318
- package/src/js/movable/movable.standalone.ts +0 -2
- package/src/js/popover.ts +0 -229
- package/src/js/resizable/resizable.embedded.ts +0 -413
- package/src/js/resizable/resizable.standalone.ts +0 -5
- package/src/js/sortable/sortable.embedded.ts +0 -527
- package/src/js/sortable/sortable.standalone.ts +0 -2
- package/src/js/splitter.ts +0 -583
- package/src/js/tabs.ts +0 -447
- package/src/js/toolbar.ts +0 -63
- package/src/js/tooltip.ts +0 -367
- /package/dist/css/{mixins.css → mixins/input.mixins.css} +0 -0
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import {updateListboxMessage, updateListboxValueLabel} from '../internal/listbox/listbox.dom';
|
|
2
|
-
import type {
|
|
3
|
-
OuiListboxAutoComplete,
|
|
4
|
-
OuiListboxAutoCompleteType,
|
|
5
|
-
OuiListboxLocalizations,
|
|
6
|
-
} from '../internal/listbox/listbox.model';
|
|
7
|
-
import {getAttributeValue} from '../internal/misc';
|
|
8
|
-
import {OuiLocalizations, updateLocalizations} from '../l10n';
|
|
9
|
-
import {COMBOBOX_AUTOCOMPLETES} from './constants.combobox';
|
|
10
|
-
import {updateComboboxSelectionItems} from './dom.combobox';
|
|
11
|
-
import type {OuiComboboxElement} from './index';
|
|
12
|
-
import {comboboxLocalizations, comboboxStates} from './state.combobox';
|
|
13
|
-
|
|
14
|
-
// #region Functions
|
|
15
|
-
|
|
16
|
-
export function getComboboxAutoComplete(
|
|
17
|
-
element: OuiComboboxElement,
|
|
18
|
-
select: boolean,
|
|
19
|
-
): OuiListboxAutoComplete {
|
|
20
|
-
let value: OuiListboxAutoCompleteType;
|
|
21
|
-
|
|
22
|
-
if (select) {
|
|
23
|
-
value = 'list';
|
|
24
|
-
} else {
|
|
25
|
-
value = getAttributeValue(element, 'autocomplete', COMBOBOX_AUTOCOMPLETES, 'none');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
value,
|
|
30
|
-
both: value === 'both',
|
|
31
|
-
inline: value === 'inline',
|
|
32
|
-
list: value === 'list',
|
|
33
|
-
none: value === 'none',
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function getComboboxId(): string {
|
|
38
|
-
index += 1;
|
|
39
|
-
|
|
40
|
-
return `oui_combobox_${index}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function hasTextSelection(element: HTMLElement): element is HTMLInputElement {
|
|
44
|
-
return element instanceof HTMLInputElement && element.selectionStart !== element.selectionEnd;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Set combobox localizations for a specific language
|
|
49
|
-
*
|
|
50
|
-
* @param language Language code
|
|
51
|
-
* @param localizations Localizations for language
|
|
52
|
-
*/
|
|
53
|
-
export function setComboboxLocalizations(
|
|
54
|
-
language: string,
|
|
55
|
-
localizations: Partial<OuiListboxLocalizations>,
|
|
56
|
-
): void;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Set combobox localizations for one or more languages
|
|
60
|
-
*
|
|
61
|
-
* @param localizations Localizations for one or more languages
|
|
62
|
-
*/
|
|
63
|
-
export function setComboboxLocalizations(
|
|
64
|
-
localizations: Record<string, Partial<OuiListboxLocalizations>>,
|
|
65
|
-
): void;
|
|
66
|
-
|
|
67
|
-
export function setComboboxLocalizations(
|
|
68
|
-
first: string | Record<string, Partial<OuiListboxLocalizations>>,
|
|
69
|
-
second?: Partial<OuiListboxLocalizations>,
|
|
70
|
-
): void {
|
|
71
|
-
updateComboboxLocalizations(comboboxLocalizations, comboboxLocalizations.values, first, second);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function updateComboboxLocalizations(
|
|
75
|
-
instance: OuiLocalizations<OuiListboxLocalizations>,
|
|
76
|
-
destination: Record<string, Partial<OuiListboxLocalizations>>,
|
|
77
|
-
first: string | Record<string, Partial<OuiListboxLocalizations>>,
|
|
78
|
-
second?: Partial<OuiListboxLocalizations>,
|
|
79
|
-
): void {
|
|
80
|
-
updateLocalizations(
|
|
81
|
-
instance,
|
|
82
|
-
typeof first === 'string'
|
|
83
|
-
? {
|
|
84
|
-
[first]: second!,
|
|
85
|
-
}
|
|
86
|
-
: first,
|
|
87
|
-
destination,
|
|
88
|
-
() => {
|
|
89
|
-
for (const state of comboboxStates.set) {
|
|
90
|
-
updateListboxMessage(state);
|
|
91
|
-
updateListboxValueLabel(state);
|
|
92
|
-
updateComboboxSelectionItems(state);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// #endregion
|
|
99
|
-
|
|
100
|
-
// #region Variables
|
|
101
|
-
|
|
102
|
-
let index = 0;
|
|
103
|
-
|
|
104
|
-
// #endregion
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type {OuiFloatable} from '../floatable/floatable.embedded';
|
|
2
|
-
import type {OuiListboxState, OuiListboxType} from '../internal/listbox/listbox.model';
|
|
3
|
-
|
|
4
|
-
// #region Types
|
|
5
|
-
|
|
6
|
-
export type OuiComboboxAnchor = {
|
|
7
|
-
container?: HTMLElement;
|
|
8
|
-
element: HTMLElement;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type OuiComboboxFilter = {
|
|
12
|
-
element: HTMLInputElement;
|
|
13
|
-
value: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type OuiComboboxGroup = {
|
|
17
|
-
element: HTMLElement;
|
|
18
|
-
header: HTMLElement;
|
|
19
|
-
options: HTMLElement[];
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type OuiComboboxLabel = {
|
|
23
|
-
element: HTMLLabelElement;
|
|
24
|
-
id: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type OuiComboboxOptions = {
|
|
28
|
-
all: HTMLElement[];
|
|
29
|
-
selected: HTMLElement[];
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export type OuiComboboxSelection = {
|
|
33
|
-
container: HTMLElement;
|
|
34
|
-
items: OuiComboboxSelectionItem[];
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export type OuiComboboxSelectionItem = {
|
|
38
|
-
button: HTMLButtonElement;
|
|
39
|
-
element: HTMLElement;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export type OuiComboboxState = {
|
|
43
|
-
anchor: OuiComboboxAnchor;
|
|
44
|
-
floatable: OuiFloatable;
|
|
45
|
-
selection?: OuiComboboxSelection;
|
|
46
|
-
type: OuiListboxType;
|
|
47
|
-
} & OuiListboxState;
|
|
48
|
-
|
|
49
|
-
export type OuiComboboxValues = {
|
|
50
|
-
current: string[];
|
|
51
|
-
initial: string[];
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// #endregion
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import {noop} from '@oscarpalmer/atoms/function';
|
|
2
|
-
import {setAria} from '@oscarpalmer/toretto/aria';
|
|
3
|
-
import {setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
4
|
-
import {getData} from '@oscarpalmer/toretto/data';
|
|
5
|
-
import {on} from '@oscarpalmer/toretto/event';
|
|
6
|
-
import {createEmbeddedFloatable} from '../floatable/floatable.embedded';
|
|
7
|
-
import {LISTBOX_TYPES} from '../internal/listbox/listbox.constants';
|
|
8
|
-
import {generateListboxIds} from '../internal/listbox/listbox.misc';
|
|
9
|
-
import type {
|
|
10
|
-
OuiListboxCallbacks,
|
|
11
|
-
OuiListboxLocalizations,
|
|
12
|
-
OuiListboxStates,
|
|
13
|
-
} from '../internal/listbox/listbox.model';
|
|
14
|
-
import {initializeListboxState} from '../internal/listbox/listbox.state';
|
|
15
|
-
import {getAttributeValue, getBooleanAriaValue} from '../internal/misc';
|
|
16
|
-
import {getLocalizations} from '../l10n';
|
|
17
|
-
import {COMBOBOX_ATTRIBUTES, COMBOBOX_MESSAGES} from './constants.combobox';
|
|
18
|
-
import {createComboboxAnchor, createComboboxContent} from './dom.combobox';
|
|
19
|
-
import {
|
|
20
|
-
onComboboxActivation,
|
|
21
|
-
onComboboxApply,
|
|
22
|
-
onComboboxEnter,
|
|
23
|
-
onComboboxEscape,
|
|
24
|
-
onComboboxFilter,
|
|
25
|
-
onComboboxNavigation,
|
|
26
|
-
onComboboxPreview,
|
|
27
|
-
onComboboxSelection,
|
|
28
|
-
onComboboxTab,
|
|
29
|
-
onComboboxToggle,
|
|
30
|
-
preventComboboxActivation,
|
|
31
|
-
skipComboboxNavigation,
|
|
32
|
-
} from './event.combobox';
|
|
33
|
-
import type {OuiComboboxElement} from './index';
|
|
34
|
-
import {getComboboxAutoComplete, getComboboxId} from './misc.combobox';
|
|
35
|
-
import type {OuiComboboxState} from './models.combobox';
|
|
36
|
-
|
|
37
|
-
// #region Functions
|
|
38
|
-
|
|
39
|
-
export function createComboboxState(
|
|
40
|
-
element: OuiComboboxElement,
|
|
41
|
-
internals: ElementInternals,
|
|
42
|
-
): OuiComboboxState {
|
|
43
|
-
const select = element.querySelector('select');
|
|
44
|
-
|
|
45
|
-
if (select == null || select.id === '') {
|
|
46
|
-
throw new Error(COMBOBOX_MESSAGES.select);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const label = element.querySelector(`label[for="${select.id}"]`) as HTMLLabelElement;
|
|
50
|
-
|
|
51
|
-
if (label == null) {
|
|
52
|
-
throw new Error(COMBOBOX_MESSAGES.label);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
element.id = select.id;
|
|
56
|
-
|
|
57
|
-
const disabled = getBooleanAriaValue(element, 'disabled') || select.disabled;
|
|
58
|
-
const multiple = element.multiple || select.multiple;
|
|
59
|
-
const readonly = getBooleanAriaValue(element, 'readonly');
|
|
60
|
-
const required = getBooleanAriaValue(element, 'required') || select.required;
|
|
61
|
-
|
|
62
|
-
const id = getComboboxId();
|
|
63
|
-
const type = multiple ? 'select' : getAttributeValue(element, 'type', LISTBOX_TYPES, 'select');
|
|
64
|
-
|
|
65
|
-
const autocomplete = getComboboxAutoComplete(element, type === 'select');
|
|
66
|
-
|
|
67
|
-
setAttributes(element, {
|
|
68
|
-
autocomplete: autocomplete.value,
|
|
69
|
-
name: select.name === '' ? select.id : select.name,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const labelId = label.id;
|
|
73
|
-
|
|
74
|
-
label.htmlFor = id;
|
|
75
|
-
label.id = `${id}_label`;
|
|
76
|
-
|
|
77
|
-
generateListboxIds(id, select);
|
|
78
|
-
|
|
79
|
-
const parameters = {
|
|
80
|
-
autocomplete,
|
|
81
|
-
element,
|
|
82
|
-
id,
|
|
83
|
-
label,
|
|
84
|
-
multiple,
|
|
85
|
-
select,
|
|
86
|
-
type,
|
|
87
|
-
attributes: COMBOBOX_ATTRIBUTES,
|
|
88
|
-
listbox: false,
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const anchor = createComboboxAnchor(parameters);
|
|
92
|
-
const content = createComboboxContent(parameters);
|
|
93
|
-
|
|
94
|
-
const {selected} = content.list.options;
|
|
95
|
-
|
|
96
|
-
const values =
|
|
97
|
-
selected.length === 0 ? [''] : selected.map(option => getData(option, 'value', false) ?? '');
|
|
98
|
-
|
|
99
|
-
const state: OuiComboboxState = {
|
|
100
|
-
autocomplete,
|
|
101
|
-
disabled,
|
|
102
|
-
id,
|
|
103
|
-
internals,
|
|
104
|
-
multiple,
|
|
105
|
-
readonly,
|
|
106
|
-
required,
|
|
107
|
-
select,
|
|
108
|
-
type,
|
|
109
|
-
active: selected[0],
|
|
110
|
-
anchor: {
|
|
111
|
-
container: anchor.container,
|
|
112
|
-
element: anchor.element,
|
|
113
|
-
},
|
|
114
|
-
attributes: COMBOBOX_ATTRIBUTES,
|
|
115
|
-
callbacks: comboboxCallbacks as OuiComboboxState['callbacks'],
|
|
116
|
-
content: content.element,
|
|
117
|
-
elements: [element, anchor.element, content.filter?.element],
|
|
118
|
-
filter: {
|
|
119
|
-
element: content.filter?.element ?? (anchor.element as HTMLInputElement),
|
|
120
|
-
value: '',
|
|
121
|
-
},
|
|
122
|
-
floatable: undefined as never,
|
|
123
|
-
groups: content.list.groups,
|
|
124
|
-
host: element,
|
|
125
|
-
label: {
|
|
126
|
-
element: label,
|
|
127
|
-
id: labelId,
|
|
128
|
-
},
|
|
129
|
-
list: content.list.element,
|
|
130
|
-
listbox: false,
|
|
131
|
-
listeners: [],
|
|
132
|
-
localizations: {
|
|
133
|
-
component: {},
|
|
134
|
-
global: comboboxLocalizations,
|
|
135
|
-
},
|
|
136
|
-
message: content.message,
|
|
137
|
-
name: element.name,
|
|
138
|
-
options: {
|
|
139
|
-
selected,
|
|
140
|
-
all: content.list.options.all,
|
|
141
|
-
},
|
|
142
|
-
selection: anchor.selection,
|
|
143
|
-
values: {
|
|
144
|
-
current: values.slice(),
|
|
145
|
-
initial: values.slice(),
|
|
146
|
-
label: content.value,
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
return initializeListboxState(state, comboboxStates, onAttachCombobox);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export function onAttachCombobox(state: OuiComboboxState): void {
|
|
154
|
-
const {anchor, content, filter, select} = state;
|
|
155
|
-
|
|
156
|
-
select.hidden = true;
|
|
157
|
-
|
|
158
|
-
select.insertAdjacentElement('afterend', anchor.container ?? anchor.element);
|
|
159
|
-
(anchor.container ?? anchor.element).insertAdjacentElement('afterend', content);
|
|
160
|
-
|
|
161
|
-
select.remove();
|
|
162
|
-
|
|
163
|
-
state.floatable = createEmbeddedFloatable(anchor.container ?? anchor.element, content, {
|
|
164
|
-
position: 'below-start',
|
|
165
|
-
reusable: false,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
state.floatable.update();
|
|
169
|
-
|
|
170
|
-
state.listeners.push(
|
|
171
|
-
on(content, 'toggle', () => {
|
|
172
|
-
setAria(anchor.element, 'expanded', state.floatable.open);
|
|
173
|
-
|
|
174
|
-
setAria(
|
|
175
|
-
filter.element,
|
|
176
|
-
'activedescendant',
|
|
177
|
-
state.floatable.open ? state.active?.id : undefined,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
if (state.floatable.open) {
|
|
181
|
-
filter.element.focus();
|
|
182
|
-
}
|
|
183
|
-
}),
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export function onDetachCombobox(state: OuiComboboxState): void {
|
|
188
|
-
const {content, floatable, label, select} = state;
|
|
189
|
-
|
|
190
|
-
floatable.destroy();
|
|
191
|
-
|
|
192
|
-
const anchor = state.anchor.container ?? state.anchor.element;
|
|
193
|
-
|
|
194
|
-
anchor.insertAdjacentElement('beforebegin', select);
|
|
195
|
-
|
|
196
|
-
anchor.remove();
|
|
197
|
-
content.remove();
|
|
198
|
-
|
|
199
|
-
label.element.htmlFor = select.id;
|
|
200
|
-
label.element.id = state.label.id;
|
|
201
|
-
|
|
202
|
-
select.hidden = false;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// #endregion
|
|
206
|
-
|
|
207
|
-
// #region Variables
|
|
208
|
-
|
|
209
|
-
const comboboxCallbacks: OuiListboxCallbacks<OuiComboboxState> = {
|
|
210
|
-
data: {
|
|
211
|
-
onApply: onComboboxApply,
|
|
212
|
-
onFilter: onComboboxFilter,
|
|
213
|
-
onForm: noop,
|
|
214
|
-
onPreview: onComboboxPreview,
|
|
215
|
-
onToggle: onComboboxToggle,
|
|
216
|
-
},
|
|
217
|
-
keydown: {
|
|
218
|
-
onActivation: onComboboxActivation,
|
|
219
|
-
onEnter: onComboboxEnter,
|
|
220
|
-
onEscape: onComboboxEscape,
|
|
221
|
-
onNavigation: onComboboxNavigation,
|
|
222
|
-
onSelection: onComboboxSelection,
|
|
223
|
-
onTab: onComboboxTab,
|
|
224
|
-
onToggle: onComboboxToggle,
|
|
225
|
-
preventActivation: preventComboboxActivation,
|
|
226
|
-
skipNavigation: skipComboboxNavigation,
|
|
227
|
-
},
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
export const comboboxLocalizations = getLocalizations<OuiListboxLocalizations>({
|
|
231
|
-
empty: 'No results found',
|
|
232
|
-
input: 'Please enter a value',
|
|
233
|
-
invalid: 'Please select an option from the list',
|
|
234
|
-
max: max => `Please select fewer options (maximum is ${max})`,
|
|
235
|
-
min: min => `Please select more options (minimum is ${min})`,
|
|
236
|
-
remove: label => `Remove ${label}`,
|
|
237
|
-
results: amount => `${amount} results available`,
|
|
238
|
-
selected: amount => `${amount} selected`,
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
export const comboboxStates: OuiListboxStates<OuiComboboxState> = {
|
|
242
|
-
map: new WeakMap(),
|
|
243
|
-
set: new Set(),
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
// #endregion
|
package/src/js/dialog.ts
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import {getAria, setAria} from '@oscarpalmer/toretto/aria';
|
|
2
|
-
import {on} from '@oscarpalmer/toretto/event';
|
|
3
|
-
import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
|
|
4
|
-
import {getOnBeforeToggleListener} from './floatable/floatable.embedded';
|
|
5
|
-
import {attributable} from './internal/attributable';
|
|
6
|
-
import {ATTRIBUTE_MOVABLE_HANDLE} from './movable/movable.embedded';
|
|
7
|
-
import {createMovable, type OuiMovable} from './movable/movable.standalone';
|
|
8
|
-
import {createResizable, RESIZABLE_ATTRIBUTE_HANDLE} from './resizable/resizable.embedded';
|
|
9
|
-
import type {OuiResizable} from './resizable/resizable.standalone';
|
|
10
|
-
import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
11
|
-
import {setStyles} from '@oscarpalmer/toretto/style';
|
|
12
|
-
|
|
13
|
-
// #region Types
|
|
14
|
-
|
|
15
|
-
class OuiDialog {
|
|
16
|
-
readonly #state: OuiDialogState;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Is the dialog open?
|
|
20
|
-
*/
|
|
21
|
-
get open(): boolean {
|
|
22
|
-
return this.#state.element.open;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Open or close the dialog
|
|
27
|
-
*/
|
|
28
|
-
set open(value: boolean) {
|
|
29
|
-
if (value === true) {
|
|
30
|
-
this.show();
|
|
31
|
-
} else if (value === false) {
|
|
32
|
-
this.hide();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
constructor(state: OuiDialogState) {
|
|
37
|
-
this.#state = state;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Closes the dialog by request
|
|
42
|
-
*/
|
|
43
|
-
hide(request: true, value?: string): void;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Closes the dialog
|
|
47
|
-
*/
|
|
48
|
-
hide(value?: string): void;
|
|
49
|
-
|
|
50
|
-
hide(first?: string | boolean, second?: string): void {
|
|
51
|
-
if (!this.#state.element.open) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (first === true) {
|
|
56
|
-
this.#state.element.requestClose(typeof second === 'string' ? second : undefined);
|
|
57
|
-
} else {
|
|
58
|
-
this.#state.element.close(typeof first === 'string' ? first : undefined);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Opens the dialog
|
|
64
|
-
*/
|
|
65
|
-
show(modal?: boolean): void {
|
|
66
|
-
const {element} = this.#state;
|
|
67
|
-
|
|
68
|
-
if (element == null || element.open) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const isModal = modal !== false;
|
|
73
|
-
|
|
74
|
-
setAria(element, 'modal', isModal);
|
|
75
|
-
|
|
76
|
-
if (isModal) {
|
|
77
|
-
element.showModal();
|
|
78
|
-
} else {
|
|
79
|
-
element.show();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
type OuiDialogState = {
|
|
85
|
-
dialog: OuiDialog;
|
|
86
|
-
element: HTMLDialogElement;
|
|
87
|
-
listeners: RemovableEventListener[];
|
|
88
|
-
modal: boolean;
|
|
89
|
-
movable?: OuiMovable;
|
|
90
|
-
resizable?: OuiResizable;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// #endregion
|
|
94
|
-
|
|
95
|
-
// #region Functions
|
|
96
|
-
|
|
97
|
-
function addDialog(element: HTMLElement): void {
|
|
98
|
-
if (!(element instanceof HTMLDialogElement)) {
|
|
99
|
-
throw new TypeError(MESSAGE);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (!states.has(element)) {
|
|
103
|
-
states.set(element, getState(element));
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function destroyDialog(state: OuiDialogState): void {
|
|
108
|
-
state.element.close();
|
|
109
|
-
|
|
110
|
-
setAria(state.element, 'modal', state.modal);
|
|
111
|
-
|
|
112
|
-
state.element.removeAttribute(ATTRIBUTE_OPEN);
|
|
113
|
-
|
|
114
|
-
for (const listener of state.listeners) {
|
|
115
|
-
listener();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
state.movable?.destroy();
|
|
119
|
-
state.resizable?.destroy();
|
|
120
|
-
|
|
121
|
-
state.dialog = undefined as never;
|
|
122
|
-
state.element = undefined as never;
|
|
123
|
-
state.listeners = undefined as never;
|
|
124
|
-
state.movable = undefined;
|
|
125
|
-
state.resizable = undefined;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get the _OuiDialog_ for an element
|
|
130
|
-
*
|
|
131
|
-
* @param element Element to get _OuiDialog_ for
|
|
132
|
-
* @returns _OuiDialog_ instance
|
|
133
|
-
*/
|
|
134
|
-
function getDialog(element: HTMLDialogElement): OuiDialog | undefined {
|
|
135
|
-
return states.get(element)?.dialog;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function getMovable(element: HTMLDialogElement): OuiMovable | undefined {
|
|
139
|
-
const handles = element.querySelectorAll(SELECTOR_MOVER);
|
|
140
|
-
|
|
141
|
-
if (handles.length === 0) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
for (const handle of handles) {
|
|
146
|
-
setAttribute(handle, ATTRIBUTE_MOVABLE_HANDLE, '');
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return createMovable(element, {
|
|
150
|
-
container: getAttribute(element, ATTRIBUTE_CONTAINER),
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function getResizable(element: HTMLDialogElement): OuiResizable | undefined {
|
|
155
|
-
const handle = element.querySelector(SELECTOR_RESIZER);
|
|
156
|
-
|
|
157
|
-
if (handle == null) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
setAttribute(handle, RESIZABLE_ATTRIBUTE_HANDLE, '');
|
|
162
|
-
|
|
163
|
-
return createResizable(element);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function getState(element: HTMLDialogElement): OuiDialogState {
|
|
167
|
-
const state: OuiDialogState = {
|
|
168
|
-
element,
|
|
169
|
-
dialog: undefined as never,
|
|
170
|
-
listeners: [
|
|
171
|
-
getOnBeforeToggleListener(element),
|
|
172
|
-
on(element, 'toggle', event => {
|
|
173
|
-
const {source} = event;
|
|
174
|
-
|
|
175
|
-
if (element.open) {
|
|
176
|
-
const modal =
|
|
177
|
-
(source instanceof HTMLButtonElement && source.command === 'show-modal') ||
|
|
178
|
-
element.matches(':modal');
|
|
179
|
-
|
|
180
|
-
setAria(element, 'modal', modal);
|
|
181
|
-
setAttribute(element, ATTRIBUTE_OPEN, '');
|
|
182
|
-
|
|
183
|
-
element.focus();
|
|
184
|
-
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
state.resizable?.set();
|
|
187
|
-
}, 500);
|
|
188
|
-
} else {
|
|
189
|
-
setAttribute(element, ATTRIBUTE_OPEN);
|
|
190
|
-
setAria(element, 'modal', state.modal);
|
|
191
|
-
|
|
192
|
-
setStyles(element, {
|
|
193
|
-
inset: '',
|
|
194
|
-
position: '',
|
|
195
|
-
transform: '',
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
state.resizable?.reset();
|
|
199
|
-
}
|
|
200
|
-
}),
|
|
201
|
-
],
|
|
202
|
-
modal: getAria(element, 'modal') === 'true' || element.matches(':modal'),
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
state.dialog = new OuiDialog(state);
|
|
206
|
-
|
|
207
|
-
state.movable = getMovable(element);
|
|
208
|
-
state.resizable = getResizable(element);
|
|
209
|
-
|
|
210
|
-
return state;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
function removeDialog(element: HTMLElement): void {
|
|
214
|
-
const state = states.get(element);
|
|
215
|
-
|
|
216
|
-
if (state == null) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
destroyDialog(state);
|
|
221
|
-
|
|
222
|
-
states.delete(element);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// #endregion
|
|
226
|
-
|
|
227
|
-
// #region Variables
|
|
228
|
-
|
|
229
|
-
const ATTRIBUTE = 'oui-dialog';
|
|
230
|
-
|
|
231
|
-
const ATTRIBUTE_CONTAINER = `${ATTRIBUTE}-container`;
|
|
232
|
-
|
|
233
|
-
const ATTRIBUTE_OPEN = `${ATTRIBUTE}-open`;
|
|
234
|
-
|
|
235
|
-
const MESSAGE = 'The element must be an instance of HTMLDialogElement';
|
|
236
|
-
|
|
237
|
-
const SELECTOR_MOVER = `[${ATTRIBUTE}-mover]`;
|
|
238
|
-
|
|
239
|
-
const SELECTOR_RESIZER = `[${ATTRIBUTE}-resizer]`;
|
|
240
|
-
|
|
241
|
-
const states = new WeakMap<HTMLElement, OuiDialogState>();
|
|
242
|
-
|
|
243
|
-
// #endregion
|
|
244
|
-
|
|
245
|
-
// #region Initialization
|
|
246
|
-
|
|
247
|
-
attributable(ATTRIBUTE, addDialog, removeDialog);
|
|
248
|
-
|
|
249
|
-
// #endregion
|
|
250
|
-
|
|
251
|
-
// #region Exports
|
|
252
|
-
|
|
253
|
-
export {getDialog, type OuiDialog};
|
|
254
|
-
|
|
255
|
-
// #endregion
|