@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
@@ -1 +1 @@
1
- import{g as r,r as e,c as o,h as t,H as i}from"./p-BPeerEwm.js";import{A as a}from"./p-CPOia2kT.js";import{R as s}from"./p-FBuCCcFC.js";import"./p-CdDO7mQa.js";function l(r){return r.el.shadowRoot?.querySelector("input")??r.el.querySelector("input")??null}class c{hosts=[];_focusedHost=null;_focusinHandler=r=>{this.hosts.some((e=>e.el.contains(r.target)))||this.clearFocused()};register(r){if(!this.hosts.includes(r)){const e=0===this.hosts.length;this.hosts.push(r),this.sortHosts(),e&&document.addEventListener("focusin",this._focusinHandler,!0)}}unregister(r){r===this._focusedHost&&(this._focusedHost=null),this.hosts=this.hosts.filter((e=>e!==r)),0===this.hosts.length&&document.removeEventListener("focusin",this._focusinHandler,!0)}get sortedEnabled(){return this.hosts.filter((r=>!r.disabled))}setFocused(r){this._focusedHost=r,this.updateTabindex(),r.focusInput()}clearFocused(){this._focusedHost=null,this.updateTabindex()}select(r){this._focusedHost=null;for(const e of this.hosts)e.checked=e===r;this.updateTabindex()}updateTabindex(){const r=this.sortedEnabled,e=this.hosts.find((r=>r.checked));let o;o=this._focusedHost&&r.includes(this._focusedHost)?this._focusedHost:e??r[0]??null;for(const r of this.hosts){const e=l(r);e&&(e.tabIndex=r===o?0:-1)}}sortHosts(){this.hosts.sort(((r,e)=>r.el.compareDocumentPosition(e.el)&Node.DOCUMENT_POSITION_FOLLOWING?-1:1))}}class n{host;static registry=new Map;group=null;_groupKey=null;_scope=null;constructor(r){this.host=r}hostConnected(){const{group:r,key:e,scope:o}=n.acquireGroup(this.host);this._groupKey=e,this._scope=o,this.group=r,this.group.register(this.host),this.group.updateTabindex()}hostDidRender(){this.group?.updateTabindex()}hostDisconnected(){this.group&&(this.group.unregister(this.host),this.group.updateTabindex(),n.releaseGroup(this._groupKey,this._scope),this._groupKey=null,this._scope=null,this.group=null)}get sortedEnabled(){return this.group?.sortedEnabled??[]}select(r){this.group?.select(r)}setFocused(r){this.group?.setFocused(r)}clearFocused(){this.group?.clearFocused()}updateTabindex(){this.group?.updateTabindex()}static acquireGroup(r){const e=r.name;if(!e)return{group:new c,key:null,scope:null};const o=r.el.closest("form")??document,t=function(r,e){return e instanceof HTMLFormElement?(e.dataset.lmvzRadioGroupId||(e.dataset.lmvzRadioGroupId=String(Math.random())),`${r}::form::${e.dataset.lmvzRadioGroupId}`):`${r}::document`}(e,o);let i=n.registry.get(t);return i||(i={group:new c,refCount:0},n.registry.set(t,i)),i.refCount++,{group:i.group,key:t,scope:o}}static releaseGroup(r,e){if(!r)return;const o=n.registry.get(r);o&&(o.refCount--,o.refCount<=0&&(n.registry.delete(r),e instanceof HTMLFormElement&&e.removeAttribute("data-lmvz-radio-group-id")))}}let d=0;const h=class extends s{get el(){return r(this)}get validationEl(){return this.el}internals;nativeInput;radioId="lmvz-radio-"+d++;initialChecked=!1;radioGroupController;get helperId(){return this.helperText?`${this.radioId}-helper`:void 0}label;checked=!1;value="on";name;disabled=!1;required=!1;error=!1;helperText;form;autofocus=!1;_handlingNativeChange=!1;_handlingFormReset=!1;handleCheckedChange(r,e){this.internals.setFormValue?.(r?this.value:null),r||!e||this._handlingNativeChange||this._handlingFormReset||this.lmvzChange.emit(!1),!r||e||this._handlingNativeChange||this._handlingFormReset||this.lmvzChange.emit(!0)}handleValueChange(r){this.checked&&this.internals.setFormValue?.(r)}handleLabelChange(r){r||console.warn("[lmvz-radio] label prop is required and must not be empty")}lmvzChange;lmvzActivation;async focusInput(){this.nativeInput?.focus()}async checkValidity(){return this.internals?.checkValidity()??!0}async reportValidity(){return this.internals?.reportValidity()??!0}constructor(r){super(),e(this,r),this.lmvzChange=o(this,"lmvzChange",7),this.lmvzActivation=o(this,"lmvzActivation",7),r.$hostElement$["s-ei"]?this.internals=r.$hostElement$["s-ei"]:(this.internals=r.$hostElement$.attachInternals(),r.$hostElement$["s-ei"]=this.internals),this.addController(new a(this,{reValidateOnPropChanges:!0})),this.radioGroupController=new n(this),this.addController(this.radioGroupController)}componentWillLoad(){this.initialChecked=this.checked,this.internals.setFormValue?.(this.checked?this.value:null),super.componentWillLoad()}formAssociatedCallback(){this.internals.setFormValue?.(this.checked?this.value:null)}formResetCallback(){this._handlingFormReset=!0;try{this.checked=this.initialChecked}finally{this._handlingFormReset=!1}}formStateRestoreCallback(r){if("string"==typeof r){this._handlingFormReset=!0;try{this.checked=r===this.value}finally{this._handlingFormReset=!1}}}handleChange=r=>{this._handlingNativeChange=!0;try{this.checked=r.target.checked,this.lmvzChange.emit(this.checked),this.radioGroupController.select(this),this.lmvzActivation.emit()}finally{this._handlingNativeChange=!1}};handleKeydown(r){const{key:e}=r;if(!["ArrowDown","ArrowRight","ArrowUp","ArrowLeft","Home","End"].includes(e))return;r.preventDefault();const o=this.radioGroupController.sortedEnabled;if(0===o.length)return;const t=o.indexOf(this);if(-1===t)return;let i;i="ArrowDown"===e||"ArrowRight"===e?(t+1)%o.length:"ArrowUp"===e||"ArrowLeft"===e?(t-1+o.length)%o.length:"Home"===e?0:o.length-1;const a=o[i];a&&this.radioGroupController.setFocused(a)}render(){return t(i,{key:"c07af5c7d75b0f0d2c20b3af9ea763bd28e027b5"},t("input",{key:"2e7fddb7aa5df3f8bc0f1efbd110158680ec45d7",type:"radio",id:this.radioId,name:this.name??void 0,value:this.value,checked:this.checked,disabled:this.disabled,required:this.required,autoFocus:this.autofocus,"aria-invalid":this.error?"true":void 0,"aria-describedby":this.helperId,ref:r=>this.nativeInput=r,onChange:this.handleChange}),t("span",{key:"a2afc55b85527674e5a18bfc28e194ecc034053a",class:"circle","aria-hidden":"true"},this.checked&&t("span",{key:"d135da1d567743ea98ec5860feda3e6e8013bdb6",class:"dot"})),t("span",{key:"38c83e877135b221260bacdefca3cdb5446a4453",class:"content"},t("label",{key:"781d9d5544c0cb9d061875ef3674f3c3156f0675",htmlFor:this.radioId},this.label),t("span",{key:"1ed064b27dea65cbfb1b1bd38a9cb1b7a07de37e","aria-live":"polite",class:"helper-text",id:this.helperId},this.helperText)))}static get formAssociated(){return!0}static get watchers(){return{checked:[{handleCheckedChange:0}],value:[{handleValueChange:0}],label:[{handleLabelChange:0}]}}};h.style="@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; } } .sc-lmvz-radio-h { display: inline-block; --radio-circle-size: var(--lmvz-global-s18, 18px); --radio-dot-size: 0.5rem; --radio-bg: var(--lmvz-semantic-color-surface-input-primary, #ffffff); --radio-border-color: var(--lmvz-semantic-color-border-default, #e0e0e0); --radio-border-color-hover: var(--lmvz-semantic-color-border-hover, #c7c7c7); --radio-border-color-checked: var(--lmvz-semantic-color-border-active, #0f8acc); --radio-border-color-error: var(--lmvz-semantic-color-status-on-danger, #e52a31); --radio-dot-color: var(--lmvz-semantic-color-border-active, #0f8acc); --radio-wrapper-bg-hover: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0); --radio-wrapper-bg-active: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0); --radio-label-color: var(--lmvz-semantic-color-on-surface-primary, #000000); --radio-label-color-checked: var(--lmvz-semantic-color-status-on-active, #0e7ab4); --radio-helper-color: var(--lmvz-semantic-color-on-surface-secondary, #7a7a7a); --radio-easing: var(--lmvz-global-easing-default, ease); --radio-duration: 0.2s; display: flex; align-items: center; gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); padding-block: var(--lmvz-dimension-2-8, clamp(0.13rem, 0.03rem + 0.39vw, 0.5rem)); padding-inline: var(--lmvz-dimension-8-12, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); border-radius: var(--lmvz-semantic-border-radius-round, 999px); overflow: clip; cursor: pointer; background-color: transparent; position: relative; transition: background-color var(--radio-duration) var(--radio-easing); } input.sc-lmvz-radio { position: absolute; inset-block-start: var(--lmvz-dimension-2-8, clamp(0.13rem, 0.03rem + 0.39vw, 0.5rem)); inset-inline-start: var(--lmvz-dimension-4-10, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); opacity: 0; width: var(--radio-circle-size); height: var(--radio-circle-size); margin: 0; cursor: pointer; z-index: 1; } .circle.sc-lmvz-radio { width: var(--radio-circle-size); height: var(--radio-circle-size); border-radius: 50%; border: var(--lmvz-semantic-border-width-default, 1px) solid var(--radio-border-color); background-color: var(--radio-bg); pointer-events: none; flex-shrink: 0; display: flex; align-items: center; justify-content: center; box-sizing: border-box; transition: border-color var(--radio-duration) var(--radio-easing); } .dot.sc-lmvz-radio { width: var(--radio-dot-size); height: var(--radio-dot-size); border-radius: 50%; background-color: var(--radio-dot-color); } .content.sc-lmvz-radio { display: flex; flex-direction: column; overflow-wrap: break-word; min-width: 0; } label.sc-lmvz-radio { font: var(--lmvz-typography-body-md); color: var(--radio-label-color); cursor: pointer; transition: color var(--radio-duration) var(--radio-easing); } .helper-text.sc-lmvz-radio { display: block; font: var(--lmvz-typography-body-sm); color: var(--radio-helper-color); margin-block-start: 2px; } .helper-text.sc-lmvz-radio:empty { display: none; } @media (hover: hover) { .sc-lmvz-radio-h:hover .circle.sc-lmvz-radio { border-color: var(--radio-border-color-hover); } .sc-lmvz-radio-h:hover { background-color: var(--radio-wrapper-bg-hover); } } .sc-lmvz-radio-h:active { background-color: var(--radio-wrapper-bg-active); } [checked].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: var(--radio-border-color-checked); } [checked].sc-lmvz-radio-h label.sc-lmvz-radio { color: var(--radio-label-color-checked); } [error].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: var(--radio-border-color-error); } [error].sc-lmvz-radio-h .helper-text.sc-lmvz-radio { color: var(--lmvz-semantic-color-status-on-danger, #e52a31); } [disabled].sc-lmvz-radio-h { opacity: var(--lmvz-component-input-disabled-opacity, 40%); pointer-events: none; cursor: not-allowed; } @media (forced-colors: active) { .circle.sc-lmvz-radio { forced-color-adjust: auto; border-color: ButtonText; background-color: Field; } [checked].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: Highlight; } .dot.sc-lmvz-radio { background-color: ButtonText; } [checked].sc-lmvz-radio-h .dot.sc-lmvz-radio { background-color: HighlightText; } }.sc-lmvz-radio-h:focus-within{outline:var(--lmvz-ds-outline);outline-offset:var(--lmvz-ds-outline-offset)}@media (forced-colors: active){.sc-lmvz-radio-h:focus-within{outline-color:Highlight;box-shadow:none}}";export{h as lmvz_radio}
1
+ import{g as r,r as e,c as o,h as t,H as i}from"./p-BPeerEwm.js";import{A as a}from"./p-CPOia2kT.js";import{R as s}from"./p-FBuCCcFC.js";import"./p-CdDO7mQa.js";function l(r){return r.el.shadowRoot?.querySelector("input")??r.el.querySelector("input")??null}class c{hosts=[];_focusedHost=null;_focusinHandler=r=>{this.hosts.some((e=>e.el.contains(r.target)))||this.clearFocused()};register(r){if(!this.hosts.includes(r)){const e=0===this.hosts.length;this.hosts.push(r),this.sortHosts(),e&&document.addEventListener("focusin",this._focusinHandler,!0)}}unregister(r){r===this._focusedHost&&(this._focusedHost=null),this.hosts=this.hosts.filter((e=>e!==r)),0===this.hosts.length&&document.removeEventListener("focusin",this._focusinHandler,!0)}get sortedEnabled(){return this.hosts.filter((r=>!r.disabled))}setFocused(r){this._focusedHost=r,this.updateTabindex(),r.focusInput()}clearFocused(){this._focusedHost=null,this.updateTabindex()}select(r){this._focusedHost=null;for(const e of this.hosts)e.checked=e===r;this.updateTabindex()}updateTabindex(){const r=this.sortedEnabled,e=this.hosts.find((r=>r.checked));let o;o=this._focusedHost&&r.includes(this._focusedHost)?this._focusedHost:e??r[0]??null;for(const r of this.hosts){const e=l(r);e&&(e.tabIndex=r===o?0:-1)}}sortHosts(){this.hosts.sort(((r,e)=>r.el.compareDocumentPosition(e.el)&Node.DOCUMENT_POSITION_FOLLOWING?-1:1))}}class n{host;static registry=new Map;group=null;_groupKey=null;_scope=null;constructor(r){this.host=r}hostConnected(){const{group:r,key:e,scope:o}=n.acquireGroup(this.host);this._groupKey=e,this._scope=o,this.group=r,this.group.register(this.host),this.group.updateTabindex()}hostDidRender(){this.group?.updateTabindex()}hostDisconnected(){this.group&&(this.group.unregister(this.host),this.group.updateTabindex(),n.releaseGroup(this._groupKey,this._scope),this._groupKey=null,this._scope=null,this.group=null)}get sortedEnabled(){return this.group?.sortedEnabled??[]}select(r){this.group?.select(r)}setFocused(r){this.group?.setFocused(r)}clearFocused(){this.group?.clearFocused()}updateTabindex(){this.group?.updateTabindex()}static acquireGroup(r){const e=r.name;if(!e)return{group:new c,key:null,scope:null};const o=r.el.closest("form")??document,t=function(r,e){return e instanceof HTMLFormElement?(e.dataset.lmvzRadioGroupId||(e.dataset.lmvzRadioGroupId=String(Math.random())),`${r}::form::${e.dataset.lmvzRadioGroupId}`):`${r}::document`}(e,o);let i=n.registry.get(t);return i||(i={group:new c,refCount:0},n.registry.set(t,i)),i.refCount++,{group:i.group,key:t,scope:o}}static releaseGroup(r,e){if(!r)return;const o=n.registry.get(r);o&&(o.refCount--,o.refCount<=0&&(n.registry.delete(r),e instanceof HTMLFormElement&&e.removeAttribute("data-lmvz-radio-group-id")))}}let d=0;const h=class extends s{get el(){return r(this)}get validationEl(){return this.el}internals;nativeInput;radioId="lmvz-radio-"+d++;initialChecked=!1;radioGroupController;get helperId(){return this.helperText?`${this.radioId}-helper`:void 0}label;checked=!1;value="on";name;disabled=!1;required=!1;error=!1;helperText;form;autofocus=!1;_handlingNativeChange=!1;_handlingFormReset=!1;handleCheckedChange(r,e){this.internals.setFormValue?.(r?this.value:null),r||!e||this._handlingNativeChange||this._handlingFormReset||this.lmvzChange.emit(!1),!r||e||this._handlingNativeChange||this._handlingFormReset||this.lmvzChange.emit(!0)}handleValueChange(r){this.checked&&this.internals.setFormValue?.(r)}handleLabelChange(r){r||console.warn("[lmvz-radio] label prop is required and must not be empty")}lmvzChange;lmvzActivation;async focusInput(){this.nativeInput?.focus()}async checkValidity(){return this.internals?.checkValidity()??!0}async reportValidity(){return this.internals?.reportValidity()??!0}constructor(r){super(),e(this,r),this.lmvzChange=o(this,"lmvzChange",7),this.lmvzActivation=o(this,"lmvzActivation",7),r.$hostElement$["s-ei"]?this.internals=r.$hostElement$["s-ei"]:(this.internals=r.$hostElement$.attachInternals(),r.$hostElement$["s-ei"]=this.internals),this.addController(new a(this,{reValidateOnPropChanges:!0})),this.radioGroupController=new n(this),this.addController(this.radioGroupController)}componentWillLoad(){this.initialChecked=this.checked,this.internals.setFormValue?.(this.checked?this.value:null),super.componentWillLoad()}formAssociatedCallback(){this.internals.setFormValue?.(this.checked?this.value:null)}formResetCallback(){this._handlingFormReset=!0;try{this.checked=this.initialChecked}finally{this._handlingFormReset=!1}}formStateRestoreCallback(r){if("string"==typeof r){this._handlingFormReset=!0;try{this.checked=r===this.value}finally{this._handlingFormReset=!1}}}handleChange=r=>{this._handlingNativeChange=!0;try{this.checked=r.target.checked,this.lmvzChange.emit(this.checked),this.radioGroupController.select(this),this.lmvzActivation.emit()}finally{this._handlingNativeChange=!1}};handleKeydown(r){const{key:e}=r;if(!["ArrowDown","ArrowRight","ArrowUp","ArrowLeft","Home","End"].includes(e))return;r.preventDefault();const o=this.radioGroupController.sortedEnabled;if(0===o.length)return;const t=o.indexOf(this);if(-1===t)return;let i;i="ArrowDown"===e||"ArrowRight"===e?(t+1)%o.length:"ArrowUp"===e||"ArrowLeft"===e?(t-1+o.length)%o.length:"Home"===e?0:o.length-1;const a=o[i];a&&this.radioGroupController.setFocused(a)}render(){return t(i,{key:"9b8fbfe18376f9411f792630065dfd219f9ddb32"},t("input",{key:"24a0675eff854bbd751c07905db4be11e5353d11",type:"radio",id:this.radioId,name:this.name??void 0,value:this.value,checked:this.checked,disabled:this.disabled,required:this.required,autoFocus:this.autofocus,"aria-invalid":this.error?"true":void 0,"aria-describedby":this.helperId,ref:r=>this.nativeInput=r,onChange:this.handleChange}),t("span",{key:"f888c1f76f6f929609584d378dbe0974fd980f68",class:"circle","aria-hidden":"true"},this.checked&&t("span",{key:"57fbb1e7abdca10861cf8709d4300459e1f62e5c",class:"dot"})),t("span",{key:"1c845611162be86500e8475ac37412e2d3f2fd99",class:"content"},t("label",{key:"1399f4d34ff0e6d369cefc9f5d08208a4dee593f",htmlFor:this.radioId},this.label),t("span",{key:"1345435ff2f4773260ea3f73e943f043c2b88bdb","aria-live":"polite",class:"helper-text",id:this.helperId},this.helperText)))}static get formAssociated(){return!0}static get watchers(){return{checked:[{handleCheckedChange:0}],value:[{handleValueChange:0}],label:[{handleLabelChange:0}]}}};h.style="@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; } } .sc-lmvz-radio-h { display: inline-block; --radio-circle-size: var(--lmvz-global-s18, 18px); --radio-dot-size: 0.5rem; --radio-bg: var(--lmvz-semantic-color-surface-input-primary, #ffffff); --radio-border-color: var(--lmvz-semantic-color-border-default, #e0e0e0); --radio-border-color-hover: var(--lmvz-semantic-color-border-hover, #c7c7c7); --radio-border-color-checked: var(--lmvz-semantic-color-border-active, #0f8acc); --radio-border-color-error: var(--lmvz-semantic-color-status-on-danger, #e52a31); --radio-dot-color: var(--lmvz-semantic-color-border-active, #0f8acc); --radio-wrapper-bg-hover: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0); --radio-wrapper-bg-active: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0); --radio-label-color: var(--lmvz-semantic-color-on-surface-primary, #000000); --radio-label-color-checked: var(--lmvz-semantic-color-status-on-active, #0e7ab4); --radio-helper-color: var(--lmvz-semantic-color-on-surface-secondary, #7a7a7a); --radio-easing: var(--lmvz-global-easing-default, ease); --radio-duration: 0.2s; display: flex; align-items: center; gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); padding-block: var(--lmvz-dimension-2-8, clamp(0.13rem, 0.03rem + 0.39vw, 0.5rem)); padding-inline: var(--lmvz-dimension-8-12, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); border-radius: var(--lmvz-semantic-border-radius-round, 999px); overflow: clip; cursor: pointer; background-color: transparent; position: relative; transition: background-color var(--radio-duration) var(--radio-easing); } input.sc-lmvz-radio { position: absolute; inset-block-start: var(--lmvz-dimension-2-8, clamp(0.13rem, 0.03rem + 0.39vw, 0.5rem)); inset-inline-start: var(--lmvz-dimension-4-10, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); opacity: 0; width: var(--radio-circle-size); height: var(--radio-circle-size); margin: 0; cursor: pointer; z-index: 1; } .circle.sc-lmvz-radio { width: var(--radio-circle-size); height: var(--radio-circle-size); border-radius: 50%; border: var(--lmvz-semantic-border-width-default, 1px) solid var(--radio-border-color); background-color: var(--radio-bg); pointer-events: none; flex-shrink: 0; display: flex; align-items: center; justify-content: center; box-sizing: border-box; transition: border-color var(--radio-duration) var(--radio-easing); } .dot.sc-lmvz-radio { width: var(--radio-dot-size); height: var(--radio-dot-size); border-radius: 50%; background-color: var(--radio-dot-color); } .content.sc-lmvz-radio { display: flex; flex-direction: column; overflow-wrap: break-word; min-width: 0; } label.sc-lmvz-radio { font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router); color: var(--radio-label-color); cursor: pointer; transition: color var(--radio-duration) var(--radio-easing); } .helper-text.sc-lmvz-radio { display: block; font: var(--lmvz-typography-body-sm, 400 clamp(0.69rem, 0.67rem + 0.06vw, 0.75rem) / 1.5 Router); color: var(--radio-helper-color); margin-block-start: 2px; } .helper-text.sc-lmvz-radio:empty { display: none; } @media (hover: hover) { .sc-lmvz-radio-h:hover .circle.sc-lmvz-radio { border-color: var(--radio-border-color-hover); } .sc-lmvz-radio-h:hover { background-color: var(--radio-wrapper-bg-hover); } } .sc-lmvz-radio-h:active { background-color: var(--radio-wrapper-bg-active); } [checked].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: var(--radio-border-color-checked); } [checked].sc-lmvz-radio-h label.sc-lmvz-radio { color: var(--radio-label-color-checked); } [error].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: var(--radio-border-color-error); } [error].sc-lmvz-radio-h .helper-text.sc-lmvz-radio { color: var(--lmvz-semantic-color-status-on-danger, #e52a31); } [disabled].sc-lmvz-radio-h { opacity: var(--lmvz-component-input-disabled-opacity, 40%); pointer-events: none; cursor: not-allowed; } @media (forced-colors: active) { .circle.sc-lmvz-radio { forced-color-adjust: auto; border-color: ButtonText; background-color: Field; } [checked].sc-lmvz-radio-h .circle.sc-lmvz-radio { border-color: Highlight; } .dot.sc-lmvz-radio { background-color: ButtonText; } [checked].sc-lmvz-radio-h .dot.sc-lmvz-radio { background-color: HighlightText; } }.sc-lmvz-radio-h:focus-within{outline:var(--lmvz-ds-outline, 1px solid #0e7ab4);outline-offset:var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem))}@media (forced-colors: active){.sc-lmvz-radio-h:focus-within{outline-color:Highlight;box-shadow:none}}";export{h as lmvz_radio}
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-06-15T12:09:01",
2
+ "timestamp": "2026-06-22T12:04:47",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.5",
@@ -93,6 +93,67 @@
93
93
  "dependencies": [],
