@lmvz-ds/components 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/cjs/{ds.constants-JXqgKnXL.js → ds.constants-CKeXfK-s.js} +12 -0
  3. package/cjs/{component-C7cavwmZ.js → element.util-Cq4y-_iX.js} +42 -31
  4. package/cjs/index.cjs.js +8 -1
  5. package/cjs/{list-keyboard-controller-CzZdPBeH.js → list-keyboard-controller-StN6Yn8W.js} +13 -8
  6. package/cjs/lmvz-action-list.cjs.entry.js +79 -0
  7. package/cjs/lmvz-button-group.cjs.entry.js +43 -47
  8. package/cjs/lmvz-button_2.cjs.entry.js +10 -8
  9. package/cjs/lmvz-card.cjs.entry.js +2 -2
  10. package/cjs/lmvz-checkbox.cjs.entry.js +2 -2
  11. package/cjs/lmvz-chip.cjs.entry.js +3 -3
  12. package/cjs/lmvz-components.cjs.js +1 -1
  13. package/cjs/lmvz-header_2.cjs.entry.js +3 -3
  14. package/cjs/lmvz-input.cjs.entry.js +6 -6
  15. package/cjs/lmvz-link.cjs.entry.js +69 -0
  16. package/cjs/lmvz-menuitem.cjs.entry.js +2 -2
  17. package/cjs/lmvz-message.cjs.entry.js +2 -2
  18. package/cjs/lmvz-modal.cjs.entry.js +5 -5
  19. package/cjs/lmvz-radio.cjs.entry.js +3 -3
  20. package/cjs/lmvz-select.cjs.entry.js +2 -2
  21. package/cjs/lmvz-snackbar.cjs.entry.js +2 -2
  22. package/cjs/lmvz-spinner.cjs.entry.js +1 -1
  23. package/cjs/lmvz-tab.cjs.entry.js +2 -2
  24. package/cjs/lmvz-tabs.cjs.entry.js +4 -4
  25. package/cjs/lmvz-toggle.cjs.entry.js +5 -5
  26. package/cjs/loader.cjs.js +1 -1
  27. package/cjs/stencil.util-DzvzXSwk.js +25 -0
  28. package/collection/api/ds.constants.js +1 -0
  29. package/collection/collection-manifest.json +2 -0
  30. package/collection/components/lmvz-action-list/lmvz-action-list.css +93 -0
  31. package/collection/components/lmvz-action-list/lmvz-action-list.js +104 -0
  32. package/collection/components/lmvz-button/lmvz-button.css +67 -44
  33. package/collection/components/lmvz-button/lmvz-button.js +28 -7
  34. package/collection/components/lmvz-button-group/lmvz-button-group.css +35 -3
  35. package/collection/components/lmvz-button-group/lmvz-button-group.js +54 -38
  36. package/collection/components/lmvz-card/lmvz-card.css +66 -47
  37. package/collection/components/lmvz-card/lmvz-card.js +2 -2
  38. package/collection/components/lmvz-checkbox/lmvz-checkbox.css +8 -5
  39. package/collection/components/lmvz-checkbox/lmvz-checkbox.js +2 -2
  40. package/collection/components/lmvz-chip/lmvz-chip.css +4 -2
  41. package/collection/components/lmvz-chip/lmvz-chip.js +7 -7
  42. package/collection/components/lmvz-header/lmvz-header.js +2 -2
  43. package/collection/components/lmvz-icon/lmvz-icon.js +2 -2
  44. package/collection/components/lmvz-input/lmvz-input.css +2 -2
  45. package/collection/components/lmvz-input/lmvz-input.js +5 -5
  46. package/collection/components/lmvz-link/lmvz-link.css +44 -0
  47. package/collection/components/lmvz-link/lmvz-link.js +183 -0
  48. package/collection/components/lmvz-menuitem/lmvz-menuitem.css +2 -1
  49. package/collection/components/lmvz-menuitem/lmvz-menuitem.js +2 -2
  50. package/collection/components/lmvz-message/lmvz-message.css +2 -1
  51. package/collection/components/lmvz-message/lmvz-message.js +1 -1
  52. package/collection/components/lmvz-modal/lmvz-modal.css +11 -2
  53. package/collection/components/lmvz-modal/lmvz-modal.js +3 -3
  54. package/collection/components/lmvz-radio/lmvz-radio.css +4 -2
  55. package/collection/components/lmvz-radio/lmvz-radio.js +2 -2
  56. package/collection/components/lmvz-select/lmvz-select.css +4 -3
  57. package/collection/components/lmvz-select/lmvz-select.js +2 -2
  58. package/collection/components/lmvz-snackbar/lmvz-snackbar.css +2 -1
  59. package/collection/components/lmvz-snackbar/lmvz-snackbar.js +1 -1
  60. package/collection/components/lmvz-spinner/lmvz-spinner.js +1 -1
  61. package/collection/components/lmvz-tab/lmvz-tab.css +11 -3
  62. package/collection/components/lmvz-tab/lmvz-tab.js +1 -1
  63. package/collection/components/lmvz-tabs/lmvz-tabs.css +7 -0
  64. package/collection/components/lmvz-tabs/lmvz-tabs.js +2 -2
  65. package/collection/components/lmvz-toggle/lmvz-toggle.css +2 -1
  66. package/collection/components/lmvz-toggle/lmvz-toggle.js +3 -3
  67. package/collection/index.js +1 -1
  68. package/collection/integration/header-integration/header-integration.js +1 -1
  69. package/collection/styles/fragments/_focus-within.css +2 -2
  70. package/collection/utils/aria/aria.constants.js +53 -0
  71. package/collection/utils/aria/list-keyboard-controller.js +12 -7
  72. package/collection/utils/async/async.util.js +62 -0
  73. package/collection/utils/data/event.utilt.js +19 -0
  74. package/collection/utils/data/number.util.js +6 -0
  75. package/collection/utils/data/object.util.js +20 -0
  76. package/collection/utils/data/time.util.js +3 -0
  77. package/collection/utils/element/element.util.js +117 -0
  78. package/collection/utils/{assets.js → stencil/assets.js} +1 -1
  79. package/collection/utils/stencil/stencil.util.js +12 -0
  80. package/components/index.d.ts +4 -0
  81. package/components/index.d.ts.bak +4 -0
  82. package/components/index.js +1 -1
  83. package/components/lmvz-action-list.d.ts +11 -0
  84. package/components/lmvz-action-list.d.ts.bak +11 -0
  85. package/components/lmvz-action-list.js +1 -0
  86. package/components/lmvz-button-group.js +1 -1
  87. package/components/lmvz-button.js +1 -1
  88. package/components/lmvz-card.js +1 -1
  89. package/components/lmvz-checkbox.js +1 -1
  90. package/components/lmvz-chip.js +1 -1
  91. package/components/lmvz-header.js +1 -1
  92. package/components/lmvz-icon.js +1 -1
  93. package/components/lmvz-input.js +1 -1
  94. package/components/lmvz-link.d.ts +11 -0
  95. package/components/lmvz-link.d.ts.bak +11 -0
  96. package/components/lmvz-link.js +1 -0
  97. package/components/lmvz-menuitem.js +1 -1
  98. package/components/lmvz-message.js +1 -1
  99. package/components/lmvz-modal.js +1 -1
  100. package/components/lmvz-radio.js +1 -1
  101. package/components/lmvz-select.js +1 -1
  102. package/components/lmvz-snackbar.js +1 -1
  103. package/components/lmvz-spinner.js +1 -1
  104. package/components/lmvz-tab.js +1 -1
  105. package/components/lmvz-tabs.js +1 -1
  106. package/components/lmvz-toggle.js +1 -1
  107. package/components/p-B0H9qIwE.js +1 -0
  108. package/components/p-B4m1n4et.js +1 -0
  109. package/components/p-CJRqhXjK.js +1 -0
  110. package/components/p-CxfT9IA1.js +1 -0
  111. package/components/{p-CXakymyP.js → p-DJ90327O.js} +1 -1
  112. package/components/p-DeO5Vbxh.js +1 -0
  113. package/components/p-DuEtnKRj.js +1 -0
  114. package/esm/ds.constants-DuEtnKRj.js +18 -0
  115. package/esm/{component-DOTK1OW3.js → element.util-CxfT9IA1.js} +37 -31
  116. package/esm/index.js +1 -1
  117. package/esm/{list-keyboard-controller-Coi8XfUH.js → list-keyboard-controller-BKa9Kd2t.js} +12 -7
  118. package/esm/lmvz-action-list.entry.js +77 -0
  119. package/esm/lmvz-button-group.entry.js +35 -39
  120. package/esm/lmvz-button_2.entry.js +9 -7
  121. package/esm/lmvz-card.entry.js +2 -2
  122. package/esm/lmvz-checkbox.entry.js +2 -2
  123. package/esm/lmvz-chip.entry.js +3 -3
  124. package/esm/lmvz-components.js +1 -1
  125. package/esm/lmvz-header_2.entry.js +3 -3
  126. package/esm/lmvz-input.entry.js +5 -5
  127. package/esm/lmvz-link.entry.js +67 -0
  128. package/esm/lmvz-menuitem.entry.js +2 -2
  129. package/esm/lmvz-message.entry.js +2 -2
  130. package/esm/lmvz-modal.entry.js +3 -3
  131. package/esm/lmvz-radio.entry.js +3 -3
  132. package/esm/lmvz-select.entry.js +2 -2
  133. package/esm/lmvz-snackbar.entry.js +2 -2
  134. package/esm/lmvz-spinner.entry.js +1 -1
  135. package/esm/lmvz-tab.entry.js +2 -2
  136. package/esm/lmvz-tabs.entry.js +4 -4
  137. package/esm/lmvz-toggle.entry.js +4 -4
  138. package/esm/loader.js +1 -1
  139. package/esm/stencil.util-CJRqhXjK.js +23 -0
  140. package/hydrate/index.js +586 -396
  141. package/hydrate/index.mjs +586 -396
  142. package/lmvz-components/index.esm.js +1 -1
  143. package/lmvz-components/lmvz-components.esm.js +1 -1
  144. package/lmvz-components/p-1ce90ea7.entry.js +1 -0
  145. package/lmvz-components/{p-4484ab62.entry.js → p-24125bcf.entry.js} +1 -1
  146. package/lmvz-components/p-25a78ead.entry.js +1 -0
  147. package/lmvz-components/p-4072b2fb.entry.js +1 -0
  148. package/lmvz-components/p-48109e1d.entry.js +1 -0
  149. package/lmvz-components/{p-3b3e532f.entry.js → p-582f44ff.entry.js} +1 -1
  150. package/lmvz-components/p-592d509b.entry.js +1 -0
  151. package/lmvz-components/{p-7fd7e04c.entry.js → p-6f61c24d.entry.js} +1 -1
  152. package/lmvz-components/{p-5fcc6f84.entry.js → p-703b10b5.entry.js} +1 -1
  153. package/lmvz-components/p-74c7521c.entry.js +1 -0
  154. package/lmvz-components/{p-7e9938e7.entry.js → p-80a26307.entry.js} +1 -1
  155. package/lmvz-components/p-8e1f66dd.entry.js +1 -0
  156. package/lmvz-components/p-947e1fe6.entry.js +1 -0
  157. package/lmvz-components/p-B4m1n4et.js +1 -0
  158. package/lmvz-components/p-CJRqhXjK.js +1 -0
  159. package/lmvz-components/p-CxfT9IA1.js +1 -0
  160. package/lmvz-components/p-DuEtnKRj.js +1 -0
  161. package/lmvz-components/{p-2981a238.entry.js → p-b79af711.entry.js} +1 -1
  162. package/lmvz-components/p-c00f0d96.entry.js +1 -0
  163. package/lmvz-components/p-c0d05a97.entry.js +1 -0
  164. package/lmvz-components/p-c3e8092e.entry.js +1 -0
  165. package/lmvz-components/{p-fe7999d4.entry.js → p-ed3c2b13.entry.js} +1 -1
  166. package/lmvz-components/{p-af4e26da.entry.js → p-fa2cd315.entry.js} +1 -1
  167. package/manifest.json +336 -14
  168. package/package.json +9 -1
  169. package/types/api/ds.constants.d.ts +1 -37
  170. package/types/api/ds.types.d.ts +68 -1
  171. package/types/components/lmvz-action-list/lmvz-action-list.d.ts +15 -0
  172. package/types/components/lmvz-button/lmvz-button.d.ts +6 -3
  173. package/types/components/lmvz-button-group/lmvz-button-group.d.ts +2 -0
  174. package/types/components/lmvz-checkbox/lmvz-checkbox.d.ts +1 -1
  175. package/types/components/lmvz-chip/lmvz-chip.d.ts +2 -2
  176. package/types/components/lmvz-header/lmvz-header.d.ts +1 -1
  177. package/types/components/lmvz-icon/lmvz-icon.d.ts +1 -1
  178. package/types/components/lmvz-input/lmvz-input.d.ts +1 -1
  179. package/types/components/lmvz-link/lmvz-link.d.ts +13 -0
  180. package/types/components/lmvz-menuitem/lmvz-menuitem.d.ts +1 -1
  181. package/types/components/lmvz-modal/lmvz-modal.d.ts +1 -1
  182. package/types/components/lmvz-radio/lmvz-radio.d.ts +1 -1
  183. package/types/components/lmvz-select/lmvz-select.d.ts +1 -1
  184. package/types/components/lmvz-tabs/lmvz-tabs.d.ts +1 -1
  185. package/types/components/lmvz-toggle/lmvz-toggle.d.ts +1 -1
  186. package/types/components.d.ts +153 -2
  187. package/types/index.d.ts +1 -1
  188. package/types/utils/aria/aria-validation-controller.d.ts +3 -3
  189. package/types/utils/aria/aria.constants.d.ts +1 -0
  190. package/types/utils/aria/element-activation-controller.d.ts +1 -1
  191. package/types/utils/aria/list-keyboard-controller.d.ts +4 -1
  192. package/types/utils/async/async.util.d.ts +8 -0
  193. package/types/utils/data/event.utilt.d.ts +4 -0
  194. package/types/utils/data/number.util.d.ts +2 -0
  195. package/types/utils/data/object.util.d.ts +5 -0
  196. package/types/utils/data/time.util.d.ts +1 -0
  197. package/types/utils/element/element.util.d.ts +21 -0
  198. package/types/utils/radio/radio-group-controller.d.ts +1 -1
  199. package/types/utils/{reactive-controller-host.d.ts → stencil/reactive-controller-host.d.ts} +1 -1
  200. package/types/utils/stencil/stencil.util.d.ts +6 -0
  201. package/collection/utils/component.js +0 -270
  202. package/collection/utils/http.js +0 -21
  203. package/collection/utils/http.unit.js +0 -47
  204. package/components/p-BxPuC-EQ.js +0 -1
  205. package/components/p-CtaMrBNE.js +0 -1
  206. package/components/p-DBZE-Jyu.js +0 -1
  207. package/components/p-DOTK1OW3.js +0 -1
  208. package/esm/ds.constants-DWePb-zu.js +0 -13
  209. package/lmvz-components/p-087853c3.entry.js +0 -1
  210. package/lmvz-components/p-35b5efdc.entry.js +0 -1
  211. package/lmvz-components/p-4ba3f830.entry.js +0 -1
  212. package/lmvz-components/p-83ab106c.entry.js +0 -1
  213. package/lmvz-components/p-87d207e7.entry.js +0 -1
  214. package/lmvz-components/p-912776f8.entry.js +0 -1
  215. package/lmvz-components/p-CtaMrBNE.js +0 -1
  216. package/lmvz-components/p-DOTK1OW3.js +0 -1
  217. package/lmvz-components/p-DWePb-zu.js +0 -1
  218. package/lmvz-components/p-ca497e57.entry.js +0 -1
  219. package/lmvz-components/p-d8b55d55.entry.js +0 -1
  220. package/lmvz-components/p-f030f6f6.entry.js +0 -1
  221. package/types/utils/component.d.ts +0 -33
  222. package/types/utils/http.d.ts +0 -26
  223. package/types/utils/http.unit.d.ts +0 -1
  224. /package/collection/utils/{reactive-controller-host.js → stencil/reactive-controller-host.js} +0 -0
  225. /package/types/utils/{assets.d.ts → stencil/assets.d.ts} +0 -0
