@mhmo91/schmancy 0.10.19 → 0.10.20

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 (326) hide show
  1. package/custom-elements.json +0 -13
  2. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js → overlay.confirm-body-mYm0zq4k.js} +1 -1
  3. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js.map → overlay.confirm-body-mYm0zq4k.js.map} +1 -1
  4. package/dist/agent/schmancy.agent.js +808 -882
  5. package/dist/agent/schmancy.agent.js.map +1 -1
  6. package/dist/agent/schmancy.manifest.json +1 -9
  7. package/dist/area-C7MNn-3e.cjs +12 -0
  8. package/dist/area-C7MNn-3e.cjs.map +1 -0
  9. package/dist/{area-BIipuSyO.js → area-CRe41aIG.js} +91 -130
  10. package/dist/area-CRe41aIG.js.map +1 -0
  11. package/dist/area.cjs +1 -1
  12. package/dist/area.js +1 -1
  13. package/dist/{autocomplete-Mrb3koUN.js → autocomplete-CRDFL4Ul.js} +2 -2
  14. package/dist/{autocomplete-Mrb3koUN.js.map → autocomplete-CRDFL4Ul.js.map} +1 -1
  15. package/dist/{autocomplete-B8CE5vGw.cjs → autocomplete-CqUl7o0e.cjs} +1 -1
  16. package/dist/{autocomplete-B8CE5vGw.cjs.map → autocomplete-CqUl7o0e.cjs.map} +1 -1
  17. package/dist/autocomplete.cjs +1 -1
  18. package/dist/autocomplete.js +1 -1
  19. package/dist/avatar.cjs +1 -1
  20. package/dist/avatar.js +1 -1
  21. package/dist/badge.cjs +1 -1
  22. package/dist/badge.js +1 -1
  23. package/dist/{boat-OatK_MGh.cjs → boat-BHV5kOlN.cjs} +1 -1
  24. package/dist/{boat-OatK_MGh.cjs.map → boat-BHV5kOlN.cjs.map} +1 -1
  25. package/dist/{boat-CNWIQPA1.js → boat-XajM8A3M.js} +1 -1
  26. package/dist/{boat-CNWIQPA1.js.map → boat-XajM8A3M.js.map} +1 -1
  27. package/dist/boat.cjs +1 -1
  28. package/dist/boat.js +1 -1
  29. package/dist/breadcrumb.cjs +1 -1
  30. package/dist/breadcrumb.js +1 -1
  31. package/dist/{busy-CMKX4oQf.cjs → busy-BlBZ5ZOs.cjs} +1 -1
  32. package/dist/{busy-CMKX4oQf.cjs.map → busy-BlBZ5ZOs.cjs.map} +1 -1
  33. package/dist/{busy-Cetzws-m.js → busy-D8YsqVBf.js} +1 -1
  34. package/dist/{busy-Cetzws-m.js.map → busy-D8YsqVBf.js.map} +1 -1
  35. package/dist/busy.cjs +1 -1
  36. package/dist/busy.js +1 -1
  37. package/dist/button.cjs +15 -9
  38. package/dist/button.cjs.map +1 -1
  39. package/dist/button.js +15 -9
  40. package/dist/button.js.map +1 -1
  41. package/dist/{card-D2k3dRL0.js → card-C9TljY2Z.js} +1 -1
  42. package/dist/{card-D2k3dRL0.js.map → card-C9TljY2Z.js.map} +1 -1
  43. package/dist/{card-8VXoo2C_.cjs → card-yT_St83D.cjs} +1 -1
  44. package/dist/{card-8VXoo2C_.cjs.map → card-yT_St83D.cjs.map} +1 -1
  45. package/dist/card.cjs +1 -1
  46. package/dist/card.js +1 -1
  47. package/dist/{checkbox-8hNsBejz.js → checkbox-BDgh4rge.js} +1 -1
  48. package/dist/{checkbox-8hNsBejz.js.map → checkbox-BDgh4rge.js.map} +1 -1
  49. package/dist/{checkbox-Cq5wzeaY.cjs → checkbox-Dz2lkJs0.cjs} +1 -1
  50. package/dist/{checkbox-Cq5wzeaY.cjs.map → checkbox-Dz2lkJs0.cjs.map} +1 -1
  51. package/dist/checkbox.cjs +1 -1
  52. package/dist/checkbox.js +1 -1
  53. package/dist/{chips-Dx_WvOGk.cjs → chips-M7Dr2npv.cjs} +2 -4
  54. package/dist/chips-M7Dr2npv.cjs.map +1 -0
  55. package/dist/{chips-D1kJrbzo.js → chips-N7fu0hA4.js} +3 -5
  56. package/dist/chips-N7fu0hA4.js.map +1 -0
  57. package/dist/chips.cjs +1 -1
  58. package/dist/chips.js +2 -2
  59. package/dist/connectivity.cjs +1 -1
  60. package/dist/connectivity.js +1 -1
  61. package/dist/content-drawer.cjs +1 -1
  62. package/dist/content-drawer.js +1 -1
  63. package/dist/{date-range-H903Vt_r.cjs → date-range-D2vxD814.cjs} +1 -1
  64. package/dist/{date-range-H903Vt_r.cjs.map → date-range-D2vxD814.cjs.map} +1 -1
  65. package/dist/{date-range-Dv-DM6mB.js → date-range-DFWOMgI3.js} +2 -2
  66. package/dist/{date-range-Dv-DM6mB.js.map → date-range-DFWOMgI3.js.map} +1 -1
  67. package/dist/{date-range-inline-Bvs2ZvEY.cjs → date-range-inline-C5JuZ_Kw.cjs} +1 -1
  68. package/dist/{date-range-inline-Bvs2ZvEY.cjs.map → date-range-inline-C5JuZ_Kw.cjs.map} +1 -1
  69. package/dist/{date-range-inline-TWWnTZlw.js → date-range-inline-D3q1OoKk.js} +1 -1
  70. package/dist/{date-range-inline-TWWnTZlw.js.map → date-range-inline-D3q1OoKk.js.map} +1 -1
  71. package/dist/date-range-inline.cjs +1 -1
  72. package/dist/date-range-inline.js +1 -1
  73. package/dist/date-range.cjs +1 -1
  74. package/dist/date-range.js +1 -1
  75. package/dist/delay.cjs +1 -1
  76. package/dist/delay.js +1 -1
  77. package/dist/{details-Cpg8sH2F.js → details-BrUPmd92.js} +2 -2
  78. package/dist/details-BrUPmd92.js.map +1 -0
  79. package/dist/{details-CwSDur6j.cjs → details-DmDEInaL.cjs} +2 -2
  80. package/dist/details-DmDEInaL.cjs.map +1 -0
  81. package/dist/details.cjs +1 -1
  82. package/dist/details.js +1 -1
  83. package/dist/{divider-Be833gGZ.js → divider-BLijs8ba.js} +1 -1
  84. package/dist/{divider-Be833gGZ.js.map → divider-BLijs8ba.js.map} +1 -1
  85. package/dist/{divider-BNdVLE0H.cjs → divider-B_Ts_-qz.cjs} +1 -1
  86. package/dist/{divider-BNdVLE0H.cjs.map → divider-B_Ts_-qz.cjs.map} +1 -1
  87. package/dist/divider.cjs +1 -1
  88. package/dist/divider.js +1 -1
  89. package/dist/dropdown.cjs +1 -1
  90. package/dist/dropdown.js +1 -1
  91. package/dist/{expand-CtoffNNj.js → expand-C-xSpg7M.js} +2 -2
  92. package/dist/{expand-CtoffNNj.js.map → expand-C-xSpg7M.js.map} +1 -1
  93. package/dist/{expand-BP6RLzHw.cjs → expand-DV5sWUB6.cjs} +1 -1
  94. package/dist/{expand-BP6RLzHw.cjs.map → expand-DV5sWUB6.cjs.map} +1 -1
  95. package/dist/expand.cjs +1 -1
  96. package/dist/expand.js +1 -1
  97. package/dist/{float-CfbQM_2v.cjs → float-LyKef0LY.cjs} +1 -1
  98. package/dist/{float-CfbQM_2v.cjs.map → float-LyKef0LY.cjs.map} +1 -1
  99. package/dist/{float-KmbhaQHA.js → float-Y22yVBE2.js} +1 -1
  100. package/dist/{float-KmbhaQHA.js.map → float-Y22yVBE2.js.map} +1 -1
  101. package/dist/float.cjs +1 -1
  102. package/dist/float.js +1 -1
  103. package/dist/{form-CuBIrKOA.cjs → form-C_smXI2-.cjs} +1 -1
  104. package/dist/{form-CuBIrKOA.cjs.map → form-C_smXI2-.cjs.map} +1 -1
  105. package/dist/{form-8IcmP8uV.js → form-LFkEQkOX.js} +8 -8
  106. package/dist/{form-8IcmP8uV.js.map → form-LFkEQkOX.js.map} +1 -1
  107. package/dist/form.cjs +1 -1
  108. package/dist/form.js +6 -6
  109. package/dist/handover/agent-runtime-followups.md +1 -1
  110. package/dist/handover/agent-runtime-v1.md +3 -3
  111. package/dist/{icons-D7df1ysG.js → icons-B3pFrwKC.js} +1 -1
  112. package/dist/{icons-D7df1ysG.js.map → icons-B3pFrwKC.js.map} +1 -1
  113. package/dist/{icons-BJld4JHp.cjs → icons-CCNy4Egc.cjs} +1 -1
  114. package/dist/{icons-BJld4JHp.cjs.map → icons-CCNy4Egc.cjs.map} +1 -1
  115. package/dist/icons.cjs +1 -1
  116. package/dist/icons.js +1 -1
  117. package/dist/{iframe-DAbgW9tT.js → iframe-BbFlCEyP.js} +1 -1
  118. package/dist/{iframe-DAbgW9tT.js.map → iframe-BbFlCEyP.js.map} +1 -1
  119. package/dist/{iframe-GT6D8l5Z.cjs → iframe-CCcmLZ_K.cjs} +1 -1
  120. package/dist/{iframe-GT6D8l5Z.cjs.map → iframe-CCcmLZ_K.cjs.map} +1 -1
  121. package/dist/iframe.cjs +1 -1
  122. package/dist/iframe.js +1 -1
  123. package/dist/index.cjs +1 -1
  124. package/dist/index.js +27 -27
  125. package/dist/{input-DC6ap_uN.js → input-Dkneo4uA.js} +2 -2
  126. package/dist/{input-DC6ap_uN.js.map → input-Dkneo4uA.js.map} +1 -1
  127. package/dist/{input-chip-c5n547tg.js → input-chip-C1-TYu4v.js} +1 -1
  128. package/dist/{input-chip-c5n547tg.js.map → input-chip-C1-TYu4v.js.map} +1 -1
  129. package/dist/{input-chip-MsiMu-b5.cjs → input-chip-F5NEkkBU.cjs} +1 -1
  130. package/dist/{input-chip-MsiMu-b5.cjs.map → input-chip-F5NEkkBU.cjs.map} +1 -1
  131. package/dist/{input-BE9wEEw4.cjs → input-sBZ89wz1.cjs} +1 -1
  132. package/dist/{input-BE9wEEw4.cjs.map → input-sBZ89wz1.cjs.map} +1 -1
  133. package/dist/input.cjs +1 -1
  134. package/dist/input.js +1 -1
  135. package/dist/json.cjs +1 -1
  136. package/dist/json.js +2 -2
  137. package/dist/kbd.cjs +1 -1
  138. package/dist/kbd.js +1 -1
  139. package/dist/layout.cjs +1 -1
  140. package/dist/layout.js +1 -1
  141. package/dist/{lightbox-HqJBBjAT.cjs → lightbox-B4m5lxGs.cjs} +1 -1
  142. package/dist/{lightbox-HqJBBjAT.cjs.map → lightbox-B4m5lxGs.cjs.map} +1 -1
  143. package/dist/{lightbox-CNX9Eg3U.js → lightbox-D7hYFspE.js} +1 -1
  144. package/dist/{lightbox-CNX9Eg3U.js.map → lightbox-D7hYFspE.js.map} +1 -1
  145. package/dist/lightbox.cjs +1 -1
  146. package/dist/lightbox.js +1 -1
  147. package/dist/{list-bhyuQSyO.cjs → list-C2ycz-yr.cjs} +1 -1
  148. package/dist/{list-bhyuQSyO.cjs.map → list-C2ycz-yr.cjs.map} +1 -1
  149. package/dist/{list-C76Pb-c1.js → list-Ou72tSeq.js} +1 -1
  150. package/dist/{list-C76Pb-c1.js.map → list-Ou72tSeq.js.map} +1 -1
  151. package/dist/list.cjs +1 -1
  152. package/dist/list.js +1 -1
  153. package/dist/{menu-BqKQ-s0C.cjs → menu-ComSx-T0.cjs} +1 -1
  154. package/dist/{menu-BqKQ-s0C.cjs.map → menu-ComSx-T0.cjs.map} +1 -1
  155. package/dist/{menu-C5ksITpG.js → menu-YHbpRa7x.js} +2 -2
  156. package/dist/{menu-C5ksITpG.js.map → menu-YHbpRa7x.js.map} +1 -1
  157. package/dist/menu.cjs +1 -1
  158. package/dist/menu.js +1 -1
  159. package/dist/mixins-B9kY_60p.js +636 -0
  160. package/dist/{mixins-DCVXqL1Q.js.map → mixins-B9kY_60p.js.map} +1 -1
  161. package/dist/mixins-BwGJwK7X.cjs +254 -0
  162. package/dist/{mixins-Du9HMrIG.cjs.map → mixins-BwGJwK7X.cjs.map} +1 -1
  163. package/dist/mixins.cjs +1 -1
  164. package/dist/mixins.js +1 -1
  165. package/dist/nav-drawer.cjs +1 -1
  166. package/dist/nav-drawer.js +1 -1
  167. package/dist/navigation-bar.cjs +1 -1
  168. package/dist/navigation-bar.js +1 -1
  169. package/dist/navigation-rail.cjs +1 -1
  170. package/dist/navigation-rail.js +1 -1
  171. package/dist/{notification-DR3gvWt8.cjs → notification-DZhL0ZEg.cjs} +1 -1
  172. package/dist/{notification-DR3gvWt8.cjs.map → notification-DZhL0ZEg.cjs.map} +1 -1
  173. package/dist/{notification-eZxtr3NN.js → notification-O4Q5pyio.js} +2 -2
  174. package/dist/{notification-eZxtr3NN.js.map → notification-O4Q5pyio.js.map} +1 -1
  175. package/dist/notification.cjs +1 -1
  176. package/dist/notification.js +1 -1
  177. package/dist/{option-CBEHYG4U.js → option-BCks0a4i.js} +1 -1
  178. package/dist/{option-CBEHYG4U.js.map → option-BCks0a4i.js.map} +1 -1
  179. package/dist/{option-BDOKUqTy.cjs → option-C2VKw8Yt.cjs} +1 -1
  180. package/dist/{option-BDOKUqTy.cjs.map → option-C2VKw8Yt.cjs.map} +1 -1
  181. package/dist/option.cjs +1 -1
  182. package/dist/option.js +1 -1
  183. package/dist/{overlay-oxM9OLXP.js → overlay-C0YSnxoV.js} +8 -10
  184. package/dist/overlay-C0YSnxoV.js.map +1 -0
  185. package/dist/{overlay-DG6EeyKt.cjs → overlay-CG1gc1Jw.cjs} +2 -2
  186. package/dist/overlay-CG1gc1Jw.cjs.map +1 -0
  187. package/dist/overlay.cjs +1 -1
  188. package/dist/{overlay.confirm-body-78e1WrN9.cjs → overlay.confirm-body-B-Kmn7LF.cjs} +1 -1
  189. package/dist/{overlay.confirm-body-78e1WrN9.cjs.map → overlay.confirm-body-B-Kmn7LF.cjs.map} +1 -1
  190. package/dist/{overlay.confirm-body-D_P2e7l6.js → overlay.confirm-body-BmOnrKbF.js} +1 -1
  191. package/dist/{overlay.confirm-body-D_P2e7l6.js.map → overlay.confirm-body-BmOnrKbF.js.map} +1 -1
  192. package/dist/overlay.js +3 -3
  193. package/dist/{overlay.service-DQkGPUY7.cjs → overlay.service-BPKV2a8w.cjs} +1 -1
  194. package/dist/{overlay.service-DQkGPUY7.cjs.map → overlay.service-BPKV2a8w.cjs.map} +1 -1
  195. package/dist/{overlay.service-C8NwO4Bx.js → overlay.service-CRoq9Gu-.js} +2 -2
  196. package/dist/{overlay.service-C8NwO4Bx.js.map → overlay.service-CRoq9Gu-.js.map} +1 -1
  197. package/dist/page.cjs +1 -1
  198. package/dist/page.js +2 -2
  199. package/dist/{progress-CMSst_2U.cjs → progress-B9RWAFv5.cjs} +1 -1
  200. package/dist/{progress-CMSst_2U.cjs.map → progress-B9RWAFv5.cjs.map} +1 -1
  201. package/dist/{progress-C4kDZfb7.js → progress-CEEl7vdd.js} +1 -1
  202. package/dist/{progress-C4kDZfb7.js.map → progress-CEEl7vdd.js.map} +1 -1
  203. package/dist/progress.cjs +1 -1
  204. package/dist/progress.js +1 -1
  205. package/dist/radio-group-C2y6H5YY.cjs +19 -0
  206. package/dist/radio-group-C2y6H5YY.cjs.map +1 -0
  207. package/dist/radio-group-VERF_8rC.js +71 -0
  208. package/dist/radio-group-VERF_8rC.js.map +1 -0
  209. package/dist/radio-group.cjs +1 -1
  210. package/dist/radio-group.js +1 -1
  211. package/dist/range.cjs +1 -1
  212. package/dist/range.js +1 -1
  213. package/dist/{scroll-C1klVgSQ.js → scroll-Bj7FsS08.js} +1 -1
  214. package/dist/{scroll-C1klVgSQ.js.map → scroll-Bj7FsS08.js.map} +1 -1
  215. package/dist/{scroll-S-bXF2u6.cjs → scroll-Djz3pJfX.cjs} +1 -1
  216. package/dist/{scroll-S-bXF2u6.cjs.map → scroll-Djz3pJfX.cjs.map} +1 -1
  217. package/dist/{select-UU2pB67h.js → select-ClJj_2AP.js} +3 -3
  218. package/dist/select-ClJj_2AP.js.map +1 -0
  219. package/dist/select-CngphfDB.cjs +56 -0
  220. package/dist/select-CngphfDB.cjs.map +1 -0
  221. package/dist/select.cjs +1 -1
  222. package/dist/select.js +1 -1
  223. package/dist/skeleton.cjs +1 -1
  224. package/dist/skeleton.js +1 -1
  225. package/dist/skills/SKILL.md +12 -0
  226. package/dist/skills/schmancy/SKILL.md +12 -0
  227. package/dist/slider.cjs +1 -1
  228. package/dist/slider.js +1 -1
  229. package/dist/{splash-screen-ChMkAPLU.js → splash-screen-BQsBy3O1.js} +1 -1
  230. package/dist/{splash-screen-ChMkAPLU.js.map → splash-screen-BQsBy3O1.js.map} +1 -1
  231. package/dist/{splash-screen-BvaDkvJU.cjs → splash-screen-CntIFk2h.cjs} +1 -1
  232. package/dist/{splash-screen-BvaDkvJU.cjs.map → splash-screen-CntIFk2h.cjs.map} +1 -1
  233. package/dist/splash-screen.cjs +1 -1
  234. package/dist/splash-screen.js +1 -1
  235. package/dist/{src-DnunCC4X.js → src-BAXhEv8f.js} +32 -32
  236. package/dist/{src-DnunCC4X.js.map → src-BAXhEv8f.js.map} +1 -1
  237. package/dist/{src-BIlD63Cz.cjs → src-ChFa-FDD.cjs} +1 -1
  238. package/dist/{src-BIlD63Cz.cjs.map → src-ChFa-FDD.cjs.map} +1 -1
  239. package/dist/steps.cjs +1 -1
  240. package/dist/steps.js +1 -1
  241. package/dist/{surface-DCRy-EyT.js → surface-CHUJSY1o.js} +1 -1
  242. package/dist/{surface-DCRy-EyT.js.map → surface-CHUJSY1o.js.map} +1 -1
  243. package/dist/{surface-DWwQDX9r.cjs → surface-CXmQuXun.cjs} +1 -1
  244. package/dist/{surface-DWwQDX9r.cjs.map → surface-CXmQuXun.cjs.map} +1 -1
  245. package/dist/surface.cjs +1 -1
  246. package/dist/surface.js +1 -1
  247. package/dist/switch.cjs +1 -1
  248. package/dist/switch.js +1 -1
  249. package/dist/table.cjs +1 -1
  250. package/dist/table.js +1 -1
  251. package/dist/{tabs-lxQHWEb7.cjs → tabs-Bku0sC0p.cjs} +1 -1
  252. package/dist/{tabs-lxQHWEb7.cjs.map → tabs-Bku0sC0p.cjs.map} +1 -1
  253. package/dist/{tabs-CkDNLbiS.js → tabs-DPVX21WM.js} +1 -1
  254. package/dist/{tabs-CkDNLbiS.js.map → tabs-DPVX21WM.js.map} +1 -1
  255. package/dist/tabs.cjs +1 -1
  256. package/dist/tabs.js +1 -1
  257. package/dist/teleport.cjs +1 -1
  258. package/dist/teleport.js +1 -1
  259. package/dist/{textarea-CNa4dSvF.cjs → textarea-CqJNviYi.cjs} +1 -1
  260. package/dist/{textarea-CNa4dSvF.cjs.map → textarea-CqJNviYi.cjs.map} +1 -1
  261. package/dist/{textarea-DkfGmRSI.js → textarea-D6z1UZzs.js} +1 -1
  262. package/dist/{textarea-DkfGmRSI.js.map → textarea-D6z1UZzs.js.map} +1 -1
  263. package/dist/textarea.cjs +1 -1
  264. package/dist/textarea.js +1 -1
  265. package/dist/{theme-CMyXTDht.cjs → theme-BpKVBJCr.cjs} +1 -1
  266. package/dist/{theme-CMyXTDht.cjs.map → theme-BpKVBJCr.cjs.map} +1 -1
  267. package/dist/{theme-CNWRYdfn.js → theme-DbHfINBV.js} +1 -1
  268. package/dist/{theme-CNWRYdfn.js.map → theme-DbHfINBV.js.map} +1 -1
  269. package/dist/{theme-button-CixloLin.js → theme-button-BeU8Nbs2.js} +1 -1
  270. package/dist/{theme-button-CixloLin.js.map → theme-button-BeU8Nbs2.js.map} +1 -1
  271. package/dist/{theme-button-kMhsX5Oe.cjs → theme-button-Cof9I85G.cjs} +1 -1
  272. package/dist/{theme-button-kMhsX5Oe.cjs.map → theme-button-Cof9I85G.cjs.map} +1 -1
  273. package/dist/theme-button.cjs +1 -1
  274. package/dist/theme-button.js +1 -1
  275. package/dist/theme.cjs +1 -1
  276. package/dist/theme.js +2 -2
  277. package/dist/tree.cjs +1 -1
  278. package/dist/tree.js +1 -1
  279. package/dist/typography.cjs +1 -1
  280. package/dist/typography.js +1 -1
  281. package/dist/visually-hidden.cjs +1 -1
  282. package/dist/visually-hidden.js +1 -1
  283. package/dist/{window-qaGFMn_4.cjs → window-Cql1aIX2.cjs} +1 -1
  284. package/dist/{window-qaGFMn_4.cjs.map → window-Cql1aIX2.cjs.map} +1 -1
  285. package/dist/{window-BcvDNi9D.js → window-DmMNsos0.js} +1 -1
  286. package/dist/{window-BcvDNi9D.js.map → window-DmMNsos0.js.map} +1 -1
  287. package/dist/window.cjs +1 -1
  288. package/dist/window.js +1 -1
  289. package/package.json +1 -1
  290. package/skills/schmancy/SKILL.md +12 -0
  291. package/src/CLAUDE.md +20 -0
  292. package/src/area/area.component.ts +155 -342
  293. package/src/button/button.ts +8 -5
  294. package/src/button/icon-button.ts +8 -5
  295. package/src/chips/filter-chip.ts +1 -3
  296. package/src/details/details.ts +1 -1
  297. package/src/form/fields/radio-group/radio-button.ts +22 -44
  298. package/src/form/fields/radio-group/radio-group.ts +20 -75
  299. package/src/form/fields/select/select.ts +3 -2
  300. package/src/overlay/overlay.component.ts +29 -39
  301. package/src/overlay/overlay.positioning.ts +10 -2
  302. package/src/state/schmancy-state.html +897 -0
  303. package/src/state/schmancy-state.md +981 -0
  304. package/types/src/area/area.component.d.ts +0 -15
  305. package/types/src/button/icon-button.d.ts +1 -1
  306. package/types/src/form/fields/radio-group/radio-button.d.ts +2 -5
  307. package/types/src/form/fields/radio-group/radio-group.d.ts +2 -10
  308. package/types/src/overlay/overlay.positioning.d.ts +9 -1
  309. package/dist/area-BIipuSyO.js.map +0 -1
  310. package/dist/area-C-EMiNEE.cjs +0 -12
  311. package/dist/area-C-EMiNEE.cjs.map +0 -1
  312. package/dist/chips-D1kJrbzo.js.map +0 -1
  313. package/dist/chips-Dx_WvOGk.cjs.map +0 -1
  314. package/dist/details-Cpg8sH2F.js.map +0 -1
  315. package/dist/details-CwSDur6j.cjs.map +0 -1
  316. package/dist/mixins-DCVXqL1Q.js +0 -636
  317. package/dist/mixins-Du9HMrIG.cjs +0 -254
  318. package/dist/overlay-DG6EeyKt.cjs.map +0 -1
  319. package/dist/overlay-oxM9OLXP.js.map +0 -1
  320. package/dist/radio-group-DB9D2ZkA.js +0 -108
  321. package/dist/radio-group-DB9D2ZkA.js.map +0 -1
  322. package/dist/radio-group-dVUvYFq7.cjs +0 -40
  323. package/dist/radio-group-dVUvYFq7.cjs.map +0 -1
  324. package/dist/select-UU2pB67h.js.map +0 -1
  325. package/dist/select-fu_-rZyn.cjs +0 -56
  326. package/dist/select-fu_-rZyn.cjs.map +0 -1
