@oscarpalmer/oui 0.32.0 → 0.34.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 (59) hide show
  1. package/dist/css/combobox.css +93 -42
  2. package/dist/js/combobox/constants.combobox.d.mts +2 -0
  3. package/dist/js/combobox/constants.combobox.mjs +46 -0
  4. package/dist/js/combobox/data.combobox.d.mts +18 -0
  5. package/dist/js/combobox/data.combobox.mjs +2 -0
  6. package/dist/js/combobox/dom.combobox.d.mts +110 -0
  7. package/dist/js/combobox/dom.combobox.mjs +2 -0
  8. package/dist/js/combobox/event.combobox.d.mts +17 -0
  9. package/dist/js/combobox/event.combobox.mjs +2 -0
  10. package/dist/js/combobox/form.combobox.d.mts +6 -0
  11. package/dist/js/combobox/form.combobox.mjs +2 -0
  12. package/dist/js/combobox/i18n.combobox.d.mts +2 -0
  13. package/dist/js/combobox/i18n.combobox.mjs +2 -0
  14. package/dist/js/combobox/index.d.mts +2 -0
  15. package/dist/js/combobox/index.mjs +194 -0
  16. package/dist/js/combobox/misc.combobox.d.mts +14 -0
  17. package/dist/js/combobox/misc.combobox.mjs +2 -0
  18. package/dist/js/combobox/models.combobox.d.mts +2 -0
  19. package/dist/js/combobox/models.combobox.mjs +1 -0
  20. package/dist/js/combobox/state.combobox.d.mts +11 -0
  21. package/dist/js/combobox/state.combobox.mjs +2 -0
  22. package/dist/js/constants.combobox-DqNUGBLS.d.mts +243 -0
  23. package/dist/js/data.combobox-8RwBv5ey.mjs +1077 -0
  24. package/dist/js/dialog.mjs +3 -2
  25. package/dist/js/floatable/floatable.embedded.mjs +4 -4
  26. package/dist/js/focus-trap/focus-trap.embedded.mjs +3 -3
  27. package/dist/js/index.d.mts +3 -3
  28. package/dist/js/index.mjs +3 -2
  29. package/dist/js/internal/draggable.mjs +6 -6
  30. package/dist/js/internal/navigable.mjs +3 -3
  31. package/dist/js/menu.mjs +3 -2
  32. package/dist/js/movable/movable.embedded.mjs +3 -3
  33. package/dist/js/popover.mjs +1 -1
  34. package/dist/js/resizable/resizable.embedded.mjs +7 -7
  35. package/dist/js/sortable/sortable.embedded.mjs +7 -6
  36. package/dist/js/splitter.mjs +7 -13
  37. package/dist/js/tooltip.mjs +3 -3
  38. package/package.json +6 -6
  39. package/src/css/combobox.scss +98 -31
  40. package/src/js/combobox/constants.combobox.ts +62 -0
  41. package/src/js/combobox/data.combobox.ts +236 -0
  42. package/src/js/combobox/dom.combobox.ts +794 -0
  43. package/src/js/combobox/event.combobox.ts +454 -0
  44. package/src/js/combobox/form.combobox.ts +115 -0
  45. package/src/js/combobox/i18n.combobox.ts +179 -0
  46. package/src/js/combobox/index.ts +307 -0
  47. package/src/js/combobox/misc.combobox.ts +138 -0
  48. package/src/js/combobox/models.combobox.ts +94 -0
  49. package/src/js/combobox/state.combobox.ts +235 -0
  50. package/src/js/index.ts +1 -1
  51. package/src/js/internal/draggable.ts +3 -3
  52. package/src/js/internal/navigable.ts +10 -3
  53. package/src/js/movable/movable.embedded.ts +2 -2
  54. package/src/js/resizable/resizable.embedded.ts +3 -3
  55. package/src/js/sortable/sortable.embedded.ts +2 -2
  56. package/src/js/splitter.ts +2 -2
  57. package/dist/js/combobox.d.mts +0 -91
  58. package/dist/js/combobox.mjs +0 -855
  59. package/src/js/combobox.ts +0 -1634
