@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
@@ -1,10 +1,10 @@
1
1
  import { getLocalization, localize } from "../l10n.mjs";
2
- import { _ as createListboxValueLabel, f as createListboxInput, l as createListboxFilter, m as createListboxMessage, p as createListboxList } from "../listbox.data-BWd0PCy7.mjs";
2
+ import { _ as createListboxValueLabel, f as createListboxInput, l as createListboxFilter, m as createListboxMessage, p as createListboxList } from "../listbox.data-C7CRa5Ya.mjs";
3
3
  import { COMBOBOX_ATTRIBUTE_ANCHOR, COMBOBOX_ATTRIBUTE_SELECTION, COMBOBOX_ATTRIBUTE_SELECTION_ITEM } from "./constants.combobox.mjs";
4
4
  import { setAria } from "@oscarpalmer/toretto/aria";
5
5
  import { setAttribute } from "@oscarpalmer/toretto/attribute";
6
- import { getData } from "@oscarpalmer/toretto/data";
7
6
  import { createElement } from "@oscarpalmer/toretto/create";
7
+ import { getData } from "@oscarpalmer/toretto/data";
8
8
  //#region src/js/combobox/dom.combobox.ts
9
9
  function createComboboxAnchor(parameters) {
10
10
  const { select } = parameters;
@@ -29,7 +29,10 @@ function createComboboxButton(parameters) {
29
29
  haspopup: "listbox",
30
30
  labelledby: `${label.id} ${id}_value`
31
31
  },
32
- property: { textContent: multiple ? "" : select.selectedOptions[0]?.textContent ?? "" }
32
+ property: {
33
+ textContent: multiple ? "" : select.selectedOptions[0]?.textContent ?? "",
34
+ type: "button"
35
+ }
33
36
  });
34
37
  if (!multiple) return { element };
35
38
  const container = createElement("div");
@@ -101,7 +104,8 @@ function createComboboxSelectionItem(option, state) {
101
104
  [COMBOBOX_ATTRIBUTE_SELECTION_ITEM]: "",
102
105
  tabindex: -1
103
106
  },
104
- data: { option: option.id }
107
+ data: { option: option.id },
108
+ property: { type: "button" }
105
109
  });
