@oscarpalmer/oui 0.38.0 → 0.40.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 (264) hide show
  1. package/README.md +1 -1
  2. package/dist/css/badge.css +11 -8
  3. package/dist/css/button.css +106 -14
  4. package/dist/css/color-picker.css +555 -73
  5. package/dist/css/color.css +86 -86
  6. package/dist/css/combobox.css +98 -4
  7. package/dist/css/content.css +7 -6
  8. package/dist/css/floatable.css +1 -3
  9. package/dist/css/form.css +99 -6
  10. package/dist/css/icon.css +99 -0
  11. package/dist/css/listbox.css +3 -0
  12. package/dist/css/message.css +4 -3
  13. package/dist/css/mixins/button.mixins.css +1 -0
  14. package/dist/css/reset.css +1 -1
  15. package/dist/css/tabs.css +95 -3
  16. package/dist/css/typography.css +90 -0
  17. package/dist/js/color-picker/color-picker.constants.d.mts +2 -0
  18. package/dist/js/color-picker/color-picker.constants.mjs +60 -0
  19. package/dist/js/color-picker/color-picker.dom.d.mts +8 -0
  20. package/dist/js/color-picker/color-picker.dom.mjs +191 -0
  21. package/dist/js/color-picker/color-picker.event.d.mts +9 -0
  22. package/dist/js/color-picker/color-picker.event.mjs +2 -0
  23. package/dist/js/color-picker/color-picker.form.d.mts +5 -0
  24. package/dist/js/color-picker/color-picker.form.mjs +27 -0
  25. package/dist/js/color-picker/color-picker.misc.d.mts +2 -0
  26. package/dist/js/color-picker/color-picker.misc.mjs +2 -0
  27. package/dist/js/color-picker/color-picker.model.d.mts +2 -0
  28. package/dist/js/color-picker/color-picker.model.mjs +24 -0
  29. package/dist/js/color-picker/color-picker.output.d.mts +8 -0
  30. package/dist/js/color-picker/color-picker.output.mjs +235 -0
  31. package/dist/js/color-picker/color-picker.state.d.mts +8 -0
  32. package/dist/js/color-picker/color-picker.state.mjs +2 -0
  33. package/dist/js/{color-picker.d.mts → color-picker/index.d.mts} +10 -43
  34. package/dist/js/color-picker/index.mjs +305 -0
  35. package/dist/js/color-picker.constants-D1mxw_Le.d.mts +179 -0
  36. package/dist/js/color-picker.event-Cksj5TvS.mjs +500 -0
  37. package/dist/js/color-picker.misc-CtsXGrOe.d.mts +27 -0
  38. package/dist/js/combobox/combobox.constants.d.mts +2 -0
  39. package/dist/js/combobox/{constants.combobox.mjs → combobox.constants.mjs} +21 -21
  40. package/dist/js/combobox/combobox.dom.d.mts +26 -0
  41. package/dist/js/combobox/{dom.combobox.mjs → combobox.dom.mjs} +44 -37
  42. package/dist/js/combobox/combobox.event.d.mts +22 -0
  43. package/dist/js/combobox/{event.combobox.mjs → combobox.event.mjs} +1 -1
  44. package/dist/js/combobox/combobox.misc.d.mts +2 -0
  45. package/dist/js/combobox/{misc.combobox.mjs → combobox.misc.mjs} +1 -1
  46. package/dist/js/combobox/combobox.model.d.mts +2 -0
  47. package/dist/js/combobox/combobox.state.d.mts +10 -0
  48. package/dist/js/combobox/combobox.state.mjs +2 -0
  49. package/dist/js/combobox/index.d.mts +163 -2
  50. package/dist/js/combobox/index.mjs +53 -52
  51. package/dist/js/combobox.constants-DZVkMP5g.d.mts +19 -0
  52. package/dist/js/combobox.misc-C1tPZZDi.d.mts +22 -0
  53. package/dist/js/{combobox/models.combobox.d.mts → combobox.model-oDV06XCN.d.mts} +6 -6
  54. package/dist/js/{state.combobox-Qm3FWzYW.mjs → combobox.state-BfJ3Hxg8.mjs} +96 -82
  55. package/dist/js/constants.listbox-C5Ap6Ag_.d.mts +9 -0
  56. package/dist/js/dialog/dialog.model.d.mts +2 -0
  57. package/dist/js/dialog/dialog.model.mjs +11 -0
  58. package/dist/js/dialog/index.d.mts +12 -0
  59. package/dist/js/dialog/index.mjs +123 -0
  60. package/dist/js/dialog.model-DX2mndMh.d.mts +45 -0
  61. package/dist/js/floatable/floatable.embedded.d.mts +2 -2
  62. package/dist/js/floatable/floatable.embedded.mjs +64 -92
  63. package/dist/js/floatable/floatable.model.d.mts +2 -0
  64. package/dist/js/floatable/floatable.model.mjs +23 -0
  65. package/dist/js/floatable/floatable.standalone.d.mts +2 -1
  66. package/dist/js/floatable.embedded-MeTyXjFn.d.mts +17 -0
  67. package/dist/js/floatable.model-DXsQgoU7.d.mts +62 -0
  68. package/dist/js/focus-trap/focus-trap.embedded.d.mts +2 -2
  69. package/dist/js/focus-trap/focus-trap.embedded.mjs +112 -134
  70. package/dist/js/focus-trap/focus-trap.model.d.mts +2 -0
  71. package/dist/js/focus-trap/focus-trap.model.mjs +15 -0
  72. package/dist/js/focus-trap/focus-trap.standalone.d.mts +2 -1
  73. package/dist/js/focus-trap.embedded-DIU05m1z.d.mts +13 -0
  74. package/dist/js/{focus-trap.embedded-DR8NpZfr.d.mts → focus-trap.model-BeX6UYlw.d.mts} +16 -18
  75. package/dist/js/index.d.mts +26 -14
  76. package/dist/js/index.mjs +18 -15
  77. package/dist/js/internal/attributable.d.mts +2 -3
  78. package/dist/js/internal/attributable.mjs +3 -2
  79. package/dist/js/internal/draggable/draggable.model.d.mts +2 -0
  80. package/dist/js/internal/draggable/draggable.model.mjs +37 -0
  81. package/dist/js/internal/draggable/index.d.mts +13 -0
  82. package/dist/js/internal/{draggable.mjs → draggable/index.mjs} +83 -114
  83. package/dist/js/internal/listbox/listbox.constants.d.mts +7 -10
  84. package/dist/js/internal/listbox/listbox.constants.mjs +15 -16
  85. package/dist/js/internal/listbox/listbox.data.d.mts +9 -10
  86. package/dist/js/internal/listbox/listbox.data.mjs +1 -1
  87. package/dist/js/internal/listbox/listbox.dom.d.mts +19 -20
  88. package/dist/js/internal/listbox/listbox.dom.mjs +1 -1
  89. package/dist/js/internal/listbox/listbox.event.d.mts +3 -4
  90. package/dist/js/internal/listbox/listbox.event.mjs +23 -20
  91. package/dist/js/internal/listbox/listbox.form.d.mts +4 -5
  92. package/dist/js/internal/listbox/listbox.form.mjs +15 -12
  93. package/dist/js/internal/listbox/listbox.misc.d.mts +10 -11
  94. package/dist/js/internal/listbox/listbox.misc.mjs +1 -1
  95. package/dist/js/internal/listbox/listbox.model.d.mts +2 -2
  96. package/dist/js/internal/listbox/listbox.state.d.mts +5 -6
  97. package/dist/js/internal/listbox/listbox.state.mjs +19 -20
  98. package/dist/js/internal/misc.d.mts +5 -4
  99. package/dist/js/internal/misc.mjs +7 -1
  100. package/dist/js/internal/navigable/index.d.mts +6 -0
  101. package/dist/js/internal/navigable/index.mjs +125 -0
  102. package/dist/js/internal/navigable/navigable.model.d.mts +2 -0
  103. package/dist/js/internal/navigable/navigable.model.mjs +18 -0
  104. package/dist/js/l10n/index.d.mts +9 -0
  105. package/dist/js/{l10n.mjs → l10n/index.mjs} +50 -23
  106. package/dist/js/l10n/l10n.model.d.mts +2 -0
  107. package/dist/js/l10n/l10n.model.mjs +9 -0
  108. package/dist/js/l10n.model-D6a9frgl.d.mts +26 -0
  109. package/dist/js/listbox/constants.listbox.d.mts +2 -2
  110. package/dist/js/listbox/constants.listbox.mjs +10 -14
  111. package/dist/js/listbox/event.listbox.d.mts +6 -7
  112. package/dist/js/listbox/event.listbox.mjs +47 -1
  113. package/dist/js/listbox/index.d.mts +8 -6
  114. package/dist/js/listbox/index.mjs +47 -49
  115. package/dist/js/listbox/misc.listbox.d.mts +1 -1
  116. package/dist/js/listbox/misc.listbox.mjs +1 -1
  117. package/dist/js/listbox/state.listbox.d.mts +8 -10
  118. package/dist/js/listbox/state.listbox.mjs +2 -2
  119. package/dist/js/{listbox.data-C7CRa5Ya.mjs → listbox.data-BQyZGKgr.mjs} +83 -66
  120. package/dist/js/{listbox.model-CRReGOmu.d.mts → listbox.model-CuBOj4qe.d.mts} +15 -11
  121. package/dist/js/menu/index.mjs +167 -0
  122. package/dist/js/menu/menu.model.d.mts +33 -0
  123. package/dist/js/menu/menu.model.mjs +15 -0
  124. package/dist/js/{misc.listbox-Cyz2CRDy.mjs → misc.listbox-CjfBUbHD.mjs} +27 -69
  125. package/dist/js/{misc.listbox-gnoJhrTr.d.mts → misc.listbox-CtoGvXQo.d.mts} +2 -2
  126. package/dist/js/movable/movable.embedded.d.mts +2 -2
  127. package/dist/js/movable/movable.embedded.mjs +60 -72
  128. package/dist/js/movable/movable.model.d.mts +2 -0
  129. package/dist/js/movable/movable.model.mjs +12 -0
  130. package/dist/js/movable/movable.standalone.d.mts +2 -1
  131. package/dist/js/movable.embedded-DoyXLegc.d.mts +11 -0
  132. package/dist/js/movable.model-BHaK_mKw.d.mts +186 -0
  133. package/dist/js/navigable.model-BPOM8DZk.d.mts +44 -0
  134. package/dist/js/popover/index.d.mts +12 -0
  135. package/dist/js/{popover.mjs → popover/index.mjs} +40 -50
  136. package/dist/js/popover/popover.model.d.mts +2 -0
  137. package/dist/js/popover/popover.model.mjs +12 -0
  138. package/dist/js/popover.model-ubKNG612.d.mts +38 -0
  139. package/dist/js/resizable/resizable.embedded.d.mts +2 -2
  140. package/dist/js/resizable/resizable.embedded.mjs +44 -59
  141. package/dist/js/resizable/resizable.model.d.mts +2 -0
  142. package/dist/js/resizable/resizable.model.mjs +21 -0
  143. package/dist/js/resizable/resizable.standalone.d.mts +2 -1
  144. package/dist/js/resizable.embedded-Bf1qBUdt.d.mts +11 -0
  145. package/dist/js/resizable.model-BwzJcTVJ.d.mts +46 -0
  146. package/dist/js/sortable/sortable.embedded.d.mts +2 -2
  147. package/dist/js/sortable/sortable.embedded.mjs +69 -82
  148. package/dist/js/sortable/sortable.model.d.mts +2 -0
  149. package/dist/js/sortable/sortable.model.mjs +24 -0
  150. package/dist/js/sortable/sortable.standalone.d.mts +2 -1
  151. package/dist/js/sortable.embedded-DzBKAwSG.d.mts +11 -0
  152. package/dist/js/{splitter.d.mts → splitter/index.d.mts} +8 -7
  153. package/dist/js/splitter/index.mjs +284 -0
  154. package/dist/js/splitter/splitter.model.d.mts +2 -0
  155. package/dist/js/splitter/splitter.model.mjs +37 -0
  156. package/dist/js/splitter.model-DOLNjLVS.d.mts +57 -0
  157. package/dist/js/{tabs.d.mts → tabs/index.d.mts} +7 -8
  158. package/dist/js/{tabs.mjs → tabs/index.mjs} +58 -58
  159. package/dist/js/tabs/tabs.model.d.mts +2 -0
  160. package/dist/js/tabs/tabs.model.mjs +18 -0
  161. package/dist/js/tabs.model-DRBX_JtI.d.mts +40 -0
  162. package/dist/js/toolbar/index.mjs +27 -0
  163. package/dist/js/toolbar/toolbar.model.d.mts +11 -0
  164. package/dist/js/toolbar/toolbar.model.mjs +7 -0
  165. package/dist/js/tooltip/index.d.mts +19 -0
  166. package/dist/js/{tooltip.mjs → tooltip/index.mjs} +60 -85
  167. package/dist/js/tooltip/tooltip.model.d.mts +2 -0
  168. package/dist/js/tooltip/tooltip.model.mjs +15 -0
  169. package/dist/js/tooltip.model-DRkY_BsL.d.mts +37 -0
  170. package/package.json +43 -37
  171. package/dist/js/color-picker.mjs +0 -924
  172. package/dist/js/combobox/constants.combobox.d.mts +0 -2
  173. package/dist/js/combobox/dom.combobox.d.mts +0 -27
  174. package/dist/js/combobox/event.combobox.d.mts +0 -23
  175. package/dist/js/combobox/misc.combobox.d.mts +0 -2
  176. package/dist/js/combobox/state.combobox.d.mts +0 -12
  177. package/dist/js/combobox/state.combobox.mjs +0 -2
  178. package/dist/js/constants.combobox-DmRAMC64.d.mts +0 -26
  179. package/dist/js/constants.listbox-DRsXUxd3.d.mts +0 -14
  180. package/dist/js/dialog.d.mts +0 -47
  181. package/dist/js/dialog.mjs +0 -131
  182. package/dist/js/draggable-a6w0J1OD.d.mts +0 -154
  183. package/dist/js/floatable.embedded-Bct4U5Dm.d.mts +0 -69
  184. package/dist/js/index-DJdFlTLm.d.mts +0 -177
  185. package/dist/js/internal/draggable.d.mts +0 -2
  186. package/dist/js/internal/navigable.d.mts +0 -37
  187. package/dist/js/internal/navigable.mjs +0 -135
  188. package/dist/js/l10n-Bn-7RcwR.d.mts +0 -20
  189. package/dist/js/l10n.d.mts +0 -2
  190. package/dist/js/menu.mjs +0 -172
  191. package/dist/js/popover.d.mts +0 -38
  192. package/dist/js/resizable.embedded-3qoR0Bjm.d.mts +0 -34
  193. package/dist/js/splitter.mjs +0 -322
  194. package/dist/js/toolbar.mjs +0 -31
  195. package/dist/js/tooltip.d.mts +0 -45
  196. package/src/css/a11y.scss +0 -13
  197. package/src/css/badge.scss +0 -62
  198. package/src/css/button.scss +0 -50
  199. package/src/css/color-picker.scss +0 -344
  200. package/src/css/color.scss +0 -113
  201. package/src/css/combobox.scss +0 -255
  202. package/src/css/content.scss +0 -181
  203. package/src/css/flex.scss +0 -107
  204. package/src/css/floatable.scss +0 -155
  205. package/src/css/form.scss +0 -575
  206. package/src/css/listbox.scss +0 -121
  207. package/src/css/message.scss +0 -74
  208. package/src/css/mixins/badge.mixins.scss +0 -53
  209. package/src/css/mixins/button.mixins.scss +0 -112
  210. package/src/css/mixins/input.mixins.scss +0 -114
  211. package/src/css/mixins/message.mixins.scss +0 -41
  212. package/src/css/mixins/misc.mixins.scss +0 -48
  213. package/src/css/mixins/shadow.mixins.scss +0 -57
  214. package/src/css/reset.scss +0 -392
  215. package/src/css/splitter.scss +0 -89
  216. package/src/css/table.scss +0 -107
  217. package/src/css/tabs.scss +0 -74
  218. package/src/js/color-picker.ts +0 -1653
  219. package/src/js/combobox/constants.combobox.ts +0 -83
  220. package/src/js/combobox/dom.combobox.ts +0 -411
  221. package/src/js/combobox/event.combobox.ts +0 -365
  222. package/src/js/combobox/index.ts +0 -382
  223. package/src/js/combobox/misc.combobox.ts +0 -104
  224. package/src/js/combobox/models.combobox.ts +0 -54
  225. package/src/js/combobox/state.combobox.ts +0 -246
  226. package/src/js/dialog.ts +0 -255
  227. package/src/js/floatable/floatable.embedded.ts +0 -336
  228. package/src/js/floatable/floatable.standalone.ts +0 -6
  229. package/src/js/focus-trap/focus-trap.embedded.ts +0 -411
  230. package/src/js/focus-trap/focus-trap.standalone.ts +0 -1
  231. package/src/js/index.ts +0 -16
  232. package/src/js/internal/attributable.ts +0 -73
  233. package/src/js/internal/draggable.ts +0 -657
  234. package/src/js/internal/listbox/listbox.constants.ts +0 -25
  235. package/src/js/internal/listbox/listbox.data.ts +0 -287
  236. package/src/js/internal/listbox/listbox.dom.ts +0 -446
  237. package/src/js/internal/listbox/listbox.event.ts +0 -129
  238. package/src/js/internal/listbox/listbox.form.ts +0 -125
  239. package/src/js/internal/listbox/listbox.misc.ts +0 -135
  240. package/src/js/internal/listbox/listbox.model.ts +0 -169
  241. package/src/js/internal/listbox/listbox.state.ts +0 -82
  242. package/src/js/internal/misc.ts +0 -27
  243. package/src/js/internal/navigable.ts +0 -317
  244. package/src/js/l10n.ts +0 -192
  245. package/src/js/listbox/constants.listbox.ts +0 -61
  246. package/src/js/listbox/event.listbox.ts +0 -106
  247. package/src/js/listbox/index.ts +0 -364
  248. package/src/js/listbox/misc.listbox.ts +0 -70
  249. package/src/js/listbox/state.listbox.ts +0 -194
  250. package/src/js/menu.ts +0 -348
  251. package/src/js/movable/movable.embedded.ts +0 -318
  252. package/src/js/movable/movable.standalone.ts +0 -2
  253. package/src/js/popover.ts +0 -229
  254. package/src/js/resizable/resizable.embedded.ts +0 -413
  255. package/src/js/resizable/resizable.standalone.ts +0 -5
  256. package/src/js/sortable/sortable.embedded.ts +0 -527
  257. package/src/js/sortable/sortable.standalone.ts +0 -2
  258. package/src/js/splitter.ts +0 -583
  259. package/src/js/tabs.ts +0 -441
  260. package/src/js/toolbar.ts +0 -63
  261. package/src/js/tooltip.ts +0 -367
  262. /package/dist/js/combobox/{models.combobox.mjs → combobox.model.mjs} +0 -0
  263. /package/dist/js/{menu.d.mts → menu/index.d.mts} +0 -0
  264. /package/dist/js/{toolbar.d.mts → toolbar/index.d.mts} +0 -0