@@ -55,22 +55,34 @@ h6 {
55
55
  display: none !important;
56
56
  }
57
57
 
58
+ hr {
59
+ height: 0;
60
+ border: none;
61
+ margin: var(--lmvz-dimension-4-8, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)) 0;
62
+ border-top: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-subtle, #f0f0f0);
63
+ }
64
+
58
65
  }
59
66
  :host {
60
67
  /* * the (invalid nested) import will be handled by postcss */
61
68
  /* stylelint-disable-next-line no-invalid-position-at-import-rule */
62
69
  button {
63
70
  /* secondary styling is default, primary is explicit */
64
- --lmvz-button-color: var(--lmvz-component-color, var(--lmvz-semantic-color-int-on-secondary, #000000));
65
- --lmvz-button-padding-inline: var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)));
66
- --lmvz-button-padding-block: var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem)));
67
- --lmvz-button-gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem));
68
- --lmvz-button-min-height: var(--lmvz-component-input-size-md, clamp(2.5rem, 2.44rem + 0.26vw, 2.75rem));
69
- --lmvz-button-font: var(--lmvz-typography-body-md-strong);
70
- --lmvz-button-radius: var(--lmvz-component-input-radius-default, 999px);
71
- --lmvz-button-border-width: 0;
72
- --lmvz-button-border-color: transparent;
73
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0);
71
+ /* --lmvz-button-background, --lmvz-button-color, --lmvz-button-radius are declared on :host
72
+ so that outer ::slotted(lmvz-button) overrides are inherited correctly via shadow inheritance.
73
+ They are also declared here so that non-shadow consumers (e.g. @lmvz-ds/styles buttons.css
74
+ bundle and lmvz-card) have the default values in scope. */
75
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0));
76
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000));
77
+ --lmvz-button-radius: var(--lmvz-button-radius-override, var(--lmvz-component-input-radius-default, 999px));
78
+ --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))));
79
+ --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))));
80
+ --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)));
81
+ --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)));
82
+ --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-md-strong, 500 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5
83
+ Router));
84
+ --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
85
+ --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
74
86
 