@@ -0,0 +1,179 @@
1
+ import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
+ import {
3
+ updateComboboxAnchor,
4
+ updateComboboxMessage,
5
+ updateComboboxSelectionItems,
6
+ } from './dom.combobox';
7
+ import {getComboboxVisibleOptions} from './misc.combobox';
8
+ import type {OuiComboboxLocalizations, OuiComboboxState} from './models.combobox';
9
+ import {comboboxStates} from './state.combobox';
10
+
11
+ // #region Functions
12
+
13
+ export function getComboboxLanguage(state: OuiComboboxState): string {
14
+ return (
15
+ state.host.closest('[lang]')?.getAttribute('lang') ?? document.documentElement.lang
16
+ ).toLowerCase();
17
+ }
18
+
19
+ export function getComboboxLocalization<Key extends keyof OuiComboboxLocalizations>(
20
+ key: Key,
21
+ state: OuiComboboxState,
22
+ ): OuiComboboxLocalizations[Key] {
23
+ const language = getComboboxLanguage(state);
24
+
25
+ const allLocalizations = [state.localizations, LOCALIZATIONS.globals];
26
+ const {length} = allLocalizations;
27
+
28
+ let localization: OuiComboboxLocalizations[Key] | undefined;
29
+ let shortLanguage: string | undefined;
30
+
31
+ for (let index = 0; index < length; index += 1) {
32
+ const localizations = allLocalizations[index];
33
+
34
+ localization = localizations?.[language]?.[key];
35
+
36
+ if (localization != null) {
37
+ break;
38
+ }
39
+
40
+ shortLanguage ??= language.split('-')[0];
41
+
42
+ if (shortLanguage === language) {
43
+ continue;
44
+ }
45
+
46
+ localization = localizations?.[shortLanguage]?.[key];
47
+
48
+ if (localization != null) {
49
+ break;
50
+ }
51
+ }
52
+
53
+ return localization ?? LOCALIZATIONS.defaults[key];
54
+ }
55
+
56
+ /**
57
+ * Set combobox localizations for a specific language
58
+ *
59
+ * @param language Language code
60
+ * @param localizations Localizations for language
61
+ */
62
+ export function setComboboxLocalizations(
63
+ language: string,
64
+ localizations: Partial<OuiComboboxLocalizations>,
65
+ ): void;
66
+
67
+ /**
68
+ * Set combobox localizations for one or more languages
69
+ *
70
+ * @param localizations Localizations for one or more languages
71
+ */
72
+ export function setComboboxLocalizations(
73
+ localizations: Record<string, Partial<OuiComboboxLocalizations>>,
74
+ ): void;
75
+
76
+ export function setComboboxLocalizations(
77
+ first: string | Record<string, Partial<OuiComboboxLocalizations>>,
78
+ second?: Partial<OuiComboboxLocalizations>,
79
+ ): void {
80
+ updateComboboxLocalizations(
81
+ typeof first === 'string'
82
+ ? {
83
+ [first]: second!,
84
+ }
85
+ : first,
86
+ );
87
+ }
88
+
89
+ export function updateComboboxLocalizations(
90
+ values: Record<string, Partial<Record<string, string | GenericCallback>>>,
91
+ destination?: Record<string, Partial<OuiComboboxLocalizations>>,
92
+ ): void {
93
+ if (typeof values !== 'object' || values == null) {
94
+ return;
95
+ }
96
+
97
+ const localizations = destination ?? LOCALIZATIONS.globals;
98
+
99
+ const languages = Object.keys(values);
100
+ const languagesLength = languages.length;
101
+
102
+ let updated = false;
103
+
104
+ for (let languagesIndex = 0; languagesIndex < languagesLength; languagesIndex += 1) {
105
+ const language = languages[languagesIndex];
106
+ const languageValue = values[language];
107
+
108
+ if (typeof languageValue !== 'object' || languageValue == null) {
109
+ continue;
110
+ }
111
+
112
+ const normalizedLanguage = language.toLowerCase();
113
+
114
+ localizations[normalizedLanguage] ??= {};
115
+
116
+ const keys = Object.keys(languageValue);
117
+ const keysLength = keys.length;
118
+
119
+ for (let keysIndex = 0; keysIndex < keysLength; keysIndex += 1) {
120
+ const key = keys[keysIndex];
121
+ const keyValue = languageValue[key];
122
+
123
+ const normalizedKey = key.toLowerCase() as keyof OuiComboboxLocalizations;
124
+
125
+ if (
126
+ LOCALIZATIONS.keys.has(normalizedKey) &&
127
+ (typeof keyValue === 'string' || typeof keyValue === 'function')
128
+ ) {
129
+ updated = true;
130
+
131
+ localizations[normalizedLanguage][normalizedKey] = keyValue as never;
132
+ }
133
+ }
134
+ }
135
+
136
+ if (!updated) {
137
+ return;
138
+ }
139
+
140
+ for (const state of comboboxStates.set) {
141
+ updateComboboxAnchor(state);
142
+ updateComboboxMessage(state, getComboboxVisibleOptions(state).length);
143
+ updateComboboxSelectionItems(state);
144
+ }
145
+ }
146
+
147
+ // #endregion
148
+
149
+ // #region Variables
150
+
151
+ const LOCALIZATIONS: {
152
+ defaults: OuiComboboxLocalizations;
153
+ globals: Record<string, Partial<OuiComboboxLocalizations>>;
154
+ keys: Set<keyof OuiComboboxLocalizations>;
155
+ } = {
156
+ defaults: {
157
+ empty: 'No results found',
158
+ input: 'Please enter a value',
159
+ invalid: 'Please select an option from the list',
160
+ max: max => `Please select fewer options (maximum is ${max})`,
161
+ min: min => `Please select more options (minimum is ${min})`,
162
+ remove: label => `Remove ${label}`,
163
+ results: amount => `${amount} results available`,
164
+ selected: amount => `${amount} selected`,
165
+ },
166
+ globals: {},
167
+ keys: new Set<keyof OuiComboboxLocalizations>([
168
+ 'empty',
169
+ 'input',
170
+ 'invalid',
171
+ 'max',
172
+ 'min',
173
+ 'remove',
174
+ 'results',
175
+ 'selected',
176
+ ]),
177
+ };
178
+
179
+ // #endregion
@@ -0,0 +1,307 @@
1
+ import {parse} from '@oscarpalmer/atoms/string';
2
+ import {getAttribute} from '@oscarpalmer/toretto/attribute';
3
+ import {COMBOBOX_TAGNAME} from './constants.combobox';
4
+ import {setComboboxValue, setComboboxValues} from './data.combobox';
5
+ import {setComboboxDisabled, setComboboxReadonly, setComboboxRequired} from './dom.combobox';
6
+ import {updateComboboxLocalizations} from './i18n.combobox';
7
+ import {setComboboxFilter, setComboboxLimit} from './misc.combobox';
8
+ import type {OuiComboboxLocalizations, OuiComboboxState, OuiComboboxType} from './models.combobox';
9
+ import {attachCombobox, createComboboxState, detachCombobox} from './state.combobox';
10
+
11
+ // #region Types
12
+
13
+ declare global {
14
+ interface HTMLElementTagNameMap {
15
+ [COMBOBOX_TAGNAME]: OuiComboboxElement;
16
+ }
17
+ }
18
+
19
+ export class OuiComboboxElement extends HTMLElement {
20
+ static formAssociated = true;
21
+
22
+ static observedAttributes = ['max', 'min', 'required', 'value'];
23
+
24
+ readonly #internals: ElementInternals;
25
+
26
+ #restored?: string[];
27
+
28
+ #state!: OuiComboboxState;
29
+
30
+ /**
31
+ * Is the combobox disabled?
32
+ */
33
+ get disabled(): boolean {
34
+ return this.#state?.disabled ?? false;
35
+ }
36
+
37
+ /**
38
+ * Should the combobox be disabled?
39
+ */
40
+ set disabled(value: boolean) {
41
+ if (typeof value === 'boolean' && value !== this.disabled) {
42
+ setComboboxDisabled(this.#state, value);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Current filter value
48
+ */
49
+ get filter(): string {
50
+ return this.#state.filter.element.value;
51
+ }
52
+
53
+ /**
54
+ * Set the filter value
55
+ */
56
+ set filter(value: string) {
57
+ setComboboxFilter(this.#state, value);
58
+ }
59
+
60
+ /**
61
+ * Maximum number of selected options
62
+ */
63
+ get max(): number | undefined {
64
+ return this.#state?.max;
65
+ }
66
+
67
+ /**
68
+ * Set the maximum number of selected options
69
+ */
70
+ set max(value: number) {
71
+ setComboboxLimit('max', this.#state, value);
72
+ }
73
+
74
+ /**
75
+ * Minimum number of selected options
76
+ */
77
+ get min(): number | undefined {
78
+ return this.#state?.min;
79
+ }
80
+
81
+ /**
82
+ * Set the minimum number of selected options
83
+ */
84
+ set min(value: number) {
85
+ setComboboxLimit('min', this.#state, value);
86
+ }
87
+
88
+ /**
89
+ * Does the combobox allow multiple values?
90
+ */
91
+ get multiple(): boolean {
92
+ return this.hasAttribute('multiple');
93
+ }
94
+
95
+ /**
96
+ * Name of the combobox
97
+ */
98
+ get name(): string {
99
+ return getAttribute(this, 'name') ?? '';
100
+ }
101
+
102
+ /**
103
+ * Is the combobox readonly?
104
+ */
105
+ get readonly(): boolean {
106
+ return this.#state?.readonly ?? false;
107
+ }
108
+
109
+ /**
110
+ * Should the combobox be readonly?
111
+ */
112
+ set readonly(value: boolean) {
113
+ if (typeof value === 'boolean' && value !== this.readonly) {
114
+ setComboboxReadonly(this.#state, value);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Is the combobox required?
120
+ */
121
+ get required(): boolean {
122
+ return this.#state?.required ?? false;
123
+ }
124
+
125
+ /**
126
+ * Should the combobox be required?
127
+ */
128
+ set required(value: boolean) {
129
+ if (typeof value === 'boolean' && value !== this.required) {
130
+ setComboboxRequired(this.#state, value);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Selected options
136
+ */
137
+ get selected(): HTMLElement[] {
138
+ return this.#state.options.selected.slice();
139
+ }
140
+
141
+ /**
142
+ * Type of combobox
143
+ */
144
+ get type(): OuiComboboxType {
145
+ return this.#state.type;
146
+ }
147
+
148
+ /**
149
+ * Current value
150
+ */
151
+ get value(): string {
152
+ return this.#state.values.current[0];
153
+ }
154
+
155
+ /**
156
+ * Set the value
157
+ */
158
+ set value(value: unknown) {
159
+ setComboboxValue(this.#state, value);
160
+ }
161
+
162
+ /**
163
+ * Current values
164
+ */
165
+ get values(): string[] {
166
+ return this.#state.values.current.slice();
167
+ }
168
+
169
+ /**
170
+ * Set the values
171
+ */
172
+ set values(value: unknown[]) {
173
+ setComboboxValues(this.#state, value);
174
+ }
175
+
176
+ constructor() {
177
+ super();
178
+
179
+ this.#internals = this.attachInternals();
180
+ }
181
+
182
+ attributeChangedCallback(name: string, _: string | null, value: string | null): void {
183
+ if (this.#state == null) {
184
+ return;
185
+ }
186
+
187
+ switch (name) {
188
+ case 'required':
189
+ this[name] = this.hasAttribute(name);
190
+ break;
191
+
192
+ case 'max':
193
+ case 'min':
194
+ setComboboxLimit(name, this.#state, value);
195
+ break;
196
+
197
+ case 'value':
198
+ this.value = value ?? '';
199
+ break;
200
+
201
+ default:
202
+ break;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Clear all selected options
208
+ */
209
+ clear(): void {
210
+ setComboboxValues(this.#state, []);
211
+ }
212
+
213
+ connectedCallback(): void {
214
+ if (this.#state == null) {
215
+ this.#initialize();
216
+ } else {
217
+ attachCombobox(this.#state);
218
+ }
219
+ }
220
+
221
+ disconnectedCallback(): void {
222
+ if (this.#state != null) {
223
+ detachCombobox(this.#state);
224
+ }
225
+ }
226
+
227
+ formDisabledCallback(disabled: boolean): void {
228
+ this.disabled = disabled;
229
+ }
230
+
231
+ formResetCallback(): void {
232
+ setComboboxValues(this.#state, this.#state.values.initial, false);
233
+ }
234
+
235
+ formStateRestoreCallback(state: string | File | FormData, reason: unknown): void {
236
+ if (reason !== 'restore') {
237
+ return;
238
+ }
239
+
240
+ const parsed = typeof state === 'string' ? parse(state) : undefined;
241
+
242
+ if (!Array.isArray(parsed)) {
243
+ return;
244
+ }
245
+
246
+ if (this.#state == null) {
247
+ this.#restored = parsed;
248
+ } else {
249
+ setComboboxValues(this.#state, parsed);
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Set combobox localizations for a specific language
255
+ *
256
+ * @param language Language code
257
+ * @param localizations Localizations for language
258
+ */
259
+ setLocalizations(language: string, localizations: Partial<OuiComboboxLocalizations>): void;
260
+
261
+ /**
262
+ * Set combobox localizations for one or more languages
263
+ *
264
+ * @param localizations Localizations for one or more languages
265
+ */
266
+ setLocalizations(localizations: Record<string, Partial<OuiComboboxLocalizations>>): void;
267
+
268
+ setLocalizations(
269
+ first: string | Record<string, Partial<OuiComboboxLocalizations>>,
270
+ second?: Partial<OuiComboboxLocalizations>,
271
+ ): void {
272
+ updateComboboxLocalizations(
273
+ typeof first === 'string'
274
+ ? {
275
+ [first]: second!,
276
+ }
277
+ : first,
278
+ this.#state.localizations,
279
+ );
280
+ }
281
+
282
+ #initialize(): void {
283
+ this.tabIndex = -1;
284
+
285
+ this.#state = createComboboxState(this, this.#internals);
286
+
287
+ if (this.#restored != null) {
288
+ setComboboxValues(this.#state, this.#restored, false);
289
+
290
+ this.#restored = undefined;
291
+ }
292
+ }
293
+ }
294
+
295
+ // #endregion
296
+
297
+ // #region Initialization
298
+
299
+ customElements.define(COMBOBOX_TAGNAME, OuiComboboxElement);
300
+
301
+ // #endregion
302
+
303
+ // #region Exports
304
+
305
+ export {setComboboxLocalizations} from './i18n.combobox';
306
+
307
+ // #endregion
@@ -0,0 +1,138 @@
1
+ import {getAria} from '@oscarpalmer/toretto/aria';
2
+ import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
3
+ import type {AnyAriaBooleanAttribute} from '@oscarpalmer/toretto/models';
4
+ import type {OuiComboboxElement} from '.';
5
+ import {COMBOBOX_AUTOCOMPLETES} from './constants.combobox';
6
+ import {onComboboxFilter} from './event.combobox';
7
+ import {updateComboboxValidity} from './form.combobox';
8
+ import type {
9
+ OuiComboboxAutoComplete,
10
+ OuiComboboxAutoCompleteType,
11
+ OuiComboboxState,
12
+ } from './models.combobox';
13
+
14
+ // #region Functions
15
+
16
+ export function generateComboboxIds(prefix: string, select: HTMLSelectElement): void {
17
+ const elements = [...select.children].flatMap(child =>
18
+ child instanceof HTMLOptGroupElement
19
+ ? [
20
+ child,
21
+ ...[...child.children].filter(groupChild => groupChild instanceof HTMLOptionElement),
22
+ ]
23
+ : child instanceof HTMLOptionElement
24
+ ? [child]
25
+ : [],
26
+ );
27
+
28
+ const {length} = elements;
29
+
30
+ for (let index = 0; index < length; index += 1) {
31
+ const element = elements[index];
32
+
33
+ if (element.id === '') {
34
+ element.id = `${prefix}${element instanceof HTMLOptGroupElement ? '_group_' : '_option_'}${index}`;
35
+ }
36
+ }
37
+ }
38
+
39
+ export function getComboboxAttributeValue<Value>(
40
+ element: HTMLElement,
41
+ attribute: string,
42
+ possible: Set<Value>,
43
+ defaultValue: Value,
44
+ ): Value {
45
+ const value = getAttribute(element, attribute);
46
+
47
+ return possible.has(value as Value) ? (value as Value) : defaultValue;
48
+ }
49
+
50
+ export function getComboboxAutoComplete(
51
+ element: OuiComboboxElement,
52
+ select: boolean,
53
+ ): OuiComboboxAutoComplete {
54
+ let value: OuiComboboxAutoCompleteType;
55
+
56
+ if (select) {
57
+ value = 'list';
58
+ } else {
59
+ value = getComboboxAttributeValue(element, 'autocomplete', COMBOBOX_AUTOCOMPLETES, 'none');
60
+ }
61
+
62
+ return {
63
+ value,
64
+ both: value === 'both',
65
+ inline: value === 'inline',
66
+ list: value === 'list',
67
+ none: value === 'none',
68
+ };
69
+ }
70
+
71
+ export function getComboboxBooleanAria(
72
+ element: HTMLElement,
73
+ attribute: AnyAriaBooleanAttribute,
74
+ ): boolean {
75
+ const value = getAria(element, attribute);
76
+
77
+ return value === true || value === 'true';
78
+ }
79
+
80
+ export function getComboboxId(): string {
81
+ index += 1;
82
+
83
+ return `oui_combobox_${index}`;
84
+ }
85
+
86
+ export function getComboboxVisibleOptions(state: OuiComboboxState): HTMLElement[] {
87
+ return state.options.all.filter(option => !option.hidden);
88
+ }
89
+
90
+ export function hasTextSelection(element: HTMLElement): element is HTMLInputElement {
91
+ return element instanceof HTMLInputElement && element.selectionStart !== element.selectionEnd;
92
+ }
93
+
94
+ export function setComboboxFilter(state: OuiComboboxState, value: unknown): void {
95
+ if (typeof value !== 'string') {
96
+ return;
97
+ }
98
+
99
+ const type: InputEvent['inputType'] =
100
+ value.length < state.filter.element.value.length ? 'deleteContentBackward' : 'insertText';
101
+
102
+ state.filter.element.value = value;
103
+
104
+ onComboboxFilter(type, state);
105
+ }
106
+
107
+ export function setComboboxLimit(
108
+ type: 'max' | 'min',
109
+ state: OuiComboboxState,
110
+ value?: unknown,
111
+ ): void {
112
+ let actual = value;
113
+
114
+ if (typeof actual === 'string') {
115
+ actual = Number.parseInt(actual, 10);
116
+ }
117
+
118
+ const updateLimit =
119
+ typeof actual === 'number' && !Number.isNaN(actual) && actual >= 0
120
+ ? actual !== state[type]
121
+ : actual == null;
122
+
123
+ if (updateLimit) {
124
+ state[type] = actual as number | undefined;
125
+
126
+ setAttribute(state.host, type, actual);
127
+
128
+ updateComboboxValidity(state);
129
+ }
130
+ }
131
+
132
+ // #endregion
133
+
134
+ // #region Variables
135
+
136
+ let index = 0;
137
+
138
+ // #endregion
@@ -0,0 +1,94 @@
1
+ import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
2
+ import type {OuiFloatable} from '../floatable/floatable.embedded';
3
+ import type {OuiComboboxElement} from './index';
4
+
5
+ export type OuiComboboxAnchor = {
6
+ container?: HTMLElement;
7
+ element: HTMLElement;
8
+ };
9
+
10
+ export type OuiComboboxAutoComplete = Record<OuiComboboxAutoCompleteType, boolean> & {
11
+ value: OuiComboboxAutoCompleteType;
12
+ };
13
+
14
+ export type OuiComboboxAutoCompleteType = 'both' | 'inline' | 'list' | 'none';
15
+
16
+ export type OuiComboboxFilter = {
17
+ element: HTMLInputElement;
18
+ value: string;
19
+ };
20
+
21
+ export type OuiComboboxGroup = {
22
+ element: HTMLElement;
23
+ header: HTMLElement;
24
+ options: HTMLElement[];
25
+ };
26
+
27
+ export type OuiComboboxLabel = {
28
+ element: HTMLLabelElement;
29
+ id: string;
30
+ };
31
+
32
+ export type OuiComboboxLocalizations = {
33
+ empty: string | (() => string);
34
+ input: string | (() => string);
35
+ invalid: string | (() => string);
36
+ max: string | ((max: number) => string);
37
+ min: string | ((min: number) => string);
38
+ remove: string | ((label: string, value: string) => string);
39
+ results: string | ((amount: number) => string);
40
+ selected: string | ((amount: number) => string);
41
+ };
42
+
43
+ export type OuiComboboxOptions = {
44
+ all: HTMLElement[];
45
+ selected: HTMLElement[];
46
+ };
47
+
48
+ export type OuiComboboxPreview = 'none' | 'set' | 'typed';
49
+
50
+ export type OuiComboboxSelection = {
51
+ container: HTMLElement;
52
+ items: OuiComboboxSelectionItem[];
53
+ };
54
+
55
+ export type OuiComboboxSelectionItem = {
56
+ button: HTMLButtonElement;
57
+ element: HTMLElement;
58
+ };
59
+
60
+ export type OuiComboboxState = {
61
+ active?: HTMLElement;
62
+ anchor: OuiComboboxAnchor;
63
+ autocomplete: OuiComboboxAutoComplete;
64
+ content: HTMLElement;
65
+ disabled: boolean;
66
+ filter: OuiComboboxFilter;
67
+ floatable: OuiFloatable;
68
+ groups?: OuiComboboxGroup[];
69
+ host: OuiComboboxElement;
70
+ id: string;
71
+ internals: ElementInternals;
72
+ label: OuiComboboxLabel;
73
+ listeners: RemovableEventListener[];
74
+ localizations: Record<string, Partial<OuiComboboxLocalizations>>;
75
+ max?: number;
76
+ min?: number;
77
+ message: HTMLElement;
78
+ name: string;
79
+ multiple: boolean;
80
+ options: OuiComboboxOptions;
81
+ readonly: boolean;
82
+ required: boolean;
83
+ select: HTMLSelectElement;
84
+ selection?: OuiComboboxSelection;
85
+ type: OuiComboboxType;
86
+ values: OuiComboboxValues;
87
+ };
88
+
89
+ export type OuiComboboxType = 'autocomplete' | 'select';
90
+
91
+ export type OuiComboboxValues = {
92
+ current: string[];
93
+ initial: string[];
94
+ };