94
94
  "dependencyGraph": {}
95
95
  },
96
+ {
97
+ "filePath": "src/components/lmvz-action-list/lmvz-action-list.tsx",
98
+ "encapsulation": "scoped",
99
+ "tag": "lmvz-action-list",
100
+ "readme": "# lmvz-action-list\n\nA menu of actions. Renders an internal `<ul role=\"menu\">` and projects consumer-supplied interactive elements as menuitems.\n\n## Usage\n\nSlot `<lmvz-button>` or native `<button>` elements **directly** — no `<li>` wrapper. Dividers are slotted `<hr>`. Groups are `<div role=\"group\" aria-label=\"…\">` containing interactive children.\n\n```html\n<lmvz-action-list label=\"File actions\">\n <lmvz-button>Open</lmvz-button>\n <lmvz-button>Save</lmvz-button>\n <hr />\n <lmvz-button class=\"lmvz-action-list-item--danger\">Delete</lmvz-button>\n</lmvz-action-list>\n```\n\n## API\n\n### Props\n\n| Prop | Type | Default | Description |\n|---|---|---|---|\n| `label` | `string \\| undefined` | `undefined` | Accessible name for the menu. Reflected as `aria-label` on the internal `<ul role=\"menu\">`. Optional — consumers may provide context via surrounding markup. |\n\n### Slots\n\n| Slot | Description |\n|---|---|\n| *(default)* | Accepts `<lmvz-button>` or native `<button>` (menuitems), `<hr>` (separators), and `<div role=\"group\" aria-label=\"…\">` (groups containing menuitems). **No `<li>` wrapper.** |\n\n### CSS Classes\n\n| Class | Applied to | Description |\n|---|---|---|\n| `lmvz-action-list-item--danger` | Slotted `<lmvz-button>` or `<button>` | Applies danger/destructive styling (status-danger tokens). Stable public contract. |\n\n### Events\n\nNone. Activation is handled by the consumer's `<lmvz-button>` or `<button>`.\n\n### Groups\n\nWrap related menuitems in a `<div role=\"group\" aria-label=\"Group name\">`. A dev-time warning is emitted when a group has no accessible name.\n\n```html\n<lmvz-action-list>\n <div role=\"group\" aria-label=\"Edit\">\n <lmvz-button>Cut</lmvz-button>\n <lmvz-button>Copy</lmvz-button>\n </div>\n <hr />\n <lmvz-button>Paste</lmvz-button>\n</lmvz-action-list>\n```\n\n### Keyboard navigation\n\nArrow keys (↑/↓) and Home/End move focus between menuitems using roving tabindex.\n\n**Known limitation:** Tab-exit, Escape-to-close, and typeahead navigation are not implemented in this standalone action list. These belong to a future popup/menu-button owner.\n\n### Deferred / Out of scope\n\n- Disabled item state\n- Leading or trailing icon slot per item\n",
101
+ "docs": "A keyboard-navigable action list component implementing the WAI-ARIA `menu` pattern.\n\nRenders a styled `<ul role=\"menu\">` that accepts `<lmvz-button>`, native `<button>`,\n`<hr>` dividers, and `<div role=\"group\">` groups via the default slot.\nArrow keys move focus across interactive items; Home/End jump to first/last.\n\n**Disabled items:** Items with the native `disabled` attribute (or `disabled` prop on\n`<lmvz-button>`) are silently skipped during arrow-key navigation. This matches the\nbehaviour of native `<select>` and keeps the interaction model simple.\nTrade-off: screen reader users navigating by arrow key cannot discover disabled items\nor read their labels. If surfacing disabled items to all users is required, use\n`aria-disabled=\"true\"` on the item instead and handle activation prevention in the\nclick/activation handler — the controller's `isFocusableElement` callback can then be\nused to override the skip logic.",
102
+ "docsTags": [
103
+ {
104
+ "name": "slot",
105
+ "text": "default - `<lmvz-button>`, native `<button>`, `<hr>` dividers, or\n`<div role=\"group\" aria-label=\"…\">` groups containing buttons."
106
+ },
107
+ {
108
+ "name": "example",
109
+ "text": "```html\n<lmvz-action-list label=\"Actions\">\n <lmvz-button>Edit</lmvz-button>\n <hr />\n <lmvz-button class=\"lmvz-action-list-item--danger\">Delete</lmvz-button>\n</lmvz-action-list>\n```"
110
+ }
111
+ ],
112
+ "usage": {},
113
+ "props": [
114
+ {
115
+ "name": "label",
116
+ "type": "string | undefined",
117
+ "complexType": {
118
+ "original": "string",
119
+ "resolved": "string | undefined",
120
+ "references": {}
121
+ },
122
+ "mutable": false,
123
+ "attr": "label",
124
+ "reflectToAttr": false,
125
+ "docs": "Accessible label for the menu, reflected as `aria-label` on the host Element.\nWhen absent, `aria-label` is not rendered on the host.",
126
+ "docsTags": [],
127
+ "values": [
128
+ {
129
+ "type": "string"
130
+ },
131
+ {
132
+ "type": "undefined"
133
+ }
134
+ ],
135
+ "optional": true,
136
+ "required": false,
137
+ "getter": false,
138
+ "setter": false
139
+ }
140
+ ],
141
+ "methods": [],
142
+ "events": [],
143
+ "listeners": [],
144
+ "styles": [],
145
+ "slots": [
146
+ {
147
+ "name": "default",
148
+ "docs": "`<lmvz-button>`, native `<button>`, `<hr>` dividers, or\n`<div role=\"group\" aria-label=\"…\">` groups containing buttons."
149
+ }
150
+ ],
151
+ "parts": [],
152
+ "states": [],
153
+ "dependents": [],
154
+ "dependencies": [],
155
+ "dependencyGraph": {}
156
+ },
96
157
  {
97
158
  "filePath": "src/components/lmvz-button/lmvz-button.tsx",
98
159
  "encapsulation": "shadow",
@@ -107,6 +168,32 @@
107
168
  ],
