@lmvz-ds/components 0.35.2 → 0.36.1

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 (239) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/assets/icons/calendar.svg +7 -0
  3. package/cjs/{aria-validation-controller-BC0Eaiv4.js → aria-validation-controller-Do0uEK4t.js} +1 -1
  4. package/cjs/aria.constants-DPK5mQEL.js +65 -0
  5. package/cjs/{directional-focus-controller-DBat-oF7.js → directional-focus-controller-8Xd_7MHT.js} +3 -1
  6. package/cjs/{element-activation-controller-BHqCUgQv.js → element-activation-controller-DzTUocEO.js} +1 -1
  7. package/cjs/{element.util-CRS_YJ59.js → element.util-BlhcwmfR.js} +8 -54
  8. package/cjs/{index-TGsVZNDP.js → index-BgvZ4y-3.js} +12 -0
  9. package/cjs/lmvz-action-list.cjs.entry.js +5 -4
  10. package/cjs/lmvz-action.cjs.entry.js +1 -1
  11. package/cjs/lmvz-button-group.cjs.entry.js +3 -2
  12. package/cjs/lmvz-button_2.cjs.entry.js +6 -5
  13. package/cjs/lmvz-card.cjs.entry.js +1 -1
  14. package/cjs/lmvz-checkbox.cjs.entry.js +40 -6
  15. package/cjs/lmvz-chip.cjs.entry.js +2 -2
  16. package/cjs/lmvz-components.cjs.js +2 -2
  17. package/cjs/lmvz-datepicker.cjs.entry.js +2771 -0
  18. package/cjs/lmvz-header_2.cjs.entry.js +7 -6
  19. package/cjs/lmvz-input.cjs.entry.js +71 -15
  20. package/cjs/lmvz-link.cjs.entry.js +2 -2
  21. package/cjs/lmvz-menuitem.cjs.entry.js +6 -5
  22. package/cjs/lmvz-message.cjs.entry.js +2 -2
  23. package/cjs/lmvz-modal.cjs.entry.js +5 -4
  24. package/cjs/lmvz-popover.cjs.entry.js +25 -10
  25. package/cjs/lmvz-radio.cjs.entry.js +63 -5
  26. package/cjs/lmvz-select.cjs.entry.js +425 -18
  27. package/cjs/lmvz-snackbar.cjs.entry.js +2 -2
  28. package/cjs/lmvz-spinner.cjs.entry.js +2 -2
  29. package/cjs/lmvz-tab.cjs.entry.js +2 -2
  30. package/cjs/lmvz-tabs.cjs.entry.js +5 -4
  31. package/cjs/lmvz-toggle.cjs.entry.js +7 -4
  32. package/cjs/loader.cjs.js +2 -2
  33. package/collection/assets/icons/calendar.svg +7 -0
  34. package/collection/collection-manifest.json +1 -0
  35. package/collection/components/lmvz-checkbox/lmvz-checkbox.css +4 -2
  36. package/collection/components/lmvz-checkbox/lmvz-checkbox.js +68 -8
  37. package/collection/components/lmvz-datepicker/lmvz-datepicker.css +161 -0
  38. package/collection/components/lmvz-datepicker/lmvz-datepicker.js +1002 -0
  39. package/collection/components/lmvz-datepicker/lmvz-datepicker.utils.js +189 -0
  40. package/collection/components/lmvz-datepicker/test/lmvz-datepicker.utils.unit.js +300 -0
  41. package/collection/components/lmvz-header/lmvz-header.js +1 -1
  42. package/collection/components/lmvz-icon/lmvz-icon.js +1 -1
  43. package/collection/components/lmvz-input/lmvz-input.css +1 -1
  44. package/collection/components/lmvz-input/lmvz-input.js +85 -12
  45. package/collection/components/lmvz-link/lmvz-link.js +1 -1
  46. package/collection/components/lmvz-menuitem/lmvz-menuitem.js +1 -1
  47. package/collection/components/lmvz-message/lmvz-message.js +1 -1
  48. package/collection/components/lmvz-modal/lmvz-modal.js +1 -1
  49. package/collection/components/lmvz-popover/lmvz-popover.css +1 -1
  50. package/collection/components/lmvz-popover/lmvz-popover.js +50 -6
  51. package/collection/components/lmvz-radio/lmvz-radio.js +77 -9
  52. package/collection/components/lmvz-select/lmvz-select.css +96 -34
  53. package/collection/components/lmvz-select/lmvz-select.js +412 -21
  54. package/collection/components/lmvz-snackbar/lmvz-snackbar.js +1 -1
  55. package/collection/components/lmvz-spinner/lmvz-spinner.js +1 -1
  56. package/collection/components/lmvz-tab/lmvz-tab.js +1 -1
  57. package/collection/components/lmvz-tabs/lmvz-tabs.js +1 -1
  58. package/collection/components/lmvz-toggle/lmvz-toggle.js +21 -1
  59. package/collection/integration/header-integration/header-integration.js +1 -1
  60. package/collection/styles/fragments/_focus-within.css +2 -2
  61. package/collection/utils/aria/aria.constants.js +7 -0
  62. package/collection/utils/aria/directional-focus-controller.js +3 -1
  63. package/collection/utils/aria/listbox-controller.js +154 -0
  64. package/collection/utils/element/element.util.js +5 -0
  65. package/collection/utils/radio/radio-group-controller.js +17 -0
  66. package/components/index.d.ts +2 -0
  67. package/components/index.d.ts.bak +2 -0
  68. package/components/index.js +1 -1
  69. package/components/lmvz-action-list.js +1 -1
  70. package/components/lmvz-action.js +1 -1
  71. package/components/lmvz-button-group.js +1 -1
  72. package/components/lmvz-button.js +1 -1
  73. package/components/lmvz-card.js +1 -1
  74. package/components/lmvz-checkbox.js +1 -1
  75. package/components/lmvz-chip.js +1 -1
  76. package/components/lmvz-datepicker.d.ts +11 -0
  77. package/components/lmvz-datepicker.d.ts.bak +11 -0
  78. package/components/lmvz-datepicker.js +1 -0
  79. package/components/lmvz-header.js +1 -1
  80. package/components/lmvz-icon.js +1 -1
  81. package/components/lmvz-input.js +1 -1
  82. package/components/lmvz-link.js +1 -1
  83. package/components/lmvz-menuitem.js +1 -1
  84. package/components/lmvz-message.js +1 -1
  85. package/components/lmvz-modal.js +1 -1
  86. package/components/lmvz-popover.js +1 -1
  87. package/components/lmvz-radio.js +1 -1
  88. package/components/lmvz-select.js +1 -1
  89. package/components/lmvz-snackbar.js +1 -1
  90. package/components/lmvz-spinner.js +1 -1
  91. package/components/lmvz-tab.js +1 -1
  92. package/components/lmvz-tabs.js +1 -1
  93. package/components/lmvz-toggle.js +1 -1
  94. package/components/{p-Chj7BuUZ.js → p--FDdvoIg.js} +1 -1
  95. package/components/{p-CFTmV4XZ.js → p-BAj4FkUt.js} +1 -1
  96. package/components/p-BApwCp0R.js +1 -0
  97. package/components/{p-CxLd309t.js → p-BLMXiDE0.js} +1 -1
  98. package/components/{p-DGg7OzDl.js → p-BPYBmylI.js} +1 -1
  99. package/components/p-BhALzK62.js +1 -0
  100. package/components/{p-B_rnXUwq.js → p-Bnri3fEI.js} +1 -1
  101. package/components/p-C-pRMuMh.js +1 -0
  102. package/components/p-C5gRiLRR.js +1 -0
  103. package/components/{p-D5FL8n1q.js → p-CrQCHVKL.js} +1 -1
  104. package/components/p-DqdrUt_G.js +1 -0
  105. package/components/{p-CgK6-SEe.js → p-diOze8wI.js} +1 -1
  106. package/esm/{aria-validation-controller-BvOU1BO8.js → aria-validation-controller-Cp6pofER.js} +1 -1
  107. package/esm/aria.constants-DIyiticz.js +62 -0
  108. package/esm/{directional-focus-controller-DgAdCZrG.js → directional-focus-controller-QukTTWBE.js} +3 -1
  109. package/esm/{element-activation-controller-7PNSl6io.js → element-activation-controller-dxJZKMag.js} +1 -1
  110. package/esm/{element.util-BFcYfHYq.js → element.util-3ydVsxUW.js} +7 -54
  111. package/esm/{index-BPeerEwm.js → index-BOXP1Vx0.js} +12 -1
  112. package/esm/lmvz-action-list.entry.js +5 -4
  113. package/esm/lmvz-action.entry.js +1 -1
  114. package/esm/lmvz-button-group.entry.js +3 -2
  115. package/esm/lmvz-button_2.entry.js +6 -5
  116. package/esm/lmvz-card.entry.js +1 -1
  117. package/esm/lmvz-checkbox.entry.js +40 -6
  118. package/esm/lmvz-chip.entry.js +2 -2
  119. package/esm/lmvz-components.js +3 -3
  120. package/esm/lmvz-datepicker.entry.js +2769 -0
  121. package/esm/lmvz-header_2.entry.js +7 -6
  122. package/esm/lmvz-input.entry.js +71 -15
  123. package/esm/lmvz-link.entry.js +2 -2
  124. package/esm/lmvz-menuitem.entry.js +6 -5
  125. package/esm/lmvz-message.entry.js +2 -2
  126. package/esm/lmvz-modal.entry.js +5 -4
  127. package/esm/lmvz-popover.entry.js +25 -10
  128. package/esm/lmvz-radio.entry.js +63 -5
  129. package/esm/lmvz-select.entry.js +425 -18
  130. package/esm/lmvz-snackbar.entry.js +2 -2
  131. package/esm/lmvz-spinner.entry.js +2 -2
  132. package/esm/lmvz-tab.entry.js +2 -2
  133. package/esm/lmvz-tabs.entry.js +5 -4
  134. package/esm/lmvz-toggle.entry.js +7 -4
  135. package/esm/loader.js +3 -3
  136. package/hydrate/index.js +3474 -75
  137. package/hydrate/index.mjs +3474 -75
  138. package/lmvz-components/lmvz-components.esm.js +1 -1
  139. package/lmvz-components/{p-eb62d4af.entry.js → p-0af0211a.entry.js} +1 -1
  140. package/lmvz-components/{p-5bbbcfc0.entry.js → p-0f65d001.entry.js} +1 -1
  141. package/lmvz-components/p-137b1fe1.entry.js +1 -0
  142. package/lmvz-components/p-26dd9684.entry.js +1 -0
  143. package/lmvz-components/p-36f44108.entry.js +1 -0
  144. package/lmvz-components/p-398b5cf4.entry.js +1 -0
  145. package/lmvz-components/p-3a396fc8.entry.js +1 -0
  146. package/lmvz-components/{p-0c05f24b.entry.js → p-3d5867df.entry.js} +1 -1
  147. package/lmvz-components/p-40716828.entry.js +1 -0
  148. package/lmvz-components/{p-a887018d.entry.js → p-492adf21.entry.js} +1 -1
  149. package/lmvz-components/{p-24d13be6.entry.js → p-4fa6e72f.entry.js} +1 -1
  150. package/lmvz-components/p-70f1e31a.entry.js +1 -0
  151. package/lmvz-components/p-71d06d1d.entry.js +1 -0
  152. package/lmvz-components/{p-d45164a8.entry.js → p-7a7aa922.entry.js} +1 -1
  153. package/lmvz-components/p-88661c50.entry.js +1 -0
  154. package/lmvz-components/p-91eb71bb.entry.js +1 -0
  155. package/lmvz-components/p-BA3wizqg.js +1 -0
  156. package/lmvz-components/{p-BPeerEwm.js → p-BOXP1Vx0.js} +2 -2
  157. package/lmvz-components/{p-D9PQIBzA.js → p-BeY96W7m.js} +1 -1
  158. package/lmvz-components/p-CHxiS3ja.js +1 -0
  159. package/lmvz-components/{p-wlMjNjuv.js → p-CPSyM_e-.js} +1 -1
  160. package/lmvz-components/p-DIyiticz.js +1 -0
  161. package/lmvz-components/p-a680a7b2.entry.js +1 -0
  162. package/lmvz-components/{p-c2544495.entry.js → p-a6fe9b61.entry.js} +1 -1
  163. package/lmvz-components/{p-ecbd9e93.entry.js → p-a99acb02.entry.js} +1 -1
  164. package/lmvz-components/p-f16a19fc.entry.js +1 -0
  165. package/lmvz-components/p-f3f0ed49.entry.js +1 -0
  166. package/lmvz-components/p-f516a949.entry.js +1 -0
  167. package/manifest.json +1305 -188
  168. package/package.json +5 -1
  169. package/types/api/ds.constants.d.ts +0 -1
  170. package/types/api/ds.types.d.ts +9 -0
  171. package/types/components/lmvz-action/lmvz-action.d.ts +0 -1
  172. package/types/components/lmvz-action-list/lmvz-action-list.d.ts +0 -1
  173. package/types/components/lmvz-button/lmvz-button.d.ts +0 -1
  174. package/types/components/lmvz-button-group/lmvz-button-group.d.ts +0 -1
  175. package/types/components/lmvz-card/lmvz-card.d.ts +0 -1
  176. package/types/components/lmvz-checkbox/lmvz-checkbox.d.ts +9 -2
  177. package/types/components/lmvz-chip/lmvz-chip.d.ts +0 -1
  178. package/types/components/lmvz-datepicker/lmvz-datepicker.d.ts +77 -0
  179. package/types/components/lmvz-datepicker/lmvz-datepicker.utils.d.ts +22 -0
  180. package/types/components/lmvz-datepicker/test/lmvz-datepicker.utils.unit.d.ts +1 -0
  181. package/types/components/lmvz-header/lmvz-header.d.ts +0 -1
  182. package/types/components/lmvz-icon/lmvz-icon.d.ts +0 -1
  183. package/types/components/lmvz-input/lmvz-input.d.ts +8 -1
  184. package/types/components/lmvz-link/lmvz-link.d.ts +0 -1
  185. package/types/components/lmvz-menuitem/lmvz-menuitem.d.ts +0 -1
  186. package/types/components/lmvz-message/lmvz-message.d.ts +0 -1
  187. package/types/components/lmvz-message/public.d.ts +0 -1
  188. package/types/components/lmvz-modal/lmvz-modal.d.ts +0 -1
  189. package/types/components/lmvz-modal/test/testing.d.ts +0 -1
  190. package/types/components/lmvz-popover/lmvz-popover.d.ts +2 -1
  191. package/types/components/lmvz-radio/lmvz-radio.d.ts +12 -3
  192. package/types/components/lmvz-select/lmvz-select.d.ts +53 -5
  193. package/types/components/lmvz-snackbar/lmvz-snackbar.d.ts +0 -1
  194. package/types/components/lmvz-snackbar/public.d.ts +0 -1
  195. package/types/components/lmvz-snackbar/snackbar-controller.d.ts +0 -1
  196. package/types/components/lmvz-spinner/lmvz-spinner.d.ts +0 -1
  197. package/types/components/lmvz-tab/lmvz-tab.d.ts +0 -1
  198. package/types/components/lmvz-tabs/lmvz-tabs.d.ts +0 -1
  199. package/types/components/lmvz-toggle/lmvz-toggle.d.ts +1 -1
  200. package/types/components.d.ts +312 -12
  201. package/types/index.d.ts +0 -1
  202. package/types/utils/aria/aria-validation-controller.d.ts +0 -1
  203. package/types/utils/aria/aria.constants.d.ts +1 -1
  204. package/types/utils/aria/directional-focus-controller.d.ts +0 -1
  205. package/types/utils/aria/element-activation-controller.d.ts +0 -1
  206. package/types/utils/aria/listbox-controller.d.ts +42 -0
  207. package/types/utils/async/async.util.d.ts +1 -2
  208. package/types/utils/data/event.util.d.ts +0 -1
  209. package/types/utils/data/number.util.d.ts +0 -1
  210. package/types/utils/data/object.util.d.ts +0 -1
  211. package/types/utils/data/time.util.d.ts +0 -1
  212. package/types/utils/element/element.util.d.ts +1 -1
  213. package/types/utils/environment.d.ts +0 -1
  214. package/types/utils/icons/icons-registry.d.ts +0 -1
  215. package/types/utils/icons/icons.d.ts +0 -1
  216. package/types/utils/icons/icons.unit.d.ts +0 -1
  217. package/types/utils/icons/public.d.ts +0 -1
  218. package/types/utils/public.d.ts +0 -1
  219. package/types/utils/radio/radio-group-controller.d.ts +3 -1
  220. package/types/utils/stencil/assets.d.ts +0 -1
  221. package/types/utils/stencil/reactive-controller-host.d.ts +0 -1
  222. package/types/utils/stencil/stencil.util.d.ts +0 -1
  223. package/components/p-DLUsBYJH.js +0 -1
  224. package/components/p-zMWemcoB.js +0 -1
  225. package/lmvz-components/p-194a3af5.entry.js +0 -1
  226. package/lmvz-components/p-46edf36f.entry.js +0 -1
  227. package/lmvz-components/p-5ff55ba9.entry.js +0 -1
  228. package/lmvz-components/p-888e04d7.entry.js +0 -1
  229. package/lmvz-components/p-9dc420e2.entry.js +0 -1
  230. package/lmvz-components/p-BFcYfHYq.js +0 -1
  231. package/lmvz-components/p-BuEA0MWd.js +0 -1
  232. package/lmvz-components/p-aaa7691c.entry.js +0 -1
  233. package/lmvz-components/p-b6dd045b.entry.js +0 -1
  234. package/lmvz-components/p-c3e62aba.entry.js +0 -1
  235. package/lmvz-components/p-d4154a65.entry.js +0 -1
  236. package/lmvz-components/p-e4ce63b3.entry.js +0 -1
  237. package/lmvz-components/p-eb4c5a6f.entry.js +0 -1
  238. package/lmvz-components/p-f42b16e6.entry.js +0 -1
  239. package/lmvz-components/p-fbf066d9.entry.js +0 -1
