@odx/foundation 1.0.0-beta.99 → 1.0.0-rc.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 (170) hide show
  1. package/CHANGELOG.md +335 -0
  2. package/README.md +61 -29
  3. package/dist/lib/breakpoints.d.ts +61 -0
  4. package/dist/lib/breakpoints.js +139 -0
  5. package/dist/lib/format.d.ts +58 -0
  6. package/dist/lib/format.js +63 -0
  7. package/dist/lib/localization.d.ts +12 -0
  8. package/dist/lib/localization.js +28 -0
  9. package/dist/lib/models.d.ts +39 -0
  10. package/dist/lib/models.js +34 -0
  11. package/dist/lib/signals.d.ts +20 -0
  12. package/dist/lib/signals.js +47 -0
  13. package/dist/lib/theming.d.ts +18 -0
  14. package/dist/lib/theming.js +38 -0
  15. package/dist/lib/utils/breakpoint.d.ts +38 -0
  16. package/dist/lib/utils/breakpoint.js +103 -0
  17. package/dist/lib/utils/shared-media-observer.d.ts +4 -0
  18. package/dist/lib/utils/shared-media-observer.js +43 -0
  19. package/dist/main.d.ts +7 -0
  20. package/dist/main.js +5 -1227
  21. package/dist/oss-licenses.json +1 -0
  22. package/dist/styles.css +1 -1
  23. package/package.json +27 -50
  24. package/dist/_virtual_class-decorator-runtime.js +0 -13
  25. package/dist/components/accordion/accordion.d.ts +0 -25
  26. package/dist/components/accordion-item/accordion-item.d.ts +0 -26
  27. package/dist/components/accordion-panel/accordion-panel.d.ts +0 -13
  28. package/dist/components/action-button/action-button.d.ts +0 -27
  29. package/dist/components/anchor-navigation/anchor-navigation.d.ts +0 -21
  30. package/dist/components/anchor-navigation/anchor-observer.d.ts +0 -11
  31. package/dist/components/anchor-navigation/index.d.ts +0 -3
  32. package/dist/components/area-header/area-header.d.ts +0 -21
  33. package/dist/components/avatar/avatar.d.ts +0 -36
  34. package/dist/components/avatar-group/avatar-group.d.ts +0 -15
  35. package/dist/components/badge/badge.d.ts +0 -24
  36. package/dist/components/breadcrumbs/breadcrumbs-item.d.ts +0 -17
  37. package/dist/components/breadcrumbs/breadcrumbs.d.ts +0 -21
  38. package/dist/components/breadcrumbs/index.d.ts +0 -3
  39. package/dist/components/button/button.d.ts +0 -54
  40. package/dist/components/button-group/button-group.d.ts +0 -20
  41. package/dist/components/card/card.d.ts +0 -15
  42. package/dist/components/checkbox/checkbox.d.ts +0 -14
  43. package/dist/components/checkbox-group/checkbox-group.d.ts +0 -19
  44. package/dist/components/chip/chip.d.ts +0 -31
  45. package/dist/components/circular-progress-bar/circular-progress-bar.d.ts +0 -49
  46. package/dist/components/combobox/autocomplete.d.ts +0 -23
  47. package/dist/components/content-box/content-box.d.ts +0 -11
  48. package/dist/components/dropdown/dropdown.d.ts +0 -25
  49. package/dist/components/form-field/form-field.d.ts +0 -16
  50. package/dist/components/format/base-format.d.ts +0 -13
  51. package/dist/components/format/format-bytes.d.ts +0 -13
  52. package/dist/components/format/format-date.d.ts +0 -14
  53. package/dist/components/format/format-number.d.ts +0 -20
  54. package/dist/components/format/index.d.ts +0 -6
  55. package/dist/components/format/relative-time.d.ts +0 -21
  56. package/dist/components/header/header-actions.d.ts +0 -10
  57. package/dist/components/header/header.d.ts +0 -14
  58. package/dist/components/header/index.d.ts +0 -3
  59. package/dist/components/headline/headline.d.ts +0 -22
  60. package/dist/components/highlight/highlight.d.ts +0 -23
  61. package/dist/components/icon-button/icon-button.d.ts +0 -14
  62. package/dist/components/image/image.d.ts +0 -34
  63. package/dist/components/inline-message/inline-message.d.ts +0 -28
  64. package/dist/components/input/input.d.ts +0 -27
  65. package/dist/components/kpi/kpi.d.ts +0 -36
  66. package/dist/components/line-clamp/line-clamp.d.ts +0 -12
  67. package/dist/components/link/link.d.ts +0 -11
  68. package/dist/components/list/list.d.ts +0 -15
  69. package/dist/components/list-item/list-item.d.ts +0 -26
  70. package/dist/components/loader.d.ts +0 -2
  71. package/dist/components/loading-overlay/loading-overlay.d.ts +0 -20
  72. package/dist/components/loading-spinner/loading-spinner.d.ts +0 -12
  73. package/dist/components/logo/logo.d.ts +0 -21
  74. package/dist/components/main-menu/index.d.ts +0 -6
  75. package/dist/components/main-menu/main-menu-button.d.ts +0 -12
  76. package/dist/components/main-menu/main-menu-link.d.ts +0 -9
  77. package/dist/components/main-menu/main-menu-subtitle.d.ts +0 -12
  78. package/dist/components/main-menu/main-menu-title.d.ts +0 -12
  79. package/dist/components/main-menu/main-menu.d.ts +0 -17
  80. package/dist/components/main.d.ts +0 -72
  81. package/dist/components/menu/index.d.ts +0 -3
  82. package/dist/components/menu/menu-label.d.ts +0 -9
  83. package/dist/components/menu/menu.d.ts +0 -21
  84. package/dist/components/menu-item/menu-item.d.ts +0 -14
  85. package/dist/components/modal/modal.d.ts +0 -37
  86. package/dist/components/navigation-item/navigation-item.d.ts +0 -22
  87. package/dist/components/option/option.d.ts +0 -11
  88. package/dist/components/page/page.d.ts +0 -27
  89. package/dist/components/page-layout/page-layout.d.ts +0 -11
  90. package/dist/components/pagination/pagination.d.ts +0 -32
  91. package/dist/components/popover/popover-host.d.ts +0 -35
  92. package/dist/components/popover/popover-observer.d.ts +0 -11
  93. package/dist/components/popover/popover.d.ts +0 -13
  94. package/dist/components/progress-bar/progress-bar.d.ts +0 -30
  95. package/dist/components/radio-button/radio-button.d.ts +0 -13
  96. package/dist/components/radio-group/radio-group.d.ts +0 -16
  97. package/dist/components/rail-navigation/rail-navigation.d.ts +0 -19
  98. package/dist/components/search-bar/index.d.ts +0 -3
  99. package/dist/components/search-bar/search-bar.d.ts +0 -33
  100. package/dist/components/search-bar/search-bar.events.d.ts +0 -7
  101. package/dist/components/select/select.d.ts +0 -26
  102. package/dist/components/separator/separator.d.ts +0 -21
  103. package/dist/components/skeleton/skeleton.d.ts +0 -31
  104. package/dist/components/slider/index.d.ts +0 -5
  105. package/dist/components/slider/slider-handle.d.ts +0 -28
  106. package/dist/components/slider/slider-marks.d.ts +0 -16
  107. package/dist/components/slider/slider.d.ts +0 -26
  108. package/dist/components/slider/slider.models.d.ts +0 -29
  109. package/dist/components/spacer/spacer.d.ts +0 -13
  110. package/dist/components/spinbox/spinbox.d.ts +0 -23
  111. package/dist/components/stack/stack.d.ts +0 -38
  112. package/dist/components/status/status.d.ts +0 -23
  113. package/dist/components/switch/switch.d.ts +0 -12
  114. package/dist/components/table/index.d.ts +0 -9
  115. package/dist/components/table/table-body.d.ts +0 -12
  116. package/dist/components/table/table-cell.d.ts +0 -12
  117. package/dist/components/table/table-checkbox-cell.d.ts +0 -19
  118. package/dist/components/table/table-header-cell.d.ts +0 -13
  119. package/dist/components/table/table-header.d.ts +0 -14
  120. package/dist/components/table/table-row.d.ts +0 -20
  121. package/dist/components/table/table.d.ts +0 -20
  122. package/dist/components/table/table.models.d.ts +0 -10
  123. package/dist/components/text/text.d.ts +0 -33
  124. package/dist/components/title/title.d.ts +0 -22
  125. package/dist/components/toast/toast.d.ts +0 -24
  126. package/dist/components/toggle-button/toggle-button.d.ts +0 -13
  127. package/dist/components/toggle-button-group/toggle-button-group.d.ts +0 -10
  128. package/dist/components/toggle-content/toggle-content.d.ts +0 -12
  129. package/dist/components/tooltip/tooltip.d.ts +0 -37
  130. package/dist/components/translate/translate.d.ts +0 -16
  131. package/dist/components/visually-hidden/visually-hidden.d.ts +0 -11
  132. package/dist/components.js +0 -4493
  133. package/dist/i18n/config.d.ts +0 -32
  134. package/dist/i18n/format.d.ts +0 -6
  135. package/dist/i18n/is-localized.d.ts +0 -15
  136. package/dist/i18n/localization.d.ts +0 -5
  137. package/dist/i18n/main.d.ts +0 -7
  138. package/dist/i18n/models.d.ts +0 -7
  139. package/dist/i18n/translate.d.ts +0 -11
  140. package/dist/i18n.js +0 -145
  141. package/dist/lib/control/checkbox-form-control.d.ts +0 -16
  142. package/dist/lib/control/checkbox-group-form-control.d.ts +0 -23
  143. package/dist/lib/control/form-control.d.ts +0 -30
  144. package/dist/lib/control/listbox-form-control.d.ts +0 -26
  145. package/dist/lib/control/number-form-control.d.ts +0 -13
  146. package/dist/lib/control/option-control.d.ts +0 -24
  147. package/dist/lib/control/radio-group-form-control.d.ts +0 -22
  148. package/dist/lib/controllers/active-descendants-controller.d.ts +0 -29
  149. package/dist/lib/controllers/drag.controller.d.ts +0 -19
  150. package/dist/lib/controllers/expandable-controller.d.ts +0 -17
  151. package/dist/lib/custom-element.d.ts +0 -16
  152. package/dist/lib/interactive/interactive-element.d.ts +0 -23
  153. package/dist/lib/interactive/interactive-link.d.ts +0 -21
  154. package/dist/lib/main.d.ts +0 -28
  155. package/dist/lib/mixins/can-be-disabled.d.ts +0 -7
  156. package/dist/lib/mixins/can-be-expanded.d.ts +0 -10
  157. package/dist/lib/mixins/is-draggable.d.ts +0 -16
  158. package/dist/lib/models/drag-event.d.ts +0 -9
  159. package/dist/lib/models/placement.d.ts +0 -17
  160. package/dist/lib/models/shape.d.ts +0 -7
  161. package/dist/lib/models/size.d.ts +0 -11
  162. package/dist/lib/models/variant.d.ts +0 -12
  163. package/dist/lib/utils/compute-popover-placement.d.ts +0 -14
  164. package/dist/lib/utils/dom.d.ts +0 -27
  165. package/dist/lib/utils/get-unique-id.d.ts +0 -19
  166. package/dist/lib/utils/lit.d.ts +0 -4
  167. package/dist/lib/utils/shared-resize-observer.d.ts +0 -11
  168. package/dist/lib/utils/types.d.ts +0 -60
  169. package/dist/loader.js +0 -7
  170. package/dist/vendor.js +0 -1982
