@lmvz-ds/components 0.35.0 → 0.35.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 (192) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +10 -0
  3. package/cjs/{async.util-BQ60l-WC.js → async.util-Dnl6c82X.js} +1 -0
  4. package/cjs/{list-keyboard-controller-Dm5S_l0D.js → directional-focus-controller-DBat-oF7.js} +13 -1
  5. package/cjs/element-activation-controller-BHqCUgQv.js +57 -0
  6. package/cjs/{element.util-Dbyc8yUG.js → element.util-CRS_YJ59.js} +10 -2
  7. package/cjs/lmvz-action-list.cjs.entry.js +8 -5
  8. package/cjs/lmvz-action.cjs.entry.js +1 -1
  9. package/cjs/lmvz-button-group.cjs.entry.js +1 -1
  10. package/cjs/lmvz-button_2.cjs.entry.js +4 -5
  11. package/cjs/lmvz-checkbox.cjs.entry.js +1 -1
  12. package/cjs/lmvz-chip.cjs.entry.js +1 -1
  13. package/cjs/lmvz-components.cjs.js +1 -1
  14. package/cjs/lmvz-header_2.cjs.entry.js +9 -6
  15. package/cjs/lmvz-input.cjs.entry.js +3 -3
  16. package/cjs/lmvz-menuitem.cjs.entry.js +3 -2
  17. package/cjs/lmvz-message.cjs.entry.js +42 -9
  18. package/cjs/lmvz-modal.cjs.entry.js +3 -3
  19. package/cjs/lmvz-popover.cjs.entry.js +48 -28
  20. package/cjs/lmvz-radio.cjs.entry.js +1 -1
  21. package/cjs/lmvz-select.cjs.entry.js +1 -1
  22. package/cjs/lmvz-tabs.cjs.entry.js +9 -6
  23. package/cjs/lmvz-toggle.cjs.entry.js +3 -3
  24. package/cjs/loader.cjs.js +1 -1
  25. package/{esm/reactive-controller-host-FBuCCcFC.js → cjs/reactive-controller-host-Bc6B_T45.js} +19 -1
  26. package/cjs/{stencil.util-DxdYjVoH.js → stencil.util-CBrPLd-F.js} +1 -1
  27. package/collection/components/lmvz-action/lmvz-action.js +1 -1
  28. package/collection/components/lmvz-action-list/lmvz-action-list.js +26 -2
  29. package/collection/components/lmvz-button/lmvz-button.js +1 -2
  30. package/collection/components/lmvz-header/lmvz-header.js +26 -2
  31. package/collection/components/lmvz-message/lmvz-message.js +42 -9
  32. package/collection/components/lmvz-modal/lmvz-modal.js +1 -1
  33. package/collection/components/lmvz-modal/test/testing.js +36 -0
  34. package/collection/components/lmvz-popover/lmvz-popover.js +55 -28
  35. package/collection/components/lmvz-tabs/lmvz-tabs.js +22 -2
  36. package/collection/utils/aria/{list-keyboard-controller.js → directional-focus-controller.js} +11 -0
  37. package/collection/utils/aria/element-activation-controller.js +27 -11
  38. package/collection/utils/data/{event.utilt.js → event.util.js} +8 -0
  39. package/collection/utils/element/element.util.js +9 -2
  40. package/collection/utils/stencil/reactive-controller-host.js +14 -0
  41. package/components/index.js +1 -1
  42. package/components/lmvz-action-list.js +1 -1
  43. package/components/lmvz-action.js +1 -1
  44. package/components/lmvz-button-group.js +1 -1
  45. package/components/lmvz-button.js +1 -1
  46. package/components/lmvz-checkbox.js +1 -1
  47. package/components/lmvz-chip.js +1 -1
  48. package/components/lmvz-header.js +1 -1
  49. package/components/lmvz-icon.js +1 -1
  50. package/components/lmvz-input.js +1 -1
  51. package/components/lmvz-link.js +1 -1
  52. package/components/lmvz-menuitem.js +1 -1
  53. package/components/lmvz-message.js +1 -1
  54. package/components/lmvz-modal.js +1 -1
  55. package/components/lmvz-popover.js +1 -1
  56. package/components/lmvz-radio.js +1 -1
  57. package/components/lmvz-select.js +1 -1
  58. package/components/lmvz-snackbar.js +1 -1
  59. package/components/lmvz-tabs.js +1 -1
  60. package/components/lmvz-toggle.js +1 -1
  61. package/components/p-BVzxNP7h.js +1 -0
  62. package/components/p-CgK6-SEe.js +1 -0
  63. package/components/{p-DbIm98qX.js → p-Chj7BuUZ.js} +1 -1
  64. package/components/p-CxLd309t.js +1 -0
  65. package/components/{p-D7S1WiEC.js → p-D5FL8n1q.js} +1 -1
  66. package/components/p-DLUsBYJH.js +1 -0
  67. package/components/p-DZj20TV1.js +1 -0
  68. package/components/p-bh9cItsP.js +1 -0
  69. package/components/p-zMWemcoB.js +1 -0
  70. package/esm/{async.util-D9nUtvTm.js → async.util-DZj20TV1.js} +1 -1
  71. package/esm/{list-keyboard-controller-tle6IRkv.js → directional-focus-controller-DgAdCZrG.js} +13 -2
  72. package/esm/element-activation-controller-7PNSl6io.js +54 -0
  73. package/esm/{element.util-B0eCxdyI.js → element.util-BFcYfHYq.js} +10 -3
  74. package/esm/lmvz-action-list.entry.js +7 -4
  75. package/esm/lmvz-action.entry.js +1 -1
  76. package/esm/lmvz-button-group.entry.js +1 -1
  77. package/esm/lmvz-button_2.entry.js +4 -5
  78. package/esm/lmvz-checkbox.entry.js +1 -1
  79. package/esm/lmvz-chip.entry.js +1 -1
  80. package/esm/lmvz-components.js +1 -1
  81. package/esm/lmvz-header_2.entry.js +8 -5
  82. package/esm/lmvz-input.entry.js +3 -3
  83. package/esm/lmvz-menuitem.entry.js +3 -2
  84. package/esm/lmvz-message.entry.js +42 -9
  85. package/esm/lmvz-modal.entry.js +3 -3
  86. package/esm/lmvz-popover.entry.js +48 -28
  87. package/esm/lmvz-radio.entry.js +1 -1
  88. package/esm/lmvz-select.entry.js +1 -1
  89. package/esm/lmvz-tabs.entry.js +7 -4
  90. package/esm/lmvz-toggle.entry.js +3 -3
  91. package/esm/loader.js +1 -1
  92. package/{cjs/reactive-controller-host-B_lZtcA6.js → esm/reactive-controller-host-CICeIanv.js} +15 -3
  93. package/esm/{stencil.util-wGFRYLwZ.js → stencil.util-D2-5rsN3.js} +1 -1
  94. package/hydrate/index.js +212 -97
  95. package/hydrate/index.mjs +212 -97
  96. package/lmvz-components/lmvz-components.esm.js +1 -1
  97. package/lmvz-components/{p-c87e2281.entry.js → p-194a3af5.entry.js} +1 -1
  98. package/lmvz-components/{p-e0432f54.entry.js → p-24d13be6.entry.js} +1 -1
  99. package/lmvz-components/p-4416d688.entry.js +1 -0
  100. package/lmvz-components/{p-c082390b.entry.js → p-46edf36f.entry.js} +1 -1
  101. package/lmvz-components/{p-4c68d21a.entry.js → p-489d9912.entry.js} +1 -1
  102. package/lmvz-components/p-5ff55ba9.entry.js +1 -0
  103. package/lmvz-components/{p-c494bf8f.entry.js → p-888e04d7.entry.js} +1 -1
  104. package/lmvz-components/p-9dc420e2.entry.js +1 -0
  105. package/lmvz-components/p-BFcYfHYq.js +1 -0
  106. package/lmvz-components/p-BuEA0MWd.js +1 -0
  107. package/lmvz-components/p-CICeIanv.js +1 -0
  108. package/lmvz-components/p-DZj20TV1.js +1 -0
  109. package/lmvz-components/p-a887018d.entry.js +1 -0
  110. package/lmvz-components/p-aaa7691c.entry.js +1 -0
  111. package/lmvz-components/p-af48eccb.entry.js +1 -0
  112. package/lmvz-components/p-bh9cItsP.js +1 -0
  113. package/lmvz-components/{p-1d2c11ea.entry.js → p-d4154a65.entry.js} +1 -1
  114. package/lmvz-components/p-e4ce63b3.entry.js +1 -0
  115. package/lmvz-components/{p-cb75c951.entry.js → p-eb4c5a6f.entry.js} +1 -1
  116. package/lmvz-components/{p-8fb4c347.entry.js → p-eb62d4af.entry.js} +1 -1
  117. package/lmvz-components/{p-a4ef8e55.entry.js → p-f42b16e6.entry.js} +1 -1
  118. package/lmvz-components/p-wlMjNjuv.js +1 -0
  119. package/manifest.json +79 -5
  120. package/package.json +1 -1
  121. package/types/api/ds.constants.d.ts +1 -0
  122. package/types/components/lmvz-action/lmvz-action.d.ts +1 -0
  123. package/types/components/lmvz-action-list/lmvz-action-list.d.ts +3 -1
  124. package/types/components/lmvz-button/lmvz-button.d.ts +2 -1
  125. package/types/components/lmvz-button-group/lmvz-button-group.d.ts +1 -0
  126. package/types/components/lmvz-card/lmvz-card.d.ts +1 -0
  127. package/types/components/lmvz-checkbox/lmvz-checkbox.d.ts +1 -0
  128. package/types/components/lmvz-chip/lmvz-chip.d.ts +1 -0
  129. package/types/components/lmvz-header/lmvz-header.d.ts +4 -2
  130. package/types/components/lmvz-icon/lmvz-icon.d.ts +1 -0
  131. package/types/components/lmvz-input/lmvz-input.d.ts +1 -0
  132. package/types/components/lmvz-link/lmvz-link.d.ts +1 -0
  133. package/types/components/lmvz-menuitem/lmvz-menuitem.d.ts +1 -0
  134. package/types/components/lmvz-message/lmvz-message.d.ts +1 -0
  135. package/types/components/lmvz-message/public.d.ts +1 -0
  136. package/types/components/lmvz-modal/lmvz-modal.d.ts +1 -0
  137. package/types/components/lmvz-modal/test/testing.d.ts +10 -0
  138. package/types/components/lmvz-popover/lmvz-popover.d.ts +6 -3
  139. package/types/components/lmvz-radio/lmvz-radio.d.ts +1 -0
  140. package/types/components/lmvz-select/lmvz-select.d.ts +1 -0
  141. package/types/components/lmvz-snackbar/lmvz-snackbar.d.ts +1 -0
  142. package/types/components/lmvz-snackbar/public.d.ts +1 -0
  143. package/types/components/lmvz-snackbar/snackbar-controller.d.ts +1 -0
  144. package/types/components/lmvz-spinner/lmvz-spinner.d.ts +1 -0
  145. package/types/components/lmvz-tab/lmvz-tab.d.ts +1 -0
  146. package/types/components/lmvz-tabs/lmvz-tabs.d.ts +3 -1
  147. package/types/components/lmvz-toggle/lmvz-toggle.d.ts +1 -0
  148. package/types/components.d.ts +18 -0
  149. package/types/index.d.ts +1 -0
  150. package/types/utils/aria/aria-validation-controller.d.ts +1 -0
  151. package/types/utils/aria/aria.constants.d.ts +1 -0
  152. package/types/utils/aria/{list-keyboard-controller.d.ts → directional-focus-controller.d.ts} +13 -2
  153. package/types/utils/aria/element-activation-controller.d.ts +11 -2
  154. package/types/utils/async/async.util.d.ts +1 -0
  155. package/types/utils/data/event.util.d.ts +6 -0
  156. package/types/utils/data/number.util.d.ts +1 -0
  157. package/types/utils/data/object.util.d.ts +1 -0
  158. package/types/utils/data/time.util.d.ts +1 -0
  159. package/types/utils/element/element.util.d.ts +2 -0
  160. package/types/utils/environment.d.ts +1 -0
  161. package/types/utils/icons/icons-registry.d.ts +1 -0
  162. package/types/utils/icons/icons.d.ts +1 -0
  163. package/types/utils/icons/icons.unit.d.ts +1 -0
  164. package/types/utils/icons/public.d.ts +1 -0
  165. package/types/utils/public.d.ts +1 -0
  166. package/types/utils/radio/radio-group-controller.d.ts +1 -0
  167. package/types/utils/stencil/assets.d.ts +1 -0
  168. package/types/utils/stencil/reactive-controller-host.d.ts +8 -1
  169. package/types/utils/stencil/stencil.util.d.ts +1 -0
  170. package/cjs/element-activation-controller-DC_6T0Rt.js +0 -31
  171. package/components/p-BhSTYZC6.js +0 -1
  172. package/components/p-CK3Ixl1K.js +0 -1
  173. package/components/p-CN0JX9-m.js +0 -1
  174. package/components/p-D-2gj6LP.js +0 -1
  175. package/components/p-D9nUtvTm.js +0 -1
  176. package/components/p-DAMVH-31.js +0 -1
  177. package/components/p-JtkmlmeY.js +0 -1
  178. package/esm/element-activation-controller-CN0JX9-m.js +0 -29
  179. package/lmvz-components/p-45c3ccb6.entry.js +0 -1
  180. package/lmvz-components/p-49e98627.entry.js +0 -1
  181. package/lmvz-components/p-50063516.entry.js +0 -1
  182. package/lmvz-components/p-76be3fc9.entry.js +0 -1
  183. package/lmvz-components/p-854f1c72.entry.js +0 -1
  184. package/lmvz-components/p-886e42c7.entry.js +0 -1
  185. package/lmvz-components/p-9f8fd077.entry.js +0 -1
  186. package/lmvz-components/p-B0eCxdyI.js +0 -1
  187. package/lmvz-components/p-BhSTYZC6.js +0 -1
  188. package/lmvz-components/p-CN0JX9-m.js +0 -1
  189. package/lmvz-components/p-D9nUtvTm.js +0 -1
  190. package/lmvz-components/p-DuLiExhX.js +0 -1
  191. package/lmvz-components/p-FBuCCcFC.js +0 -1
  192. package/types/utils/data/event.utilt.d.ts +0 -4
