@oscarpalmer/oui 0.35.0 → 0.37.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 (128) hide show
  1. package/dist/css/badge.css +18 -15
  2. package/dist/css/button.css +35 -31
  3. package/dist/css/color.css +20 -20
  4. package/dist/css/combobox.css +134 -35
  5. package/dist/css/content.css +29 -10
  6. package/dist/css/floatable.css +10 -10
  7. package/dist/css/form.css +393 -129
  8. package/dist/css/listbox.css +176 -0
  9. package/dist/css/message.css +13 -10
  10. package/dist/css/reset.css +29 -88
  11. package/dist/css/splitter.css +2 -2
  12. package/dist/css/tabs.css +103 -0
  13. package/dist/js/combobox/constants.combobox.d.mts +2 -2
  14. package/dist/js/combobox/constants.combobox.mjs +40 -33
  15. package/dist/js/combobox/dom.combobox.d.mts +8 -91
  16. package/dist/js/combobox/dom.combobox.mjs +204 -2
  17. package/dist/js/combobox/event.combobox.d.mts +14 -8
  18. package/dist/js/combobox/event.combobox.mjs +2 -2
  19. package/dist/js/combobox/index.d.mts +1 -1
  20. package/dist/js/combobox/index.mjs +20 -18
  21. package/dist/js/combobox/misc.combobox.d.mts +2 -2
  22. package/dist/js/combobox/misc.combobox.mjs +2 -2
  23. package/dist/js/combobox/models.combobox.d.mts +44 -2
  24. package/dist/js/combobox/state.combobox.d.mts +9 -10
  25. package/dist/js/combobox/state.combobox.mjs +2 -2
  26. package/dist/js/constants.combobox-DmRAMC64.d.mts +26 -0
  27. package/dist/js/constants.listbox-DRsXUxd3.d.mts +14 -0
  28. package/dist/js/focus-trap/focus-trap.embedded.mjs +6 -10
  29. package/dist/js/index-EfkUSals.d.mts +139 -0
  30. package/dist/js/index.d.mts +5 -2
  31. package/dist/js/index.mjs +5 -2
  32. package/dist/js/internal/attributable.mjs +4 -3
  33. package/dist/js/internal/draggable.mjs +16 -22
  34. package/dist/js/internal/listbox/listbox.constants.d.mts +11 -0
  35. package/dist/js/internal/listbox/listbox.constants.mjs +23 -0
  36. package/dist/js/internal/listbox/listbox.data.d.mts +20 -0
  37. package/dist/js/internal/listbox/listbox.data.mjs +2 -0
  38. package/dist/js/internal/listbox/listbox.dom.d.mts +66 -0
  39. package/dist/js/internal/listbox/listbox.dom.mjs +2 -0
  40. package/dist/js/internal/listbox/listbox.event.d.mts +5 -0
  41. package/dist/js/internal/listbox/listbox.event.mjs +63 -0
  42. package/dist/js/internal/listbox/listbox.form.d.mts +6 -0
  43. package/dist/js/internal/listbox/listbox.form.mjs +52 -0
  44. package/dist/js/internal/listbox/listbox.misc.d.mts +12 -0
  45. package/dist/js/internal/listbox/listbox.misc.mjs +2 -0
  46. package/dist/js/internal/listbox/listbox.model.d.mts +2 -0
  47. package/dist/js/internal/listbox/listbox.model.mjs +1 -0
  48. package/dist/js/internal/listbox/listbox.state.d.mts +7 -0
  49. package/dist/js/internal/listbox/listbox.state.mjs +40 -0
  50. package/dist/js/internal/misc.d.mts +6 -0
  51. package/dist/js/internal/misc.mjs +13 -0
  52. package/dist/js/internal/navigable.d.mts +11 -5
  53. package/dist/js/internal/navigable.mjs +44 -18
  54. package/dist/js/l10n-Bn-7RcwR.d.mts +20 -0
  55. package/dist/js/l10n.d.mts +2 -20
  56. package/dist/js/listbox/constants.listbox.d.mts +2 -0
  57. package/dist/js/listbox/constants.listbox.mjs +40 -0
  58. package/dist/js/listbox/event.listbox.d.mts +8 -0
  59. package/dist/js/listbox/event.listbox.mjs +2 -0
  60. package/dist/js/listbox/index.d.mts +116 -0
  61. package/dist/js/listbox/index.mjs +189 -0
  62. package/dist/js/listbox/misc.listbox.d.mts +2 -0
  63. package/dist/js/listbox/misc.listbox.mjs +2 -0
  64. package/dist/js/listbox/state.listbox.d.mts +11 -0
  65. package/dist/js/listbox/state.listbox.mjs +2 -0
  66. package/dist/js/listbox.data-BWd0PCy7.mjs +424 -0
  67. package/dist/js/listbox.model-CRReGOmu.d.mts +125 -0
  68. package/dist/js/misc.listbox-BI-XsTOf.mjs +197 -0
  69. package/dist/js/misc.listbox-gnoJhrTr.d.mts +20 -0
  70. package/dist/js/movable/movable.embedded.mjs +3 -6
  71. package/dist/js/resizable/resizable.embedded.mjs +16 -26
  72. package/dist/js/sortable/sortable.embedded.mjs +4 -2
  73. package/dist/js/splitter.mjs +15 -12
  74. package/dist/js/state.combobox-4xq0FPCF.mjs +365 -0
  75. package/dist/js/tabs.d.mts +25 -0
  76. package/dist/js/tabs.mjs +240 -0
  77. package/dist/js/tooltip.mjs +13 -12
  78. package/package.json +7 -3
  79. package/src/css/badge.scss +6 -18
  80. package/src/css/button.scss +6 -45
  81. package/src/css/color.scss +20 -20
  82. package/src/css/combobox.scss +21 -52
  83. package/src/css/content.scss +30 -3
  84. package/src/css/floatable.scss +17 -17
  85. package/src/css/form.scss +84 -72
  86. package/src/css/listbox.scss +120 -0
  87. package/src/css/message.scss +13 -28
  88. package/src/css/mixins.scss +253 -28
  89. package/src/css/reset.scss +37 -86
  90. package/src/css/splitter.scss +2 -2
  91. package/src/css/tabs.scss +85 -0
  92. package/src/js/combobox/constants.combobox.ts +46 -25
  93. package/src/js/combobox/dom.combobox.ts +36 -454
  94. package/src/js/combobox/event.combobox.ts +129 -218
  95. package/src/js/combobox/index.ts +37 -30
  96. package/src/js/combobox/misc.combobox.ts +30 -114
  97. package/src/js/combobox/models.combobox.ts +7 -47
  98. package/src/js/combobox/state.combobox.ts +126 -127
  99. package/src/js/focus-trap/focus-trap.embedded.ts +11 -19
  100. package/src/js/index.ts +2 -0
  101. package/src/js/internal/draggable.ts +29 -33
  102. package/src/js/internal/listbox/listbox.constants.ts +25 -0
  103. package/src/js/{combobox/data.combobox.ts → internal/listbox/listbox.data.ts} +94 -43
  104. package/src/js/internal/listbox/listbox.dom.ts +445 -0
  105. package/src/js/internal/listbox/listbox.event.ts +129 -0
  106. package/src/js/{combobox/form.combobox.ts → internal/listbox/listbox.form.ts} +13 -14
  107. package/src/js/internal/listbox/listbox.misc.ts +135 -0
  108. package/src/js/internal/listbox/listbox.model.ts +169 -0
  109. package/src/js/internal/listbox/listbox.state.ts +82 -0
  110. package/src/js/internal/misc.ts +27 -0
  111. package/src/js/internal/navigable.ts +80 -23
  112. package/src/js/l10n.ts +8 -8
  113. package/src/js/listbox/constants.listbox.ts +61 -0
  114. package/src/js/listbox/event.listbox.ts +106 -0
  115. package/src/js/listbox/index.ts +302 -0
  116. package/src/js/listbox/misc.listbox.ts +70 -0
  117. package/src/js/listbox/state.listbox.ts +196 -0
  118. package/src/js/movable/movable.embedded.ts +11 -13
  119. package/src/js/resizable/resizable.embedded.ts +25 -39
  120. package/src/js/splitter.ts +21 -18
  121. package/src/js/tabs.ts +447 -0
  122. package/src/js/tooltip.ts +20 -17
  123. package/dist/js/combobox/data.combobox.d.mts +0 -18
  124. package/dist/js/combobox/data.combobox.mjs +0 -2
  125. package/dist/js/combobox/form.combobox.d.mts +0 -6
  126. package/dist/js/combobox/form.combobox.mjs +0 -2
  127. package/dist/js/constants.combobox-h_kyDegw.d.mts +0 -248
  128. package/dist/js/data.combobox-B8HMkDOh.mjs +0 -1030