@@ -1,5 +1,6 @@
1
- import { h, Host } from "@stencil/core";
1
+ import { h, Host, } from "@stencil/core";
2
2
  import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
3
+ import { ListboxController } from "../../utils/aria/listbox-controller";
3
4
  import { ReactiveControllerHost } from "../../utils/stencil/reactive-controller-host";
4
5
  let selectIdCounter = 0;
5
6
  export class LmvzSelect extends ReactiveControllerHost {
@@ -7,54 +8,258 @@ export class LmvzSelect extends ReactiveControllerHost {
7
8
  get validationEl() {
8
9
  return this.el;
9
10
  }
11
+ internals;
10
12
  selectId = `lmvz-select-${selectIdCounter++}`;
11
- nativeSelectEl;
13
+ triggerId = `${this.selectId}-trigger`;
14
+ popoverId = `${this.selectId}-listbox`;
15
+ triggerEl;
16
+ optionsSourceEl;
17
+ optionsMutationObserver;
18
+ initialValue;
19
+ initialValueCaptured = false;
20
+ flatOptions = [];
21
+ optionsById = new Map();
22
+ listboxController = new ListboxController({
23
+ onActiveChange: (id) => {
24
+ this.activeId = id;
25
+ },
26
+ onSelect: (id) => this.handleOptionSelect(id),
27
+ onClose: () => this.closePopover(),
28
+ });
29
+ get helperId() {
30
+ return this.helperText ? `${this.selectId}-helper` : undefined;
31
+ }
32
+ get showErrorMessage() {
33
+ return this.error && Boolean(this.errorMessage);
34
+ }
35
+ get errorId() {
36
+ return `${this.selectId}-error`;
37
+ }
38
+ get describedBy() {
39
+ const ids = [];
40
+ if (this.helperId)
41
+ ids.push(this.helperId);
42
+ if (this.showErrorMessage)
43
+ ids.push(this.errorId);
44
+ return ids.length > 0 ? ids.join(' ') : undefined;
45
+ }
12
46
  constructor() {
13
47
  super();
14
48
  this.addController(new AriaValidationController(this));
49
+ this.addController(this.listboxController);
15
50
  }
16
51
  lmvzChange;
17
52
  value;
18
53
  label;
19
54
  helperText;
55
+ nativeError = false;
56
+ errorFromProp = false;
57
+ get error() {
58
+ return this.errorFromProp || this.nativeError;
59
+ }
60
+ set error(value) {
61
+ this.errorFromProp = value;
62
+ }
63
+ errorMessage;
20
64
  disabled = false;
21
65
  required = false;
22
66
  name;
23
67
  size = 'default';
24
68
  highlighted = false;
25
69
  selectedLabel = '';
70
+ selectedId;
71
+ activeId;
72
+ isOpen = false;
73
+ optionGroups = [];
26
74
  get hasValue() {
27
75
  return Boolean(this.value);
28
76
  }
77
+ componentWillLoad() {
78
+ this.updateValidity();
79
+ super.componentWillLoad();
80
+ }
29
81
  componentDidLoad() {
30
- this.syncSelectedLabel();
82
+ this.handleSlotChange();
83
+ this.observeSlottedOptionMutations();
84
+ this.updateValidity();
31
85
  super.componentDidLoad();
32
86
  }
87
+ disconnectedCallback() {
88
+ this.optionsMutationObserver?.disconnect();
89
+ super.disconnectedCallback();
90
+ }
91
+ observeSlottedOptionMutations() {
92
+ if (typeof MutationObserver === 'undefined')
93
+ return;
94
+ this.optionsMutationObserver?.disconnect();
95
+ this.optionsMutationObserver = new MutationObserver(this.handleSlotChange);
96
+ this.optionsMutationObserver.observe(this.el, {
97
+ attributes: true,
98
+ attributeFilter: ['disabled', 'selected', 'value', 'label'],
99
+ characterData: true,
100
+ childList: true,
101
+ subtree: true,
102
+ });
103
+ }
104
+ async focusTrigger() {
105
+ this.triggerEl?.focus();
106
+ }
107
+ async blurTrigger() {
108
+ this.triggerEl?.blur();
109
+ }
110
+ async checkValidity() {
111
+ return this.internals.checkValidity?.() ?? true;
112
+ }
113
+ async reportValidity() {
114
+ return this.internals.reportValidity?.() ?? true;
115
+ }
116
+ async getValidationMessage() {
117
+ return this.internals.validationMessage ?? '';
118
+ }
119
+ formAssociatedCallback(form) {
120
+ if (!form)
121
+ return;
122
+ this.internals.setFormValue?.(this.value ?? '');
123
+ }
124
+ formResetCallback() {
125
+ this.internals.setValidity?.({});
126
+ this.value = this.initialValue;
127
+ this.updateValidity();
128
+ }
129
+ formStateRestoreCallback(state) {
130
+ this.value = state;
131
+ }
33
132
  handleValueChange(newValue) {
34
- if (this.nativeSelectEl && this.nativeSelectEl.value !== (newValue ?? '')) {
35
- this.nativeSelectEl.value = newValue ?? '';
133
+ this.applySelectionFromValue();
134
+ if (this.selectedId && !this.isOpen) {
135
+ this.listboxController.setActiveId(this.selectedId);
136
+ }
137
+ this.internals.setFormValue?.(newValue ?? '');
138
+ this.updateValidity();
139
+ }
140
+ handleRequiredChange() {
141
+ this.updateValidity();
142
+ }
143
+ handleDisabledChange(disabled) {
144
+ if (!disabled)
145
+ return;
146
+ this.closePopover();
147
+ this.triggerEl?.blur();
148
+ }
149
+ handleSlotChange = () => {
150
+ const container = this.optionsSourceEl;
151
+ if (!container)
152
+ return;
153
+ const { flat, groups } = parseOptionElements(container, this.selectId);
154
+ this.flatOptions = flat;
155
+ this.optionsById = new Map(flat.map((option) => [option.id, option]));
156
+ this.optionGroups = groups;
157
+ if (!this.value) {
158
+ const preselected = flat.find((option) => option.selected && !option.disabled);
159
+ if (preselected) {
160
+ this.value = preselected.value;
161
+ }
162
+ }
163
+ this.applySelectionFromValue();
164
+ this.listboxController.setOptions(flat.map(({ id, label, disabled }) => ({ id, label, disabled })));
165
+ if (!this.initialValueCaptured) {
166
+ this.initialValue = this.value;
167
+ this.initialValueCaptured = true;
168
+ }
169
+ };
170
+ applySelectionFromValue() {
171
+ const match = this.value ? this.flatOptions.find((option) => option.value === this.value) : undefined;
172
+ this.selectedId = match?.id;
173
+ this.selectedLabel = match?.label ?? '';
174
+ this.listboxController.setSelectedId(match?.id);
175
+ }
176
+ updateValidity() {
177
+ if (this.required && !this.value) {
178
+ this.internals.setValidity?.({ valueMissing: true }, 'Please select a value.', this.triggerEl);
179
+ return;
180
+ }
181
+ this.internals.setValidity?.({});
182
+ this.nativeError = false;
183
+ }
184
+ handleInvalid() {
185
+ this.nativeError = true;
186
+ }
187
+ handleOptionSelect(id) {
188
+ const option = this.optionsById.get(id);
189
+ if (!option)
190
+ return;
191
+ const isNewValue = option.value !== this.value;
192
+ this.value = option.value;
193
+ if (isNewValue) {
194
+ this.lmvzChange.emit(option.value);
36
195
  }
37
- this.syncSelectedLabel();
196
+ this.closePopover();
38
197
  }
39
- syncSelectedLabel() {
40
- if (!this.nativeSelectEl)
198
+ handleOptionClick = (option) => {
199
+ if (option.disabled || this.disabled)
41
200
  return;
42
- const idx = this.nativeSelectEl.selectedIndex;
43
- this.selectedLabel = idx >= 0 ? (this.nativeSelectEl.options[idx]?.text ?? '') : '';
44
- }
45
- handleChange = (event) => {
46
- const select = event.target;
47
- this.value = select.value;
48
- this.syncSelectedLabel();
49
- this.lmvzChange.emit(select.value);
201
+ this.listboxController.selectOption(option.id);
50
202
  };
203
+ handleLabelClick = () => {
204
+ if (this.disabled)
205
+ return;
206
+ this.triggerEl?.focus();
207
+ this.openPopover();
208
+ };
209
+ handleTriggerClick = () => {
210
+ if (this.disabled)
211
+ return;
212
+ if (this.isOpen) {
213
+ this.closePopover();
214
+ }
215
+ else {
216
+ this.openPopover();
217
+ }
218
+ };
219
+ handleTriggerKeydown = (event) => {
220
+ if (this.disabled)
221
+ return;
222
+ if (!this.isOpen) {
223
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter' || event.key === ' ') {
224
+ event.preventDefault();
225
+ this.openPopover();
226
+ }
227
+ return;
228
+ }
229
+ this.listboxController.handleKeydown(event);
230
+ };
231
+ handleTriggerBlur = () => {
232
+ this.closePopover();
233
+ };
234
+ handlePopoverClose = () => {
235
+ this.isOpen = false;
236
+ this.listboxController.clearTypeahead();
237
+ };
238
+ openPopover() {
239
+ if (this.isOpen || this.disabled)
240
+ return;
241
+ this.isOpen = true;
242
+ }
243
+ closePopover() {
244
+ if (!this.isOpen)
245
+ return;
246
+ this.isOpen = false;
247
+ this.listboxController.clearTypeahead();
248
+ }
249
+ renderOptionGroups() {
250
+ return this.optionGroups.map((group, groupIndex) => group.label ? (h("div", { role: "group", "aria-label": group.label, key: `lmvz-select-group-${groupIndex}` }, group.options.map((option) => this.renderOption(option)))) : (group.options.map((option) => this.renderOption(option))));
251
+ }
252
+ renderOption(option) {
253
+ return (h("div", { id: option.id, key: option.id, role: "option", class: "lmvz-select-option", "aria-selected": option.id === this.selectedId ? 'true' : 'false', "aria-disabled": option.disabled ? 'true' : undefined, "data-active": option.id === this.activeId ? 'true' : undefined, onMouseDown: (event) => event.preventDefault(), onClick: () => this.handleOptionClick(option) }, option.label));
254
+ }
51
255
  render() {
52
256
  const hasValue = this.hasValue;
53
257
  const shouldShowLabel = hasValue;
54
- return (h(Host, { key: 'f1180d4a5f1c30414b06c19314eb75630aa181f7', "data-highlighted": String(this.highlighted) }, h("div", { key: '01088c7f3315faab1fb23c99cf8b30f7d59abfc6', class: hasValue ? 'select-wrapper has-value' : 'select-wrapper' }, h("label", { key: '34d23292b6b65fac000f822e1e2839e28b1bfee9', htmlFor: this.selectId, class: shouldShowLabel ? 'floating-label' : 'assistive-label' }, this.label, this.required && shouldShowLabel && h("span", { key: 'ba171cdd9b53f8fa7b7fcb2c39a0b4aa69940b95', "aria-hidden": "true" }, " *")), h("div", { key: '798a6ef187b4aaaa45ecb3d6f94c30e7facb7a38', "aria-hidden": "true" }, h("span", { key: '33ea2169d94f4f8cf6263ed0c3bd6a9e593207a4' }, hasValue ? this.selectedLabel : this.label, this.required && !hasValue && h("span", { key: '0ea2d4987587a1a42dfd037dcefeed3f1b3356ef', "aria-hidden": "true" }, " *")), h("span", { key: '7bd24b3921cc5cd261f563476a79d61a288d60bb' }, h("svg", { key: '9887853724abada1fe36f7225db7903ee6e4040d', width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { key: 'b55a82230d46944ca3bd46f00f8c59b1a75ab8b8', d: "M20.3334 8.66663L12.0001 17L3.66675 8.66663", stroke: "currentColor", "stroke-width": "1.75", "stroke-linecap": "round", "stroke-linejoin": "round" })))), h("select", { key: 'd786f49b4522baf4c803ed3046b3606f29d6dae1', id: this.selectId, ref: (el) => (this.nativeSelectEl = el), name: this.name, disabled: this.disabled, required: this.required, "aria-label": this.label, onChange: this.handleChange }, !hasValue && h("option", { key: '5ffa7ffb7cd79c28a8bd212cc4d123dceb77aad4', value: "", disabled: true, selected: true, hidden: true }), h("slot", { key: '8a4141ead35cfd07c14d869715397d12ea8b64d7' }))), this.helperText && h("div", { key: 'dc5ccd28b0a903f6ed674d994e302caed1d9e9bb', role: "status" }, this.helperText)));
258
+ return (h(Host, { key: '0bcc303a802db20a6be6558b8add53d0fa398493', "data-highlighted": String(this.highlighted) }, h("div", { key: 'e248f8277b4786b34dfd064cb9c7b70302cf018a', class: hasValue ? 'select-wrapper has-value' : 'select-wrapper' }, h("label", { key: '1c97c830d5782cadad98fb895d70c438031d3457', htmlFor: this.triggerId, class: shouldShowLabel ? 'floating-label' : 'assistive-label', onMouseDown: (event) => event.preventDefault(), onClick: this.handleLabelClick }, this.label, this.required && shouldShowLabel && h("span", { key: '16157962846bffc111f5c672852f7b23e9ed2b73', "aria-hidden": "true" }, " *")), h("div", { key: 'bc5e3e6b335723cfd9872ff955a1e8d664d4eeb8', id: this.triggerId, ref: (el) => (this.triggerEl = el), class: "select-trigger", role: "combobox", tabIndex: this.disabled ? -1 : 0, "aria-haspopup": "listbox", "aria-expanded": String(this.isOpen), "aria-controls": this.popoverId, "aria-activedescendant": this.isOpen ? this.activeId : undefined, "aria-label": hasValue ? `${this.label}, ${this.selectedLabel}` : this.label, "aria-disabled": this.disabled ? 'true' : undefined, "aria-required": this.required ? 'true' : 'false', "aria-invalid": this.error ? 'true' : 'false', "aria-errormessage": this.showErrorMessage ? this.errorId : undefined, "aria-describedby": this.describedBy, onClick: this.handleTriggerClick, onKeyDown: this.handleTriggerKeydown, onBlur: this.handleTriggerBlur }, h("span", { key: '620c6108f679c8e5563c0e21d7b89d71434c01a2' }, hasValue ? this.selectedLabel : this.label, this.required && !hasValue && h("span", { key: 'a2183941c7843bae3e9989f8e8b26be28fbbf6d7', "aria-hidden": "true" }, " *")), h("span", { key: 'b57e14bda44dc0de5a35623a5cb203b7f570c802', "aria-hidden": "true" }, h("svg", { key: '71ac319e398f07f7e65fe1f73f6d2a7c08b631a8', width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: '80b4a978471251ee8d2cce2d74a48fad750db125', d: "M20.3334 8.66663L12.0001 17L3.66675 8.66663", stroke: "currentColor", "stroke-width": "1.75", "stroke-linecap": "round", "stroke-linejoin": "round" })))), h("lmvz-popover", { key: '15528c9a3f1404c385f4eb865cf78ef5891dcb32', id: this.popoverId, anchor: this.triggerId, open: this.isOpen, containerRole: "listbox", autoFocus: false, label: this.label, onLmvzClose: this.handlePopoverClose, size: "sm" }, this.renderOptionGroups()), h("div", { key: 'f1b833973497e6dfd2013522e067382c73baa7a1', class: "lmvz-select-native-options", hidden: true, "aria-hidden": "true", ref: (el) => (this.optionsSourceEl = el) }, h("slot", { key: '670bf62c50cbdd965342279b99e303614771ffa1', onSlotchange: this.handleSlotChange }))), this.helperText && (h("div", { key: '849e35da09bff25896b08f275c265baa0ee12960', id: this.helperId, role: "status" }, this.helperText)), this.showErrorMessage && (h("div", { key: 'd01c2dca8767aa815d08d895f308c42150cc3263', id: this.errorId, role: "alert" }, this.errorMessage))));
55
259
  }
56
260
  static get is() { return "lmvz-select"; }
57
261
  static get encapsulation() { return "scoped"; }
262
+ static get formAssociated() { return true; }
58
263
  static get originalStyleUrls() {
59
264
  return {
60
265
  "$": ["./lmvz-select.css"]
@@ -124,6 +329,47 @@ export class LmvzSelect extends ReactiveControllerHost {
124
329
  "reflect": false,
125
330
  "attribute": "helper-text"
126
331
  },
332
+ "error": {
333
+ "type": "boolean",
334
+ "mutable": false,
335
+ "complexType": {
336
+ "original": "boolean",
337
+ "resolved": "boolean",
338
+ "references": {}
339
+ },
340
+ "required": false,
341
+ "optional": false,
342
+ "docs": {
343
+ "tags": [{
344
+ "name": "default",
345
+ "text": "false"
346
+ }],
347
+ "text": "Whether the select is in an error state.\nWhen not set manually, this will automatically reflect native HTML5 validation state"
348
+ },
349
+ "getter": true,
350
+ "setter": true,
351
+ "reflect": true,
352
+ "attribute": "error"
353
+ },
354
+ "errorMessage": {
355
+ "type": "string",
356
+ "mutable": false,
357
+ "complexType": {
358
+ "original": "string",
359
+ "resolved": "string | undefined",
360
+ "references": {}
361
+ },
362
+ "required": false,
363
+ "optional": true,
364
+ "docs": {
365
+ "tags": [],
366
+ "text": "Error message displayed below the select field when error is true."
367
+ },
368
+ "getter": false,
369
+ "setter": false,
370
+ "reflect": false,
371
+ "attribute": "error-message"
372
+ },
127
373
  "disabled": {
128
374
  "type": "boolean",
129
375
  "mutable": false,
@@ -182,11 +428,11 @@ export class LmvzSelect extends ReactiveControllerHost {
182
428
  "optional": true,
183
429
  "docs": {
184
430
  "tags": [],
185
- "text": "Name attribute passed to the native select for form submission."
431
+ "text": "Name attribute for form submission via ElementInternals."
186
432
  },
187
433
  "getter": false,
188
434
  "setter": false,
189
- "reflect": false,
435
+ "reflect": true,
190
436
  "attribute": "name"
191
437
  },
192
438
  "size": {
@@ -231,7 +477,7 @@ export class LmvzSelect extends ReactiveControllerHost {
231
477
  "name": "default",
232
478
  "text": "false"
233
479
  }],
234
- "text": "Whether the select has an active filter or selection that should be visually\ndistinguished (e.g. a filter chip is applied).\n\nWhen `true`:\n- The host attribute `highlighted` is present (CSS: `:host([highlighted])`).\n- The host attribute `data-highlighted=\"true\"` is set for assistive-technology\n consumers that observe data attributes. When `false`, `data-highlighted` is\n set to `\"false\"`.\n\nNote: `aria-pressed` and `aria-selected` are intentionally not used here.\n`aria-pressed` is reserved for toggle-button roles; `aria-selected` is\nreserved for option/listbox roles. The `data-highlighted` attribute provides\nthe accessible contract without conflicting with native `<select>` semantics."
480
+ "text": "Whether the select has an active filter or selection that should be visually\ndistinguished (e.g. a filter chip is applied).\n\nWhen `true`:\n- The host attribute `highlighted` is present (CSS: `:host([highlighted])`).\n- The host attribute `data-highlighted=\"true\"` is set for assistive-technology\n consumers that observe data attributes. When `false`, `data-highlighted` is\n set to `\"false\"`.\n\nNote: `aria-pressed` is intentionally not used here; it is reserved for toggle-button\nroles. `aria-selected` is reserved for this component's own `role=\"option\"` elements.\nThe `data-highlighted` attribute provides the accessible contract for this state."
235
481
  },
236
482
  "getter": false,
237
483
  "setter": false,
@@ -243,7 +489,12 @@ export class LmvzSelect extends ReactiveControllerHost {
243
489
  }
244
490
  static get states() {
245
491
  return {
246
- "selectedLabel": {}
492
+ "nativeError": {},
493
+ "selectedLabel": {},
494
+ "selectedId": {},
495
+ "activeId": {},
496
+ "isOpen": {},
497
+ "optionGroups": {}
247
498
  };
248
499
  }
249
500
  static get events() {
@@ -264,11 +515,151 @@ export class LmvzSelect extends ReactiveControllerHost {
264
515
  }
265
516
  }];
266
517
  }
518
+ static get methods() {
519
+ return {
520
+ "focusTrigger": {
521
+ "complexType": {
522
+ "signature": "() => Promise<void>",
523
+ "parameters": [],
524
+ "references": {
525
+ "Promise": {
526
+ "location": "global",
527
+ "id": "global::Promise"
528
+ }
529
+ },
530
+ "return": "Promise<void>"
531
+ },
532
+ "docs": {
533
+ "text": "Sets focus on the combobox trigger.",
534
+ "tags": []
535
+ }
536
+ },
537
+ "blurTrigger": {
538
+ "complexType": {
539
+ "signature": "() => Promise<void>",
540
+ "parameters": [],
541
+ "references": {
542
+ "Promise": {
543
+ "location": "global",
544
+ "id": "global::Promise"
545
+ }
546
+ },
547
+ "return": "Promise<void>"
548
+ },
549
+ "docs": {
550
+ "text": "Removes focus from the combobox trigger.",
551
+ "tags": []
552
+ }
553
+ },
554
+ "checkValidity": {
555
+ "complexType": {
556
+ "signature": "() => Promise<boolean>",
557
+ "parameters": [],
558
+ "references": {
559
+ "Promise": {
560
+ "location": "global",
561
+ "id": "global::Promise"
562
+ }
563
+ },
564
+ "return": "Promise<boolean>"
565
+ },
566
+ "docs": {
567
+ "text": "Returns whether the select satisfies its validation constraints.",
568
+ "tags": []
569
+ }
570
+ },
571
+ "reportValidity": {
572
+ "complexType": {
573
+ "signature": "() => Promise<boolean>",
574
+ "parameters": [],
575
+ "references": {
576
+ "Promise": {
577
+ "location": "global",
578
+ "id": "global::Promise"
579
+ }
580
+ },
581
+ "return": "Promise<boolean>"
582
+ },
583
+ "docs": {
584
+ "text": "Reports validation errors to the user.",
585
+ "tags": []
586
+ }
587
+ },
588
+ "getValidationMessage": {
589
+ "complexType": {
590
+ "signature": "() => Promise<string>",
591
+ "parameters": [],
592
+ "references": {
593
+ "Promise": {
594
+ "location": "global",
595
+ "id": "global::Promise"
596
+ }
597
+ },
598
+ "return": "Promise<string>"
599
+ },
600
+ "docs": {
601
+ "text": "Returns the current validation message, if any.",
602
+ "tags": []
603
+ }
604
+ }
605
+ };
606
+ }
267
607
  static get elementRef() { return "el"; }
268
608
  static get watchers() {
269
609
  return [{
270
610
  "propName": "value",
271
611
  "methodName": "handleValueChange"
612
+ }, {
613
+ "propName": "required",
614
+ "methodName": "handleRequiredChange"
615
+ }, {
616
+ "propName": "disabled",
617
+ "methodName": "handleDisabledChange"
272
618
  }];
273
619
  }
620
+ static get listeners() {
621
+ return [{
622
+ "name": "invalid",
623
+ "method": "handleInvalid",
624
+ "target": undefined,
625
+ "capture": false,
626
+ "passive": false
627
+ }];
628
+ }
629
+ static get attachInternalsMemberName() { return "internals"; }
630
+ }
631
+ function parseOptionElements(container, idPrefix) {
632
+ const flat = [];
633
+ const groups = [];
634
+ let looseGroup;
635
+ let optionIndex = 0;
636
+ const toOptionData = (optionEl, disabledOverride = false) => {
637
+ const option = optionEl;
638
+ const data = {
639
+ id: `${idPrefix}-option-${optionIndex++}`,
640
+ value: option.value,
641
+ label: (option.textContent ?? '').trim(),
642
+ disabled: disabledOverride || option.disabled,
643
+ selected: option.selected,
644
+ };
645
+ flat.push(data);
646
+ return data;
647
+ };
648
+ Array.from(container.children).forEach((child) => {
649
+ if (child.tagName === 'OPTGROUP') {
650
+ looseGroup = undefined;
651
+ const optgroup = child;
652
+ const options = Array.from(optgroup.querySelectorAll('option')).map((option) => toOptionData(option, optgroup.disabled));
653
+ groups.push({ label: optgroup.label || undefined, options });
654
+ return;
655
+ }
656
+ if (child.tagName === 'OPTION') {
657
+ if (!looseGroup) {
658
+ looseGroup = { label: undefined, options: [] };
659
+ groups.push(looseGroup);
660
+ }
661
+ looseGroup.options.push(toOptionData(child));
662
+ }
663
+ });
664
+ return { flat, groups };
274
665
  }
@@ -58,7 +58,7 @@ export class LmvzSnackbar {
58
58
  this.el.dispatchEvent(new CustomEvent('lmvzAction', { bubbles: false, composed: false }));
59
59
  };
60
60
  render() {
61
- return (h(Host, { key: '6c2898f187ed9b456dd0c13294eb466270b116cb', class: this.animationClass }, h("lmvz-icon", { key: '9b4903f0e2099d44f0ed1773ed23f948b894f603', icon: STATUS_SVG[this.status], size: "md", weight: "bold" }), h("span", { key: '38163523ce0bba29dbe387e5c808ae9f5f2c2c55', class: "message" }, this.message), this.actionLabel && (h("lmvz-button", { key: 'bf5eb3e5075dec7c10f95a46db207ccb3181c88b', variant: "tertiary", scale: "small", onLmvzActivation: this.handleActionClick }, this.actionLabel))));
61
+ return (h(Host, { key: 'f58c7657bf5511c72930dfc54ace4af1ff7f3554', class: this.animationClass }, h("lmvz-icon", { key: '8632b42b9b246bf58480fb17ca336ce5f0883845', icon: STATUS_SVG[this.status], size: "md", weight: "bold" }), h("span", { key: '4ca56d2cdf29415c6d21cc50399dc28aebb8de99', class: "message" }, this.message), this.actionLabel && (h("lmvz-button", { key: 'd09043056b968421143aa180f464effcd7b781fe', variant: "tertiary", scale: "small", onLmvzActivation: this.handleActionClick }, this.actionLabel))));
62
62
  }
63
63
  static get is() { return "lmvz-snackbar"; }
64
64
  static get encapsulation() { return "shadow"; }
@@ -4,7 +4,7 @@ export class LmvzSpinner {
4
4
  ariaLabel;
5
5
  render() {
6
6
  const hasLabel = !!this.ariaLabel?.trim();
7
- return (h(Host, { key: '75f8aabfe2eae72d29c5f0aa0663d0c37286ab78', role: hasLabel ? 'status' : undefined, "aria-label": hasLabel ? this.ariaLabel : undefined, "aria-hidden": hasLabel ? undefined : 'true' }, h("svg", { key: 'aadf9daaa1f363752e08eed3136fc8a8f15d3bdf', part: "indicator", viewBox: "0 0 16 16", "aria-hidden": "true" }, h("circle", { key: 'e658f4be70b5bd03b3828071cbce977576afa3c8', pathLength: "100", cx: "8", cy: "8", r: "6" }))));
7
+ return (h(Host, { key: 'cf60fcf652f377a66596cc51138bb73f7465a4e7', role: hasLabel ? 'status' : undefined, "aria-label": hasLabel ? this.ariaLabel : undefined, "aria-hidden": hasLabel ? undefined : 'true' }, h("svg", { key: '121ab46a591242fbc0f1c3540e8f2a7b72c9582a', part: "indicator", viewBox: "0 0 16 16", "aria-hidden": "true" }, h("circle", { key: 'fe649394c9bd6e7a06113e9a50b595bb890a6fac', pathLength: "100", cx: "8", cy: "8", r: "6" }))));
8
8
  }
9
9
  static get is() { return "lmvz-spinner"; }
10
10
  static get encapsulation() { return "shadow"; }
@@ -14,7 +14,7 @@ export class LmvzTab {
14
14
  this.el.dispatchEvent(new CustomEvent('lmvzTabReady', { bubbles: true, composed: false }));
15
15
  }
16
16
  render() {
17
- return (h(Host, { key: '6bb908c4956e84cd344fc8e81b400d33bb2dce98' }, h("button", { key: 'fbc5b650c9bfb5653d17f9a66a14ffbf0fe87f83', part: "button", role: "tab", disabled: this.disabled, "aria-selected": String(this.selected), "aria-disabled": this.disabled ? 'true' : undefined, tabIndex: 0 }, h("slot", { key: 'a16da4d11ecca9db3d03da3b0076b698295ead1f', name: "media", ref: (el) => (this.mediaSlotEl = el), onSlotchange: this.handleMediaSlotChange }), h("span", { key: 'e9e83fd4aa556716af3c7b7e52e1e1d8a5a33061', class: "label" }, h("slot", { key: 'a4c0378e62d67d7bcc772ff6a77ae1a86f41208c' })), h("span", { key: 'de03b763d99f55b8773334df3d18c2d3855de4de', "aria-hidden": "true", part: "indicator", class: "indicator" }))));
17
+ return (h(Host, { key: '4380fe35cacb11bc7114664c126504e8f4fb09a0' }, h("button", { key: 'ac77443cbba5c94f864820088f60c0bac23d0775', part: "button", role: "tab", disabled: this.disabled, "aria-selected": String(this.selected), "aria-disabled": this.disabled ? 'true' : undefined, tabIndex: 0 }, h("slot", { key: '9988497505ca3effa6c41011ac408a5d25629ca1', name: "media", ref: (el) => (this.mediaSlotEl = el), onSlotchange: this.handleMediaSlotChange }), h("span", { key: '70566c46fba36b8717aa82917e45abd39cd7a2ea', class: "label" }, h("slot", { key: 'a595738c387ee2f4f77f6ccdfdfb0589751ce999' })), h("span", { key: '933758dc965d1151ca6a96367ea40290189384ad', "aria-hidden": "true", part: "indicator", class: "indicator" }))));
18
18
  }
19
19
  static get is() { return "lmvz-tab"; }
20
20
  static get encapsulation() { return "shadow"; }
@@ -235,7 +235,7 @@ export class LmvzTabs extends ReactiveControllerHost {
235
235
  this.selectTab(value);
236
236
  };
237
237
  render() {
238
- return (h(Host, { key: '98df29f336a3ea47efa6c76a773de28c5174c718', onClick: this.handleTabClick, onKeydown: this.handleKeydown }, h("div", { key: '7e35ae180c4ebf2f5a82e0fad0977cd3c38ac659', role: "tablist", "aria-orientation": this.orientation, class: "tablist" }, h("slot", { key: '2520bc8b8988a60b37a067828ad237bf8dcfcc59', ref: (el) => (this.tabSlotEl = el) })), h("div", { key: 'bd4a954b6caca2d9f2eb588f58590821ec4af888', part: "panels-container", class: "panels-container" }, h("slot", { key: 'b4dffff530328e6e4c8d305895ef4dd2d5952757', name: "panels", ref: (el) => (this.panelSlotEl = el) }))));
238
+ return (h(Host, { key: '33205038c047420618800be3ef755e1d13a0127c', onClick: this.handleTabClick, onKeydown: this.handleKeydown }, h("div", { key: 'e803f772c5b187326fc80cfa2d3b9d74f6ee1df8', role: "tablist", "aria-orientation": this.orientation, class: "tablist" }, h("slot", { key: '6871a7b6b26c6251ceb544c03b245450aa53373d', ref: (el) => (this.tabSlotEl = el) })), h("div", { key: '17721962da2ecf107a5b878dea996812c61be998', part: "panels-container", class: "panels-container" }, h("slot", { key: '485de66efc7812ecb2368a6b01b0d8ab63971497', name: "panels", ref: (el) => (this.panelSlotEl = el) }))));
239
239
  }
240
240
  static get is() { return "lmvz-tabs"; }
241
241
  static get encapsulation() { return "shadow"; }
@@ -53,6 +53,9 @@ export class LmvzToggle extends ReactiveControllerHost {
53
53
  async reportValidity() {
54
54
  return this.nativeInputElement?.reportValidity?.() ?? false;
55
55
  }
56
+ async getValidationMessage() {
57
+ return this.nativeInputElement?.validationMessage ?? '';
58
+ }
56
59
  async getInputElement() {
57
60
  if (!this.nativeInputElement) {
58
61
  await new Promise((resolve) => componentOnReady(this.el, resolve));
@@ -65,7 +68,7 @@ export class LmvzToggle extends ReactiveControllerHost {
65
68
  this.lmvzChange.emit(newChecked);
66
69
  };
67
70
  render() {
68
- return (h(Host, { key: '901f821ddae696fe877435bf20d08e4032cd61ee' }, h("span", { key: 'bbac0ab3e40e426be511cc49a0dcb2497edd7a9a', class: "track" }, h("input", { key: '1df7a78df28517189f690c6d453193e30d97d9ea', type: "checkbox", role: "switch", id: this.toggleId, checked: this.checked, disabled: this.disabled, required: this.required, name: this.name, value: this.value, form: this.form, ref: (el) => (this.nativeInputElement = el), onChange: this.handleChange }), h("span", { key: 'e975c1c280983355f2504fba15553a9f19e4216f', class: "thumb", "aria-hidden": "true" })), h("label", { key: '09b3305a1d0d6c116310cf88d1f8a92f6856f57e', htmlFor: this.toggleId }, this.label)));
71
+ return (h(Host, { key: 'a0e0272a8457ee6b07a102aa10e5a7c0292a55d9' }, h("span", { key: '5d14029bee4b66f5ed2ee1eb189a1d80a68abe3e', class: "track" }, h("input", { key: '926b1ca6065750717577ece30e8e78b9004ec0e8', type: "checkbox", role: "switch", id: this.toggleId, checked: this.checked, disabled: this.disabled, required: this.required, name: this.name, value: this.value, form: this.form, ref: (el) => (this.nativeInputElement = el), onChange: this.handleChange }), h("span", { key: 'bdee06bab6acba72d019134828f7415d7b347c49', class: "thumb", "aria-hidden": "true" })), h("label", { key: 'b8eaa9305352f7146bf95bb517766310517d60e6', htmlFor: this.toggleId }, this.label)));
69
72
  }
70
73
  static get is() { return "lmvz-toggle"; }
71
74
  static get encapsulation() { return "scoped"; }
@@ -321,6 +324,23 @@ export class LmvzToggle extends ReactiveControllerHost {
321
324
  "tags": []
322
325
  }
323
326
  },
327
+ "getValidationMessage": {
328
+ "complexType": {
329
+ "signature": "() => Promise<string>",
330
+ "parameters": [],
331
+ "references": {
332
+ "Promise": {
333
+ "location": "global",
334
+ "id": "global::Promise"
335
+ }
336
+ },
337
+ "return": "Promise<string>"
338
+ },
339
+ "docs": {
340
+ "text": "Returns the current validation message, if any.",
341
+ "tags": []
342
+ }
343
+ },
324
344
  "getInputElement": {
325
345
  "complexType": {
326
346
  "signature": "() => Promise<HTMLInputElement | undefined>",
@@ -20,7 +20,7 @@ export class HeaderIntegration {
20
20
  this.activeNav = navId;
21
21
  }
22
22
  render() {
23
- return (h(Host, { key: '0f1fa3c964fddcf63eb73be55916d8c2f4a630e5' }, h("lmvz-header", { key: '89d4a59c997a1ff05e536fdde5898a3763f86653', lmvzActiveNav: this.activeNav }, h("lmvz-menuitem", { key: 'fa781e3736311d06fab93203736bac84a3900450', slot: "nav-primary", id: "lehrmittel", onLmvzActivation: this.activate.bind(this) }, h("a", { key: '7dd41dd42c216fb13f0702db2365c8445ddd99a3', href: "#" }, "Lehrmittel")), h("lmvz-menuitem", { key: 'd3b5ea3523c3cb908d543b9a37dd6e6e00f1b034', slot: "nav-primary", id: "verwaltung", onLmvzActivation: this.activate.bind(this) }, h("a", { key: '18dc59245cc938959ac693a910687eaa7be5d657', href: "#" }, "Verwaltung")), h("lmvz-menuitem", { key: '149f5349580f0934b41c86bc77cc8a86659fc89f', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: 'd71d55a21fee01b1f8041e7bb60f5848374dd133', ...typedIconFromSet('lmvz', 'edit') }), "Deutsch 7"), h("lmvz-menuitem", { key: '2821335ea576bff31d06c684544ec049985dc054', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: '8f1779694542aa3f28b15deaa4c0690b34280984', ...typedIconFromSet('lmvz', 'edit') }), "Mathe 2"), h("lmvz-menuitem", { key: '993dd7117c561c3428e27623e290a782997ca638', slot: "connect-nav-verwaltung" }, h("lmvz-icon", { key: 'a95c11de062609b7d88d369872c8521472decaac', ...typedIconFromSet('lmvz', 'settings') }), "iwas mit Verwaltung"), h("lmvz-menuitem", { key: '6fd78c92f39adf2eeba6e562cd7eb1a5a9fc0660', slot: "connect-nav-verwaltung", "aria-label": "Einstellungen" }, h("lmvz-icon", { key: '579ec3fc78d316e2746b7bd9744f05eb7fc7989b', ...typedIconFromSet('lmvz', 'settings') })), h("lmvz-button", { key: '836beb07c150f02095431d29f4b7945cb2b6e55d', slot: "actions", "aria-label": "Benutzerkonto" }, h("lmvz-icon", { key: 'e47cca91742bf91fca8bbb20e47073deb6e7463a', ...typedIconFromSet('lmvz', 'user'), size: "lg" })))));
23
+ return (h(Host, { key: 'fcade3c1829fa6c3c1911c7a98dffd57e08ce1fe' }, h("lmvz-header", { key: '69a4966cbd57347e693b2a28d71c3a711a27dece', lmvzActiveNav: this.activeNav }, h("lmvz-menuitem", { key: 'c9fe5ea860f09a7bfb10742ca59494a56a929634', slot: "nav-primary", id: "lehrmittel", onLmvzActivation: this.activate.bind(this) }, h("a", { key: '509de0e603fd7caab3c9afb3c33ba426687af626', href: "#" }, "Lehrmittel")), h("lmvz-menuitem", { key: '4b71922d9b24e498ffb9fad4ed51fe8129cdd24b', slot: "nav-primary", id: "verwaltung", onLmvzActivation: this.activate.bind(this) }, h("a", { key: 'f2748efdad33464b699d149658bffa081dfd40fc', href: "#" }, "Verwaltung")), h("lmvz-menuitem", { key: '928f2938d1869daff7392eae819d35915b3b354f', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: '4c685e59db6250418fbd4158ab4e3b9e220e6515', ...typedIconFromSet('lmvz', 'edit') }), "Deutsch 7"), h("lmvz-menuitem", { key: '904f4f480f313df8bb0d90ff871fa81d4e456bcd', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: '6048794171f6f5a121bd49ac9c74eb08d67cb714', ...typedIconFromSet('lmvz', 'edit') }), "Mathe 2"), h("lmvz-menuitem", { key: 'd27207e37a1f3c2a1190ef4f226e95447f3d5be2', slot: "connect-nav-verwaltung" }, h("lmvz-icon", { key: 'ab52392ef4174e0dca7db6e827169e6d6b96ef72', ...typedIconFromSet('lmvz', 'settings') }), "iwas mit Verwaltung"), h("lmvz-menuitem", { key: '80ee897b06f16a11b4bc8cbaefa47c5e91982248', slot: "connect-nav-verwaltung", "aria-label": "Einstellungen" }, h("lmvz-icon", { key: '62abb091e83d38a9b092609c4b4077d743c71238', ...typedIconFromSet('lmvz', 'settings') })), h("lmvz-button", { key: '97432e879cbad971666621c9fce3c83c8e380c6c', slot: "actions", "aria-label": "Benutzerkonto" }, h("lmvz-icon", { key: '991b8c9569eae3e9e073b421066369c62b348797', ...typedIconFromSet('lmvz', 'user'), size: "lg" })))));
24
24
  }
25
25
  static get is() { return "header-integration"; }
26
26
  static get encapsulation() { return "shadow"; }
@@ -1,4 +1,4 @@
1
- :host(:focus-within) {
1
+ :host:has(:focus-visible) {
2
2
  outline: var(--lmvz-ds-outline, 1px solid #0e7ab4);
3
3
  outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem));
4
4
  }
@@ -6,7 +6,7 @@
6
6
  /* Forced Colors / Windows High Contrast */
7
7
 
8
8
  @media (forced-colors: active) {
9
- :host(:focus-within) {
9
+ :host:has(:focus-visible) {
10
10
  outline-color: Highlight;
11
11
  box-shadow: none;
12
12
  }