@odx/foundation 1.0.0-beta.9 → 1.0.0-beta.90

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