75
87
  display: inline-flex;
76
88
  align-items: center;
@@ -101,8 +113,10 @@ button > * {
101
113
  }
102
114
 
103
115
  button:focus-visible {
104
- outline: var(--lmvz-ds-outline);
105
- outline-offset: var(--lmvz-ds-outline-offset);
116
+ outline: var(--lmvz-ds-outline, 1px solid #0e7ab4);
117
+ outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem));
118
+ position: relative;
119
+ z-index: 1;
106
120
  }
107
121
 
108
122
  button:is([disabled], .disabled) {
@@ -118,78 +132,87 @@ button:is([disabled], .disabled) {
118
132
  }
119
133
 
120
134
  button:not([disabled]):hover {
121
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0);
135
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0));
122
136
  }
123
137
 
124
138
  button:not([disabled]):active {
125
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4);
139
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4));
126
140
  }
127
141
 
128
142
  button.primary {
129
- --lmvz-button-background: var(--lmvz-semantic-color-int-primary, #000000);
130
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-primary, #ffffff);
131
- --lmvz-button-border-width: 0;
132
- --lmvz-button-border-color: transparent;
143
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary, #000000));
144
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-primary, #ffffff));
145
+ --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
146
+ --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
133
147
  }
134
148
 
135
149
  button.primary:not([disabled], .disabled):hover {
136
- --lmvz-button-background: var(--lmvz-semantic-color-int-primary-hover, #2e2e2e);
150
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-hover, #2e2e2e));
137
151
  }
138
152
 
139
153
  button.primary:not([disabled], .disabled):active {
140
- --lmvz-button-background: var(--lmvz-semantic-color-int-primary-active, #545454);
154
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-active, #545454));
141
155
  }
142
156
 
143
157
  button.secondary {
144
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0);
145
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary, #000000);
146
- --lmvz-button-border-width: 0;
147
- --lmvz-button-border-color: transparent;
158
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0));
159
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000));
160
+ --lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
161
+ --lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
148
162
  }