package/dist/main.js CHANGED
@@ -1,1227 +1,5 @@
1
- import { _ as __decorateClass } from './_virtual_class-decorator-runtime.js';
2
- import { unsafeCSS, LitElement, html, isServer, nothing } from 'lit';
3
- import { property, queryAssignedElements, query } from 'lit/decorators.js';
4
- import { u as uniqBy, r as round, R as RovingTabindexController, m as minBy, c as computePosition, a as autoUpdate, t as throttle, o as offset, s as shift, f as flip, b as size, d as arrow, h as hide } from './vendor.js';
5
-
6
- const customElementStyles = "@layer reset,base,variant,state;@layer reset{:is(*){box-sizing:border-box;scrollbar-width:thin}:not(:defined){display:none}:before,:after{box-sizing:border-box}[popover]{outline:none;border:none}img,picture,video,canvas,svg{display:block;margin:0;max-width:100%}input,button,textarea,select{margin:0;font:inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap:break-word;margin:0}p{text-wrap:pretty}h1,h2,h3,h4,h5,h6{text-wrap:balance}}@layer base{odx-icon{transition:var(--odx-transition-default);transition-property:transform}[odxPreventTextOverflow]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}odx-list-item:has(:is([odx-button],odx-list-item::part(control)):not([disabled]):active){--_color-background-pressed: var(--_color-background-hover)}[odx-button]:has(odx-icon:only-child),[odx-button]:has(odx-avatar:only-child){--_min-inline-size: 0}odx-accordion[indicator-position=start]{odx-accordion-item::part(indicator){--rotate: -90deg;order:-1}odx-accordion-item[expanded]::part(indicator){--rotate: 0}}odx-input:has([slot=suffix])::part(base){padding-inline-end:var(--odx-size-px)}}@layer reset{:host{outline:none;border:none;border-color:transparent}}";
7
-
8
- function customElement(tagName, ...styles) {
9
- return (target) => {
10
- const mergedStyles = [customElementStyles, target.styles, ...styles].flatMap((styles2) => {
11
- return typeof styles2 === "string" ? unsafeCSS(styles2) : styles2 || [];
12
- });
13
- target.styles = uniqBy(mergedStyles, String);
14
- target.tagName = tagName;
15
- target.define = () => {
16
- if (customElements.get(tagName)) return;
17
- customElements.define(tagName, target);
18
- };
19
- };
20
- }
21
- class CustomElement extends LitElement {
22
- render() {
23
- return html`<slot></slot>`;
24
- }
25
- /** @internal */
26
- emit(event, eventInit) {
27
- if (typeof event === "string") {
28
- return !this.dispatchEvent(new CustomEvent(event, { bubbles: false, composed: false, cancelable: true, ...eventInit }));
29
- }
30
- return !this.dispatchEvent(event);
31
- }
32
- }
33
-
34
- function parseDate(value) {
35
- const date = new Date(value);
36
- if (Number.isNaN(date.getTime()) && typeof value === "string") {
37
- return Number.isNaN(Number(value)) ? null : new Date(Number(value));
38
- }
39
- return Number.isNaN(date.getTime()) ? null : date;
40
- }
41
- function findClosestDocument(node) {
42
- let parent = node.parentNode;
43
- while (parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && parent.nodeType !== Node.DOCUMENT_NODE) {
44
- parent = parent.parentNode;
45
- }
46
- return parent ?? document;
47
- }
48
- function forwardEvent(target, eventInit) {
49
- return (event) => {
50
- event.stopPropagation();
51
- const shouldPreventDefault = target.dispatchEvent(
52
- new CustomEvent(event.type, { bubbles: event.bubbles, composed: event.composed, cancelable: event.cancelable, ...eventInit })
53
- );
54
- if (shouldPreventDefault) return;
55
- event.preventDefault();
56
- };
57
- }
58
- function getElementFromEvent(event, filterFn) {
59
- return event.composedPath().find((node) => node instanceof Element && filterFn(node));
60
- }
61
- async function waitForAnimations(element, subtree = false) {
62
- if (!element || typeof element.getAnimations !== "function") {
63
- return [];
64
- }
65
- return await Promise.all(element.getAnimations({ subtree }).map((animation) => animation.finished)).catch(() => []);
66
- }
67
- function toAriaBooleanAttribute(value, removeOnFalse = true) {
68
- return removeOnFalse && value === false ? null : String(value);
69
- }
70
- function toPx(value) {
71
- if (value == null || Number.isNaN(value)) return null;
72
- return `${round(value, 2)}px`;
73
- }
74
- function getAssignedElement(root, options) {
75
- const { slot, selector } = options ?? {};
76
- const slotSelector = `slot${slot ? `[name=${slot}]` : ":not([name])"}`;
77
- const slotEl = root?.querySelector(slotSelector);
78
- const elements = slotEl?.assignedElements(options) ?? [];
79
- if (selector == null) {
80
- return elements[0];
81
- }
82
- return elements.find((node) => node.matches(selector));
83
- }
84
- function getKeyInfo(event) {
85
- const { code, shiftKey } = event;
86
- return {
87
- up: code === "ArrowUp",
88
- right: code === "ArrowRight",
89
- down: code === "ArrowDown",
90
- left: code === "ArrowLeft",
91
- enter: code === "Enter",
92
- escape: code === "Escape",
93
- space: code === "Space",
94
- tab: !shiftKey && code === "Tab",
95
- backTab: shiftKey && code === "Tab",
96
- start: code === "Home",
97
- end: code === "End"
98
- };
99
- }
100
-
101
- const CanBeDisabled = (superClass) => {
102
- class CanBeDisabledMixin extends superClass {
103
- constructor() {
104
- super(...arguments);
105
- this.disabled = false;
106
- }
107
- #initialTabIndex;
108
- connectedCallback() {
109
- super.connectedCallback();
110
- this.#initialTabIndex = this.hasAttribute("tabindex") ? this.tabIndex : void 0;
111
- }
112
- willUpdate(props) {
113
- super.willUpdate(props);
114
- if (props.has("disabled")) {
115
- this.#handleDisabledChange();
116
- }
117
- }
118
- #handleDisabledChange() {
119
- this.ariaDisabled = toAriaBooleanAttribute(this.disabled);
120
- if (this.disabled) {
121
- this.tabIndex = -1;
122
- } else if (this.#initialTabIndex === void 0) {
123
- this.removeAttribute("tabindex");
124
- } else {
125
- this.tabIndex = this.#initialTabIndex;
126
- }
127
- }
128
- }
129
- __decorateClass([
130
- property({ type: Boolean, reflect: true, useDefault: true })
131
- ], CanBeDisabledMixin.prototype, "disabled", 2);
132
- return CanBeDisabledMixin;
133
- };
134
-
135
- class FormControl extends CanBeDisabled(CustomElement) {
136
- constructor() {
137
- super();
138
- this.name = "";
139
- this.value = "";
140
- this.readonly = false;
141
- this.required = false;
142
- this.internals = this.attachInternals();
143
- }
144
- static {
145
- /** @internal */
146
- this.formAssociated = true;
147
- }
148
- static {
149
- /** @internal */
150
- this.shadowRootOptions = {
151
- ...CustomElement.shadowRootOptions,
152
- delegatesFocus: true
153
- };
154
- }
155
- get form() {
156
- return this.internals.form;
157
- }
158
- get validity() {
159
- return this.internals.validity;
160
- }
161
- get validationMessage() {
162
- return this.internals.validationMessage;
163
- }
164
- get willValidate() {
165
- return this.internals.willValidate;
166
- }
167
- toFormValue() {
168
- return this.value ? String(this.value) : null;
169
- }
170
- checkValidity() {
171
- return this.internals.checkValidity();
172
- }
173
- setValidity(flags, target = this) {
174
- const errorKey = Object.keys(flags ?? {}).find((key) => flags?.[key] === true);
175
- this.internals.setValidity(flags, errorKey ?? "unknown error", target);
176
- }
177
- reportValidity() {
178
- this.internals.reportValidity();
179
- }
180
- clear() {
181
- this.value = "";
182
- }
183
- willUpdate(props) {
184
- super.willUpdate(props);
185
- if (props.has("required")) {
186
- this.ariaRequired = toAriaBooleanAttribute(this.required);
187
- }
188
- if (props.has("readonly")) {
189
- this.ariaReadOnly = toAriaBooleanAttribute(this.readonly);
190
- }
191
- if (props.has("value")) {
192
- this.internals.setFormValue(this.toFormValue());
193
- }
194
- this.updateAriaAttributes?.();
195
- }
196
- }
197
- __decorateClass([
198
- property()
199
- ], FormControl.prototype, "name", 2);
200
- __decorateClass([
201
- property({ type: Boolean, reflect: true, useDefault: true })
202
- ], FormControl.prototype, "readonly", 2);
203
- __decorateClass([
204
- property({ type: Boolean, reflect: true, useDefault: true })
205
- ], FormControl.prototype, "required", 2);
206
-
207
- const LINK_SELECTORS = /* @__PURE__ */ new Set(["a", "button", "odx-link"]);
208
- class CheckboxFormControl extends FormControl {
209
- constructor() {
210
- super();
211
- this.role = null;
212
- this.checked = false;
213
- this.value = "";
214
- this.#handleClick = ({ target }) => {
215
- if (LINK_SELECTORS.has(target.localName)) return;
216
- this.toggle(void 0, true);
217
- };
218
- this.#handleKeyboardEvent = (event) => {
219
- const key = getKeyInfo(event);
220
- if (!(key.enter || key.space)) return;
221
- event.preventDefault();
222
- if (event.type === "keydown" || LINK_SELECTORS.has(event.target.localName)) return;
223
- this.toggle(void 0, true);
224
- };
225
- if (!isServer) {
226
- this.addEventListener("click", this.#handleClick);
227
- this.addEventListener("keydown", this.#handleKeyboardEvent);
228
- this.addEventListener("keyup", this.#handleKeyboardEvent);
229
- }
230
- }
231
- static {
232
- /** @internal */
233
- this.shadowRootOptions = {
234
- ...CustomElement.shadowRootOptions,
235
- delegatesFocus: false
236
- };
237
- }
238
- toFormValue() {
239
- if (this.value) {
240
- return this.checked ? this.value : null;
241
- }
242
- return this.checked ? "on" : null;
243
- }
244
- clear() {
245
- this.checked = false;
246
- }
247
- toggle(state, emitEvent = false) {
248
- const currentState = this.checked;
249
- const newState = state ?? !currentState;
250
- if (this.disabled || this.readonly || newState === currentState) return;
251
- this.checked = newState;
252
- if (!(emitEvent && this.emit("change", { bubbles: true }))) return;
253
- this.checked = currentState;
254
- }
255
- connectedCallback() {
256
- this.tabIndex = 0;
257
- super.connectedCallback();
258
- this.role ||= "checkbox";
259
- }
260
- updateAriaAttributes() {
261
- super.updateAriaAttributes?.();
262
- this.ariaChecked = toAriaBooleanAttribute(this.checked, false);
263
- }
264
- #handleClick;
265
- #handleKeyboardEvent;
266
- }
267
- __decorateClass([
268
- property({ type: Boolean, reflect: true, useDefault: true })
269
- ], CheckboxFormControl.prototype, "checked", 2);
270
- __decorateClass([
271
- property()
272
- ], CheckboxFormControl.prototype, "value", 2);
273
-
274
- const GROUP_CONTROL_SELECTOR = "odx-checkbox-group-control";
275
- const _CheckboxGroupFormControl = class _CheckboxGroupFormControl extends FormControl {
276
- constructor() {
277
- super();
278
- this.value = [];
279
- this.#handleChangeEvent = (event) => {
280
- if (this.isControl(event.target)) {
281
- this.#handleControlChange(event);
282
- }
283
- };
284
- this.#handleControlChange = (event) => {
285
- if (!this.isControl(event.target)) return;
286
- if (event.target.checked) {
287
- this.updateValue([...this.value, event.target.value], true);
288
- } else {
289
- this.updateValue(
290
- this.value.filter((value) => value !== event.target.value),
291
- true
292
- );
293
- }
294
- };
295
- if (!isServer) {
296
- this.addEventListener("change", this.#handleChangeEvent);
297
- }
298
- }
299
- get childGroups() {
300
- return this.elements.filter((element) => element instanceof _CheckboxGroupFormControl);
301
- }
302
- get controls() {
303
- return this.#findControls((element) => !element.hasAttribute(GROUP_CONTROL_SELECTOR)).concat(this.childGroups.flatMap((group) => group.controls));
304
- }
305
- get selectedControls() {
306
- return this.controls.filter((control) => this.isControlChecked(control));
307
- }
308
- get groupControl() {
309
- return this.#findControls((element) => element.hasAttribute(GROUP_CONTROL_SELECTOR))[0] ?? null;
310
- }
311
- clear() {
312
- this.value = [];
313
- }
314
- toFormValue() {
315
- const formData = new FormData();
316
- this.value.forEach((value, index) => {
317
- formData.append(`${this.name}[${index}]`, value);
318
- });
319
- return formData;
320
- }
321
- isControl(element) {
322
- return element instanceof CheckboxFormControl;
323
- }
324
- isGroupControl(element) {
325
- return this.isControl(element) && element.hasAttribute(GROUP_CONTROL_SELECTOR);
326
- }
327
- isControlChecked(control) {
328
- return this.value.includes(control.value);
329
- }
330
- async firstUpdated(_changedProperties) {
331
- await 0;
332
- this.value = this.controls.filter((control) => control.checked).map((control) => control.value);
333
- }
334
- updated(props) {
335
- super.updated(props);
336
- if (props.has("value")) {
337
- this.updateControls((control) => {
338
- control.checked = this.isControlChecked(control);
339
- });
340
- if (this.groupControl) {
341
- this.groupControl.checked = this.controls.length > 0 && this.value.length === this.controls.length;
342
- if ("indeterminate" in this.groupControl) {
343
- this.groupControl.indeterminate = this.value.length > 0 && this.value.length < this.controls.length;
344
- }
345
- }
346
- }
347
- if (props.has("name")) {
348
- this.updateControls((control) => {
349
- control.name = this.name;
350
- });
351
- }
352
- if (props.has("disabled")) {
353
- if (this.groupControl) {
354
- this.groupControl.disabled = this.disabled;
355
- }
356
- this.updateControls((control) => {
357
- control.disabled = this.disabled;
358
- });
359
- }
360
- if (props.has("readonly")) {
361
- if (this.groupControl) {
362
- this.groupControl.readonly = this.disabled;
363
- }
364
- this.updateControls((control) => {
365
- control.readonly = this.readonly;
366
- });
367
- }
368
- }
369
- updateControls(updateFn) {
370
- this.controls.forEach(updateFn);
371
- }
372
- updateValue(value, dispatchEvent) {
373
- this.value = value;
374
- for (const group of this.childGroups) {
375
- const groupValue = this.value.filter((value2) => group.controls.some((control) => control.value === value2));
376
- group.updateValue(groupValue, false);
377
- }
378
- if (!dispatchEvent) return;
379
- this.emit("change", { bubbles: true });
380
- }
381
- #findControls(predicate) {
382
- return this.elements.filter((element) => this.isControl(element) && predicate(element));
383
- }
384
- #handleChangeEvent;
385
- #handleControlChange;
386
- };
387
- __decorateClass([
388
- queryAssignedElements({ flatten: true })
389
- ], _CheckboxGroupFormControl.prototype, "elements", 2);
390
- __decorateClass([
391
- property({ type: Array })
392
- ], _CheckboxGroupFormControl.prototype, "value", 2);
393
- let CheckboxGroupFormControl = _CheckboxGroupFormControl;
394
-
395
- const ActiveDescendantsControllerOptions = (options) => ({
396
- getItems: () => [],
397
- ...options
398
- });
399
- class ActiveDescendantsController {
400
- #host;
401
- #options;
402
- #activeIndex = -1;
403
- get activeIndex() {
404
- return this.#activeIndex;
405
- }
406
- get activeItem() {
407
- return this.items[this.#activeIndex];
408
- }
409
- get items() {
410
- return this.#options.getItems().filter((item) => item.isConnected);
411
- }
412
- constructor(host, options) {
413
- this.#host = host;
414
- this.#options = ActiveDescendantsControllerOptions(options);
415
- host.addController(this);
416
- }
417
- activate(initialActiveIndex) {
418
- if (initialActiveIndex === void 0) {
419
- this.first();
420
- } else {
421
- this.update(initialActiveIndex);
422
- }
423
- this.#host.addEventListener("keydown", this.#handleKeyboardEvent);
424
- }
425
- deactivate() {
426
- this.#host.removeEventListener("keydown", this.#handleKeyboardEvent);
427
- this.update();
428
- }
429
- previous() {
430
- const index = this.items.findLastIndex((item, index2) => item.canActivate() && this.#activeIndex > index2);
431
- this.update(index);
432
- }
433
- next() {
434
- const index = this.items.findIndex((item, index2) => item.canActivate() && this.#activeIndex < index2);
435
- this.update(index);
436
- }
437
- first() {
438
- this.update(this.items.findIndex((item) => item.canActivate()));
439
- }
440
- last() {
441
- this.update(this.items.findLastIndex((item) => item.canActivate()));
442
- }
443
- select(item) {
444
- const index = this.items.indexOf(item);
445
- if (index === -1 || !item.canActivate()) return;
446
- this.update(index);
447
- }
448
- update(index, force = false) {
449
- const previousActiveItem = this.items[this.#activeIndex];
450
- const activeItem = this.items[index ?? this.#activeIndex];
451
- if (force !== false || !activeItem?.canActivate()) return;
452
- this.#activeIndex = index ?? this.#activeIndex;
453
- this.#host.setAttribute("aria-activedescendant", activeItem?.id ?? "");
454
- previousActiveItem?.deactivate();
455
- activeItem?.activate();
456
- this.#options.onChange?.(previousActiveItem, activeItem, previousActiveItem === void 0 && !!activeItem);
457
- }
458
- #handleKeyboardEvent = (event) => {
459
- const key = getKeyInfo(event);
460
- if (!(key.up || key.down || key.start || key.end)) return;
461
- event.preventDefault();
462
- if (key.down) {
463
- this.next();
464
- } else if (key.up) {
465
- this.previous();
466
- } else if (key.start) {
467
- this.first();
468
- } else if (key.end) {
469
- this.last();
470
- }
471
- };
472
- }
473
-
474
- let uniqueIdCounter = 0;
475
- function getUniqueId(prefix) {
476
- return `${prefix}-${uniqueIdCounter++}`;
477
- }
478
-
479
- class OptionControl extends CanBeDisabled(CustomElement) {
480
- constructor() {
481
- super(...arguments);
482
- this.role = null;
483
- this.value = "";
484
- this.selected = false;
485
- this.readonly = false;
486
- }
487
- #label;
488
- set label(value) {
489
- this.#label = value;
490
- }
491
- get label() {
492
- return (this.#label || this.textContent?.trim()) ?? "";
493
- }
494
- canActivate() {
495
- return !(this.disabled || this.hidden);
496
- }
497
- canSelect() {
498
- return this.canActivate();
499
- }
500
- isActive() {
501
- return this.hasAttribute("odx-active") && !this.canActivate();
502
- }
503
- activate() {
504
- if (!this.canActivate()) return;
505
- this.toggleAttribute("odx-active", true);
506
- }
507
- deactivate() {
508
- this.toggleAttribute("odx-active", false);
509
- }
510
- connectedCallback() {
511
- super.connectedCallback();
512
- this.role ||= "option";
513
- this.id ||= getUniqueId(this.localName);
514
- }
515
- willUpdate(props) {
516
- super.willUpdate(props);
517
- if (props.has("selected")) {
518
- this.ariaSelected = this.canSelect() ? toAriaBooleanAttribute(this.selected, false) : null;
519
- }
520
- }
521
- }
522
- __decorateClass([
523
- property({ type: String })
524
- ], OptionControl.prototype, "label", 1);
525
- __decorateClass([
526
- property()
527
- ], OptionControl.prototype, "value", 2);
528
- __decorateClass([
529
- property({ type: Boolean, reflect: true, useDefault: true })
530
- ], OptionControl.prototype, "selected", 2);
531
- __decorateClass([
532
- property({ type: Boolean, reflect: true, useDefault: true })
533
- ], OptionControl.prototype, "readonly", 2);
534
- __decorateClass([
535
- property()
536
- ], OptionControl.prototype, "type", 2);
537
-
538
- class ListboxFormControl extends FormControl {
539
- constructor() {
540
- super();
541
- this.activeDescendants = new ActiveDescendantsController(this, {
542
- getItems: () => this.options,
543
- onChange: (_, option) => {
544
- option?.scrollIntoView();
545
- if (!(option && this.canAutoSelect(option)) || option.selected) return;
546
- this.toggleOption(option, true);
547
- }
548
- });
549
- this.autoSelect = false;
550
- this.multiple = false;
551
- this.placeholder = "";
552
- this.value = "";
553
- this.#handleBlur = (_event) => {
554
- this.activeDescendants.deactivate();
555
- };
556
- this.#handleClick = (event) => {
557
- const option = getElementFromEvent(event, (node) => node instanceof OptionControl);
558
- if (!option) return;
559
- this.toggleOption(option);
560
- this.#handleOptionSelection(option);
561
- };
562
- this.#handleFocus = (_event) => {
563
- this.activeDescendants.activate(this.selectedIndices[0]);
564
- };
565
- this.#handleKeydown = (event) => {
566
- if (event.target !== this) return;
567
- const activeOption = this.activeDescendants.activeItem;
568
- if (!activeOption) return;
569
- const key = getKeyInfo(event);
570
- if (!(key.enter || key.space)) return;
571
- if (this.multiple) {
572
- event.stopPropagation();
573
- event.stopImmediatePropagation();
574
- }
575
- this.toggleOption(activeOption);
576
- this.#handleOptionSelection(activeOption);
577
- };
578
- if (!isServer) {
579
- this.addEventListener("focusout", this.#handleBlur);
580
- this.addEventListener("focusin", this.#handleFocus);
581
- this.addEventListener("click", this.#handleClick);
582
- this.addEventListener("keydown", this.#handleKeydown);
583
- }
584
- }
585
- get selectedOptions() {
586
- return this.options.filter((option) => option.selected);
587
- }
588
- get selectedIndices() {
589
- return this.selectedOptions.map((option) => this.options.indexOf(option));
590
- }
591
- canAutoSelect(option) {
592
- return this.autoSelect && !this.multiple && this.canSelect(option);
593
- }
594
- canSelect(option) {
595
- return option.canSelect();
596
- }
597
- toggleOption(option, state) {
598
- if (!this.canSelect(option)) return;
599
- const newState = state ?? (this.required && !this.multiple || !option.selected);
600
- if (this.disabled || this.readonly) return;
601
- option.selected = newState;
602
- this.updateValue(option);
603
- if (newState) {
604
- option.scrollIntoView();
605
- }
606
- }
607
- clear() {
608
- this.value = this.multiple ? [] : "";
609
- }
610
- connectedCallback() {
611
- super.connectedCallback();
612
- this.role ||= "listbox";
613
- this.id ||= getUniqueId(this.localName);
614
- }
615
- handleSlotChange() {
616
- this.value ||= this.multiple ? this.selectedOptions.map((option) => option.value) : this.selectedOptions[0]?.value ?? "";
617
- this.requestUpdate("value");
618
- }
619
- updateValue(option) {
620
- const oldValue = this.value;
621
- if (this.multiple) {
622
- const value = typeof this.value === "string" ? [this.value].filter(Boolean) : this.value;
623
- this.value = option?.selected ? [...value, option.value] : value.filter((value2) => value2 !== option?.value);
624
- } else {
625
- this.value = option?.selected ? option.value : "";
626
- }
627
- if (option) {
628
- this.activeDescendants.select(option);
629
- }
630
- if (oldValue === this.value) return;
631
- this.requestUpdate();
632
- this.emit("change");
633
- }
634
- willUpdate(props) {
635
- super.willUpdate(props);
636
- if (props.has("value")) {
637
- this.updateOptions((option) => {
638
- if (!option.canSelect()) return;
639
- option.selected = this.multiple ? this.value.includes(option.value) : this.value === option.value;
640
- });
641
- }
642
- if (props.has("multiple")) {
643
- this.#handleMultipleChange();
644
- }
645
- if (props.has("required") || props.has("value")) {
646
- if (!this.selectedOptions[0]?.selected) return;
647
- this.setValidity({ valueMissing: this.required && this.value.length === 0 }, this.selectedOptions[0]);
648
- }
649
- }
650
- updateOptions(updateFn) {
651
- for (const option of this.options ?? []) {
652
- updateFn(option);
653
- }
654
- }
655
- #handleOptionSelection(option) {
656
- if (!option.selected) return;
657
- this.emit("select", { detail: option });
658
- }
659
- #handleMultipleChange() {
660
- const optionType = this.multiple ? "checkbox" : null;
661
- this.updateOptions((option) => {
662
- option.type = optionType;
663
- });
664
- if (!this.multiple && this.selectedOptions[0]) {
665
- this.updateValue(this.selectedOptions[0]);
666
- }
667
- }
668
- #handleBlur;
669
- #handleClick;
670
- #handleFocus;
671
- #handleKeydown;
672
- }
673
- __decorateClass([
674
- property({ type: Boolean, attribute: "auto-select" })
675
- ], ListboxFormControl.prototype, "autoSelect", 2);
676
- __decorateClass([
677
- property({ type: Boolean, reflect: true, useDefault: true })
678
- ], ListboxFormControl.prototype, "multiple", 2);
679
- __decorateClass([
680
- property()
681
- ], ListboxFormControl.prototype, "placeholder", 2);
682
- __decorateClass([
683
- property()
684
- ], ListboxFormControl.prototype, "value", 2);
685
-
686
- const MIN_STEP_VALUE = 1 / 2 ^ 16;
687
- class NumberFormControl extends FormControl {
688
- constructor() {
689
- super(...arguments);
690
- this.min = 0;
691
- this.max = 100;
692
- this.step = 1;
693
- this.value = 0;
694
- }
695
- clear() {
696
- this.value = 0;
697
- }
698
- getValueText() {
699
- return this.ariaValueText?.trim() ?? "";
700
- }
701
- willUpdate(props) {
702
- if (props.has("value")) {
703
- this.internals.ariaValueNow = String(this.value);
704
- this.internals.ariaValueText = this.getValueText();
705
- }
706
- if (props.has("min")) {
707
- this.internals.ariaValueMin = String(this.min);
708
- }
709
- if (props.has("max")) {
710
- this.internals.ariaValueMax = String(this.max);
711
- }
712
- if (props.has("step")) {
713
- this.step = Math.max(MIN_STEP_VALUE, this.step);
714
- }
715
- this.value = Math.max(this.min, Math.min(this.value, this.max));
716
- super.willUpdate(props);
717
- }
718
- toFormValue() {
719
- return String(this.value);
720
- }
721
- }
722
- __decorateClass([
723
- property({ type: Number })
724
- ], NumberFormControl.prototype, "min", 2);
725
- __decorateClass([
726
- property({ type: Number })
727
- ], NumberFormControl.prototype, "max", 2);
728
- __decorateClass([
729
- property({ type: Number })
730
- ], NumberFormControl.prototype, "step", 2);
731
- __decorateClass([
732
- property({ type: Number })
733
- ], NumberFormControl.prototype, "value", 2);
734
-
735
- class RadioGroupFormControl extends FormControl {
736
- constructor() {
737
- super();
738
- this.value = "";
739
- this.#handleChange = ({ target }) => {
740
- if (!this.isControl(target) || this.value === target.value) return;
741
- this.value = target.value;
742
- };
743
- if (!isServer) {
744
- this.addEventListener("change", this.#handleChange, { capture: true });
745
- new RovingTabindexController(this, {
746
- direction: "both",
747
- hostDelegatesFocus: true,
748
- elements: () => this.getControls(),
749
- elementEnterAction: (element) => element.click(),
750
- focusInIndex: (elements) => {
751
- const selectedIndex = elements.findIndex((control) => this.isControlChecked(control));
752
- return selectedIndex !== -1 ? selectedIndex : 0;
753
- }
754
- });
755
- }
756
- }
757
- static {
758
- this.shadowRootOptions = {
759
- ...CustomElement.shadowRootOptions,
760
- delegatesFocus: true
761
- };
762
- }
763
- getControls() {
764
- return this.elements.filter((element) => this.isControl(element));
765
- }
766
- connectedCallback() {
767
- super.connectedCallback();
768
- this.role ||= "radiogroup";
769
- }
770
- isControl(element) {
771
- return element instanceof CheckboxFormControl;
772
- }
773
- isControlChecked(control) {
774
- return this.value === control.value;
775
- }
776
- willUpdate(changes) {
777
- super.update(changes);
778
- if (changes.has("value")) {
779
- this.updateControls((control) => {
780
- control.checked = this.isControlChecked(control);
781
- });
782
- }
783
- if (changes.has("name")) {
784
- this.updateControls((control) => {
785
- control.name = this.name;
786
- });
787
- }
788
- if (changes.has("disabled")) {
789
- this.updateControls((control) => {
790
- control.disabled = this.disabled;
791
- });
792
- }
793
- if (changes.has("readonly")) {
794
- this.updateControls((control) => {
795
- control.readonly = this.readonly;
796
- });
797
- }
798
- if (changes.has("required") || changes.has("value")) {
799
- const [firstControl] = this.getControls();
800
- if (!firstControl) return;
801
- this.setValidity({ valueMissing: this.required && this.value.length === 0 }, firstControl);
802
- }
803
- }
804
- updateControls(updateFn) {
805
- this.getControls().forEach(updateFn);
806
- }
807
- #handleChange;
808
- }
809
- __decorateClass([
810
- queryAssignedElements({ flatten: true })
811
- ], RadioGroupFormControl.prototype, "elements", 2);
812
- __decorateClass([
813
- property()
814
- ], RadioGroupFormControl.prototype, "value", 2);
815
-
816
- const DragControllerOptions = (config) => ({
817
- getDraggableElements: () => [],
818
- ...config
819
- });
820
- class DragController {
821
- #host;
822
- #options;
823
- #dragTargets = /* @__PURE__ */ new WeakSet();
824
- #listeners = /* @__PURE__ */ new Map();
825
- get draggableElements() {
826
- return this.#options.getDraggableElements().filter((element) => !element.dragDisabled);
827
- }
828
- get container() {
829
- return this.#options.getContainer?.() ?? this.#host;
830
- }
831
- constructor(host, options) {
832
- this.#host = host;
833
- this.#options = DragControllerOptions(options);
834
- this.#host.addController(this);
835
- }
836
- hostConnected() {
837
- this.#host.style.touchAction = "none";
838
- }
839
- hostDisconnected() {
840
- this.#host.style.touchAction = "";
841
- for (const removeListener of this.#listeners.values()) {
842
- removeListener();
843
- }
844
- }
845
- hostUpdated() {
846
- this.#dragTargets = new WeakSet(this.draggableElements);
847
- this.#host.removeEventListener("pointerdown", this.#handleDragStart);
848
- this.#host.addEventListener("pointerdown", this.#handleDragStart);
849
- }
850
- isDraggable(element) {
851
- if (element instanceof HTMLElement) {
852
- return "isDragActive" in element && this.#dragTargets.has(element);
853
- }
854
- return false;
855
- }
856
- #handleDragStart = async (event) => {
857
- event.preventDefault();
858
- event.stopPropagation();
859
- const target = this.#getDragTarget(event);
860
- if (!target) return;
861
- const onPointerMove = (event2) => this.#handleDragMove(event2, target);
862
- const onPointerUp = (event2) => this.#handleDragEnd(event2, target);
863
- target.beforeDragStart?.({ event, position: this.#calculatePosition(event) });
864
- this.#host.setPointerCapture(event.pointerId);
865
- this.#host.addEventListener("pointermove", onPointerMove);
866
- this.#host.addEventListener("pointerup", onPointerUp, { once: true });
867
- this.#listeners.set(target, () => {
868
- this.#host.removeEventListener("pointermove", onPointerMove);
869
- this.#host.removeEventListener("pointerup", onPointerUp);
870
- });
871
- await 0;
872
- target.dragStart?.({ event, position: this.#calculatePosition(event) });
873
- };
874
- #handleDragMove = (event, target) => {
875
- event.preventDefault();
876
- event.stopPropagation();
877
- target.dragMove?.({ event, position: this.#calculatePosition(event) });
878
- };
879
- #handleDragEnd = async (event, target) => {
880
- event.preventDefault();
881
- event.stopPropagation();
882
- target.dragEnd?.({ event, position: this.#calculatePosition(event) });
883
- this.#host.releasePointerCapture(event.pointerId);
884
- this.#listeners.get(target)?.();
885
- this.#listeners.delete(target);
886
- this.#host.requestUpdate();
887
- await this.#host.updateComplete;
888
- target.afterDragEnd?.({ event, position: this.#calculatePosition(event) });
889
- };
890
- #calculatePosition(event) {
891
- const { left, top, width } = this.container.getBoundingClientRect();
892
- return { x: (event.clientX - left) / width * 100, y: (event.clientY - top) / width * 100 };
893
- }
894
- #getDragTarget(event) {
895
- return minBy(this.draggableElements, (element) => element.getDistance?.(this.container, event) ?? Number.MAX_SAFE_INTEGER) ?? null;
896
- }
897
- }
898
-
899
- const ExpandableItemManagerOptions = (options) => ({
900
- ...options
901
- });
902
- class ExpandableItemManager {
903
- #host;
904
- #config;
905
- get items() {
906
- return this.#config.getItems?.() ?? [];
907
- }
908
- constructor(host, options) {
909
- this.#host = host;
910
- this.#config = ExpandableItemManagerOptions(options);
911
- this.#host.addController(this);
912
- if (!isServer) {
913
- this.#host.addEventListener("toggle", this.#handleToggle);
914
- this.#host.addEventListener("click", this.#handleClick);
915
- }
916
- }
917
- #handleToggle = (event) => {
918
- if (!event.target) return;
919
- event.stopPropagation();
920
- if (event.newState !== "open" || this.#host.multiple) return;
921
- for (const item of this.items) {
922
- if (event.target === item) continue;
923
- item.toggle(false);
924
- }
925
- };
926
- #handleClick = (event) => {
927
- const item = getElementFromEvent(event, (node) => this.items.includes(node));
928
- if (!(item && getElementFromEvent(event, (node) => node === item.getExpandControl()))) return;
929
- event.stopPropagation();
930
- item.toggle();
931
- };
932
- }
933
-
934
- const optionalAttr = (value) => {
935
- return value == null || value === "" ? nothing : value;
936
- };
937
- function optionalSlot(host, slotName) {
938
- if (host.querySelector(`[slot="${slotName}"]`)) {
939
- return html`
940
- <div class="${slotName}" part="${slotName}-container">
941
- <slot name="${slotName}" @slotchange="${() => host.requestUpdate()}"></slot>
942
- </div>
943
- `;
944
- }
945
- return nothing;
946
- }
947
-
948
- const styles = "@layer base{:host{--_color-background: var(--odx-color-background-transparent-rest);--_color-background-hover: var(--odx-color-background-transparent-hover);--_color-background-pressed: var(--odx-color-background-transparent-pressed);--_color-foreground: var(--odx-color-foreground-rest);--_color-stroke: transparent;--_color-stroke-hover: transparent;--_color-stroke-pressed: transparent;--_block-size: var(--odx-size-225);--_min-inline-size: var(--odx-size-500);--_font-size: var(--odx-typography-font-size-3);--_icon-size: var(--odx-typography-font-size-6);--_padding-block: var(--odx-size-37);--_padding-inline: var(--odx-size-50);--_icon-margin: 0;position:relative;margin:0;border-radius:var(--odx-border-radius-controls);cursor:pointer;block-size:var(--_block-size);min-inline-size:max(var(--_min-inline-size),min-content);max-inline-size:100%;user-select:none;-webkit-tap-highlight-color:transparent}:host(:focus-visible){outline:none}:host,[part=base]{display:inline-flex;place-items:center;touch-action:manipulation}[part=base]{gap:var(--_padding-inline);transition:var(--odx-transition-reduced);transition-property:background-color,border-color,color,opacity,transform,block-size;outline:var(--odx-focus-ring-outline);outline-offset:0;border:var(--odx-border-width-thin) solid var(--_color-stroke);border-radius:inherit;background-color:var(--_color-background, transparent);cursor:inherit;padding-block:var(--_padding-block);padding-inline:var(--_padding-inline);block-size:100%;inline-size:100%;overflow:hidden;text-decoration:none;line-height:min(calc(var(--_block-size) / 2 - var(--odx-size-25)),1em);color:var(--_color-foreground);font-size:var(--_font-size);font-weight:var(--odx-typography-font-weight-normal);&:focus-visible{outline-color:var(--odx-color-stroke-focus-outer)}}[part=base]::-moz-focus-inner{border:0;padding:0}[part=loader]{--_size: calc(var(--_icon-size) - var(--odx-size-25));margin-inline:calc(var(--_icon-margin) + var(--odx-size-12));color:var(--_color-foreground)}[part=label]{flex:1;margin-block:calc(-1 * var(--_padding-block));margin-inline:calc(-1 * var(--_padding-inline));padding-block:var(--_padding-block);padding-inline:var(--_padding-inline);text-align:left}:is(odx-icon),::slotted(:is(odx-avatar,odx-icon)){--size: var(--_icon-size);margin-inline:var(--_icon-margin)}::slotted([slot=\"badge\"]){--_badge-margin: var(--odx-size-12);position:absolute;inset-block-start:var(--_badge-margin);inset-inline-end:var(--_badge-margin);pointer-events:none;translate:var(--odx-size-37) -50%}::slotted(odx-avatar){--color-background: var(--odx-color-background-transparent-pressed);--_size: var(--odx-size-200);--_spacing: calc(var(--odx-size-75) - var(--odx-size-px));margin:0 calc(-1 * var(--_spacing));font-size:var(--odx-typography-font-size-2)}}@layer state{:host(:not([loading])) [part=base]:hover{--_color-background: var(--_color-background-hover);--_color-stroke: var(--_color-stroke-hover)}:host(:not([loading])) [part=base]:active{--_color-background: var(--_color-background-pressed);--_color-stroke: var(--_color-stroke-pressed)}:host([loading]){cursor:default}:host([disabled]){--_color-background: var(--odx-color-background-disabled-rest);--_color-background-hover: var(--odx-color-background-disabled-rest);--_color-background-pressed: var(--odx-color-background-disabled-rest);--_color-foreground: var(--odx-color-foreground-disabled-rest);--_color-stroke: var(--odx-color-stroke-disabled-rest);cursor:not-allowed}:host(:is([align-badge=\"end\"],[align-badge=\"center\"])) ::slotted([slot=\"badge\"]){inset-block-start:unset;inset-block-end:0}:host([align-badge=\"end\"]) ::slotted([slot=\"badge\"]){translate:var(--odx-size-37) 50%}:host([align-badge=\"center\"]) ::slotted([slot=\"badge\"]){inset-inline:auto;translate:0 calc(50% + var(--_badge-margin))}}";
949
-
950
- class InteractiveLink extends CanBeDisabled(CustomElement) {
951
- constructor() {
952
- super(...arguments);
953
- this.href = "";
954
- this.target = "";
955
- this.rel = "noreferrer noopener";
956
- }
957
- static {
958
- /** @internal */
959
- this.shadowRootOptions = {
960
- ...CustomElement.shadowRootOptions,
961
- delegatesFocus: true
962
- };
963
- }
964
- render() {
965
- const { ariaLabel, ariaHasPopup, ariaExpanded, ariaCurrent, ariaHidden } = this;
966
- return html`<a
967
- part="base"
968
- role="button"
969
- aria-label="${optionalAttr(ariaLabel)}"
970
- aria-haspopup="${optionalAttr(ariaHasPopup)}"
971
- aria-expanded="${optionalAttr(ariaExpanded)}"
972
- aria-current="${optionalAttr(ariaCurrent)}"
973
- aria-hidden="${optionalAttr(ariaHidden)}"
974
- href=${optionalAttr(this.href)}
975
- target=${optionalAttr(this.href && this.target)}
976
- download=${optionalAttr(this.href && this.download)}
977
- rel=${optionalAttr(this.href && this.rel)}
978
- >
979
- ${this.renderContent()}
980
- </a>`;
981
- }
982
- renderContent() {
983
- return html`<slot></slot>`;
984
- }
985
- }
986
- __decorateClass([
987
- query('[part~="base"]', true)
988
- ], InteractiveLink.prototype, "nativeElement", 2);
989
- __decorateClass([
990
- property()
991
- ], InteractiveLink.prototype, "href", 2);
992
- __decorateClass([
993
- property()
994
- ], InteractiveLink.prototype, "target", 2);
995
- __decorateClass([
996
- property()
997
- ], InteractiveLink.prototype, "rel", 2);
998
- __decorateClass([
999
- property()
1000
- ], InteractiveLink.prototype, "download", 2);
1001
-
1002
- class InteractiveElement extends InteractiveLink {
1003
- constructor() {
1004
- super(...arguments);
1005
- this.loading = false;
1006
- this.lineClamp = 2;
1007
- }
1008
- static {
1009
- this.styles = unsafeCSS(styles);
1010
- }
1011
- render() {
1012
- if (this.href) {
1013
- return super.render();
1014
- }
1015
- const { ariaLabel, ariaHasPopup, ariaExpanded } = this;
1016
- const type = "type" in this ? this.type : "button";
1017
- return html`
1018
- <button
1019
- id=${optionalAttr(this.id)}
1020
- part="base"
1021
- aria-label="${optionalAttr(ariaLabel)}"
1022
- aria-haspopup="${optionalAttr(ariaHasPopup)}"
1023
- aria-expanded="${optionalAttr(ariaExpanded)}"
1024
- type=${type}
1025
- ?disabled=${this.disabled || this.loading}
1026
- >
1027
- ${this.renderContent()}
1028
- </button>
1029
- `;
1030
- }
1031
- renderContent(withSpinner = true) {
1032
- return html`
1033
- ${this.#renderSlot("prefix", !withSpinner)}
1034
- <odx-line-clamp part="label" .max=${this.lineClamp}>
1035
- ${this.#renderSlot(void 0, !withSpinner)}
1036
- </odx-line-clamp>
1037
- ${this.#renderSlot("suffix", !withSpinner)}
1038
- `;
1039
- }
1040
- renderLoader() {
1041
- return html`<odx-loading-spinner part="loader"></odx-loading-spinner>`;
1042
- }
1043
- #renderSlot(name, force) {
1044
- if (!force && this.loading && this.#isLoaderSlot(name)) {
1045
- return this.renderLoader();
1046
- }
1047
- return html`<slot name=${optionalAttr(name)}></slot>`;
1048
- }
1049
- #isLoaderSlot(name) {
1050
- return name === void 0 && this.loaderSlot === "default" || this.querySelectorAll(`[slot=${this.loaderSlot || name}]`).length > 0;
1051
- }
1052
- }
1053
- __decorateClass([
1054
- property({ type: Boolean, reflect: true, useDefault: true })
1055
- ], InteractiveElement.prototype, "loading", 2);
1056
- __decorateClass([
1057
- property({ type: Number, attribute: "line-clamp" })
1058
- ], InteractiveElement.prototype, "lineClamp", 2);
1059
-
1060
- const CanBeExpanded = (superClass) => {
1061
- class CanBeExpandedMixin extends superClass {
1062
- constructor() {
1063
- super(...arguments);
1064
- this.expanded = false;
1065
- }
1066
- getExpandControl() {
1067
- return this;
1068
- }
1069
- toggle(state, emitEvent = true) {
1070
- const newState = state ?? !this.expanded;
1071
- if (this.disabled || this.expanded === newState) return;
1072
- const currentState = this.expanded;
1073
- this.expanded = newState;
1074
- const toggleEvent = new ToggleEvent("toggle", {
1075
- composed: true,
1076
- bubbles: true,
1077
- oldState: currentState ? "open" : "closed",
1078
- newState: newState ? "open" : "closed"
1079
- });
1080
- if (!(emitEvent && this.emit(toggleEvent))) return;
1081
- this.expanded = currentState;
1082
- }
1083
- }
1084
- __decorateClass([
1085
- property({ type: Boolean, reflect: true, useDefault: true })
1086
- ], CanBeExpandedMixin.prototype, "expanded", 2);
1087
- return CanBeExpandedMixin;
1088
- };
1089
-
1090
- const IS_DRAG_ACTIVE_ATTRIBUTE = "odx-drag-active";
1091
- const IsDraggable = (superClass) => {
1092
- class IsDraggableElement extends superClass {
1093
- constructor() {
1094
- super(...arguments);
1095
- this.dragDisabled = false;
1096
- }
1097
- get isDragActive() {
1098
- return this.hasAttribute(IS_DRAG_ACTIVE_ATTRIBUTE);
1099
- }
1100
- dragStart() {
1101
- this.toggleAttribute(IS_DRAG_ACTIVE_ATTRIBUTE, true);
1102
- }
1103
- afterDragEnd() {
1104
- this.toggleAttribute(IS_DRAG_ACTIVE_ATTRIBUTE, false);
1105
- }
1106
- }
1107
- __decorateClass([
1108
- property({ type: Boolean })
1109
- ], IsDraggableElement.prototype, "dragDisabled", 2);
1110
- return IsDraggableElement;
1111
- };
1112
-
1113
- const Placement = {
1114
- TOP: "top",
1115
- TOP_START: "top-start",
1116
- TOP_END: "top-end",
1117
- RIGHT: "right",
1118
- RIGHT_START: "right-start",
1119
- RIGHT_END: "right-end",
1120
- BOTTOM: "bottom",
1121
- BOTTOM_START: "bottom-start",
1122
- BOTTOM_END: "bottom-end",
1123
- LEFT: "left",
1124
- LEFT_START: "left-start",
1125
- LEFT_END: "left-end"
1126
- };
1127
-
1128
- const Shape = {
1129
- CIRCLE: "circle",
1130
- RECTANGLE: "rectangle"
1131
- };
1132
-
1133
- const Size = {
1134
- XS: "xs",
1135
- SM: "sm",
1136
- MD: "md",
1137
- LG: "lg",
1138
- XL: "xl",
1139
- XXL: "xxl"
1140
- };
1141
-
1142
- const Variant = {
1143
- NEUTRAL: "neutral",
1144
- PRIMARY: "primary",
1145
- ACCENT: "accent",
1146
- SUCCESS: "success",
1147
- WARNING: "warning",
1148
- DANGER: "danger",
1149
- GHOST: "ghost"
1150
- };
1151
-
1152
- function PopoverPlacementOptions(options) {
1153
- return {
1154
- placement: "bottom",
1155
- enableFallback: true,
1156
- fallbackAxisSideDirection: "end",
1157
- matchReferenceWidth: false,
1158
- offset: 0,
1159
- ...options
1160
- };
1161
- }
1162
- async function computePopoverPlacement(referenceElement, floatingElement, options) {
1163
- const { arrowElement, placement, offset: offset$1, matchReferenceWidth, enableFallback, fallbackAxisSideDirection, minHeight } = options;
1164
- const arrowSize = arrowElement?.offsetWidth ?? 0;
1165
- const arrowMiddleware = arrowElement ? arrow({ element: arrowElement, padding: arrowSize * 2 }) : void 0;
1166
- const flipMiddleWare = enableFallback ? flip({ fallbackAxisSideDirection }) : void 0;
1167
- floatingElement.setAttribute("popover-placement", placement);
1168
- const result = await computePosition(referenceElement, floatingElement, {
1169
- strategy: "fixed",
1170
- placement,
1171
- middleware: [
1172
- offset(offset$1 + arrowSize / 2),
1173
- shift({ padding: 12 }),
1174
- flipMiddleWare,
1175
- size({
1176
- apply: ({ availableHeight, availableWidth, rects, placement: currentPlacement }) => {
1177
- floatingElement.style.setProperty("--_popover-min-inline-size", matchReferenceWidth ? toPx(rects.reference.width) : null);
1178
- floatingElement.style.setProperty("--_popover-max-inline-size", toPx(availableWidth));
1179
- floatingElement.style.setProperty("--_popover-min-block-size", minHeight ? toPx(Math.min(availableHeight, minHeight)) : null);
1180
- floatingElement.style.setProperty("--_popover-max-block-size", toPx(availableHeight));
1181
- floatingElement.setAttribute("popover-placement", currentPlacement);
1182
- }
1183
- }),
1184
- arrowMiddleware,
1185
- hide()
1186
- ]
1187
- });
1188
- if (arrowElement && result.middlewareData.arrow) {
1189
- Object.assign(arrowElement.style, {
1190
- left: toPx(result.middlewareData.arrow.x),
1191
- top: toPx(result.middlewareData.arrow.y)
1192
- });
1193
- }
1194
- floatingElement.style.setProperty("--_popover-position-x", toPx(result.x));
1195
- floatingElement.style.setProperty("--_popover-position-y", toPx(result.y));
1196
- }
1197
- function positionUpdater(referenceElement, floatingElement, options) {
1198
- return autoUpdate(
1199
- referenceElement,
1200
- floatingElement,
1201
- throttle(() => referenceElement && computePopoverPlacement(referenceElement, floatingElement, options), 1e3 / 30),
1202
- { animationFrame: true }
1203
- );
1204
- }
1205
-
1206
- class SharedResizeObserverInstance {
1207
- #observer;
1208
- #handlers = /* @__PURE__ */ new WeakMap();
1209
- observe(target, handler, options = { fpsLimit: 30 }) {
1210
- this.unobserve(target);
1211
- this.#handlers.set(target, throttle(handler, 1e3 / options.fpsLimit));
1212
- this.#observer ??= new ResizeObserver((entries) => {
1213
- if (!this.#observer) return;
1214
- for (const entry of entries) {
1215
- this.#handlers.get(entry.target)?.([entry], this.#observer);
1216
- }
1217
- });
1218
- this.#observer?.observe(target, options);
1219
- }
1220
- unobserve(target) {
1221
- this.#observer?.unobserve(target);
1222
- this.#handlers.delete(target);
1223
- }
1224
- }
1225
- const SharedResizeObserver = new SharedResizeObserverInstance();
1226
-
1227
- export { ActiveDescendantsController, ActiveDescendantsControllerOptions, CanBeDisabled, CanBeExpanded, CheckboxFormControl, CheckboxGroupFormControl, CustomElement, DragController, DragControllerOptions, ExpandableItemManager, ExpandableItemManagerOptions, FormControl, IS_DRAG_ACTIVE_ATTRIBUTE, InteractiveElement, InteractiveLink, IsDraggable, ListboxFormControl, NumberFormControl, OptionControl, Placement, PopoverPlacementOptions, RadioGroupFormControl, Shape, SharedResizeObserver, Size, Variant, computePopoverPlacement, customElement, findClosestDocument, forwardEvent, getAssignedElement, getElementFromEvent, getKeyInfo, getUniqueId, optionalAttr, optionalSlot, parseDate, positionUpdater, toAriaBooleanAttribute, toPx, waitForAnimations };
1
+ export { breakpointAttribute, buildBreakpoint, createBreakpointUpdater, defaultBreakpoints, expandBreakpoints, observeBreakpoint, registeredBreakpoints, setupBreakpoints } from './lib/breakpoints.js';
2
+ export { formatDate, formatList, formatNumber, formatRelativeTime, parseDate } from './lib/format.js';
3
+ export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions } from './lib/localization.js';
4
+ export { computed, effect, sharedSignal, signal } from './lib/signals.js';
5
+ export { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme, toggleDarkMode, userPrefersDarkMode } from './lib/theming.js';