package/hydrate/index.js CHANGED
@@ -5418,7 +5418,7 @@ class LmvzAction {
5418
5418
  this.actionClick.emit(event);
5419
5419
  }
5420
5420
  render() {
5421
- return (hAsync(Host, { key: '15c0f20e08cd5019abfd3bb71ec69d175dc5ba48', onClick: this._onClick.bind(this) }, hAsync("slot", { key: 'f71a7853168d1b66b0a50b0f971d140385530ac3' })));
5421
+ return (hAsync(Host, { key: '4d83f95393704400034fef7313ac52bcc100be95', onClick: this._onClick.bind(this) }, hAsync("slot", { key: 'ffbdeca0877eb9a76bc4ac1b8b77b37b60fdabd5' })));
5422
5422
  }
5423
5423
  static get style() { return lmvzActionCss(); }
5424
5424
  static get cmpMeta() { return {
@@ -5771,13 +5771,17 @@ function findFormByRef(form, el) {
5771
5771
  }
5772
5772
  function isInteractiveElement(el) {
5773
5773
  const tagName = el.tagName.toLowerCase();
5774
- if (['button', 'input', 'select', 'textarea'].includes(tagName)) {
5774
+ if (['button', 'lmvz-button', 'input', 'lmvz-input', 'select', 'lmvz-select', 'textarea'].includes(tagName)) {
5775
5775
  return true;
5776
5776
  }
5777
- if (tagName === 'a' && el.hasAttribute('href')) {
5777
+ if (['a', 'lmvz-link'].includes(tagName) && el.hasAttribute('href')) {
5778
5778
  return true;
5779
5779
  }
5780
5780
  if (el.hasAttribute('tabindex')) {
5781
+ const tabindex = parseInt(el.getAttribute('tabindex') ?? '-1');
5782
+ if (isNaN(tabindex) || tabindex < 0) {
5783
+ console.warn('Interactive element is not keyboard accessible due to negative tabindex!', el);
5784
+ }
5781
5785
  return true;
5782
5786
  }
5783
5787
  const role = el.getAttribute('role');
@@ -5789,7 +5793,67 @@ function isInteractiveElement(el) {
5789
5793
  }
5790
5794
  return false;
5791
5795
  }
5796
+ function isHtmlElement(element) {
5797
+ return element instanceof HTMLElement;
5798
+ }
5799
+
5800
+ const META_BASE = '__LMVZ__';
5801
+ class ReactiveControllerHost {
5802
+ controllers = new Set();
5803
+ addController(controller) {
5804
+ this.controllers.add(controller);
5805
+ }
5806
+ removeController(controller) {
5807
+ this.controllers.delete(controller);
5808
+ }
5809
+ get activeControllers() {
5810
+ return Array.from(this.controllers).filter((controller) => !controller.disabled);
5811
+ }
5812
+ connectedCallback() {
5813
+ if (!this.controllers.size) {
5814
+ console.warn('ReactiveControllerHost connected with no controllers registered.', this);
5815
+ }
5816
+ this.activeControllers.forEach((controller) => controller.hostConnected?.());
5817
+ }
5818
+ disconnectedCallback() {
5819
+ this.activeControllers.forEach((controller) => controller.hostDisconnected?.());
5820
+ }
5821
+ componentWillLoad() {
5822
+ this.activeControllers.forEach((controller) => controller.hostWillLoad?.());
5823
+ }
5824
+ componentDidLoad() {
5825
+ this.activeControllers.forEach((controller) => controller.hostDidLoad?.());
5826
+ }
5827
+ componentWillRender() {
5828
+ this.activeControllers.forEach((controller) => controller.hostWillRender?.());
5829
+ }
5830
+ componentDidRender() {
5831
+ this.activeControllers.forEach((controller) => controller.hostDidRender?.());
5832
+ }
5833
+ componentWillUpdate() {
5834
+ this.activeControllers.forEach((controller) => controller.hostWillUpdate?.());
5835
+ }
5836
+ componentDidUpdate() {
5837
+ this.activeControllers.forEach((controller) => controller.hostDidUpdate?.());
5838
+ }
5839
+ }
5840
+ function registerLmvzComponentMetaInfo(el, key, info) {
5841
+ if (!el) {
5842
+ console.warn('component is undefined');
5843
+ return;
5844
+ }
5845
+ const cmp = el;
5846
+ if (!cmp[META_BASE])
5847
+ cmp[META_BASE] = {};
5848
+ cmp[META_BASE][key] = info;
5849
+ }
5850
+ function getLmvzComponentMetaInfo(el, key) {
5851
+ return el?.[META_BASE]?.[key];
5852
+ }
5792
5853
 
5854
+ function isFocusControllerHost(el) {
5855
+ return Boolean(getLmvzComponentMetaInfo(el, 'isFocusControllerHost'));
5856
+ }
5793
5857
  const defaultConfig = {
5794
5858
  orientation: 'both',
5795
5859
  enableHomeAndEnd: false,
@@ -5808,6 +5872,7 @@ class DirectionalFocusController {
5808
5872
  };
5809
5873
  }
5810
5874
  hostConnected() {
5875
+ registerLmvzComponentMetaInfo(this.host.el, 'isFocusControllerHost', true);
5811
5876
  this.host.el.addEventListener('keydown', this.handleKeydown);
5812
5877
  this.syncManagedFocusTarget();
5813
5878
  }
@@ -5824,6 +5889,12 @@ class DirectionalFocusController {
5824
5889
  this.currentElement = element !== null && element !== undefined && 'focus' in element && element.nodeType === 1 ? element : undefined;
5825
5890
  this.syncManagedFocusTarget(previousElement);
5826
5891
  }
5892
+ async initFocus() {
5893
+ const element = this.selectManagedElement();
5894
+ if (!element)
5895
+ return;
5896
+ this.applyFocusTarget(element, true);
5897
+ }
5827
5898
  handleKeydown = (event) => {
5828
5899
  const intent = this.getFocusIntent(event.key);
5829
5900
  if (!intent)
@@ -5963,46 +6034,6 @@ function resolveElement(el) {
5963
6034
  return isDirectionalFocusReceiver(el) ? (el.resolveFocusableElement() ?? el) : el;
5964
6035
  }
5965
6036
 
5966
- class ReactiveControllerHost {
5967
- controllers = new Set();
5968
- addController(controller) {
5969
- this.controllers.add(controller);
5970
- }
5971
- removeController(controller) {
5972
- this.controllers.delete(controller);
5973
- }
5974
- get activeControllers() {
5975
- return Array.from(this.controllers).filter((controller) => !controller.disabled);
5976
- }
5977
- connectedCallback() {
5978
- if (!this.controllers.size) {
5979
- console.warn('ReactiveControllerHost connected with no controllers registered.', this);
5980
- }
5981
- this.activeControllers.forEach((controller) => controller.hostConnected?.());
5982
- }
5983
- disconnectedCallback() {
5984
- this.activeControllers.forEach((controller) => controller.hostDisconnected?.());
5985
- }
5986
- componentWillLoad() {
5987
- this.activeControllers.forEach((controller) => controller.hostWillLoad?.());
5988
- }
5989
- componentDidLoad() {
5990
- this.activeControllers.forEach((controller) => controller.hostDidLoad?.());
5991
- }
5992
- componentWillRender() {
5993
- this.activeControllers.forEach((controller) => controller.hostWillRender?.());
5994
- }
5995
- componentDidRender() {
5996
- this.activeControllers.forEach((controller) => controller.hostDidRender?.());
5997
- }
5998
- componentWillUpdate() {
5999
- this.activeControllers.forEach((controller) => controller.hostWillUpdate?.());
6000
- }
6001
- componentDidUpdate() {
6002
- this.activeControllers.forEach((controller) => controller.hostDidUpdate?.());
6003
- }
6004
- }
6005
-
6006
6037
  const lmvzActionListCss = () => `@layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides; @layer lmvz-ds.reset { body { margin: 0; } h1, h2, h3, h4, h5, h6 { margin: 0; } *[hidden] { display: none !important; } hr { height: 0; border: none; margin: var(--lmvz-dimension-8-4, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)) 0; border-top: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-subtle, #f0f0f0); } } .sc-lmvz-action-list-h { display: flex; flex-direction: column; gap: 0; min-width: 15vw; button { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000)); --lmvz-button-radius: var(--lmvz-button-radius-override, var(--lmvz-component-input-radius-default, 999px)); --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-md, clamp(2.5rem, 2.44rem + 0.26vw, 2.75rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-md-strong, normal 700 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router)); --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); display: inline-flex; align-items: center; justify-content: var(--lmvz-button-content-justification-override, center); gap: var(--lmvz-button-gap); padding-block: var(--lmvz-button-padding-block); padding-inline: var(--lmvz-button-padding-inline); min-height: var(--lmvz-button-min-height); border-radius: var(--lmvz-button-radius); border: var(--lmvz-button-border-width) solid var(--lmvz-button-border-color); background-color: var(--lmvz-button-background); color: var(--lmvz-button-color); cursor: pointer; font: var(--lmvz-button-font); text-decoration: none; white-space: nowrap; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } button > * { font: inherit; color: inherit; } button:focus-visible { outline: var(--lmvz-ds-outline, 1px solid #0e7ab4); outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)); position: relative; z-index: 1; } button:is([disabled], .disabled) { cursor: not-allowed; pointer-events: none; opacity: var(--lmvz-component-input-disabled-opacity, 40%); } button:not([disabled]):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0)); } button:not([disabled]):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4)); } button.primary { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary, #000000)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-primary, #ffffff)); --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); } button.primary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-hover, #2e2e2e)); } button.primary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-active, #545454)); } button.danger { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff)); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.danger:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-status-danger, #fbdfe0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.danger:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-status-on-danger-subtle, #e8454b)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.tertiary { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary, #000000)); } button.tertiary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-hover, #000000)); } button.tertiary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-active, #000000)); } button.small { --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-sm-strong, normal 700 clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem) / 1.5 Router)); } button.large { --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-lg-strong, normal 700 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5 Router)); } lmvz-button, button { --lmvz-button-radius-override: var(--lmvz-semantic-border-radius-md, 6px); --lmvz-button-padding-inline-override: var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)); --lmvz-button-padding-block-override: var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)); --lmvz-button-font-override: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router); --lmvz-button-content-justification-override: normal; width: 100%; display: block; } button { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary, #000000)); &:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-hover, #000000)); } &:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-active, #000000)); } } }`;
6007
6038
 
6008
6039
  class LmvzActionList extends ReactiveControllerHost {
@@ -6032,6 +6063,9 @@ class LmvzActionList extends ReactiveControllerHost {
6032
6063
  this.handleSlotChange();
6033
6064
  super.componentDidLoad();
6034
6065
  }
6066
+ async initFocus() {
6067
+ this.focusController.initFocus();
6068
+ }
6035
6069
  handleSlotChange = () => {
6036
6070
  const slot = this.slotEl;
6037
6071
  if (!slot)
@@ -6052,14 +6086,15 @@ class LmvzActionList extends ReactiveControllerHost {
6052
6086
  };
6053
6087
  render() {
6054
6088
  const ariaLabel = this.label || undefined;
6055
- return (hAsync(Host, { key: '1180ac5cb2ad83db0279a5cd2ce15d9ab75d03ca', role: "menu", "aria-label": ariaLabel }, hAsync("slot", { key: '479179e7ec42780e73936d50703ff46d48a89efb', onSlotchange: this.handleSlotChange, ref: (el) => (this.slotEl = el) })));
6089
+ return (hAsync(Host, { key: '9dee495856e733cb17f30d0d8588362a8dcb28ce', role: "menu", "aria-label": ariaLabel }, hAsync("slot", { key: 'c6454dbbe63eed5be01f3247934245d1cc1ad6e2', onSlotchange: this.handleSlotChange, ref: (el) => (this.slotEl = el) })));
6056
6090
  }
6057
6091
  static get style() { return lmvzActionListCss(); }
6058
6092
  static get cmpMeta() { return {
6059
6093
  "$flags$": 774,
6060
6094
  "$tagName$": "lmvz-action-list",
6061
6095
  "$members$": {
6062
- "label": [1]
6096
+ "label": [1],
6097
+ "initFocus": [64]
6063
6098
  },
6064
6099
  "$listeners$": undefined,
6065
6100
  "$lazyBundleId$": "-",
@@ -6180,26 +6215,30 @@ function requireClassnames () {
6180
6215
  var classnamesExports = requireClassnames();
6181
6216
  var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
6182
6217
 
6218
+ function filterKeysAndCallback(callback, keys = [' ']) {
6219
+ return (event) => {
6220
+ if (!keys.includes(event.key))
6221
+ return;
6222
+ event.preventDefault();
6223
+ callback(event);
6224
+ };
6225
+ }
6226
+
6183
6227
  class ElementActivationController {
6184
6228
  host;
6185
6229
  config;
6230
+ handlers = new AbortController();
6186
6231
  constructor(host, config) {
6187
6232
  this.host = host;
6188
6233
  this.config = config;
6234
+ registerLmvzComponentMetaInfo(host.el, 'isLmvzElementActivationHost', true);
6189
6235
  }
6190
6236
  hostDidLoad() {
6191
- if (!this.host.el.hasAttribute('tabindex')) {
6192
- console.warn('Interactive element does not have a tabindex attribute!', this.host.el);
6193
- }
6194
- this.host.el.addEventListener('keydown', this.handleKeyDown.bind(this));
6195
- this.host.el.addEventListener('click', this.handleActivation.bind(this));
6237
+ bindHandlers(this.host.el, this.handleActivation.bind(this), this.handlers.signal, this.config?.keys ?? ['Enter', ' ']);
6238
+ }
6239
+ hostDisconnected() {
6240
+ this.handlers.abort();
6196
6241
  }
6197
- handleKeyDown = (event) => {
6198
- if ((this.config?.keys ?? ['Enter', ' ']).includes(event.key)) {
6199
- event.preventDefault();
6200
- this.handleActivation(event);
6201
- }
6202
- };
6203
6242
  handleActivation = (event) => {
6204
6243
  this.host.lmvzActivation.emit();
6205
6244
  if (this.config?.localHandler) {
@@ -6207,6 +6246,24 @@ class ElementActivationController {
6207
6246
  }
6208
6247
  };
6209
6248
  }
6249
+ function bindHandlers(target, handler, abortSignal, keys = [' ']) {
6250
+ target.addEventListener('keydown', filterKeysAndCallback(handler, keys), { signal: abortSignal });
6251
+ target.addEventListener('click', handler, { signal: abortSignal });
6252
+ }
6253
+ function isLmvzElementActivationHost(el) {
6254
+ return getLmvzComponentMetaInfo(el, 'isLmvzElementActivationHost');
6255
+ }
6256
+ function addElementActivationListener(...[target, handler, abortSignal, keys]) {
6257
+ if (isLmvzElementActivationHost(target)) {
6258
+ target.addEventListener('lmvzActivation', handler, { signal: abortSignal });
6259
+ return;
6260
+ }
6261
+ if (!isInteractiveElement(target)) {
6262
+ console.error('addElementActivationListener called with non-interactive element');
6263
+ return;
6264
+ }
6265
+ bindHandlers(target, handler, abortSignal, keys);
6266
+ }
6210
6267
 
6211
6268
  const lmvzButtonCss = () => ` @layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides; @layer lmvz-ds.theme { @font-face { font-family: Router; src: local('RouterBook-Regular'), local('Router-Book'), url('/assets/fonts/Router-Book.woff') format('woff'); font-weight: 400; } @font-face { font-family: Router; src: local('RouterMedium-Regular'), local('Router-Medium'), url('/assets/fonts/Router-Medium.woff') format('woff'); font-weight: 500; } @font-face { font-family: Router; src: local('RouterBold-Regular'), local('Router-Bold'), url('/assets/fonts/Router-Bold.woff') format('woff'); font-weight: 700; } } @layer lmvz-ds.reset { body { margin: 0; } h1, h2, h3, h4, h5, h6 { margin: 0; } *[hidden] { display: none !important; } hr { height: 0; border: none; margin: var(--lmvz-dimension-8-4, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)) 0; border-top: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-subtle, #f0f0f0); } } :host { button { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000)); --lmvz-button-radius: var(--lmvz-button-radius-override, var(--lmvz-component-input-radius-default, 999px)); --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-md, clamp(2.5rem, 2.44rem + 0.26vw, 2.75rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-md-strong, normal 700 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router)); --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); display: inline-flex; align-items: center; justify-content: var(--lmvz-button-content-justification-override, center); gap: var(--lmvz-button-gap); padding-block: var(--lmvz-button-padding-block); padding-inline: var(--lmvz-button-padding-inline); min-height: var(--lmvz-button-min-height); border-radius: var(--lmvz-button-radius); border: var(--lmvz-button-border-width) solid var(--lmvz-button-border-color); background-color: var(--lmvz-button-background); color: var(--lmvz-button-color); cursor: pointer; font: var(--lmvz-button-font); text-decoration: none; white-space: nowrap; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } button > * { font: inherit; color: inherit; } button:focus-visible { outline: var(--lmvz-ds-outline, 1px solid #0e7ab4); outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)); position: relative; z-index: 1; } button:is([disabled], .disabled) { cursor: not-allowed; pointer-events: none; opacity: var(--lmvz-component-input-disabled-opacity, 40%); } button:not([disabled]):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0)); } button:not([disabled]):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4)); } button.primary { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary, #000000)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-primary, #ffffff)); --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); } button.primary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-hover, #2e2e2e)); } button.primary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-active, #545454)); } button.danger { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff)); --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.danger:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-status-danger, #fbdfe0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.danger:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-status-on-danger-subtle, #e8454b)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-status-on-danger, #a31419)); } button.tertiary { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary, #000000)); } button.tertiary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-hover, #000000)); } button.tertiary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0)); --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-active, #000000)); } button.small { --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-sm-strong, normal 700 clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem) / 1.5 Router)); } button.large { --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem))); --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem))); --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem))); --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-label-lg-strong, normal 700 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5 Router)); } display: inline-block; button { width: 100%; } } ::slotted(*) { --lmvz-component-color: var(--lmvz-button-color); } `;
6212
6269
 
@@ -6237,7 +6294,6 @@ class LmvzButton extends ReactiveControllerHost {
6237
6294
  this.addController(new AriaValidationController(this));
6238
6295
  this.addController(new ElementActivationController(this, {
6239
6296
  localHandler: this.handleClick.bind(this),
6240
- keys: ['Enter'],
6241
6297
  }));
6242
6298
  }
6243
6299
  connectedCallback() {
@@ -6298,7 +6354,7 @@ class LmvzButton extends ReactiveControllerHost {
6298
6354
  };
6299
6355
  render() {
6300
6356
  this.renderHiddenButton();
6301
- return (hAsync(Host, { key: 'f3e619dca398c3a8a78e9d2f8c3df4178b2531b2', role: "presentation" }, hAsync("button", { key: 'eb1aac6756a70968d3a72cb40c1d52d96340423e', ref: (e) => (this.validationEl = e), part: "button", role: this.buttonRole, disabled: this.disabled, type: this.type, class: classNames(this.variant ?? 'secondary', { [this.scale ?? '']: !!this.scale, disabled: this.disabled }), ...this.inheritedAttributes }, hAsync("slot", { key: '786ff1c10ae05eda646c77ac8779813be6e51949' }))));
6357
+ return (hAsync(Host, { key: 'eb0ee982f50f1e41b2aa72a0598d739b972cbcdf', role: "presentation" }, hAsync("button", { key: 'aed6f44f51222e31d5f1deec952c0d81b8f1200a', ref: (e) => (this.validationEl = e), part: "button", role: this.buttonRole, disabled: this.disabled, type: this.type, class: classNames(this.variant ?? 'secondary', { [this.scale ?? '']: !!this.scale, disabled: this.disabled }), ...this.inheritedAttributes }, hAsync("slot", { key: '2aaedfde3c0d6ebf426f20a8489b22c2a356767e' }))));
6302
6358
  }
6303
6359
  static get delegatesFocus() { return true; }
6304
6360
  static get style() { return lmvzButtonCss(); }
@@ -8976,6 +9032,9 @@ class LmvzHeader extends ReactiveControllerHost {
8976
9032
  handleActiveNavChange() {
8977
9033
  this.updateElementsActive();
8978
9034
  }
9035
+ async initFocus() {
9036
+ this.keyboardNavigationController.initFocus();
9037
+ }
8979
9038
  componentDidLoad() {
8980
9039
  this.primarySlot?.addEventListener('slotchange', this.handlePrimaryNavItemsChange.bind(this));
8981
9040
  this.handlePrimaryNavItemsChange();
@@ -9027,7 +9086,7 @@ class LmvzHeader extends ReactiveControllerHost {
9027
9086
  }
9028
9087
  }
9029
9088
  render() {
9030
- return (hAsync(Host, { key: '5730219e990fc0f131ffacc7c88e6a5311553399', onFocus: this.delegateFocus.bind(this) }, hAsync("div", { key: '7285f2dcac7d60c5d93328aa0e2fe8aa6b7b379c', class: "brand" }, hAsync("slot", { key: 'd06d953ee82eab20da3f383c15032bcbe8803ff9', name: "brand" }, hAsync("img", { key: 'd2441ce0efbf99c05f6344051703a96ffb376450', id: "fallback-logo-lmvz", src: logoSvg, alt: "Lehrmittelverlag Z\u00FCrich" }))), hAsync("nav", { key: '7f092938728af5cb6568383a6622df49f222dc93', "aria-label": "Hauptnavigation" }, hAsync("div", { key: 'caa56893d6185aebb89661e62a555407675ccc2a', role: "menubar", class: "primary-menubar" }, hAsync("slot", { key: '90684f49cd3d53e20a63d4ebc37ec24e630bc313', name: "nav-primary", ref: (el) => (this.primarySlot = el) }), hAsync("div", { key: 'ead46c08c6833565a55cd7af27fbece4e4468a03', role: "menu", id: "nav-secondary", class: "secondary-menubar", hidden: !this.lmvzActiveNav, ref: (el) => (this.secondaryNav = el) }, hAsync("slot", { key: '3f2ba617d9ed78abb9ab94b9515b02bb6836385a', name: this.secondarySlotName, ref: (el) => (this.secondarySlot = el) })))), hAsync("div", { key: '6fc79122baa3fd95992cbf30a465c3b40438a18f', class: "actions" }, hAsync("slot", { key: 'c427f5a3ad693169e267060b9076086fd0e37670', name: "actions" }))));
9089
+ return (hAsync(Host, { key: 'ce4b8cf9f7687e4af97d45908e2f0e484b90684f', onFocus: this.delegateFocus.bind(this) }, hAsync("div", { key: 'a2213d8038d126e47262c4ec18071dd4302152db', class: "brand" }, hAsync("slot", { key: '68a0a1e2b21859d78d2f9a7d3f5c86020c52c225', name: "brand" }, hAsync("img", { key: 'd0a878bc4c9f7a3460e857fb5aa52f1d942a0423', id: "fallback-logo-lmvz", src: logoSvg, alt: "Lehrmittelverlag Z\u00FCrich" }))), hAsync("nav", { key: '687791624d6ced477bc0cce73ce97b26c7d03af0', "aria-label": "Hauptnavigation" }, hAsync("div", { key: 'a9e8fa4a57e619a3d3b1056bfc0d5df74e89f630', role: "menubar", class: "primary-menubar" }, hAsync("slot", { key: 'f75f0a3bed2267aff902490f1905c67ad1b7e6be', name: "nav-primary", ref: (el) => (this.primarySlot = el) }), hAsync("div", { key: '3cf2d099bed99e4ba7b32a2f3171c69663785012', role: "menu", id: "nav-secondary", class: "secondary-menubar", hidden: !this.lmvzActiveNav, ref: (el) => (this.secondaryNav = el) }, hAsync("slot", { key: '85dbe77ea8ab62aa400640495e11e2d174ca5210', name: this.secondarySlotName, ref: (el) => (this.secondarySlot = el) })))), hAsync("div", { key: 'cf5d135a5b969af6a2bbb5432a10f8e1b9af1dca', class: "actions" }, hAsync("slot", { key: '1a0323668942151c071a24238039c7a216358363', name: "actions" }))));
9031
9090
  }
9032
9091
  static get watchers() { return {
9033
9092
  "lmvzActiveNav": [{
@@ -9040,7 +9099,8 @@ class LmvzHeader extends ReactiveControllerHost {
9040
9099
  "$tagName$": "lmvz-header",
9041
9100
  "$members$": {
9042
9101
  "role": [2561],
9043
- "lmvzActiveNav": [1, "lmvz-active-nav"]
9102
+ "lmvzActiveNav": [1, "lmvz-active-nav"],
9103
+ "initFocus": [64]
9044
9104
  },
9045
9105
  "$listeners$": undefined,
9046
9106
  "$lazyBundleId$": "-",
@@ -9505,14 +9565,47 @@ const TYPE_SVG = {
9505
9565
  warning: WARNING_SVG,
9506
9566
  };
9507
9567
  const BLOCK_TAGS = new Set([
9508
- 'ADDRESS', 'ARTICLE', 'ASIDE', 'BLOCKQUOTE',
9509
- 'CAPTION', 'COLGROUP',
9510
- 'DD', 'DETAILS', 'DIALOG', 'DIV', 'DL', 'DT',
9511
- 'FIELDSET', 'FIGCAPTION', 'FIGURE', 'FOOTER', 'FORM',
9512
- 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HGROUP', 'HR',
9513
- 'LI', 'MAIN', 'MENU', 'NAV',
9514
- 'OL', 'P', 'PRE',
9515
- 'SECTION', 'TABLE', 'TBODY', 'TD', 'TH', 'THEAD', 'TFOOT', 'TR',
9568
+ 'ADDRESS',
9569
+ 'ARTICLE',
9570
+ 'ASIDE',
9571
+ 'BLOCKQUOTE',
9572
+ 'CAPTION',
9573
+ 'COLGROUP',
9574
+ 'DD',
9575
+ 'DETAILS',
9576
+ 'DIALOG',
9577
+ 'DIV',
9578
+ 'DL',
9579
+ 'DT',
9580
+ 'FIELDSET',
9581
+ 'FIGCAPTION',
9582
+ 'FIGURE',
9583
+ 'FOOTER',
9584
+ 'FORM',
9585
+ 'H1',
9586
+ 'H2',
9587
+ 'H3',
9588
+ 'H4',
9589
+ 'H5',
9590
+ 'H6',
9591
+ 'HEADER',
9592
+ 'HGROUP',
9593
+ 'HR',
9594
+ 'LI',
9595
+ 'MAIN',
9596
+ 'MENU',
9597
+ 'NAV',
9598
+ 'OL',
9599
+ 'P',
9600
+ 'PRE',
9601
+ 'SECTION',
9602
+ 'TABLE',
9603
+ 'TBODY',
9604
+ 'TD',
9605
+ 'TH',
9606
+ 'THEAD',
9607
+ 'TFOOT',
9608
+ 'TR',
9516
9609
  'UL',
9517
9610
  ]);
9518
9611
  class LmvzMessage {
@@ -9558,7 +9651,7 @@ class LmvzMessage {
9558
9651
  }
9559
9652
  render() {
9560
9653
  const role = this.live === 'assertive' ? 'alert' : this.live === 'polite' ? 'status' : 'note';
9561
- return (hAsync(Host, { key: 'f422e8ee4bb4466757c081bc6b33761db15cb02d', role: role }, this.leadingIcon && hAsync("span", { key: 'c4077083db459a65cacce2cbb8e8dbb477572d95', class: "leading-icon", "aria-hidden": "true", innerHTML: TYPE_SVG[this.type] }), hAsync("span", { key: '77c3af94194adc2b663c6d6626951e5789e17686', class: "message" }, hAsync("slot", { key: '8db714f6bd0ac80a3c77a2768431baa37a63b3d1', ref: (el) => (this.messageSlot = el), onSlotchange: this.handleSlotChange })), this.actionLabel && (hAsync("lmvz-button", { key: 'f75e835f39e97ea217727b55dc842ceda004834b', variant: "tertiary", scale: "small", onLmvzActivation: this.handleActionClick }, this.actionLabel)), this.dismissible && (hAsync("lmvz-button", { key: '51b04ad48a68e0843445104e303eae5bb4cdd351', variant: "tertiary", scale: "small", "aria-label": this.closeLabel, onClick: this.handleDismissClick }, hAsync("lmvz-icon", { key: '5949210f479a6a19f1c4bb9d3c91a77a1c0ad8a6', "aria-hidden": "true", icon: CLOSE_SM_SVG })))));
9654
+ return (hAsync(Host, { key: '99dad82a6300fb8d089f1ea688186d4b4316a058', role: role }, this.leadingIcon && hAsync("span", { key: '2adf33102f7075a83ebf29d9b6e0d433a17beb68', class: "leading-icon", "aria-hidden": "true", innerHTML: TYPE_SVG[this.type] }), hAsync("span", { key: '286d3d0ea065534b84be18c927b2fcd7f30f34bd', class: "message" }, hAsync("slot", { key: '261e865980515a816382b2c7c6b3a52b500308bf', ref: (el) => (this.messageSlot = el), onSlotchange: this.handleSlotChange })), this.actionLabel && (hAsync("lmvz-button", { key: '46d964c0490bbdd47426fc228db0e3ccb108b416', variant: "tertiary", scale: "small", onLmvzActivation: this.handleActionClick }, this.actionLabel)), this.dismissible && (hAsync("lmvz-button", { key: 'ce1ec8beb756c2e11c948e227f94f81bd5568c88', variant: "tertiary", scale: "small", "aria-label": this.closeLabel, onClick: this.handleDismissClick }, hAsync("lmvz-icon", { key: '5361c424e77ffea7984c2fd42357666cd86ba1d6', "aria-hidden": "true", icon: CLOSE_SM_SVG })))));
9562
9655
  }
9563
9656
  static get style() { return lmvzMessageCss(); }
9564
9657
  static get cmpMeta() { return {
@@ -9802,7 +9895,7 @@ class LmvzModal extends ReactiveControllerHost {
9802
9895
  this.hasHeader = this.hasAssignedContent(this.headerSlot);
9803
9896
  };
9804
9897
  render() {
9805
- return (hAsync(Host, { key: '8b5f506cdac223a440309d472639fe965b94f8c2' }, hAsync("dialog", { key: '0b70ac4d9590266271052c4d7fdef03c684d9b72', ref: (element) => (this.dialogEl = element), onCancel: this.handleDialogCancel, onClose: this.handleDialogClose, ...this.dialogAccessibilityAttributes }, hAsync("div", { key: '25b529bec1905408c2041b7370ab37586eade47d', class: "modal-shell" }, hAsync("header", { key: 'd86ae4a6f4ac7f6efd38385f1407d1f6bfbb1abb', class: { header: true, 'has-title': this.hasHeader } }, hAsync("div", { key: '7fd7059bfb0b90834895a87c2f2598e2e8c2ba80', class: "title", id: this.dialogTitleId, hidden: !this.hasHeader }, hAsync("slot", { key: 'b6eb7885e220e5def4c3c8420d5b83f4a7e30907', name: "header", ref: (element) => (this.headerSlot = element), onSlotchange: this.handleHeaderSlotChange })), hAsync("lmvz-button", { key: 'dcebb06482cdef7423c6b62ef877ca9aaabf55a4', ref: (element) => (this.closeButtonEl = element), type: "button", class: "close-button", "aria-label": this.closeLabel, onClick: this.handleCloseButtonClick, variant: "tertiary" }, hAsync("lmvz-icon", { key: '0db22c68fe164ed2a33bfaeacf9eac619424f464', icon: closeIconSvg }))), hAsync("div", { key: 'ef402c343f2c68210351f7556eec08f2e9be851b', class: "body" }, hAsync("slot", { key: '3fe86dc88c88c2cf7bfe3429c62cb2047b64611a' })), hAsync("footer", { key: '92b7bdab1ffe700749fc029723f70913f436397d', class: "actions", hidden: !this.buttonGroupEl?.hasActions }, hAsync("lmvz-button-group", { key: '7e1b310fb1b20449ead14d0702af4977c74198dd', ref: (element) => (this.buttonGroupEl = element) }, hAsync("slot", { key: 'cb2187ab2758c61e80b65f9fc55c6be5f9fd0458', name: "actions" })))))));
9898
+ return (hAsync(Host, { key: '8b5f506cdac223a440309d472639fe965b94f8c2' }, hAsync("dialog", { key: '0b70ac4d9590266271052c4d7fdef03c684d9b72', ref: (element) => (this.dialogEl = element), onCancel: this.handleDialogCancel, onClose: this.handleDialogClose, ...this.dialogAccessibilityAttributes }, hAsync("div", { key: '25b529bec1905408c2041b7370ab37586eade47d', class: "modal-shell" }, hAsync("header", { key: 'd86ae4a6f4ac7f6efd38385f1407d1f6bfbb1abb', class: { header: true, 'has-title': this.hasHeader } }, hAsync("div", { key: '7fd7059bfb0b90834895a87c2f2598e2e8c2ba80', class: "title", id: this.dialogTitleId, hidden: !this.hasHeader }, hAsync("slot", { key: 'b6eb7885e220e5def4c3c8420d5b83f4a7e30907', name: "header", ref: (element) => (this.headerSlot = element), onSlotchange: this.handleHeaderSlotChange })), hAsync("lmvz-button", { key: '72e17391097dfa756e572764f40080b6eec222b2', ref: (element) => (this.closeButtonEl = element), type: "button", class: "close-button", "aria-label": this.closeLabel, onLmvzActivation: this.handleCloseButtonClick, variant: "tertiary" }, hAsync("lmvz-icon", { key: '7bbae1aefa9ccc6646d5861683e3476339a545e4', icon: closeIconSvg }))), hAsync("div", { key: '9f22628448e9af527eb10ef2602c498afc55c029', class: "body" }, hAsync("slot", { key: '413e72707749b3abc987ef47a81cccda4b874c84' })), hAsync("footer", { key: 'a1a8f648e88d1f9045e9cf866d332aac69e033df', class: "actions", hidden: !this.buttonGroupEl?.hasActions }, hAsync("lmvz-button-group", { key: '7d7eeee7a2551a09bfb4fc513bde48828be5ee8b', ref: (element) => (this.buttonGroupEl = element) }, hAsync("slot", { key: '76b00523167c5fa08f11fc351a37638227401711', name: "actions" })))))));
9806
9899
  }
9807
9900
  static get watchers() { return {
9808
9901
  "open": [{
@@ -11191,10 +11284,12 @@ class LmvzPopover {
11191
11284
  this.lmvzCancel = createEvent(this, "lmvzCancel", 7);
11192
11285
  }
11193
11286
  get el() { return getElement(this); }
11194
- closureController = new AbortController();
11287
+ extEventController = new AbortController();
11288
+ closureController;
11195
11289
  containerEl;
11196
11290
  slotEl;
11197
11291
  previouslyFocusedElement = null;
11292
+ anchorEl;
11198
11293
  open = false;
11199
11294
  anchor;
11200
11295
  placement = 'bottom-start';
@@ -11220,7 +11315,6 @@ class LmvzPopover {
11220
11315
  }
11221
11316
  componentDidLoad() {
11222
11317
  autoAssignId(this.el);
11223
- validatePopoverAria(this.el, this.label, this.anchor, this.resolveAnchor());
11224
11318
  }
11225
11319
  handleOpenChange(isOpen) {
11226
11320
  if (isOpen) {
@@ -11230,24 +11324,40 @@ class LmvzPopover {
11230
11324
  this.onClose();
11231
11325
  }
11232
11326
  }
11233
- handleAnchorChange() {
11234
- if (this.open) {
11235
- this.updatePosition();
11327
+ async handleAnchorChange(anchor) {
11328
+ if (!anchor) {
11329
+ console.warn('anchor property missing for popover', this.el?.id);
11330
+ this.anchor = undefined;
11331
+ return;
11236
11332
  }
11333
+ await wait();
11334
+ this.anchorEl = typeof anchor === 'string' ? document.getElementById(anchor) : anchor;
11335
+ this.setupAnchorEl();
11336
+ if (!this.open)
11337
+ return;
11338
+ this.updatePosition();
11237
11339
  }
11238
11340
  disconnectedCallback() {
11239
11341
  this.removeCloseHandlers();
11342
+ this.extEventController.abort();
11240
11343
  }
11241
- resolveAnchor() {
11242
- if (!this.anchor)
11243
- return null;
11244
- if (typeof this.anchor === 'string') {
11245
- return document.getElementById(this.anchor);
11344
+ setupAnchorEl() {
11345
+ const { anchorEl } = this;
11346
+ if (!anchorEl) {
11347
+ console.warn('no anchor element set for', this);
11348
+ return;
11349
+ }
11350
+ if (!anchorEl.hasAttribute('aria-haspopup')) {
11351
+ anchorEl.setAttribute('aria-haspopup', 'dialog');
11352
+ }
11353
+ anchorEl.setAttribute('aria-controls', this.el.getAttribute('id'));
11354
+ if (isActionButton(anchorEl)) {
11355
+ addElementActivationListener(anchorEl, this.toggle.bind(this), this.extEventController.signal);
11246
11356
  }
11247
- return this.anchor;
11357
+ validatePopoverAria(this.el, this.label, this.anchor, anchorEl);
11248
11358
  }
11249
11359
  async updatePosition() {
11250
- const anchorEl = this.resolveAnchor();
11360
+ const { anchorEl } = this;
11251
11361
  const container = this.containerEl;
11252
11362
  if (!anchorEl || !container)
11253
11363
  return;
@@ -11262,7 +11372,6 @@ class LmvzPopover {
11262
11372
  async onOpen() {
11263
11373
  this.previouslyFocusedElement = getDeepActiveElement(document);
11264
11374
  this.setupCloseHandlers();
11265
- console.log('onOpen');
11266
11375
  await waitFrame();
11267
11376
  await this.updatePosition();
11268
11377
  autoAssignId(this.el);
@@ -11280,20 +11389,14 @@ class LmvzPopover {
11280
11389
  this.lmvzClose.emit();
11281
11390
  }
11282
11391
  applyAnchorAriaOpen() {
11283
- const anchorEl = this.resolveAnchor();
11284
- if (!anchorEl)
11392
+ if (!this.anchorEl)
11285
11393
  return;
11286
- if (!anchorEl.hasAttribute('aria-haspopup')) {
11287
- anchorEl.setAttribute('aria-haspopup', 'dialog');
11288
- }
11289
- anchorEl.setAttribute('aria-expanded', 'true');
11290
- anchorEl.setAttribute('aria-controls', this.el.getAttribute('id'));
11394
+ this.anchorEl.setAttribute('aria-expanded', 'true');
11291
11395
  }
11292
11396
  applyAnchorAriaClose() {
11293
- const anchorEl = this.resolveAnchor();
11294
- if (!anchorEl)
11397
+ if (!this.anchorEl)
11295
11398
  return;
11296
- anchorEl.setAttribute('aria-expanded', 'false');
11399
+ this.anchorEl.setAttribute('aria-expanded', 'false');
11297
11400
  }
11298
11401
  focusFirst() {
11299
11402
  const { slotEl } = this;
@@ -11301,6 +11404,12 @@ class LmvzPopover {
11301
11404
  return;
11302
11405
  const assigned = slotEl.assignedElements({ flatten: true });
11303
11406
  for (const el of assigned) {
11407
+ if (!isHtmlElement(el))
11408
+ continue;
11409
+ if (isFocusControllerHost(el)) {
11410
+ el.initFocus();
11411
+ return;
11412
+ }
11304
11413
  const focusable = walkShadowDOMUntil(el, canReceiveFocus);
11305
11414
  if (focusable) {
11306
11415
  focusable.focus();
@@ -11322,6 +11431,7 @@ class LmvzPopover {
11322
11431
  }
11323
11432
  }
11324
11433
  setupCloseHandlers() {
11434
+ this.closureController = new AbortController();
11325
11435
  const options = { signal: this.closureController.signal };
11326
11436
  document.addEventListener('mousedown', (event) => {
11327
11437
  if (!this.open)
@@ -11339,17 +11449,17 @@ class LmvzPopover {
11339
11449
  }, options);
11340
11450
  }
11341
11451
  removeCloseHandlers() {
11342
- this.closureController.abort();
11452
+ this.closureController?.abort();
11343
11453
  }
11344
11454
  render() {
11345
- return (hAsync(Host, { key: '3dd462a66f17c1617e44787107379d9e4d8ca321' }, hAsync("div", { key: '27106bc8f3169eb07e0d671635074ddb53feb652', role: "dialog", part: "container", class: `container lmvz-wrapper-card-${this.size}`, "aria-label": this.label || undefined, ref: (el) => (this.containerEl = el) }, hAsync("slot", { key: '3401e621d999a225aeb7cb23fa4f5412544a6dab', ref: (el) => (this.slotEl = el) }))));
11455
+ return (hAsync(Host, { key: '744dae23d80c1e81a0b8bd2e9fcb02c6669d54cd' }, hAsync("div", { key: '7f40e25f1e05738b2bbf900b90613004eb188395', role: "dialog", part: "container", class: `container lmvz-wrapper-card-${this.size}`, "aria-label": this.label || undefined, ref: (el) => (this.containerEl = el) }, hAsync("slot", { key: '5a400fd9e697254007973f2dce172588fe3760ee', ref: (el) => (this.slotEl = el) }))));
11346
11456
  }
11347
11457
  static get watchers() { return {
11348
11458
  "open": [{
11349
11459
  "handleOpenChange": 0
11350
11460
  }],
11351
11461
  "anchor": [{
11352
- "handleAnchorChange": 0
11462
+ "handleAnchorChange": 1
11353
11463
  }]
11354
11464
  }; }
11355
11465
  static get style() { return lmvzPopoverCss(); }
@@ -11363,6 +11473,7 @@ class LmvzPopover {
11363
11473
  "size": [1],
11364
11474
  "autoFocus": [4, "auto-focus"],
11365
11475
  "label": [1],
11476
+ "anchorEl": [32],
11366
11477
  "show": [64],
11367
11478
  "hide": [64],
11368
11479
  "toggle": [64]
@@ -12037,6 +12148,9 @@ class LmvzTabs extends ReactiveControllerHost {
12037
12148
  this.syncFocusTargets();
12038
12149
  this.syncTabOrientation();
12039
12150
  }
12151
+ async initFocus() {
12152
+ this.focusController.initFocus();
12153
+ }
12040
12154
  async activateTab(value) {
12041
12155
  const tab = this.findTabByValue(value);
12042
12156
  if (!tab || this.isTabDisabled(tab))
@@ -12226,7 +12340,7 @@ class LmvzTabs extends ReactiveControllerHost {
12226
12340
  this.selectTab(value);
12227
12341
  };
12228
12342
  render() {
12229
- return (hAsync(Host, { key: '2f681e7bfc21bd513bcb994f92c893bbc03ff713', onClick: this.handleTabClick, onKeydown: this.handleKeydown }, hAsync("div", { key: '456ce3d11ccacd3e79995ffa643bb164127344b3', role: "tablist", "aria-orientation": this.orientation, class: "tablist" }, hAsync("slot", { key: 'e4e4c698dde6416e0ba4d319e64d9ba3a2f79a19', ref: (el) => (this.tabSlotEl = el) })), hAsync("div", { key: '3b90c8e7006dbf75e22b8377a18ac47488b1184f', part: "panels-container", class: "panels-container" }, hAsync("slot", { key: '4cb4a9b04ab529a1bc7744a1893acf9a71c5c65e', name: "panels", ref: (el) => (this.panelSlotEl = el) }))));
12343
+ return (hAsync(Host, { key: '98df29f336a3ea47efa6c76a773de28c5174c718', onClick: this.handleTabClick, onKeydown: this.handleKeydown }, hAsync("div", { key: '7e35ae180c4ebf2f5a82e0fad0977cd3c38ac659', role: "tablist", "aria-orientation": this.orientation, class: "tablist" }, hAsync("slot", { key: '2520bc8b8988a60b37a067828ad237bf8dcfcc59', ref: (el) => (this.tabSlotEl = el) })), hAsync("div", { key: 'bd4a954b6caca2d9f2eb588f58590821ec4af888', part: "panels-container", class: "panels-container" }, hAsync("slot", { key: 'b4dffff530328e6e4c8d305895ef4dd2d5952757', name: "panels", ref: (el) => (this.panelSlotEl = el) }))));
12230
12344
  }
12231
12345
  static get watchers() { return {
12232
12346
  "value": [{
@@ -12244,6 +12358,7 @@ class LmvzTabs extends ReactiveControllerHost {
12244
12358
  "value": [1537],
12245
12359
  "orientation": [1537],
12246
12360
  "resolvedValue": [32],
12361
+ "initFocus": [64],
12247
12362
  "activateTab": [64],
12248
12363
  "getTabElements": [64],
12249
12364
  "setTabPanelIds": [64]