149
163
 
150
164
  button.secondary:not([disabled], .disabled):hover {
151
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0);
152
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-hover, #000000);
165
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0));
166
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary-hover, #000000));
153
167
  }
154
168
 
155
169
  button.secondary:not([disabled], .disabled):active {
156
- --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4);
157
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-active, #000000);
170
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4));
171
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary-active, #000000));
158
172
  }
159
173
 
160
174
  button.tertiary {
161
- --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary, #ffffff);
162
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary, #000000);
175
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff));
176
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary, #000000));
163
177
  }
164
178
 
165
179
  button.tertiary:not([disabled], .disabled):hover {
166
- --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0);
167
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-hover, #000000);
180
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0));
181
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-hover, #000000));
168
182
  }
169
183
 
170
184
  button.tertiary:not([disabled], .disabled):active {
171
- --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0);
172
- --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-active, #000000);
185
+ --lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0));
186
+ --lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-active, #000000));
173
187
  }
174
188
 
175
189
  button.small {
176
- --lmvz-button-padding-inline: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem));
177
- --lmvz-button-padding-block: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem));
178
- --lmvz-button-gap: var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem));
179
- --lmvz-button-min-height: var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem));
180
- --lmvz-button-font: var(--lmvz-typography-body-sm-strong);
190
+ --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)));
191
+ --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)));
192
+ --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem)));
193
+ --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem)));
194
+ --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-sm-strong, 500 clamp(0.69rem, 0.67rem + 0.06vw, 0.75rem) / 1.5
195
+ Router));
181
196
  }