@@ -1,287 +0,0 @@
1
- import {getString} from '@oscarpalmer/atoms/string';
2
- import {setAria} from '@oscarpalmer/toretto/aria';
3
- import {setAttribute} from '@oscarpalmer/toretto/attribute';
4
- import {getData} from '@oscarpalmer/toretto/data';
5
- import {dispatch} from '@oscarpalmer/toretto/event';
6
- import {updateListboxMessage, updateListboxPreview, updateListboxValueLabel} from './listbox.dom';
7
- import {updateListboxForm} from './listbox.form';
8
- import {setListboxFilter} from './listbox.misc';
9
- import type {OuiListboxPreview, OuiListboxState} from './listbox.model';
10
-
11
- // #region Types
12
-
13
- type ApplySelectionParameters<State extends OuiListboxState = OuiListboxState> = {
14
- added: boolean;
15
- emit?: boolean;
16
- option?: HTMLElement;
17
- scroll?: boolean;
18
- selected?: HTMLElement[];
19
- state: State;
20
- values?: string[];
21
- };
22
-
23
- // #endregion
24
-
25
- // #region Functions
26
-
27
- export function applyListboxSelection<State extends OuiListboxState>(
28
- parameters: ApplySelectionParameters<State>,
29
- ): void {
30
- const {added, emit, option, scroll, selected, state} = parameters;
31
- const {length} = state.options.all;
32
-
33
- for (let index = 0; index < length; index += 1) {
34
- const option = state.options.all[index];
35
-
36
- setAria(
37
- option,
38
- 'selected',
39
- (state.type === 'select' || !state.autocomplete.none) &&
40
- (selected ?? state.options.selected).includes(option),
41
- );
42
- }
43
-
44
- const values =
45
- parameters.values ??
46
- (state.autocomplete.none && !state.listbox
47
- ? [state.filter.element.value]
48
- : (selected ?? state.options.selected).map(option => getData(option, 'value', false) ?? ''));
49
-
50
- if (values.length === 0) {
51
- values.push('');
52
- }
53
-
54
- if (selected != null) {
55
- state.options.selected = selected;
56
- }
57
-
58
- const update =
59
- values.length === state.values.current.length
60
- ? values.some(value => !state.values.current.includes(value))
61
- : true;
62
-
63
- if (!update) {
64
- return;
65
- }
66
-
67
- updateListboxForm(state, values, emit);
68
- updateListboxMessage(state);
69
- updateListboxPreview('set', state, option, scroll);
70
- updateListboxValueLabel(state);
71
-
72
- state.callbacks.data.onApply(state, option, values, added, selected, emit);
73
- }
74
-
75
- export function filterListbox(type: InputEvent['inputType'], state: OuiListboxState): void {
76
- if (state.disabled || state.readonly) {
77
- return;
78
- }
79
-
80
- const update = state.filter.element.value !== state.filter.value;
81
-
82
- const option = filterListboxOptions(state);
83
-
84
- let preview: OuiListboxPreview | undefined;
85
-
86
- if (type.includes('delete')) {
87
- preview = 'none';
88
- } else if (type.includes('insert')) {
89
- preview = 'typed';
90
- }
91
-
92
- if (preview != null) {
93
- state.callbacks.data.onFilter(preview, state, update, option);
94
- }
95
-
96
- if (update) {
97
- state.filter.value = state.filter.element.value;
98
-
99
- dispatch(state.host, 'input');
100
- }
101
- }
102
-
103
- export function filterListboxOption(
104
- state: OuiListboxState,
105
- value: unknown,
106
- textContent?: boolean,
107
- ): HTMLElement | undefined {
108
- const filterTextContent = textContent ?? false;
109
-
110
- const filter = getString(value).toLocaleLowerCase();
111
-
112
- filterListboxOptions(state);
113
-
114
- const {length} = state.options.all;
115
-
116
- let match: HTMLElement | undefined;
117
-
118
- for (let index = 0; index < length; index += 1) {
119
- const option = state.options.all[index];
120
-
121
- const value = (
122
- filterTextContent ? option.textContent : (getData(option, 'value', false) ?? '')
123
- ).toLocaleLowerCase();
124
-
125
- if (value === filter) {
126
- match = option;
127
-
128
- break;
129
- }
130
- }
131
-
132
- return match;
133
- }
134
-
135
- export function filterListboxOptions(state: OuiListboxState): HTMLElement | undefined {
136
- function filter(options: HTMLElement[]): boolean {
137
- const {length} = options;
138
-
139
- let count = 0;
140
-
141
- for (let index = 0; index < length; index += 1) {
142
- const option = options[index];
143
-
144
- option.hidden =
145
- (state.type === 'select' || !state.autocomplete.none) &&
146
- !option.textContent.toLocaleLowerCase().includes(value);
147
-
148
- if (!option.hidden) {
149
- count += 1;
150
-
151
- visible.push(option);
152
- }
153
- }
154
-
155
- return count === 0;
156
- }
157
-
158
- const value = state.filter.element.value.toLocaleLowerCase();
159
-
160
- const visible: HTMLElement[] = [];
161
-
162
- if (state.groups == null) {
163
- filter(state.options.all);
164
- } else {
165
- const groupsLength = state.groups.length;
166
-
167
- for (let groupIndex = 0; groupIndex < groupsLength; groupIndex += 1) {
168
- const {element, options} = state.groups[groupIndex];
169
-
170
- element.hidden = filter(options);
171
- }
172
- }
173
-
174
- setAttribute(state.list, state.attributes.empty, visible.length === 0 ? '' : undefined);
175
-
176
- updateListboxMessage(state);
177
-
178
- return state.active != null && visible.includes(state.active) ? state.active : visible[0];
179
- }
180
-
181
- export function setListboxValue<State extends OuiListboxState>(
182
- state: State,
183
- value: unknown,
184
- emit?: boolean,
185
- ): void {
186
- if (state.autocomplete.none && !state.listbox) {
187
- setListboxFilter(state, getString(value));
188
-
189
- return;
190
- }
191
-
192
- const option = filterListboxOption(state, value);
193
-
194
- if (option != null) {
195
- setListboxValues(state, [value], emit);
196
- }
197
- }
198
-
199
- export function setListboxValues<State extends OuiListboxState>(
200
- state: State,
201
- value: unknown[],
202
- emit?: boolean,
203
- ): void {
204
- if (!Array.isArray(value)) {
205
- return;
206
- }
207
-
208
- const values = (state.multiple ? value : value.slice(0, 1)).map(value =>
209
- getString(value).toLocaleLowerCase(),
210
- );
211
-
212
- if (values.length === 0) {
213
- values.push('');
214
- }
215
-
216
- if (state.autocomplete.none && !state.listbox) {
217
- setListboxValue(state, values[0], emit);
218
-
219
- return;
220
- }
221
-
222
- const {length} = state.options.all;
223
-
224
- const selected: HTMLElement[] = [];
225
-
226
- for (let index = 0; index < length; index += 1) {
227
- const option = state.options.all[index];
228
-
229
- if (values.includes(getData(option, 'value', false)?.toLocaleLowerCase() ?? '')) {
230
- selected.push(option);
231
- }
232
- }
233
-
234
- applyListboxSelection({
235
- emit,
236
- selected,
237
- state,
238
- added: true,
239
- option: selected[0] ?? state.options.all[0],
240
- values: state.autocomplete.none && !state.listbox ? values : undefined,
241
- });
242
- }
243
-
244
- export function toggleListboxOption<State extends OuiListboxState>(
245
- state: State,
246
- option?: HTMLElement,
247
- ): void {
248
- if (option == null || (!state.multiple && state.options.selected.includes(option))) {
249
- state.callbacks.data.onToggle(state);
250
-
251
- return;
252
- }
253
-
254
- const selected = state.options.selected.slice();
255
-
256
- let added = true;
257
-
258
- if (state.multiple) {
259
- const index = selected.indexOf(option);
260
-
261
- if (index === -1) {
262
- selected.push(option);
263
- } else {
264
- added = false;
265
-
266
- selected.splice(index, 1);
267
- }
268
- } else {
269
- selected.splice(0, selected.length, option);
270
- }
271
-
272
- applyListboxSelection({
273
- added,
274
- option,
275
- selected,
276
- state,
277
- scroll: false,
278
- values:
279
- state.autocomplete.none && !state.listbox && option != null
280
- ? [option.textContent]
281
- : undefined,
282
- });
283
-
284
- state.callbacks.data.onToggle(state);
285
- }
286
-
287
- // #endregion
@@ -1,446 +0,0 @@
1
- import {createElement, setAria, setAttribute} from '@oscarpalmer/toretto';
2
- import {getLocalization, localize} from '../../l10n';
3
- import {listboxScrollOptions} from './listbox.constants';
4
- import {getListboxVisibleOptions} from './listbox.misc';
5
- import type {
6
- OuiListboxAttributes,
7
- OuiListboxAutoComplete,
8
- OuiListboxGroup,
9
- OuiListboxLocalizations,
10
- OuiListboxOptions,
11
- OuiListboxPreview,
12
- OuiListboxState,
13
- OuiListboxType,
14
- } from './listbox.model';
15
-
16
- // #region Types
17
-
18
- export type CreateListboxContent = {
19
- element: HTMLDivElement;
20
- filter?: CreateListboxFilter;
21
- list: CreateListboxList;
22
- message: HTMLDivElement;
23
- value: HTMLSpanElement;
24
- };
25
-
26
- export type CreateListboxContentParameters = {
27
- attributes: OuiListboxAttributes;
28
- autocomplete: OuiListboxAutoComplete;
29
- element: HTMLElement;
30
- id: string;
31
- label: HTMLLabelElement;
32
- listbox: boolean;
33
- multiple: boolean;
34
- select: HTMLSelectElement;
35
- type: OuiListboxType;
36
- };
37
-
38
- export type CreateListboxFilter = {
39
- container: HTMLElement;
40
- element: HTMLInputElement;
41
- };
42
-
43
- type CreateListboxGroupParameters = {
44
- group: HTMLOptGroupElement;
45
- groupOptions: HTMLOptionElement[];
46
- original: CreateListboxContentParameters;
47
- selected: HTMLElement[];
48
- type: OuiListboxType;
49
- };
50
-
51
- export type CreateListboxList = {
52
- element: HTMLUListElement;
53
- groups?: OuiListboxGroup[];
54
- options: OuiListboxOptions;
55
- };
56
-
57
- type CreateListboxOptionParameters = {
58
- group?: string;
59
- index: number;
60
- option: HTMLOptionElement;
61
- original: CreateListboxContentParameters;
62
- type: OuiListboxType;
63
- };
64
-
65
- type CreateListboxOptionsParameters = {
66
- group?: string;
67
- list: HTMLElement;
68
- options: HTMLOptionElement[];
69
- original: CreateListboxContentParameters;
70
- selected: HTMLElement[];
71
- type: OuiListboxType;
72
- };
73
-
74
- // #endregion
75
-
76
- // #region Functions
77
-
78
- export function createListboxContent(
79
- parameters: CreateListboxContentParameters,
80
- ): CreateListboxContent {
81
- const element = createElement('div', {
82
- attribute: {
83
- [parameters.attributes.content]: '',
84
- },
85
- });
86
-
87
- const filter = createListboxFilter(parameters);
88
- const list = createListboxList(parameters);
89
- const message = createListboxMessage(parameters.attributes.message);
90
- const value = createListboxValueLabel(parameters.id);
91
-
92
- if (filter != null) {
93
- element.append(filter.container);
94
- }
95
-
96
- element.append(list.element, message, value);
97
-
98
- return {
99
- element,
100
- filter,
101
- list,
102
- message,
103
- value,
104
- };
105
- }
106
-
107
- export function createListboxFilter(
108
- parameters: CreateListboxContentParameters,
109
- ): CreateListboxFilter | undefined {
110
- if (parameters.type === 'autocomplete') {
111
- return;
112
- }
113
-
114
- const container = createElement('div', {
115
- attribute: {
116
- [parameters.attributes.filter]: '',
117
- },
118
- });
119
-
120
- const element = createListboxInput(parameters, '');
121
-
122
- setAttribute(element, parameters.attributes.input, '');
123
-
124
- container.append(element);
125
-
126
- return {container, element};
127
- }
128
-
129
- export function createListboxGroup(parameters: CreateListboxGroupParameters): OuiListboxGroup {
130
- const {group, groupOptions, selected, type} = parameters;
131
-
132
- const element = createElement('li', {
133
- aria: {
134
- label: group.label,
135
- },
136
- property: {
137
- role: 'group',
138
- },
139
- });
140
-
141
- const list = createElement('ul', {
142
- property: {
143
- role: 'none',
144
- },
145
- });
146
-
147
- const header = createListboxHeader(parameters, group);
148
-
149
- element.append(header, list);
150
-
151
- return {
152
- element,
153
- header,
154
- options: createListboxOptions({
155
- list,
156
- selected,
157
- type,
158
- group: header.id,
159
- options: groupOptions,
160
- original: parameters.original,
161
- }),
162
- };
163
- }
164
-
165
- export function createListboxHeader(
166
- parameters: CreateListboxGroupParameters,
167
- group: HTMLOptGroupElement,
168
- ): HTMLElement {
169
- return createElement('div', {
170
- aria: {
171
- hidden: true,
172
- },
173
- attribute: {
174
- [parameters.original.attributes.header]: '',
175
- },
176
- property: {
177
- id: group.id,
178
- textContent: group.label,
179
- },
180
- });
181
- }
182
-
183
- export function createListboxInput(
184
- parameters: CreateListboxContentParameters,
185
- value: string,
186
- ): HTMLInputElement {
187
- const {autocomplete, id, label, listbox, type} = parameters;
188
-
189
- const isAutocomplete = type === 'autocomplete';
190
-
191
- const input = createElement('input', {
192
- aria: {
193
- autocomplete: autocomplete.value,
194
- controls: `${id}_list`,
195
- haspopup: isAutocomplete ? 'listbox' : undefined,
196
- labelledby: label.id,
197
- },
198
- attribute: {
199
- autocorrect: 'off',
200
- autocomplete: 'off',
201
- form: '',
202
- inputmode: 'text',
203
- spellcheck: 'false',
204
- },
205
- property: {
206
- id,
207
- value,
208
- role: isAutocomplete || listbox ? 'combobox' : 'searchbox',
209
- type: 'text',
210
- },
211
- });
212
-
213
- if (isAutocomplete || listbox) {
214
- setAria(input, 'expanded', listbox);
215
- }
216
-
217
- return input;
218
- }
219
-
220
- export function createListboxList(parameters: CreateListboxContentParameters): CreateListboxList {
221
- const {attributes, id, label, multiple, select, type} = parameters;
222
-
223
- const element = createElement('ul', {
224
- aria: {
225
- labelledby: label.id,
226
- multiselectable: multiple,
227
- },
228
- attribute: {
229
- [attributes.list]: '',
230
- tabindex: -1,
231
- },
232
- property: {
233
- id: `${id}_list`,
234
- role: 'listbox',
235
- },
236
- });
237
-
238
- const children = [...select.children];
239
- const childrenLength = children.length;
240
-
241
- const options: HTMLElement[] = [];
242
- const selected: HTMLElement[] = [];
243
-
244
- let groups: OuiListboxGroup[] | undefined;
245
-
246
- for (let childIndex = 0; childIndex < childrenLength; childIndex += 1) {
247
- const child = children[childIndex];
248
-
249
- if (child instanceof HTMLOptionElement) {
250
- const option = createListboxOption({
251
- type,
252
- option: child,
253
- original: parameters,
254
- index: childIndex,
255
- });
256
-
257
- element.append(option);
258
- options.push(option);
259
-
260
- if (child.selected) {
261
- selected.push(option);
262
- }
263
-
264
- continue;
265
- }
266
-
267
- if (!(child instanceof HTMLOptGroupElement)) {
268
- continue;
269
- }
270
-
271
- const group = createListboxGroup({
272
- selected,
273
- type,
274
- group: child,
275
- groupOptions: [...child.children] as HTMLOptionElement[],
276
- original: parameters,
277
- });
278
-
279
- groups ??= [];
280
-
281
- element.append(group.element);
282
- groups.push(group);
283
- options.push(...group.options);
284
- }
285
-
286
- return {
287
- element,
288
- groups,
289
- options: {
290
- selected,
291
- all: options,
292
- },
293
- };
294
- }
295
-
296
- export function createListboxMessage(attribute: string): HTMLDivElement {
297
- return createElement('div', {
298
- aria: {
299
- live: 'polite',
300
- },
301
- attribute: {
302
- [attribute]: '',
303
- },
304
- property: {
305
- hidden: true,
306
- role: 'status',
307
- },
308
- });
309
- }
310
-
311
- export function createListboxOption(parameters: CreateListboxOptionParameters): HTMLElement {
312
- const {group, option, original} = parameters;
313
-
314
- return createElement('li', {
315
- aria: {
316
- selected: (parameters.type === 'select' || !original.autocomplete.none) && option.selected,
317
- },
318
- attribute: {
319
- [original.attributes.option]: '',
320
- },
321
- data: {
322
- group,
323
- value: option.value,
324
- },
325
- property: {
326
- id: option.id,
327
- role: 'option',
328
- textContent: option.textContent,
329
- },
330
- });
331
- }
332
-
333
- export function createListboxOptions(parameters: CreateListboxOptionsParameters): HTMLElement[] {
334
- const {group, list, options, original, selected, type} = parameters;
335
-
336
- const items: HTMLElement[] = [];
337
-
338
- for (let index = 0; index < options.length; index += 1) {
339
- const option = options[index];
340
-
341
- const item = createListboxOption({group, index, option, original, type});
342
-
343
- items.push(item);
344
-
345
- if (option.selected) {
346
- selected.push(item);
347
- }
348
-
349
- list.append(item);
350
- }
351
-
352
- return items;
353
- }
354
-
355
- export function createListboxValueLabel(id: string): HTMLSpanElement {
356
- return createElement('span', {
357
- property: {
358
- hidden: true,
359
- id: `${id}_value`,
360
- },
361
- });
362
- }
363
-
364
- export function updateListboxMessage(state: OuiListboxState): void {
365
- const {attributes, host, localizations, message} = state;
366
-
367
- const visible = getListboxVisibleOptions(state).length;
368
-
369
- setAttribute(message, attributes.hidden, visible > 0 ? '' : undefined);
370
-
371
- let data: Record<string, unknown> = {};
372
- let parameters: unknown[] = [];
373
-
374
- let key: keyof OuiListboxLocalizations | undefined;
375
-
376
- if (visible === 0) {
377
- key = 'empty';
378
- } else {
379
- data = {amount: visible};
380
- key = 'results';
381
- parameters = [visible];
382
- }
383
-
384
- const localization = getLocalization(localizations.global, host, key, localizations.component);
385
-
386
- message.textContent = localize(localization, data, parameters);
387
-
388
- message.hidden = false;
389
- }
390
-
391
- export function updateListboxPreview<State extends OuiListboxState>(
392
- preview: OuiListboxPreview,
393
- state: State,
394
- active?: HTMLElement,
395
- scroll?: boolean,
396
- ): void {
397
- const {length} = state.options.all;
398
-
399
- for (let index = 0; index < length; index += 1) {
400
- const option = state.options.all[index];
401
-
402
- setAttribute(option, state.attributes.active, option === active ? '' : undefined);
403
- }
404
-
405
- state.active = active;
406
-
407
- setAria(
408
- state.filter.element,
409
- 'activedescendant',
410
- state.content.checkVisibility() ? active?.id : undefined,
411
- );
412
-
413
- if (scroll ?? true) {
414
- active?.scrollIntoView(listboxScrollOptions);
415
- }
416
-
417
- if (preview !== 'none') {
418
- state.callbacks.data.onPreview(preview, state, active);
419
- }
420
- }
421
-
422
- export function updateListboxValueLabel<State extends OuiListboxState>(state: State): void {
423
- let label: string;
424
-
425
- if (state.multiple) {
426
- const localization = getLocalization(
427
- state.localizations.global,
428
- state.host,
429
- 'selected',
430
- state.localizations.component,
431
- );
432
-
433
- const {length} = state.options.selected;
434
-
435
- label = localize(localization, {amount: length}, [length]);
436
- } else {
437
- label =
438
- state.autocomplete.none && !state.listbox
439
- ? state.filter.element.value
440
- : (state.options.selected[0]?.textContent ?? '');
441
- }
442
-
443
- state.values.label.textContent = label;
444
- }
445
-
446
- // #endregion