@mhmo91/schmancy 0.10.36 → 0.10.38

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 (572) hide show
  1. package/custom-elements.json +54 -31
  2. package/dist/SchmancyElement-BNnyBOwk.js +286 -0
  3. package/dist/{SchmancyElement-C3CpdNsi.js.map → SchmancyElement-BNnyBOwk.js.map} +1 -1
  4. package/dist/SchmancyElement-C41uPa6l.cjs +2 -0
  5. package/dist/{SchmancyElement-BBzRWB1w.cjs.map → SchmancyElement-C41uPa6l.cjs.map} +1 -1
  6. package/dist/agent/schmancy.agent.js +2432 -2361
  7. package/dist/agent/schmancy.agent.js.map +1 -1
  8. package/dist/agent/schmancy.manifest.json +4 -22
  9. package/dist/area-2FrTZI_T.cjs +21 -0
  10. package/dist/area-2FrTZI_T.cjs.map +1 -0
  11. package/dist/{area-BA96mwFY.js → area-KVDzhT4s.js} +4 -4
  12. package/dist/area-KVDzhT4s.js.map +1 -0
  13. package/dist/area.cjs +1 -1
  14. package/dist/area.js +2 -2
  15. package/dist/{audio-D52h1jAT.js → audio-D3gnp15Y.js} +1 -1
  16. package/dist/{audio-D52h1jAT.js.map → audio-D3gnp15Y.js.map} +1 -1
  17. package/dist/{audio-B_jT9Xr7.cjs → audio-EaD0Ggfh.cjs} +1 -1
  18. package/dist/{audio-B_jT9Xr7.cjs.map → audio-EaD0Ggfh.cjs.map} +1 -1
  19. package/dist/audio.cjs +1 -1
  20. package/dist/audio.js +2 -2
  21. package/dist/autocomplete-DMmxsvUe.cjs +115 -0
  22. package/dist/autocomplete-DMmxsvUe.cjs.map +1 -0
  23. package/dist/{autocomplete-CI4QJXAN.js → autocomplete-DWiEqlQf.js} +96 -96
  24. package/dist/autocomplete-DWiEqlQf.js.map +1 -0
  25. package/dist/autocomplete.cjs +1 -1
  26. package/dist/autocomplete.js +1 -1
  27. package/dist/avatar.cjs +1 -1
  28. package/dist/avatar.js +3 -3
  29. package/dist/badge.cjs +1 -1
  30. package/dist/badge.js +1 -1
  31. package/dist/{boat-_N1x5U_3.js → boat-DmyG7y1V.js} +4 -4
  32. package/dist/{boat-_N1x5U_3.js.map → boat-DmyG7y1V.js.map} +1 -1
  33. package/dist/{boat-I4B1UNMc.cjs → boat-dB1_qLm0.cjs} +1 -1
  34. package/dist/{boat-I4B1UNMc.cjs.map → boat-dB1_qLm0.cjs.map} +1 -1
  35. package/dist/boat.cjs +1 -1
  36. package/dist/boat.js +1 -1
  37. package/dist/breadcrumb.cjs +3 -3
  38. package/dist/breadcrumb.cjs.map +1 -1
  39. package/dist/breadcrumb.js +4 -4
  40. package/dist/breadcrumb.js.map +1 -1
  41. package/dist/{busy-BIUonyPk.cjs → busy-Cj_PV7oC.cjs} +1 -1
  42. package/dist/{busy-BIUonyPk.cjs.map → busy-Cj_PV7oC.cjs.map} +1 -1
  43. package/dist/{busy-CCB3qKnh.js → busy-enYCTssB.js} +2 -2
  44. package/dist/{busy-CCB3qKnh.js.map → busy-enYCTssB.js.map} +1 -1
  45. package/dist/busy.cjs +1 -1
  46. package/dist/busy.js +1 -1
  47. package/dist/{button-C89bPnHt.js → button-BQSOVnHn.js} +10 -9
  48. package/dist/button-BQSOVnHn.js.map +1 -0
  49. package/dist/button-WRmXlNyw.cjs +62 -0
  50. package/dist/button-WRmXlNyw.cjs.map +1 -0
  51. package/dist/button.cjs +6 -6
  52. package/dist/button.cjs.map +1 -1
  53. package/dist/button.js +17 -16
  54. package/dist/button.js.map +1 -1
  55. package/dist/{card-CFsCgJKZ.js → card-BHTz1GwB.js} +16 -16
  56. package/dist/card-BHTz1GwB.js.map +1 -0
  57. package/dist/{card-BO93_oxQ.cjs → card-ThG_ZaQE.cjs} +3 -3
  58. package/dist/card-ThG_ZaQE.cjs.map +1 -0
  59. package/dist/card.cjs +1 -1
  60. package/dist/card.js +1 -1
  61. package/dist/{checkbox-CFUBUFtW.cjs → checkbox-C4zeib84.cjs} +2 -2
  62. package/dist/{checkbox-CFUBUFtW.cjs.map → checkbox-C4zeib84.cjs.map} +1 -1
  63. package/dist/{checkbox-Bh7q0djq.js → checkbox-Ce0DlAdW.js} +6 -6
  64. package/dist/{checkbox-Bh7q0djq.js.map → checkbox-Ce0DlAdW.js.map} +1 -1
  65. package/dist/checkbox.cjs +1 -1
  66. package/dist/checkbox.js +1 -1
  67. package/dist/{chips-BfzpsyV1.cjs → chips-B1jui8Pe.cjs} +3 -3
  68. package/dist/chips-B1jui8Pe.cjs.map +1 -0
  69. package/dist/{chips-6YaoRmeG.js → chips-DAy6v93f.js} +20 -19
  70. package/dist/chips-DAy6v93f.js.map +1 -0
  71. package/dist/chips.cjs +1 -1
  72. package/dist/chips.js +2 -2
  73. package/dist/connectivity.cjs +1 -1
  74. package/dist/connectivity.js +3 -3
  75. package/dist/content-drawer.cjs +1 -1
  76. package/dist/content-drawer.js +1 -1
  77. package/dist/cursor-glow-Ah7VXSj7.js.map +1 -1
  78. package/dist/cursor-glow-Bulq-38P.cjs.map +1 -1
  79. package/dist/{date-range-N-A249O9.cjs → date-range-BUaPgbTZ.cjs} +2 -2
  80. package/dist/date-range-BUaPgbTZ.cjs.map +1 -0
  81. package/dist/{date-range-CEo_Kjqw.js → date-range-NTpoA1in.js} +4 -4
  82. package/dist/date-range-NTpoA1in.js.map +1 -0
  83. package/dist/{date-range-inline-DFopysWF.cjs → date-range-inline-D0I6k84h.cjs} +1 -1
  84. package/dist/{date-range-inline-DFopysWF.cjs.map → date-range-inline-D0I6k84h.cjs.map} +1 -1
  85. package/dist/{date-range-inline-BwialV9j.js → date-range-inline-DjRdMZ1z.js} +2 -2
  86. package/dist/{date-range-inline-BwialV9j.js.map → date-range-inline-DjRdMZ1z.js.map} +1 -1
  87. package/dist/date-range-inline.cjs +1 -1
  88. package/dist/date-range-inline.js +1 -1
  89. package/dist/date-range.cjs +1 -1
  90. package/dist/date-range.js +1 -1
  91. package/dist/delay.cjs +1 -1
  92. package/dist/delay.js +2 -2
  93. package/dist/{details-GtpfI2hA.js → details-CY49XVfp.js} +43 -35
  94. package/dist/details-CY49XVfp.js.map +1 -0
  95. package/dist/details-DQNj2oaU.cjs +164 -0
  96. package/dist/details-DQNj2oaU.cjs.map +1 -0
  97. package/dist/details.cjs +1 -1
  98. package/dist/details.js +1 -1
  99. package/dist/{directives-CvYGSW_a.cjs → directives-Bb0S1DKZ.cjs} +4 -4
  100. package/dist/directives-Bb0S1DKZ.cjs.map +1 -0
  101. package/dist/{directives-C2dXgpCY.js → directives-Bfm1lkoy.js} +30 -23
  102. package/dist/directives-Bfm1lkoy.js.map +1 -0
  103. package/dist/directives.cjs +1 -1
  104. package/dist/directives.js +2 -2
  105. package/dist/{divider-D0pGX2VB.js → divider-BeyX_C0A.js} +2 -2
  106. package/dist/{divider-D0pGX2VB.js.map → divider-BeyX_C0A.js.map} +1 -1
  107. package/dist/{divider-rNsWCvMi.cjs → divider-Ck2C1sKl.cjs} +1 -1
  108. package/dist/{divider-rNsWCvMi.cjs.map → divider-Ck2C1sKl.cjs.map} +1 -1
  109. package/dist/divider.cjs +1 -1
  110. package/dist/divider.js +1 -1
  111. package/dist/dropdown.cjs +1 -1
  112. package/dist/dropdown.js +2 -2
  113. package/dist/{expand-FcKAzJta.js → expand-BYsSEtp6.js} +53 -53
  114. package/dist/expand-BYsSEtp6.js.map +1 -0
  115. package/dist/expand-CUF163mg.cjs +141 -0
  116. package/dist/expand-CUF163mg.cjs.map +1 -0
  117. package/dist/expand.cjs +1 -1
  118. package/dist/expand.js +1 -1
  119. package/dist/fab.cjs +1 -1
  120. package/dist/fab.js +2 -2
  121. package/dist/{float-CQ1WEp3M.js → float-Cgllk_H9.js} +2 -2
  122. package/dist/{float-CQ1WEp3M.js.map → float-Cgllk_H9.js.map} +1 -1
  123. package/dist/{float-CDjgxWyy.cjs → float-OvqX0nqG.cjs} +1 -1
  124. package/dist/{float-CDjgxWyy.cjs.map → float-OvqX0nqG.cjs.map} +1 -1
  125. package/dist/float.cjs +1 -1
  126. package/dist/float.js +1 -1
  127. package/dist/form-4GKROq2P.cjs +27 -0
  128. package/dist/form-4GKROq2P.cjs.map +1 -0
  129. package/dist/{form-H24puioV.js → form-DxaV_Ose.js} +39 -39
  130. package/dist/form-DxaV_Ose.js.map +1 -0
  131. package/dist/form.cjs +3 -3
  132. package/dist/form.cjs.map +1 -1
  133. package/dist/form.js +34 -34
  134. package/dist/form.js.map +1 -1
  135. package/dist/gravity-6pL6CfIr.cjs.map +1 -1
  136. package/dist/gravity-sVK3zGBF.js.map +1 -1
  137. package/dist/handover/agent-runtime-followups.md +1 -1
  138. package/dist/handover/agent-runtime-v1.md +3 -3
  139. package/dist/{icons-DBxfN91B.js → icons-CJ2mXcBi.js} +9 -9
  140. package/dist/icons-CJ2mXcBi.js.map +1 -0
  141. package/dist/icons-sZ-LybA9.cjs +24 -0
  142. package/dist/icons-sZ-LybA9.cjs.map +1 -0
  143. package/dist/icons.cjs +1 -1
  144. package/dist/icons.js +1 -1
  145. package/dist/{iframe-BDVElN8z.js → iframe-DWvN5nGB.js} +11 -11
  146. package/dist/iframe-DWvN5nGB.js.map +1 -0
  147. package/dist/{iframe-CG-z9qev.cjs → iframe-DpCv-QH2.cjs} +7 -7
  148. package/dist/iframe-DpCv-QH2.cjs.map +1 -0
  149. package/dist/iframe.cjs +1 -1
  150. package/dist/iframe.js +1 -1
  151. package/dist/index.cjs +1 -1
  152. package/dist/index.js +37 -37
  153. package/dist/{input-Bt_o4sYo.js → input-BCCHz6tB.js} +7 -7
  154. package/dist/input-BCCHz6tB.js.map +1 -0
  155. package/dist/{input-B14Nn6xD.cjs → input-Z-3N5JMv.cjs} +2 -2
  156. package/dist/input-Z-3N5JMv.cjs.map +1 -0
  157. package/dist/{input-chip-DEqO0DXc.js → input-chip-BOrcKH-H.js} +2 -2
  158. package/dist/{input-chip-DEqO0DXc.js.map → input-chip-BOrcKH-H.js.map} +1 -1
  159. package/dist/{input-chip-ugYu9Fn9.cjs → input-chip-ChAgRCXZ.cjs} +1 -1
  160. package/dist/{input-chip-ugYu9Fn9.cjs.map → input-chip-ChAgRCXZ.cjs.map} +1 -1
  161. package/dist/input.cjs +1 -1
  162. package/dist/input.js +1 -1
  163. package/dist/json.cjs +1 -1
  164. package/dist/json.js +3 -3
  165. package/dist/kbd.cjs +1 -1
  166. package/dist/kbd.js +2 -2
  167. package/dist/{layout-BJ_43VrH.js → layout-CFiG3lNT.js} +1 -1
  168. package/dist/{layout-BJ_43VrH.js.map → layout-CFiG3lNT.js.map} +1 -1
  169. package/dist/{layout-DF9ZaQ-b.cjs → layout-DZ4dpLh9.cjs} +1 -1
  170. package/dist/{layout-DF9ZaQ-b.cjs.map → layout-DZ4dpLh9.cjs.map} +1 -1
  171. package/dist/layout.cjs +1 -1
  172. package/dist/layout.js +2 -2
  173. package/dist/lazy-BaAiIUru.js +19 -0
  174. package/dist/lazy-BaAiIUru.js.map +1 -0
  175. package/dist/lazy-C-7a4FAe.cjs +1 -0
  176. package/dist/lazy-C-7a4FAe.cjs.map +1 -0
  177. package/dist/{lightbox-ZmuoBBFT.js → lightbox-B7Y4Nij_.js} +2 -2
  178. package/dist/lightbox-B7Y4Nij_.js.map +1 -0
  179. package/dist/{lightbox-B47Zoqv-.cjs → lightbox-Dpwsn8Qr.cjs} +1 -1
  180. package/dist/lightbox-Dpwsn8Qr.cjs.map +1 -0
  181. package/dist/lightbox.cjs +1 -1
  182. package/dist/lightbox.js +1 -1
  183. package/dist/{list-CaSWrlG2.cjs → list-BhM-6dAi.cjs} +1 -1
  184. package/dist/{list-CaSWrlG2.cjs.map → list-BhM-6dAi.cjs.map} +1 -1
  185. package/dist/{list-C47xzld_.js → list-C5WVoIfJ.js} +2 -2
  186. package/dist/{list-C47xzld_.js.map → list-C5WVoIfJ.js.map} +1 -1
  187. package/dist/list.cjs +1 -1
  188. package/dist/list.js +1 -1
  189. package/dist/magnetic-DKtc4umC.cjs.map +1 -1
  190. package/dist/magnetic-DaOOv5Dz.js.map +1 -1
  191. package/dist/{menu-8RObM6Ie.js → menu-CBAAJoHu.js} +3 -3
  192. package/dist/{menu-8RObM6Ie.js.map → menu-CBAAJoHu.js.map} +1 -1
  193. package/dist/{menu-Jpsy85SX.cjs → menu-DFQjJk3H.cjs} +1 -1
  194. package/dist/{menu-Jpsy85SX.cjs.map → menu-DFQjJk3H.cjs.map} +1 -1
  195. package/dist/menu.cjs +1 -1
  196. package/dist/menu.js +1 -1
  197. package/dist/{mixins-DTzfFVyv.js → mixins-DGBI7YPO.js} +11 -11
  198. package/dist/mixins-DGBI7YPO.js.map +1 -0
  199. package/dist/{mixins-DPdzC9ZH.cjs → mixins-fIpzhVMd.cjs} +1 -1
  200. package/dist/mixins-fIpzhVMd.cjs.map +1 -0
  201. package/dist/mixins.cjs +1 -1
  202. package/dist/mixins.js +2 -2
  203. package/dist/nav-drawer.cjs +1 -1
  204. package/dist/nav-drawer.js +1 -1
  205. package/dist/navigation-bar.cjs +1 -1
  206. package/dist/navigation-bar.js +1 -1
  207. package/dist/navigation-rail.cjs +3 -3
  208. package/dist/navigation-rail.cjs.map +1 -1
  209. package/dist/navigation-rail.js +11 -10
  210. package/dist/navigation-rail.js.map +1 -1
  211. package/dist/notification-B6yDL91t.cjs +24 -0
  212. package/dist/notification-B6yDL91t.cjs.map +1 -0
  213. package/dist/{notification-Ccktcj9H.js → notification-BB9OBRCr.js} +22 -22
  214. package/dist/notification-BB9OBRCr.js.map +1 -0
  215. package/dist/notification.cjs +1 -1
  216. package/dist/notification.js +1 -1
  217. package/dist/{option-CkMxwBqU.js → option-B21ImL0k.js} +2 -2
  218. package/dist/{option-CkMxwBqU.js.map → option-B21ImL0k.js.map} +1 -1
  219. package/dist/{option-0aNiVB3Q.cjs → option-CJQM5I9q.cjs} +1 -1
  220. package/dist/{option-0aNiVB3Q.cjs.map → option-CJQM5I9q.cjs.map} +1 -1
  221. package/dist/option.cjs +1 -1
  222. package/dist/option.js +1 -1
  223. package/dist/{overlay-H3Wt_dgQ.js → overlay-CWsihJ-E.js} +75 -67
  224. package/dist/overlay-CWsihJ-E.js.map +1 -0
  225. package/dist/overlay-DkIX9Ig3.cjs +58 -0
  226. package/dist/overlay-DkIX9Ig3.cjs.map +1 -0
  227. package/dist/overlay.cjs +1 -1
  228. package/dist/{overlay.confirm-body-Dxn_wNm3.js → overlay.confirm-body-CPqqPNks.js} +10 -10
  229. package/dist/overlay.confirm-body-CPqqPNks.js.map +1 -0
  230. package/dist/{overlay.confirm-body-CR9xaqOE.cjs → overlay.confirm-body-DwTfiNlV.cjs} +3 -3
  231. package/dist/overlay.confirm-body-DwTfiNlV.cjs.map +1 -0
  232. package/dist/overlay.js +4 -4
  233. package/dist/overlay.service-DU1nqh6A.cjs +1 -0
  234. package/dist/{overlay.service-DEj3rfRr.cjs.map → overlay.service-DU1nqh6A.cjs.map} +1 -1
  235. package/dist/{overlay.service-C46kOtUi.js → overlay.service-KTgBxjFb.js} +4 -4
  236. package/dist/{overlay.service-C46kOtUi.js.map → overlay.service-KTgBxjFb.js.map} +1 -1
  237. package/dist/{progress-zs18GR6C.cjs → progress-B-Qg44XY.cjs} +1 -1
  238. package/dist/{progress-zs18GR6C.cjs.map → progress-B-Qg44XY.cjs.map} +1 -1
  239. package/dist/{progress-BK7gSq8j.js → progress-CUSS1sNz.js} +2 -2
  240. package/dist/{progress-BK7gSq8j.js.map → progress-CUSS1sNz.js.map} +1 -1
  241. package/dist/progress.cjs +1 -1
  242. package/dist/progress.js +1 -1
  243. package/dist/{radio-group-1HCpzRUB.js → radio-group-AHLvrN8O.js} +7 -7
  244. package/dist/radio-group-AHLvrN8O.js.map +1 -0
  245. package/dist/{radio-group-DbYlyPc-.cjs → radio-group-BEtvCSS1.cjs} +2 -2
  246. package/dist/radio-group-BEtvCSS1.cjs.map +1 -0
  247. package/dist/radio-group.cjs +1 -1
  248. package/dist/radio-group.js +1 -1
  249. package/dist/range.cjs +1 -1
  250. package/dist/range.js +2 -2
  251. package/dist/select-BWpV2iv-.cjs +56 -0
  252. package/dist/select-BWpV2iv-.cjs.map +1 -0
  253. package/dist/{select-CEyhNtZ2.js → select-Cawz88lG.js} +46 -46
  254. package/dist/select-Cawz88lG.js.map +1 -0
  255. package/dist/select.cjs +1 -1
  256. package/dist/select.js +1 -1
  257. package/dist/skeleton.cjs +1 -1
  258. package/dist/skeleton.js +2 -2
  259. package/dist/skills/SKILL.md +17 -11
  260. package/dist/skills/overlay.md +14 -7
  261. package/dist/skills/schmancy/SKILL.md +17 -11
  262. package/dist/skills/schmancy/overlay.md +14 -7
  263. package/dist/skills/schmancy/steps.md +68 -34
  264. package/dist/skills/steps.md +68 -34
  265. package/dist/slider.cjs +1 -1
  266. package/dist/slider.js +2 -2
  267. package/dist/{sound.service-DO4SmUUT.js → sound.service-CK-5zob-.js} +4 -3
  268. package/dist/sound.service-CK-5zob-.js.map +1 -0
  269. package/dist/{sound.service-G_8GV_6L.cjs → sound.service-D2GGaBXc.cjs} +1 -1
  270. package/dist/sound.service-D2GGaBXc.cjs.map +1 -0
  271. package/dist/{splash-screen-B1mM4_xz.js → splash-screen-BUEtjHXC.js} +13 -13
  272. package/dist/splash-screen-BUEtjHXC.js.map +1 -0
  273. package/dist/{splash-screen-cbz4bxjB.cjs → splash-screen-DqPuipox.cjs} +6 -6
  274. package/dist/splash-screen-DqPuipox.cjs.map +1 -0
  275. package/dist/splash-screen.cjs +1 -1
  276. package/dist/splash-screen.js +1 -1
  277. package/dist/{src-tncsWsTY.js → src-CIqAj3Eh.js} +45 -45
  278. package/dist/src-CIqAj3Eh.js.map +1 -0
  279. package/dist/{src-czeiuT1m.cjs → src-CYqBQTyt.cjs} +6 -6
  280. package/dist/src-CYqBQTyt.cjs.map +1 -0
  281. package/dist/{state-Cx0aoL5e.cjs → state-BxDNox-2.cjs} +1 -1
  282. package/dist/{state-Cx0aoL5e.cjs.map → state-BxDNox-2.cjs.map} +1 -1
  283. package/dist/{state-DJDp3N7J.js → state-CnZCDMT0.js} +9 -9
  284. package/dist/{state-DJDp3N7J.js.map → state-CnZCDMT0.js.map} +1 -1
  285. package/dist/state.cjs +1 -1
  286. package/dist/state.js +2 -2
  287. package/dist/steps.cjs +35 -19
  288. package/dist/steps.cjs.map +1 -1
  289. package/dist/steps.js +96 -73
  290. package/dist/steps.js.map +1 -1
  291. package/dist/{surface-CYBl8_a3.js → surface-BMdG3dKQ.js} +2 -2
  292. package/dist/{surface-CYBl8_a3.js.map → surface-BMdG3dKQ.js.map} +1 -1
  293. package/dist/{surface-C3cxTcJD.cjs → surface-CWwYD_z2.cjs} +1 -1
  294. package/dist/{surface-C3cxTcJD.cjs.map → surface-CWwYD_z2.cjs.map} +1 -1
  295. package/dist/surface.cjs +1 -1
  296. package/dist/surface.js +1 -1
  297. package/dist/switch.cjs +4 -4
  298. package/dist/switch.cjs.map +1 -1
  299. package/dist/switch.js +11 -11
  300. package/dist/switch.js.map +1 -1
  301. package/dist/table.cjs +1 -1
  302. package/dist/table.js +2 -2
  303. package/dist/{tabs-DHy93Q3N.js → tabs-CDQYDc6v.js} +2 -2
  304. package/dist/{tabs-DHy93Q3N.js.map → tabs-CDQYDc6v.js.map} +1 -1
  305. package/dist/{tabs-ORQ_Zd43.cjs → tabs-CbD9E1gd.cjs} +1 -1
  306. package/dist/{tabs-ORQ_Zd43.cjs.map → tabs-CbD9E1gd.cjs.map} +1 -1
  307. package/dist/tabs.cjs +1 -1
  308. package/dist/tabs.js +1 -1
  309. package/dist/teleport.cjs +1 -1
  310. package/dist/teleport.js +1 -1
  311. package/dist/textarea-Brgi-vD2.cjs +43 -0
  312. package/dist/textarea-Brgi-vD2.cjs.map +1 -0
  313. package/dist/{textarea-DHIMt-ly.js → textarea-MPyrMi-S.js} +4 -4
  314. package/dist/textarea-MPyrMi-S.js.map +1 -0
  315. package/dist/textarea.cjs +1 -1
  316. package/dist/textarea.js +1 -1
  317. package/dist/{theme-CJpjkqHr.cjs → theme-BMbXoqi0.cjs} +1 -1
  318. package/dist/{theme-CJpjkqHr.cjs.map → theme-BMbXoqi0.cjs.map} +1 -1
  319. package/dist/{theme-CgI9PRco.js → theme-DZu-xmVp.js} +5 -5
  320. package/dist/{theme-CgI9PRco.js.map → theme-DZu-xmVp.js.map} +1 -1
  321. package/dist/{theme-button--FuBkuVr.cjs → theme-button-B0OLb-43.cjs} +1 -1
  322. package/dist/{theme-button--FuBkuVr.cjs.map → theme-button-B0OLb-43.cjs.map} +1 -1
  323. package/dist/{theme-button-D-FXb3oO.js → theme-button-D_qGvEYs.js} +2 -2
  324. package/dist/{theme-button-D-FXb3oO.js.map → theme-button-D_qGvEYs.js.map} +1 -1
  325. package/dist/theme-button.cjs +1 -1
  326. package/dist/theme-button.js +1 -1
  327. package/dist/theme.cjs +1 -1
  328. package/dist/theme.js +3 -3
  329. package/dist/{theme.service-BfTK1Wtl.js → theme.service-7VkM-hVf.js} +15 -11
  330. package/dist/theme.service-7VkM-hVf.js.map +1 -0
  331. package/dist/theme.service-B15FdjOS.cjs +1 -0
  332. package/dist/theme.service-B15FdjOS.cjs.map +1 -0
  333. package/dist/tree.cjs +4 -4
  334. package/dist/tree.cjs.map +1 -1
  335. package/dist/tree.js +8 -8
  336. package/dist/tree.js.map +1 -1
  337. package/dist/{typography-CxA3sx9B.cjs → typography-D4Fo1UGh.cjs} +3 -3
  338. package/dist/{typography-CxA3sx9B.cjs.map → typography-D4Fo1UGh.cjs.map} +1 -1
  339. package/dist/{typography-BEGLfHwz.js → typography-SZhjb_4R.js} +9 -9
  340. package/dist/{typography-BEGLfHwz.js.map → typography-SZhjb_4R.js.map} +1 -1
  341. package/dist/typography.cjs +1 -1
  342. package/dist/typography.js +1 -1
  343. package/dist/visually-hidden.cjs +1 -1
  344. package/dist/visually-hidden.js +2 -2
  345. package/dist/{window-B_n4P9az.js → window-BDVyrBnk.js} +101 -100
  346. package/dist/window-BDVyrBnk.js.map +1 -0
  347. package/dist/window-BbBYjm7R.cjs +59 -0
  348. package/dist/window-BbBYjm7R.cjs.map +1 -0
  349. package/dist/window.cjs +1 -1
  350. package/dist/window.js +1 -1
  351. package/package.json +1 -1
  352. package/skills/schmancy/SKILL.md +17 -11
  353. package/skills/schmancy/overlay.md +14 -7
  354. package/skills/schmancy/steps.md +68 -34
  355. package/src/area/area.component.ts +1 -1
  356. package/src/area/area.service.test.ts +2 -2
  357. package/src/area/area.service.ts +1 -1
  358. package/src/area/lazy.ts +87 -83
  359. package/src/audio/sound.service.ts +3 -3
  360. package/src/breadcrumb/breadcrumb.ts +2 -2
  361. package/src/button/button.ts +11 -11
  362. package/src/button/icon-button.ts +18 -18
  363. package/src/card/card.ts +16 -16
  364. package/src/content-drawer/drawer.ts +6 -6
  365. package/src/details/details.ts +55 -55
  366. package/src/directives/ai-badge.ts +2 -1
  367. package/src/directives/animate-text.ts +2 -1
  368. package/src/directives/art/art.directive.ts +2 -1
  369. package/src/directives/battery.ts +2 -1
  370. package/src/directives/confirm-click.ts +5 -3
  371. package/src/directives/cursor-glow.ts +2 -1
  372. package/src/directives/cycle-text.ts +2 -1
  373. package/src/directives/depth-of-field.ts +2 -1
  374. package/src/directives/drag.ts +4 -2
  375. package/src/directives/fyi.ts +2 -1
  376. package/src/directives/gravity.ts +2 -1
  377. package/src/directives/hummingbird.ts +2 -1
  378. package/src/directives/intersect.ts +3 -2
  379. package/src/directives/liquid.ts +2 -1
  380. package/src/directives/living-border.ts +2 -1
  381. package/src/directives/long-press.ts +2 -1
  382. package/src/directives/magnetic.ts +2 -1
  383. package/src/directives/missed-punch.ts +2 -1
  384. package/src/directives/nebula.ts +6 -5
  385. package/src/directives/overflow-within.ts +2 -1
  386. package/src/directives/reveal.ts +193 -118
  387. package/src/directives/urgent.ts +2 -1
  388. package/src/directives/working-snake.ts +2 -1
  389. package/src/expand/expand-root.component.ts +27 -27
  390. package/src/expand/expand.component.ts +48 -48
  391. package/src/form/fields/autocomplete/autocomplete.ts +154 -154
  392. package/src/form/fields/checkbox/checkbox.ts +4 -4
  393. package/src/form/fields/chips/chips.ts +2 -2
  394. package/src/form/fields/chips/filter-chip.ts +15 -15
  395. package/src/form/fields/date-range/date-range.ts +2 -2
  396. package/src/form/fields/input/input.ts +12 -12
  397. package/src/form/fields/radio-group/radio-button.ts +2 -2
  398. package/src/form/fields/radio-group/radio-group.ts +3 -3
  399. package/src/form/fields/select/select.ts +56 -56
  400. package/src/form/fields/switch/switch.ts +10 -10
  401. package/src/form/fields/textarea/textarea.ts +2 -2
  402. package/src/form/form-summary.ts +33 -33
  403. package/src/form/form.ts +45 -45
  404. package/src/icons/icon.ts +10 -8
  405. package/src/iframe/iframe.ts +11 -11
  406. package/src/lightbox/flip-directive.ts +2 -1
  407. package/src/lightbox/lightbox.directive.ts +2 -1
  408. package/src/nav-drawer/navbar.ts +3 -3
  409. package/src/navigation-rail/navigation-rail.ts +10 -10
  410. package/src/notification/notification.ts +22 -22
  411. package/src/overlay/overlay.component.ts +106 -83
  412. package/src/overlay/overlay.confirm-body.ts +4 -4
  413. package/src/overlay/overlay.service.ts +3 -3
  414. package/src/overlay/overlay.types.ts +4 -2
  415. package/src/splash-screen/splash-screen.ts +11 -11
  416. package/src/state/index.ts +12 -12
  417. package/src/state/schmancy-context.ts +9 -9
  418. package/src/steps/index.ts +1 -1
  419. package/src/steps/schmancy-step.ts +91 -65
  420. package/src/steps/{schmancy-steps-container.ts → schmancy-steps.ts} +18 -38
  421. package/src/steps/steps.context.ts +5 -4
  422. package/src/steps/steps.test.ts +120 -0
  423. package/src/teleport/teleport.component.ts +2 -2
  424. package/src/theme/theme.service.ts +17 -17
  425. package/src/tree/tree.ts +7 -7
  426. package/src/typography/typography.ts +7 -7
  427. package/src/window/window-manager.ts +20 -20
  428. package/src/window/window.ts +100 -100
  429. package/types/mixins/SchmancyElement.d.ts +3 -2
  430. package/types/mixins/formField.mixin.d.ts +1 -1
  431. package/types/src/area/area.service.d.ts +1 -1
  432. package/types/src/area/lazy.d.ts +0 -6
  433. package/types/src/audio/sound.service.d.ts +1 -2
  434. package/types/src/breadcrumb/breadcrumb.d.ts +1 -1
  435. package/types/src/button/button.d.ts +3 -3
  436. package/types/src/button/icon-button.d.ts +6 -7
  437. package/types/src/card/card.d.ts +5 -5
  438. package/types/src/content-drawer/drawer.d.ts +1 -1
  439. package/types/src/details/details.d.ts +2 -21
  440. package/types/src/directives/ai-badge.d.ts +2 -2
  441. package/types/src/directives/animate-text.d.ts +2 -2
  442. package/types/src/directives/art/art.directive.d.ts +2 -2
  443. package/types/src/directives/battery.d.ts +2 -2
  444. package/types/src/directives/confirm-click.d.ts +2 -2
  445. package/types/src/directives/cursor-glow.d.ts +2 -2
  446. package/types/src/directives/cycle-text.d.ts +2 -2
  447. package/types/src/directives/depth-of-field.d.ts +2 -2
  448. package/types/src/directives/drag.d.ts +4 -4
  449. package/types/src/directives/fyi.d.ts +2 -2
  450. package/types/src/directives/gravity.d.ts +2 -2
  451. package/types/src/directives/hummingbird.d.ts +2 -2
  452. package/types/src/directives/intersect.d.ts +2 -2
  453. package/types/src/directives/liquid.d.ts +2 -2
  454. package/types/src/directives/living-border.d.ts +2 -2
  455. package/types/src/directives/long-press.d.ts +2 -2
  456. package/types/src/directives/magnetic.d.ts +2 -2
  457. package/types/src/directives/missed-punch.d.ts +2 -2
  458. package/types/src/directives/nebula.d.ts +2 -2
  459. package/types/src/directives/overflow-within.d.ts +2 -2
  460. package/types/src/directives/reveal.d.ts +17 -7
  461. package/types/src/directives/urgent.d.ts +2 -2
  462. package/types/src/directives/working-snake.d.ts +2 -2
  463. package/types/src/expand/expand-root.component.d.ts +8 -8
  464. package/types/src/expand/expand.component.d.ts +11 -11
  465. package/types/src/form/fields/autocomplete/autocomplete.d.ts +29 -29
  466. package/types/src/form/fields/checkbox/checkbox.d.ts +1 -1
  467. package/types/src/form/fields/chips/chips.d.ts +1 -1
  468. package/types/src/form/fields/chips/filter-chip.d.ts +1 -2
  469. package/types/src/form/fields/input/input.d.ts +3 -3
  470. package/types/src/form/fields/radio-group/radio-button.d.ts +1 -1
  471. package/types/src/form/fields/radio-group/radio-group.d.ts +1 -1
  472. package/types/src/form/fields/select/select.d.ts +8 -8
  473. package/types/src/form/fields/switch/switch.d.ts +3 -3
  474. package/types/src/form/fields/textarea/textarea.d.ts +1 -1
  475. package/types/src/form/form-summary.d.ts +7 -7
  476. package/types/src/form/form.d.ts +11 -11
  477. package/types/src/icons/icon.d.ts +2 -2
  478. package/types/src/iframe/iframe.d.ts +3 -3
  479. package/types/src/lightbox/flip-directive.d.ts +2 -2
  480. package/types/src/lightbox/lightbox.directive.d.ts +2 -2
  481. package/types/src/nav-drawer/navbar.d.ts +1 -1
  482. package/types/src/navigation-rail/navigation-rail.d.ts +2 -2
  483. package/types/src/notification/notification.d.ts +8 -8
  484. package/types/src/overlay/overlay.component.d.ts +16 -16
  485. package/types/src/overlay/overlay.confirm-body.d.ts +1 -1
  486. package/types/src/overlay/overlay.types.d.ts +4 -2
  487. package/types/src/splash-screen/splash-screen.d.ts +2 -2
  488. package/types/src/state/index.d.ts +1 -1
  489. package/types/src/state/schmancy-context.d.ts +3 -3
  490. package/types/src/steps/index.d.ts +1 -1
  491. package/types/src/steps/schmancy-step.d.ts +8 -23
  492. package/types/src/steps/{schmancy-steps-container.d.ts → schmancy-steps.d.ts} +8 -9
  493. package/types/src/steps/steps.context.d.ts +2 -1
  494. package/types/src/steps/steps.test.d.ts +2 -0
  495. package/types/src/teleport/teleport.component.d.ts +1 -1
  496. package/types/src/theme/theme.service.d.ts +1 -4
  497. package/types/src/tree/tree.d.ts +3 -3
  498. package/types/src/typography/typography.d.ts +1 -1
  499. package/types/src/window/window-manager.d.ts +2 -2
  500. package/types/src/window/window.d.ts +20 -20
  501. package/dist/SchmancyElement-BBzRWB1w.cjs +0 -2
  502. package/dist/SchmancyElement-C3CpdNsi.js +0 -284
  503. package/dist/area-BA96mwFY.js.map +0 -1
  504. package/dist/area-DtyQDdOF.cjs +0 -21
  505. package/dist/area-DtyQDdOF.cjs.map +0 -1
  506. package/dist/autocomplete-Bts5Jwwr.cjs +0 -115
  507. package/dist/autocomplete-Bts5Jwwr.cjs.map +0 -1
  508. package/dist/autocomplete-CI4QJXAN.js.map +0 -1
  509. package/dist/button-C89bPnHt.js.map +0 -1
  510. package/dist/button-CkwQH-g3.cjs +0 -62
  511. package/dist/button-CkwQH-g3.cjs.map +0 -1
  512. package/dist/card-BO93_oxQ.cjs.map +0 -1
  513. package/dist/card-CFsCgJKZ.js.map +0 -1
  514. package/dist/chips-6YaoRmeG.js.map +0 -1
  515. package/dist/chips-BfzpsyV1.cjs.map +0 -1
  516. package/dist/date-range-CEo_Kjqw.js.map +0 -1
  517. package/dist/date-range-N-A249O9.cjs.map +0 -1
  518. package/dist/details-BLRPV8sY.cjs +0 -164
  519. package/dist/details-BLRPV8sY.cjs.map +0 -1
  520. package/dist/details-GtpfI2hA.js.map +0 -1
  521. package/dist/directives-C2dXgpCY.js.map +0 -1
  522. package/dist/directives-CvYGSW_a.cjs.map +0 -1
  523. package/dist/expand-FcKAzJta.js.map +0 -1
  524. package/dist/expand-tffQHGbZ.cjs +0 -141
  525. package/dist/expand-tffQHGbZ.cjs.map +0 -1
  526. package/dist/form-H24puioV.js.map +0 -1
  527. package/dist/form-VYhbbir3.cjs +0 -27
  528. package/dist/form-VYhbbir3.cjs.map +0 -1
  529. package/dist/icons-B_a1HStW.cjs +0 -24
  530. package/dist/icons-B_a1HStW.cjs.map +0 -1
  531. package/dist/icons-DBxfN91B.js.map +0 -1
  532. package/dist/iframe-BDVElN8z.js.map +0 -1
  533. package/dist/iframe-CG-z9qev.cjs.map +0 -1
  534. package/dist/input-B14Nn6xD.cjs.map +0 -1
  535. package/dist/input-Bt_o4sYo.js.map +0 -1
  536. package/dist/lazy-CayEFyC3.cjs +0 -1
  537. package/dist/lazy-CayEFyC3.cjs.map +0 -1
  538. package/dist/lazy-D-bO2r4m.js +0 -13
  539. package/dist/lazy-D-bO2r4m.js.map +0 -1
  540. package/dist/lightbox-B47Zoqv-.cjs.map +0 -1
  541. package/dist/lightbox-ZmuoBBFT.js.map +0 -1
  542. package/dist/mixins-DPdzC9ZH.cjs.map +0 -1
  543. package/dist/mixins-DTzfFVyv.js.map +0 -1
  544. package/dist/notification-Ccktcj9H.js.map +0 -1
  545. package/dist/notification-DSkB-sn0.cjs +0 -24
  546. package/dist/notification-DSkB-sn0.cjs.map +0 -1
  547. package/dist/overlay-BS-ta-zq.cjs +0 -58
  548. package/dist/overlay-BS-ta-zq.cjs.map +0 -1
  549. package/dist/overlay-H3Wt_dgQ.js.map +0 -1
  550. package/dist/overlay.confirm-body-CR9xaqOE.cjs.map +0 -1
  551. package/dist/overlay.confirm-body-Dxn_wNm3.js.map +0 -1
  552. package/dist/overlay.service-DEj3rfRr.cjs +0 -1
  553. package/dist/radio-group-1HCpzRUB.js.map +0 -1
  554. package/dist/radio-group-DbYlyPc-.cjs.map +0 -1
  555. package/dist/select-B-SSmUDe.cjs +0 -56
  556. package/dist/select-B-SSmUDe.cjs.map +0 -1
  557. package/dist/select-CEyhNtZ2.js.map +0 -1
  558. package/dist/sound.service-DO4SmUUT.js.map +0 -1
  559. package/dist/sound.service-G_8GV_6L.cjs.map +0 -1
  560. package/dist/splash-screen-B1mM4_xz.js.map +0 -1
  561. package/dist/splash-screen-cbz4bxjB.cjs.map +0 -1
  562. package/dist/src-czeiuT1m.cjs.map +0 -1
  563. package/dist/src-tncsWsTY.js.map +0 -1
  564. package/dist/textarea-CEUaDURR.cjs +0 -43
  565. package/dist/textarea-CEUaDURR.cjs.map +0 -1
  566. package/dist/textarea-DHIMt-ly.js.map +0 -1
  567. package/dist/theme.service-BfTK1Wtl.js.map +0 -1
  568. package/dist/theme.service-Dg7LO0Qz.cjs +0 -1
  569. package/dist/theme.service-Dg7LO0Qz.cjs.map +0 -1
  570. package/dist/window-B_n4P9az.js.map +0 -1
  571. package/dist/window-Vl1u1-EG.cjs +0 -59
  572. package/dist/window-Vl1u1-EG.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { u as e } from "./SchmancyElement-C3CpdNsi.js";
