@odx/foundation 1.0.0-beta.98 → 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 -1206
  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 -28
  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 -34
  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 -24
  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 -22
  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 -4478
  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 -15
  142. package/dist/lib/control/checkbox-group-form-control.d.ts +0 -22
  143. package/dist/lib/control/form-control.d.ts +0 -29
  144. package/dist/lib/control/listbox-form-control.d.ts +0 -25
  145. package/dist/lib/control/number-form-control.d.ts +0 -12
  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,1206 +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
- willUpdate(props) {
181
- super.willUpdate(props);
182
- if (props.has("required")) {
183
- this.ariaRequired = toAriaBooleanAttribute(this.required);
184
- }
185
- if (props.has("readonly")) {
186
- this.ariaReadOnly = toAriaBooleanAttribute(this.readonly);
187
- }
188
- if (props.has("value")) {
189
- this.internals.setFormValue(this.toFormValue());
190
- }
191
- this.updateAriaAttributes?.();
192
- }
193
- }
194
- __decorateClass([
195
- property()
196
- ], FormControl.prototype, "name", 2);
197
- __decorateClass([
198
- property({ type: Boolean, reflect: true, useDefault: true })
199
- ], FormControl.prototype, "readonly", 2);
200
- __decorateClass([
201
- property({ type: Boolean, reflect: true, useDefault: true })
202
- ], FormControl.prototype, "required", 2);
203
-
204
- const LINK_SELECTORS = /* @__PURE__ */ new Set(["a", "button", "odx-link"]);
205
- class CheckboxFormControl extends FormControl {
206
- constructor() {
207
- super();
208
- this.role = null;
209
- this.checked = false;
210
- this.value = "";
211
- this.#handleClick = ({ target }) => {
212
- if (LINK_SELECTORS.has(target.localName)) return;
213
- this.toggle(void 0, true);
214
- };
215
- this.#handleKeyboardEvent = (event) => {
216
- const key = getKeyInfo(event);
217
- if (!(key.enter || key.space)) return;
218
- event.preventDefault();
219
- if (event.type === "keydown" || LINK_SELECTORS.has(event.target.localName)) return;
220
- this.toggle(void 0, true);
221
- };
222
- if (!isServer) {
223
- this.addEventListener("click", this.#handleClick);
224
- this.addEventListener("keydown", this.#handleKeyboardEvent);
225
- this.addEventListener("keyup", this.#handleKeyboardEvent);
226
- }
227
- }
228
- static {
229
- /** @internal */
230
- this.shadowRootOptions = {
231
- ...CustomElement.shadowRootOptions,
232
- delegatesFocus: false
233
- };
234
- }
235
- toFormValue() {
236
- if (this.value) {
237
- return this.checked ? this.value : null;
238
- }
239
- return this.checked ? "on" : null;
240
- }
241
- toggle(state, emitEvent = false) {
242
- const currentState = this.checked;
243
- const newState = state ?? !currentState;
244
- if (this.disabled || this.readonly || newState === currentState) return;
245
- this.checked = newState;
246
- if (!(emitEvent && this.emit("change", { bubbles: true }))) return;
247
- this.checked = currentState;
248
- }
249
- connectedCallback() {
250
- this.tabIndex = 0;
251
- super.connectedCallback();
252
- this.role ||= "checkbox";
253
- }
254
- updateAriaAttributes() {
255
- super.updateAriaAttributes?.();
256
- this.ariaChecked = toAriaBooleanAttribute(this.checked, false);
257
- }
258
- #handleClick;
259
- #handleKeyboardEvent;
260
- }
261
- __decorateClass([
262
- property({ type: Boolean, reflect: true, useDefault: true })
263
- ], CheckboxFormControl.prototype, "checked", 2);
264
- __decorateClass([
265
- property()
266
- ], CheckboxFormControl.prototype, "value", 2);
267
-
268
- const GROUP_CONTROL_SELECTOR = "odx-checkbox-group-control";
269
- const _CheckboxGroupFormControl = class _CheckboxGroupFormControl extends FormControl {
270
- constructor() {
271
- super();
272
- this.value = [];
273
- this.#handleChangeEvent = (event) => {
274
- if (this.isControl(event.target)) {
275
- this.#handleControlChange(event);
276
- }
277
- };
278
- this.#handleControlChange = (event) => {
279
- if (!this.isControl(event.target)) return;
280
- if (event.target.checked) {
281
- this.updateValue([...this.value, event.target.value], true);
282
- } else {
283
- this.updateValue(
284
- this.value.filter((value) => value !== event.target.value),
285
- true
286
- );
287
- }
288
- };
289
- if (!isServer) {
290
- this.addEventListener("change", this.#handleChangeEvent);
291
- }
292
- }
293
- get childGroups() {
294
- return this.elements.filter((element) => element instanceof _CheckboxGroupFormControl);
295
- }
296
- get controls() {
297
- return this.#findControls((element) => !element.hasAttribute(GROUP_CONTROL_SELECTOR)).concat(this.childGroups.flatMap((group) => group.controls));
298
- }
299
- get selectedControls() {
300
- return this.controls.filter((control) => this.isControlChecked(control));
301
- }
302
- get groupControl() {
303
- return this.#findControls((element) => element.hasAttribute(GROUP_CONTROL_SELECTOR))[0] ?? null;
304
- }
305
- async firstUpdated(_changedProperties) {
306
- await 0;
307
- this.value = this.controls.filter((control) => control.checked).map((control) => control.value);
308
- }
309
- toFormValue() {
310
- const formData = new FormData();
311
- this.value.forEach((value, index) => {
312
- formData.append(`${this.name}[${index}]`, value);
313
- });
314
- return formData;
315
- }
316
- isControl(element) {
317
- return element instanceof CheckboxFormControl;
318
- }
319
- isGroupControl(element) {
320
- return this.isControl(element) && element.hasAttribute(GROUP_CONTROL_SELECTOR);
321
- }
322
- isControlChecked(control) {
323
- return this.value.includes(control.value);
324
- }
325
- updated(props) {
326
- super.updated(props);
327
- if (props.has("value")) {
328
- this.updateControls((control) => {
329
- control.checked = this.isControlChecked(control);
330
- });
331
- if (this.groupControl) {
332
- this.groupControl.checked = this.controls.length > 0 && this.value.length === this.controls.length;
333
- if ("indeterminate" in this.groupControl) {
334
- this.groupControl.indeterminate = this.value.length > 0 && this.value.length < this.controls.length;
335
- }
336
- }
337
- }
338
- if (props.has("name")) {
339
- this.updateControls((control) => {
340
- control.name = this.name;
341
- });
342
- }
343
- if (props.has("disabled")) {
344
- this.updateControls((control) => {
345
- control.disabled = this.disabled;
346
- });
347
- }
348
- if (props.has("readonly")) {
349
- this.updateControls((control) => {
350
- control.readonly = this.readonly;
351
- });
352
- }
353
- }
354
- updateControls(updateFn) {
355
- this.controls.forEach(updateFn);
356
- }
357
- updateValue(value, dispatchEvent) {
358
- this.value = value;
359
- for (const group of this.childGroups) {
360
- const groupValue = this.value.filter((value2) => group.controls.some((control) => control.value === value2));
361
- group.updateValue(groupValue, false);
362
- }
363
- if (!dispatchEvent) return;
364
- this.emit("change", { bubbles: true });
365
- }
366
- #findControls(predicate) {
367
- return this.elements.filter((element) => this.isControl(element) && predicate(element));
368
- }
369
- #handleChangeEvent;
370
- #handleControlChange;
371
- };
372
- __decorateClass([
373
- queryAssignedElements({ flatten: true })
374
- ], _CheckboxGroupFormControl.prototype, "elements", 2);
375
- __decorateClass([
376
- property({ type: Array })
377
- ], _CheckboxGroupFormControl.prototype, "value", 2);
378
- let CheckboxGroupFormControl = _CheckboxGroupFormControl;
379
-
380
- const ActiveDescendantsControllerOptions = (options) => ({
381
- getItems: () => [],
382
- ...options
383
- });
384
- class ActiveDescendantsController {
385
- #host;
386
- #options;
387
- #activeIndex = -1;
388
- get activeIndex() {
389
- return this.#activeIndex;
390
- }
391
- get activeItem() {
392
- return this.items[this.#activeIndex];
393
- }
394
- get items() {
395
- return this.#options.getItems().filter((item) => item.isConnected);
396
- }
397
- constructor(host, options) {
398
- this.#host = host;
399
- this.#options = ActiveDescendantsControllerOptions(options);
400
- host.addController(this);
401
- }
402
- activate(initialActiveIndex) {
403
- if (initialActiveIndex === void 0) {
404
- this.first();
405
- } else {
406
- this.update(initialActiveIndex);
407
- }
408
- this.#host.addEventListener("keydown", this.#handleKeyboardEvent);
409
- }
410
- deactivate() {
411
- this.#host.removeEventListener("keydown", this.#handleKeyboardEvent);
412
- this.update();
413
- }
414
- previous() {
415
- const index = this.items.findLastIndex((item, index2) => item.canActivate() && this.#activeIndex > index2);
416
- this.update(index);
417
- }
418
- next() {
419
- const index = this.items.findIndex((item, index2) => item.canActivate() && this.#activeIndex < index2);
420
- this.update(index);
421
- }
422
- first() {
423
- this.update(this.items.findIndex((item) => item.canActivate()));
424
- }
425
- last() {
426
- this.update(this.items.findLastIndex((item) => item.canActivate()));
427
- }
428
- select(item) {
429
- const index = this.items.indexOf(item);
430
- if (index === -1 || !item.canActivate()) return;
431
- this.update(index);
432
- }
433
- update(index, force = false) {
434
- const previousActiveItem = this.items[this.#activeIndex];
435
- const activeItem = this.items[index ?? this.#activeIndex];
436
- if (force !== false || !activeItem?.canActivate()) return;
437
- this.#activeIndex = index ?? this.#activeIndex;
438
- this.#host.setAttribute("aria-activedescendant", activeItem?.id ?? "");
439
- previousActiveItem?.deactivate();
440
- activeItem?.activate();
441
- this.#options.onChange?.(previousActiveItem, activeItem, previousActiveItem === void 0 && !!activeItem);
442
- }
443
- #handleKeyboardEvent = (event) => {
444
- const key = getKeyInfo(event);
445
- if (!(key.up || key.down || key.start || key.end)) return;
446
- event.preventDefault();
447
- if (key.down) {
448
- this.next();
449
- } else if (key.up) {
450
- this.previous();
451
- } else if (key.start) {
452
- this.first();
453
- } else if (key.end) {
454
- this.last();
455
- }
456
- };
457
- }
458
-
459
- let uniqueIdCounter = 0;
460
- function getUniqueId(prefix) {
461
- return `${prefix}-${uniqueIdCounter++}`;
462
- }
463
-
464
- class OptionControl extends CanBeDisabled(CustomElement) {
465
- constructor() {
466
- super(...arguments);
467
- this.role = null;
468
- this.value = "";
469
- this.selected = false;
470
- this.readonly = false;
471
- }
472
- #label;
473
- set label(value) {
474
- this.#label = value;
475
- }
476
- get label() {
477
- return (this.#label || this.textContent?.trim()) ?? "";
478
- }
479
- canActivate() {
480
- return !(this.disabled || this.hidden);
481
- }
482
- canSelect() {
483
- return this.canActivate();
484
- }
485
- isActive() {
486
- return this.hasAttribute("odx-active") && !this.canActivate();
487
- }
488
- activate() {
489
- if (!this.canActivate()) return;
490
- this.toggleAttribute("odx-active", true);
491
- }
492
- deactivate() {
493
- this.toggleAttribute("odx-active", false);
494
- }
495
- connectedCallback() {
496
- super.connectedCallback();
497
- this.role ||= "option";
498
- this.id ||= getUniqueId(this.localName);
499
- }
500
- willUpdate(props) {
501
- super.willUpdate(props);
502
- if (props.has("selected")) {
503
- this.ariaSelected = this.canSelect() ? toAriaBooleanAttribute(this.selected, false) : null;
504
- }
505
- }
506
- }
507
- __decorateClass([
508
- property({ type: String })
509
- ], OptionControl.prototype, "label", 1);
510
- __decorateClass([
511
- property()
512
- ], OptionControl.prototype, "value", 2);
513
- __decorateClass([
514
- property({ type: Boolean, reflect: true, useDefault: true })
515
- ], OptionControl.prototype, "selected", 2);
516
- __decorateClass([
517
- property({ type: Boolean, reflect: true, useDefault: true })
518
- ], OptionControl.prototype, "readonly", 2);
519
- __decorateClass([
520
- property()
521
- ], OptionControl.prototype, "type", 2);
522
-
523
- class ListboxFormControl extends FormControl {
524
- constructor() {
525
- super();
526
- this.activeDescendants = new ActiveDescendantsController(this, {
527
- getItems: () => this.options,
528
- onChange: (_, option, firstChange) => {
529
- option?.scrollIntoView();
530
- if (!(option && this.canAutoSelect(option)) || firstChange || option.selected) return;
531
- this.toggleOption(option, true);
532
- }
533
- });
534
- this.autoSelect = false;
535
- this.multiple = false;
536
- this.placeholder = "";
537
- this.value = "";
538
- this.#handleBlur = (_event) => {
539
- this.activeDescendants.deactivate();
540
- };
541
- this.#handleClick = (event) => {
542
- const option = getElementFromEvent(event, (node) => node instanceof OptionControl);
543
- if (!option) return;
544
- this.toggleOption(option);
545
- this.#handleOptionSelection(option);
546
- };
547
- this.#handleFocus = (_event) => {
548
- this.activeDescendants.activate(this.selectedIndices[0]);
549
- };
550
- this.#handleKeydown = (event) => {
551
- if (event.target !== this) return;
552
- const activeOption = this.activeDescendants.activeItem;
553
- if (!activeOption) return;
554
- const key = getKeyInfo(event);
555
- if (!(key.enter || key.space)) return;
556
- if (this.multiple) {
557
- event.stopPropagation();
558
- event.stopImmediatePropagation();
559
- }
560
- this.toggleOption(activeOption);
561
- this.#handleOptionSelection(activeOption);
562
- };
563
- if (!isServer) {
564
- this.addEventListener("focusout", this.#handleBlur);
565
- this.addEventListener("focusin", this.#handleFocus);
566
- this.addEventListener("click", this.#handleClick);
567
- this.addEventListener("keydown", this.#handleKeydown);
568
- }
569
- }
570
- get selectedOptions() {
571
- return this.options.filter((option) => option.selected);
572
- }
573
- get selectedIndices() {
574
- return this.selectedOptions.map((option) => this.options.indexOf(option));
575
- }
576
- canAutoSelect(option) {
577
- return this.autoSelect && !this.multiple && this.canSelect(option);
578
- }
579
- canSelect(option) {
580
- return option.canSelect();
581
- }
582
- toggleOption(option, state) {
583
- if (!this.canSelect(option)) return;
584
- const newState = state ?? (this.required && !this.multiple || !option.selected);
585
- if (this.disabled || this.readonly) return;
586
- option.selected = newState;
587
- this.updateValue(option);
588
- if (newState) {
589
- option.scrollIntoView();
590
- }
591
- }
592
- connectedCallback() {
593
- super.connectedCallback();
594
- this.role ||= "listbox";
595
- this.id ||= getUniqueId(this.localName);
596
- }
597
- handleSlotChange() {
598
- this.value ||= this.multiple ? this.selectedOptions.map((option) => option.value) : this.selectedOptions[0]?.value ?? "";
599
- this.requestUpdate("value");
600
- }
601
- updateValue(option) {
602
- const oldValue = this.value;
603
- if (this.multiple) {
604
- const value = typeof this.value === "string" ? [this.value].filter(Boolean) : this.value;
605
- this.value = option?.selected ? [...value, option.value] : value.filter((value2) => value2 !== option?.value);
606
- } else {
607
- this.value = option?.selected ? option.value : "";
608
- }
609
- if (option) {
610
- this.activeDescendants.select(option);
611
- }
612
- if (oldValue === this.value) return;
613
- this.requestUpdate();
614
- this.emit("change");
615
- }
616
- willUpdate(props) {
617
- super.willUpdate(props);
618
- if (props.has("value")) {
619
- this.updateOptions((option) => {
620
- if (!option.canSelect()) return;
621
- option.selected = this.multiple ? this.value.includes(option.value) : this.value === option.value;
622
- });
623
- }
624
- if (props.has("multiple")) {
625
- this.#handleMultipleChange();
626
- }
627
- if (props.has("required") || props.has("value")) {
628
- if (!this.selectedOptions[0]?.selected) return;
629
- this.setValidity({ valueMissing: this.required && this.value.length === 0 }, this.selectedOptions[0]);
630
- }
631
- }
632
- updateOptions(updateFn) {
633
- for (const option of this.options ?? []) {
634
- updateFn(option);
635
- }
636
- }
637
- #handleOptionSelection(option) {
638
- if (!option.selected) return;
639
- this.emit("select", { detail: option });
640
- }
641
- #handleMultipleChange() {
642
- const optionType = this.multiple ? "checkbox" : null;
643
- this.updateOptions((option) => {
644
- option.type = optionType;
645
- });
646
- if (!this.multiple && this.selectedOptions[0]) {
647
- this.updateValue(this.selectedOptions[0]);
648
- }
649
- }
650
- #handleBlur;
651
- #handleClick;
652
- #handleFocus;
653
- #handleKeydown;
654
- }
655
- __decorateClass([
656
- property({ type: Boolean, attribute: "auto-select" })
657
- ], ListboxFormControl.prototype, "autoSelect", 2);
658
- __decorateClass([
659
- property({ type: Boolean, reflect: true, useDefault: true })
660
- ], ListboxFormControl.prototype, "multiple", 2);
661
- __decorateClass([
662
- property()
663
- ], ListboxFormControl.prototype, "placeholder", 2);
664
- __decorateClass([
665
- property()
666
- ], ListboxFormControl.prototype, "value", 2);
667
-
668
- const MIN_STEP_VALUE = 1 / 2 ^ 16;
669
- class NumberFormControl extends FormControl {
670
- constructor() {
671
- super(...arguments);
672
- this.min = 0;
673
- this.max = 100;
674
- this.step = 1;
675
- this.value = 0;
676
- }
677
- getValueText() {
678
- return this.ariaValueText?.trim() ?? "";
679
- }
680
- willUpdate(props) {
681
- if (props.has("value")) {
682
- this.internals.ariaValueNow = String(this.value);
683
- this.internals.ariaValueText = this.getValueText();
684
- }
685
- if (props.has("min")) {
686
- this.internals.ariaValueMin = String(this.min);
687
- }
688
- if (props.has("max")) {
689
- this.internals.ariaValueMax = String(this.max);
690
- }
691
- if (props.has("step")) {
692
- this.step = Math.max(MIN_STEP_VALUE, this.step);
693
- }
694
- this.value = Math.max(this.min, Math.min(this.value, this.max));
695
- super.willUpdate(props);
696
- }
697
- toFormValue() {
698
- return String(this.value);
699
- }
700
- }
701
- __decorateClass([
702
- property({ type: Number })
703
- ], NumberFormControl.prototype, "min", 2);
704
- __decorateClass([
705
- property({ type: Number })
706
- ], NumberFormControl.prototype, "max", 2);
707
- __decorateClass([
708
- property({ type: Number })
709
- ], NumberFormControl.prototype, "step", 2);
710
- __decorateClass([
711
- property({ type: Number })
712
- ], NumberFormControl.prototype, "value", 2);
713
-
714
- class RadioGroupFormControl extends FormControl {
715
- constructor() {
716
- super();
717
- this.value = "";
718
- this.#handleChange = ({ target }) => {
719
- if (!this.isControl(target) || this.value === target.value) return;
720
- this.value = target.value;
721
- };
722
- if (!isServer) {
723
- this.addEventListener("change", this.#handleChange, { capture: true });
724
- new RovingTabindexController(this, {
725
- direction: "both",
726
- hostDelegatesFocus: true,
727
- elements: () => this.getControls(),
728
- elementEnterAction: (element) => element.click(),
729
- focusInIndex: (elements) => {
730
- const selectedIndex = elements.findIndex((control) => this.isControlChecked(control));
731
- return selectedIndex !== -1 ? selectedIndex : 0;
732
- }
733
- });
734
- }
735
- }
736
- static {
737
- this.shadowRootOptions = {
738
- ...CustomElement.shadowRootOptions,
739
- delegatesFocus: true
740
- };
741
- }
742
- getControls() {
743
- return this.elements.filter((element) => this.isControl(element));
744
- }
745
- connectedCallback() {
746
- super.connectedCallback();
747
- this.role ||= "radiogroup";
748
- }
749
- isControl(element) {
750
- return element instanceof CheckboxFormControl;
751
- }
752
- isControlChecked(control) {
753
- return this.value === control.value;
754
- }
755
- willUpdate(changes) {
756
- super.update(changes);
757
- if (changes.has("value")) {
758
- this.updateControls((control) => {
759
- control.checked = this.isControlChecked(control);
760
- });
761
- }
762
- if (changes.has("name")) {
763
- this.updateControls((control) => {
764
- control.name = this.name;
765
- });
766
- }
767
- if (changes.has("disabled")) {
768
- this.updateControls((control) => {
769
- control.disabled = this.disabled;
770
- });
771
- }
772
- if (changes.has("readonly")) {
773
- this.updateControls((control) => {
774
- control.readonly = this.readonly;
775
- });
776
- }
777
- if (changes.has("required") || changes.has("value")) {
778
- const [firstControl] = this.getControls();
779
- if (!firstControl) return;
780
- this.setValidity({ valueMissing: this.required && this.value.length === 0 }, firstControl);
781
- }
782
- }
783
- updateControls(updateFn) {
784
- this.getControls().forEach(updateFn);
785
- }
786
- #handleChange;
787
- }
788
- __decorateClass([
789
- queryAssignedElements({ flatten: true })
790
- ], RadioGroupFormControl.prototype, "elements", 2);
791
- __decorateClass([
792
- property()
793
- ], RadioGroupFormControl.prototype, "value", 2);
794
-
795
- const DragControllerOptions = (config) => ({
796
- getDraggableElements: () => [],
797
- ...config
798
- });
799
- class DragController {
800
- #host;
801
- #options;
802
- #dragTargets = /* @__PURE__ */ new WeakSet();
803
- #listeners = /* @__PURE__ */ new Map();
804
- get draggableElements() {
805
- return this.#options.getDraggableElements().filter((element) => !element.dragDisabled);
806
- }
807
- get container() {
808
- return this.#options.getContainer?.() ?? this.#host;
809
- }
810
- constructor(host, options) {
811
- this.#host = host;
812
- this.#options = DragControllerOptions(options);
813
- this.#host.addController(this);
814
- }
815
- hostConnected() {
816
- this.#host.style.touchAction = "none";
817
- }
818
- hostDisconnected() {
819
- this.#host.style.touchAction = "";
820
- for (const removeListener of this.#listeners.values()) {
821
- removeListener();
822
- }
823
- }
824
- hostUpdated() {
825
- this.#dragTargets = new WeakSet(this.draggableElements);
826
- this.#host.removeEventListener("pointerdown", this.#handleDragStart);
827
- this.#host.addEventListener("pointerdown", this.#handleDragStart);
828
- }
829
- isDraggable(element) {
830
- if (element instanceof HTMLElement) {
831
- return "isDragActive" in element && this.#dragTargets.has(element);
832
- }
833
- return false;
834
- }
835
- #handleDragStart = async (event) => {
836
- event.preventDefault();
837
- event.stopPropagation();
838
- const target = this.#getDragTarget(event);
839
- if (!target) return;
840
- const onPointerMove = (event2) => this.#handleDragMove(event2, target);
841
- const onPointerUp = (event2) => this.#handleDragEnd(event2, target);
842
- target.beforeDragStart?.({ event, position: this.#calculatePosition(event) });
843
- this.#host.setPointerCapture(event.pointerId);
844
- this.#host.addEventListener("pointermove", onPointerMove);
845
- this.#host.addEventListener("pointerup", onPointerUp, { once: true });
846
- this.#listeners.set(target, () => {
847
- this.#host.removeEventListener("pointermove", onPointerMove);
848
- this.#host.removeEventListener("pointerup", onPointerUp);
849
- });
850
- await 0;
851
- target.dragStart?.({ event, position: this.#calculatePosition(event) });
852
- };
853
- #handleDragMove = (event, target) => {
854
- event.preventDefault();
855
- event.stopPropagation();
856
- target.dragMove?.({ event, position: this.#calculatePosition(event) });
857
- };
858
- #handleDragEnd = async (event, target) => {
859
- event.preventDefault();
860
- event.stopPropagation();
861
- target.dragEnd?.({ event, position: this.#calculatePosition(event) });
862
- this.#host.releasePointerCapture(event.pointerId);
863
- this.#listeners.get(target)?.();
864
- this.#listeners.delete(target);
865
- this.#host.requestUpdate();
866
- await this.#host.updateComplete;
867
- target.afterDragEnd?.({ event, position: this.#calculatePosition(event) });
868
- };
869
- #calculatePosition(event) {
870
- const { left, top, width } = this.container.getBoundingClientRect();
871
- return { x: (event.clientX - left) / width * 100, y: (event.clientY - top) / width * 100 };
872
- }
873
- #getDragTarget(event) {
874
- return minBy(this.draggableElements, (element) => element.getDistance?.(this.container, event) ?? Number.MAX_SAFE_INTEGER) ?? null;
875
- }
876
- }
877
-
878
- const ExpandableItemManagerOptions = (options) => ({
879
- ...options
880
- });
881
- class ExpandableItemManager {
882
- #host;
883
- #config;
884
- get items() {
885
- return this.#config.getItems?.() ?? [];
886
- }
887
- constructor(host, options) {
888
- this.#host = host;
889
- this.#config = ExpandableItemManagerOptions(options);
890
- this.#host.addController(this);
891
- if (!isServer) {
892
- this.#host.addEventListener("toggle", this.#handleToggle);
893
- this.#host.addEventListener("click", this.#handleClick);
894
- }
895
- }
896
- #handleToggle = (event) => {
897
- if (!event.target) return;
898
- event.stopPropagation();
899
- if (event.newState !== "open" || this.#host.multiple) return;
900
- for (const item of this.items) {
901
- if (event.target === item) continue;
902
- item.toggle(false);
903
- }
904
- };
905
- #handleClick = (event) => {
906
- const item = getElementFromEvent(event, (node) => this.items.includes(node));
907
- if (!(item && getElementFromEvent(event, (node) => node === item.getExpandControl()))) return;
908
- event.stopPropagation();
909
- item.toggle();
910
- };
911
- }
912
-
913
- const optionalAttr = (value) => {
914
- return value == null || value === "" ? nothing : value;
915
- };
916
- function optionalSlot(host, slotName) {
917
- if (host.querySelector(`[slot="${slotName}"]`)) {
918
- return html`
919
- <div class="${slotName}" part="${slotName}-container">
920
- <slot name="${slotName}" @slotchange="${() => host.requestUpdate()}"></slot>
921
- </div>
922
- `;
923
- }
924
- return nothing;
925
- }
926
-
927
- 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))}}";
928
-
929
- class InteractiveLink extends CanBeDisabled(CustomElement) {
930
- constructor() {
931
- super(...arguments);
932
- this.href = "";
933
- this.target = "";
934
- this.rel = "noreferrer noopener";
935
- }
936
- static {
937
- /** @internal */
938
- this.shadowRootOptions = {
939
- ...CustomElement.shadowRootOptions,
940
- delegatesFocus: true
941
- };
942
- }
943
- render() {
944
- const { ariaLabel, ariaHasPopup, ariaExpanded, ariaCurrent, ariaHidden } = this;
945
- return html`<a
946
- part="base"
947
- role="button"
948
- aria-label="${optionalAttr(ariaLabel)}"
949
- aria-haspopup="${optionalAttr(ariaHasPopup)}"
950
- aria-expanded="${optionalAttr(ariaExpanded)}"
951
- aria-current="${optionalAttr(ariaCurrent)}"
952
- aria-hidden="${optionalAttr(ariaHidden)}"
953
- href=${optionalAttr(this.href)}
954
- target=${optionalAttr(this.href && this.target)}
955
- download=${optionalAttr(this.href && this.download)}
956
- rel=${optionalAttr(this.href && this.rel)}
957
- >
958
- ${this.renderContent()}
959
- </a>`;
960
- }
961
- renderContent() {
962
- return html`<slot></slot>`;
963
- }
964
- }
965
- __decorateClass([
966
- query('[part~="base"]', true)
967
- ], InteractiveLink.prototype, "nativeElement", 2);
968
- __decorateClass([
969
- property()
970
- ], InteractiveLink.prototype, "href", 2);
971
- __decorateClass([
972
- property()
973
- ], InteractiveLink.prototype, "target", 2);
974
- __decorateClass([
975
- property()
976
- ], InteractiveLink.prototype, "rel", 2);
977
- __decorateClass([
978
- property()
979
- ], InteractiveLink.prototype, "download", 2);
980
-
981
- class InteractiveElement extends InteractiveLink {
982
- constructor() {
983
- super(...arguments);
984
- this.loading = false;
985
- this.lineClamp = 2;
986
- }
987
- static {
988
- this.styles = unsafeCSS(styles);
989
- }
990
- render() {
991
- if (this.href) {
992
- return super.render();
993
- }
994
- const { ariaLabel, ariaHasPopup, ariaExpanded } = this;
995
- const type = "type" in this ? this.type : "button";
996
- return html`
997
- <button
998
- id=${optionalAttr(this.id)}
999
- part="base"
1000
- aria-label="${optionalAttr(ariaLabel)}"
1001
- aria-haspopup="${optionalAttr(ariaHasPopup)}"
1002
- aria-expanded="${optionalAttr(ariaExpanded)}"
1003
- type=${type}
1004
- ?disabled=${this.disabled || this.loading}
1005
- >
1006
- ${this.renderContent()}
1007
- </button>
1008
- `;
1009
- }
1010
- renderContent(withSpinner = true) {
1011
- return html`
1012
- ${this.#renderSlot("prefix", !withSpinner)}
1013
- <odx-line-clamp part="label" .max=${this.lineClamp}>
1014
- ${this.#renderSlot(void 0, !withSpinner)}
1015
- </odx-line-clamp>
1016
- ${this.#renderSlot("suffix", !withSpinner)}
1017
- `;
1018
- }
1019
- renderLoader() {
1020
- return html`<odx-loading-spinner part="loader"></odx-loading-spinner>`;
1021
- }
1022
- #renderSlot(name, force) {
1023
- if (!force && this.loading && this.#isLoaderSlot(name)) {
1024
- return this.renderLoader();
1025
- }
1026
- return html`<slot name=${optionalAttr(name)}></slot>`;
1027
- }
1028
- #isLoaderSlot(name) {
1029
- return name === void 0 && this.loaderSlot === "default" || this.querySelectorAll(`[slot=${this.loaderSlot || name}]`).length > 0;
1030
- }
1031
- }
1032
- __decorateClass([
1033
- property({ type: Boolean, reflect: true, useDefault: true })
1034
- ], InteractiveElement.prototype, "loading", 2);
1035
- __decorateClass([
1036
- property({ type: Number, attribute: "line-clamp" })
1037
- ], InteractiveElement.prototype, "lineClamp", 2);
1038
-
1039
- const CanBeExpanded = (superClass) => {
1040
- class CanBeExpandedMixin extends superClass {
1041
- constructor() {
1042
- super(...arguments);
1043
- this.expanded = false;
1044
- }
1045
- getExpandControl() {
1046
- return this;
1047
- }
1048
- toggle(state, emitEvent = true) {
1049
- const newState = state ?? !this.expanded;
1050
- if (this.disabled || this.expanded === newState) return;
1051
- const currentState = this.expanded;
1052
- this.expanded = newState;
1053
- const toggleEvent = new ToggleEvent("toggle", {
1054
- composed: true,
1055
- bubbles: true,
1056
- oldState: currentState ? "open" : "closed",
1057
- newState: newState ? "open" : "closed"
1058
- });
1059
- if (!(emitEvent && this.emit(toggleEvent))) return;
1060
- this.expanded = currentState;
1061
- }
1062
- }
1063
- __decorateClass([
1064
- property({ type: Boolean, reflect: true, useDefault: true })
1065
- ], CanBeExpandedMixin.prototype, "expanded", 2);
1066
- return CanBeExpandedMixin;
1067
- };
1068
-
1069
- const IS_DRAG_ACTIVE_ATTRIBUTE = "odx-drag-active";
1070
- const IsDraggable = (superClass) => {
1071
- class IsDraggableElement extends superClass {
1072
- constructor() {
1073
- super(...arguments);
1074
- this.dragDisabled = false;
1075
- }
1076
- get isDragActive() {
1077
- return this.hasAttribute(IS_DRAG_ACTIVE_ATTRIBUTE);
1078
- }
1079
- dragStart() {
1080
- this.toggleAttribute(IS_DRAG_ACTIVE_ATTRIBUTE, true);
1081
- }
1082
- afterDragEnd() {
1083
- this.toggleAttribute(IS_DRAG_ACTIVE_ATTRIBUTE, false);
1084
- }
1085
- }
1086
- __decorateClass([
1087
- property({ type: Boolean })
1088
- ], IsDraggableElement.prototype, "dragDisabled", 2);
1089
- return IsDraggableElement;
1090
- };
1091
-
1092
- const Placement = {
1093
- TOP: "top",
1094
- TOP_START: "top-start",
1095
- TOP_END: "top-end",
1096
- RIGHT: "right",
1097
- RIGHT_START: "right-start",
1098
- RIGHT_END: "right-end",
1099
- BOTTOM: "bottom",
1100
- BOTTOM_START: "bottom-start",
1101
- BOTTOM_END: "bottom-end",
1102
- LEFT: "left",
1103
- LEFT_START: "left-start",
1104
- LEFT_END: "left-end"
1105
- };
1106
-
1107
- const Shape = {
1108
- CIRCLE: "circle",
1109
- RECTANGLE: "rectangle"
1110
- };
1111
-
1112
- const Size = {
1113
- XS: "xs",
1114
- SM: "sm",
1115
- MD: "md",
1116
- LG: "lg",
1117
- XL: "xl",
1118
- XXL: "xxl"
1119
- };
1120
-
1121
- const Variant = {
1122
- NEUTRAL: "neutral",
1123
- PRIMARY: "primary",
1124
- ACCENT: "accent",
1125
- SUCCESS: "success",
1126
- WARNING: "warning",
1127
- DANGER: "danger",
1128
- GHOST: "ghost"
1129
- };
1130
-
1131
- function PopoverPlacementOptions(options) {
1132
- return {
1133
- placement: "bottom",
1134
- enableFallback: true,
1135
- fallbackAxisSideDirection: "end",
1136
- matchReferenceWidth: false,
1137
- offset: 0,
1138
- ...options
1139
- };
1140
- }
1141
- async function computePopoverPlacement(referenceElement, floatingElement, options) {
1142
- const { arrowElement, placement, offset: offset$1, matchReferenceWidth, enableFallback, fallbackAxisSideDirection, minHeight } = options;
1143
- const arrowSize = arrowElement?.offsetWidth ?? 0;
1144
- const arrowMiddleware = arrowElement ? arrow({ element: arrowElement, padding: arrowSize * 2 }) : void 0;
1145
- const flipMiddleWare = enableFallback ? flip({ fallbackAxisSideDirection }) : void 0;
1146
- floatingElement.setAttribute("popover-placement", placement);
1147
- const result = await computePosition(referenceElement, floatingElement, {
1148
- strategy: "fixed",
1149
- placement,
1150
- middleware: [
1151
- offset(offset$1 + arrowSize / 2),
1152
- shift({ padding: 12 }),
1153
- flipMiddleWare,
1154
- size({
1155
- apply: ({ availableHeight, availableWidth, rects, placement: currentPlacement }) => {
1156
- floatingElement.style.setProperty("--_popover-min-inline-size", matchReferenceWidth ? toPx(rects.reference.width) : null);
1157
- floatingElement.style.setProperty("--_popover-max-inline-size", toPx(availableWidth));
1158
- floatingElement.style.setProperty("--_popover-min-block-size", minHeight ? toPx(Math.min(availableHeight, minHeight)) : null);
1159
- floatingElement.style.setProperty("--_popover-max-block-size", toPx(availableHeight));
1160
- floatingElement.setAttribute("popover-placement", currentPlacement);
1161
- }
1162
- }),
1163
- arrowMiddleware,
1164
- hide()
1165
- ]
1166
- });
1167
- if (arrowElement && result.middlewareData.arrow) {
1168
- Object.assign(arrowElement.style, {
1169
- left: toPx(result.middlewareData.arrow.x),
1170
- top: toPx(result.middlewareData.arrow.y)
1171
- });
1172
- }
1173
- floatingElement.style.setProperty("--_popover-position-x", toPx(result.x));
1174
- floatingElement.style.setProperty("--_popover-position-y", toPx(result.y));
1175
- }
1176
- function positionUpdater(referenceElement, floatingElement, options) {
1177
- return autoUpdate(
1178
- referenceElement,
1179
- floatingElement,
1180
- throttle(() => referenceElement && computePopoverPlacement(referenceElement, floatingElement, options), 1e3 / 30),
1181
- { animationFrame: true }
1182
- );
1183
- }
1184
-
1185
- class SharedResizeObserverInstance {
1186
- #observer;
1187
- #handlers = /* @__PURE__ */ new WeakMap();
1188
- observe(target, handler, options = { fpsLimit: 30 }) {
1189
- this.unobserve(target);
1190
- this.#handlers.set(target, throttle(handler, 1e3 / options.fpsLimit));
1191
- this.#observer ??= new ResizeObserver((entries) => {
1192
- if (!this.#observer) return;
1193
- for (const entry of entries) {
1194
- this.#handlers.get(entry.target)?.([entry], this.#observer);
1195
- }
1196
- });
1197
- this.#observer?.observe(target, options);
1198
- }
1199
- unobserve(target) {
1200
- this.#observer?.unobserve(target);
1201
- this.#handlers.delete(target);
1202
- }
1203
- }
1204
- const SharedResizeObserver = new SharedResizeObserverInstance();
1205
-
1206
- 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';