@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.
Files changed (183) hide show
  1. package/dist/css/a11y.css +1 -0
  2. package/dist/css/badge.css +12 -8
  3. package/dist/css/button.css +111 -14
  4. package/dist/css/color-picker.css +859 -0
  5. package/dist/css/color.css +86 -87
  6. package/dist/css/combobox.css +105 -4
  7. package/dist/css/content.css +8 -6
  8. package/dist/css/floatable.css +3 -3
  9. package/dist/css/form.css +106 -6
  10. package/dist/css/icon.css +99 -0
  11. package/dist/css/listbox.css +5 -0
  12. package/dist/css/message.css +6 -3
  13. package/dist/css/mixins/badge.mixins.css +2 -0
  14. package/dist/css/mixins/button.mixins.css +3 -0
  15. package/dist/css/mixins/message.mixins.css +1 -0
  16. package/dist/css/mixins/misc.mixins.css +2 -0
  17. package/dist/css/mixins/shadow.mixins.css +1 -0
  18. package/dist/css/reset.css +3 -3
  19. package/dist/css/splitter.css +1 -1
  20. package/dist/css/tabs.css +115 -23
  21. package/dist/css/typography.css +90 -0
  22. package/dist/js/color-picker/constants.color-picker.d.mts +2 -0
  23. package/dist/js/color-picker/constants.color-picker.mjs +59 -0
  24. package/dist/js/color-picker/dom.color-picker.d.mts +8 -0
  25. package/dist/js/color-picker/dom.color-picker.mjs +191 -0
  26. package/dist/js/color-picker/event.color-picker.d.mts +9 -0
  27. package/dist/js/color-picker/event.color-picker.mjs +2 -0
  28. package/dist/js/color-picker/form.color-picker.d.mts +5 -0
  29. package/dist/js/color-picker/form.color-picker.mjs +24 -0
  30. package/dist/js/color-picker/index.d.mts +2 -0
  31. package/dist/js/color-picker/index.mjs +303 -0
  32. package/dist/js/color-picker/misc.color-picker.d.mts +2 -0
  33. package/dist/js/color-picker/misc.color-picker.mjs +2 -0
  34. package/dist/js/color-picker/models.color-picker.d.mts +2 -0
  35. package/dist/js/color-picker/models.color-picker.mjs +24 -0
  36. package/dist/js/color-picker/output.color-picker.d.mts +8 -0
  37. package/dist/js/color-picker/output.color-picker.mjs +233 -0
  38. package/dist/js/color-picker/state.color-picker.d.mts +8 -0
  39. package/dist/js/color-picker/state.color-picker.mjs +2 -0
  40. package/dist/js/combobox/constants.combobox.d.mts +1 -1
  41. package/dist/js/combobox/dom.combobox.d.mts +12 -13
  42. package/dist/js/combobox/dom.combobox.mjs +12 -5
  43. package/dist/js/combobox/event.combobox.d.mts +20 -21
  44. package/dist/js/combobox/event.combobox.mjs +1 -1
  45. package/dist/js/combobox/index.d.mts +1 -1
  46. package/dist/js/combobox/index.mjs +56 -2
  47. package/dist/js/combobox/misc.combobox.d.mts +1 -1
  48. package/dist/js/combobox/misc.combobox.mjs +1 -1
  49. package/dist/js/combobox/models.combobox.d.mts +12 -13
  50. package/dist/js/combobox/state.combobox.d.mts +8 -9
  51. package/dist/js/combobox/state.combobox.mjs +1 -1
  52. package/dist/js/constants.color-picker-B-gFjL8m.d.mts +364 -0
  53. package/dist/js/constants.combobox-8EMRmv09.d.mts +18 -0
  54. package/dist/js/constants.listbox-DGnX32kv.d.mts +8 -0
  55. package/dist/js/dialog.d.mts +2 -2
  56. package/dist/js/dialog.mjs +1 -1
  57. package/dist/js/{draggable-a6w0J1OD.d.mts → draggable-B5-70SZm.d.mts} +5 -4
  58. package/dist/js/event.color-picker-BEpq0Adu.mjs +485 -0
  59. package/dist/js/floatable/floatable.embedded.d.mts +1 -1
  60. package/dist/js/floatable/floatable.embedded.mjs +11 -8
  61. package/dist/js/floatable/floatable.standalone.d.mts +1 -1
  62. package/dist/js/{floatable.embedded-Bct4U5Dm.d.mts → floatable.embedded-DQYkXt8X.d.mts} +1 -1
  63. package/dist/js/focus-trap/focus-trap.embedded.d.mts +1 -1
  64. package/dist/js/focus-trap/focus-trap.standalone.d.mts +1 -1
  65. package/dist/js/{focus-trap.embedded-DR8NpZfr.d.mts → focus-trap.embedded-CjyFQYow.d.mts} +2 -2
  66. package/dist/js/{index-EfkUSals.d.mts → index-C5D3-oiI.d.mts} +41 -3
  67. package/dist/js/index.d.mts +8 -7
  68. package/dist/js/index.mjs +6 -3
  69. package/dist/js/internal/attributable.d.mts +2 -3
  70. package/dist/js/internal/draggable.d.mts +1 -1
  71. package/dist/js/internal/draggable.mjs +1 -1
  72. package/dist/js/internal/listbox/listbox.constants.d.mts +7 -10
  73. package/dist/js/internal/listbox/listbox.constants.mjs +15 -16
  74. package/dist/js/internal/listbox/listbox.data.d.mts +9 -10
  75. package/dist/js/internal/listbox/listbox.data.mjs +1 -1
  76. package/dist/js/internal/listbox/listbox.dom.d.mts +19 -20
  77. package/dist/js/internal/listbox/listbox.dom.mjs +1 -1
  78. package/dist/js/internal/listbox/listbox.event.d.mts +3 -4
  79. package/dist/js/internal/listbox/listbox.event.mjs +4 -4
  80. package/dist/js/internal/listbox/listbox.form.d.mts +4 -5
  81. package/dist/js/internal/listbox/listbox.form.mjs +16 -15
  82. package/dist/js/internal/listbox/listbox.misc.d.mts +10 -11
  83. package/dist/js/internal/listbox/listbox.misc.mjs +1 -1
  84. package/dist/js/internal/listbox/listbox.model.d.mts +1 -1
  85. package/dist/js/internal/listbox/listbox.state.d.mts +5 -6
  86. package/dist/js/internal/listbox/listbox.state.mjs +3 -3
  87. package/dist/js/internal/misc.d.mts +4 -4
  88. package/dist/js/internal/misc.mjs +9 -1
  89. package/dist/js/internal/navigable.d.mts +9 -10
  90. package/dist/js/internal/navigable.mjs +1 -0
  91. package/dist/js/listbox/constants.listbox.d.mts +1 -1
  92. package/dist/js/listbox/event.listbox.d.mts +6 -7
  93. package/dist/js/listbox/event.listbox.mjs +1 -1
  94. package/dist/js/listbox/index.d.mts +43 -5
  95. package/dist/js/listbox/index.mjs +56 -2
  96. package/dist/js/listbox/misc.listbox.d.mts +1 -1
  97. package/dist/js/listbox/misc.listbox.mjs +1 -1
  98. package/dist/js/listbox/state.listbox.d.mts +7 -8
  99. package/dist/js/listbox/state.listbox.mjs +1 -1
  100. package/dist/js/{listbox.data-BWd0PCy7.mjs → listbox.data-DQ7-x2uY.mjs} +8 -7
  101. package/dist/js/{listbox.model-CRReGOmu.d.mts → listbox.model-BHPA7GM4.d.mts} +3 -3
  102. package/dist/js/menu.mjs +1 -1
  103. package/dist/js/{misc.listbox-BI-XsTOf.mjs → misc.listbox-DKB-j0UK.mjs} +4 -5
  104. package/dist/js/{misc.listbox-gnoJhrTr.d.mts → misc.listbox-mZMuYOxg.d.mts} +1 -1
  105. package/dist/js/movable/movable.embedded.d.mts +1 -1
  106. package/dist/js/movable/movable.standalone.d.mts +1 -1
  107. package/dist/js/popover.d.mts +2 -2
  108. package/dist/js/popover.mjs +1 -1
  109. package/dist/js/resizable/resizable.embedded.d.mts +1 -1
  110. package/dist/js/resizable/resizable.embedded.mjs +1 -1
  111. package/dist/js/resizable/resizable.standalone.d.mts +1 -1
  112. package/dist/js/{resizable.embedded-3qoR0Bjm.d.mts → resizable.embedded-dvhdfQgt.d.mts} +1 -1
  113. package/dist/js/sortable/sortable.embedded.d.mts +1 -1
  114. package/dist/js/sortable/sortable.standalone.d.mts +1 -1
  115. package/dist/js/splitter.d.mts +2 -3
  116. package/dist/js/splitter.mjs +2 -2
  117. package/dist/js/{state.combobox-4xq0FPCF.mjs → state.combobox-BWDFHwoi.mjs} +9 -9
  118. package/dist/js/tabs.d.mts +4 -5
  119. package/dist/js/tabs.mjs +4 -7
  120. package/dist/js/tooltip.d.mts +1 -1
  121. package/package.json +24 -22
  122. package/dist/js/constants.combobox-DmRAMC64.d.mts +0 -26
  123. package/dist/js/constants.listbox-DRsXUxd3.d.mts +0 -14
  124. package/src/css/a11y.scss +0 -13
  125. package/src/css/badge.scss +0 -62
  126. package/src/css/button.scss +0 -50
  127. package/src/css/color.scss +0 -115
  128. package/src/css/combobox.scss +0 -252
  129. package/src/css/content.scss +0 -180
  130. package/src/css/flex.scss +0 -107
  131. package/src/css/floatable.scss +0 -152
  132. package/src/css/form.scss +0 -573
  133. package/src/css/listbox.scss +0 -120
  134. package/src/css/message.scss +0 -73
  135. package/src/css/mixins.scss +0 -419
  136. package/src/css/reset.scss +0 -392
  137. package/src/css/splitter.scss +0 -89
  138. package/src/css/table.scss +0 -107
  139. package/src/css/tabs.scss +0 -85
  140. package/src/js/combobox/constants.combobox.ts +0 -83
  141. package/src/js/combobox/dom.combobox.ts +0 -407
  142. package/src/js/combobox/event.combobox.ts +0 -365
  143. package/src/js/combobox/index.ts +0 -320
  144. package/src/js/combobox/misc.combobox.ts +0 -104
  145. package/src/js/combobox/models.combobox.ts +0 -54
  146. package/src/js/combobox/state.combobox.ts +0 -246
  147. package/src/js/dialog.ts +0 -255
  148. package/src/js/floatable/floatable.embedded.ts +0 -332
  149. package/src/js/floatable/floatable.standalone.ts +0 -6
  150. package/src/js/focus-trap/focus-trap.embedded.ts +0 -411
  151. package/src/js/focus-trap/focus-trap.standalone.ts +0 -1
  152. package/src/js/index.ts +0 -15
  153. package/src/js/internal/attributable.ts +0 -73
  154. package/src/js/internal/draggable.ts +0 -657
  155. package/src/js/internal/listbox/listbox.constants.ts +0 -25
  156. package/src/js/internal/listbox/listbox.data.ts +0 -287
  157. package/src/js/internal/listbox/listbox.dom.ts +0 -445
  158. package/src/js/internal/listbox/listbox.event.ts +0 -129
  159. package/src/js/internal/listbox/listbox.form.ts +0 -115
  160. package/src/js/internal/listbox/listbox.misc.ts +0 -135
  161. package/src/js/internal/listbox/listbox.model.ts +0 -169
  162. package/src/js/internal/listbox/listbox.state.ts +0 -82
  163. package/src/js/internal/misc.ts +0 -27
  164. package/src/js/internal/navigable.ts +0 -315
  165. package/src/js/l10n.ts +0 -192
  166. package/src/js/listbox/constants.listbox.ts +0 -61
  167. package/src/js/listbox/event.listbox.ts +0 -106
  168. package/src/js/listbox/index.ts +0 -302
  169. package/src/js/listbox/misc.listbox.ts +0 -70
  170. package/src/js/listbox/state.listbox.ts +0 -196
  171. package/src/js/menu.ts +0 -348
  172. package/src/js/movable/movable.embedded.ts +0 -318
  173. package/src/js/movable/movable.standalone.ts +0 -2
  174. package/src/js/popover.ts +0 -229
  175. package/src/js/resizable/resizable.embedded.ts +0 -413
  176. package/src/js/resizable/resizable.standalone.ts +0 -5
  177. package/src/js/sortable/sortable.embedded.ts +0 -527
  178. package/src/js/sortable/sortable.standalone.ts +0 -2
  179. package/src/js/splitter.ts +0 -583
  180. package/src/js/tabs.ts +0 -447
  181. package/src/js/toolbar.ts +0 -63
  182. package/src/js/tooltip.ts +0 -367
  183. /package/dist/css/{mixins.css → mixins/input.mixins.css} +0 -0