182
197
 
183
198
  button.large {
184
- --lmvz-button-padding-inline: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem));
185
- --lmvz-button-padding-block: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem));
186
- --lmvz-button-gap: var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem));
187
- --lmvz-button-min-height: var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem));
188
- --lmvz-button-font: var(--lmvz-typography-body-lg-strong);
199
+ --lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)));
200
+ --lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)));
201
+ --lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem)));
202
+ --lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem)));
203
+ --lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-lg-strong, 500 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5
204
+ Router));
189
205
  }
190
206
 
191
207
 
192
208
  display: inline-block;
209
+
210
+ button {
211
+ width: 100%;
212
+ }
213
+ }
214
+ button {
215
+ width: 100%;
193
216
  }
194
217
  ::slotted(*) {
195
218
  --lmvz-component-color: var(--lmvz-button-color);
@@ -2,8 +2,8 @@ import { Host, h } from "@stencil/core";
2
2
  import classNames from "classnames";
3
3
  import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
4
4
  import { ElementActivationController } from "../../utils/aria/element-activation-controller";
5
- import { findFormByRef, inheritAriaAttributes } from "../../utils/component";
6
- import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
5
+ import { findFormByRef, inheritAriaAttributes } from "../../utils/element/element.util";
6
+ import { ReactiveControllerHost } from "../../utils/stencil/reactive-controller-host";
7
7
  export class LmvzButton extends ReactiveControllerHost {
8
8
  el;
9
9
  validationEl;
@@ -11,8 +11,9 @@ export class LmvzButton extends ReactiveControllerHost {
11
11
  formEl = null;
12
12
  formButtonEl = null;
13
13
  lmvzActivation;
14
- get ti() {
15
- return 0;
14
+ ti = 0;
15
+ resolveFocusableElement() {
16
+ return this.validationEl;
16
17
  }
17
18
  scale = 'default';
18
19
  variant;
@@ -22,6 +23,7 @@ export class LmvzButton extends ReactiveControllerHost {
22
23
  formMethod;
23
24
  name;
24
25
  value;
26
+ buttonRole;
25
27
  constructor() {
26
28
  super();
27
29
  this.addController(new AriaValidationController(this));
@@ -31,7 +33,7 @@ export class LmvzButton extends ReactiveControllerHost {
31
33
  }));
32
34
  }
33
35
  connectedCallback() {
34
- this.inheritedAttributes = inheritAriaAttributes(this.el);
36
+ this.inheritedAttributes = inheritAriaAttributes(this.el, ['role']);
35
37
  super.connectedCallback();
36
38
  }
37
39
  disconnectedCallback() {
@@ -88,7 +90,7 @@ export class LmvzButton extends ReactiveControllerHost {
88
90
  };
89
91
  render() {
90
92
  this.renderHiddenButton();
91
- return (h(Host, { key: '8196de85afc3878c6f38e582d7c031f5d19bcd36', "aria-disabled": this.disabled ? 'true' : null }, h("button", { key: '8d73f979fa227de22a03403a2a3938684911060a', ref: (e) => (this.validationEl = e), part: "button", disabled: this.disabled, type: this.type, class: classNames(this.variant ?? 'secondary', { [this.scale ?? '']: !!this.scale, disabled: this.disabled }), ...this.inheritedAttributes }, h("slot", { key: '18e91a2f94ba0d7e5cf13150191003e2f0b2a03a' }))));
93
+ return (h(Host, { key: 'f3e619dca398c3a8a78e9d2f8c3df4178b2531b2', role: "presentation" }, h("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 }, h("slot", { key: '786ff1c10ae05eda646c77ac8779813be6e51949' }))));
92
94
  }
93
95
  static get is() { return "lmvz-button"; }
94
96
  static get encapsulation() { return "shadow"; }
@@ -119,7 +121,7 @@ export class LmvzButton extends ReactiveControllerHost {
119
121
  "tags": [],
120
122
  "text": ""
121
123
  },
122
- "getter": true,
124
+ "getter": false,
123
125
  "setter": false,
124
126
  "reflect": true,
125
127
  "attribute": "tabindex",
@@ -312,6 +314,25 @@ export class LmvzButton extends ReactiveControllerHost {
312
314
  "setter": false,
313
315
  "reflect": false,
314
316
  "attribute": "value"
317
+ },
318
+ "buttonRole": {
319
+ "type": "string",
320
+ "mutable": false,
321
+ "complexType": {
322
+ "original": "string",
323
+ "resolved": "string | undefined",
324
+ "references": {}
325
+ },
326
+ "required": false,
327
+ "optional": true,
328
+ "docs": {
329
+ "tags": [],
330
+ "text": "ARIA role applied to the inner `<button>` element.\nWhen set, the host element receives `role=\"presentation\"` so that AT\nsees only one interactive element with the correct role.\nUse `\"menuitem\"` when the button is a child of a `role=\"menu\"` container."
331
+ },
332
+ "getter": false,
333
+ "setter": false,
334
+ "reflect": false,
335
+ "attribute": "button-role"
315
336
  }
316
337
  };
317
338
  }
@@ -1,13 +1,45 @@
1
1
  :host {
2
2
  display: flex;
3
- justify-content: flex-end;
3
+ flex-flow: row-reverse wrap;
4
4
  gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem));
5
- font: var(--lmvz-typography-body-md);
5
+ font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5
6
+ Router);
6
7
 
7
8
  /* TODO(LDHCID-135): Action wrapping threshold remains an assumption and currently follows intrinsic content width */
8
- flex-wrap: wrap;
9
+ }
10
+
11
+ :host([stacked]) {
12
+ flex-flow: column nowrap;
13
+ align-items: stretch;
14
+ padding: 0;
15
+ }
16
+
17
+ :host([stacked]) ::slotted(*) {
18
+ display: block;
19
+ width: 100%;
9
20
  }
10
21
 
11
22
  ::slotted([hidden]) {
12
23
  display: none !important;
13
24
  }
25
+
26
+ /*
27
+ * Non-stacked alignment split: push tertiary cluster to the right, primary/secondary stays left.
28
+ *
29
+ * OQ-A1 resolution: margin-inline-end: auto is used (not margin-inline-start).
30
+ * The host uses flex-flow: row-reverse, so the flex main axis runs right→left
31
+ * (main-start is on the right, main-end is on the left in LTR).
32
+ * Tertiary buttons appear last in DOM but are rendered leftmost by row-reverse.
33
+ * Applying margin-inline-end: auto on the tertiary items creates an auto margin on
34
+ * their inline-end side (right in LTR), which corresponds to the flex main-start
35
+ * direction — this absorbs all available space between the p/s cluster and the
36
+ * tertiary cluster, pushing tertiary visually to the right as intended.
37
+ */
38
+
39
+ :host(:not([data-only-tertiary], [stacked])) ::slotted([data-first-tertiary]) {
40
+ margin-inline-end: auto;
41
+ }
42
+
43
+ :host([data-only-tertiary]:not([stacked])) {
44
+ justify-content: flex-end;
45
+ }
@@ -1,11 +1,13 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { negate } from "@lmvz-ds/lib-ts/stream/negate.js";
3
- import { isAriaValidationEnabled } from "../..";
4
- import { canReceiveFocus } from "../../utils/component";
3
+ import { isAriaValidationEnabled, variants } from "../..";
4
+ import { canReceiveFocus, isActionButton, isDisabledButton, isLmvzButton, isPrimaryAction, isSecondaryAction, isVisible } from "../../utils/element/element.util";
5
5
  export class LmvzButtonGroup {
6
+ el;
6
7
  actionsSlot;
7
8
  validationMessageCache = [];
8
9
  actionsStateObserver;
10
+ stacked = false;
9
11
  get primaryEnabledAction() {
10
12
  return this.enabledButtons.find(isPrimaryAction) ?? this.enabledButtons[0];
11
13
  }
@@ -37,23 +39,23 @@ export class LmvzButtonGroup {
37
39
  const primaryActions = this.visibleButtons.filter(isPrimaryAction);
38
40
  const secondaryActions = this.visibleButtons.filter(isSecondaryAction);
39
41
  const issues = [];
40
- const order = this.visibleButtons.toReversed();
42
+ const order = this.visibleButtons;
41
43
  if (primaryActions.length !== 1)
42
- issues.push('LmvzModal actions slot must contain exactly one primary action.');
44
+ issues.push('LmvzButtonGroup actions slot should contain exactly one primary action.');
43
45
  if (secondaryActions.length > 1)
44
- issues.push(`LmvzModal actions slot must contain at most one secondary action (received ${secondaryActions.length})`);
46
+ issues.push(`LmvzButtonGroup actions slot should contain at most one secondary action (received ${secondaryActions.length})`);
45
47
  if (primaryActions.length) {
46
48
  const primaryAction = primaryActions[0];
47
49
  const secondaryAction = secondaryActions[0];
48
50
  if (order.indexOf(primaryAction) !== 0)
49
- issues.push('Primary action must be the last focusable element in the actions slot (i.e. rightmost button).');
51
+ issues.push('Primary action should be the first focusable element in the actions slot (i.e. first child of the actions slot).');
50
52
  if (secondaryAction && order.indexOf(secondaryAction) !== 1)
51
- issues.push('Secondary action must be the second-to-last focusable element in the actions slot (i.e. left of primary button).');
53
+ issues.push('Secondary action should be the second focusable element in the actions slot (i.e. immediately after the primary button).');
52
54
  }
53
55
  else if (secondaryActions.length) {
54
56
  const secondaryAction = secondaryActions[0];
55
57
  if (order.indexOf(secondaryAction) !== 0)
56
- issues.push('Secondary action must be the last focusable element in the actions slot when no primary action is present (i.e. rightmost button).');
58
+ issues.push('Secondary action should be the first focusable element in the actions slot when no primary action is present (i.e. first child of the actions slot).');
57
59
  }
58
60
  return issues;
59
61
  }
@@ -91,20 +93,35 @@ export class LmvzButtonGroup {
91
93
  }
92
94
  });
93
95
  this.checkActions();
94
- const length = this.visibleButtons.length;
95
- for (let i = 0; i < length; i++) {
96
- const variant = i === length - 1 ? 'primary' : i === length - 2 ? 'secondary' : 'tertiary';
97
- const element = this.visibleButtons.at(i);
96
+ const visibleButtons = this.visibleButtons;
97
+ const hasNonTertiary = visibleButtons.length > 0 && visibleButtons.some((btn) => isPrimaryAction(btn) || isSecondaryAction(btn));
98
+ if (visibleButtons.length > 0 && !hasNonTertiary) {
99
+ this.el.setAttribute('data-only-tertiary', '');
100
+ }
101
+ else {
102
+ this.el.removeAttribute('data-only-tertiary');
103
+ }
104
+ this.visibleButtons.forEach((element, i) => {
105
+ const variant = variants[i] ?? 'tertiary';
98
106
  if (!element)
99
- continue;
107
+ return;
100
108
  if (isLmvzButton(element)) {
101
- if (!element.getAttribute('variant'))
109
+ if (!element.getAttribute('variant') && !element.variant)
102
110
  element.setAttribute('variant', variant);
103
111
  }
104
112
  else {
105
113
  element.classList.add(variant);
106
114
  }
107
- }
115
+ });
116
+ const firstTertiary = this.visibleButtons.find((btn) => btn.getAttribute('variant') === 'tertiary');
117
+ this.visibleButtons.forEach((btn) => {
118
+ if (btn === firstTertiary) {
119
+ btn.setAttribute('data-first-tertiary', '');
120
+ }
121
+ else {
122
+ btn.removeAttribute('data-first-tertiary');
123
+ }
124
+ });
108
125
  this.focusPrimaryAction();
109
126
  }