@@ -6,13 +6,12 @@ import {
6
6
  catchError,
7
7
  distinctUntilChanged,
8
8
  filter,
9
+ from,
9
10
  fromEvent,
10
11
  map,
11
12
  merge,
12
13
  of,
13
- shareReplay,
14
14
  switchMap,
15
- take,
16
15
  takeUntil,
17
16
  tap,
18
17
  } from 'rxjs'
@@ -31,407 +30,221 @@ export class SchmancyArea extends SchmancyElement {
31
30
  }
32
31
  `]
33
32
 
34
- /**
35
- * The name of the router outlet
36
- * @attr
37
- * @type {string}
38
- * @public
39
- * @required
40
- */
41
33
  @property() name!: string
42
34
 
43
35
  @property() default!: RouteComponent
44
36
 
45
- /**
46
- * Query for assigned route elements in the slot
47
- * This will automatically update when slot content changes
48
- */
49
37
  @queryAssignedElements({ selector: 'schmancy-route', flatten: true })
50
38
  private routes!: SchmancyRoute[]
51
39
 
52
40
  protected firstUpdated(): void {
53
41
  if (!this.name) throw new Error('Area name is required')
54
42
 
55
- // Single unified routing pipeline with all logic inline
56
43
  merge(
57
- // Source 1: Programmatic navigation from area.request
44
+ // Programmatic navigation
58
45
  area.request.pipe(
59
46
  filter(({ area }) => area === this.name),
60
47
  ),
61
48
 
62
- // Source 2: Initial page load - parse route from URL
49
+ // Initial URL parse
63
50
  of(null).pipe(
64
- take(1),
65
51
  map(() => {
66
- // Parse route from URL on initial load
67
52
  const path = location.pathname
68
53
  const lastSegment = path.split('/').pop() || ''
69
-
70
- // Check for JSON encoded route in URL
71
54
  if (lastSegment && (lastSegment.includes('{') || lastSegment.includes('%7B'))) {
72
55
  try {
73
- const parsed = JSON.parse(decodeURIComponent(lastSegment)) as Record<string, ActiveRoute>
74
- if (parsed[this.name]) {
75
- return {
76
- area: this.name,
77
- component: parsed[this.name].component,
78
- state: parsed[this.name].state || {},
79
- params: parsed[this.name].params || {},
80
- props: parsed[this.name].props || {},
81
- historyStrategy: HISTORY_STRATEGY.replace,
82
- } as RouteAction
56
+ const parsed = JSON.parse(decodeURIComponent(lastSegment))
57
+ if (typeof parsed === 'object' && parsed !== null && parsed[this.name]) {
58
+ const r = parsed[this.name]
59
+ return { area: this.name, component: r.component, state: r.state || {}, params: r.params || {}, props: r.props || {}, historyStrategy: HISTORY_STRATEGY.replace } as RouteAction
83
60
  }
84
61
  } catch {}
85
62
  }
86
-
87
- // Segment-based routing
88
- const segments = path.split('/').filter(Boolean)
89
- const matchingSegment = segments.find(seg =>
90
- this.routes?.some(r => r.when === seg)
91
- )
92
-
63
+ const matchingSegment = path.split('/').filter(Boolean).find(seg => this.routes?.some(r => r.when === seg))
93
64
  if (matchingSegment) {
94
- return {
95
- area: this.name,
96
- component: matchingSegment,
97
- state: {},
98
- params: {},
99
- historyStrategy: HISTORY_STRATEGY.silent,
100
- } as RouteAction
65
+ return { area: this.name, component: matchingSegment, state: {}, params: {}, historyStrategy: HISTORY_STRATEGY.silent } as RouteAction
101
66
  }
102
-
103
- // Use default route if available
104
67
  return this.default
105
- ? {
106
- area: this.name,
107
- component: this.default,
108
- state: {},
109
- params: {},
110
- historyStrategy: HISTORY_STRATEGY.silent,
111
- } as RouteAction
68
+ ? { area: this.name, component: this.default, state: {}, params: {}, historyStrategy: HISTORY_STRATEGY.silent } as RouteAction
112
69
  : null
113
- })
70
+ }),
114
71
  ),
115
72
 
116
- // Source 3: Browser navigation (back/forward) - parse from browser state
73
+ // Browser back/forward
117
74
  fromEvent<PopStateEvent>(window, 'popstate').pipe(
118
75
  map(() => {
119
- // Parse route from browser state during popstate
120
- // First check history state
121
76
  if (history.state?.schmancyAreas?.[this.name]) {
122
- const stateData = history.state.schmancyAreas[this.name]
123
- return {
124
- area: this.name,
125
- component: stateData.component,
126
- state: stateData.state || {},
127
- params: stateData.params || {},
128
- props: stateData.props || {},
129
- historyStrategy: HISTORY_STRATEGY.pop,
130
- } as RouteAction
77
+ const s = history.state.schmancyAreas[this.name]
78
+ return { area: this.name, component: s.component, state: s.state || {}, params: s.params || {}, props: s.props || {}, historyStrategy: HISTORY_STRATEGY.pop } as RouteAction
131
79
  }
132
-
133
- // Fallback to URL parsing if no state (e.g., navigating to root)
134
80
  const path = location.pathname
135
81
  const lastSegment = path.split('/').pop() || ''
136
-
137
- // Check for JSON encoded route in URL
138
82
  if (lastSegment && (lastSegment.includes('{') || lastSegment.includes('%7B'))) {
139
83
  try {
140
- const parsed = JSON.parse(decodeURIComponent(lastSegment)) as Record<string, ActiveRoute>
141
- if (parsed[this.name]) {
142
- return {
143
- area: this.name,
144
- component: parsed[this.name].component,
145
- state: parsed[this.name].state || {},
146
- params: parsed[this.name].params || {},
147
- props: parsed[this.name].props || {},
148
- historyStrategy: HISTORY_STRATEGY.replace,
149
- } as RouteAction
84
+ const parsed = JSON.parse(decodeURIComponent(lastSegment))
85
+ if (typeof parsed === 'object' && parsed !== null && parsed[this.name]) {
86
+ const r = parsed[this.name]
87
+ return { area: this.name, component: r.component, state: r.state || {}, params: r.params || {}, props: r.props || {}, historyStrategy: HISTORY_STRATEGY.replace } as RouteAction
150
88
  }
151
89
  } catch {}
152
90
  }
153
-
154
- // Segment-based routing
155
- const segments = path.split('/').filter(Boolean)
156
- const matchingSegment = segments.find(seg =>
157
- this.routes?.some(r => r.when === seg)
158
- )
159
-
91
+ const matchingSegment = path.split('/').filter(Boolean).find(seg => this.routes?.some(r => r.when === seg))
160
92
  if (matchingSegment) {
161
- return {
162
- area: this.name,
163
- component: matchingSegment,
164
- state: {},
165
- params: {},
166
- historyStrategy: HISTORY_STRATEGY.silent,
167
- } as RouteAction
93
+ return { area: this.name, component: matchingSegment, state: {}, params: {}, historyStrategy: HISTORY_STRATEGY.silent } as RouteAction
168
94
  }
169
-
170
- // Use default route if available
171
95
  return this.default
172
- ? {
173
- area: this.name,
174
- component: this.default,
175
- state: {},
176
- params: {},
177
- historyStrategy: HISTORY_STRATEGY.silent,
178
- } as RouteAction
96
+ ? { area: this.name, component: this.default, state: {}, params: {}, historyStrategy: HISTORY_STRATEGY.silent } as RouteAction
179
97
  : null
180
- })
181
- )
98
+ }),
99
+ ),
182
100
  ).pipe(
183
- // Filter out null routes
184
- filter((route): route is RouteAction => route !== null),
185
-
186
- // Performance: mark navigation start
187
- tap(() => performance.mark(`area-${this.name}-nav-start`)),
188
-
189
- // Step 1: Find matching route (resolve lazy only if needed for route matching)
190
- switchMap(async action => {
191
- let component: RouteComponent | null = action.component
192
- let matchedRoute: SchmancyRoute | undefined
193
-
194
- // If component is a string, find the matching route
195
- if (typeof component === 'string' && this.routes) {
196
- matchedRoute = this.routes.find(r => r.when === component)
197
- if (matchedRoute) {
198
- component = matchedRoute.component
101
+ filter((r): r is RouteAction => r !== null),
102
+
103
+ // Per-navigation error isolation — one bad nav skips, outer stream keeps flowing
104
+ switchMap(action => of(action).pipe(
105
+ // Step 1: resolve component + find matched route
106
+ switchMap(action => {
107
+ let component: RouteComponent | null = action.component
108
+ let matchedRoute: SchmancyRoute | undefined
109
+
110
+ if (typeof component === 'string' && this.routes) {
111
+ matchedRoute = this.routes.find(r => r.when === component)
112
+ if (matchedRoute) component = matchedRoute.component
199
113
  }
200
- }
201
-
202
- // If component is a lazy function and we don't have a matched route yet,
203
- // resolve it to find the route by tag name
204
- if (
205
- !matchedRoute &&
206
- typeof component === 'function' &&
207
- ('preload' in component || '_promise' in component || '_module' in component)
208
- ) {
209
- try {
210
- const module = await (component as unknown as () => Promise<{ default: CustomElementConstructor }>)()
211
- component = module.default
212
- // Now find route by tag name
213
- const tagName = customElements.getName(component as CustomElementConstructor)
214
- if (tagName && this.routes) {
215
- matchedRoute = this.routes.find(r => r.when === tagName)
216
- }
217
- } catch (e) {
218
- console.error(`[${this.name}] Lazy load failed:`, e)
219
- return { ...action, component: null, matchedRoute: undefined }
114
+ if (!matchedRoute && component instanceof HTMLElement && this.routes) {
115
+ matchedRoute = this.routes.find(r => r.when === component.tagName.toLowerCase())
220
116
  }
221
- }
222
-
223
- // If component is HTMLElement, find by tag name
224
- if (!matchedRoute && component instanceof HTMLElement && this.routes) {
225
- const tagName = component.tagName.toLowerCase()
226
- matchedRoute = this.routes.find(r => r.when === tagName)
227
- }
228
-
229
- return { ...action, component, matchedRoute }
230
- }),
231
-
232
- // Step 2: Check route guards
233
- switchMap(route => {
234
- if (!route.matchedRoute?.guard) {
235
- return of(route)
236
- }
237
-
238
- return route.matchedRoute.guard.pipe(
239
- switchMap(guardResult => {
240
- if (guardResult === true) {
241
- return of(route)
242
- }
243
-
244
- // Guard failed, dispatch redirect event
245
- const redirectEvent = new CustomEvent('redirect', {
246
- detail: {
247
- blockedRoute: route.matchedRoute?.when || 'unknown',
248
- area: this.name,
249
- params: route.params || {},
250
- state: route.state || {},
251
- redirectTarget: typeof guardResult === 'object' ? guardResult : undefined,
252
- },
253
- bubbles: true,
254
- composed: true,
255
- })
256
- route.matchedRoute.dispatchEvent(redirectEvent)
257
-
258
- return EMPTY
259
- })
260
- )
261
- }),
262
-
263
- // Step 3: Load lazy components (after guard check for performance)
264
- switchMap(async route => {
265
- let component = route.component
266
-
267
- if (
268
- typeof component === 'function' &&
269
- ('preload' in component || '_promise' in component || '_module' in component)
270
- ) {
271
- try {
272
- const module = await (component as unknown as () => Promise<{ default: CustomElementConstructor }>)()
273
- component = module.default
274
- } catch (e) {
275
- console.error(`[${this.name}] Lazy load failed:`, e)
276
- return { ...route, component: null }
117
+ if (!matchedRoute && typeof component === 'function' && 'preload' in component) {
118
+ return from(
119
+ (component as () => Promise<{ default: CustomElementConstructor }>)().then(m => ({
120
+ ...action,
121
+ component: m.default as RouteComponent,
122
+ matchedRoute: this.routes?.find(r => r.when === (customElements.getName(m.default) ?? '')) ?? undefined,
123
+ }))
124
+ )
277
125
  }
278
- }
279
-
280
- return { ...route, component }
281
- }),
282
-
283
- // Step 4: Create unique key for deduplication
284
- map(route => {
285
- let identifier = ''
286
- const component = route.component
287
-
288
- if (!component || component === '') {
289
- identifier = 'null'
290
- } else if (typeof component === 'string') {
291
- identifier = component
292
- } else if (component instanceof HTMLElement) {
293
- identifier = component.tagName.toLowerCase()
294
- } else if (typeof component === 'function') {
295
- identifier = component.name || 'CustomElement'
296
- }
297
-
298
- const key = `${identifier}${JSON.stringify(route.params)}${JSON.stringify(route.state)}${JSON.stringify(route.props)}`
299
-
300
- return { ...route, key, tagName: identifier }
301
- }),
126
+ return of({ ...action, component, matchedRoute })
127
+ }),
128
+
129
+ // Step 2: guard check
130
+ switchMap(carry => {
131
+ if (!carry.matchedRoute?.guard) return of(carry)
132
+ return carry.matchedRoute.guard.pipe(
133
+ switchMap(allowed => {
134
+ if (allowed) return of(carry)
135
+ carry.matchedRoute?.dispatchEvent(new CustomEvent('redirect', {
136
+ detail: { blockedRoute: carry.matchedRoute?.when ?? 'unknown', area: this.name, params: carry.params || {}, state: carry.state || {} },
137
+ bubbles: true,
138
+ composed: true,
139
+ }))
140
+ return EMPTY
141
+ }),
142
+ )
143
+ }),
144
+
145
+ // Step 3: load lazy component (after guard, for perf)
146
+ switchMap(carry => {
147
+ if (!(typeof carry.component === 'function' && 'preload' in carry.component)) return of(carry)
148
+ return from(
149
+ (carry.component as () => Promise<{ default: CustomElementConstructor }>)()
150
+ .then(m => ({ ...carry, component: m.default as RouteComponent }))
151
+ )
152
+ }),
153
+
154
+ // Step 4: dedup key
155
+ map(carry => {
156
+ const c = carry.component
157
+ const id =
158
+ !c || c === '' ? 'null'
159
+ : typeof c === 'string' ? c
160
+ : c instanceof HTMLElement ? c.tagName.toLowerCase()
161
+ : typeof c === 'function' ? c.name || 'CustomElement'
162
+ : 'null'
163
+ return { ...carry, key: `${id}${JSON.stringify(carry.params)}${JSON.stringify(carry.state)}${JSON.stringify(carry.props)}` }
164
+ }),
165
+
166
+ catchError(err => {
167
+ console.error(`[${this.name}] Navigation error:`, err)
168
+ return EMPTY
169
+ }),
170
+ )),
302
171
 
303
- // Step 5: Deduplicate navigation requests
304
172
  distinctUntilChanged((a, b) => a.key === b.key),
305
173
 
306
- // Step 6: Create DOM element from component
307
- map(route => {
174
+ // Step 5: instantiate element
175
+ map(carry => {
176
+ const c = carry.component
308
177
  let element: HTMLElement | null = null
309
- const component = route.component
310
-
311
- if (!component || component === '') {
312
- element = null
313
- } else if (typeof component === 'string') {
314
- try {
315
- element = document.createElement(component)
316
- } catch {
317
- console.error(`[${this.name}] Failed to create element:`, component)
318
- }
319
- } else if (component instanceof HTMLElement) {
320
- element = component
321
- } else if (typeof component === 'function') {
322
- try {
323
- element = new (component as CustomElementConstructor)()
324
- } catch (e) {
325
- console.error(`[${this.name}] Failed to instantiate:`, e)
326
- }
178
+ if (typeof c === 'string' && c !== '') {
179
+ try { element = document.createElement(c) } catch { console.error(`[${this.name}] Failed to create element:`, c) }
180
+ } else if (c instanceof HTMLElement) {
181
+ element = c
182
+ } else if (typeof c === 'function') {
183
+ try { element = new (c as CustomElementConstructor)() } catch (e) { console.error(`[${this.name}] Failed to instantiate:`, e) }
327
184
  }
328
-
329
- // Apply properties
330
185
  if (element) {
331
- if (route.params) Object.assign(element, route.params)
332
- if (route.props) Object.assign(element, route.props)
333
- if (route.state) Object.assign(element, { state: route.state })
186
+ if (carry.params) Object.assign(element, carry.params)
187
+ if (carry.props) Object.assign(element, carry.props)
188
+ if (carry.state) Object.assign(element, { state: carry.state })
334
189
  }
335
-
336
- return { element, route }
190
+ return { ...carry, element }
337
191
  }),
338
192
 
339
- shareReplay(1),
340
-
341
- // Step 7: Swap components in DOM and update history
342
- tap(({ element, route }) => this.swapComponents(element, route)),
343
-
344
- // Performance: measure navigation duration
345
- tap(() => {
346
- performance.mark(`area-${this.name}-nav-end`)
347
- performance.measure(`area-${this.name}-navigation`, `area-${this.name}-nav-start`, `area-${this.name}-nav-end`)
348
- }),
349
-
350
- catchError(error => {
351
- console.error(`[${this.name}] Navigation error:`, error)
352
- return EMPTY
353
- }),
354
-
355
- takeUntil(this.disconnecting)
356
- )
357
- .subscribe()
358
- }
359
-
360
-
361
- /**
362
- * Swap components with animation
363
- */
364
- private swapComponents(newComponent: HTMLElement | null, routeAction: RouteAction) {
365
- // Find current routed component (not route definitions)
366
- const oldComponent = Array.from(this.children).find(
367
- child => !(child instanceof SchmancyRoute)
368
- ) as HTMLElement | undefined
369
-
370
- // Clear if no new component
371
- if (!newComponent) {
372
- oldComponent?.remove()
373
- return
374
- }
375
-
376
- // Get animation duration (0 = instant, default = 150ms)
377
- const duration = routeAction.animationDuration ?? 150
378
-
379
- // Animate transition (or instant swap if duration is 0)
380
- if (duration === 0) {
381
- // Instant swap - no animation
382
- oldComponent?.remove()
383
- this.appendChild(newComponent)
384
- } else if (oldComponent) {
385
- // GPU optimization: promote layers before animation
386
- oldComponent.style.willChange = 'opacity'
387
- newComponent.style.willChange = 'opacity'
388
- // Skip paint for outgoing component
389
- oldComponent.style.contentVisibility = 'hidden'
390
-
391
- // Animated swap - fade out old, then fade in new
392
- const fadeOut = oldComponent.animate([{ opacity: 1 }, { opacity: 0 }], { duration, easing: 'ease-out' })
393
- fadeOut.onfinish = () => {
394
- oldComponent.remove()
395
- this.appendChild(newComponent)
396
- const fadeIn = newComponent.animate([{ opacity: 0 }, { opacity: 1 }], { duration, easing: 'ease-in' })
397
- fadeIn.onfinish = () => {
398
- // Clean up GPU layer promotion
399
- newComponent.style.willChange = 'auto'
193
+ // Step 6: swap DOM, write area state, update history
194
+ tap(carry => {
195
+ const old = Array.from(this.children).find(c => !(c instanceof SchmancyRoute)) as HTMLElement | undefined
196
+ const { element } = carry
197
+
198
+ if (!element) { old?.remove(); return }
199
+
200
+ const duration = carry.animationDuration ?? 150
201
+
202
+ if (duration === 0) {
203
+ old?.remove()
204
+ this.appendChild(element)
205
+ } else if (old) {
206
+ old.style.willChange = 'opacity'
207
+ element.style.willChange = 'opacity'
208
+ old.style.contentVisibility = 'hidden'
209
+ old.animate([{ opacity: 1 }, { opacity: 0 }], { duration, easing: 'ease-out' }).finished
210
+ .then(() => {
211
+ if (!this.isConnected) return
212
+ old.remove()
213
+ this.appendChild(element)
214
+ return element.animate([{ opacity: 0 }, { opacity: 1 }], { duration, easing: 'ease-in' }).finished
215
+ })
216
+ .then(() => (element.style.willChange = 'auto'))
217
+ } else {
218
+ this.appendChild(element)
219
+ element.animate([{ opacity: 0 }, { opacity: 1 }], {
220
+ duration: duration > 100 ? Math.max(100, duration * 0.66) : duration,
221
+ easing: 'ease-in',
222
+ }).finished.then(() => (element.style.willChange = 'auto'))
400
223
  }
401
- }
402
- } else {
403
- // No old component - just fade in new
404
- newComponent.style.willChange = 'opacity'
405
- this.appendChild(newComponent)
406
- const fadeInDuration = duration > 100 ? Math.max(100, duration * 0.66) : duration
407
- const fadeIn = newComponent.animate([{ opacity: 0 }, { opacity: 1 }], { duration: fadeInDuration, easing: 'ease-in' })
408
- fadeIn.onfinish = () => {
409
- newComponent.style.willChange = 'auto'
410
- }
411
- }
412
-
413
- // Update area state
414
- const activeRoute: ActiveRoute = {
415
- component: newComponent.tagName.toLowerCase(),
416
- state: routeAction.state || {},
417
- area: this.name,
418
- params: routeAction.params || {},
419
- props: routeAction.props || {},
420
- }
421
224
 
422
- area.current.set(this.name, activeRoute)
423
- area.$current.next(area.current)
225
+ const activeRoute: ActiveRoute = {
226
+ component: element.tagName.toLowerCase(),
227
+ state: carry.state || {},
228
+ area: this.name,
229
+ params: carry.params || {},
230
+ props: carry.props || {},
231
+ }
232
+ area.current.set(this.name, activeRoute)
233
+ area.$current.next(area.current)
234
+
235
+ if (area.enableHistoryMode) {
236
+ area._updateBrowserHistory(
237
+ this.name,
238
+ activeRoute,
239
+ carry.historyStrategy ?? HISTORY_STRATEGY.push,
240
+ carry.clearQueryParams,
241
+ carry.path,
242
+ )
243
+ }
244
+ }),
424
245
 
425
- // Update browser history
426
- if (area.enableHistoryMode) {
427
- area._updateBrowserHistory(
428
- this.name,
429
- activeRoute,
430
- routeAction.historyStrategy || HISTORY_STRATEGY.push,
431
- routeAction.clearQueryParams,
432
- routeAction.path
433
- )
434
- }
246
+ takeUntil(this.disconnecting),
247
+ ).subscribe()
435
248
  }
436
249
 
437
250
  disconnectedCallback() {
@@ -1,5 +1,5 @@
1
- import { SchmancyElement } from '@mixins/index'
2
1
  import { provide } from '@lit/context'
2
+ import { SchmancyElement } from '@mixins/index'
3
3
  import { css, html, LitElement } from 'lit'
4
4
  import { customElement, property, query, queryAssignedElements } from 'lit/decorators.js'
5
5
  import { ifDefined } from 'lit/directives/if-defined.js'
@@ -26,8 +26,7 @@ export type ButtonColor = 'primary' | 'secondary' | 'success' | 'error' | 'warni
26
26
  @customElement('schmancy-button')
27
27
  export class SchmancyButton extends SchmancyElement {
28
28
  static styles = [css`:host{
29
- display: inline-block;
30
- min-width: fit-content;
29
+ display: inline-flex;
31
30
  overflow: hidden;
32
31
  position: relative;
33
32
  touch-action: manipulation;
@@ -36,6 +35,10 @@ export class SchmancyButton extends SchmancyElement {
36
35
  box-shadow 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
37
36
  transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
38
37
  }
38
+ :host([width="full"]) {
39
+ display: flex;
40
+ width: 100%;
41
+ }
39
42
  :host(:hover:not([disabled])) {
40
43
  box-shadow: 0 4px 16px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 20%, transparent);
41
44
  }