@@ -1,365 +0,0 @@
1
- import {clamp} from '@oscarpalmer/atoms/number';
2
- import {findAncestor, getData} from '@oscarpalmer/toretto';
3
- import {on} from '@oscarpalmer/toretto/event';
4
- import {LISTBOX_KEYS} from '../internal/listbox/listbox.constants';
5
- import {
6
- applyListboxSelection,
7
- filterListbox,
8
- filterListboxOption,
9
- filterListboxOptions,
10
- toggleListboxOption,
11
- } from '../internal/listbox/listbox.data';
12
- import {updateListboxPreview} from '../internal/listbox/listbox.dom';
13
- import {processListboxKeydown} from '../internal/listbox/listbox.event';
14
- import type {OuiListboxPreview} from '../internal/listbox/listbox.model';
15
- import {
16
- COMBOBOX_ATTRIBUTE_SELECTION_ITEM,
17
- COMBOBOX_SELECTORS,
18
- COMBOBOX_TAGNAME,
19
- } from './constants.combobox';
20
- import {
21
- updateComboboxAutocomplete,
22
- updateComboboxSelection,
23
- updateComboboxTabindices,
24
- } from './dom.combobox';
25
- import type {OuiComboboxElement} from './index';
26
- import {hasTextSelection} from './misc.combobox';
27
- import type {OuiComboboxState} from './models.combobox';
28
- import {comboboxStates} from './state.combobox';
29
-
30
- // #region Functions
31
-
32
- export function onComboboxActivation(state: OuiComboboxState): void {
33
- state.floatable.show();
34
- }
35
-
36
- export function onComboboxApply(
37
- state: OuiComboboxState,
38
- option: HTMLElement | undefined,
39
- _: string[],
40
- added: boolean,
41
- selected?: HTMLElement[],
42
- ): void {
43
- updateComboboxSelection(state, option, added, selected);
44
- }
45
-
46
- export function onComboboxClickContent(event: PointerEvent, state: OuiComboboxState): void {
47
- if (state == null) {
48
- return;
49
- }
50
-
51
- if (state.disabled) {
52
- return;
53
- }
54
-
55
- const option = findAncestor(event, COMBOBOX_SELECTORS.option);
56
-
57
- if (!(option instanceof HTMLElement)) {
58
- state.filter.element.focus();
59
- } else if (state.readonly) {
60
- onComboboxPreview('set', state, option);
61
- } else {
62
- toggleListboxOption(state, option);
63
- }
64
- }
65
-
66
- function onComboboxClickDocument(event: PointerEvent): void {
67
- const combobox = findAncestor(event, COMBOBOX_TAGNAME);
68
- const state = comboboxStates.map.get(combobox!);
69
-
70
- if (combobox == null || state == null) {
71
- return;
72
- }
73
-
74
- if (findAncestor(event, COMBOBOX_SELECTORS.content) != null) {
75
- onComboboxClickContent(event, state);
76
-
77
- return;
78
- }
79
-
80
- const label = findAncestor(event, 'label');
81
-
82
- if (label != null) {
83
- if (label === state.label.element && combobox.type === 'select') {
84
- state.anchor.element.focus();
85
-
86
- if (!state.disabled) {
87
- state.floatable.show();
88
- }
89
- }
90
-
91
- return;
92
- }
93
-
94
- const selection = findAncestor(event, `[${COMBOBOX_ATTRIBUTE_SELECTION_ITEM}]`);
95
-
96
- if (selection != null) {
97
- const option = state.options.selected.find(
98
- option => option.id === getData(selection, 'option', false),
99
- );
100
-
101
- if (state.disabled) {
102
- state.anchor.element.focus();
103
- } else if (state.readonly) {
104
- updateComboboxTabindices(state, option);
105
- } else {
106
- toggleListboxOption(state, option);
107
- }
108
-
109
- return;
110
- }
111
-
112
- const anchor = findAncestor(event, COMBOBOX_SELECTORS.anchor);
113
-
114
- if (anchor != null && !state.disabled) {
115
- state.floatable.show();
116
-
117
- return;
118
- }
119
- }
120
-
121
- export function onComboboxEnter(state: OuiComboboxState): void {
122
- if (state.disabled || state.readonly) {
123
- return;
124
- }
125
-
126
- if (hasTextSelection(state.anchor.element)) {
127
- onComboboxSelection(state, true);
128
- } else {
129
- toggleListboxOption(state, state.active);
130
- }
131
- }
132
-
133
- export function onComboboxEscape(state: OuiComboboxState): void {
134
- state.floatable.hide();
135
- }
136
-
137
- export function onComboboxFilter(
138
- preview: OuiListboxPreview,
139
- state: OuiComboboxState,
140
- update: boolean,
141
- active?: HTMLElement,
142
- emit?: boolean,
143
- ): void {
144
- if (state.autocomplete.none) {
145
- applyListboxSelection({
146
- state,
147
- added: false,
148
- emit: (emit ?? true) && update,
149
- });
150
- } else {
151
- updateListboxPreview(preview, state, active);
152
- }
153
- }
154
-
155
- export function onComboboxFocusout(event: FocusEvent): void {
156
- setTimeout(() => {
157
- const combobox = findAncestor(event, COMBOBOX_TAGNAME);
158
- const state = comboboxStates.map.get(combobox!);
159
-
160
- if (
161
- combobox == null ||
162
- state == null ||
163
- state.disabled ||
164
- state.readonly ||
165
- state.type === 'select' ||
166
- state.host === document.activeElement ||
167
- state.host.contains(document.activeElement)
168
- ) {
169
- return;
170
- }
171
-
172
- const option = filterListboxOption(state, state.filter.element.value, true);
173
-
174
- applyListboxSelection({
175
- option,
176
- state,
177
- added: false,
178
- selected: option == null ? [] : [option],
179
- });
180
- });
181
- }
182
-
183
- export function onComboboxInput(event: InputEvent): void {
184
- const combobox = findAncestor(event, COMBOBOX_TAGNAME) as OuiComboboxElement | null;
185
- const state = comboboxStates.map.get(combobox!);
186
-
187
- if (combobox != null && state != null && event.target === state.filter.element) {
188
- filterListbox(event.inputType, state);
189
- }
190
- }
191
-
192
- export function onComboboxKeydown(event: KeyboardEvent): void {
193
- const combobox = findAncestor(event, COMBOBOX_TAGNAME) as OuiComboboxElement | null;
194
- const state = comboboxStates.map.get(combobox!);
195
-
196
- if (combobox == null || state == null) {
197
- return;
198
- }
199
-
200
- const item = findAncestor(event, COMBOBOX_SELECTORS.selectionItem);
201
-
202
- if (item instanceof HTMLElement) {
203
- onComboboxKeydownSelection(event, state, item);
204
- } else {
205
- processListboxKeydown(event, state);
206
- }
207
- }
208
-
209
- export function onComboboxKeydownSelection(
210
- event: KeyboardEvent,
211
- state: OuiComboboxState,
212
- item: HTMLElement,
213
- ): void {
214
- if (LISTBOX_KEYS.activation.has(event.key)) {
215
- event.preventDefault();
216
-
217
- onComboboxRemoveSelection(state, item);
218
-
219
- return;
220
- }
221
-
222
- if (state.disabled || state.selection == null) {
223
- return;
224
- }
225
-
226
- const {length} = state.selection.items;
227
-
228
- const index = state.selection.items.findIndex(selection => selection.button === item);
229
-
230
- let next: number | undefined;
231
-
232
- switch (event.key) {
233
- case 'ArrowDown':
234
- state.anchor.element.focus();
235
- state.anchor.element.click();
236
- return;
237
-
238
- case 'ArrowRight':
239
- case 'ArrowLeft':
240
- next = clamp(index + (event.key === 'ArrowRight' ? 1 : -1), 0, length - 1, true);
241
- break;
242
-
243
- case 'End':
244
- next = length - 1;
245
- break;
246
-
247
- case 'Home':
248
- next = 0;
249
- break;
250
-
251
- default:
252
- break;
253
- }
254
-
255
- if (next == null) {
256
- return;
257
- }
258
-
259
- event.preventDefault();
260
-
261
- for (let index = 0; index < length; index += 1) {
262
- const {button} = state.selection.items[index];
263
- const selected = index === next;
264
-
265
- button.tabIndex = selected ? 0 : -1;
266
-
267
- if (selected) {
268
- button.focus();
269
- }
270
- }
271
- }
272
-
273
- export function onComboboxPreview(
274
- preview: OuiListboxPreview,
275
- state: OuiComboboxState,
276
- active?: HTMLElement,
277
- ): void {
278
- updateComboboxAutocomplete(preview, state, active);
279
- }
280
-
281
- export function onComboboxRemoveSelection(state: OuiComboboxState, item: HTMLElement): void {
282
- if (state.disabled || state.readonly) {
283
- return;
284
- }
285
-
286
- const option = state.options.selected.find(
287
- option => option.id === getData(item, 'option', false),
288
- );
289
-
290
- if (option != null) {
291
- toggleListboxOption(state, option);
292
- }
293
- }
294
-
295
- export function onComboboxNavigation(
296
- preview: OuiListboxPreview,
297
- state: OuiComboboxState,
298
- active?: HTMLElement,
299
- ): void {
300
- updateListboxPreview(preview, state, active);
301
- }
302
-
303
- export function onComboboxSelection(state: OuiComboboxState, hasSelection?: boolean): void {
304
- if (!(hasSelection ?? hasTextSelection(state.anchor.element))) {
305
- return;
306
- }
307
-
308
- state.filter.value =
309
- state.anchor.element === state.filter.element ? state.filter.element.value : '';
310
-
311
- toggleListboxOption(state, filterListboxOptions(state) ?? state.active);
312
- }
313
-
314
- export function onComboboxTab(state: OuiComboboxState): void {
315
- setTimeout(() => {
316
- if (state.host === document.activeElement) {
317
- return;
318
- }
319
-
320
- if (
321
- state.selection?.container.contains(document.activeElement) ||
322
- !state.host.contains(document.activeElement)
323
- ) {
324
- state.floatable.hide();
325
- }
326
- });
327
- }
328
-
329
- export function onComboboxToggle(state: OuiComboboxState): void {
330
- if (!state.multiple) {
331
- state.floatable.hide();
332
- }
333
- }
334
-
335
- export function preventComboboxActivation(state: OuiComboboxState): boolean {
336
- return state.floatable.open;
337
- }
338
-
339
- export function skipComboboxNavigation(state: OuiComboboxState): boolean {
340
- if (state.floatable.open) {
341
- return false;
342
- }
343
-
344
- state.floatable.show();
345
-
346
- return true;
347
- }
348
-
349
- // #endregion
350
-
351
- // #region Initialization
352
-
353
- on(document, 'click', onComboboxClickDocument);
354
-
355
- on(document, 'focusout', onComboboxFocusout);
356
-
357
- on(document, 'input', onComboboxInput, {
358
- passive: false,
359
- });
360
-
361
- on(document, 'keydown', onComboboxKeydown, {
362
- passive: false,
363
- });
364
-
365
- // #endregion
@@ -1,320 +0,0 @@
1
- import {parse} from '@oscarpalmer/atoms/string';
2
- import {getAttribute} from '@oscarpalmer/toretto/attribute';
3
- import {setListboxValue, setListboxValues} from '../internal/listbox/listbox.data';
4
- import {
5
- setListboxDisabled,
6
- setListboxFilter,
7
- setListboxLimit,
8
- setListboxReadonly,
9
- setListboxRequired,
10
- } from '../internal/listbox/listbox.misc';
11
- import type {OuiListboxLocalizations, OuiListboxType} from '../internal/listbox/listbox.model';
12
- import {attachListbox, detachListbox} from '../internal/listbox/listbox.state';
13
- import {updateLocalizations} from '../l10n';
14
- import {COMBOBOX_TAGNAME} from './constants.combobox';
15
- import type {OuiComboboxState} from './models.combobox';
16
- import {
17
- comboboxStates,
18
- createComboboxState,
19
- onAttachCombobox,
20
- onDetachCombobox,
21
- } from './state.combobox';
22
-
23
- // #region Types
24
-
25
- declare global {
26
- interface HTMLElementTagNameMap {
27
- [COMBOBOX_TAGNAME]: OuiComboboxElement;
28
- }
29
- }
30
-
31
- export class OuiComboboxElement extends HTMLElement {
32
- static formAssociated = true;
33
-
34
- static observedAttributes = ['max', 'min', 'required', 'value'];
35
-
36
- readonly #internals: ElementInternals;
37
-
38
- #restored?: string[];
39
-
40
- #state!: OuiComboboxState;
41
-
42
- /**
43
- * Is the combobox disabled?
44
- */
45
- get disabled(): boolean {
46
- return this.#state?.disabled ?? false;
47
- }
48
-
49
- /**
50
- * Should the combobox be disabled?
51
- */
52
- set disabled(value: boolean) {
53
- if (typeof value === 'boolean' && value !== this.disabled) {
54
- setListboxDisabled(this.#state, value);
55
- }
56
- }
57
-
58
- /**
59
- * Current filter value
60
- */
61
- get filter(): string {
62
- return this.#state.filter.element.value;
63
- }
64
-
65
- /**
66
- * Set the filter value
67
- */
68
- set filter(value: string) {
69
- setListboxFilter(this.#state, value);
70
- }
71
-
72
- /**
73
- * Maximum number of selected options
74
- */
75
- get max(): number | undefined {
76
- return this.#state?.max;
77
- }
78
-
79
- /**
80
- * Set the maximum number of selected options
81
- */
82
- set max(value: number) {
83
- setListboxLimit('max', this.#state, value);
84
- }
85
-
86
- /**
87
- * Minimum number of selected options
88
- */
89
- get min(): number | undefined {
90
- return this.#state?.min;
91
- }
92
-
93
- /**
94
- * Set the minimum number of selected options
95
- */
96
- set min(value: number) {
97
- setListboxLimit('min', this.#state, value);
98
- }
99
-
100
- /**
101
- * Does the combobox allow multiple values?
102
- */
103
- get multiple(): boolean {
104
- return this.hasAttribute('multiple');
105
- }
106
-
107
- /**
108
- * Name of the combobox
109
- */
110
- get name(): string {
111
- return getAttribute(this, 'name') ?? '';
112
- }
113
-
114
- /**
115
- * Is the combobox readonly?
116
- */
117
- get readonly(): boolean {
118
- return this.#state?.readonly ?? false;
119
- }
120
-
121
- /**
122
- * Should the combobox be readonly?
123
- */
124
- set readonly(value: boolean) {
125
- if (typeof value === 'boolean' && value !== this.readonly) {
126
- setListboxReadonly(this.#state, value);
127
- }
128
- }
129
-
130
- /**
131
- * Is the combobox required?
132
- */
133
- get required(): boolean {
134
- return this.#state?.required ?? false;
135
- }
136
-
137
- /**
138
- * Should the combobox be required?
139
- */
140
- set required(value: boolean) {
141
- if (typeof value === 'boolean' && value !== this.required) {
142
- setListboxRequired(this.#state, value);
143
- }
144
- }
145
-
146
- /**
147
- * Selected options
148
- */
149
- get selected(): HTMLElement[] {
150
- return this.#state.options.selected.slice();
151
- }
152
-
153
- /**
154
- * Type of combobox
155
- */
156
- get type(): OuiListboxType {
157
- return this.#state.type;
158
- }
159
-
160
- /**
161
- * Current value
162
- */
163
- get value(): string {
164
- return this.#state.values.current[0];
165
- }
166
-
167
- /**
168
- * Set the value
169
- */
170
- set value(value: unknown) {
171
- setListboxValue(this.#state, value);
172
- }
173
-
174
- /**
175
- * Current values
176
- */
177
- get values(): string[] {
178
- return this.#state.values.current.slice();
179
- }
180
-
181
- /**
182
- * Set the values
183
- */
184
- set values(values: unknown[]) {
185
- setListboxValues(this.#state, values);
186
- }
187
-
188
- constructor() {
189
- super();
190
-
191
- this.#internals = this.attachInternals();
192
- }
193
-
194
- attributeChangedCallback(name: string, _: string | null, value: string | null): void {
195
- if (this.#state == null) {
196
- return;
197
- }
198
-
199
- switch (name) {
200
- case 'required':
201
- this[name] = this.hasAttribute(name);
202
- break;
203
-
204
- case 'max':
205
- case 'min':
206
- setListboxLimit(name, this.#state, value);
207
- break;
208
-
209
- case 'value':
210
- this.value = value ?? '';
211
- break;
212
-
213
- default:
214
- break;
215
- }
216
- }
217
-
218
- /**
219
- * Clear all selected options
220
- */
221
- clear(): void {
222
- setListboxValues(this.#state, []);
223
- }
224
-
225
- connectedCallback(): void {
226
- if (this.#state == null) {
227
- this.#initialize();
228
- } else {
229
- attachListbox(this.#state, comboboxStates, onAttachCombobox);
230
- }
231
- }
232
-
233
- disconnectedCallback(): void {
234
- if (this.#state != null) {
235
- detachListbox(this.#state, comboboxStates, onDetachCombobox);
236
- }
237
- }
238
-
239
- formDisabledCallback(disabled: boolean): void {
240
- this.disabled = disabled;
241
- }
242
-
243
- formResetCallback(): void {
244
- setListboxValues(this.#state, this.#state.values.initial);
245
- }
246
-
247
- formStateRestoreCallback(state: string | File | FormData, reason: unknown): void {
248
- if (reason !== 'restore') {
249
- return;
250
- }
251
-
252
- const parsed = typeof state === 'string' ? parse(state) : undefined;
253
-
254
- if (!Array.isArray(parsed)) {
255
- return;
256
- }
257
-
258
- if (this.#state == null) {
259
- this.#restored = parsed;
260
- } else {
261
- setListboxValues(this.#state, parsed);
262
- }
263
- }
264
-
265
- /**
266
- * Set combobox localizations for a specific language
267
- *
268
- * @param language Language code
269
- * @param localizations Localizations for language
270
- */
271
- setLocalizations(language: string, localizations: Partial<OuiListboxLocalizations>): void;
272
-
273
- /**
274
- * Set combobox localizations for one or more languages
275
- *
276
- * @param localizations Localizations for one or more languages
277
- */
278
- setLocalizations(localizations: Record<string, Partial<OuiListboxLocalizations>>): void;
279
-
280
- setLocalizations(
281
- first: string | Record<string, Partial<OuiListboxLocalizations>>,
282
- second?: Partial<OuiListboxLocalizations>,
283
- ): void {
284
- updateLocalizations(
285
- this.#state.localizations.global,
286
- typeof first === 'string'
287
- ? {
288
- [first]: second!,
289
- }
290
- : first,
291
- this.#state.localizations.component,
292
- );
293
- }
294
-
295
- #initialize(): void {
296
- this.tabIndex = -1;
297
-
298
- this.#state = createComboboxState(this, this.#internals);
299
-
300
- if (this.#restored != null) {
301
- setListboxValues(this.#state, this.#restored);
302
-
303
- this.#restored = undefined;
304
- }
305
- }
306
- }
307
-
308
- // #endregion
309
-
310
- // #region Initialization
311
-
312
- customElements.define(COMBOBOX_TAGNAME, OuiComboboxElement);
313
-
314
- // #endregion
315
-
316
- // #region Exports
317
-
318
- export {setComboboxLocalizations} from './misc.combobox';
319
-
320
- // #endregion