110
127
  focusPrimaryAction() {
@@ -132,7 +149,7 @@ export class LmvzButtonGroup {
132
149
  });
133
150
  }
134
151
  render() {
135
- return (h(Host, { key: '56b60821ecaa2301d13e78d621e873aa74cd170e' }, h("slot", { key: 'e6a1422950fa5b0026356b7788a607a690116186', ref: (element) => (this.actionsSlot = element), onSlotchange: this.handleActionsSlotChange })));
152
+ return (h(Host, { key: '3e8ce38f7e83e201e47d31579f22161ff36247b1' }, h("slot", { key: 'bc953d19b333f51c5f5c5ba86be3a85d155a29d1', ref: (element) => (this.actionsSlot = element), onSlotchange: this.handleActionsSlotChange })));
136
153
  }
137
154
  static get is() { return "lmvz-button-group"; }
138
155
  static get encapsulation() { return "shadow"; }
@@ -148,6 +165,26 @@ export class LmvzButtonGroup {
148
165
  }
149
166
  static get properties() {
150
167
  return {
168
+ "stacked": {
169
+ "type": "boolean",
170
+ "mutable": false,
171
+ "complexType": {
172
+ "original": "boolean",
173
+ "resolved": "boolean",
174
+ "references": {}
175
+ },
176
+ "required": false,
177
+ "optional": false,
178
+ "docs": {
179
+ "tags": [],
180
+ "text": ""
181
+ },
182
+ "getter": false,
183
+ "setter": false,
184
+ "reflect": true,
185
+ "attribute": "stacked",
186
+ "defaultValue": "false"
187
+ },
151
188
  "primaryEnabledAction": {
152
189
  "type": "unknown",
153
190
  "mutable": false,
@@ -191,26 +228,5 @@ export class LmvzButtonGroup {
191
228
  }
192
229
  };
193
230
  }
194
- }
195
- function isActionButton(element) {
196
- return ['LMVZ-BUTTON', 'BUTTON'].includes(element.tagName.toUpperCase());
197
- }
198
- function isLmvzButton(element) {
199
- return element?.tagName.toUpperCase() === 'LMVZ-BUTTON';
200
- }
201
- function isDisabledButton(element) {
202
- return element.hasAttribute('disabled') || element.disabled === true;
203
- }
204
- function isVisible(element) {
205
- return !element.hasAttribute('hidden');
206
- }
207
- function getActionVariant(element) {
208
- const variant = element.getAttribute('variant') ?? element.variant;
209
- return variant === 'primary' || variant === 'secondary' || variant === 'tertiary' ? variant : 'secondary';
210
- }
211
- function isPrimaryAction(element) {
212
- return getActionVariant(element) === 'primary';
213
- }
214
- function isSecondaryAction(element) {
215
- return getActionVariant(element) === 'secondary';
231
+ static get elementRef() { return "el"; }
216
232
  }