108
169
  "usage": {},
109
170
  "props": [
171
+ {
172
+ "name": "buttonRole",
173
+ "type": "string | undefined",
174
+ "complexType": {
175
+ "original": "string",
176
+ "resolved": "string | undefined",
177
+ "references": {}
178
+ },
179
+ "mutable": false,
180
+ "attr": "button-role",
181
+ "reflectToAttr": false,
182
+ "docs": "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.",
183
+ "docsTags": [],
184
+ "values": [
185
+ {
186
+ "type": "string"
187
+ },
188
+ {
189
+ "type": "undefined"
190
+ }
191
+ ],
192
+ "optional": true,
193
+ "required": false,
194
+ "getter": false,
195
+ "setter": false
196
+ },
110
197
  {
111
198
  "name": "disabled",
112
199
  "type": "boolean",
@@ -291,10 +378,6 @@
291
378
  "reflectToAttr": true,
292
379
  "docs": "",
293
380
  "docsTags": [
294
- {
295
- "name": "readonly",
296
- "text": ""
297
- },
298
381
  {
299
382
  "name": "default",
300
383
  "text": "0"
@@ -308,7 +391,7 @@
308
391
  ],
309
392
  "optional": false,
310
393
  "required": false,
311
- "getter": true,
394
+ "getter": false,
312
395
  "setter": false
313
396
  },
314
397
  {
@@ -473,8 +556,8 @@
473
556
  "filePath": "src/components/lmvz-button-group/lmvz-button-group.tsx",
474
557
  "encapsulation": "shadow",
475
558
  "tag": "lmvz-button-group",
476
- "readme": "# lmvz-button-group\n\nInternal component used by `lmvz-modal` to manage its actions slot. Auto-assigns `variant` attributes to slotted buttons by order (last → primary, second-to-last → secondary, earlier → tertiary) when no explicit variant is set. Exposes `primaryEnabledAction` (first non-disabled button with variant primary, falls back to first enabled) and `hasActions` (true if any visible, non-disabled button is present).\n",
477
- "docs": "Internal component used by `lmvz-modal` to manage its actions slot. Auto-assigns `variant` attributes to slotted buttons by order (last → primary, second-to-last → secondary, earlier → tertiary) when no explicit variant is set. Exposes `primaryEnabledAction` (first non-disabled button with variant primary, falls back to first enabled) and `hasActions` (true if any visible, non-disabled button is present).",
559
+ "readme": "# lmvz-button-group\n\nInternal component used by `lmvz-modal` to manage its actions slot. Auto-assigns `variant` attributes to slotted buttons by order (first → primary, second → secondary, later → tertiary) when no explicit variant is set. Exposes `primaryEnabledAction` (first non-disabled button with variant primary, falls back to first enabled) and `hasActions` (true if any visible, non-disabled button is present).\n\n## Props\n\n### `stacked`\n\nType: `boolean` | Default: `false`\n\nRenders buttons in a vertical stack (full-width column) instead of horizontal row. When `stacked` is true, buttons stretch to full width and are arranged vertically with the primary button on top.\n\n## Authoring Conventions\n\n**Primary button placement:** The primary button must always be the first child in the DOM, regardless of horizontal or stacked layout. This ensures consistent focus order and authoring predictability. In the default horizontal layout, the primary action renders visually on the right because the component uses `row-reverse` flex direction internally.\n\n**Stacked layout limits:** Design guidelines recommend a maximum of 2 buttons in stacked groups. Stacked groups with more than 2 buttons may exceed typical mobile viewport heights.\n\n**Icon restrictions in stacked mode:** Do not use buttons with leading icons in stacked button groups. Leading icons are sized for horizontal layouts and create misaligned spacing in vertical stacks. Use plain labels or trailing icons if necessary.\n",
560
+ "docs": "Internal component used by `lmvz-modal` to manage its actions slot. Auto-assigns `variant` attributes to slotted buttons by order (first → primary, second → secondary, later → tertiary) when no explicit variant is set. Exposes `primaryEnabledAction` (first non-disabled button with variant primary, falls back to first enabled) and `hasActions` (true if any visible, non-disabled button is present).",
478
561
  "docsTags": [],
479
562
  "usage": {},
480
563
  "props": [
@@ -540,6 +623,35 @@
540
623
  "required": false,
541
624
  "getter": true,
542
625
  "setter": false
626
+ },
627
+ {
628
+ "name": "stacked",
629
+ "type": "boolean",
630
+ "complexType": {
631
+ "original": "boolean",
632
+ "resolved": "boolean",
633
+ "references": {}
634
+ },
635
+ "mutable": false,
636
+ "attr": "stacked",
637
+ "reflectToAttr": true,
638
+ "docs": "",
639
+ "docsTags": [
640
+ {
641
+ "name": "default",
642
+ "text": "false"
643
+ }
644
+ ],
645
+ "default": "false",
646
+ "values": [
647
+ {
648
+ "type": "boolean"
649
+ }
650
+ ],
651
+ "optional": false,
652
+ "required": false,
653
+ "getter": false,
654
+ "setter": false
543
655
  }
544
656
  ],
545
657
  "methods": [],
@@ -1144,8 +1256,8 @@
1144
1256
  "references": {
1145
1257
  "Chip": {
1146
1258
  "location": "import",
1147
- "path": "../../api/ds.constants.js",
1148
- "id": "src/api/ds.constants.ts::Chip",
1259
+ "path": "../../api/ds.types.js",
1260
+ "id": "src/api/ds.types.d.ts::Chip",
1149
1261
  "referenceLocation": "Chip"
1150
1262
  }
1151
1263
  }
@@ -1185,8 +1297,8 @@
1185
1297
  "references": {
1186
1298
  "Chip": {
1187
1299
  "location": "import",
1188
- "path": "../../api/ds.constants.js",
1189
- "id": "src/api/ds.constants.ts::Chip",
1300
+ "path": "../../api/ds.types.js",
1301
+ "id": "src/api/ds.types.d.ts::Chip",
1190
1302
  "referenceLocation": "Chip"
1191
1303
  }
1192
1304
  }
@@ -1586,12 +1698,16 @@
1586
1698
  "parts": [],
1587
1699
  "states": [],
1588
1700
  "dependents": [
1701
+ "lmvz-link",
1589
1702
  "lmvz-message",
1590
1703
  "lmvz-modal",
1591
1704
  "lmvz-snackbar"
1592
1705
  ],
1593
1706
  "dependencies": [],
1594
1707
  "dependencyGraph": {
1708
+ "lmvz-link": [
1709
+ "lmvz-icon"
1710
+ ],
1595
1711
  "lmvz-message": [
1596
1712
  "lmvz-icon"
1597
1713
  ],
@@ -5683,6 +5799,207 @@
5683
5799
  "dependencies": [],
5684
5800
  "dependencyGraph": {}
5685
5801
  },
5802
+ {
5803
+ "filePath": "src/components/lmvz-link/lmvz-link.tsx",
5804
+ "encapsulation": "shadow",
5805
+ "tag": "lmvz-link",
5806
+ "readme": "# lmvz-link\n\nThe link renders a semantically correct native anchor element with a trailing icon indicating the navigation type.\n\n## Visual Types\n\nThe component supports two visual types controlled by the `type` prop:\n\n- **`internal`** — renders an arrow-right icon, indicating navigation within the same site or application\n- **`external`** — renders an external icon, indicating navigation to an external destination\n\n## Label and Accessibility\n\nThe default slot accepts inline label text for the link. When the link opens in a new tab (`target=\"_blank\"`), a visually-hidden external label is automatically appended to improve accessible announcements. The text of this label is controlled by the `externalLabel` prop (default: `\"(öffnet in neuem Tab)\"`) and can be customized for localization.\n",
5807
+ "docs": "The link renders a native anchor element with an icon indicating navigation type.",
5808
+ "docsTags": [
5809
+ {
5810
+ "name": "slot",
5811
+ "text": "default - Inline label text for the link."
5812
+ }
5813
+ ],
5814
+ "usage": {},
5815
+ "props": [
5816
+ {
5817
+ "name": "externalLabel",
5818
+ "type": "string",
5819
+ "complexType": {
5820
+ "original": "string",
5821
+ "resolved": "string",
5822
+ "references": {}
5823
+ },
5824
+ "mutable": false,
5825
+ "attr": "external-label",
5826
+ "reflectToAttr": false,
5827
+ "docs": "Visually-hidden text appended inside the anchor when `target=\"_blank\"`.\nProvides an accessible cue for screen reader users.",
5828
+ "docsTags": [
5829
+ {
5830
+ "name": "default",
5831
+ "text": "'(öffnet in neuem Tab)'"
5832
+ }
5833
+ ],
5834
+ "default": "'(öffnet in neuem Tab)'",
5835
+ "values": [
5836
+ {
5837
+ "type": "string"
5838
+ }
5839
+ ],
5840
+ "optional": false,
5841
+ "required": false,
5842
+ "getter": false,
5843
+ "setter": false
5844
+ },
5845
+ {
5846
+ "name": "href",
5847
+ "type": "string",
5848
+ "complexType": {
5849
+ "original": "string",
5850
+ "resolved": "string",
5851
+ "references": {}
5852
+ },
5853
+ "mutable": false,
5854
+ "attr": "href",
5855
+ "reflectToAttr": true,
5856
+ "docs": "The URL the link points to. Mirrors the native anchor `href` attribute.",
5857
+ "docsTags": [
5858
+ {
5859
+ "name": "default",
5860
+ "text": "''"
5861
+ }
5862
+ ],
5863
+ "default": "''",
5864
+ "values": [
5865
+ {
5866
+ "type": "string"
5867
+ }
5868
+ ],
5869
+ "optional": false,
5870
+ "required": false,
5871
+ "getter": false,
5872
+ "setter": false
5873
+ },
5874
+ {
5875
+ "name": "rel",
5876
+ "type": "string | undefined",
5877
+ "complexType": {
5878
+ "original": "string",
5879
+ "resolved": "string | undefined",
5880
+ "references": {}
5881
+ },
5882
+ "mutable": false,
5883
+ "attr": "rel",
5884
+ "reflectToAttr": false,
5885
+ "docs": "Relationship of the linked URL. When `target=\"_blank\"`, `noopener` and\n`noreferrer` are automatically added if not already present.",
5886
+ "docsTags": [],
5887
+ "values": [
5888
+ {
5889
+ "type": "string"
5890
+ },
5891
+ {
5892
+ "type": "undefined"
5893
+ }
5894
+ ],
5895
+ "optional": true,
5896
+ "required": false,
5897
+ "getter": false,
5898
+ "setter": false
5899
+ },
5900
+ {
5901
+ "name": "target",
5902
+ "type": "\"_blank\" | \"_parent\" | \"_self\" | \"_top\" | undefined",
5903
+ "complexType": {
5904
+ "original": "'_self' | '_blank' | '_parent' | '_top'",
5905
+ "resolved": "\"_blank\" | \"_parent\" | \"_self\" | \"_top\" | undefined",
5906
+ "references": {}
5907
+ },
5908
+ "mutable": false,
5909
+ "attr": "target",
5910
+ "reflectToAttr": true,
5911
+ "docs": "Where to open the linked document.",
5912
+ "docsTags": [],
5913
+ "values": [
5914
+ {
5915
+ "value": "_blank",
5916
+ "type": "string"
5917
+ },
5918
+ {
5919
+ "value": "_parent",
5920
+ "type": "string"
5921
+ },
5922
+ {
5923
+ "value": "_self",
5924
+ "type": "string"
5925
+ },
5926
+ {
5927
+ "value": "_top",
5928
+ "type": "string"
5929
+ },
5930
+ {
5931
+ "type": "undefined"
5932
+ }
5933
+ ],
5934
+ "optional": true,
5935
+ "required": false,
5936
+ "getter": false,
5937
+ "setter": false
5938
+ },
5939
+ {
5940
+ "name": "type",
5941
+ "type": "\"external\" | \"internal\"",
5942
+ "complexType": {
5943
+ "original": "Link.Type",
5944
+ "resolved": "\"external\" | \"internal\"",
5945
+ "references": {
5946
+ "Link": {
5947
+ "location": "import",
5948
+ "path": "../../api/ds.types.js",
5949
+ "id": "src/api/ds.types.d.ts::Link",
5950
+ "referenceLocation": "Link"
5951
+ }
5952
+ }
5953
+ },
5954
+ "mutable": true,
5955
+ "attr": "type",
5956
+ "reflectToAttr": true,
5957
+ "docs": "Navigation type. Drives the icon shown after the label text.\n- `internal` → arrow-right icon\n- `external` → external icon\nInvalid values are normalized to `internal`.",
5958
+ "docsTags": [
5959
+ {
5960
+ "name": "default",
5961
+ "text": "'internal'"
5962
+ }
5963
+ ],
5964
+ "default": "'internal'",
5965
+ "values": [
5966
+ {
5967
+ "value": "external",
5968
+ "type": "string"
5969
+ },
5970
+ {
5971
+ "value": "internal",
5972
+ "type": "string"
5973
+ }
5974
+ ],
5975
+ "optional": false,
5976
+ "required": false,
5977
+ "getter": false,
5978
+ "setter": false
5979
+ }
5980
+ ],
5981
+ "methods": [],
5982
+ "events": [],
5983
+ "listeners": [],
5984
+ "styles": [],
5985
+ "slots": [
5986
+ {
5987
+ "name": "default",
5988
+ "docs": "Inline label text for the link."
5989
+ }
5990
+ ],
5991
+ "parts": [],
5992
+ "states": [],
5993
+ "dependents": [],
5994
+ "dependencies": [
5995
+ "lmvz-icon"
5996
+ ],
5997
+ "dependencyGraph": {
5998
+ "lmvz-link": [
5999
+ "lmvz-icon"
6000
+ ]
6001
+ }
6002
+ },
5686
6003
  {
5687
6004
  "filePath": "src/components/lmvz-menuitem/lmvz-menuitem.tsx",
5688
6005
  "encapsulation": "scoped",
@@ -7988,10 +8305,10 @@
7988
8305
  "docstring": "",
7989
8306
  "path": "src/api/index.d.ts"
7990
8307
  },
7991
- "src/api/ds.constants.ts::Chip": {
8308
+ "src/api/ds.types.d.ts::Chip": {
7992
8309
  "declaration": "any",
7993
8310
  "docstring": "",
7994
- "path": "src/api/ds.constants.ts"
8311
+ "path": "src/api/ds.types.d.ts"
7995
8312
  },
7996
8313
  "../../lib/ts/dist/validation/SVGString.d.ts::SVGString": {
7997
8314
  "declaration": "export type SVGString = string & Brand.Brand<'SVG'>;",
@@ -8008,6 +8325,11 @@
8008
8325
  "docstring": "",
8009
8326
  "path": "src/api/index.d.ts"
8010
8327
  },
8328
+ "src/api/ds.types.d.ts::Link": {
8329
+ "declaration": "any",
8330
+ "docstring": "",
8331
+ "path": "src/api/ds.types.d.ts"
8332
+ },
8011
8333
  "src/api/index.d.ts::Message": {
8012
8334
  "declaration": "any",
8013
8335
  "docstring": "",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmvz-ds/components",
3
3
  "private": false,
4
- "version": "0.29.0",
4
+ "version": "0.31.0",
5
5
  "type": "module",
6
6
  "description": "The components of the design system",
7
7
  "author": "Patrick Nemenz <patrick.nemenz@adesso.at>",
@@ -56,6 +56,10 @@
56
56
  "types": "./components/lmvz-icon.d.ts",
57
57
  "import": "./components/lmvz-icon.js"
58
58
  },
59
+ "./lmvz-link": {
60
+ "types": "./components/lmvz-link.d.ts",
61
+ "import": "./components/lmvz-link.js"
62
+ },
59
63
  "./lmvz-input": {
60
64
  "types": "./components/lmvz-input.d.ts",
61
65
  "import": "./components/lmvz-input.js"
@@ -107,6 +111,10 @@
107
111
  "./lmvz-spinner": {
108
112
  "import": "./components/lmvz-spinner.js",
109
113
  "types": "./components/lmvz-spinner.d.ts"
114
+ },
115
+ "./lmvz-action-list": {
116
+ "import": "./components/lmvz-action-list.js",
117
+ "types": "./components/lmvz-action-list.d.ts"
110
118
  }
111
119
  },
112
120
  "main": "./index.cjs.js",
@@ -9,44 +9,8 @@ export declare const iconSizes: readonly ["xs", "sm", "md", "lg", "inherit"];
9
9
  export declare const iconWeights: readonly ["thin", "medium", "bold"];
10
10
  export declare const chipTypes: readonly ["active", "warning", "success", "error", "neutral"];
11
11
  export declare const chipSizes: readonly ["default", "small"];
12
- export declare namespace LmvzDS {
13
- type Variant = (typeof variants)[number];
14
- type Size = (typeof sizes)[number];
15
- }
16
- export declare namespace Typography {
17
- type Size = (typeof textSizes)[number];
18
- }
19
- export declare namespace Button {
20
- type Scale = (typeof scaleValues)[number];
21
- type Variant = LmvzDS.Variant;
22
- }
23
- export declare namespace Chip {
24
- type Type = (typeof chipTypes)[number];
25
- type Size = (typeof chipSizes)[number];
26
- }
27
- export declare namespace Icon {
28
- type Size = (typeof iconSizes)[number];
29
- type IconWeight = (typeof iconWeights)[number];
30
- }
31
- export declare namespace Input {
32
- type Type = (typeof inputTypes)[number];
33
- type Size = (typeof inputSizes)[number];
34
- type Autocomplete = HTMLInputElement['autocomplete'];
35
- type Inputmode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
36
- type Autocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
37
- }
38
- export declare namespace Select {
39
- type Size = (typeof selectSizes)[number];
40
- }
12
+ export declare const linkTypes: readonly ["internal", "external"];
41
13
  export declare const messageTypes: readonly ["neutral", "warning"];
42
- export declare namespace Message {
43
- type Type = (typeof messageTypes)[number];
44
- }
45
14
  export declare const snackbarStatuses: readonly ["success", "warning", "error"];
46
15
  export declare const snackbarPriorities: readonly ["low", "normal", "high"];
47
16
  export declare const snackbarDismissReasons: readonly ["timeout", "manual", "action", "overridden", "swallowed"];
48
- export declare namespace Snackbar {
49
- type Status = (typeof snackbarStatuses)[number];
50
- type Priority = (typeof snackbarPriorities)[number];
51
- type DismissReason = (typeof snackbarDismissReasons)[number];
52
- }
@@ -1,4 +1,71 @@
1
- export type * from './ds.constants';
1
+ import type {
2
+ chipSizes,
3
+ chipTypes,
4
+ iconSizes,
5
+ iconWeights,
6
+ inputSizes,
7
+ inputTypes,
8
+ linkTypes,
9
+ messageTypes,
10
+ scaleValues,
11
+ selectSizes,
12
+ sizes,
13
+ snackbarDismissReasons,
14
+ snackbarPriorities,
15
+ snackbarStatuses,
16
+ textSizes,
17
+ variants,
18
+ } from './ds.constants';
19
+
20
+ export namespace LmvzDS {
21
+ export type Variant = (typeof variants)[number];
22
+ export type Size = (typeof sizes)[number];
23
+ }
24
+ export namespace Typography {
25
+ export type Size = (typeof textSizes)[number];
26
+ }
27
+ export namespace Button {
28
+ export type Scale = (typeof scaleValues)[number];
29
+ export type Variant = LmvzDS.Variant;
30
+ }
31
+ export namespace Chip {
32
+ export type Type = (typeof chipTypes)[number];
33
+ export type Size = (typeof chipSizes)[number];
34
+ }
35
+ export namespace Link {
36
+ export type Type = (typeof linkTypes)[number];
37
+ }
38
+ export namespace Icon {
39
+ export type Size = (typeof iconSizes)[number];
40
+ export type IconWeight = (typeof iconWeights)[number];
41
+ }
42
+ export namespace Input {
43
+ export type Type = (typeof inputTypes)[number];
44
+ export type Size = (typeof inputSizes)[number];
45
+
46
+ export type Autocomplete = HTMLInputElement['autocomplete'];
47
+ /**
48
+ * Inputmode attribute for mobile keyboards
49
+ */
50
+ export type Inputmode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
51
+ /**
52
+ * Autocapitalize attribute for mobile keyboards
53
+ */
54
+ export type Autocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
55
+ }
56
+ export namespace Select {
57
+ export type Size = (typeof selectSizes)[number];
58
+ }
59
+
60
+ export namespace Message {
61
+ export type Type = (typeof messageTypes)[number];
62
+ }
63
+
64
+ export namespace Snackbar {
65
+ export type Status = (typeof snackbarStatuses)[number];
66
+ export type Priority = (typeof snackbarPriorities)[number];
67
+ export type DismissReason = (typeof snackbarDismissReasons)[number];
68
+ }
2
69
 
3
70
  export type Attributes = { [key: string]: unknown };
4
71
  export type FormRef = string | HTMLFormElement | undefined;