@oscarpalmer/oui 0.36.0 → 0.38.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 (104) hide show
  1. package/dist/css/a11y.css +1 -0
  2. package/dist/css/badge.css +19 -15
  3. package/dist/css/button.css +40 -31
  4. package/dist/css/color-picker.css +377 -0
  5. package/dist/css/color.css +20 -21
  6. package/dist/css/combobox.css +140 -34
  7. package/dist/css/content.css +30 -10
  8. package/dist/css/floatable.css +12 -10
  9. package/dist/css/form.css +400 -129
  10. package/dist/css/listbox.css +43 -17
  11. package/dist/css/message.css +15 -10
  12. package/dist/css/mixins/badge.mixins.css +2 -0
  13. package/dist/css/mixins/button.mixins.css +2 -0
  14. package/dist/css/mixins/message.mixins.css +1 -0
  15. package/dist/css/mixins/misc.mixins.css +2 -0
  16. package/dist/css/mixins/shadow.mixins.css +1 -0
  17. package/dist/css/reset.css +31 -90
  18. package/dist/css/splitter.css +3 -3
  19. package/dist/css/tabs.css +103 -0
  20. package/dist/js/color-picker.d.mts +213 -0
  21. package/dist/js/color-picker.mjs +924 -0
  22. package/dist/js/combobox/dom.combobox.mjs +8 -4
  23. package/dist/js/combobox/event.combobox.mjs +1 -1
  24. package/dist/js/combobox/index.d.mts +1 -1
  25. package/dist/js/combobox/index.mjs +56 -2
  26. package/dist/js/combobox/misc.combobox.d.mts +1 -1
  27. package/dist/js/combobox/misc.combobox.mjs +1 -1
  28. package/dist/js/combobox/state.combobox.d.mts +1 -1
  29. package/dist/js/combobox/state.combobox.mjs +1 -1
  30. package/dist/js/dialog.mjs +2 -2
  31. package/dist/js/floatable/floatable.embedded.mjs +13 -10
  32. package/dist/js/focus-trap/focus-trap.embedded.mjs +9 -13
  33. package/dist/js/{index-EfkUSals.d.mts → index-DJdFlTLm.d.mts} +39 -1
  34. package/dist/js/index.d.mts +4 -2
  35. package/dist/js/index.mjs +5 -3
  36. package/dist/js/internal/draggable.mjs +20 -26
  37. package/dist/js/internal/listbox/listbox.data.mjs +1 -1
  38. package/dist/js/internal/listbox/listbox.dom.mjs +1 -1
  39. package/dist/js/internal/listbox/listbox.event.mjs +1 -1
  40. package/dist/js/internal/listbox/listbox.form.mjs +17 -16
  41. package/dist/js/internal/listbox/listbox.misc.mjs +1 -1
  42. package/dist/js/internal/listbox/listbox.state.mjs +4 -4
  43. package/dist/js/internal/navigable.d.mts +11 -5
  44. package/dist/js/internal/navigable.mjs +46 -19
  45. package/dist/js/listbox/event.listbox.mjs +1 -1
  46. package/dist/js/listbox/index.d.mts +38 -0
  47. package/dist/js/listbox/index.mjs +56 -2
  48. package/dist/js/listbox/misc.listbox.mjs +1 -1
  49. package/dist/js/listbox/state.listbox.mjs +1 -1
  50. package/dist/js/{listbox.data-BWd0PCy7.mjs → listbox.data-C7CRa5Ya.mjs} +5 -4
  51. package/dist/js/menu.mjs +1 -1
  52. package/dist/js/{misc.listbox-BI-XsTOf.mjs → misc.listbox-Cyz2CRDy.mjs} +2 -3
  53. package/dist/js/movable/movable.embedded.mjs +5 -8
  54. package/dist/js/popover.mjs +2 -2
  55. package/dist/js/resizable/resizable.embedded.mjs +21 -31
  56. package/dist/js/sortable/sortable.embedded.mjs +4 -4
  57. package/dist/js/splitter.mjs +20 -17
  58. package/dist/js/{state.combobox-4xq0FPCF.mjs → state.combobox-Qm3FWzYW.mjs} +3 -3
  59. package/dist/js/tabs.d.mts +25 -0
  60. package/dist/js/tabs.mjs +237 -0
  61. package/dist/js/tooltip.mjs +16 -15
  62. package/package.json +7 -5
  63. package/src/css/a11y.scss +2 -2
  64. package/src/css/badge.scss +8 -20
  65. package/src/css/button.scss +8 -47
  66. package/src/css/color-picker.scss +344 -0
  67. package/src/css/color.scss +20 -22
  68. package/src/css/combobox.scss +29 -57
  69. package/src/css/content.scss +34 -6
  70. package/src/css/floatable.scss +22 -19
  71. package/src/css/form.scss +94 -80
  72. package/src/css/listbox.scss +6 -34
  73. package/src/css/message.scss +16 -30
  74. package/src/css/mixins/badge.mixins.scss +53 -0
  75. package/src/css/mixins/button.mixins.scss +112 -0
  76. package/src/css/mixins/input.mixins.scss +114 -0
  77. package/src/css/mixins/message.mixins.scss +41 -0
  78. package/src/css/mixins/misc.mixins.scss +48 -0
  79. package/src/css/mixins/shadow.mixins.scss +57 -0
  80. package/src/css/reset.scss +39 -88
  81. package/src/css/splitter.scss +3 -3
  82. package/src/css/tabs.scss +74 -0
  83. package/src/js/color-picker.ts +1653 -0
  84. package/src/js/combobox/dom.combobox.ts +4 -0
  85. package/src/js/combobox/index.ts +63 -1
  86. package/src/js/dialog.ts +1 -1
  87. package/src/js/floatable/floatable.embedded.ts +18 -14
  88. package/src/js/focus-trap/focus-trap.embedded.ts +11 -19
  89. package/src/js/index.ts +2 -0
  90. package/src/js/internal/draggable.ts +29 -33
  91. package/src/js/internal/listbox/listbox.dom.ts +2 -1
  92. package/src/js/internal/listbox/listbox.form.ts +32 -22
  93. package/src/js/internal/listbox/listbox.state.ts +3 -3
  94. package/src/js/internal/navigable.ts +82 -23
  95. package/src/js/listbox/index.ts +62 -0
  96. package/src/js/listbox/state.listbox.ts +0 -2
  97. package/src/js/movable/movable.embedded.ts +11 -13
  98. package/src/js/popover.ts +1 -1
  99. package/src/js/resizable/resizable.embedded.ts +25 -39
  100. package/src/js/splitter.ts +21 -18
  101. package/src/js/tabs.ts +441 -0
  102. package/src/js/tooltip.ts +20 -17
  103. package/src/css/mixins.scss +0 -194
  104. /package/dist/css/{mixins.css → mixins/input.mixins.css} +0 -0