2
- import { o as t } from "./mixins-DTzfFVyv.js";
3
- import { S as n } from "./directives-C2dXgpCY.js";
1
+ import { u as e } from "./SchmancyElement-BNnyBOwk.js";
2
+ import { o as t } from "./mixins-DGBI7YPO.js";
3
+ import { S as n } from "./directives-Bfm1lkoy.js";
4
4
  import { t as r } from "./theme.interface-odQEpZZH.js";
5
5
  import { BehaviorSubject as i, Subject as a, combineLatest as o, fromEvent as s, takeUntil as c } from "rxjs";
6
6
  import { tap as l, withLatestFrom as u } from "rxjs/operators";
@@ -11,14 +11,14 @@ import { ifDefined as y } from "lit/directives/if-defined.js";
11
11
  import { autoUpdate as b, computePosition as x, flip as S, offset as C, shift as w } from "@floating-ui/dom";
12
12
  var T = class extends t() {
13
13
  constructor(...e) {
14
- super(...e), this.placeholder = "", this.multi = !1, this.size = "md", this.isOpen = !1, this.valueLabel = "", this.isValid = !0, this.selectDefaultValue = "", this._options$ = new i([]), this._selectedValue$ = new i(""), this._selectedValues$ = new i([]), this._optionSelect$ = new a(), this._userInteracted = !1, this._focusedOptionId = "", this.handleKeyDown = (e) => {
14
+ super(...e), this.placeholder = "", this.multi = !1, this.size = "md", this.isOpen = !1, this.valueLabel = "", this.isValid = !0, this.selectDefaultValue = "", this.options$ = new i([]), this.selectedValue$ = new i(""), this.selectedValues$ = new i([]), this.optionSelect$ = new a(), this.userInteracted = !1, this.focusedOptionId = "", this.handleKeyDown = (e) => {
15
15
  if (this.disabled) return;
16
16
  if (!this.isOpen) return void ([
17
17
  "Enter",
18
18
  " ",
19
19
  "ArrowDown"
20
20
  ].includes(e.key) && (e.preventDefault(), this.openDropdown(!1)));
21
- let t = Array.from(this.options || []), n = t.findIndex((e) => e.id === this._focusedOptionId) ?? -1;
21
+ let t = Array.from(this.options || []), n = t.findIndex((e) => e.id === this.focusedOptionId) ?? -1;
22
22
  switch (e.key) {
23
23
  case "Escape":
24
24
  e.preventDefault(), this.closeDropdown();
@@ -37,8 +37,8 @@ var T = class extends t() {
37
37
  break;
38
38
  case "Enter":
39
39
  case " ":
40
- if (e.preventDefault(), this._focusedOptionId) {
41
- let e = t.find((e) => e.id === this._focusedOptionId);
40
+ if (e.preventDefault(), this.focusedOptionId) {
41
+ let e = t.find((e) => e.id === this.focusedOptionId);
42
42
  e && this.handleOptionSelect(e.value);
43
43
  }
44
44
  break;
@@ -60,22 +60,22 @@ var T = class extends t() {
60
60
  `];
61
61
  }
62
62
  get value() {
63
- return this.multi ? this._selectedValues$?.value ?? [] : this._selectedValue$?.value ?? "";
63
+ return this.multi ? this.selectedValues$?.value ?? [] : this.selectedValue$?.value ?? "";
64
64
  }
65
65
  set value(e) {
66
- if (this._selectedValue$ && this._selectedValues$) if (this.multi) {
66
+ if (this.selectedValue$ && this.selectedValues$) if (this.multi) {
67
67
  let t = Array.isArray(e) ? e : e ? String(e).split(",").map((e) => e.trim()).filter(Boolean) : [];
68
- this._selectedValues$.next(t);
69
- } else this._selectedValue$.next(e == null ? "" : String(e));
68
+ this.selectedValues$.next(t);
69
+ } else this.selectedValue$.next(e == null ? "" : String(e));
70
70
  }
71
71
  get values() {
72
- return [...this._selectedValues$.value];
72
+ return [...this.selectedValues$.value];
73
73
  }
74
74
  set values(e) {
75
- this._selectedValues$.next(Array.isArray(e) ? [...e] : []);
75
+ this.selectedValues$.next(Array.isArray(e) ? [...e] : []);
76
76
  }
77
77
  connectedCallback() {
78
- super.connectedCallback(), this.id ||= `schmancy-select-${Math.random().toString(36).substring(2, 9)}`, this.selectDefaultValue = this.value, s(this, "keydown").pipe(c(this.disconnecting)).subscribe(this.handleKeyDown), this._setupReactivePipelines();
78
+ super.connectedCallback(), this.id ||= `schmancy-select-${Math.random().toString(36).substring(2, 9)}`, this.selectDefaultValue = this.value, s(this, "keydown").pipe(c(this.disconnecting)).subscribe(this.handleKeyDown), this.setupReactivePipelines();
79
79
  }
80
80
  disconnectedCallback() {
81
81
  super.disconnectedCallback(), this.cleanupPositioner?.();
@@ -85,17 +85,17 @@ var T = class extends t() {
85
85
  }
86
86
  updated(e) {
87
87
  if (super.updated(e), e.has("value")) {
88
- let e = this.multi ? this._selectedValues$.value.join(",") : this._selectedValue$.value;
88
+ let e = this.multi ? this.selectedValues$.value.join(",") : this.selectedValue$.value;
89
89
  this.internals?.setFormValue(e);
90
90
  }
91
91
  e.has("isOpen") && (this.isOpen ? this.positionDropdown() : this.cleanupPositioner?.());
92
92
  }
93
93
  syncSelection() {
94
94
  if (this.multi) {
95
- let e = this._selectedValues$.value;
95
+ let e = this.selectedValues$.value;
96
96
  this.options?.forEach((t) => t.selected = e.includes(t.value)), this.valueLabel = e.length > 0 && this.options?.filter((t) => e.includes(t.value)).map((e) => e.label || e.textContent || "").join(", ") || this.placeholder;
97
97
  } else {
98
- let e = this._selectedValue$.value;
98
+ let e = this.selectedValue$.value;
99
99
  this.options?.forEach((t) => {
100
100
  t.selected = t.value === e;
101
101
  });
@@ -105,7 +105,7 @@ var T = class extends t() {
105
105
  }
106
106
  setupOptionsAccessibility() {
107
107
  this.options?.forEach((e, t) => {
108
- e.setAttribute("role", "option"), e.id ||= `${this.id}-option-${t}`, e.tabIndex = -1, e.setAttribute("aria-selected", String(this.multi ? this._selectedValues$.value.includes(e.value) : e.value === this._selectedValue$.value));
108
+ e.setAttribute("role", "option"), e.id ||= `${this.id}-option-${t}`, e.tabIndex = -1, e.setAttribute("aria-selected", String(this.multi ? this.selectedValues$.value.includes(e.value) : e.value === this.selectedValue$.value));
109
109
  });
110
110
  }
111
111
  async positionDropdown() {
@@ -132,7 +132,7 @@ var T = class extends t() {
132
132
  focusOption(e, t) {
133
133
  let n = e[t];
134
134
  if (n) {
135
- n.focus(), this._focusedOptionId = n.id;
135
+ n.focus(), this.focusedOptionId = n.id;
136
136
  let e = this.renderRoot.querySelector(".trigger");
137
137
  if (e && e.setAttribute("aria-activedescendant", n.id), this.ul && n.offsetTop !== void 0) {
138
138
  let e = n.offsetTop, t = n.offsetHeight, r = this.ul.scrollTop, i = this.ul.clientHeight;
@@ -143,35 +143,35 @@ var T = class extends t() {
143
143
  async openDropdown(e = !1) {
144
144
  if (this.disabled) return;
145
145
  this.isOpen = !0, await this.updateComplete;
146
- let t = Array.from(this.options || []), n = this.multi ? 0 : t.findIndex((e) => e.value === this._selectedValue$.value);
146
+ let t = Array.from(this.options || []), n = this.multi ? 0 : t.findIndex((e) => e.value === this.selectedValue$.value);
147
147
  this.focusOption(t, Math.max(n, 0)), e && this.reportValidity();
148
148
  }
149
149
  closeDropdown() {
150
- this._userInteracted && (this.touched = !0), this.isOpen = !1, this._focusedOptionId = "";
150
+ this.userInteracted && (this.touched = !0), this.isOpen = !1, this.focusedOptionId = "";
151
151
  let e = this.renderRoot.querySelector(".trigger");
152
- e && (e.removeAttribute("aria-activedescendant"), e?.focus()), this._userInteracted && this._shouldShowError() && this.checkValidity();
152
+ e && (e.removeAttribute("aria-activedescendant"), e?.focus()), this.userInteracted && this.shouldShowError() && this.checkValidity();
153
153
  }
154
- _setupReactivePipelines() {
154
+ setupReactivePipelines() {
155
155
  s(this, "option-select").pipe(l((e) => {
156
156
  e.stopPropagation();
157
157
  let t = this.options.find((t) => t.value === e.detail.value);
158
- t && this._optionSelect$.next(t);
159
- }), c(this.disconnecting)).subscribe(), this._optionSelect$.pipe(u(this._selectedValue$, this._selectedValues$), l(([e, t, n]) => {
160
- if (this._userInteracted = !0, this.markTouched(), this.multi) {
158
+ t && this.optionSelect$.next(t);
159
+ }), c(this.disconnecting)).subscribe(), this.optionSelect$.pipe(u(this.selectedValue$, this.selectedValues$), l(([e, t, n]) => {
160
+ if (this.userInteracted = !0, this.markTouched(), this.multi) {
161
161
  let t = n.indexOf(e.value), r = t > -1 ? [...n.slice(0, t), ...n.slice(t + 1)] : [...n, e.value];
162
- this._selectedValues$.next(r), this.internals?.setFormValue(r.join(",")), this.valueLabel = r.length > 0 ? this.options.filter((e) => r.includes(e.value)).map((e) => e.label || e.textContent || "").join(", ") : this.placeholder;
163
- } else this._selectedValue$.next(e.value), this.internals?.setFormValue(e.value), this.valueLabel = e.label || e.textContent || this.placeholder, this.closeDropdown();
164
- this.setupOptionsAccessibility(), this._fireChangeEvent();
165
- }), c(this.disconnecting)).subscribe(), this._options$.pipe(l((e) => {
162
+ this.selectedValues$.next(r), this.internals?.setFormValue(r.join(",")), this.valueLabel = r.length > 0 ? this.options.filter((e) => r.includes(e.value)).map((e) => e.label || e.textContent || "").join(", ") : this.placeholder;
163
+ } else this.selectedValue$.next(e.value), this.internals?.setFormValue(e.value), this.valueLabel = e.label || e.textContent || this.placeholder, this.closeDropdown();
164
+ this.setupOptionsAccessibility(), this.fireChangeEvent();
165
+ }), c(this.disconnecting)).subscribe(), this.options$.pipe(l((e) => {
166
166
  e.forEach((e, t) => {
167
167
  e.setAttribute("role", "option"), e.tabIndex = -1, e.id ||= `${this.id}-option-${t}`, e.hasAttribute("data-event-bound") || (s(e, "click").pipe(l((e) => {
168
168
  e.stopPropagation();
169
- }), c(this.disconnecting)).subscribe(() => this._optionSelect$.next(e)), e.setAttribute("data-event-bound", "true"));
169
+ }), c(this.disconnecting)).subscribe(() => this.optionSelect$.next(e)), e.setAttribute("data-event-bound", "true"));
170
170
  });
171
171
  }), c(this.disconnecting)).subscribe(), o([
172
- this._selectedValue$,
173
- this._selectedValues$,
174
- this._options$
172
+ this.selectedValue$,
173
+ this.selectedValues$,
174
+ this.options$
175
175
  ]).pipe(l(([e, t, n]) => {
176
176
  n.length !== 0 && (this.multi ? n.forEach((e) => {
177
177
  e.selected = t.includes(e.value);
@@ -182,10 +182,10 @@ var T = class extends t() {
182
182
  }
183
183
  handleOptionSelect(e) {
184
184
  let t = this.options.find((t) => t.value === e);
185
- t && this._optionSelect$.next(t);
185
+ t && this.optionSelect$.next(t);
186
186
  }
187
- _fireChangeEvent() {
188
- let e = this.multi ? this._selectedValues$.value : this._selectedValue$.value;
187
+ fireChangeEvent() {
188
+ let e = this.multi ? this.selectedValues$.value : this.selectedValue$.value;
189
189
  this.dispatchEvent(new CustomEvent("change", {
190
190
  detail: { value: e },
191
191
  bubbles: !0,
@@ -194,9 +194,9 @@ var T = class extends t() {
194
194
  }
195
195
  checkValidity() {
196
196
  if (this.disabled) return !0;
197
- let e = this.multi ? this._selectedValues$.value.length === 0 : !this._selectedValue$.value, t = !(this.required && e);
197
+ let e = this.multi ? this.selectedValues$.value.length === 0 : !this.selectedValue$.value, t = !(this.required && e);
198
198
  if (this.isValid = t, this.isValid ? (this.validationMessage = "", this.internals?.setValidity({})) : (this.validationMessage = "Please select an option.", this.internals?.setValidity({ valueMissing: !0 }, "Please select an option.", this.inputRef)), this.inputRef && this.hasUpdated) {
199
- let e = !this.isValid && this._shouldShowError();
199
+ let e = !this.isValid && this.shouldShowError();
200
200
  this.inputRef.error = e, this.inputRef.hint = e ? this.validationMessage : this.hint;
201
201
  }
202
202
  return this.isValid;
@@ -211,16 +211,16 @@ var T = class extends t() {
211
211
  return e == null || e === "" ? [] : Array.isArray(e) ? e.map((e) => [this.name, String(e)]) : [[this.name, String(e)]];
212
212
  }
213
213
  setCustomValidity(e) {
214
- this.validationMessage = e, e ? (this.isValid = !1, this.internals?.setValidity({ customError: !0 }, e, this.inputRef)) : (this.isValid = !0, this.internals?.setValidity({})), this.inputRef && this._shouldShowError() && (this.inputRef.error = !this.isValid, this.inputRef.hint = this.isValid ? this.hint : this.validationMessage);
214
+ this.validationMessage = e, e ? (this.isValid = !1, this.internals?.setValidity({ customError: !0 }, e, this.inputRef)) : (this.isValid = !0, this.internals?.setValidity({})), this.inputRef && this.shouldShowError() && (this.inputRef.error = !this.isValid, this.inputRef.hint = this.isValid ? this.hint : this.validationMessage);
215
215
  }
216
216
  resetForm() {
217
- this.value = this.selectDefaultValue, this.valueLabel = this.placeholder, this.isValid = !0, this._userInteracted = !1, this.internals?.setValidity({}), super.resetForm(), this.inputRef && (this.inputRef.error = !1, this.inputRef.hint = this.hint);
217
+ this.value = this.selectDefaultValue, this.valueLabel = this.placeholder, this.isValid = !0, this.userInteracted = !1, this.internals?.setValidity({}), super.resetForm(), this.inputRef && (this.inputRef.error = !1, this.inputRef.hint = this.hint);
218
218
  }
219
219
  reset() {
220
220
  this.resetForm();
221
221
  }
222
222
  render() {
223
- let e = !this.isValid && this._shouldShowError() && !this.isOpen, t = this.isOpen ? v`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▲</span>` : v`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▼</span>`;
223
+ let e = !this.isValid && this.shouldShowError() && !this.isOpen, t = this.isOpen ? v`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▲</span>` : v`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▼</span>`;
224
224
  return v`
225
225
  <div class="relative ${this.disabled ? "opacity-60 cursor-not-allowed" : ""}">
226
226
  <sch-input
@@ -233,7 +233,7 @@ var T = class extends t() {
233
233
  aria-controls="options"
234
234
  aria-autocomplete="none"
235
235
  aria-required=${this.required}
236
- aria-activedescendant=${y(this._focusedOptionId || void 0)}
236
+ aria-activedescendant=${y(this.focusedOptionId || void 0)}
237
237
  aria-disabled=${this.disabled}
238
238
  .label=${this.label}
239
239
  .placeholder=${this.placeholder}
@@ -248,7 +248,7 @@ var T = class extends t() {
248
248
  clickable
249
249
  @click=${(e) => {
250
250
  if (this.disabled) return e.preventDefault(), void e.stopPropagation();
251
- this.isOpen ? (this._userInteracted = !0, this.closeDropdown()) : this.openDropdown(!1);
251
+ this.isOpen ? (this.userInteracted = !0, this.closeDropdown()) : this.openDropdown(!1);
252
252
  }}
253
253
  >
254
254
  ${t}
@@ -272,7 +272,7 @@ var T = class extends t() {
272
272
  >
273
273
  <slot
274
274
  @slotchange=${() => {
275
- this._options$.next(this.options), this.syncSelection();
275
+ this.options$.next(this.options), this.syncSelection();
276
276
  }}
277
277
  ></slot>
278
278
  </ul>
@@ -283,5 +283,5 @@ var T = class extends t() {
283
283
  e([p({ type: String })], T.prototype, "placeholder", void 0), e([p({
284
284
  type: String,
285
285
  reflect: !0
286
- })], T.prototype, "value", null), e([p({ type: Array })], T.prototype, "values", null), e([p({ type: Boolean })], T.prototype, "multi", void 0), e([p({ type: String })], T.prototype, "size", void 0), e([g()], T.prototype, "isOpen", void 0), e([g()], T.prototype, "valueLabel", void 0), e([g()], T.prototype, "isValid", void 0), e([g()], T.prototype, "selectDefaultValue", void 0), e([m("ul")], T.prototype, "ul", void 0), e([m("sch-input")], T.prototype, "inputRef", void 0), e([h({ flatten: !0 })], T.prototype, "options", void 0), e([g()], T.prototype, "_userInteracted", void 0), e([g()], T.prototype, "_focusedOptionId", void 0), T = e([f("schmancy-select")], T);
286
+ })], T.prototype, "value", null), e([p({ type: Array })], T.prototype, "values", null), e([p({ type: Boolean })], T.prototype, "multi", void 0), e([p({ type: String })], T.prototype, "size", void 0), e([g()], T.prototype, "isOpen", void 0), e([g()], T.prototype, "valueLabel", void 0), e([g()], T.prototype, "isValid", void 0), e([g()], T.prototype, "selectDefaultValue", void 0), e([m("ul")], T.prototype, "ul", void 0), e([m("sch-input")], T.prototype, "inputRef", void 0), e([h({ flatten: !0 })], T.prototype, "options", void 0), e([g()], T.prototype, "userInteracted", void 0), e([g()], T.prototype, "focusedOptionId", void 0), T = e([f("schmancy-select")], T);
287
287
  export { T as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-Cawz88lG.js","names":[],"sources":["../src/form/fields/select/select.ts"],"sourcesContent":["import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { SchmancyFormField } from '@mixins/index'\nimport { color } from '@schmancy/directives'\nimport SchmancyInput from '@schmancy/input/input'\nimport SchmancyOption from '@schmancy/option/option'\nimport { SchmancyTheme } from '@schmancy/theme/theme.interface'\nimport { css, html, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { BehaviorSubject, combineLatest, fromEvent, Subject, takeUntil } from 'rxjs'\nimport { tap, withLatestFrom } from 'rxjs/operators'\n\nexport type SchmancySelectChangeEvent = CustomEvent<{\n\tvalue: string | string[]\n}>\n\n/**\n * Select dropdown component with single and multi-select support.\n *\n * @prop {string} name - Name attribute for form submission\n * @prop {string} label - Label text displayed above the select\n * @prop {string} placeholder - Placeholder text when no value is selected\n * @prop {boolean} required - Whether the field is required\n * @prop {boolean} multi - Enable multi-select mode\n * @prop {string} value - Selected value (single select mode)\n * @prop {string[]} values - Selected values (multi-select mode)\n */\n@customElement('schmancy-select')\nexport class SchmancySelect extends SchmancyFormField() {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tposition: relative;\n\t}\n\n\t[role='listbox'] {\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t}\n`]\n\n\t// FACE wiring (formAssociated, internals, attachInternals) comes from\n\t// SchmancyFormField. Same for: name, required, disabled, validationMessage,\n\t// validateOn, touched/dirty/pristine/submitted, markTouched/markSubmitted,\n\t// formResetCallback, formDisabledCallback, FIELD_CONNECT_EVENT dispatch.\n\n\t@property({ type: String }) placeholder = ''\n\n\t// Override `value` with the narrowed select-specific type and a custom\n\t// getter/setter pair backed by reactive subjects.\n\t@property({ type: String, reflect: true })\n\toverride get value(): string | string[] {\n\t\treturn this.multi\n\t\t\t? (this.selectedValues$?.value ?? [])\n\t\t\t: (this.selectedValue$?.value ?? '')\n\t}\n\toverride set value(val: string | string[]) {\n\t\tif (!this.selectedValue$ || !this.selectedValues$) return\n\t\tif (this.multi) {\n\t\t\tconst values = Array.isArray(val)\n\t\t\t\t? val\n\t\t\t\t: val ? String(val).split(',').map(v => v.trim()).filter(Boolean) : []\n\t\t\tthis.selectedValues$.next(values)\n\t\t} else {\n\t\t\tthis.selectedValue$.next(val == null ? '' : String(val))\n\t\t}\n\t}\n\n\t// Values property for multi-select mode\n\t@property({ type: Array })\n\tget values() {\n\t\treturn [...this.selectedValues$.value]\n\t}\n\tset values(vals: string[]) {\n\t\tthis.selectedValues$.next(Array.isArray(vals) ? [...vals] : [])\n\t}\n\n\t@property({ type: Boolean }) multi = false\n\t// `label` and `hint` come from the mixin.\n\t// M3 aligned sizes: 24dp (xxs) → 32dp (xs) → 40dp (sm) → 48dp (md) → 56dp (lg)\n\t@property({ type: String }) size: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' = 'md'\n\n\t// Internal states\n\t@state() private isOpen = false\n\t@state() private valueLabel = ''\n\t@state() private isValid = true\n\n\t// Store the initial/default value for reset behavior. Distinct from the\n\t// mixin's `defaultValue` (which is `string` only); select needs the wider\n\t// shape so resetForm can restore arrays for multi-select.\n\t@state() private selectDefaultValue: string | string[] = ''\n\n\t@query('ul') private ul!: HTMLUListElement\n\t@query('sch-input') private inputRef!: SchmancyInput\n\t@queryAssignedElements({ flatten: true }) private options!: SchmancyOption[]\n\tprivate cleanupPositioner?: () => void\n\n\t// Reactive state management\n\tprivate options$ = new BehaviorSubject<SchmancyOption[]>([])\n\tprivate selectedValue$ = new BehaviorSubject<string>('')\n\tprivate selectedValues$ = new BehaviorSubject<string[]>([])\n\tprivate optionSelect$ = new Subject<SchmancyOption>()\n\n\t/**\n\t * Tracks whether the user has actively interacted (clicked/typed/keyed\n\t * inside the dropdown). Distinct from the mixin's `touched` (which fires on\n\t * blur). Used to gate dropdown-positioning side-effects on user-driven\n\t * actions versus programmatic state changes.\n\t */\n\t@state() userInteracted = false\n\n\t// Reference to current focused option (for keyboard navigation)\n\t@state() private focusedOptionId = ''\n\n\toverride connectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tif (!this.id) {\n\t\t\tthis.id = `schmancy-select-${Math.random().toString(36).substring(2, 9)}`\n\t\t}\n\n\t\t// Store initial value for reset\n\t\tthis.selectDefaultValue = this.value\n\n\t\t// Add keyboard handling to host element\n\t\tfromEvent<KeyboardEvent>(this, 'keydown').pipe(takeUntil(this.disconnecting)).subscribe(this.handleKeyDown)\n\n\t\t// Setup reactive pipelines\n\t\tthis.setupReactivePipelines()\n\t}\n\n\toverride disconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.cleanupPositioner?.()\n\t\t// Form event listeners are automatically cleaned up via takeUntil(this.disconnecting)\n\t}\n\n\tfirstUpdated() {\n\t\tthis.syncSelection()\n\t\tthis.setupOptionsAccessibility()\n\n\t\t// Initially hide any validation errors until user interacts\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t}\n\t}\n\n\toverride updated(changedProps: PropertyValues) {\n\t\tsuper.updated(changedProps)\n\n\t\tif (changedProps.has('value')) {\n\t\t\t// Multi-select serializes to a comma-joined scalar on FormData; the\n\t\t\t// mixin's willUpdate already called setFormValue with the raw\n\t\t\t// value, override here for the joined-string shape.\n\t\t\tconst formValue = this.multi\n\t\t\t\t? this.selectedValues$.value.join(',')\n\t\t\t\t: this.selectedValue$.value\n\t\t\tthis.internals?.setFormValue(formValue)\n\n\t\t\t// `dirty` is a mixin getter (value !== defaultValue); no manual flag.\n\t\t\t// Mixin's willUpdate already calls checkValidity when shouldShowError().\n\t\t}\n\n\t\t// When open state changes, setup or cleanup the dropdown positioner\n\t\tif (changedProps.has('isOpen')) {\n\t\t\tif (this.isOpen) {\n\t\t\t\tthis.positionDropdown()\n\t\t\t} else {\n\t\t\t\tthis.cleanupPositioner?.()\n\t\t\t}\n\t\t}\n\t}\n\n\t// `shouldShowValidation` removed — replaced by mixin's `shouldShowError()`.\n\n\tprivate syncSelection() {\n\t\tif (this.multi) {\n\t\t\t// Read directly from the BehaviorSubject to avoid string conversion issues\n\t\t\tconst selectedValues = this.selectedValues$.value\n\t\t\tthis.options?.forEach(o => (o.selected = selectedValues.includes(o.value))) // Update option selected state\n\t\t\tthis.valueLabel =\n\t\t\t\tselectedValues.length > 0\n\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t?.filter(o => selectedValues.includes(o.value))\n\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t.join(', ') || this.placeholder\n\t\t\t\t\t: this.placeholder\n\t\t} else {\n\t\t\t// Single select - read from BehaviorSubject\n\t\t\tconst currentValue = this.selectedValue$.value\n\t\t\tthis.options?.forEach(o => {\n\t\t\t\t// Set selected property on each option based on matching value\n\t\t\t\to.selected = o.value === currentValue\n\t\t\t})\n\t\t\tconst selectedOption = this.options?.find(o => o.value === currentValue)\n\t\t\tthis.valueLabel = selectedOption ? (selectedOption.label || selectedOption.textContent || '') : this.placeholder\n\t\t}\n\t}\n\n\tprivate setupOptionsAccessibility() {\n\t\tthis.options?.forEach((option, index) => {\n\t\t\toption.setAttribute('role', 'option')\n\t\t\tif (!option.id) {\n\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t}\n\n\t\t\t// Set tabindex to -1 so they're focusable programmatically but not in the tab order\n\t\t\toption.tabIndex = -1\n\n\t\t\toption.setAttribute(\n\t\t\t\t'aria-selected',\n\t\t\t\tString(this.multi ? this.selectedValues$.value.includes(option.value) : option.value === this.selectedValue$.value),\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate async positionDropdown() {\n\t\tconst reference = this.renderRoot.querySelector('.trigger') as HTMLElement\n\t\tif (!reference || !this.ul) return\n\n\t\tthis.cleanupPositioner = autoUpdate(reference, this.ul, async () => {\n\t\t\t// Get viewport dimensions\n\t\t\tconst viewportHeight = window.innerHeight\n\t\t\tconst triggerRect = reference.getBoundingClientRect()\n\n\t\t\t// Calculate available space below and above\n\t\t\tconst spaceBelow = viewportHeight - triggerRect.bottom\n\t\t\tconst spaceAbove = triggerRect.top\n\n\t\t\t// Calculate max height - use 75% of the largest available space, but at least 150px\n\t\t\tconst maxHeight = Math.max(Math.max(spaceBelow, spaceAbove) * 0.75, 150)\n\n\t\t\t// Determine if we should flip\n\t\t\tconst shouldFlip = spaceBelow < 200 && spaceAbove > spaceBelow\n\n\t\t\t// Apply max height\n\t\t\tthis.ul.style.maxHeight = `${maxHeight}px`\n\n\t\t\tconst { x, y } = await computePosition(reference, this.ul, {\n\t\t\t\tplacement: shouldFlip ? 'top-start' : 'bottom-start',\n\t\t\t\tmiddleware: [offset(5), flip(), shift({ padding: 5 })],\n\t\t\t})\n\n\t\t\tObject.assign(this.ul.style, {\n\t\t\t\tleft: `${x}px`,\n\t\t\t\ttop: `${y}px`,\n\t\t\t\tposition: 'absolute',\n\t\t\t\twidth: `${reference.offsetWidth}px`, // Match the width of the trigger\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate handleKeyDown = (e: KeyboardEvent) => {\n\t\t// Don't handle keyboard events when disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.isOpen) {\n\t\t\tif (['Enter', ' ', 'ArrowDown'].includes(e.key)) {\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// Find current focused option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst current = options.findIndex(o => o.id === this.focusedOptionId) ?? -1\n\n\t\tswitch (e.key) {\n\t\t\tcase 'Escape':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.min(current + 1, options.length - 1))\n\t\t\t\tbreak\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.max(current - 1, 0))\n\t\t\t\tbreak\n\t\t\tcase 'Home':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, 0)\n\t\t\t\tbreak\n\t\t\tcase 'End':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, options.length - 1)\n\t\t\t\tbreak\n\t\t\tcase 'Enter':\n\t\t\tcase ' ':\n\t\t\t\te.preventDefault()\n\t\t\t\tif (this.focusedOptionId) {\n\t\t\t\t\tconst focusedOption = options.find(opt => opt.id === this.focusedOptionId)\n\t\t\t\t\tif (focusedOption) {\n\t\t\t\t\t\tthis.handleOptionSelect(focusedOption.value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'Tab':\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate focusOption(options: SchmancyOption[], index: number) {\n\t\tconst option = options[index]\n\t\tif (option) {\n\t\t\toption.focus()\n\t\t\tthis.focusedOptionId = option.id\n\n\t\t\t// Update aria-activedescendant on the combobox\n\t\t\tconst combobox = this.renderRoot.querySelector('.trigger')\n\t\t\tif (combobox) {\n\t\t\t\tcombobox.setAttribute('aria-activedescendant', option.id)\n\t\t\t}\n\n\t\t\t// Ensure option is visible in the scrollable area\n\t\t\tif (this.ul && option.offsetTop !== undefined) {\n\t\t\t\t// Get position info\n\t\t\t\tconst optionTop = option.offsetTop\n\t\t\t\tconst optionHeight = option.offsetHeight\n\t\t\t\tconst scrollTop = this.ul.scrollTop\n\t\t\t\tconst ulHeight = this.ul.clientHeight\n\n\t\t\t\t// Scroll into view if needed\n\t\t\t\tif (optionTop < scrollTop) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop\n\t\t\t\t} else if (optionTop + optionHeight > scrollTop + ulHeight) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop + optionHeight - ulHeight\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async openDropdown(report = false) {\n\t\t// Don't open if disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\t// Don't mark as touched on opening - we'll do that on closing\n\t\t// so errors only show after interaction is complete\n\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\t// Focus first or selected option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst selectedIndex = this.multi ? 0 : options.findIndex(o => o.value === this.selectedValue$.value)\n\n\t\tthis.focusOption(options, Math.max(selectedIndex, 0))\n\n\t\t// Don't automatically validate when opening\n\t\t// Only validate if explicitly requested (like from a form submission)\n\t\tif (report) this.reportValidity()\n\t}\n\n\tprivate closeDropdown() {\n\t\t// Only mark as touched if the user actually interacted with the component\n\t\t// and made a selection or explicitly closed it without selecting\n\t\tif (this.userInteracted) {\n\t\t\tthis.touched = true\n\t\t}\n\n\t\tthis.isOpen = false\n\t\tthis.focusedOptionId = ''\n\n\t\t// Update combobox to remove aria-activedescendant\n\t\tconst combobox = this.renderRoot.querySelector<HTMLElement>('.trigger')\n\t\tif (combobox) {\n\t\t\tcombobox.removeAttribute('aria-activedescendant')\n\t\t\tcombobox?.focus()\n\t\t}\n\n\t\t// Only check validity when closing if the user has actually interacted\n\t\t// with the component and validation should be shown\n\t\tif (this.userInteracted && this.shouldShowError()) {\n\t\t\tthis.checkValidity()\n\t\t}\n\t}\n\n\tprivate setupReactivePipelines() {\n\t\t// Listen for option-select events from child options\n\t\tfromEvent<CustomEvent>(this, 'option-select')\n\t\t\t.pipe(\n\t\t\t\ttap((e) => {\n\t\t\t\t\te.stopPropagation() // Prevent event from bubbling further\n\t\t\t\t\tconst option = this.options.find(o => o.value === e.detail.value)\n\t\t\t\t\tif (option) {\n\t\t\t\t\t\tthis.optionSelect$.next(option)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Handle option selection through reactive pipeline\n\t\tthis.optionSelect$\n\t\t\t.pipe(\n\t\t\t\twithLatestFrom(this.selectedValue$, this.selectedValues$),\n\t\t\t\ttap(([option, _, currentValues]) => {\n\t\t\t\t\tthis.userInteracted = true\n\t\t\t\t\tthis.markTouched()\n\t\t\t\t\t// `dirty` is a mixin getter; setting `value` below triggers it\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\tconst index = currentValues.indexOf(option.value)\n\t\t\t\t\t\tconst newValues = index > -1\n\t\t\t\t\t\t\t? [...currentValues.slice(0, index), ...currentValues.slice(index + 1)]\n\t\t\t\t\t\t\t: [...currentValues, option.value]\n\t\t\t\t\t\tthis.selectedValues$.next(newValues)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(newValues.join(','))\n\n\t\t\t\t\t\t// Update display label\n\t\t\t\t\t\tthis.valueLabel = newValues.length > 0\n\t\t\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t\t\t.filter(o => newValues.includes(o.value))\n\t\t\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t\t\t: this.placeholder\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Single select\n\t\t\t\t\t\tthis.selectedValue$.next(option.value)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(option.value)\n\n\t\t\t\t\t\tthis.valueLabel = option.label || option.textContent || this.placeholder\n\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t}\n\n\t\t\t\t\t// Update the option's accessibility state\n\t\t\t\t\tthis.setupOptionsAccessibility()\n\n\t\t\t\t\t// Dispatch change event\n\t\t\t\t\tthis.fireChangeEvent()\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Options management pipeline - bind pointerdown events exactly like autocomplete\n\t\tthis.options$\n\t\t\t.pipe(\n\t\t\t\ttap((options) => {\n\t\t\t\t\toptions.forEach((option, index) => {\n\t\t\t\t\t\toption.setAttribute('role', 'option')\n\t\t\t\t\t\toption.tabIndex = -1\n\t\t\t\t\t\tif (!option.id) {\n\t\t\t\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Use data-event-bound to prevent duplicate bindings\n\t\t\t\t\t\tif (!option.hasAttribute('data-event-bound')) {\n\t\t\t\t\t\t\t// Use click event instead of pointerdown for better mobile UX\n\t\t\t\t\t\t\t// This allows users to scroll through options without immediately selecting\n\t\t\t\t\t\t\tfromEvent(option, 'click').pipe(\n\t\t\t\t\t\t\t\ttap(e => {\n\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t\t\t\t\t).subscribe(() => this.optionSelect$.next(option))\n\t\t\t\t\t\t\toption.setAttribute('data-event-bound', 'true')\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Selection sync pipeline - sync selected states with value changes\n\t\tcombineLatest([this.selectedValue$, this.selectedValues$, this.options$])\n\t\t\t.pipe(\n\t\t\t\ttap(([singleValue, multiValues, options]) => {\n\t\t\t\t\tif (options.length === 0) return\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = multiValues.includes(option.value)\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = option.value === singleValue\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate handleOptionSelect(value: string) {\n\t\t// This method is now called from keyboard navigation only\n\t\tconst option = this.options.find(o => o.value === value)\n\t\tif (option) {\n\t\t\tthis.optionSelect$.next(option)\n\t\t}\n\t}\n\n\tprivate fireChangeEvent() {\n\t\t// Get the current value based on multi/single mode\n\t\tconst value = this.multi ? this.selectedValues$.value : this.selectedValue$.value\n\n\t\t// Dispatch only one change event with the value in detail\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<SchmancySelectChangeEvent['detail']>('change', {\n\t\t\t\tdetail: { value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\n\t\t// Then check validity (only show error if validation should be shown)\n\t\tthis.checkValidity()\n\t}\n\n\tpublic checkValidity(): boolean {\n\t\t// Disabled fields are always valid\n\t\tif (this.disabled) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Determine if the select is empty based on whether it's multi-select or single-select\n\t\tconst isEmpty = this.multi\n\t\t\t? this.selectedValues$.value.length === 0\n\t\t\t: !this.selectedValue$.value\n\n\t\t// Check if the value is valid (not empty when required)\n\t\tconst isValid = !(this.required && isEmpty)\n\n\t\t// Set the validity state\n\t\tthis.isValid = isValid\n\n\t\tif (!this.isValid) {\n\t\t\tthis.validationMessage = 'Please select an option.'\n\t\t\tthis.internals?.setValidity({ valueMissing: true }, 'Please select an option.', this.inputRef)\n\t\t} else {\n\t\t\t// Clear validation message\n\t\t\tthis.validationMessage = ''\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update the input component to reflect our validation state\n\t\tif (this.inputRef && this.hasUpdated) {\n\t\t\tconst showError = !this.isValid && this.shouldShowError()\n\t\t\tthis.inputRef.error = showError\n\t\t\tthis.inputRef.hint = showError ? this.validationMessage : this.hint\n\t\t}\n\n\t\treturn this.isValid\n\t}\n\n\tpublic reportValidity(): boolean {\n\t\t// Force validation display regardless of validation strategy\n\t\tconst valid = this.checkValidity()\n\n\t\t// Force the input to show validation errors\n\t\tif (this.inputRef) {\n\t\t\t// Set the input's error state\n\t\t\tthis.inputRef.error = !valid\n\t\t\tthis.inputRef.hint = !valid ? this.validationMessage : this.hint\n\n\t\t\t// If invalid and not already open, automatically open the dropdown to show options\n\t\t\tif (!valid && !this.isOpen) {\n\t\t\t\t// Open the dropdown but don't mark as user interaction yet\n\t\t\t\t// This helps users immediately see available options when validation fails\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\n\t\t\t// Only call reportValidity on the input if invalid to show the native popup\n\t\t\tif (!valid) {\n\t\t\t\tthis.inputRef.reportValidity()\n\t\t\t}\n\t\t}\n\n\t\treturn valid\n\t}\n\n\t// `markTouched`, `markSubmitted`, `touched`, `dirty`, `pristine`, `submitted`,\n\t// `error` (storage) — all from the mixin. Select's `error` semantics\n\t// (errors-while-open suppression) live in render() via shouldShowError() +\n\t// !isOpen, not as a separate getter.\n\n\t/**\n\t * Multi-value-aware `toFormEntries`. Single-select emits one `[name,value]`;\n\t * multi-select emits N entries with the same name (canonical FormData shape\n\t * for repeated fields).\n\t */\n\toverride toFormEntries(): Array<[string, FormDataEntryValue]> {\n\t\tif (!this.name || this.disabled) return []\n\t\tconst v = this.value\n\t\tif (v === undefined || v === null || v === '') return []\n\t\tif (Array.isArray(v))\n\t\t\treturn v.map(item => [this.name, String(item)] as [string, FormDataEntryValue])\n\t\treturn [[this.name, String(v)]]\n\t}\n\n\toverride setCustomValidity(message: string) {\n\t\tthis.validationMessage = message\n\t\tif (message) {\n\t\t\tthis.isValid = false\n\t\t\tthis.internals?.setValidity({ customError: true }, message, this.inputRef)\n\t\t} else {\n\t\t\tthis.isValid = true\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update input if needed\n\t\tif (this.inputRef && this.shouldShowError()) {\n\t\t\tthis.inputRef.error = !this.isValid\n\t\t\tthis.inputRef.hint = !this.isValid ? this.validationMessage : this.hint\n\t\t}\n\t}\n\n\t/**\n\t * Reset to the snapshot captured at connect time. Mixin's `resetForm`\n\t * handles touched/submitted/error/validationMessage; the override layers on\n\t * select-specific cleanup (value subjects, label, validity).\n\t */\n\toverride resetForm(): void {\n\t\t// Restore value (multi-aware) before super so the mixin's defaultValue\n\t\t// reset doesn't clobber the array-shape we need.\n\t\tthis.value = this.selectDefaultValue\n\t\tthis.valueLabel = this.placeholder\n\t\tthis.isValid = true\n\t\tthis.userInteracted = false\n\t\tthis.internals?.setValidity({})\n\t\tsuper.resetForm()\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t\tthis.inputRef.hint = this.hint\n\t\t}\n\t}\n\n\t/** Back-compat alias for callers that used the previous public API. */\n\tpublic reset(): void {\n\t\tthis.resetForm()\n\t}\n\n\trender(): TemplateResult {\n\t\t// Determine if we should show errors based on the validation strategy and interaction\n\t\t// Never show errors on initial render or if the dropdown is open\n\t\tconst showErrors = !this.isValid && this.shouldShowError() && !this.isOpen\n\n\t\t// Add caret icon based on open state\n\t\tconst caretIcon = this.isOpen\n\t\t\t? html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▲</span>`\n\t\t\t: html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▼</span>`\n\n\t\treturn html`\n\t\t\t<div class=\"relative ${this.disabled ? 'opacity-60 cursor-not-allowed' : ''}\">\n\t\t\t\t<sch-input\n\t\t\t\t\t.name=${this.name ?? ''}\n\t\t\t\t\ttabIndex=${this.disabled ? '-1' : '0'}\n\t\t\t\t\tclass=\"trigger\"\n\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\taria-expanded=${this.isOpen}\n\t\t\t\t\taria-controls=\"options\"\n\t\t\t\t\taria-autocomplete=\"none\"\n\t\t\t\t\taria-required=${this.required}\n\t\t\t\t\taria-activedescendant=${ifDefined(this.focusedOptionId || undefined)}\n\t\t\t\t\taria-disabled=${this.disabled}\n\t\t\t\t\t.label=${this.label}\n\t\t\t\t\t.placeholder=${this.placeholder}\n\t\t\t\t\t.value=${this.valueLabel}\n\t\t\t\t\t.required=${this.required}\n\t\t\t\t\t.disabled=${this.disabled}\n\t\t\t\t\t.hint=${showErrors ? this.validationMessage : this.hint}\n\t\t\t\t\t.error=${showErrors}\n\t\t\t\t\t.validateOn=${this.validateOn}\n\t\t\t\t\t.size=${this.size}\n\t\t\t\t\t.readonly=${true}\n\t\t\t\t\tclickable\n\t\t\t\t\t@click=${(e: MouseEvent) => {\n\t\t\t\t\t\t// Don't process clicks if disabled\n\t\t\t\t\t\tif (this.disabled) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// On first click, don't count this as user interaction yet\n\t\t\t\t\t\tif (!this.isOpen) {\n\t\t\t\t\t\t\t// Open without triggering validation - we'll validate when they close\n\t\t\t\t\t\t\tthis.openDropdown(false)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Mark as interacted when they close the dropdown\n\t\t\t\t\t\t\tthis.userInteracted = true\n\t\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${caretIcon}\n\t\t\t\t</sch-input>\n\n\t\t\t\t<!-- Overlay for capturing clicks outside when dropdown is open -->\n\t\t\t\t${this.isOpen\n\t\t\t\t\t? html` <div class=\"fixed inset-0 z-10\" @click=${this.closeDropdown} tabindex=\"-1\" aria-hidden=\"true\"></div> `\n\t\t\t\t\t: ''}\n\n\t\t\t\t<ul\n\t\t\t\t\tid=\"options\"\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\taria-multiselectable=${this.multi}\n\t\t\t\t\tclass=${classMap({\n\t\t\t\t\t\t'absolute min-w-full w-full z-20 mt-1 rounded-md shadow-lg': true,\n\t\t\t\t\t\thidden: !this.isOpen,\n\t\t\t\t\t})}\n\t\t\t\t\t${color({\n\t\t\t\t\t\tbgColor: SchmancyTheme.sys.color.surface.low,\n\t\t\t\t\t\tcolor: SchmancyTheme.sys.color.surface.on,\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t<slot\n\t\t\t\t\t\t@slotchange=${() => {\n\t\t\t\t\t\t\tthis.options$.next(this.options)\n\t\t\t\t\t\t\t// Sync selection state when options re-render\n\t\t\t\t\t\t\tthis.syncSelection()\n\t\t\t\t\t\t}}\n\t\t\t\t\t></slot>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\n// Don't export 'select' here as it conflicts with the store's select decorator\n// export const select = SchmancySelect\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-select': SchmancySelect\n\t}\n}\n"],"mappings":"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"}
package/dist/select.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./select-B-SSmUDe.cjs`);Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return e.t}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./select-BWpV2iv-.cjs`);Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return e.t}});
package/dist/select.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./select-CEyhNtZ2.js";
1
+ import { t as e } from "./select-Cawz88lG.js";
2
2
  export { e as SchmancySelect };
package/dist/skeleton.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-BBzRWB1w.cjs`);require(`./mixins-DPdzC9ZH.cjs`);let t=require(`lit/decorators.js`),n=require(`lit`);var r=class extends e.t{constructor(...e){super(...e),this.shape=`rect`,this.width=``,this.height=``,this.radius=``}static{this.styles=[n.css`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-C41uPa6l.cjs`);require(`./mixins-fIpzhVMd.cjs`);let t=require(`lit/decorators.js`),n=require(`lit`);var r=class extends e.t{constructor(...e){super(...e),this.shape=`rect`,this.width=``,this.height=``,this.radius=``}static{this.styles=[n.css`
2
2
  :host {
3
3
  display: block;
4
4
  width: var(--_sw, 100%);
package/dist/skeleton.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as e, u as t } from "./SchmancyElement-C3CpdNsi.js";
2
- import "./mixins-DTzfFVyv.js";
1
+ import { t as e, u as t } from "./SchmancyElement-BNnyBOwk.js";
2
+ import "./mixins-DGBI7YPO.js";
3
3
  import { customElement as n, property as r } from "lit/decorators.js";
4
4
  import { css as i, html as a } from "lit";
5
5
  var o = class extends e {
@@ -74,21 +74,24 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
74
74
  - Register the tag in `HTMLElementTagNameMap` for TypeScript.
75
75
 
76
76
  **SIGNALS_ARE_THE_API**
77
- State signals are the integration layer between co-located Schmancy view components; each view component owns its IO directly and has zero property inputs and zero custom event outputs when state signals cover the shared state.
77
+ State signals are the integration layer between co-located Schmancy view components: each view component owns its IO directly and carries zero property inputs and zero custom-event outputs whenever a state signal covers the shared state. A `.property=${value}` input from a parent, a `CustomEvent` a sibling or parent handles, or a co-located orchestrator whose routing complexity does not exceed schmancy's `.guard`+`@redirect` (a linear flow, no branching, no cross-route hand-off) means that shared state belongs in a signal both components read and write directly in `render()`/`connectedCallback()`, and the orchestrator is deleted when passing data down and receiving events up was its only job.
78
78
 
79
- - Detection signals: a view component with `.property=${value}` inputs from a parent; a view component dispatching `CustomEvent`s that a sibling or parent handles; an orchestrator file co-located with a view where routing complexity does not exceed schmancy's `.guard`+`@redirect` capability (i.e., the flow is a linear sequence with no branching or cross-route hand-off).
80
- - Remediation: move shared state into schmancy state signals; have each component read/write signals directly in render() and connectedCallback(); delete the orchestrator if its only job was to pass data down and receive events up.
79
+ **TYPOGRAPHY_NO_REDUNDANT_COLOR**
80
+ A `<schmancy-typography>` color class earns its place only by overriding the component's default render color. A `class` carrying `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any utility matching the default restates what the component already renders and is removed; a color class stays only when it intentionally diverges (`text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it was redundant.
81
81
 
82
- **TYPOGRAPHY_NO_REDUNDANT_COLOR** (`TYPOGRAPHY_NO_REDUNDANT_COLOR`). `schmancy-typography` color classes override the component's default rendering color.
82
+ **EVENTS_UP_PROPS_DOWN**
83
+ When two components genuinely cannot share a signal (a generic reusable component that must not import app state), user actions travel upward as `CustomEvent` dispatch and data travels downward as Lit property bindings — never as callable property bindings. A `.onXxx=${fn}` / `.handleXxx=${fn}` in a parent template is the violation; the child dispatches `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` and the parent binds `@xxx=${handler}`.
83
84
 
84
- - Detection signals: `class` attributes on `<schmancy-typography>` containing `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any other color utility that matches the component's default — these restate what the component already renders and add no information.
85
- - Remediation: remove the redundant color class from the `class` attribute. Keep a color class only when it intentionally overrides the default (e.g. `text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it is redundant.
85
+ **CONTROLLED_VALUE_ECHO_IS_NOT_INTENT**
86
+ A value-controlled `<schmancy-*>` component (`schmancy-steps`, `schmancy-input`, `schmancy-select`, `schmancy-switch`, `schmancy-tabs` any whose reference table documents its change event as firing on "property set or user interaction") emits that event on the consumer's own programmatic `.value=${…}` binding too, including the first-render echo. A `@change` handler reads intent as the delta between the event's value and the value currently driving the binding and early-returns on equality before any state write, so the component echoing a binding the consumer itself set never propagates as a user action.
86
87
 
87
- **EVENTS_UP_PROPS_DOWN** (cross-component communication when signals don't cover it)
88
- When two components genuinely cannot share a signal (e.g., a generic reusable component that must not import app state), user actions travel upward via `CustomEvent` dispatch and data travels downward via Lit property bindings — not via callable property bindings (`onXxx`, `handleXxx`) set on child elements.
89
-
90
- - Detection signals: `.onXxx=${fn}` or `.handleXxx=${fn}` callable property bindings in a parent template.
91
- - Remediation: dispatch `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` in the child; bind `@xxx=${handler}` in the parent.
88
+ ```ts
89
+ @change=${(e: CustomEvent<{ value: number }>) => {
90
+ const next = STEPS[e.detail.value - 1]
91
+ if (next.key === stepKey(currentStep.get())) return // programmatic echo of the step we already show — not a click
92
+ viewingStep.set(next.key)
93
+ }}
94
+ ```
92
95
 
93
96
  **State**
94
97
  - States live at module scope. Many small states beat one monolith. Use `state('feature/name').{memory,session,local,idb}(initial)` from `@mhmo91/schmancy/state`.
@@ -96,6 +99,9 @@ When two components genuinely cannot share a signal (e.g., a generic reusable co
96
99
  - `await state.ready` (or `if (state.loaded)`) before reading persisted-backend values that hydrate asynchronously.
97
100
  - Storage tiers: `.memory()` (regenerable) · `.session()` (per-tab) · `.local()` (user prefs) · `.idb()` (>100-entry collections).
98
101
 
102
+ **SIGNAL_TRACKING_BEYOND_RENDER**
103
+ A `SchmancyElement` makes any imperative side-effect reactive to signal changes by running it inside `this.updateEffect(fn, { manualDispose: true })`, which applies the same auto-tracking the component's `render()` receives to any arbitrary effect and returns a disposer for integration with the component's teardown path.
104
+
99
105
  **Routing**
100
106
  - Route guards are `Observable<boolean>`, never cached booleans.
101
107
  - `when="tag-name"` must exactly match `@customElement('tag-name')`.
@@ -14,17 +14,24 @@ import {
14
14
 
15
15
  ## The novel default — anchored
16
16
 
17
- When you're triggering an overlay from a user gesture (click, touch), pass the event as `anchor`. The overlay blooms from the point of attention instead of materializing at the viewport center.
17
+ Schmancy tracks the last user gesture automatically. When you call `show()` from a `@click` handler, the overlay positions itself near the interaction point without you passing anything:
18
18
 
19
19
  ```ts
20
- private handlePick = (ev: MouseEvent) => {
21
- show(TemplatePicker, { anchor: ev, props: { kind: 'email' } })
20
+ private handlePick = () => {
21
+ show(TemplatePicker, { props: { kind: 'email' } })
22
22
  .pipe(takeUntil(this.disconnecting))
23
23
  .subscribe(picked => { if (picked) this.template = picked })
24
24
  }
25
25
  ```
26
26
 
27
- Centered is the fallback (no anchor given). Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout the system does.
27
+ Pass `anchor` explicitly only when the gesture and the `show()` call are decoupled — e.g. the click fires in a child component but `show()` runs in a parent, or you're opening from a programmatic trigger with no gesture context:
28
+
29
+ ```ts
30
+ show(Picker, { anchor: ev }) // explicit — only when gesture context is lost
31
+ show(Picker) // idiomatic — gesture tracked automatically
32
+ ```
33
+
34
+ Centered is the fallback when there is genuinely no gesture context. Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout — the system does.
28
35
 
29
36
  ## Content forms
30
37
 
@@ -33,11 +40,11 @@ Centered is the fallback (no anchor given). Sheet is the responsive adaptation (
33
40
  | Form | When to use |
34
41
  |---|---|
35
42
  | `show(MyComponent)` | Component class — most common |
36
- | `show(html\`...\`)` | Inline template (eager — values frozen at call site) |
37
- | `show(() => html\`...\`)` | **Preferred for templates** — factory called at mount time; closed-over variables are read lazily, no snapshot staleness |
43
+ | `show(html\`...\`)` | Inline template (eager — a frozen one-shot snapshot, never re-renders) |
44
+ | `show(() => html\`...\`)` | **Reactive form** — factory re-invoked when any signal it reads changes (parity with a component's render()); closed-over variables always current |
38
45
  | `show(lazy(() => import('./x')))` | Async / code-split component |
39
46
 
40
- Always prefer `() => html\`...\`` over `html\`...\`` when the template closes over any variable — the factory form evaluates those variables at mount time rather than baking them in at the call site.
47
+ Always prefer `() => html\`...\`` over `html\`...\``: the factory form is reactive — the overlay re-runs it whenever a signal it reads changes, exactly like a component's `render()`. The eager `html\`...\`` form is a frozen snapshot captured at the call site and never updates. Bind `.value=${someState.value}` inside a factory and the overlay content tracks the state live.
41
48
 
42
49
  ## Default padding
43
50
 
@@ -74,21 +74,24 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
74
74
  - Register the tag in `HTMLElementTagNameMap` for TypeScript.
75
75
 
76
76
  **SIGNALS_ARE_THE_API**
77
- State signals are the integration layer between co-located Schmancy view components; each view component owns its IO directly and has zero property inputs and zero custom event outputs when state signals cover the shared state.
77
+ State signals are the integration layer between co-located Schmancy view components: each view component owns its IO directly and carries zero property inputs and zero custom-event outputs whenever a state signal covers the shared state. A `.property=${value}` input from a parent, a `CustomEvent` a sibling or parent handles, or a co-located orchestrator whose routing complexity does not exceed schmancy's `.guard`+`@redirect` (a linear flow, no branching, no cross-route hand-off) means that shared state belongs in a signal both components read and write directly in `render()`/`connectedCallback()`, and the orchestrator is deleted when passing data down and receiving events up was its only job.
78
78
 
79
- - Detection signals: a view component with `.property=${value}` inputs from a parent; a view component dispatching `CustomEvent`s that a sibling or parent handles; an orchestrator file co-located with a view where routing complexity does not exceed schmancy's `.guard`+`@redirect` capability (i.e., the flow is a linear sequence with no branching or cross-route hand-off).
80
- - Remediation: move shared state into schmancy state signals; have each component read/write signals directly in render() and connectedCallback(); delete the orchestrator if its only job was to pass data down and receive events up.
79
+ **TYPOGRAPHY_NO_REDUNDANT_COLOR**
80
+ A `<schmancy-typography>` color class earns its place only by overriding the component's default render color. A `class` carrying `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any utility matching the default restates what the component already renders and is removed; a color class stays only when it intentionally diverges (`text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it was redundant.
81
81
 
82
- **TYPOGRAPHY_NO_REDUNDANT_COLOR** (`TYPOGRAPHY_NO_REDUNDANT_COLOR`). `schmancy-typography` color classes override the component's default rendering color.
82
+ **EVENTS_UP_PROPS_DOWN**
83
+ When two components genuinely cannot share a signal (a generic reusable component that must not import app state), user actions travel upward as `CustomEvent` dispatch and data travels downward as Lit property bindings — never as callable property bindings. A `.onXxx=${fn}` / `.handleXxx=${fn}` in a parent template is the violation; the child dispatches `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` and the parent binds `@xxx=${handler}`.
83
84
 
84
- - Detection signals: `class` attributes on `<schmancy-typography>` containing `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any other color utility that matches the component's default — these restate what the component already renders and add no information.
85
- - Remediation: remove the redundant color class from the `class` attribute. Keep a color class only when it intentionally overrides the default (e.g. `text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it is redundant.
85
+ **CONTROLLED_VALUE_ECHO_IS_NOT_INTENT**
86
+ A value-controlled `<schmancy-*>` component (`schmancy-steps`, `schmancy-input`, `schmancy-select`, `schmancy-switch`, `schmancy-tabs` any whose reference table documents its change event as firing on "property set or user interaction") emits that event on the consumer's own programmatic `.value=${…}` binding too, including the first-render echo. A `@change` handler reads intent as the delta between the event's value and the value currently driving the binding and early-returns on equality before any state write, so the component echoing a binding the consumer itself set never propagates as a user action.
86
87
 
87
- **EVENTS_UP_PROPS_DOWN** (cross-component communication when signals don't cover it)
88
- When two components genuinely cannot share a signal (e.g., a generic reusable component that must not import app state), user actions travel upward via `CustomEvent` dispatch and data travels downward via Lit property bindings — not via callable property bindings (`onXxx`, `handleXxx`) set on child elements.
89
-
90
- - Detection signals: `.onXxx=${fn}` or `.handleXxx=${fn}` callable property bindings in a parent template.
91
- - Remediation: dispatch `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` in the child; bind `@xxx=${handler}` in the parent.
88
+ ```ts
89
+ @change=${(e: CustomEvent<{ value: number }>) => {
90
+ const next = STEPS[e.detail.value - 1]
91
+ if (next.key === stepKey(currentStep.get())) return // programmatic echo of the step we already show — not a click
92
+ viewingStep.set(next.key)
93
+ }}
94
+ ```
92
95
 
93
96
  **State**
94
97
  - States live at module scope. Many small states beat one monolith. Use `state('feature/name').{memory,session,local,idb}(initial)` from `@mhmo91/schmancy/state`.
@@ -96,6 +99,9 @@ When two components genuinely cannot share a signal (e.g., a generic reusable co
96
99
  - `await state.ready` (or `if (state.loaded)`) before reading persisted-backend values that hydrate asynchronously.
97
100
  - Storage tiers: `.memory()` (regenerable) · `.session()` (per-tab) · `.local()` (user prefs) · `.idb()` (>100-entry collections).
98
101
 
102
+ **SIGNAL_TRACKING_BEYOND_RENDER**
103
+ A `SchmancyElement` makes any imperative side-effect reactive to signal changes by running it inside `this.updateEffect(fn, { manualDispose: true })`, which applies the same auto-tracking the component's `render()` receives to any arbitrary effect and returns a disposer for integration with the component's teardown path.
104
+
99
105
  **Routing**
100
106
  - Route guards are `Observable<boolean>`, never cached booleans.
101
107
  - `when="tag-name"` must exactly match `@customElement('tag-name')`.
@@ -14,17 +14,24 @@ import {
14
14
 
15
15
  ## The novel default — anchored
16
16
 
17
- When you're triggering an overlay from a user gesture (click, touch), pass the event as `anchor`. The overlay blooms from the point of attention instead of materializing at the viewport center.
17
+ Schmancy tracks the last user gesture automatically. When you call `show()` from a `@click` handler, the overlay positions itself near the interaction point without you passing anything:
18
18
 
19
19
  ```ts
20
- private handlePick = (ev: MouseEvent) => {
21
- show(TemplatePicker, { anchor: ev, props: { kind: 'email' } })
20
+ private handlePick = () => {
21
+ show(TemplatePicker, { props: { kind: 'email' } })
22
22
  .pipe(takeUntil(this.disconnecting))
23
23
  .subscribe(picked => { if (picked) this.template = picked })
24
24
  }
25
25
  ```
26
26
 
27
- Centered is the fallback (no anchor given). Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout the system does.
27
+ Pass `anchor` explicitly only when the gesture and the `show()` call are decoupled — e.g. the click fires in a child component but `show()` runs in a parent, or you're opening from a programmatic trigger with no gesture context:
28
+
29
+ ```ts
30
+ show(Picker, { anchor: ev }) // explicit — only when gesture context is lost
31
+ show(Picker) // idiomatic — gesture tracked automatically
32
+ ```
33
+
34
+ Centered is the fallback when there is genuinely no gesture context. Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout — the system does.
28
35
 
29
36
  ## Content forms
30
37
 
@@ -33,11 +40,11 @@ Centered is the fallback (no anchor given). Sheet is the responsive adaptation (
33
40
  | Form | When to use |
34
41
  |---|---|
35
42
  | `show(MyComponent)` | Component class — most common |
36
- | `show(html\`...\`)` | Inline template (eager — values frozen at call site) |
37
- | `show(() => html\`...\`)` | **Preferred for templates** — factory called at mount time; closed-over variables are read lazily, no snapshot staleness |
43
+ | `show(html\`...\`)` | Inline template (eager — a frozen one-shot snapshot, never re-renders) |
44
+ | `show(() => html\`...\`)` | **Reactive form** — factory re-invoked when any signal it reads changes (parity with a component's render()); closed-over variables always current |
38
45
  | `show(lazy(() => import('./x')))` | Async / code-split component |
39
46
 
40
- Always prefer `() => html\`...\`` over `html\`...\`` when the template closes over any variable — the factory form evaluates those variables at mount time rather than baking them in at the call site.
47
+ Always prefer `() => html\`...\`` over `html\`...\``: the factory form is reactive — the overlay re-runs it whenever a signal it reads changes, exactly like a component's `render()`. The eager `html\`...\`` form is a frozen snapshot captured at the call site and never updates. Bind `.value=${someState.value}` inside a factory and the overlay content tracks the state live.
41
48
 
42
49
  ## Default padding
43
50