@@ -0,0 +1,197 @@
1
+ import { getLocalizations, updateLocalizations } from "./l10n.mjs";
2
+ import { b as updateListboxValueLabel, c as createListboxContent, n as filterListbox, s as toggleListboxOption, t as applyListboxSelection, v as updateListboxMessage, x as generateListboxIds, y as updateListboxPreview } from "./listbox.data-BWd0PCy7.mjs";
3
+ import { initializeListboxState } from "./internal/listbox/listbox.state.mjs";
4
+ import { getBooleanAriaValue } from "./internal/misc.mjs";
5
+ import { processListboxKeydown } from "./internal/listbox/listbox.event.mjs";
6
+ import { LISTBOX_ATTRIBUTES, LISTBOX_MESSAGES, LISTBOX_SELECTORS, LISTBOX_TAGNAME } from "./listbox/constants.listbox.mjs";
7
+ import { on } from "@oscarpalmer/toretto/event";
8
+ import { setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
9
+ import { findAncestor } from "@oscarpalmer/toretto/find";
10
+ import { getData } from "@oscarpalmer/toretto/data";
11
+ import { noop } from "@oscarpalmer/atoms/function";
12
+ //#region src/js/listbox/event.listbox.ts
13
+ function onListboxClick(event) {
14
+ const listbox = findAncestor(event, LISTBOX_TAGNAME);
15
+ const state = listboxStates.map.get(listbox);
16
+ if (listbox == null || state == null) return;
17
+ const option = findAncestor(event, LISTBOX_SELECTORS.option);
18
+ if (option == null) return;
19
+ if (state.disabled) state.filter.element.focus();
20
+ else if (state.readonly) updateListboxPreview("none", state, option, false);
21
+ else toggleListboxOption(state, option);
22
+ }
23
+ function onListboxEnter(state) {
24
+ if (!state.disabled && !state.readonly) toggleListboxOption(state, state.active);
25
+ }
26
+ function onListboxFilter(preview, state, _, active) {
27
+ updateListboxPreview(preview, state, active);
28
+ }
29
+ function onListboxInput(event) {
30
+ const listbox = findAncestor(event, LISTBOX_TAGNAME);
31
+ const state = listboxStates.map.get(listbox);
32
+ if (state?.filter.element === event.target) filterListbox(event.inputType, state);
33
+ }
34
+ function onListboxKeydown(event) {
35
+ const listbox = findAncestor(event, LISTBOX_TAGNAME);
36
+ const state = listboxStates.map.get(listbox);
37
+ if (state?.filter.element === event.target) processListboxKeydown(event, state);
38
+ }
39
+ function onListboxNavigation(preview, state, active) {
40
+ if (state.multiple || state.readonly) updateListboxPreview(preview, state, active);
41
+ else applyListboxSelection({
42
+ state,
43
+ option: active,
44
+ added: true,
45
+ selected: active == null ? [] : [active]
46
+ });
47
+ }
48
+ function onListboxToggle(state) {
49
+ state.filter.element.focus();
50
+ }
51
+ on(document, "click", onListboxClick);
52
+ on(document, "input", onListboxInput);
53
+ on(document, "keydown", onListboxKeydown, { passive: false });
54
+ //#endregion
55
+ //#region src/js/listbox/state.listbox.ts
56
+ function createListboxState(element, internals) {
57
+ const select = element.querySelector("select");
58
+ if (select == null) throw new Error(LISTBOX_MESSAGES.select);
59
+ const label = element.querySelector(`label[for="${select.id}"]`);
60
+ if (label == null) throw new Error(LISTBOX_MESSAGES.label);
61
+ element.id = select.id;
62
+ setAttribute(element, "name", select.name === "" ? select.id : select.name);
63
+ const disabled = getBooleanAriaValue(element, "disabled") || select.disabled;
64
+ const multiple = element.multiple || select.multiple;
65
+ const readonly = getBooleanAriaValue(element, "readonly");
66
+ const required = getBooleanAriaValue(element, "required") || select.required;
67
+ setAttributes(element, {
68
+ autocomplete: "none",
69
+ name: select.name === "" ? select.id : select.name
70
+ });
71
+ const id = getListboxId();
72
+ const labelId = label.id;
73
+ label.htmlFor = id;
74
+ label.id = `${id}_label`;
75
+ generateListboxIds(id, select);
76
+ const type = "select";
77
+ const content = createListboxContent({
78
+ element,
79
+ id,
80
+ label,
81
+ multiple,
82
+ select,
83
+ type,
84
+ attributes: LISTBOX_ATTRIBUTES,
85
+ autocomplete: listboxAutoComplete,
86
+ listbox: true
87
+ });
88
+ const { selected } = content.list.options;
89
+ const values = selected.length === 0 ? [""] : selected.map((option) => getData(option, "value", false) ?? "");
90
+ const state = {
91
+ disabled,
92
+ id,
93
+ internals,
94
+ message: content.message,
95
+ multiple,
96
+ readonly,
97
+ required,
98
+ select,
99
+ type,
100
+ active: selected[0],
101
+ attributes: LISTBOX_ATTRIBUTES,
102
+ autocomplete: listboxAutoComplete,
103
+ callbacks: listboxCallbacks,
104
+ content: content.element,
105
+ elements: [element, content.filter.element],
106
+ filter: {
107
+ element: content.filter.element,
108
+ value: ""
109
+ },
110
+ host: element,
111
+ label: {
112
+ id: labelId,
113
+ element: label
114
+ },
115
+ list: content.list.element,
116
+ listeners: [],
117
+ listbox: true,
118
+ localizations: {
119
+ component: {},
120
+ global: listboxLocalizations
121
+ },
122
+ name: element.name,
123
+ options: content.list.options,
124
+ values: {
125
+ current: values.slice(),
126
+ initial: values.slice(),
127
+ label: content.value
128
+ }
129
+ };
130
+ return initializeListboxState(state, listboxStates, onAttachListbox);
131
+ }
132
+ function onAttachListbox(state) {
133
+ const { content, select } = state;
134
+ select.hidden = true;
135
+ select.insertAdjacentElement("afterend", content);
136
+ select.remove();
137
+ }
138
+ function onDetachListbox(state) {
139
+ const { content, select } = state;
140
+ content.insertAdjacentElement("beforebegin", select);
141
+ content.remove();
142
+ select.hidden = false;
143
+ }
144
+ const listboxAutoComplete = {
145
+ both: false,
146
+ inline: false,
147
+ list: false,
148
+ none: true
149
+ };
150
+ const listboxCallbacks = {
151
+ data: {
152
+ onApply: noop,
153
+ onFilter: onListboxFilter,
154
+ onForm: noop,
155
+ onPreview: noop,
156
+ onToggle: onListboxToggle
157
+ },
158
+ keydown: {
159
+ onEnter: onListboxEnter,
160
+ onNavigation: onListboxNavigation,
161
+ onToggle: onListboxToggle
162
+ }
163
+ };
164
+ const listboxLocalizations = getLocalizations({
165
+ empty: "No results found",
166
+ input: "",
167
+ invalid: "Please select an option from the list",
168
+ max: (max) => `Please select fewer options (maximum is ${max})`,
169
+ min: (min) => `Please select more options (minimum is ${min})`,
170
+ remove: "",
171
+ results: (amount) => `${amount} results available`,
172
+ selected: (amount) => `${amount} selected`
173
+ });
174
+ const listboxStates = {
175
+ map: /* @__PURE__ */ new WeakMap(),
176
+ set: /* @__PURE__ */ new Set()
177
+ };
178
+ //#endregion
179
+ //#region src/js/listbox/misc.listbox.ts
180
+ function getListboxId() {
181
+ index += 1;
182
+ return `oui_listbox_${index}`;
183
+ }
184
+ function setListboxLocalizations(first, second) {
185
+ updateListboxLocalizations(listboxLocalizations, listboxLocalizations.values, first, second);
186
+ }
187
+ function updateListboxLocalizations(instance, destination, first, second) {
188
+ updateLocalizations(instance, typeof first === "string" ? { [first]: second } : first, destination, () => {
189
+ for (const state of listboxStates.set) {
190
+ updateListboxMessage(state);
191
+ updateListboxValueLabel(state);
192
+ }
193
+ });
194
+ }
195
+ let index = 0;
196
+ //#endregion
197
+ export { listboxLocalizations as a, onDetachListbox as c, onListboxNavigation as d, onListboxToggle as f, createListboxState as i, onListboxEnter as l, setListboxLocalizations as n, listboxStates as o, updateListboxLocalizations as r, onAttachListbox as s, getListboxId as t, onListboxFilter as u };
@@ -0,0 +1,20 @@
1
+ import { t as OuiLocalizations } from "./l10n-Bn-7RcwR.mjs";
2
+ import { o as OuiListboxLocalizations } from "./listbox.model-CRReGOmu.mjs";
3
+ //#region src/js/listbox/misc.listbox.d.ts
4
+ declare function getListboxId(): string;
5
+ /**
6
+ * Set listbox localizations for a specific language
7
+ *
8
+ * @param language Language code
9
+ * @param localizations Localizations for language
10
+ */
11
+ declare function setListboxLocalizations(language: string, localizations: Partial<OuiListboxLocalizations>): void;
12
+ /**
13
+ * Set listbox localizations for one or more languages
14
+ *
15
+ * @param localizations Localizations for one or more languages
16
+ */
17
+ declare function setListboxLocalizations(localizations: Record<string, Partial<OuiListboxLocalizations>>): void;
18
+ declare function updateListboxLocalizations(instance: OuiLocalizations<OuiListboxLocalizations>, destination: Record<string, Partial<OuiListboxLocalizations>>, first: string | Record<string, Partial<OuiListboxLocalizations>>, second?: Partial<OuiListboxLocalizations>): void;
19
+ //#endregion
20
+ export { setListboxLocalizations as n, updateListboxLocalizations as r, getListboxId as t };
@@ -110,14 +110,11 @@ function onEnd(event, globals, item, reset) {
110
110
  }
111
111
  const container = state.container?.getBoundingClientRect();
112
112
  if (container != null) setOffset(state, container);
113
- const dispatched = dispatch(state.element, "movable:end", { detail: {
113
+ if (dispatch(state.element, "oui:movable:end", { detail: {
114
114
  from: { ...globals.original },
115
115
  to: getEventPosition(event)
116
- } });
117
- setTimeout(() => {
118
- if (dispatched.defaultPrevented) onCancel(globals, item);
119
- reset();
120
- });
116
+ } }).defaultPrevented) onCancel(globals, item);
117
+ reset();
121
118
  }
