@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,129 +0,0 @@
1
- import {clamp} from '@oscarpalmer/atoms/number';
2
- import {LISTBOX_KEYS} from './listbox.constants';
3
- import {getListboxVisibleOptions} from './listbox.misc';
4
- import type {OuiListboxPreview, OuiListboxState} from './listbox.model';
5
-
6
- // #region Functions
7
-
8
- export function processListboxKeydown<State extends OuiListboxState>(
9
- event: KeyboardEvent,
10
- state: State,
11
- ): void {
12
- const ignore = state.disabled || state.readonly;
13
- const isSelect = state.type === 'select';
14
-
15
- let preventDefault = ignore;
16
-
17
- switch (true) {
18
- case event.key === ' ': {
19
- if (!state.disabled) {
20
- state.callbacks.keydown.onActivation?.(state);
21
- }
22
-
23
- break;
24
- }
25
-
26
- case event.key === 'Enter': {
27
- preventDefault = state.callbacks.keydown.preventActivation?.(state) ?? true;
28
-
29
- if (preventDefault) {
30
- state.callbacks.keydown.onEnter?.(state);
31
- } else if (!ignore && state.type === 'select') {
32
- state.callbacks.keydown.onActivation?.(state);
33
- } else if (!ignore) {
34
- state.internals.form?.requestSubmit();
35
- }
36
-
37
- break;
38
- }
39
-
40
- case event.key === 'Escape': {
41
- preventDefault = false;
42
-
43
- state.callbacks.keydown.onEscape?.(state);
44
-
45
- break;
46
- }
47
-
48
- case !isSelect && LISTBOX_KEYS.selection.has(event.key): {
49
- if (!ignore) {
50
- state.callbacks.keydown.onSelection?.(state);
51
- }
52
-
53
- break;
54
- }
55
-
56
- case LISTBOX_KEYS.navigation.has(event.key): {
57
- if (!state.disabled) {
58
- onNavigation(event, state);
59
- }
60
-
61
- break;
62
- }
63
-
64
- default: {
65
- preventDefault = false;
66
-
67
- if (event.key === 'Tab') {
68
- state.callbacks.keydown.onTab?.(state);
69
- }
70
-
71
- break;
72
- }
73
- }
74
-
75
- if (preventDefault) {
76
- event.preventDefault();
77
- event.stopPropagation();
78
- }
79
- }
80
-
81
- function onNavigation<State extends OuiListboxState>(event: KeyboardEvent, state: State): void {
82
- const skip = state.callbacks.keydown.skipNavigation?.(state) ?? false;
83
- const visible = getListboxVisibleOptions(state);
84
-
85
- if (visible.length === 0) {
86
- return;
87
- }
88
-
89
- let next: HTMLElement | undefined;
90
-
91
- if (skip || state.active == null) {
92
- next = state.active ?? visible.at(event.key === 'ArrowDown' ? 0 : -1);
93
- } else {
94
- const current = visible.findIndex(option => option.id === state.active?.id);
95
-
96
- let index: number | undefined;
97
-
98
- switch (event.key) {
99
- case 'ArrowDown':
100
- case 'ArrowUp':
101
- index = clamp(current + (event.key === 'ArrowDown' ? 1 : -1), 0, visible.length - 1, true);
102
- break;
103
-
104
- case 'PageDown':
105
- case 'PageUp':
106
- index = clamp(current + (event.key === 'PageDown' ? 10 : -10), 0, visible.length - 1);
107
- break;
108
-
109
- default:
110
- break;
111
- }
112
-
113
- if (index != null) {
114
- next = visible[index];
115
- }
116
- }
117
-
118
- let preview: OuiListboxPreview;
119
-
120
- if (state.type === 'autocomplete' && (state.autocomplete.both || state.autocomplete.inline)) {
121
- preview = 'set';
122
- } else {
123
- preview = 'none';
124
- }
125
-
126
- state.callbacks.keydown.onNavigation(preview, state, next ?? state.active ?? visible[0]);
127
- }
128
-
129
- // #endregion
@@ -1,115 +0,0 @@
1
- import {dispatch} from '@oscarpalmer/toretto/event';
2
- import {getLocalization, localize} from '../../l10n';
3
- import type {OuiListboxState} from './listbox.model';
4
-
5
- // #region Functions
6
-
7
- export function updateListboxForm<State extends OuiListboxState>(
8
- state: State,
9
- values: string[],
10
- emit?: boolean,
11
- ): void {
12
- let value: string | FormData;
13
-
14
- if (state.multiple) {
15
- const {length} = values;
16
-
17
- value = new FormData();
18
-
19
- for (let index = 0; index < length; index += 1) {
20
- (value as FormData).append(state.name, values[index]);
21
- }
22
- } else {
23
- value = values[0];
24
- }
25
-
26
- state.values.current = values;
27
-
28
- state.internals.setFormValue(value, JSON.stringify(values));
29
-
30
- state.callbacks.data.onForm(state);
31
-
32
- updateListboxValidity(state);
33
-
34
- if (emit ?? true) {
35
- dispatch(state.host, 'oui:change');
36
- }
37
- }
38
-
39
- export function updateListboxValidity(state: OuiListboxState): void {
40
- if (state.autocomplete.none && !state.listbox) {
41
- const valueMissing = state.required && state.filter.element.value.length === 0;
42
-
43
- const localization = getLocalization(
44
- state.localizations.global,
45
- state.host,
46
- 'invalid',
47
- state.localizations.component,
48
- );
49
-
50
- state.internals.setValidity({valueMissing}, localize(localization, {}, []));
51
-
52
- state.internals.checkValidity();
53
-
54
- return;
55
- }
56
-
57
- let data: Record<string, unknown> = {};
58
- let error: 'badInput' | 'rangeOverflow' | 'rangeUnderflow' | undefined;
59
- let key: 'input' | 'max' | 'min' | undefined;
60
- let parameters: unknown[] = [];
61
-
62
- switch (true) {
63
- case state.required && state.options.selected.length === 0: {
64
- error = 'badInput';
65
- key = 'input';
66
-
67
- break;
68
- }
69
-
70
- case state.multiple &&
71
- typeof state.max === 'number' &&
72
- state.options.selected.length > state.max: {
73
- data = {amount: state.max};
74
- error = 'rangeOverflow';
75
- key = 'max';
76
- parameters = [state.max];
77
-
78
- break;
79
- }
80
-
81
- case state.multiple &&
82
- typeof state.min === 'number' &&
83
- state.options.selected.length < state.min: {
84
- data = {amount: state.min};
85
- error = 'rangeUnderflow';
86
- key = 'min';
87
- parameters = [state.min];
88
-
89
- break;
90
- }
91
-
92
- default:
93
- break;
94
- }
95
-
96
- const localization =
97
- key == null
98
- ? undefined
99
- : getLocalization(state.localizations.global, state.host, key, state.localizations.component);
100
-
101
- const message = localization == null ? undefined : localize(localization, data, parameters);
102
-
103
- state.internals.setValidity(
104
- error == null
105
- ? {}
106
- : {
107
- [error]: true,
108
- },
109
- message,
110
- );
111
-
112
- state.internals.checkValidity();
113
- }
114
-
115
- // #endregion
@@ -1,135 +0,0 @@
1
- import {setAria} from '@oscarpalmer/toretto/aria';
2
- import {setAttribute} from '@oscarpalmer/toretto/attribute';
3
- import {filterListbox} from './listbox.data';
4
- import {updateListboxValidity} from './listbox.form';
5
- import type {OuiListboxState} from './listbox.model';
6
-
7
- // #region Functions
8
-
9
- export function generateListboxIds(prefix: string, select: HTMLSelectElement): void {
10
- const elements = [...select.children].flatMap(child =>
11
- child instanceof HTMLOptGroupElement
12
- ? [
13
- child,
14
- ...[...child.children].filter(groupChild => groupChild instanceof HTMLOptionElement),
15
- ]
16
- : child instanceof HTMLOptionElement
17
- ? [child]
18
- : [],
19
- );
20
-
21
- const {length} = elements;
22
-
23
- for (let index = 0; index < length; index += 1) {
24
- const element = elements[index];
25
-
26
- if (element.id === '') {
27
- element.id = `${prefix}${element instanceof HTMLOptGroupElement ? '_group_' : '_option_'}${index}`;
28
- }
29
- }
30
- }
31
-
32
- export function getListboxVisibleOptions(state: OuiListboxState): HTMLElement[] {
33
- return state.options.all.filter(option => !option.hidden);
34
- }
35
-
36
- export function setListboxDisabled<State extends OuiListboxState>(
37
- state: State,
38
- value: boolean,
39
- ): void {
40
- state.filter.element.readOnly = state.readonly || value;
41
-
42
- setProperties('disabled', state, value);
43
- }
44
-
45
- export function setListboxFilter<State extends OuiListboxState>(
46
- state: State,
47
- value: unknown,
48
- ): void {
49
- if (typeof value !== 'string') {
50
- return;
51
- }
52
-
53
- const type: InputEvent['inputType'] =
54
- value.length < state.filter.element.value.length ? 'deleteContentBackward' : 'insertText';
55
-
56
- state.filter.element.value = value;
57
-
58
- filterListbox(type, state);
59
- }
60
-
61
- export function setListboxLimit<State extends OuiListboxState>(
62
- type: 'max' | 'min',
63
- state: State,
64
- value?: unknown,
65
- ): void {
66
- let actual = value;
67
-
68
- if (typeof actual === 'string') {
69
- actual = Number.parseInt(actual, 10);
70
- }
71
-
72
- const updateLimit =
73
- typeof actual === 'number' && !Number.isNaN(actual) && actual >= 0
74
- ? actual !== state[type]
75
- : actual == null;
76
-
77
- if (updateLimit) {
78
- state[type] = actual as number | undefined;
79
-
80
- setAttribute(state.host, type, actual);
81
-
82
- updateListboxValidity(state);
83
- }
84
- }
85
-
86
- export function setListboxMultiple(element: HTMLElement, value: boolean): void {
87
- if (value) {
88
- element.setAttribute('multiple', '');
89
- } else {
90
- element.removeAttribute('multiple');
91
- }
92
- }
93
-
94
- function setProperties<State extends OuiListboxState>(
95
- key: 'disabled' | 'readonly' | 'required',
96
- state: State,
97
- value: boolean,
98
- ): void {
99
- state[key] = value;
100
-
101
- const {length} = state.elements;
102
-
103
- for (let index = 0; index < length; index += 1) {
104
- const element = state.elements[index];
105
-
106
- if (element == null) {
107
- continue;
108
- }
109
-
110
- setAria(
111
- element,
112
- key,
113
- key !== 'readonly' || !(element instanceof HTMLButtonElement) ? value : undefined,
114
- );
115
- }
116
- }
117
-
118
- export function setListboxReadonly<State extends OuiListboxState>(
119
- state: State,
120
- value: boolean,
121
- ): void {
122
- state.filter.element.readOnly = state.disabled || value;
123
-
124
- setProperties('readonly', state, value);
125
- }
126
-
127
- export function setListboxRequired<State extends OuiListboxState>(
128
- state: State,
129
- value: boolean,
130
- ): void {
131
- setProperties('required', state, value);
132
- updateListboxValidity(state);
133
- }
134
-
135
- // #endregion
@@ -1,169 +0,0 @@
1
- import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
2
- import type {OuiLocalizations, OuiLocalizationsValues} from '../../l10n';
3
-
4
- // #region Types
5
-
6
- export type OuiListboxAttributes = {
7
- active: string;
8
- content: string;
9
- empty: string;
10
- filter: string;
11
- group: string;
12
- header: string;
13
- hidden: string;
14
- input: string;
15
- list: string;
16
- message: string;
17
- option: string;
18
- };
19
-
20
- export type OuiListboxAutoComplete = Record<OuiListboxAutoCompleteType, boolean> & {
21
- value?: OuiListboxAutoCompleteType;
22
- };
23
-
24
- export type OuiListboxAutoCompleteType = 'both' | 'inline' | 'list' | 'none';
25
-
26
- export type OuiListboxCallbacks<State extends OuiListboxState = OuiListboxState> = {
27
- data: OuiListboxCallbacksData<State>;
28
- keydown: OuiListboxCallbacksKeydown<State>;
29
- };
30
-
31
- type OuiListboxCallbacksData<State extends OuiListboxState = OuiListboxState> = {
32
- onApply: OuiListboxCallbacksDataOnApply<State>;
33
- onFilter: OuiListboxCallbacksDataOnFilter<State>;
34
- onForm: (state: State) => void;
35
- onPreview: OuiListboxCallbacksDataOnPreview<State>;
36
- onToggle: (state: State) => void;
37
- };
38
-
39
- type OuiListboxCallbacksDataOnApply<State extends OuiListboxState = OuiListboxState> = (
40
- state: State,
41
- option: HTMLElement | undefined,
42
- values: string[],
43
- added: boolean,
44
- selected?: HTMLElement[],
45
- emit?: boolean,
46
- ) => void;
47
-
48
- type OuiListboxCallbacksDataOnFilter<State extends OuiListboxState = OuiListboxState> = (
49
- preview: OuiListboxPreview,
50
- state: State,
51
- update: boolean,
52
- active?: HTMLElement,
53
- emit?: boolean,
54
- ) => void;
55
-
56
- type OuiListboxCallbacksDataOnPreview<State extends OuiListboxState = OuiListboxState> = (
57
- preview: OuiListboxPreview,
58
- state: State,
59
- active?: HTMLElement,
60
- ) => void;
61
-
62
- type OuiListboxCallbacksKeydown<State extends OuiListboxState = OuiListboxState> = {
63
- onActivation?: (state: State) => void;
64
- onEnter?: (state: State) => void;
65
- onEscape?: (state: State) => void;
66
- onNavigation: OuiListboxCallbacksDataOnNavigation<State>;
67
- onSelection?: (state: State) => void;
68
- onTab?: (state: State) => void;
69
- onToggle?: (state: State) => void;
70
- preventActivation?: (state: State) => boolean;
71
- skipNavigation?: (state: State) => boolean;
72
- };
73
-
74
- type OuiListboxCallbacksDataOnNavigation<State extends OuiListboxState = OuiListboxState> = (
75
- preview: OuiListboxPreview,
76
- state: State,
77
- active?: HTMLElement,
78
- ) => void;
79
-
80
- type OuiListboxFilter = {
81
- element: HTMLInputElement;
82
- value: string;
83
- };
84
-
85
- type OuiListboxFooter = {
86
- container: HTMLElement;
87
- message: HTMLElement;
88
- };
89
-
90
- export type OuiListboxGroup = {
91
- element: HTMLElement;
92
- header: HTMLElement;
93
- options: HTMLElement[];
94
- };
95
-
96
- type OuiListboxLabel = {
97
- element: HTMLLabelElement;
98
- id: string;
99
- };
100
-
101
- type OuiListboxLocalization<Localizations extends OuiLocalizationsValues> = {
102
- component: Record<string, Partial<Localizations>>;
103
- global: OuiLocalizations<Localizations>;
104
- };
105
-
106
- export type OuiListboxLocalizations = {
107
- empty: string | (() => string);
108
- input: string | (() => string);
109
- invalid: string | (() => string);
110
- max: string | ((max: number) => string);
111
- min: string | ((min: number) => string);
112
- remove: string | ((label: string, value: string) => string);
113
- results: string | ((amount: number) => string);
114
- selected: string | ((amount: number) => string);
115
- };
116
-
117
- export type OuiListboxOptions = {
118
- all: HTMLElement[];
119
- selected: HTMLElement[];
120
- };
121
-
122
- export type OuiListboxPreview = 'none' | 'set' | 'typed';
123
-
124
- export type OuiListboxState = {
125
- active?: HTMLElement;
126
- attributes: OuiListboxAttributes;
127
- autocomplete: OuiListboxAutoComplete;
128
- callbacks: OuiListboxCallbacks;
129
- content: HTMLDivElement;
130
- disabled: boolean;
131
- elements: Array<HTMLElement | undefined>;
132
- filter: OuiListboxFilter;
133
- footer?: OuiListboxFooter;
134
- groups?: OuiListboxGroup[];
135
- host: HTMLElement;
136
- id: string;
137
- internals: ElementInternals;
138
- label: OuiListboxLabel;
139
- list: HTMLUListElement;
140
- listbox: boolean;
141
- listeners: RemovableEventListener[];
142
- localizations: OuiListboxLocalization<OuiListboxLocalizations>;
143
- max?: number;
144
- min?: number;
145
- message: HTMLElement;
146
- multiple: boolean;
147
- name: string;
148
- options: OuiListboxOptions;
149
- readonly: boolean;
150
- required: boolean;
151
- select: HTMLSelectElement;
152
- type: OuiListboxType;
153
- values: OuiListboxValues;
154
- };
155
-
156
- export type OuiListboxStates<State extends OuiListboxState = OuiListboxState> = {
157
- map: WeakMap<HTMLElement, State>;
158
- set: Set<State>;
159
- };
160
-
161
- export type OuiListboxType = 'autocomplete' | 'select';
162
-
163
- type OuiListboxValues = {
164
- current: string[];
165
- initial: string[];
166
- label: HTMLElement;
167
- };
168
-
169
- // #endregion
@@ -1,82 +0,0 @@
1
- import {getAttribute} from '@oscarpalmer/toretto/attribute';
2
- import {filterListboxOptions} from './listbox.data';
3
- import {updateListboxMessage, updateListboxPreview, updateListboxValueLabel} from './listbox.dom';
4
- import {updateListboxForm} from './listbox.form';
5
- import {
6
- setListboxDisabled,
7
- setListboxLimit,
8
- setListboxMultiple,
9
- setListboxReadonly,
10
- setListboxRequired,
11
- } from './listbox.misc';
12
- import type {OuiListboxState, OuiListboxStates} from './listbox.model';
13
-
14
- // #region Functions
15
-
16
- export function attachListbox<State extends OuiListboxState>(
17
- state: State,
18
- states: OuiListboxStates<State>,
19
- onAttach: (state: State) => void,
20
- ): void {
21
- const {filter, host, label} = state;
22
-
23
- label.element.htmlFor = filter.element.id;
24
- label.element.id = `${state.id}_label`;
25
-
26
- onAttach(state);
27
-
28
- states.map.set(host, state);
29
- states.set.add(state);
30
- }
31
-
32
- export function detachListbox<State extends OuiListboxState>(
33
- state: State,
34
- states: OuiListboxStates<State>,
35
- onDetach: (state: State) => void,
36
- ): void {
37
- const {host, label, select} = state;
38
-
39
- const listeners = state.listeners.splice(0);
40
- const {length} = listeners;
41
-
42
- for (let index = 0; index < length; index += 1) {
43
- listeners[index]();
44
- }
45
-
46
- label.element.htmlFor = select.id;
47
- label.element.id = label.id;
48
-
49
- onDetach(state);
50
-
51
- states.map.delete(host);
52
- states.set.delete(state);
53
- }
54
-
55
- export function initializeListboxState<State extends OuiListboxState>(
56
- state: State,
57
- states: OuiListboxStates<State>,
58
- onAttach: (state: State) => void,
59
- ): State {
60
- attachListbox(state, states, onAttach);
61
-
62
- setListboxDisabled(state, state.disabled);
63
- setListboxLimit('max', state, getAttribute(state.host, 'max'));
64
- setListboxLimit('min', state, getAttribute(state.host, 'min'));
65
- setListboxMultiple(state.host, state.multiple);
66
- setListboxReadonly(state, state.readonly);
67
- setListboxRequired(state, state.required);
68
-
69
- filterListboxOptions(state);
70
-
71
- updateListboxForm(state, state.values.current, false);
72
- updateListboxMessage(state);
73
- updateListboxValueLabel(state);
74
-
75
- if (state.options.selected.length > 0) {
76
- updateListboxPreview('none', state, state.options.selected[0], false);
77
- }
78
-
79
- return state;
80
- }
81
-
82
- // #endregion
@@ -1,27 +0,0 @@
1
- import {getAria} from '@oscarpalmer/toretto/aria';
2
- import {getAttribute} from '@oscarpalmer/toretto/attribute';
3
- import type {AnyAriaBooleanAttribute} from '@oscarpalmer/toretto/models';
4
-
5
- // #region Functions
6
-
7
- export function getAttributeValue<Value>(
8
- element: HTMLElement,
9
- attribute: string,
10
- possible: Set<Value>,
11
- defaultValue: Value,
12
- ): Value {
13
- const value = getAttribute(element, attribute);
14
-
15
- return possible.has(value as Value) ? (value as Value) : defaultValue;
16
- }
17
-
18
- export function getBooleanAriaValue(
19
- element: HTMLElement,
20
- attribute: AnyAriaBooleanAttribute,
21
- ): boolean {
22
- const value = getAria(element, attribute);
23
-
24
- return value === true || value === 'true';
25
- }
26
-
27
- // #endregion