@@ -165,7 +168,7 @@ export class SchmancyButton extends SchmancyElement {
165
168
  * @default 'auto'
166
169
  * @public
167
170
  */
168
- @property()
171
+ @property({ reflect: true })
169
172
  public width: 'full' | 'auto' = 'auto'
170
173
 
171
174
  /**
@@ -301,7 +304,7 @@ export class SchmancyButton extends SchmancyElement {
301
304
 
302
305
  // Compute classes for the interactive element.
303
306
  const classes = {
304
- 'z-0 transition-all duration-200 relative rounded-2xl flex justify-center items-center outline-secondary-default focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-hidden w-full overflow-hidden':
307
+ 'z-0 transition-all duration-200 relative rounded-2xl flex justify-center items-center outline-secondary-default focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-hidden flex-1 overflow-hidden':
305
308
  true,
306
309
  // Height - M3 spec: 24dp (xxs) → 32dp (dense) → 40dp (default) → 48dp (large) → 56dp (XL)
307
310
  'h-6': this.size === 'xxs', // 24px - Ultra-compact
@@ -16,13 +16,16 @@ import { ButtonVariant } from './button'
16
16
  export class SchmnacyIconButton extends SchmancyElement {
17
17
  static styles = [css`
18
18
  :host {
19
- display: inline-block;
20
- width: fit-content;
19
+ display: inline-flex;
21
20
  border-radius: 9999px;
22
21
  transition:
23
22
  box-shadow 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
24
23
  transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
25
24
  }
25
+ :host([width="full"]) {
26
+ display: flex;
27
+ width: 100%;
28
+ }
26
29
  :host(:hover:not([disabled])) {
27
30
  box-shadow: 0 2px 12px -4px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 18%, transparent);
28
31
  }
@@ -71,7 +74,7 @@ export class SchmnacyIconButton extends SchmancyElement {
71
74
  * @type {'full' | 'auto'}
72
75
  * @default 'auto'
73
76
  */
74
- @property()
77
+ @property({ reflect: true })
75
78
  public width: 'full' | 'auto' = 'auto'
76
79
 
77
80
  /**
@@ -189,7 +192,7 @@ export class SchmnacyIconButton extends SchmancyElement {
189
192
  event.stopPropagation()
190
193
  }
191
194
 
192
- protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
195
+ protected firstUpdated(_changedProperties: PropertyValueMap<unknown> | Map<PropertyKey, unknown>): void {
193
196
  // Add any first-update logic here if needed.
194
197
  }
195
198
 
@@ -210,7 +213,7 @@ export class SchmnacyIconButton extends SchmancyElement {
210
213
  effectiveVariant === 'filled' ||
211
214
  effectiveVariant === 'filled tonal'),
212
215
  'hover:shadow-sm': !this.disabled && effectiveVariant === 'elevated',
213
- 'w-full text-center': this.width === 'full',
216
+ 'flex-1 text-center': this.width === 'full',
214
217
  'bg-surface-low text-primary-default shadow-xs': effectiveVariant === 'elevated',
215
218
  'bg-transparent text-primary-default border-1 border-outline': effectiveVariant === 'outlined',
216
219
  'bg-primary-default text-primary-on': effectiveVariant === 'filled',