106
110
  const icon = createElement("span", {
107
111
  aria: { hidden: true },
@@ -1,2 +1,2 @@
1
- import { C as skipComboboxNavigation, S as preventComboboxActivation, _ as onComboboxPreview, b as onComboboxTab, c as onComboboxClickContent, d as onComboboxFilter, f as onComboboxFocusout, g as onComboboxNavigation, h as onComboboxKeydownSelection, l as onComboboxEnter, m as onComboboxKeydown, o as onComboboxActivation, p as onComboboxInput, s as onComboboxApply, u as onComboboxEscape, v as onComboboxRemoveSelection, x as onComboboxToggle, y as onComboboxSelection } from "../state.combobox-4xq0FPCF.mjs";
1
+ import { C as skipComboboxNavigation, S as preventComboboxActivation, _ as onComboboxPreview, b as onComboboxTab, c as onComboboxClickContent, d as onComboboxFilter, f as onComboboxFocusout, g as onComboboxNavigation, h as onComboboxKeydownSelection, l as onComboboxEnter, m as onComboboxKeydown, o as onComboboxActivation, p as onComboboxInput, s as onComboboxApply, u as onComboboxEscape, v as onComboboxRemoveSelection, x as onComboboxToggle, y as onComboboxSelection } from "../state.combobox-Qm3FWzYW.mjs";
2
2
  export { onComboboxActivation, onComboboxApply, onComboboxClickContent, onComboboxEnter, onComboboxEscape, onComboboxFilter, onComboboxFocusout, onComboboxInput, onComboboxKeydown, onComboboxKeydownSelection, onComboboxNavigation, onComboboxPreview, onComboboxRemoveSelection, onComboboxSelection, onComboboxTab, onComboboxToggle, preventComboboxActivation, skipComboboxNavigation };
@@ -1,2 +1,2 @@
1
- import { a as setComboboxLocalizations, t as OuiComboboxElement } from "../index-EfkUSals.mjs";
1
+ import { a as setComboboxLocalizations, t as OuiComboboxElement } from "../index-DJdFlTLm.mjs";
2
2
  export { OuiComboboxElement, setComboboxLocalizations };
@@ -1,8 +1,8 @@
1
1
  import { updateLocalizations } from "../l10n.mjs";
2
- import { C as setListboxDisabled, D as setListboxReadonly, O as setListboxRequired, T as setListboxLimit, a as setListboxValue, o as setListboxValues, w as setListboxFilter } from "../listbox.data-BWd0PCy7.mjs";
2
+ import { C as setListboxDisabled, D as setListboxReadonly, O as setListboxRequired, T as setListboxLimit, a as setListboxValue, o as setListboxValues, w as setListboxFilter } from "../listbox.data-C7CRa5Ya.mjs";
3
3
  import { attachListbox, detachListbox } from "../internal/listbox/listbox.state.mjs";
4
4
  import { COMBOBOX_TAGNAME } from "./constants.combobox.mjs";
5
- import { D as setComboboxLocalizations, a as onDetachCombobox, i as onAttachCombobox, n as comboboxStates, r as createComboboxState } from "../state.combobox-4xq0FPCF.mjs";
5
+ import { D as setComboboxLocalizations, a as onDetachCombobox, i as onAttachCombobox, n as comboboxStates, r as createComboboxState } from "../state.combobox-Qm3FWzYW.mjs";
6
6
  import { getAttribute } from "@oscarpalmer/toretto/attribute";
7
7
  import { parse } from "@oscarpalmer/atoms/string";
8
8
  //#region src/js/combobox/index.ts
@@ -42,6 +42,18 @@ var OuiComboboxElement = class extends HTMLElement {
42
42
  setListboxFilter(this.#state, value);
43
43
  }
44
44
  /**
45
+ * Form element associated with the combobox
46
+ */
47
+ get form() {
48
+ return this.#internals.form;
49
+ }
50
+ /**
51
+ * Label elements associated with the combobox
52
+ */
53
+ get labels() {
54
+ return this.#internals.labels;
55
+ }
56
+ /**
45
57
  * Maximum number of selected options
46
58
  */
47
59
  get max() {
@@ -114,6 +126,18 @@ var OuiComboboxElement = class extends HTMLElement {
114
126
  return this.#state.type;
115
127
  }
116
128
  /**
129
+ * Validation message for the combobox
130
+ */
131
+ get validationMessage() {
132
+ return this.#internals.validationMessage;
133
+ }
134
+ /**
135
+ * Validity state for the combobox
136
+ */
137
+ get validity() {
138
+ return this.#internals.validity;
139
+ }
140
+ /**
117
141
  * Current value
118
142
  */
119
143
  get value() {
@@ -137,6 +161,12 @@ var OuiComboboxElement = class extends HTMLElement {
137
161
  set values(values) {
138
162
  setListboxValues(this.#state, values);
139
163
  }
164
+ /**
165
+ * Can the combobox be validated?
166
+ */
167
+ get willValidate() {
168
+ return this.#internals.willValidate;
169
+ }
140
170
  constructor() {
141
171
  super();
142
172
  this.#internals = this.attachInternals();
@@ -155,6 +185,14 @@ var OuiComboboxElement = class extends HTMLElement {
155
185
  }
156
186
  }
157
187
  /**
188
+ * Check if the combobox is valid
189
+ *
190
+ * @returns `true` if the combobox is valid, otherwise `false`
191
+ */
192
+ checkValidity() {
193
+ return this.#internals.checkValidity();
194
+ }
195
+ /**
158
196
  * Clear all selected options
159
197
  */
160
198
  clear() {
@@ -180,6 +218,22 @@ var OuiComboboxElement = class extends HTMLElement {
180
218
  if (this.#state == null) this.#restored = parsed;
181
219
  else setListboxValues(this.#state, parsed);
182
220
  }
221
+ /**
222
+ * Check if the combobox is valid and report any validation errors
223
+ *
224
+ * @returns `true` if the combobox is valid, otherwise `false`
225
+ */
226
+ reportValidity() {
227
+ return this.#internals.reportValidity();
228
+ }
229
+ /**
230
+ * Set a custom validation message for the combobox
231
+ *
232
+ * @param message Validation message
233
+ */
234
+ setCustomValidity(message) {
235
+ this.#internals.setValidity({ customError: message !== "" }, message, this);
236
+ }
183
237
  setLocalizations(first, second) {
184
238
  updateLocalizations(this.#state.localizations.global, typeof first === "string" ? { [first]: second } : first, this.#state.localizations.component);
185
239
  }
@@ -1,2 +1,2 @@
1
- import { a as setComboboxLocalizations, i as hasTextSelection, n as getComboboxAutoComplete, o as updateComboboxLocalizations, r as getComboboxId } from "../index-EfkUSals.mjs";
1
+ import { a as setComboboxLocalizations, i as hasTextSelection, n as getComboboxAutoComplete, o as updateComboboxLocalizations, r as getComboboxId } from "../index-DJdFlTLm.mjs";
2
2
  export { getComboboxAutoComplete, getComboboxId, hasTextSelection, setComboboxLocalizations, updateComboboxLocalizations };
@@ -1,2 +1,2 @@
1
- import { D as setComboboxLocalizations, E as hasTextSelection, O as updateComboboxLocalizations, T as getComboboxId, w as getComboboxAutoComplete } from "../state.combobox-4xq0FPCF.mjs";
1
+ import { D as setComboboxLocalizations, E as hasTextSelection, O as updateComboboxLocalizations, T as getComboboxId, w as getComboboxAutoComplete } from "../state.combobox-Qm3FWzYW.mjs";
2
2
  export { getComboboxAutoComplete, getComboboxId, hasTextSelection, setComboboxLocalizations, updateComboboxLocalizations };
@@ -1,7 +1,7 @@
1
1
  import { t as OuiLocalizations } from "../l10n-Bn-7RcwR.mjs";
2
2
  import { o as OuiListboxLocalizations, u as OuiListboxStates } from "../listbox.model-CRReGOmu.mjs";
3
3
  import { OuiComboboxState } from "./models.combobox.mjs";
4
- import { t as OuiComboboxElement } from "../index-EfkUSals.mjs";
4
+ import { t as OuiComboboxElement } from "../index-DJdFlTLm.mjs";
5
5
  //#region src/js/combobox/state.combobox.d.ts
6
6
  declare function createComboboxState(element: OuiComboboxElement, internals: ElementInternals): OuiComboboxState;
7
7
  declare function onAttachCombobox(state: OuiComboboxState): void;
@@ -1,2 +1,2 @@
1
- import { a as onDetachCombobox, i as onAttachCombobox, n as comboboxStates, r as createComboboxState, t as comboboxLocalizations } from "../state.combobox-4xq0FPCF.mjs";
1
+ import { a as onDetachCombobox, i as onAttachCombobox, n as comboboxStates, r as createComboboxState, t as comboboxLocalizations } from "../state.combobox-Qm3FWzYW.mjs";
2
2
  export { comboboxLocalizations, comboboxStates, createComboboxState, onAttachCombobox, onDetachCombobox };
@@ -4,8 +4,8 @@ import { ATTRIBUTE_MOVABLE_HANDLE, createMovable } from "./movable/movable.embed
4
4
  import "./movable/movable.standalone.mjs";
5
5
  import { RESIZABLE_ATTRIBUTE_HANDLE, createResizable } from "./resizable/resizable.embedded.mjs";
6
6
  import { getAria, setAria } from "@oscarpalmer/toretto/aria";
7
- import { on } from "@oscarpalmer/toretto/event";
8
7
  import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
8
+ import { on } from "@oscarpalmer/toretto/event";
9
9
  import { setStyles } from "@oscarpalmer/toretto/style";
10
10
  //#region src/js/dialog.ts
11
11
  var OuiDialog = class {
@@ -106,7 +106,7 @@ function getState(element) {
106
106
  state.resizable?.reset();
107
107
  }
108
108
  })],
109
- modal: getAria(element, "modal") === "true" || element.matches(":modal")
109
+ modal: getAria(element, "modal") === true || element.matches(":modal")
110
110
  };
111
111
  state.dialog = new OuiDialog(state);
112
112
  state.movable = getMovable(element);
@@ -1,9 +1,9 @@
1
1
  import { getAria } from "@oscarpalmer/toretto/aria";
2
+ import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
2
3
  import { on } from "@oscarpalmer/toretto/event";
4
+ import { setStyle, setStyles } from "@oscarpalmer/toretto/style";
3
5
  import { isPlainObject } from "@oscarpalmer/atoms/is";
4
- import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
5
6
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
- import { setStyle, setStyles } from "@oscarpalmer/toretto/style";
7
7
  //#region src/js/floatable/floatable.embedded.ts
8
8
  var OuiFloatable = class {
9
9
  #destroyed = false;
@@ -23,13 +23,7 @@ var OuiFloatable = class {
23
23
  }
24
24
  constructor(state, standalone) {
25
25
  this.#state = state;
26
- const { anchor, content } = state;
27
- if (standalone) {
28
- setAttribute(content, ATTRIBUTE_FLOATABLE, "");
29
- content.popover = "manual";
30
- } else content.popover ??= "auto";
31
- setStyle(anchor, "anchorName", state.name);
32
- setStyle(content, "positionAnchor", state.name);
26
+ this.#initialize(state, standalone);
33
27
  }
34
28
  /**
35
29
  * Destroy the floatable, removing it from the DOM and cleaning up references
@@ -61,6 +55,15 @@ var OuiFloatable = class {
61
55
  update(position) {
62
56
  if (!this.#destroyed) setPosition(this.#state, position);
63
57
  }
58
+ #initialize(state, standalone) {
59
+ const { anchor, content } = state;
60
+ if (standalone) {
61
+ setAttribute(content, ATTRIBUTE_FLOATABLE, "");
62
+ content.popover = "manual";
63
+ } else content.popover ??= "auto";
64
+ setStyle(anchor, "anchorName", state.name);
65
+ setStyle(content, "positionAnchor", state.name);
66
+ }
64
67
  };
65
68
  function getAnchorName(anchor) {
66
69
  let { anchorName } = anchor.style;
@@ -101,7 +104,7 @@ function createInstance(anchor, content, options, standalone) {
101
104
  function getOnBeforeToggleListener(element) {
102
105
  return on(element, "beforetoggle", (event) => {
103
106
  const { newState, source } = event;
104
- if (newState === "open" && source != null && getAria(source, "disabled") === "true") event.preventDefault();
107
+ if (newState === "open" && source != null && getAria(source, "disabled") === true) event.preventDefault();
105
108
  }, { passive: false });
106
109
  }
107
110
  function getOptions(input) {
@@ -1,10 +1,10 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
+ import { clamp } from "@oscarpalmer/atoms/number";
3
+ import { setAttribute } from "@oscarpalmer/toretto/attribute";
2
4
  import { dispatch, on } from "@oscarpalmer/toretto/event";
5
+ import { findAncestor } from "@oscarpalmer/toretto/find";
3
6
  import { isPlainObject } from "@oscarpalmer/atoms/is";
4
- import { setAttribute } from "@oscarpalmer/toretto/attribute";
5
7
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
- import { clamp } from "@oscarpalmer/atoms/number";
7
- import { findAncestor } from "@oscarpalmer/toretto/find";
8
8
  import { getFocusable } from "@oscarpalmer/toretto/focusable";
9
9
  //#region src/js/focus-trap/focus-trap.embedded.ts
10
10
  var OuiFocusTrap = class {
@@ -171,16 +171,12 @@ function onPointerdown(event) {
171
171
  function onTab(event) {
172
172
  const element = findAncestor(event, SELECTOR);
173
173
  const instance = instances.get(element);
174
- if (instance == null) return;
175
- const dispatched = dispatch(element, "focus-trap");
176
- setTimeout(() => {
177
- if (dispatched.defaultPrevented) return;
178
- if (!instance.disabled) event.preventDefault();
179
- const elements = getFocusable(element);
180
- const index = elements.indexOf(event.target);
181
- if (index === -1 || elements.length === 0) tabToTrap(instance, elements, element);
182
- else tabToElement(instance, elements, index, event.shiftKey ? -1 : 1);
183
- });
174
+ if (instance == null || dispatch(element, "oui:focus-trap").defaultPrevented) return;
175
+ if (!instance.disabled) event.preventDefault();
176
+ const elements = getFocusable(element);
177
+ const index = elements.indexOf(event.target);
178
+ if (index === -1 || elements.length === 0) tabToTrap(instance, elements, element);
179
+ else tabToElement(instance, elements, index, event.shiftKey ? -1 : 1);
184
180
  }
185
181
  function removeFocusTrap(element) {
186
182
  instances.get(element)?.destroy();
@@ -46,6 +46,14 @@ declare class OuiComboboxElement extends HTMLElement {
46
46
  * Set the filter value
47
47
  */
48
48
  set filter(value: string);
49
+ /**
50
+ * Form element associated with the combobox
51
+ */
52
+ get form(): HTMLFormElement | null;
53
+ /**
54
+ * Label elements associated with the combobox
55
+ */
56
+ get labels(): NodeList;
49
57
  /**
50
58
  * Maximum number of selected options
51
59
  */
@@ -94,6 +102,14 @@ declare class OuiComboboxElement extends HTMLElement {
94
102
  * Type of combobox
95
103
  */
96
104
  get type(): OuiListboxType;
105
+ /**
106
+ * Validation message for the combobox
107
+ */
108
+ get validationMessage(): string;
109
+ /**
110
+ * Validity state for the combobox
111
+ */
112
+ get validity(): ValidityState;
97
113
  /**
98
114
  * Current value
99
115
  */
@@ -110,8 +126,18 @@ declare class OuiComboboxElement extends HTMLElement {
110
126
  * Set the values
111
127
  */
112
128
  set values(values: unknown[]);
129
+ /**
130
+ * Can the combobox be validated?
131
+ */
132
+ get willValidate(): boolean;
113
133
  constructor();
114
134
  attributeChangedCallback(name: string, _: string | null, value: string | null): void;
135
+ /**
136
+ * Check if the combobox is valid
137
+ *
138
+ * @returns `true` if the combobox is valid, otherwise `false`
139
+ */
140
+ checkValidity(): boolean;
115
141
  /**
116
142
  * Clear all selected options
117
143
  */
@@ -120,7 +146,19 @@ declare class OuiComboboxElement extends HTMLElement {
120
146
  disconnectedCallback(): void;
121
147
  formDisabledCallback(disabled: boolean): void;
122
148
  formResetCallback(): void;
123
- formStateRestoreCallback(state: string | File | FormData, reason: unknown): void;
149
+ formStateRestoreCallback(state: unknown, reason: unknown): void;
150
+ /**
151
+ * Check if the combobox is valid and report any validation errors
152
+ *
153
+ * @returns `true` if the combobox is valid, otherwise `false`
154
+ */
155
+ reportValidity(): boolean;
156
+ /**
157
+ * Set a custom validation message for the combobox
158
+ *
159
+ * @param message Validation message
160
+ */
161
+ setCustomValidity(message: string): void;
124
162
  /**
125
163
  * Set combobox localizations for a specific language
126
164
  *
@@ -1,5 +1,6 @@
1
+ import { OuiColorPickerElement, OuiColorPickerEvent, setColorPickerLocalizations } from "./color-picker.mjs";
1
2
  import { a as OuiFloatablePosition, n as CreateOuiFloatableOptions, r as OuiFloatable, s as createFloatable } from "./floatable.embedded-Bct4U5Dm.mjs";
2
- import { a as setComboboxLocalizations, t as OuiComboboxElement } from "./index-EfkUSals.mjs";
3
+ import { a as setComboboxLocalizations, t as OuiComboboxElement } from "./index-DJdFlTLm.mjs";
3
4
  import { d as OuiSortable, f as createSortable, g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "./draggable-a6w0J1OD.mjs";
4
5
  import "./movable/movable.standalone.mjs";
5
6
  import { a as createResizable, n as OuiResizable, t as CreateOuiResizableOptions } from "./resizable.embedded-3qoR0Bjm.mjs";
@@ -12,5 +13,6 @@ import { OuiListboxElement } from "./listbox/index.mjs";
12
13
  import { OuiPopover, getPopover } from "./popover.mjs";
13
14
  import "./sortable/sortable.standalone.mjs";
14
15
  import { OuiSplitterElement } from "./splitter.mjs";
16
+ import { OuiTabsElement, OuiTabsEvent } from "./tabs.mjs";
15
17
  import { OuiTooltip, getTooltip, setTooltipDelay } from "./tooltip.mjs";
16
- export { type CreateOuiFloatableOptions, type CreateOuiDraggableOptions as CreateOuiMovableOptions, type CreateOuiDraggableOptions as CreateOuiSortableOptions, type CreateOuiResizableOptions, OuiComboboxElement, type OuiDialog, type OuiFloatable, type OuiFloatablePosition, type OuiFocusTrap, type OuiFocusTrapOptions, OuiListboxElement, type OuiMovable, type OuiPopover, type OuiResizable, type OuiSortable, OuiSplitterElement, type OuiTooltip, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setComboboxLocalizations, setListboxLocalizations, setTooltipDelay };
18
+ export { type CreateOuiFloatableOptions, type CreateOuiDraggableOptions as CreateOuiMovableOptions, type CreateOuiDraggableOptions as CreateOuiSortableOptions, type CreateOuiResizableOptions, OuiColorPickerElement, OuiColorPickerEvent, OuiComboboxElement, type OuiDialog, type OuiFloatable, type OuiFloatablePosition, type OuiFocusTrap, type OuiFocusTrapOptions, OuiListboxElement, type OuiMovable, type OuiPopover, type OuiResizable, type OuiSortable, OuiSplitterElement, OuiTabsElement, OuiTabsEvent, type OuiTooltip, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setColorPickerLocalizations, setComboboxLocalizations, setListboxLocalizations, setTooltipDelay };
package/dist/js/index.mjs CHANGED
@@ -1,21 +1,23 @@
1
1
  import { createFloatable } from "./floatable/floatable.embedded.mjs";
2
+ import { OuiColorPickerElement, OuiColorPickerEvent, setColorPickerLocalizations } from "./color-picker.mjs";
2
3
  import { createMovable } from "./movable/movable.embedded.mjs";
3
4
  import "./movable/movable.standalone.mjs";
4
5
  import { createResizable } from "./resizable/resizable.embedded.mjs";
5
6
  import { getDialog } from "./dialog.mjs";
6
7
  import "./menu.mjs";
7
8
  import "./toolbar.mjs";
8
- import { D as setComboboxLocalizations } from "./state.combobox-4xq0FPCF.mjs";
9
+ import { D as setComboboxLocalizations } from "./state.combobox-Qm3FWzYW.mjs";
9
10
  import { OuiComboboxElement } from "./combobox/index.mjs";
10
11
  import "./floatable/floatable.standalone.mjs";
11
12
  import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
12
13
  import "./focus-trap/focus-trap.standalone.mjs";
13
- import { n as setListboxLocalizations } from "./misc.listbox-BI-XsTOf.mjs";
14
+ import { n as setListboxLocalizations } from "./misc.listbox-Cyz2CRDy.mjs";
14
15
  import { OuiListboxElement } from "./listbox/index.mjs";
15
16
  import { getPopover } from "./popover.mjs";
16
17
  import "./resizable/resizable.standalone.mjs";
17
18
  import { createSortable } from "./sortable/sortable.embedded.mjs";
18
19
  import "./sortable/sortable.standalone.mjs";
19
20
  import { OuiSplitterElement } from "./splitter.mjs";
21
+ import { OuiTabsElement, OuiTabsEvent } from "./tabs.mjs";
20
22
  import { getTooltip, setTooltipDelay } from "./tooltip.mjs";
21
- export { OuiComboboxElement, OuiListboxElement, OuiSplitterElement, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setComboboxLocalizations, setListboxLocalizations, setTooltipDelay };
23
+ export { OuiColorPickerElement, OuiColorPickerEvent, OuiComboboxElement, OuiListboxElement, OuiSplitterElement, OuiTabsElement, OuiTabsEvent, createFloatable, createFocusTrap, createMovable, createResizable as createOuiResizable, createSortable, getDialog, getPopover, getTooltip, setColorPickerLocalizations, setComboboxLocalizations, setListboxLocalizations, setTooltipDelay };
@@ -1,10 +1,10 @@
1
- import { dispatch, getEventPosition, on } from "@oscarpalmer/toretto/event";
2
- import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
3
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
4
- import { setStyle, setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
5
1
  import { clamp } from "@oscarpalmer/atoms/number";
2
+ import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
3
+ import { dispatch, getEventPosition, on } from "@oscarpalmer/toretto/event";
6
4
  import { findAncestor } from "@oscarpalmer/toretto/find";
5
+ import { setStyle, setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
7
6
  import supportsTouch from "@oscarpalmer/toretto/touch";
7
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
8
8
  //#region src/js/internal/draggable.ts
9
9
  var OuiDraggable = class {
10
10
  #destroyed = false;
@@ -54,7 +54,7 @@ function addDraggable(element, options) {
54
54
  function cancelDrag(item) {
55
55
  if (item == null) return;
56
56
  item.state.options.drag.onCancel?.(globals, item);
57
- dispatch(item.state.element, `${item.state.name}:cancel`, { detail: { element: item.state.options.getOrigin() } });
57
+ dispatch(item.state.element, `oui:${item.state.name}:cancel`, { detail: { element: item.state.options.getOrigin() } });
58
58
  reset();
59
59
  }
60
60
  function destroyInstance(instance, state) {
@@ -130,26 +130,23 @@ function onPointerdown(event) {
130
130
  };
131
131
  globals.offset = item.state.options.position.getOffset(globals, item, element, position);
132
132
  globals.original = item.state.options.position.getOriginal(globals, item, position);
133
- const dispatched = dispatch(item.state.element, `${item.state.name}:begin`, { detail: {
133
+ if (dispatch(item.state.element, `oui:${item.state.name}:begin`, { detail: {
134
134
  element,
135
135
  position: { ...globals.original }
136
- } });
137
- setTimeout(() => {
138
- if (dispatched.defaultPrevented) {
139
- item.state.options.drag.onCancel?.(globals, item);
140
- reset();
141
- return;
142
- }
143
- const next = getNextPosition(item, position);
144
- setStyles(dragged, {
145
- position: "fixed",
146
- inset: `${next.y}px auto auto ${next.x}px`,
147
- transform: "translate3d(0, 0, 0)"
148
- });
149
- item.state.options.drag.onBegin?.(event, globals, item, element, handle, next);
150
- item.state.styling.set();
151
- styleToggler.set();
136
+ } }).defaultPrevented) {
137
+ item.state.options.drag.onCancel?.(globals, item);
138
+ reset();
139
+ return;
140
+ }
141
+ const next = getNextPosition(item, position);
142
+ setStyles(dragged, {
143
+ position: "fixed",
144
+ inset: `${next.y}px auto auto ${next.x}px`,
145
+ transform: "translate3d(0, 0, 0)"
152
146
  });
147
+ item.state.options.drag.onBegin?.(event, globals, item, element, handle, next);
148
+ item.state.styling.set();
149
+ styleToggler.set();
153
150
  }
154
151
  function onPointermove(event) {
155
152
  if (current == null) return;
@@ -161,10 +158,7 @@ function onPointermove(event) {
161
158
  calculated: next,
162
159
  original: position
163
160
  });
164
- const dispatched = dispatch(current.state.element, `${current.state.name}:move`, { detail });
165
- setTimeout(() => {
166
- if (dispatched.defaultPrevented) cancelDrag(current);
167
- });
161
+ if (dispatch(current.state.element, `oui:${current.state.name}:move`, { detail }).defaultPrevented) cancelDrag(current);
168
162
  }
169
163
  function onPointerup(event) {
170
164
  current?.state.options.drag.onEnd?.(event, globals, current, reset);
@@ -1,2 +1,2 @@
1
- import { a as setListboxValue, i as filterListboxOptions, n as filterListbox, o as setListboxValues, r as filterListboxOption, s as toggleListboxOption, t as applyListboxSelection } from "../../listbox.data-BWd0PCy7.mjs";
1
+ import { a as setListboxValue, i as filterListboxOptions, n as filterListbox, o as setListboxValues, r as filterListboxOption, s as toggleListboxOption, t as applyListboxSelection } from "../../listbox.data-C7CRa5Ya.mjs";
2
2
  export { applyListboxSelection, filterListbox, filterListboxOption, filterListboxOptions, setListboxValue, setListboxValues, toggleListboxOption };
@@ -1,2 +1,2 @@
1
- import { _ as createListboxValueLabel, b as updateListboxValueLabel, c as createListboxContent, d as createListboxHeader, f as createListboxInput, g as createListboxOptions, h as createListboxOption, l as createListboxFilter, m as createListboxMessage, p as createListboxList, u as createListboxGroup, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-BWd0PCy7.mjs";
1
+ import { _ as createListboxValueLabel, b as updateListboxValueLabel, c as createListboxContent, d as createListboxHeader, f as createListboxInput, g as createListboxOptions, h as createListboxOption, l as createListboxFilter, m as createListboxMessage, p as createListboxList, u as createListboxGroup, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-C7CRa5Ya.mjs";
2
2
  export { createListboxContent, createListboxFilter, createListboxGroup, createListboxHeader, createListboxInput, createListboxList, createListboxMessage, createListboxOption, createListboxOptions, createListboxValueLabel, updateListboxMessage, updateListboxPreview, updateListboxValueLabel };
@@ -1,5 +1,5 @@
1
1
  import { LISTBOX_KEYS } from "./listbox.constants.mjs";
2
- import { S as getListboxVisibleOptions } from "../../listbox.data-BWd0PCy7.mjs";
2
+ import { S as getListboxVisibleOptions } from "../../listbox.data-C7CRa5Ya.mjs";
3
3
  import { clamp } from "@oscarpalmer/atoms/number";
4
4
  //#region src/js/internal/listbox/listbox.event.ts
5
5
  function processListboxKeydown(event, state) {
@@ -12,14 +12,15 @@ function updateListboxForm(state, values, emit) {
12
12
  state.internals.setFormValue(value, JSON.stringify(values));
13
13
  state.callbacks.data.onForm(state);
14
14
  updateListboxValidity(state);
15
- if (emit ?? true) dispatch(state.host, "change");
15
+ if (emit ?? true) dispatch(state.host, "oui:change");
16
16
  }
17
17
  function updateListboxValidity(state) {
18
- if (state.autocomplete.none && !state.listbox) {
19
- const valueMissing = state.required && state.filter.element.value.length === 0;
20
- const localization = getLocalization(state.localizations.global, state.host, "invalid", state.localizations.component);
21
- state.internals.setValidity({ valueMissing }, localize(localization, {}, []));
22
- state.internals.checkValidity();
18
+ const { autocomplete, filter, host, internals, listbox, localizations, max, min, multiple, options, required } = state;
19
+ if (autocomplete.none && !listbox) {
20
+ const valueMissing = required && filter.element.value.length === 0;
21
+ const localization = getLocalization(localizations.global, host, "invalid", localizations.component);
22
+ internals.setValidity({ valueMissing }, localize(localization, {}, []));
23
+ internals.checkValidity();
23
24
  return;
24
25
  }
25
26
  let data = {};
@@ -27,26 +28,26 @@ function updateListboxValidity(state) {
27
28
  let key;
28
29
  let parameters = [];
29
30
  switch (true) {
30
- case state.required && state.options.selected.length === 0:
31
+ case required && options.selected.length === 0:
31
32
  error = "badInput";
32
33
  key = "input";
33
34
  break;
34
- case state.multiple && typeof state.max === "number" && state.options.selected.length > state.max:
35
- data = { amount: state.max };
35
+ case multiple && typeof max === "number" && options.selected.length > max:
36
+ data = { amount: max };
36
37
  error = "rangeOverflow";
37
38
  key = "max";
38
- parameters = [state.max];
39
+ parameters = [max];
39
40
  break;
40
- case state.multiple && typeof state.min === "number" && state.options.selected.length < state.min:
41
- data = { amount: state.min };
41
+ case multiple && typeof min === "number" && options.selected.length < min:
42
+ data = { amount: min };
42
43
  error = "rangeUnderflow";
43
44
  key = "min";
44
- parameters = [state.min];
45
+ parameters = [min];
45
46
  }
46
- const localization = key == null ? void 0 : getLocalization(state.localizations.global, state.host, key, state.localizations.component);
47
+ const localization = key == null ? void 0 : getLocalization(localizations.global, host, key, localizations.component);
47
48
  const message = localization == null ? void 0 : localize(localization, data, parameters);
48
- state.internals.setValidity(error == null ? {} : { [error]: true }, message);
49
- state.internals.checkValidity();
49
+ internals.setValidity(error == null ? {} : { [error]: true }, message);
50
+ internals.checkValidity();
50
51
  }
51
52
  //#endregion
52
53
  export { updateListboxForm, updateListboxValidity };
@@ -1,2 +1,2 @@
1
- import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, S as getListboxVisibleOptions, T as setListboxLimit, w as setListboxFilter, x as generateListboxIds } from "../../listbox.data-BWd0PCy7.mjs";
1
+ import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, S as getListboxVisibleOptions, T as setListboxLimit, w as setListboxFilter, x as generateListboxIds } from "../../listbox.data-C7CRa5Ya.mjs";
2
2
  export { generateListboxIds, getListboxVisibleOptions, setListboxDisabled, setListboxFilter, setListboxLimit, setListboxMultiple, setListboxReadonly, setListboxRequired };
@@ -1,11 +1,11 @@
1
1
  import { updateListboxForm } from "./listbox.form.mjs";
2
- import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, T as setListboxLimit, b as updateListboxValueLabel, i as filterListboxOptions, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-BWd0PCy7.mjs";
2
+ import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, T as setListboxLimit, b as updateListboxValueLabel, i as filterListboxOptions, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-C7CRa5Ya.mjs";
3
3
  import { getAttribute } from "@oscarpalmer/toretto/attribute";
4
4
  //#region src/js/internal/listbox/listbox.state.ts
5
5
  function attachListbox(state, states, onAttach) {
6
- const { filter, host, label } = state;
6
+ const { filter, host, id, label } = state;
7
7
  label.element.htmlFor = filter.element.id;
8
- label.element.id = `${state.id}_label`;
8
+ label.element.id = `${id}_label`;
9
9
  onAttach(state);
10
10
  states.map.set(host, state);
11
11
  states.set.add(state);
@@ -33,7 +33,7 @@ function initializeListboxState(state, states, onAttach) {
33
33
  updateListboxForm(state, state.values.current, false);
34
34
  updateListboxMessage(state);
35
35
  updateListboxValueLabel(state);
36
- if (state.options.selected.length > 0) updateListboxPreview("none", state, state.options.selected[0]);
36
+ if (state.options.selected.length > 0) updateListboxPreview("none", state, state.options.selected[0], false);
37
37
  return state;
38
38
  }
39
39
  //#endregion
@@ -8,24 +8,30 @@ declare class OuiNavigable {
8
8
  orientation: OuiNavigableOrientation;
9
9
  constructor(element: HTMLElement, options: OuiNavigableOptions);
10
10
  destroy(): void;
11
+ navigate(index: number, focus?: boolean): void;
11
12
  }
12
13
  type OuiNavigableActive = {
13
14
  element?: HTMLElement;
14
15
  index: number;
15
16
  };
17
+ type OuiNavigableCallback<ReturnType> = (event: KeyboardEvent, navigable: OuiNavigable) => ReturnType;
16
18
  type OuiNavigableOptions = {
19
+ orientation?: OuiNavigableOrientation;
17
20
  role?: AriaRole;
18
21
  selector: string;
19
22
  vertical: boolean;
20
- onDeactivate?: (event: KeyboardEvent, navigable: OuiNavigable) => void;
21
- onPreventNavigation?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean;
22
- onShouldActivate?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean;
23
- onShouldDeactivate?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean | undefined;
23
+ onActivate?: (navigable: OuiNavigable) => void;
24
+ onDeactivate?: OuiNavigableCallback<void>;
25
+ onNavigation?: (navigable: OuiNavigable) => void;
26
+ onPreventNavigation?: OuiNavigableCallback<boolean>;
27
+ onShouldActivate?: OuiNavigableCallback<boolean>;
28
+ onShouldDeactivate?: OuiNavigableCallback<boolean | undefined>;
24
29
  };
25
30
  type OuiNavigableOrientation = 'horizontal' | 'vertical';
26
31
  declare function getNavigable(element: HTMLElement, options: OuiNavigableOptions): OuiNavigable;
32
+ declare function getNavigableOrientation(element: HTMLElement, vertical: boolean, aria?: boolean): OuiNavigableOrientation;
27
33
  declare function updateNavigableFocus(navigable: OuiNavigable, focus: boolean, items?: HTMLElement[]): void;
28
34
  declare const NAVIGABLE_KEYS_HORIZONTAL: Set<string>;
29
35
  declare const NAVIGABLE_KEYS_VERTICAL: Set<string>;
30
36
  //#endregion
31
- export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, OuiNavigableOptions, getNavigable, updateNavigableFocus };
37
+ export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, OuiNavigableOptions, OuiNavigableOrientation, getNavigable, getNavigableOrientation, updateNavigableFocus };