122
119
  function onMove(_, globals, __, position) {
123
120
  setAttribute(globals.element?.node, ATTRIBUTE_MOVING, "");
@@ -49,7 +49,7 @@ function cancelResize(item) {
49
49
  width: `${item.state.width}px`
50
50
  });
51
51
  resetResizable();
52
- dispatch(item.state.element, "resizable:cancel");
52
+ dispatch(item.state.element, "oui:resizable:cancel");
53
53
  }
54
54
  /**
55
55
  * Creates _(or retrieves)_ a _OuiResizable_ instance for an element
@@ -130,14 +130,11 @@ function onPointerdown(event) {
130
130
  const position = getEventPosition(event);
131
131
  if (stored == null || position == null) return;
132
132
  if (supportsTouch.value) event.preventDefault();
133
- const dispatched = dispatch(element, "resizable:begin");
134
- setTimeout(() => {
135
- if (dispatched.defaultPrevented) return;
136
- current = stored;
137
- start = position;
138
- current.state.styles.set();
139
- styleToggler.set();
140
- });
133
+ if (dispatch(element, "oui:resizable:begin").defaultPrevented) return;
134
+ current = stored;
135
+ start = position;
136
+ current.state.styles.set();
137
+ styleToggler.set();
141
138
  }
142
139
  function onPointermove(event) {
143
140
  if (current == null) return;
@@ -149,27 +146,20 @@ function onPointermove(event) {
149
146
  height,
150
147
  width
151
148
  });
152
- const dispatched = dispatch(current.state.element, "resizable:resize", { detail: {
149
+ if (dispatch(current.state.element, "oui:resizable:resize", { detail: {
153
150
  height,
154
151
  width
155
- } });
156
- setTimeout(() => {
157
- if (dispatched.defaultPrevented) cancelResize(current);
158
- });
152
+ } }).defaultPrevented) cancelResize(current);
159
153
  }
160
154
  function onPointerup() {
161
- if (current == null) return;
162
- const dispatched = dispatch(current.state.element, "resizable:end");
163
- setTimeout(() => {
164
- if (current == null || dispatched.defaultPrevented) {
165
- cancelResize(current);
166
- return;
167
- }
168
- const { height, width } = current.state.element.getBoundingClientRect();
169
- current.state.height = height;
170
- current.state.width = width;
171
- resetResizable();
172
- });
155
+ if (current == null || dispatch(current.state.element, "oui:resizable:end").defaultPrevented) {
156
+ cancelResize(current);
157
+ return;
158
+ }
159
+ const { height, width } = current.state.element.getBoundingClientRect();
160
+ current.state.height = height;
161
+ current.state.width = width;
162
+ resetResizable();
173
163
  }
174
164
  function removeResizable(element) {
175
165
  items.get(element)?.instance.destroy();
@@ -98,8 +98,10 @@ function onEnd(event, globals, item, reset) {
98
98
  };
99
99
  const target = getElementFromPosition(position)[0];
100
100
  let element = findAncestor(target, SELECTOR_ITEM);
101
- if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (getAttribute(element, ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
102
- else element = element.nextElementSibling;
101
+ if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) {
102
+ if (getAttribute(element, ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
103
+ else element = element.nextElementSibling;
104
+ }
103
105
  let insert = "insert";
104
106
  let toInstance;
105
107
  let toState;
@@ -6,6 +6,7 @@ import { setStyle, toggleStyles } from "@oscarpalmer/toretto/style";
6
6
  import { clamp } from "@oscarpalmer/atoms/number";
7
7
  import { findAncestor } from "@oscarpalmer/toretto/find";
8
8
  import supportsTouch from "@oscarpalmer/toretto/touch";
9
+ import { createElement } from "@oscarpalmer/toretto/create";
9
10
  import { round } from "@oscarpalmer/atoms/math";
10
11
  //#region src/js/splitter.ts
11
12
  const ATTRIBUTE_MAX = "max";
@@ -135,21 +136,23 @@ var OuiSplitterElement = class extends HTMLElement {
135
136
  }
136
137
  };
137
138
  function createHandle() {
138
- const handle = document.createElement("span");
139
- setAria(handle, "hidden", "true");
140
- setAttribute(handle, ATTRIBUTE_HANDLE, "");
141
- return handle;
139
+ return createElement("span", {
140
+ aria: { hidden: true },
141
+ attribute: { [ATTRIBUTE_HANDLE]: "" }
142
+ });
142
143
  }
143
144
  function createSeparator(splitter) {
144
- const separator = document.createElement("div");
145
- separator.role = "separator";
146
- separator.tabIndex = 0;
147
- setAria(separator, {
148
- controls: splitter.element.id,
149
- label: "Resize panels"
145
+ return createElement("div", {
146
+ aria: {
147
+ controls: splitter.element.id,
148
+ label: "Resize panels"
149
+ },
150
+ attribute: { [ATTRIBUTE_SEPARATOR]: "" },
151
+ property: {
152
+ role: "separator",
153
+ tabIndex: 0
154
+ }
150
155
  });
151
- setAttribute(separator, ATTRIBUTE_SEPARATOR, "");
152
- return separator;
153
156
  }
154
157
  function getContained(min, value, max) {
155
158
  return round(clamp(value, min, max), VALUE_DECIMALS);