@@ -63,6 +63,20 @@ export class OuiListboxElement extends HTMLElement {
63
63
  setListboxFilter(this.#state, value);
64
64
  }
65
65
 
66
+ /**
67
+ * Form element associated with the listbox
68
+ */
69
+ get form(): HTMLFormElement | null {
70
+ return this.#internals.form;
71
+ }
72
+
73
+ /**
74
+ * Label elements associated with the listbox
75
+ */
76
+ get labels(): NodeList {
77
+ return this.#internals.labels;
78
+ }
79
+
66
80
  /**
67
81
  * Maximum number of selected options
68
82
  */
@@ -144,6 +158,20 @@ export class OuiListboxElement extends HTMLElement {
144
158
  return this.#state.options.selected.slice();
145
159
  }
146
160
 
161
+ /**
162
+ * Validation message for the listbox
163
+ */
164
+ get validationMessage(): string {
165
+ return this.#internals.validationMessage;
166
+ }
167
+
168
+ /**
169
+ * Validity state for the listbox
170
+ */
171
+ get validity(): ValidityState {
172
+ return this.#internals.validity;
173
+ }
174
+
147
175
  /**
148
176
  * Current value
149
177
  */
@@ -172,6 +200,13 @@ export class OuiListboxElement extends HTMLElement {
172
200
  setListboxValues(this.#state, values);
173
201
  }
174
202
 
203
+ /**
204
+ * Can the listbox be validated?
205
+ */
206
+ get willValidate(): boolean {
207
+ return this.#internals.willValidate;
208
+ }
209
+
175
210
  constructor() {
176
211
  super();
177
212
 
@@ -202,6 +237,15 @@ export class OuiListboxElement extends HTMLElement {
202
237
  }
203
238
  }
204
239
 
240
+ /**
241
+ * Check if the listbox is valid
242
+ *
243
+ * @returns `true` if the listbox is valid, otherwise `false`
244
+ */
245
+ checkValidity(): boolean {
246
+ return this.#internals.checkValidity();
247
+ }
248
+
205
249
  /**
206
250
  * Clear all selected options
207
251
  */
@@ -249,6 +293,24 @@ export class OuiListboxElement extends HTMLElement {
249
293
  }
250
294
  }
251
295
 
296
+ /**
297
+ * Check if the listbox is valid and report any validation errors
298
+ *
299
+ * @returns `true` if the listbox is valid, otherwise `false`
300
+ */
301
+ reportValidity(): boolean {
302
+ return this.#internals.reportValidity();
303
+ }
304
+
305
+ /**
306
+ * Set a custom validation message for the listbox
307
+ *
308
+ * @param message Validation message
309
+ */
310
+ setCustomValidity(message: string): void {
311
+ this.#internals.setValidity({customError: message !== ''}, message, this);
312
+ }
313
+
252
314
  /**
253
315
  * Set listbox localizations for a specific language
254
316
  *
@@ -43,8 +43,6 @@ export function createListboxState(
43
43
 
44
44
  element.id = select.id;
45
45
 
46
- setAttribute(element, 'name', select.name === '' ? select.id : select.name);
47
-
48
46
  const disabled = getBooleanAriaValue(element, 'disabled') || select.disabled;
49
47
  const multiple = element.multiple || select.multiple;
50
48
  const readonly = getBooleanAriaValue(element, 'readonly');
@@ -199,20 +199,18 @@ function onEnd(
199
199
  setOffset(state, container);
200
200
  }
201
201
 
202
- const dispatched = dispatch(state.element, 'movable:end', {
203
- detail: {
204
- from: {...globals.original},
205
- to: getEventPosition(event),
206
- },
207
- });
208
-
209
- setTimeout(() => {
210
- if (dispatched.defaultPrevented) {
211
- onCancel(globals, item);
212
- }
202
+ if (
203
+ dispatch(state.element, 'oui:movable:end', {
204
+ detail: {
205
+ from: {...globals.original},
206
+ to: getEventPosition(event),
207
+ },
208
+ }).defaultPrevented
209
+ ) {
210
+ onCancel(globals, item);
211
+ }
213
212
 
214
- reset();
215
- });
213
+ reset();
216
214
  }
217
215
 
218
216
  function onMove(
package/src/js/popover.ts CHANGED
@@ -125,7 +125,7 @@ function getState(anchor: HTMLElement, content: HTMLElement): OuiPopoverState {
125
125
  content,
126
126
  floatable: createEmbeddedFloatable(anchor, content, options),
127
127
  focusTrap:
128
- getAria(content, 'modal') === 'true'
128
+ getAria(content, 'modal') === true
129
129
  ? createFocusTrap(content, {
130
130
  noescape: true,
131
131
  })
@@ -101,7 +101,7 @@ function cancelResize(item?: OuiResizableItem): void {
101
101
 
102
102
  resetResizable();
103
103
 
104
- dispatch(item.state.element, 'resizable:cancel');
104
+ dispatch(item.state.element, 'oui:resizable:cancel');
105
105
  }
106
106
 
107
107
  /**
@@ -289,19 +289,15 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
289
289
  event.preventDefault();
290
290
  }
291
291
 
292
- const dispatched = dispatch(element!, 'resizable:begin');
293
-
294
- setTimeout(() => {
295
- if (dispatched.defaultPrevented) {
296
- return;
297
- }
292
+ if (dispatch(element!, 'oui:resizable:begin').defaultPrevented) {
293
+ return;
294
+ }
298
295
 
299
- current = stored;
300
- start = position;
296
+ current = stored;
297
+ start = position;
301
298
 
302
- current.state.styles.set();
303
- styleToggler.set();
304
- });
299
+ current.state.styles.set();
300
+ styleToggler.set();
305
301
  }
306
302
 
307
303
  function onPointermove(event: MouseEvent | TouchEvent): void {
@@ -320,41 +316,31 @@ function onPointermove(event: MouseEvent | TouchEvent): void {
320
316
 
321
317
  getAndSetDimensions(current.state.element, current.state.options, {height, width});
322
318
 
323
- const dispatched = dispatch(current.state.element, 'resizable:resize', {
324
- detail: {
325
- height,
326
- width,
327
- },
328
- });
329
-
330
- setTimeout(() => {
331
- if (dispatched.defaultPrevented) {
332
- cancelResize(current);
333
- }
334
- });
319
+ if (
320
+ dispatch(current.state.element, 'oui:resizable:resize', {
321
+ detail: {
322
+ height,
323
+ width,
324
+ },
325
+ }).defaultPrevented
326
+ ) {
327
+ cancelResize(current);
328
+ }
335
329
  }
336
330
 
337
331
  function onPointerup(): void {
338
- if (current == null) {
332
+ if (current == null || dispatch(current.state.element, 'oui:resizable:end').defaultPrevented) {
333
+ cancelResize(current);
334
+
339
335
  return;
340
336
  }
341
337
 
342
- const dispatched = dispatch(current.state.element, 'resizable:end');
343
-
344
- setTimeout(() => {
345
- if (current == null || dispatched.defaultPrevented) {
346
- cancelResize(current);
338
+ const {height, width} = current.state.element.getBoundingClientRect();
347
339
 
348
- return;
349
- }
350
-
351
- const {height, width} = current.state.element.getBoundingClientRect();
340
+ current.state.height = height;
341
+ current.state.width = width;
352
342
 
353
- current.state.height = height;
354
- current.state.width = width;
355
-
356
- resetResizable();
357
- });
343
+ resetResizable();
358
344
  }
359
345
 
360
346
  function removeResizable(element: HTMLElement): void {
@@ -3,6 +3,7 @@ import {round} from '@oscarpalmer/atoms/math';
3
3
  import {clamp} from '@oscarpalmer/atoms/number';
4
4
  import {setAria} from '@oscarpalmer/toretto/aria';
5
5
  import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
6
+ import {createElement} from '@oscarpalmer/toretto/create';
6
7
  import {getEventPosition, on} from '@oscarpalmer/toretto/event';
7
8
  import {findAncestor} from '@oscarpalmer/toretto/find';
8
9
  import {setStyle, toggleStyles} from '@oscarpalmer/toretto/style';
@@ -238,28 +239,30 @@ type OuiSplitterValuesNow = {
238
239
  // #region Functions
239
240
 
240
241
  function createHandle(): HTMLSpanElement {
241
- const handle = document.createElement('span');
242
-
243
- setAria(handle, 'hidden', 'true');
244
- setAttribute(handle, ATTRIBUTE_HANDLE, '');
245
-
246
- return handle;
242
+ return createElement('span', {
243
+ aria: {
244
+ hidden: true,
245
+ },
246
+ attribute: {
247
+ [ATTRIBUTE_HANDLE]: '',
248
+ },
249
+ });
247
250
  }
248
251
 
249
252
  function createSeparator(splitter: OuiSplitter): HTMLDivElement {
250
- const separator = document.createElement('div');
251
-
252
- separator.role = 'separator';
253
- separator.tabIndex = 0;
254
-
255
- setAria(separator, {
256
- controls: splitter.element.id,
257
- label: 'Resize panels',
253
+ return createElement('div', {
254
+ aria: {
255
+ controls: splitter.element.id,
256
+ label: 'Resize panels',
257
+ },
258
+ attribute: {
259
+ [ATTRIBUTE_SEPARATOR]: '',
260
+ },
261
+ property: {
262
+ role: 'separator',
263
+ tabIndex: 0,
264
+ },
258
265
  });
259
-
260
- setAttribute(separator, ATTRIBUTE_SEPARATOR, '');
261
-
262
- return separator;
263
266
  }
264
267
 
265
268
  function getContained(min: number, value: number, max: number): number {