@mhmo91/schmancy 0.10.42 → 0.10.43

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 (759) hide show
  1. package/custom-elements.json +264 -79
  2. package/dist/SchmancyElement-CeKrBW2j.cjs +2 -0
  3. package/dist/SchmancyElement-CeKrBW2j.cjs.map +1 -0
  4. package/dist/SchmancyElement-Ob9yGkiG.js +286 -0
  5. package/dist/SchmancyElement-Ob9yGkiG.js.map +1 -0
  6. package/dist/agent/schmancy.agent.js +4031 -3891
  7. package/dist/agent/schmancy.agent.js.map +1 -1
  8. package/dist/agent/schmancy.manifest.json +215 -58
  9. package/dist/animation-CCOIW4wJ.cjs.map +1 -1
  10. package/dist/animation-DCznELuT.js.map +1 -1
  11. package/dist/area-CbajcnmJ.cjs +21 -0
  12. package/dist/area-CbajcnmJ.cjs.map +1 -0
  13. package/dist/{area-DtCNCb8w.js → area-MxLAyWgV.js} +22 -22
  14. package/dist/area-MxLAyWgV.js.map +1 -0
  15. package/dist/area.cjs +1 -1
  16. package/dist/area.js +1 -1
  17. package/dist/{audio-DdN76ikW.js → audio-B_0PGwYC.js} +1 -1
  18. package/dist/audio-B_0PGwYC.js.map +1 -0
  19. package/dist/{audio-B924fI5N.cjs → audio-CpwrIaw-.cjs} +1 -1
  20. package/dist/audio-CpwrIaw-.cjs.map +1 -0
  21. package/dist/audio.cjs +1 -1
  22. package/dist/audio.js +2 -2
  23. package/dist/autocomplete-CILzaDB7.cjs +115 -0
  24. package/dist/autocomplete-CILzaDB7.cjs.map +1 -0
  25. package/dist/{autocomplete-UNOknYUz.js → autocomplete-DV9RxCun.js} +113 -113
  26. package/dist/autocomplete-DV9RxCun.js.map +1 -0
  27. package/dist/autocomplete.cjs +1 -1
  28. package/dist/autocomplete.js +1 -1
  29. package/dist/avatar.cjs +1 -1
  30. package/dist/avatar.cjs.map +1 -1
  31. package/dist/avatar.js +4 -4
  32. package/dist/avatar.js.map +1 -1
  33. package/dist/badge.cjs +1 -1
  34. package/dist/badge.js +1 -1
  35. package/dist/{boat-BZah1Sf9.js → boat-DoZGgQ0P.js} +5 -5
  36. package/dist/{boat-BZah1Sf9.js.map → boat-DoZGgQ0P.js.map} +1 -1
  37. package/dist/{boat-D3bEjxf8.cjs → boat-sg0cWO8a.cjs} +2 -2
  38. package/dist/{boat-D3bEjxf8.cjs.map → boat-sg0cWO8a.cjs.map} +1 -1
  39. package/dist/boat.cjs +1 -1
  40. package/dist/boat.js +1 -1
  41. package/dist/breadcrumb.cjs +32 -31
  42. package/dist/breadcrumb.cjs.map +1 -1
  43. package/dist/breadcrumb.js +33 -32
  44. package/dist/breadcrumb.js.map +1 -1
  45. package/dist/busy-Brs-TDh9.cjs +133 -0
  46. package/dist/busy-Brs-TDh9.cjs.map +1 -0
  47. package/dist/busy-g4LoQmhB.js +172 -0
  48. package/dist/busy-g4LoQmhB.js.map +1 -0
  49. package/dist/busy.cjs +1 -1
  50. package/dist/busy.js +1 -1
  51. package/dist/{button-CTvS5YX4.cjs → button-Cml67Y_d.cjs} +41 -32
  52. package/dist/button-Cml67Y_d.cjs.map +1 -0
  53. package/dist/{button-DgoDfcJx.js → button-DWANpZfD.js} +43 -34
  54. package/dist/button-DWANpZfD.js.map +1 -0
  55. package/dist/button.cjs +40 -33
  56. package/dist/button.cjs.map +1 -1
  57. package/dist/button.js +42 -35
  58. package/dist/button.js.map +1 -1
  59. package/dist/calendar-2dJrw9pR.cjs +58 -0
  60. package/dist/calendar-2dJrw9pR.cjs.map +1 -0
  61. package/dist/calendar-kCe5LaBa.js +434 -0
  62. package/dist/calendar-kCe5LaBa.js.map +1 -0
  63. package/dist/calendar.cjs +1 -0
  64. package/dist/calendar.js +2 -0
  65. package/dist/{card-C6ijJZpF.js → card-CS_hYJbz.js} +136 -136
  66. package/dist/card-CS_hYJbz.js.map +1 -0
  67. package/dist/card-d0KhTnx5.cjs +177 -0
  68. package/dist/card-d0KhTnx5.cjs.map +1 -0
  69. package/dist/card.cjs +1 -1
  70. package/dist/card.js +1 -1
  71. package/dist/{checkbox-7vEPZuGC.js → checkbox-Bjp7kWuE.js} +2 -2
  72. package/dist/{checkbox-7vEPZuGC.js.map → checkbox-Bjp7kWuE.js.map} +1 -1
  73. package/dist/{checkbox-DXKdxkXE.cjs → checkbox-DZ2Wrz7Y.cjs} +1 -1
  74. package/dist/{checkbox-DXKdxkXE.cjs.map → checkbox-DZ2Wrz7Y.cjs.map} +1 -1
  75. package/dist/checkbox.cjs +1 -1
  76. package/dist/checkbox.js +1 -1
  77. package/dist/{chips-9eG-96_D.cjs → chips-BHBVkxsa.cjs} +142 -153
  78. package/dist/chips-BHBVkxsa.cjs.map +1 -0
  79. package/dist/{chips-DF7akwz7.js → chips-DACeW7YL.js} +127 -138
  80. package/dist/chips-DACeW7YL.js.map +1 -0
  81. package/dist/chips.cjs +1 -1
  82. package/dist/chips.js +2 -2
  83. package/dist/connectivity.cjs +53 -35
  84. package/dist/connectivity.cjs.map +1 -1
  85. package/dist/connectivity.js +55 -37
  86. package/dist/connectivity.js.map +1 -1
  87. package/dist/content-drawer.cjs +1 -1
  88. package/dist/content-drawer.js +1 -1
  89. package/dist/cursor-glow-Ah7VXSj7.js.map +1 -1
  90. package/dist/cursor-glow-Bulq-38P.cjs.map +1 -1
  91. package/dist/date-range-CVAWMdar.cjs +138 -0
  92. package/dist/date-range-CVAWMdar.cjs.map +1 -0
  93. package/dist/date-range-D2NZU5Yg.js +433 -0
  94. package/dist/date-range-D2NZU5Yg.js.map +1 -0
  95. package/dist/{date-range-inline-DV2c_gWM.cjs → date-range-inline-CGM0SPK9.cjs} +2 -4
  96. package/dist/date-range-inline-CGM0SPK9.cjs.map +1 -0
  97. package/dist/{date-range-inline-BnOD-ddB.js → date-range-inline-D6Ozerzw.js} +3 -5
  98. package/dist/date-range-inline-D6Ozerzw.js.map +1 -0
  99. package/dist/date-range-inline.cjs +1 -1
  100. package/dist/date-range-inline.js +1 -1
  101. package/dist/date-range.cjs +1 -1
  102. package/dist/date-range.js +2 -2
  103. package/dist/dayjs.min-CvRZTfam.cjs +1 -0
  104. package/dist/dayjs.min-CvRZTfam.cjs.map +1 -0
  105. package/dist/dayjs.min-DnELezPs.js +296 -0
  106. package/dist/dayjs.min-DnELezPs.js.map +1 -0
  107. package/dist/delay.cjs +1 -1
  108. package/dist/delay.js +3 -3
  109. package/dist/{details-ByF66CyY.js → details-Ct1_GwKr.js} +104 -93
  110. package/dist/details-Ct1_GwKr.js.map +1 -0
  111. package/dist/{details-B2-jECBh.cjs → details-D4fVOaj4.cjs} +109 -98
  112. package/dist/details-D4fVOaj4.cjs.map +1 -0
  113. package/dist/details.cjs +1 -1
  114. package/dist/details.js +1 -1
  115. package/dist/{directives-DCb_LA9R.cjs → directives-B2VxfwRL.cjs} +1 -1
  116. package/dist/directives-B2VxfwRL.cjs.map +1 -0
  117. package/dist/{directives-BL7mzVsA.js → directives-Dj8jlv-Q.js} +3 -3
  118. package/dist/directives-Dj8jlv-Q.js.map +1 -0
  119. package/dist/directives.cjs +1 -1
  120. package/dist/directives.js +2 -2
  121. package/dist/discovery.service-CIa3Eeuk.cjs.map +1 -1
  122. package/dist/discovery.service-DZFxtRwW.js.map +1 -1
  123. package/dist/divider-B3v33OnX.cjs +57 -0
  124. package/dist/divider-B3v33OnX.cjs.map +1 -0
  125. package/dist/divider-BJHW3q11.js +89 -0
  126. package/dist/divider-BJHW3q11.js.map +1 -0
  127. package/dist/divider.cjs +1 -1
  128. package/dist/divider.js +1 -1
  129. package/dist/dropdown.cjs +40 -40
  130. package/dist/dropdown.cjs.map +1 -1
  131. package/dist/dropdown.js +41 -41
  132. package/dist/dropdown.js.map +1 -1
  133. package/dist/{expand-cZ8rfCWP.js → expand-BT8mOu8Q.js} +103 -97
  134. package/dist/expand-BT8mOu8Q.js.map +1 -0
  135. package/dist/expand-D0YdR9nR.cjs +147 -0
  136. package/dist/expand-D0YdR9nR.cjs.map +1 -0
  137. package/dist/expand.cjs +1 -1
  138. package/dist/expand.js +1 -1
  139. package/dist/fab.cjs +1 -1
  140. package/dist/fab.cjs.map +1 -1
  141. package/dist/fab.js +2 -2
  142. package/dist/fab.js.map +1 -1
  143. package/dist/{float-DkGyWSWy.cjs → float-BPQlDyai.cjs} +1 -1
  144. package/dist/{float-DkGyWSWy.cjs.map → float-BPQlDyai.cjs.map} +1 -1
  145. package/dist/{float-zn3DgXBT.js → float-BQcxj3i_.js} +2 -2
  146. package/dist/{float-zn3DgXBT.js.map → float-BQcxj3i_.js.map} +1 -1
  147. package/dist/float.cjs +1 -1
  148. package/dist/float.js +1 -1
  149. package/dist/{form-DowzVsgI.cjs → form-CoWFnClb.cjs} +8 -13
  150. package/dist/form-CoWFnClb.cjs.map +1 -0
  151. package/dist/{form-tG7LwDm4.js → form-hC2LvCHX.js} +10 -15
  152. package/dist/form-hC2LvCHX.js.map +1 -0
  153. package/dist/form.cjs +12 -13
  154. package/dist/form.cjs.map +1 -1
  155. package/dist/form.js +23 -24
  156. package/dist/form.js.map +1 -1
  157. package/dist/gravity-6pL6CfIr.cjs.map +1 -1
  158. package/dist/gravity-sVK3zGBF.js.map +1 -1
  159. package/dist/handover/agent-runtime-followups.md +1 -1
  160. package/dist/handover/agent-runtime-v1.md +3 -3
  161. package/dist/{hashContent-iRZJJWtE.cjs.map → hashContent--s09Ed_g.cjs.map} +1 -1
  162. package/dist/{hashContent-BqU6v1Xr.js.map → hashContent-CAvrQ56N.js.map} +1 -1
  163. package/dist/icons-BeGKDZ-k.cjs +22 -0
  164. package/dist/icons-BeGKDZ-k.cjs.map +1 -0
  165. package/dist/{icons-Dup5skuk.js → icons-DEJnIxml.js} +20 -22
  166. package/dist/icons-DEJnIxml.js.map +1 -0
  167. package/dist/icons.cjs +1 -1
  168. package/dist/icons.js +1 -1
  169. package/dist/{iframe-CDJjnNmo.cjs → iframe-BkSukM9C.cjs} +9 -9
  170. package/dist/iframe-BkSukM9C.cjs.map +1 -0
  171. package/dist/{iframe-Xc3EPMZT.js → iframe-V3S-bwEY.js} +10 -10
  172. package/dist/iframe-V3S-bwEY.js.map +1 -0
  173. package/dist/iframe.cjs +1 -1
  174. package/dist/iframe.js +1 -1
  175. package/dist/index.cjs +1 -1
  176. package/dist/index.js +61 -60
  177. package/dist/{input-cTyDxW9L.js → input-CPFCSQld.js} +3 -10
  178. package/dist/input-CPFCSQld.js.map +1 -0
  179. package/dist/{input-DnmC6J1T.cjs → input-DSfwfhhj.cjs} +2 -9
  180. package/dist/input-DSfwfhhj.cjs.map +1 -0
  181. package/dist/input-chip-BUuFJUky.cjs +129 -0
  182. package/dist/input-chip-BUuFJUky.cjs.map +1 -0
  183. package/dist/{input-chip-CYI17YOq.js → input-chip-C3a1fwKB.js} +87 -104
  184. package/dist/input-chip-C3a1fwKB.js.map +1 -0
  185. package/dist/input.cjs +1 -1
  186. package/dist/input.js +1 -1
  187. package/dist/json.cjs +5 -1
  188. package/dist/json.cjs.map +1 -1
  189. package/dist/json.js +8 -4
  190. package/dist/json.js.map +1 -1
  191. package/dist/kbd.cjs +28 -28
  192. package/dist/kbd.cjs.map +1 -1
  193. package/dist/kbd.js +29 -29
  194. package/dist/kbd.js.map +1 -1
  195. package/dist/{layout-CNlZSJFU.cjs → layout-CdyHy_oX.cjs} +1 -1
  196. package/dist/layout-CdyHy_oX.cjs.map +1 -0
  197. package/dist/{layout-DDxw0EwL.js → layout-k6fOkpif.js} +1 -1
  198. package/dist/layout-k6fOkpif.js.map +1 -0
  199. package/dist/layout.cjs +26 -26
  200. package/dist/layout.cjs.map +1 -1
  201. package/dist/layout.js +27 -27
  202. package/dist/layout.js.map +1 -1
  203. package/dist/lazy-BaAiIUru.js.map +1 -1
  204. package/dist/lazy-C-7a4FAe.cjs.map +1 -1
  205. package/dist/{lightbox-CH-y3rYB.js → lightbox-DIG0VLOK.js} +8 -14
  206. package/dist/lightbox-DIG0VLOK.js.map +1 -0
  207. package/dist/{lightbox-CvtqoInF.cjs → lightbox-E5rgd-hu.cjs} +7 -13
  208. package/dist/lightbox-E5rgd-hu.cjs.map +1 -0
  209. package/dist/lightbox.cjs +1 -1
  210. package/dist/lightbox.js +1 -1
  211. package/dist/list-BRz0rDSH.cjs +47 -0
  212. package/dist/list-BRz0rDSH.cjs.map +1 -0
  213. package/dist/{list-DrsawQ5R.js → list-NrOYDPBo.js} +42 -35
  214. package/dist/list-NrOYDPBo.js.map +1 -0
  215. package/dist/list.cjs +1 -1
  216. package/dist/list.js +1 -1
  217. package/dist/magnetic-DKtc4umC.cjs.map +1 -1
  218. package/dist/magnetic-DaOOv5Dz.js.map +1 -1
  219. package/dist/{menu-CsY5lMqY.js → menu-B1Ei9SVj.js} +12 -12
  220. package/dist/menu-B1Ei9SVj.js.map +1 -0
  221. package/dist/{menu-BFRcTe3o.cjs → menu-Duvl66Nl.cjs} +10 -10
  222. package/dist/menu-Duvl66Nl.cjs.map +1 -0
  223. package/dist/menu.cjs +1 -1
  224. package/dist/menu.js +1 -1
  225. package/dist/{mixins-BoMURWag.cjs → mixins-Cjn20BQH.cjs} +42 -100
  226. package/dist/mixins-Cjn20BQH.cjs.map +1 -0
  227. package/dist/{mixins-bCEXbwJV.js → mixins-q4KAL8Xr.js} +42 -100
  228. package/dist/mixins-q4KAL8Xr.js.map +1 -0
  229. package/dist/mixins.cjs +1 -1
  230. package/dist/mixins.js +2 -2
  231. package/dist/nav-drawer.cjs +1 -1
  232. package/dist/nav-drawer.js +1 -1
  233. package/dist/navigation-bar.cjs +1 -1
  234. package/dist/navigation-bar.js +1 -1
  235. package/dist/navigation-rail.cjs +2 -4
  236. package/dist/navigation-rail.cjs.map +1 -1
  237. package/dist/navigation-rail.js +3 -5
  238. package/dist/navigation-rail.js.map +1 -1
  239. package/dist/{notification-DFKRMmSq.js → notification-COhUhUCr.js} +5 -7
  240. package/dist/notification-COhUhUCr.js.map +1 -0
  241. package/dist/{notification-FBf3Mb2e.cjs → notification-DsdA_MJe.cjs} +2 -4
  242. package/dist/notification-DsdA_MJe.cjs.map +1 -0
  243. package/dist/notification.cjs +1 -1
  244. package/dist/notification.js +1 -1
  245. package/dist/{option-Ct0lGdH3.js → option-BIzgTbXz.js} +20 -20
  246. package/dist/option-BIzgTbXz.js.map +1 -0
  247. package/dist/option-C5hhqR2z.cjs +43 -0
  248. package/dist/option-C5hhqR2z.cjs.map +1 -0
  249. package/dist/option.cjs +1 -1
  250. package/dist/option.js +1 -1
  251. package/dist/{overlay-sRXiMkjn.cjs → overlay-BzgF8P7i.cjs} +48 -41
  252. package/dist/overlay-BzgF8P7i.cjs.map +1 -0
  253. package/dist/{overlay-Bh8Q_R01.js → overlay-LoRRemny.js} +52 -45
  254. package/dist/overlay-LoRRemny.js.map +1 -0
  255. package/dist/overlay-stack-Bdr9lOqi.cjs.map +1 -1
  256. package/dist/overlay-stack-D2rgxQLh.js.map +1 -1
  257. package/dist/overlay.cjs +1 -1
  258. package/dist/{overlay.confirm-body-CQihsR20.js → overlay.confirm-body-D0b1MoCw.js} +30 -45
  259. package/dist/overlay.confirm-body-D0b1MoCw.js.map +1 -0
  260. package/dist/{overlay.confirm-body-Jc1EuMGs.cjs → overlay.confirm-body-DCneq73Z.cjs} +22 -37
  261. package/dist/overlay.confirm-body-DCneq73Z.cjs.map +1 -0
  262. package/dist/overlay.js +3 -3
  263. package/dist/{overlay.service-BXPgS7ay.js → overlay.service-BuUeti6X.js} +2 -2
  264. package/dist/overlay.service-BuUeti6X.js.map +1 -0
  265. package/dist/{overlay.service-9Dp3g7ot.cjs → overlay.service-MMTiW2T3.cjs} +1 -1
  266. package/dist/overlay.service-MMTiW2T3.cjs.map +1 -0
  267. package/dist/{progress-CYLshdo2.js → progress-D7n3SKAO.js} +50 -50
  268. package/dist/progress-D7n3SKAO.js.map +1 -0
  269. package/dist/progress-DsCnFsH5.cjs +51 -0
  270. package/dist/progress-DsCnFsH5.cjs.map +1 -0
  271. package/dist/progress.cjs +1 -1
  272. package/dist/progress.js +1 -1
  273. package/dist/{radio-group-6kCgOgBL.cjs → radio-group-CaAjg9UV.cjs} +1 -1
  274. package/dist/radio-group-CaAjg9UV.cjs.map +1 -0
  275. package/dist/{radio-group-bZtZHOj_.js → radio-group-Drpl6Pl8.js} +2 -2
  276. package/dist/radio-group-Drpl6Pl8.js.map +1 -0
  277. package/dist/radio-group.cjs +1 -1
  278. package/dist/radio-group.js +1 -1
  279. package/dist/range.cjs +4 -2
  280. package/dist/range.cjs.map +1 -1
  281. package/dist/range.js +5 -3
  282. package/dist/range.js.map +1 -1
  283. package/dist/reduced-motion-D-L12p7G.js.map +1 -1
  284. package/dist/reduced-motion-Ds-HjMzn.cjs.map +1 -1
  285. package/dist/{rxjs-utils-Csnks202.cjs.map → rxjs-utils-4P2v57ke.cjs.map} +1 -1
  286. package/dist/{rxjs-utils-d-ivVN84.js.map → rxjs-utils-JMFdgQSl.js.map} +1 -1
  287. package/dist/rxjs-utils.cjs +1 -1
  288. package/dist/rxjs-utils.js +1 -1
  289. package/dist/search-DPKoC-dT.cjs.map +1 -1
  290. package/dist/search-MvIBA93K.js.map +1 -1
  291. package/dist/{select-CU3X-PIa.js → select-CTXkrrVZ.js} +13 -13
  292. package/dist/select-CTXkrrVZ.js.map +1 -0
  293. package/dist/select-DcLcpPCh.cjs +56 -0
  294. package/dist/select-DcLcpPCh.cjs.map +1 -0
  295. package/dist/select.cjs +1 -1
  296. package/dist/select.js +1 -1
  297. package/dist/skeleton.cjs +37 -33
  298. package/dist/skeleton.cjs.map +1 -1
  299. package/dist/skeleton.js +38 -34
  300. package/dist/skeleton.js.map +1 -1
  301. package/dist/skills/schmancy/surface.md +38 -22
  302. package/dist/skills/surface.md +38 -22
  303. package/dist/slider.cjs +31 -31
  304. package/dist/slider.cjs.map +1 -1
  305. package/dist/slider.js +32 -32
  306. package/dist/slider.js.map +1 -1
  307. package/dist/{sound.service-B4ZmXpH9.js → sound.service-AJwuk3yr.js} +1 -1
  308. package/dist/sound.service-AJwuk3yr.js.map +1 -0
  309. package/dist/{sound.service-DjlMvicQ.cjs → sound.service-CVsxhQkX.cjs} +1 -1
  310. package/dist/sound.service-CVsxhQkX.cjs.map +1 -0
  311. package/dist/{splash-screen-emCLYoVl.js → splash-screen-DANfqvlo.js} +23 -26
  312. package/dist/splash-screen-DANfqvlo.js.map +1 -0
  313. package/dist/splash-screen-K74cgU6S.cjs +38 -0
  314. package/dist/splash-screen-K74cgU6S.cjs.map +1 -0
  315. package/dist/splash-screen.cjs +1 -1
  316. package/dist/splash-screen.js +1 -1
  317. package/dist/{src-DGDTkOvC.js → src-DAtcPmCb.js} +173 -175
  318. package/dist/src-DAtcPmCb.js.map +1 -0
  319. package/dist/src-DuRvYagm.cjs +237 -0
  320. package/dist/src-DuRvYagm.cjs.map +1 -0
  321. package/dist/{state-CumAEPQH.cjs → state-BWQiqN6I.cjs} +1 -1
  322. package/dist/state-BWQiqN6I.cjs.map +1 -0
  323. package/dist/{state-DMd_FUeA.js → state-DBA_gzJO.js} +1 -1
  324. package/dist/state-DBA_gzJO.js.map +1 -0
  325. package/dist/state.cjs +1 -1
  326. package/dist/state.js +2 -2
  327. package/dist/steps.cjs +20 -12
  328. package/dist/steps.cjs.map +1 -1
  329. package/dist/steps.js +21 -13
  330. package/dist/steps.js.map +1 -1
  331. package/dist/surface-COBvWWFb.cjs +7 -0
  332. package/dist/surface-COBvWWFb.cjs.map +1 -0
  333. package/dist/{surface-DNiYigsX.js → surface-DXk1X1tL.js} +9 -9
  334. package/dist/{surface-DNiYigsX.js.map → surface-DXk1X1tL.js.map} +1 -1
  335. package/dist/surface.cjs +1 -1
  336. package/dist/surface.js +1 -1
  337. package/dist/switch.cjs +13 -4
  338. package/dist/switch.cjs.map +1 -1
  339. package/dist/switch.js +14 -5
  340. package/dist/switch.js.map +1 -1
  341. package/dist/table.cjs +4 -10
  342. package/dist/table.cjs.map +1 -1
  343. package/dist/table.js +5 -11
  344. package/dist/table.js.map +1 -1
  345. package/dist/{tabs-4T_4kCf-.js → tabs-BYhFWnsx.js} +7 -7
  346. package/dist/tabs-BYhFWnsx.js.map +1 -0
  347. package/dist/{tabs-Byxxt-AH.cjs → tabs-CJwB0fr0.cjs} +6 -6
  348. package/dist/tabs-CJwB0fr0.cjs.map +1 -0
  349. package/dist/tabs.cjs +1 -1
  350. package/dist/tabs.js +1 -1
  351. package/dist/teleport.cjs +1 -1
  352. package/dist/teleport.js +1 -1
  353. package/dist/{textarea-kkYNk1ET.js → textarea-BjDx1w2g.js} +37 -41
  354. package/dist/textarea-BjDx1w2g.js.map +1 -0
  355. package/dist/{textarea-BwYwH9fu.cjs → textarea-CGgznhd6.cjs} +36 -40
  356. package/dist/textarea-CGgznhd6.cjs.map +1 -0
  357. package/dist/textarea.cjs +1 -1
  358. package/dist/textarea.js +1 -1
  359. package/dist/{theme-BG0EnzYP.cjs → theme-BVul7lHS.cjs} +6 -6
  360. package/dist/{theme-BG0EnzYP.cjs.map → theme-BVul7lHS.cjs.map} +1 -1
  361. package/dist/{theme-DwQBl6sr.js → theme-Dvm5J8nh.js} +11 -11
  362. package/dist/{theme-DwQBl6sr.js.map → theme-Dvm5J8nh.js.map} +1 -1
  363. package/dist/{theme-button-BD8anzsZ.js → theme-button-Bko5ohFP.js} +2 -2
  364. package/dist/{theme-button-BD8anzsZ.js.map → theme-button-Bko5ohFP.js.map} +1 -1
  365. package/dist/{theme-button-DlrNoCMA.cjs → theme-button-YLY7zR1c.cjs} +1 -1
  366. package/dist/{theme-button-DlrNoCMA.cjs.map → theme-button-YLY7zR1c.cjs.map} +1 -1
  367. package/dist/theme-button.cjs +1 -1
  368. package/dist/theme-button.js +1 -1
  369. package/dist/theme.cjs +1 -1
  370. package/dist/{theme.interface-CSt7JUBD.cjs.map → theme.interface-B-qxDsZQ.cjs.map} +1 -1
  371. package/dist/{theme.interface-odQEpZZH.js.map → theme.interface-B7caS5cg.js.map} +1 -1
  372. package/dist/theme.js +4 -4
  373. package/dist/{theme.service-Dv_55nfE.js → theme.service-D94nm7Bf.js} +1 -1
  374. package/dist/theme.service-D94nm7Bf.js.map +1 -0
  375. package/dist/{theme.service-pjkTM209.cjs → theme.service-h2fXQq7x.cjs} +1 -1
  376. package/dist/theme.service-h2fXQq7x.cjs.map +1 -0
  377. package/dist/tooltip.cjs.map +1 -1
  378. package/dist/tooltip.js.map +1 -1
  379. package/dist/tree.cjs +14 -14
  380. package/dist/tree.cjs.map +1 -1
  381. package/dist/tree.js +15 -15
  382. package/dist/tree.js.map +1 -1
  383. package/dist/types.cjs +1 -1
  384. package/dist/types.cjs.map +1 -1
  385. package/dist/types.js +19 -2
  386. package/dist/types.js.map +1 -1
  387. package/dist/typewriter.cjs.map +1 -1
  388. package/dist/typewriter.js.map +1 -1
  389. package/dist/typography-ByF2k5yW.js +358 -0
  390. package/dist/typography-ByF2k5yW.js.map +1 -0
  391. package/dist/typography-Cfav17it.cjs +282 -0
  392. package/dist/typography-Cfav17it.cjs.map +1 -0
  393. package/dist/typography.cjs +1 -1
  394. package/dist/typography.js +1 -1
  395. package/dist/utils-DIXndz6Q.cjs.map +1 -0
  396. package/dist/utils-dSPH7Oh9.js.map +1 -0
  397. package/dist/utils.cjs +1 -1
  398. package/dist/utils.js +1 -1
  399. package/dist/visually-hidden.cjs +13 -13
  400. package/dist/visually-hidden.cjs.map +1 -1
  401. package/dist/visually-hidden.js +14 -14
  402. package/dist/visually-hidden.js.map +1 -1
  403. package/dist/window-Br1OmpL-.cjs +67 -0
  404. package/dist/window-Br1OmpL-.cjs.map +1 -0
  405. package/dist/{window-C76zstbV.js → window-CCmN4but.js} +24 -15
  406. package/dist/window-CCmN4but.js.map +1 -0
  407. package/dist/window.cjs +1 -1
  408. package/dist/window.js +1 -1
  409. package/package.json +1 -1
  410. package/skills/schmancy/surface.md +38 -22
  411. package/src/area/area.component.ts +249 -163
  412. package/src/area/area.service.test.ts +994 -1006
  413. package/src/area/area.service.ts +76 -72
  414. package/src/area/index.ts +7 -7
  415. package/src/area/lazy.ts +39 -42
  416. package/src/area/route.component.ts +54 -52
  417. package/src/area/router.types.ts +7 -7
  418. package/src/audio/emotional-sounds.ts +880 -801
  419. package/src/audio/sound.service.ts +26 -5
  420. package/src/avatar/avatar.ts +4 -4
  421. package/src/badge/badge.ts +15 -12
  422. package/src/badge/index.ts +1 -1
  423. package/src/boat/boat.ts +1 -1
  424. package/src/breadcrumb/breadcrumb.ts +37 -32
  425. package/src/busy/busy.ts +15 -12
  426. package/src/busy/index.ts +2 -2
  427. package/src/busy/spinner.ts +132 -119
  428. package/src/button/button.test.ts +5 -1
  429. package/src/button/button.ts +113 -72
  430. package/src/button/icon-button.ts +64 -46
  431. package/src/button/index.ts +2 -2
  432. package/src/calendar/calendar.test.ts +504 -0
  433. package/src/calendar/calendar.ts +587 -0
  434. package/src/calendar/index.ts +2 -0
  435. package/src/card/actions.ts +11 -9
  436. package/src/card/card.ts +79 -77
  437. package/src/card/content.ts +8 -6
  438. package/src/card/index.ts +4 -4
  439. package/src/card/media.ts +50 -50
  440. package/src/chips/assist-chip.ts +1 -1
  441. package/src/chips/chips.ts +1 -1
  442. package/src/chips/filter-chip.ts +1 -1
  443. package/src/chips/index.ts +1 -1
  444. package/src/chips/input-chip.ts +1 -1
  445. package/src/chips/suggestion-chip.ts +1 -1
  446. package/src/connectivity/connectivity-status.ts +90 -62
  447. package/src/content-drawer/drawer.service.ts +47 -36
  448. package/src/content-drawer/drawer.ts +31 -18
  449. package/src/content-drawer/index.ts +5 -5
  450. package/src/content-drawer/main.ts +9 -7
  451. package/src/content-drawer/sheet.ts +8 -6
  452. package/src/date-range-inline/date-range-inline.ts +523 -522
  453. package/src/date-range-inline/index.ts +2 -2
  454. package/src/delay/index.ts +1 -1
  455. package/src/details/details.ts +119 -105
  456. package/src/details/index.ts +1 -1
  457. package/src/directives/ai-badge.ts +1 -5
  458. package/src/directives/animate-text.ts +43 -31
  459. package/src/directives/art/effects/howl.ts +1 -4
  460. package/src/directives/art/effects/samwa.ts +11 -5
  461. package/src/directives/art/effects/snow.ts +1 -2
  462. package/src/directives/battery.ts +21 -12
  463. package/src/directives/confirm-click.ts +9 -17
  464. package/src/directives/cursor-glow.ts +1 -1
  465. package/src/directives/cycle-text.ts +7 -21
  466. package/src/directives/drag.ts +50 -45
  467. package/src/directives/fyi.ts +1 -6
  468. package/src/directives/gravity.ts +10 -8
  469. package/src/directives/hummingbird.ts +256 -107
  470. package/src/directives/index.ts +29 -29
  471. package/src/directives/intersect.ts +11 -11
  472. package/src/directives/layout.ts +25 -36
  473. package/src/directives/liquid.ts +4 -10
  474. package/src/directives/living-border.ts +7 -5
  475. package/src/directives/long-press.ts +2 -1
  476. package/src/directives/magnetic.ts +7 -6
  477. package/src/directives/nebula.ts +34 -28
  478. package/src/directives/overflow-within.ts +18 -20
  479. package/src/directives/reduced-motion.ts +9 -9
  480. package/src/directives/reveal.ts +193 -195
  481. package/src/directives/ripple.ts +9 -7
  482. package/src/directives/urgent.ts +3 -1
  483. package/src/directives/working-snake.ts +1 -1
  484. package/src/discovery/discovery.service.ts +198 -210
  485. package/src/discovery/index.ts +1 -1
  486. package/src/divider/divider.ts +49 -47
  487. package/src/divider/index.ts +1 -1
  488. package/src/dropdown/dropdown-content.ts +42 -40
  489. package/src/dropdown/index.ts +2 -2
  490. package/src/expand/expand-root.component.ts +70 -61
  491. package/src/expand/expand.component.ts +48 -43
  492. package/src/fab/fab.test.ts +1 -2
  493. package/src/fab/fab.ts +2 -4
  494. package/src/form/fields/autocomplete/autocomplete.scss +6 -2
  495. package/src/form/fields/autocomplete/autocomplete.ts +712 -724
  496. package/src/form/fields/autocomplete/index.ts +1 -1
  497. package/src/form/fields/checkbox/checkbox.ts +1 -4
  498. package/src/form/fields/chips/assist-chip.ts +69 -72
  499. package/src/form/fields/chips/chips.ts +14 -15
  500. package/src/form/fields/chips/filter-chip.ts +36 -32
  501. package/src/form/fields/chips/index.ts +5 -5
  502. package/src/form/fields/chips/input-chip.ts +130 -142
  503. package/src/form/fields/chips/suggestion-chip.ts +69 -72
  504. package/src/form/fields/date-range/date-range-dialog.ts +141 -194
  505. package/src/form/fields/date-range/date-range-helpers.ts +63 -64
  506. package/src/form/fields/date-range/date-range.test.ts +359 -122
  507. package/src/form/fields/date-range/date-range.ts +319 -395
  508. package/src/form/fields/date-range/index.ts +2 -2
  509. package/src/form/fields/input/index.ts +8 -8
  510. package/src/form/fields/input/input.scss +30 -26
  511. package/src/form/fields/input/input.test.ts +4 -1
  512. package/src/form/fields/input/input.ts +4 -20
  513. package/src/form/fields/radio-group/index.ts +2 -2
  514. package/src/form/fields/radio-group/radio-button.ts +8 -8
  515. package/src/form/fields/radio-group/radio-group.ts +4 -1
  516. package/src/form/fields/range/range.ts +3 -1
  517. package/src/form/fields/select/index.ts +2 -2
  518. package/src/form/fields/select/select.ts +51 -45
  519. package/src/form/fields/switch/switch.ts +13 -7
  520. package/src/form/fields/textarea/index.ts +1 -1
  521. package/src/form/fields/textarea/textarea.ts +44 -49
  522. package/src/form/form-summary.ts +15 -14
  523. package/src/form/form.test.ts +0 -1
  524. package/src/form/form.ts +11 -23
  525. package/src/icons/icon.ts +25 -25
  526. package/src/icons/index.ts +1 -1
  527. package/src/iframe/iframe.ts +11 -9
  528. package/src/index.ts +1 -0
  529. package/src/json/json.ts +9 -2
  530. package/src/kbd/kbd.ts +30 -28
  531. package/src/layout/scroll/index.ts +1 -1
  532. package/src/layout/scroll/scroll.ts +54 -54
  533. package/src/lightbox/lightbox-service.ts +27 -18
  534. package/src/lightbox/lightbox.directive.ts +2 -1
  535. package/src/lightbox/lightbox.ts +21 -38
  536. package/src/list/index.ts +3 -3
  537. package/src/list/list-item.ts +32 -26
  538. package/src/list/list.ts +13 -8
  539. package/src/menu/index.ts +2 -2
  540. package/src/menu/menu-item.ts +7 -5
  541. package/src/menu/menu.ts +8 -6
  542. package/src/nav-drawer/appbar.ts +9 -7
  543. package/src/nav-drawer/content.ts +10 -8
  544. package/src/nav-drawer/drawer.ts +29 -25
  545. package/src/nav-drawer/index.ts +6 -6
  546. package/src/navigation-bar/index.ts +2 -2
  547. package/src/navigation-bar/navigation-bar-item.ts +127 -118
  548. package/src/navigation-bar/navigation-bar.ts +103 -91
  549. package/src/navigation-rail/index.ts +2 -2
  550. package/src/navigation-rail/navigation-rail.ts +21 -22
  551. package/src/notification/index.ts +6 -6
  552. package/src/notification/notification-service.ts +1 -2
  553. package/src/notification/notification.scss +5 -1
  554. package/src/notification/notification.ts +1 -3
  555. package/src/notification/notify.ts +204 -207
  556. package/src/option/index.ts +1 -1
  557. package/src/option/option.ts +26 -25
  558. package/src/overlay/overlay.animations.ts +4 -14
  559. package/src/overlay/overlay.component.ts +110 -131
  560. package/src/overlay/overlay.confirm-body.ts +26 -48
  561. package/src/overlay/overlay.gestures.ts +8 -10
  562. package/src/overlay/overlay.layout.ts +1 -4
  563. package/src/overlay/overlay.positioning.ts +4 -15
  564. package/src/overlay/overlay.service.ts +9 -24
  565. package/src/overlay/overlay.stack.test.ts +4 -1
  566. package/src/overlay/overlay.stack.ts +4 -4
  567. package/src/overlay/overlay.types.ts +11 -20
  568. package/src/progress/index.ts +1 -1
  569. package/src/progress/progress.ts +135 -133
  570. package/src/rxjs-utils/index.ts +6 -6
  571. package/src/rxjs-utils/waitForElement.ts +20 -20
  572. package/src/rxjs-utils/waitForElementAll.ts +21 -21
  573. package/src/rxjs-utils/waitForElements.ts +27 -27
  574. package/src/rxjs-utils/waitForElementsAll.ts +27 -29
  575. package/src/rxjs-utils/waitUntil.ts +7 -12
  576. package/src/skeleton/skeleton.ts +39 -33
  577. package/src/slider/index.ts +2 -2
  578. package/src/slider/slide.ts +14 -12
  579. package/src/slider/slider.ts +24 -22
  580. package/src/splash-screen/index.ts +1 -1
  581. package/src/splash-screen/splash-screen.ts +26 -27
  582. package/src/state/active-host.ts +4 -5
  583. package/src/state/index.ts +34 -53
  584. package/src/state/persist.ts +14 -11
  585. package/src/state/schmancy-context.ts +88 -88
  586. package/src/state/state.test-d.ts +3 -13
  587. package/src/state/state.test.ts +1 -4
  588. package/src/steps/index.ts +3 -3
  589. package/src/steps/schmancy-step.ts +41 -31
  590. package/src/steps/schmancy-steps.ts +7 -5
  591. package/src/surface/index.ts +1 -1
  592. package/src/surface/surface.styles.ts +53 -104
  593. package/src/surface/surface.ts +10 -8
  594. package/src/table/index.ts +2 -2
  595. package/src/table/row.ts +1 -4
  596. package/src/table/table.ts +2 -5
  597. package/src/tabs/index.ts +2 -2
  598. package/src/tabs/tabs-group.ts +8 -6
  599. package/src/teleport/index.ts +2 -2
  600. package/src/test-utils/a11y.ts +1 -3
  601. package/src/theme/index.ts +17 -17
  602. package/src/theme/theme-audio-player.ts +18 -16
  603. package/src/theme/theme-controller-boat.ts +1 -1
  604. package/src/theme/theme-controller.ts +36 -32
  605. package/src/theme/theme.component.ts +5 -9
  606. package/src/theme/theme.events.ts +1 -1
  607. package/src/theme/theme.format.ts +7 -7
  608. package/src/theme/theme.service.ts +453 -468
  609. package/src/theme/theme.style.css +78 -23
  610. package/src/theme-button/index.ts +1 -1
  611. package/src/tooltip/tooltip.directive.ts +1 -1
  612. package/src/tree/index.ts +1 -1
  613. package/src/tree/tree.ts +24 -16
  614. package/src/types/surface.ts +38 -44
  615. package/src/typewriter/typewriter.directive.ts +30 -39
  616. package/src/typography/typography.ts +289 -269
  617. package/src/utils/animation.ts +2 -8
  618. package/src/utils/index.ts +6 -6
  619. package/src/utils/number.ts +480 -517
  620. package/src/utils/overlay-stack.ts +1 -3
  621. package/src/utils/search.ts +5 -9
  622. package/src/visually-hidden/visually-hidden.ts +15 -13
  623. package/src/window/window-manager.ts +6 -1
  624. package/src/window/window-position.ts +7 -5
  625. package/src/window/window.ts +143 -108
  626. package/types/src/calendar/calendar.d.ts +108 -0
  627. package/types/src/calendar/calendar.test.d.ts +1 -0
  628. package/types/src/calendar/index.d.ts +2 -0
  629. package/types/src/directives/cursor-glow.d.ts +1 -1
  630. package/types/src/directives/hummingbird.d.ts +3 -3
  631. package/types/src/form/fields/date-range/date-range-dialog.d.ts +24 -28
  632. package/types/src/form/fields/date-range/date-range.d.ts +35 -66
  633. package/types/src/form/fields/date-range/date-range.test.d.ts +1 -0
  634. package/types/src/form/fields/date-range/index.d.ts +1 -1
  635. package/types/src/index.d.ts +1 -0
  636. package/types/src/surface/surface.styles.d.ts +13 -6
  637. package/types/src/types/surface.d.ts +17 -22
  638. package/types/src/utils/number.d.ts +1 -1
  639. package/dist/SchmancyElement-OG71FtNv.js +0 -286
  640. package/dist/SchmancyElement-OG71FtNv.js.map +0 -1
  641. package/dist/SchmancyElement-PS1u0j1B.cjs +0 -2
  642. package/dist/SchmancyElement-PS1u0j1B.cjs.map +0 -1
  643. package/dist/area-CaEI33G0.cjs +0 -21
  644. package/dist/area-CaEI33G0.cjs.map +0 -1
  645. package/dist/area-DtCNCb8w.js.map +0 -1
  646. package/dist/audio-B924fI5N.cjs.map +0 -1
  647. package/dist/audio-DdN76ikW.js.map +0 -1
  648. package/dist/autocomplete-Dq3BkitV.cjs +0 -115
  649. package/dist/autocomplete-Dq3BkitV.cjs.map +0 -1
  650. package/dist/autocomplete-UNOknYUz.js.map +0 -1
  651. package/dist/busy--WqiXKnl.cjs +0 -134
  652. package/dist/busy--WqiXKnl.cjs.map +0 -1
  653. package/dist/busy-DzXyO0z6.js +0 -173
  654. package/dist/busy-DzXyO0z6.js.map +0 -1
  655. package/dist/button-CTvS5YX4.cjs.map +0 -1
  656. package/dist/button-DgoDfcJx.js.map +0 -1
  657. package/dist/card-C6ijJZpF.js.map +0 -1
  658. package/dist/card-Ci3_9Dd4.cjs +0 -177
  659. package/dist/card-Ci3_9Dd4.cjs.map +0 -1
  660. package/dist/chips-9eG-96_D.cjs.map +0 -1
  661. package/dist/chips-DF7akwz7.js.map +0 -1
  662. package/dist/date-range-C13_R3OA.js +0 -966
  663. package/dist/date-range-C13_R3OA.js.map +0 -1
  664. package/dist/date-range-Q2xj5Syc.cjs +0 -142
  665. package/dist/date-range-Q2xj5Syc.cjs.map +0 -1
  666. package/dist/date-range-inline-BnOD-ddB.js.map +0 -1
  667. package/dist/date-range-inline-DV2c_gWM.cjs.map +0 -1
  668. package/dist/details-B2-jECBh.cjs.map +0 -1
  669. package/dist/details-ByF66CyY.js.map +0 -1
  670. package/dist/directives-BL7mzVsA.js.map +0 -1
  671. package/dist/directives-DCb_LA9R.cjs.map +0 -1
  672. package/dist/divider-Bv2QiOZL.cjs +0 -57
  673. package/dist/divider-Bv2QiOZL.cjs.map +0 -1
  674. package/dist/divider-gYuz0zDU.js +0 -89
  675. package/dist/divider-gYuz0zDU.js.map +0 -1
  676. package/dist/expand-B9IUGVtc.cjs +0 -141
  677. package/dist/expand-B9IUGVtc.cjs.map +0 -1
  678. package/dist/expand-cZ8rfCWP.js.map +0 -1
  679. package/dist/form-DowzVsgI.cjs.map +0 -1
  680. package/dist/form-tG7LwDm4.js.map +0 -1
  681. package/dist/icons-BZeCloP9.cjs +0 -24
  682. package/dist/icons-BZeCloP9.cjs.map +0 -1
  683. package/dist/icons-Dup5skuk.js.map +0 -1
  684. package/dist/iframe-CDJjnNmo.cjs.map +0 -1
  685. package/dist/iframe-Xc3EPMZT.js.map +0 -1
  686. package/dist/input-DnmC6J1T.cjs.map +0 -1
  687. package/dist/input-cTyDxW9L.js.map +0 -1
  688. package/dist/input-chip-CV91URyU.cjs +0 -146
  689. package/dist/input-chip-CV91URyU.cjs.map +0 -1
  690. package/dist/input-chip-CYI17YOq.js.map +0 -1
  691. package/dist/layout-CNlZSJFU.cjs.map +0 -1
  692. package/dist/layout-DDxw0EwL.js.map +0 -1
  693. package/dist/lightbox-CH-y3rYB.js.map +0 -1
  694. package/dist/lightbox-CvtqoInF.cjs.map +0 -1
  695. package/dist/list-Dl8KfxrF.cjs +0 -40
  696. package/dist/list-Dl8KfxrF.cjs.map +0 -1
  697. package/dist/list-DrsawQ5R.js.map +0 -1
  698. package/dist/menu-BFRcTe3o.cjs.map +0 -1
  699. package/dist/menu-CsY5lMqY.js.map +0 -1
  700. package/dist/mixins-BoMURWag.cjs.map +0 -1
  701. package/dist/mixins-bCEXbwJV.js.map +0 -1
  702. package/dist/notification-DFKRMmSq.js.map +0 -1
  703. package/dist/notification-FBf3Mb2e.cjs.map +0 -1
  704. package/dist/option-Ct0lGdH3.js.map +0 -1
  705. package/dist/option-Il1KpU8M.cjs +0 -43
  706. package/dist/option-Il1KpU8M.cjs.map +0 -1
  707. package/dist/overlay-Bh8Q_R01.js.map +0 -1
  708. package/dist/overlay-sRXiMkjn.cjs.map +0 -1
  709. package/dist/overlay.confirm-body-CQihsR20.js.map +0 -1
  710. package/dist/overlay.confirm-body-Jc1EuMGs.cjs.map +0 -1
  711. package/dist/overlay.service-9Dp3g7ot.cjs.map +0 -1
  712. package/dist/overlay.service-BXPgS7ay.js.map +0 -1
  713. package/dist/progress-CWC5XYZ_.cjs +0 -51
  714. package/dist/progress-CWC5XYZ_.cjs.map +0 -1
  715. package/dist/progress-CYLshdo2.js.map +0 -1
  716. package/dist/radio-group-6kCgOgBL.cjs.map +0 -1
  717. package/dist/radio-group-bZtZHOj_.js.map +0 -1
  718. package/dist/select-CU3X-PIa.js.map +0 -1
  719. package/dist/select-MXsF8KsU.cjs +0 -56
  720. package/dist/select-MXsF8KsU.cjs.map +0 -1
  721. package/dist/sound.service-B4ZmXpH9.js.map +0 -1
  722. package/dist/sound.service-DjlMvicQ.cjs.map +0 -1
  723. package/dist/splash-screen-CN9dZcqC.cjs +0 -41
  724. package/dist/splash-screen-CN9dZcqC.cjs.map +0 -1
  725. package/dist/splash-screen-emCLYoVl.js.map +0 -1
  726. package/dist/src-DGDTkOvC.js.map +0 -1
  727. package/dist/src-DK3111z_.cjs +0 -240
  728. package/dist/src-DK3111z_.cjs.map +0 -1
  729. package/dist/state-CumAEPQH.cjs.map +0 -1
  730. package/dist/state-DMd_FUeA.js.map +0 -1
  731. package/dist/surface-DGI-FBoi.cjs +0 -7
  732. package/dist/surface-DGI-FBoi.cjs.map +0 -1
  733. package/dist/tabs-4T_4kCf-.js.map +0 -1
  734. package/dist/tabs-Byxxt-AH.cjs.map +0 -1
  735. package/dist/textarea-BwYwH9fu.cjs.map +0 -1
  736. package/dist/textarea-kkYNk1ET.js.map +0 -1
  737. package/dist/theme.service-Dv_55nfE.js.map +0 -1
  738. package/dist/theme.service-pjkTM209.cjs.map +0 -1
  739. package/dist/typography-BVkU11_q.js +0 -358
  740. package/dist/typography-BVkU11_q.js.map +0 -1
  741. package/dist/typography-aaQaIcNc.cjs +0 -282
  742. package/dist/typography-aaQaIcNc.cjs.map +0 -1
  743. package/dist/utils-DTa3QHxk.cjs.map +0 -1
  744. package/dist/utils-H8wNknWC.js.map +0 -1
  745. package/dist/window-C76zstbV.js.map +0 -1
  746. package/dist/window-CmB9XZzT.cjs +0 -58
  747. package/dist/window-CmB9XZzT.cjs.map +0 -1
  748. package/src/form/fields/date-range/date-range-presets.ts +0 -220
  749. package/src/form/fields/date-range/date-utils.ts +0 -58
  750. package/types/src/form/fields/date-range/date-range-presets.d.ts +0 -18
  751. package/types/src/form/fields/date-range/date-utils.d.ts +0 -15
  752. /package/dist/{hashContent-iRZJJWtE.cjs → hashContent--s09Ed_g.cjs} +0 -0
  753. /package/dist/{hashContent-BqU6v1Xr.js → hashContent-CAvrQ56N.js} +0 -0
  754. /package/dist/{rxjs-utils-Csnks202.cjs → rxjs-utils-4P2v57ke.cjs} +0 -0
  755. /package/dist/{rxjs-utils-d-ivVN84.js → rxjs-utils-JMFdgQSl.js} +0 -0
  756. /package/dist/{theme.interface-CSt7JUBD.cjs → theme.interface-B-qxDsZQ.cjs} +0 -0
  757. /package/dist/{theme.interface-odQEpZZH.js → theme.interface-B7caS5cg.js} +0 -0
  758. /package/dist/{utils-DTa3QHxk.cjs → utils-DIXndz6Q.cjs} +0 -0
  759. /package/dist/{utils-H8wNknWC.js → utils-dSPH7Oh9.js} +0 -0
package/dist/fab.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fab.cjs","names":[],"sources":["../src/fab/fab.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { when } from 'lit/directives/when.js'\nimport { magnetic } from '../directives/magnetic'\n\nexport type FabVariant = 'surface' | 'primary' | 'secondary' | 'tertiary'\nexport type FabSize = 'small' | 'medium' | 'large'\n\n/**\n * Material 3 Floating Action Button.\n *\n * Mirrors the `md-fab` reference implementation\n * (github.com/material-components/material-web) and the M3 spec\n * (m3.material.io/components/floating-action-button): four colour\n * variants, three container sizes, an extended form (set `label`),\n * and a `lowered` elevation register. Per M3 guidance a FAB is never\n * disabled, so there is no `disabled` property.\n *\n * Sizing, shape, icon size and elevation are M3 design tokens expressed\n * as `:host` rules (the same token-driven model as `md-fab`'s SCSS);\n * colour roles and the state layer are schmancy theme utilities. The\n * host shrink-wraps the inner button and clips its rounded shape.\n *\n * @element schmancy-fab\n * @slot - The icon (typically `<schmancy-icon>`).\n * @csspart base - The underlying native `<button>`.\n */\n@customElement('schmancy-fab')\nexport class SchmancyFab extends SchmancyElement {\n\tstatic styles = [\n\t\tcss`\n\t\t\t:host {\n\t\t\t\t/* M3 FAB (medium) — 16dp shape, 24dp icon, resting level 3 */\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\tflex-shrink: 0;\n\t\t\t\tposition: relative;\n\t\t\t\ttouch-action: manipulation;\n\t\t\t\toverflow: hidden;\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-3);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-4);\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransition:\n\t\t\t\t\tbox-shadow 280ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\t\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t\t\t}\n\t\t\t/* M3 small FAB — 12dp shape */\n\t\t\t:host([size='small']) {\n\t\t\t\tborder-radius: 12px;\n\t\t\t}\n\t\t\t/* M3 large FAB — 28dp shape, 36dp icon */\n\t\t\t:host([size='large']) {\n\t\t\t\tborder-radius: 28px;\n\t\t\t\t--_icon: 36px;\n\t\t\t}\n\t\t\t/* Extended FAB always uses the 16dp shape / 24dp icon */\n\t\t\t:host([extended]) {\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t}\n\t\t\t/* M3 lowered register — resting level 1, hover level 2 */\n\t\t\t:host([lowered]) {\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-1);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-2);\n\t\t\t}\n\t\t\t:host(:hover) {\n\t\t\t\tbox-shadow: var(--_elevation-hover);\n\t\t\t}\n\t\t\t:host(:active) {\n\t\t\t\t/* M3 pressed elevation == resting; schmancy spring press */\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransform: scale(0.96);\n\t\t\t\ttransition-duration: 100ms;\n\t\t\t}\n\t\t\t::slotted(*) {\n\t\t\t\tfont-size: var(--_icon);\n\t\t\t\twidth: var(--_icon);\n\t\t\t\theight: var(--_icon);\n\t\t\t}\n\t\t\t:host([extended]) ::slotted(*) {\n\t\t\t\tmargin-inline-end: 12px;\n\t\t\t}\n\t\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t\t:host {\n\t\t\t\t\ttransition: none;\n\t\t\t\t}\n\t\t\t\t:host(:active) {\n\t\t\t\t\ttransform: none;\n\t\t\t\t}\n\t\t\t}\n\t\t\t:host *,\n\t\t\t* {\n\t\t\t\ttouch-action: manipulation;\n\t\t\t}\n\t\t`,\n\t]\n\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open',\n\t\tdelegatesFocus: true,\n\t}\n\n\t@query('[part=\"base\"]', true)\n\tprivate nativeElement!: HTMLElement\n\n\tprivate ariaLabelValue!: string\n\n\t/**\n\t * Colour variant. M3 maps each to a container + on-container role.\n\t * @attr\n\t * @default 'surface'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic variant: FabVariant = 'surface'\n\n\t/**\n\t * Container size. Ignored while extended (extended is always 56dp tall).\n\t * @attr\n\t * @default 'medium'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic size: FabSize = 'medium'\n\n\t/**\n\t * Extended-FAB label. A non-empty value switches the FAB to its\n\t * extended form (icon + text), exactly as `md-fab` derives extended\n\t * from a truthy label.\n\t * @attr\n\t */\n\t@property({ type: String })\n\tpublic label = ''\n\n\t/**\n\t * Reflected mirror of \"label is non-empty\" so `:host([extended])`\n\t * can drive the extended geometry. Synced from `label`; read it,\n\t * don't set it.\n\t * @attr\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic extended = false\n\n\t/**\n\t * Lowers the FAB's elevation register (M3 lowered FAB).\n\t * @attr\n\t * @default false\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic lowered = false\n\n\tpublic override set ariaLabel(value: string) {\n\t\tconst oldVal = this.ariaLabelValue\n\t\tthis.ariaLabelValue = value\n\t\tif (this.hasAttribute('aria-label')) {\n\t\t\tthis.removeAttribute('aria-label')\n\t\t}\n\t\tthis.requestUpdate('ariaLabel', oldVal)\n\t}\n\n\t@property({ attribute: 'aria-label' })\n\tpublic override get ariaLabel() {\n\t\treturn this.ariaLabelValue\n\t}\n\n\t/** Sets focus on the FAB. */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.nativeElement.focus(options)\n\t}\n\n\t/** Removes focus from the FAB. */\n\tpublic override blur() {\n\t\tthis.nativeElement.blur()\n\t}\n\n\tprotected willUpdate(changed: Map<string, unknown>) {\n\t\tif (changed.has('label')) this.extended = this.label.length > 0\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'relative z-0 flex items-center justify-center overflow-hidden border-0 cursor-pointer outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-secondary-default':\n\t\t\t\ttrue,\n\t\t\t// M3 container — fixed square per size, content-width when extended\n\t\t\t'size-10': !this.extended && this.size === 'small',\n\t\t\t'size-14': !this.extended && this.size === 'medium',\n\t\t\t'size-24': !this.extended && this.size === 'large',\n\t\t\t'h-14 ps-4 pe-5 gap-3 text-sm font-medium leading-5': this.extended,\n\t\t\t// M3 container + on-container colour roles per variant\n\t\t\t'bg-surface-containerHigh text-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-container text-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-container text-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-container text-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\tconst stateLayerClasses = {\n\t\t\t'absolute inset-0 z-0 opacity-0 transition-opacity duration-150 hover:opacity-8 focus-visible:opacity-10 active:opacity-10':\n\t\t\t\ttrue,\n\t\t\t'bg-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\treturn html`\n\t\t\t<button\n\t\t\t\t${magnetic({ strength: 3, radius: 60 })}\n\t\t\t\tpart=\"base\"\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label=${ifDefined(this.ariaLabel)}\n\t\t\t\tclass=\"${this.classMap(classes)}\"\n\t\t\t>\n\t\t\t\t<div class=\"${this.classMap(stateLayerClasses)}\"></div>\n\t\t\t\t<slot aria-hidden=${ifDefined(this.ariaLabel || this.label ? 'true' : undefined)}></slot>\n\t\t\t\t${when(this.extended, () => html`<span class=\"relative z-0\">${this.label}</span>`)}\n\t\t\t</button>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-fab': SchmancyFab\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fab.cjs","names":[],"sources":["../src/fab/fab.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { when } from 'lit/directives/when.js'\nimport { magnetic } from '../directives/magnetic'\n\nexport type FabVariant = 'surface' | 'primary' | 'secondary' | 'tertiary'\nexport type FabSize = 'small' | 'medium' | 'large'\n\n/**\n * Material 3 Floating Action Button.\n *\n * Mirrors the `md-fab` reference implementation\n * (github.com/material-components/material-web) and the M3 spec\n * (m3.material.io/components/floating-action-button): four colour\n * variants, three container sizes, an extended form (set `label`),\n * and a `lowered` elevation register. Per M3 guidance a FAB is never\n * disabled, so there is no `disabled` property.\n *\n * Sizing, shape, icon size and elevation are M3 design tokens expressed\n * as `:host` rules (the same token-driven model as `md-fab`'s SCSS);\n * colour roles and the state layer are schmancy theme utilities. The\n * host shrink-wraps the inner button and clips its rounded shape.\n *\n * @element schmancy-fab\n * @slot - The icon (typically `<schmancy-icon>`).\n * @csspart base - The underlying native `<button>`.\n */\n@customElement('schmancy-fab')\nexport class SchmancyFab extends SchmancyElement {\n\tstatic styles = [\n\t\tcss`\n\t\t\t:host {\n\t\t\t\t/* M3 FAB (medium) — 16dp shape, 24dp icon, resting level 3 */\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\tflex-shrink: 0;\n\t\t\t\tposition: relative;\n\t\t\t\ttouch-action: manipulation;\n\t\t\t\toverflow: hidden;\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-3);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-4);\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransition:\n\t\t\t\t\tbox-shadow 280ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\t\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t\t\t}\n\t\t\t/* M3 small FAB — 12dp shape */\n\t\t\t:host([size='small']) {\n\t\t\t\tborder-radius: 12px;\n\t\t\t}\n\t\t\t/* M3 large FAB — 28dp shape, 36dp icon */\n\t\t\t:host([size='large']) {\n\t\t\t\tborder-radius: 28px;\n\t\t\t\t--_icon: 36px;\n\t\t\t}\n\t\t\t/* Extended FAB always uses the 16dp shape / 24dp icon */\n\t\t\t:host([extended]) {\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t}\n\t\t\t/* M3 lowered register — resting level 1, hover level 2 */\n\t\t\t:host([lowered]) {\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-1);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-2);\n\t\t\t}\n\t\t\t:host(:hover) {\n\t\t\t\tbox-shadow: var(--_elevation-hover);\n\t\t\t}\n\t\t\t:host(:active) {\n\t\t\t\t/* M3 pressed elevation == resting; schmancy spring press */\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransform: scale(0.96);\n\t\t\t\ttransition-duration: 100ms;\n\t\t\t}\n\t\t\t::slotted(*) {\n\t\t\t\tfont-size: var(--_icon);\n\t\t\t\twidth: var(--_icon);\n\t\t\t\theight: var(--_icon);\n\t\t\t}\n\t\t\t:host([extended]) ::slotted(*) {\n\t\t\t\tmargin-inline-end: 12px;\n\t\t\t}\n\t\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t\t:host {\n\t\t\t\t\ttransition: none;\n\t\t\t\t}\n\t\t\t\t:host(:active) {\n\t\t\t\t\ttransform: none;\n\t\t\t\t}\n\t\t\t}\n\t\t\t:host *,\n\t\t\t* {\n\t\t\t\ttouch-action: manipulation;\n\t\t\t}\n\t\t`,\n\t]\n\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open',\n\t\tdelegatesFocus: true,\n\t}\n\n\t@query('[part=\"base\"]', true)\n\tprivate nativeElement!: HTMLElement\n\n\tprivate ariaLabelValue!: string\n\n\t/**\n\t * Colour variant. M3 maps each to a container + on-container role.\n\t * @attr\n\t * @default 'surface'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic variant: FabVariant = 'surface'\n\n\t/**\n\t * Container size. Ignored while extended (extended is always 56dp tall).\n\t * @attr\n\t * @default 'medium'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic size: FabSize = 'medium'\n\n\t/**\n\t * Extended-FAB label. A non-empty value switches the FAB to its\n\t * extended form (icon + text), exactly as `md-fab` derives extended\n\t * from a truthy label.\n\t * @attr\n\t */\n\t@property({ type: String })\n\tpublic label = ''\n\n\t/**\n\t * Reflected mirror of \"label is non-empty\" so `:host([extended])`\n\t * can drive the extended geometry. Synced from `label`; read it,\n\t * don't set it.\n\t * @attr\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic extended = false\n\n\t/**\n\t * Lowers the FAB's elevation register (M3 lowered FAB).\n\t * @attr\n\t * @default false\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic lowered = false\n\n\tpublic override set ariaLabel(value: string) {\n\t\tconst oldVal = this.ariaLabelValue\n\t\tthis.ariaLabelValue = value\n\t\tif (this.hasAttribute('aria-label')) {\n\t\t\tthis.removeAttribute('aria-label')\n\t\t}\n\t\tthis.requestUpdate('ariaLabel', oldVal)\n\t}\n\n\t@property({ attribute: 'aria-label' })\n\tpublic override get ariaLabel() {\n\t\treturn this.ariaLabelValue\n\t}\n\n\t/** Sets focus on the FAB. */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.nativeElement.focus(options)\n\t}\n\n\t/** Removes focus from the FAB. */\n\tpublic override blur() {\n\t\tthis.nativeElement.blur()\n\t}\n\n\tprotected willUpdate(changed: Map<string, unknown>) {\n\t\tif (changed.has('label')) this.extended = this.label.length > 0\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'relative z-0 flex items-center justify-center overflow-hidden border-0 cursor-pointer outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-secondary-default': true,\n\t\t\t// M3 container — fixed square per size, content-width when extended\n\t\t\t'size-10': !this.extended && this.size === 'small',\n\t\t\t'size-14': !this.extended && this.size === 'medium',\n\t\t\t'size-24': !this.extended && this.size === 'large',\n\t\t\t'h-14 ps-4 pe-5 gap-3 text-sm font-medium leading-5': this.extended,\n\t\t\t// M3 container + on-container colour roles per variant\n\t\t\t'bg-surface-containerHigh text-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-container text-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-container text-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-container text-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\tconst stateLayerClasses = {\n\t\t\t'absolute inset-0 z-0 opacity-0 transition-opacity duration-150 hover:opacity-8 focus-visible:opacity-10 active:opacity-10': true,\n\t\t\t'bg-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\treturn html`\n\t\t\t<button\n\t\t\t\t${magnetic({ strength: 3, radius: 60 })}\n\t\t\t\tpart=\"base\"\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label=${ifDefined(this.ariaLabel)}\n\t\t\t\tclass=\"${this.classMap(classes)}\"\n\t\t\t>\n\t\t\t\t<div class=\"${this.classMap(stateLayerClasses)}\"></div>\n\t\t\t\t<slot aria-hidden=${ifDefined(this.ariaLabel || this.label ? 'true' : undefined)}></slot>\n\t\t\t\t${when(this.extended, () => html`<span class=\"relative z-0\">${this.label}</span>`)}\n\t\t\t</button>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-fab': SchmancyFab\n\t}\n}\n"],"mappings":"mWA8BO,IAAA,EAAA,cAA0B,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,QAuFH,UAAA,KAAA,KAQN,SAAA,KAAA,MASR,GAAA,KAAA,SAAA,CASG,EAAA,KAAA,QAAA,CAQD,CAAA,CAAA,OAAA,KAAA,OAxHD,CACf,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAoEiC,CAAA,GACjC,EAAA,WAAW,kBACd,KAAM,OACN,eAAA,CAAgB,CAAA,CAAA,CAkDjB,IAAA,UAA8B,EAAA,CAC7B,IAAM,EAAS,KAAK,eACpB,KAAK,eAAiB,EAClB,KAAK,aAAa,YAAA,GACrB,KAAK,gBAAgB,YAAA,EAEtB,KAAK,cAAc,YAAa,CAAA,CACjC,CAEA,IAAA,WACoB,CACnB,OAAO,KAAK,cACb,CAGA,MAAsB,EAAA,CACrB,KAAK,cAAc,MAAM,CAAA,CAC1B,CAGA,MAAA,CACC,KAAK,cAAc,KAAA,CACpB,CAEA,WAAqB,EAAA,CAChB,EAAQ,IAAI,OAAA,IAAU,KAAK,SAAW,KAAK,MAAM,OAAS,EAC/D,CAEA,QAAA,CACC,IAAM,EAAU,CACf,oNAAA,CAAqN,EAErN,UAAA,CAAY,KAAK,UAAY,KAAK,OAAS,QAC3C,UAAA,CAAY,KAAK,UAAY,KAAK,OAAS,SAC3C,UAAA,CAAY,KAAK,UAAY,KAAK,OAAS,QAC3C,qDAAsD,KAAK,SAE3D,gDAAiD,KAAK,UAAY,UAClE,gDAAiD,KAAK,UAAY,UAClE,oDAAqD,KAAK,UAAY,YACtE,kDAAmD,KAAK,UAAY,UAAZ,EAGnD,EAAoB,CACzB,4HAAA,CAA6H,EAC7H,qBAAsB,KAAK,UAAY,UACvC,yBAA0B,KAAK,UAAY,UAC3C,2BAA4B,KAAK,UAAY,YAC7C,0BAA2B,KAAK,UAAY,UAAZ,EAGjC,MAAO,GAAA,IAAI;;MAEP,EAAA,EAAS,CAAE,SAAU,EAAG,OAAQ,EAAA,CAAA,EAAA;;;iCAGX,KAAK,SAAA,EAAA;aACnB,KAAK,SAAS,CAAA,EAAA;;kBAET,KAAK,SAAS,CAAA,EAAA;wCACE,KAAK,WAAa,KAAK,MAAQ,OAAA,IAAS,EAAA,EAAA;iBAC/D,KAAK,aAAgB,EAAA,IAAI,8BAA8B,KAAK,MAAA,QAAA,EAAA;;GAGtE,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OA/GO,gBAAA,CAAiB,CAAA,CAAA,EAAI,EAAA,UAAA,gBAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAUlB,CAAE,QAAA,CAAS,EAAM,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,UAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAQ/B,CAAE,QAAA,CAAS,EAAM,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,OAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAS/B,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,QAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAShB,CAAE,KAAM,QAAS,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,WAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAQhC,CAAE,KAAM,QAAS,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,UAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAYhC,CAAE,UAAW,YAAA,CAAA,CAAA,EAAc,EAAA,UAAA,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eArIvB,cAAA,CAAA,EAAc,CAAA,EAAA,OAAA,eAAA,QAAA,cAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
package/dist/fab.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as e, u as t } from "./SchmancyElement-OG71FtNv.js";
2
- import "./mixins-bCEXbwJV.js";
1
+ import { t as e, u as t } from "./SchmancyElement-Ob9yGkiG.js";
2
+ import "./mixins-q4KAL8Xr.js";
3
3
  import { t as n } from "./magnetic-DaOOv5Dz.js";
4
4
  import { customElement as r, property as i, query as a } from "lit/decorators.js";
5
5
  import { LitElement as o, css as s, html as c } from "lit";
package/dist/fab.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fab.js","names":[],"sources":["../src/fab/fab.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { when } from 'lit/directives/when.js'\nimport { magnetic } from '../directives/magnetic'\n\nexport type FabVariant = 'surface' | 'primary' | 'secondary' | 'tertiary'\nexport type FabSize = 'small' | 'medium' | 'large'\n\n/**\n * Material 3 Floating Action Button.\n *\n * Mirrors the `md-fab` reference implementation\n * (github.com/material-components/material-web) and the M3 spec\n * (m3.material.io/components/floating-action-button): four colour\n * variants, three container sizes, an extended form (set `label`),\n * and a `lowered` elevation register. Per M3 guidance a FAB is never\n * disabled, so there is no `disabled` property.\n *\n * Sizing, shape, icon size and elevation are M3 design tokens expressed\n * as `:host` rules (the same token-driven model as `md-fab`'s SCSS);\n * colour roles and the state layer are schmancy theme utilities. The\n * host shrink-wraps the inner button and clips its rounded shape.\n *\n * @element schmancy-fab\n * @slot - The icon (typically `<schmancy-icon>`).\n * @csspart base - The underlying native `<button>`.\n */\n@customElement('schmancy-fab')\nexport class SchmancyFab extends SchmancyElement {\n\tstatic styles = [\n\t\tcss`\n\t\t\t:host {\n\t\t\t\t/* M3 FAB (medium) — 16dp shape, 24dp icon, resting level 3 */\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\tflex-shrink: 0;\n\t\t\t\tposition: relative;\n\t\t\t\ttouch-action: manipulation;\n\t\t\t\toverflow: hidden;\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-3);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-4);\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransition:\n\t\t\t\t\tbox-shadow 280ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\t\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t\t\t}\n\t\t\t/* M3 small FAB — 12dp shape */\n\t\t\t:host([size='small']) {\n\t\t\t\tborder-radius: 12px;\n\t\t\t}\n\t\t\t/* M3 large FAB — 28dp shape, 36dp icon */\n\t\t\t:host([size='large']) {\n\t\t\t\tborder-radius: 28px;\n\t\t\t\t--_icon: 36px;\n\t\t\t}\n\t\t\t/* Extended FAB always uses the 16dp shape / 24dp icon */\n\t\t\t:host([extended]) {\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t}\n\t\t\t/* M3 lowered register — resting level 1, hover level 2 */\n\t\t\t:host([lowered]) {\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-1);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-2);\n\t\t\t}\n\t\t\t:host(:hover) {\n\t\t\t\tbox-shadow: var(--_elevation-hover);\n\t\t\t}\n\t\t\t:host(:active) {\n\t\t\t\t/* M3 pressed elevation == resting; schmancy spring press */\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransform: scale(0.96);\n\t\t\t\ttransition-duration: 100ms;\n\t\t\t}\n\t\t\t::slotted(*) {\n\t\t\t\tfont-size: var(--_icon);\n\t\t\t\twidth: var(--_icon);\n\t\t\t\theight: var(--_icon);\n\t\t\t}\n\t\t\t:host([extended]) ::slotted(*) {\n\t\t\t\tmargin-inline-end: 12px;\n\t\t\t}\n\t\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t\t:host {\n\t\t\t\t\ttransition: none;\n\t\t\t\t}\n\t\t\t\t:host(:active) {\n\t\t\t\t\ttransform: none;\n\t\t\t\t}\n\t\t\t}\n\t\t\t:host *,\n\t\t\t* {\n\t\t\t\ttouch-action: manipulation;\n\t\t\t}\n\t\t`,\n\t]\n\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open',\n\t\tdelegatesFocus: true,\n\t}\n\n\t@query('[part=\"base\"]', true)\n\tprivate nativeElement!: HTMLElement\n\n\tprivate ariaLabelValue!: string\n\n\t/**\n\t * Colour variant. M3 maps each to a container + on-container role.\n\t * @attr\n\t * @default 'surface'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic variant: FabVariant = 'surface'\n\n\t/**\n\t * Container size. Ignored while extended (extended is always 56dp tall).\n\t * @attr\n\t * @default 'medium'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic size: FabSize = 'medium'\n\n\t/**\n\t * Extended-FAB label. A non-empty value switches the FAB to its\n\t * extended form (icon + text), exactly as `md-fab` derives extended\n\t * from a truthy label.\n\t * @attr\n\t */\n\t@property({ type: String })\n\tpublic label = ''\n\n\t/**\n\t * Reflected mirror of \"label is non-empty\" so `:host([extended])`\n\t * can drive the extended geometry. Synced from `label`; read it,\n\t * don't set it.\n\t * @attr\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic extended = false\n\n\t/**\n\t * Lowers the FAB's elevation register (M3 lowered FAB).\n\t * @attr\n\t * @default false\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic lowered = false\n\n\tpublic override set ariaLabel(value: string) {\n\t\tconst oldVal = this.ariaLabelValue\n\t\tthis.ariaLabelValue = value\n\t\tif (this.hasAttribute('aria-label')) {\n\t\t\tthis.removeAttribute('aria-label')\n\t\t}\n\t\tthis.requestUpdate('ariaLabel', oldVal)\n\t}\n\n\t@property({ attribute: 'aria-label' })\n\tpublic override get ariaLabel() {\n\t\treturn this.ariaLabelValue\n\t}\n\n\t/** Sets focus on the FAB. */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.nativeElement.focus(options)\n\t}\n\n\t/** Removes focus from the FAB. */\n\tpublic override blur() {\n\t\tthis.nativeElement.blur()\n\t}\n\n\tprotected willUpdate(changed: Map<string, unknown>) {\n\t\tif (changed.has('label')) this.extended = this.label.length > 0\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'relative z-0 flex items-center justify-center overflow-hidden border-0 cursor-pointer outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-secondary-default':\n\t\t\t\ttrue,\n\t\t\t// M3 container — fixed square per size, content-width when extended\n\t\t\t'size-10': !this.extended && this.size === 'small',\n\t\t\t'size-14': !this.extended && this.size === 'medium',\n\t\t\t'size-24': !this.extended && this.size === 'large',\n\t\t\t'h-14 ps-4 pe-5 gap-3 text-sm font-medium leading-5': this.extended,\n\t\t\t// M3 container + on-container colour roles per variant\n\t\t\t'bg-surface-containerHigh text-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-container text-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-container text-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-container text-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\tconst stateLayerClasses = {\n\t\t\t'absolute inset-0 z-0 opacity-0 transition-opacity duration-150 hover:opacity-8 focus-visible:opacity-10 active:opacity-10':\n\t\t\t\ttrue,\n\t\t\t'bg-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\treturn html`\n\t\t\t<button\n\t\t\t\t${magnetic({ strength: 3, radius: 60 })}\n\t\t\t\tpart=\"base\"\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label=${ifDefined(this.ariaLabel)}\n\t\t\t\tclass=\"${this.classMap(classes)}\"\n\t\t\t>\n\t\t\t\t<div class=\"${this.classMap(stateLayerClasses)}\"></div>\n\t\t\t\t<slot aria-hidden=${ifDefined(this.ariaLabel || this.label ? 'true' : undefined)}></slot>\n\t\t\t\t${when(this.extended, () => html`<span class=\"relative z-0\">${this.label}</span>`)}\n\t\t\t</button>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-fab': SchmancyFab\n\t}\n}\n"],"mappings":";;;;;;;AA8BO,IAAA,IAAA,cAA0B,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,UAuFH,WAAA,KAAA,OAQN,UAAA,KAAA,QASR,IAAA,KAAA,WAAA,CASG,GAAA,KAAA,UAAA,CAQD;CAAA;CAAA;EAAA,KAAA,SAxHD,CACf,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoEiC;GAAA,GACjC,EAAW;GACd,MAAM;GACN,gBAAA,CAAgB;EAAA;CAAA;CAkDjB,IAAA,UAA8B,GAAA;EAC7B,IAAM,IAAS,KAAK;EACpB,KAAK,iBAAiB,GAClB,KAAK,aAAa,YAAA,KACrB,KAAK,gBAAgB,YAAA,GAEtB,KAAK,cAAc,aAAa,CAAA;CACjC;CAEA,IAAA,YACoB;EACnB,OAAO,KAAK;CACb;CAGA,MAAsB,GAAA;EACrB,KAAK,cAAc,MAAM,CAAA;CAC1B;CAGA,OAAA;EACC,KAAK,cAAc,KAAA;CACpB;CAEA,WAAqB,GAAA;EAChB,EAAQ,IAAI,OAAA,MAAU,KAAK,WAAW,KAAK,MAAM,SAAS;CAC/D;CAEA,SAAA;EACC,IAAM,IAAU;GACf,qNAAA,CACC;GAED,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,sDAAsD,KAAK;GAE3D,iDAAiD,KAAK,YAAY;GAClE,iDAAiD,KAAK,YAAY;GAClE,qDAAqD,KAAK,YAAY;GACtE,mDAAmD,KAAK,YAAY;EAAZ,GAGnD,IAAoB;GACzB,6HAAA,CACC;GACD,sBAAsB,KAAK,YAAY;GACvC,0BAA0B,KAAK,YAAY;GAC3C,4BAA4B,KAAK,YAAY;GAC7C,2BAA2B,KAAK,YAAY;EAAZ;EAGjC,OAAO,CAAI;;MAEP,EAAS;GAAE,UAAU;GAAG,QAAQ;EAAA,CAAA,EAAA;;;iBAGrB,EAAU,KAAK,SAAA,EAAA;aACnB,KAAK,SAAS,CAAA,EAAA;;kBAET,KAAK,SAAS,CAAA,EAAA;wBACR,EAAU,KAAK,aAAa,KAAK,QAAQ,SAAA,KAAS,CAAA,EAAA;MACpE,EAAK,KAAK,gBAAgB,CAAI,8BAA8B,KAAK,MAAA,QAAA,EAAA;;;CAGtE;AAAA;AAAA,EAAA,CAjHC,EAAM,mBAAA,CAAiB,CAAA,CAAA,GAAI,EAAA,WAAA,iBAAA,KAAA,CAAA,GAAA,EAAA,CAU3B,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;AAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,WAAA,KAAA,CAAA,GAAA,EAAA,CAQxC,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;AAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,QAAA,KAAA,CAAA,GAAA,EAAA,CASxC,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,SAAA,KAAA,CAAA,GAAA,EAAA,CASzB,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,YAAA,KAAA,CAAA,GAAA,EAAA,CAQzC,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,WAAA,KAAA,CAAA,GAAA,EAAA,CAYzC,EAAS,EAAE,WAAW,aAAA,CAAA,CAAA,GAAc,EAAA,WAAA,aAAA,IAAA,GAAA,IAAA,EAAA,CArIrC,EAAc,cAAA,CAAA,GAAc,CAAA;AAAA,SAAA,KAAA"}
1
+ {"version":3,"file":"fab.js","names":[],"sources":["../src/fab/fab.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { when } from 'lit/directives/when.js'\nimport { magnetic } from '../directives/magnetic'\n\nexport type FabVariant = 'surface' | 'primary' | 'secondary' | 'tertiary'\nexport type FabSize = 'small' | 'medium' | 'large'\n\n/**\n * Material 3 Floating Action Button.\n *\n * Mirrors the `md-fab` reference implementation\n * (github.com/material-components/material-web) and the M3 spec\n * (m3.material.io/components/floating-action-button): four colour\n * variants, three container sizes, an extended form (set `label`),\n * and a `lowered` elevation register. Per M3 guidance a FAB is never\n * disabled, so there is no `disabled` property.\n *\n * Sizing, shape, icon size and elevation are M3 design tokens expressed\n * as `:host` rules (the same token-driven model as `md-fab`'s SCSS);\n * colour roles and the state layer are schmancy theme utilities. The\n * host shrink-wraps the inner button and clips its rounded shape.\n *\n * @element schmancy-fab\n * @slot - The icon (typically `<schmancy-icon>`).\n * @csspart base - The underlying native `<button>`.\n */\n@customElement('schmancy-fab')\nexport class SchmancyFab extends SchmancyElement {\n\tstatic styles = [\n\t\tcss`\n\t\t\t:host {\n\t\t\t\t/* M3 FAB (medium) — 16dp shape, 24dp icon, resting level 3 */\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\tflex-shrink: 0;\n\t\t\t\tposition: relative;\n\t\t\t\ttouch-action: manipulation;\n\t\t\t\toverflow: hidden;\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-3);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-4);\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransition:\n\t\t\t\t\tbox-shadow 280ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\t\t\t\ttransform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\t\t\t}\n\t\t\t/* M3 small FAB — 12dp shape */\n\t\t\t:host([size='small']) {\n\t\t\t\tborder-radius: 12px;\n\t\t\t}\n\t\t\t/* M3 large FAB — 28dp shape, 36dp icon */\n\t\t\t:host([size='large']) {\n\t\t\t\tborder-radius: 28px;\n\t\t\t\t--_icon: 36px;\n\t\t\t}\n\t\t\t/* Extended FAB always uses the 16dp shape / 24dp icon */\n\t\t\t:host([extended]) {\n\t\t\t\tborder-radius: 16px;\n\t\t\t\t--_icon: 24px;\n\t\t\t}\n\t\t\t/* M3 lowered register — resting level 1, hover level 2 */\n\t\t\t:host([lowered]) {\n\t\t\t\t--_elevation: var(--schmancy-sys-elevation-1);\n\t\t\t\t--_elevation-hover: var(--schmancy-sys-elevation-2);\n\t\t\t}\n\t\t\t:host(:hover) {\n\t\t\t\tbox-shadow: var(--_elevation-hover);\n\t\t\t}\n\t\t\t:host(:active) {\n\t\t\t\t/* M3 pressed elevation == resting; schmancy spring press */\n\t\t\t\tbox-shadow: var(--_elevation);\n\t\t\t\ttransform: scale(0.96);\n\t\t\t\ttransition-duration: 100ms;\n\t\t\t}\n\t\t\t::slotted(*) {\n\t\t\t\tfont-size: var(--_icon);\n\t\t\t\twidth: var(--_icon);\n\t\t\t\theight: var(--_icon);\n\t\t\t}\n\t\t\t:host([extended]) ::slotted(*) {\n\t\t\t\tmargin-inline-end: 12px;\n\t\t\t}\n\t\t\t@media (prefers-reduced-motion: reduce) {\n\t\t\t\t:host {\n\t\t\t\t\ttransition: none;\n\t\t\t\t}\n\t\t\t\t:host(:active) {\n\t\t\t\t\ttransform: none;\n\t\t\t\t}\n\t\t\t}\n\t\t\t:host *,\n\t\t\t* {\n\t\t\t\ttouch-action: manipulation;\n\t\t\t}\n\t\t`,\n\t]\n\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tmode: 'open',\n\t\tdelegatesFocus: true,\n\t}\n\n\t@query('[part=\"base\"]', true)\n\tprivate nativeElement!: HTMLElement\n\n\tprivate ariaLabelValue!: string\n\n\t/**\n\t * Colour variant. M3 maps each to a container + on-container role.\n\t * @attr\n\t * @default 'surface'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic variant: FabVariant = 'surface'\n\n\t/**\n\t * Container size. Ignored while extended (extended is always 56dp tall).\n\t * @attr\n\t * @default 'medium'\n\t */\n\t@property({ reflect: true, type: String })\n\tpublic size: FabSize = 'medium'\n\n\t/**\n\t * Extended-FAB label. A non-empty value switches the FAB to its\n\t * extended form (icon + text), exactly as `md-fab` derives extended\n\t * from a truthy label.\n\t * @attr\n\t */\n\t@property({ type: String })\n\tpublic label = ''\n\n\t/**\n\t * Reflected mirror of \"label is non-empty\" so `:host([extended])`\n\t * can drive the extended geometry. Synced from `label`; read it,\n\t * don't set it.\n\t * @attr\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic extended = false\n\n\t/**\n\t * Lowers the FAB's elevation register (M3 lowered FAB).\n\t * @attr\n\t * @default false\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic lowered = false\n\n\tpublic override set ariaLabel(value: string) {\n\t\tconst oldVal = this.ariaLabelValue\n\t\tthis.ariaLabelValue = value\n\t\tif (this.hasAttribute('aria-label')) {\n\t\t\tthis.removeAttribute('aria-label')\n\t\t}\n\t\tthis.requestUpdate('ariaLabel', oldVal)\n\t}\n\n\t@property({ attribute: 'aria-label' })\n\tpublic override get ariaLabel() {\n\t\treturn this.ariaLabelValue\n\t}\n\n\t/** Sets focus on the FAB. */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.nativeElement.focus(options)\n\t}\n\n\t/** Removes focus from the FAB. */\n\tpublic override blur() {\n\t\tthis.nativeElement.blur()\n\t}\n\n\tprotected willUpdate(changed: Map<string, unknown>) {\n\t\tif (changed.has('label')) this.extended = this.label.length > 0\n\t}\n\n\trender() {\n\t\tconst classes = {\n\t\t\t'relative z-0 flex items-center justify-center overflow-hidden border-0 cursor-pointer outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 outline-secondary-default': true,\n\t\t\t// M3 container — fixed square per size, content-width when extended\n\t\t\t'size-10': !this.extended && this.size === 'small',\n\t\t\t'size-14': !this.extended && this.size === 'medium',\n\t\t\t'size-24': !this.extended && this.size === 'large',\n\t\t\t'h-14 ps-4 pe-5 gap-3 text-sm font-medium leading-5': this.extended,\n\t\t\t// M3 container + on-container colour roles per variant\n\t\t\t'bg-surface-containerHigh text-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-container text-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-container text-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-container text-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\tconst stateLayerClasses = {\n\t\t\t'absolute inset-0 z-0 opacity-0 transition-opacity duration-150 hover:opacity-8 focus-visible:opacity-10 active:opacity-10': true,\n\t\t\t'bg-primary-default': this.variant === 'surface',\n\t\t\t'bg-primary-onContainer': this.variant === 'primary',\n\t\t\t'bg-secondary-onContainer': this.variant === 'secondary',\n\t\t\t'bg-tertiary-onContainer': this.variant === 'tertiary',\n\t\t}\n\n\t\treturn html`\n\t\t\t<button\n\t\t\t\t${magnetic({ strength: 3, radius: 60 })}\n\t\t\t\tpart=\"base\"\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label=${ifDefined(this.ariaLabel)}\n\t\t\t\tclass=\"${this.classMap(classes)}\"\n\t\t\t>\n\t\t\t\t<div class=\"${this.classMap(stateLayerClasses)}\"></div>\n\t\t\t\t<slot aria-hidden=${ifDefined(this.ariaLabel || this.label ? 'true' : undefined)}></slot>\n\t\t\t\t${when(this.extended, () => html`<span class=\"relative z-0\">${this.label}</span>`)}\n\t\t\t</button>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-fab': SchmancyFab\n\t}\n}\n"],"mappings":";;;;;;;AA8BO,IAAA,IAAA,cAA0B,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,UAuFH,WAAA,KAAA,OAQN,UAAA,KAAA,QASR,IAAA,KAAA,WAAA,CASG,GAAA,KAAA,UAAA,CAQD;CAAA;CAAA;EAAA,KAAA,SAxHD,CACf,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoEiC;GAAA,GACjC,EAAW;GACd,MAAM;GACN,gBAAA,CAAgB;EAAA;CAAA;CAkDjB,IAAA,UAA8B,GAAA;EAC7B,IAAM,IAAS,KAAK;EACpB,KAAK,iBAAiB,GAClB,KAAK,aAAa,YAAA,KACrB,KAAK,gBAAgB,YAAA,GAEtB,KAAK,cAAc,aAAa,CAAA;CACjC;CAEA,IAAA,YACoB;EACnB,OAAO,KAAK;CACb;CAGA,MAAsB,GAAA;EACrB,KAAK,cAAc,MAAM,CAAA;CAC1B;CAGA,OAAA;EACC,KAAK,cAAc,KAAA;CACpB;CAEA,WAAqB,GAAA;EAChB,EAAQ,IAAI,OAAA,MAAU,KAAK,WAAW,KAAK,MAAM,SAAS;CAC/D;CAEA,SAAA;EACC,IAAM,IAAU;GACf,qNAAA,CAAqN;GAErN,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,WAAA,CAAY,KAAK,YAAY,KAAK,SAAS;GAC3C,sDAAsD,KAAK;GAE3D,iDAAiD,KAAK,YAAY;GAClE,iDAAiD,KAAK,YAAY;GAClE,qDAAqD,KAAK,YAAY;GACtE,mDAAmD,KAAK,YAAY;EAAZ,GAGnD,IAAoB;GACzB,6HAAA,CAA6H;GAC7H,sBAAsB,KAAK,YAAY;GACvC,0BAA0B,KAAK,YAAY;GAC3C,4BAA4B,KAAK,YAAY;GAC7C,2BAA2B,KAAK,YAAY;EAAZ;EAGjC,OAAO,CAAI;;MAEP,EAAS;GAAE,UAAU;GAAG,QAAQ;EAAA,CAAA,EAAA;;;iBAGrB,EAAU,KAAK,SAAA,EAAA;aACnB,KAAK,SAAS,CAAA,EAAA;;kBAET,KAAK,SAAS,CAAA,EAAA;wBACR,EAAU,KAAK,aAAa,KAAK,QAAQ,SAAA,KAAS,CAAA,EAAA;MACpE,EAAK,KAAK,gBAAgB,CAAI,8BAA8B,KAAK,MAAA,QAAA,EAAA;;;CAGtE;AAAA;AAAA,EAAA,CA/GC,EAAM,mBAAA,CAAiB,CAAA,CAAA,GAAI,EAAA,WAAA,iBAAA,KAAA,CAAA,GAAA,EAAA,CAU3B,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;AAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,WAAA,KAAA,CAAA,GAAA,EAAA,CAQxC,EAAS;CAAE,SAAA,CAAS;CAAM,MAAM;AAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,QAAA,KAAA,CAAA,GAAA,EAAA,CASxC,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,SAAA,KAAA,CAAA,GAAA,EAAA,CASzB,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,YAAA,KAAA,CAAA,GAAA,EAAA,CAQzC,EAAS;CAAE,MAAM;CAAS,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,WAAA,KAAA,CAAA,GAAA,EAAA,CAYzC,EAAS,EAAE,WAAW,aAAA,CAAA,CAAA,GAAc,EAAA,WAAA,aAAA,IAAA,GAAA,IAAA,EAAA,CArIrC,EAAc,cAAA,CAAA,GAAc,CAAA;AAAA,SAAA,KAAA"}
@@ -1 +1 @@
1
- require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-PS1u0j1B.cjs`),t=require(`./window-CmB9XZzT.cjs`);let n=require(`lit/decorators.js`);var r=class extends t.t{},i=r=e.u([(0,n.customElement)(`schmancy-float`)],r);Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}});
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-CeKrBW2j.cjs`),t=require(`./window-Br1OmpL-.cjs`);let n=require(`lit/decorators.js`);var r=class extends t.t{},i=r=e.u([(0,n.customElement)(`schmancy-float`)],r);Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}});
@@ -1 +1 @@
1
- {"version":3,"file":"float-DkGyWSWy.cjs","names":[],"sources":["../src/float/float.ts"],"sourcesContent":["/**\n * Backward compatibility alias — schmancy-float is now schmancy-window.\n *\n * Existing consumers using <schmancy-float> continue to work.\n * New code should use <schmancy-window> directly.\n */\n\nimport { customElement } from 'lit/decorators.js'\nimport SchmancyWindow from '../window/window.js'\n\n@customElement('schmancy-float')\nexport default class SchmancyFloat extends SchmancyWindow {}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-float': SchmancyFloat\n\t}\n}\n"],"mappings":"wJAWe,IAAA,EAAA,cAA4B,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAD5B,gBAAA,CAAA,EAAgB,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"float-BPQlDyai.cjs","names":[],"sources":["../src/float/float.ts"],"sourcesContent":["/**\n * Backward compatibility alias — schmancy-float is now schmancy-window.\n *\n * Existing consumers using <schmancy-float> continue to work.\n * New code should use <schmancy-window> directly.\n */\n\nimport { customElement } from 'lit/decorators.js'\nimport SchmancyWindow from '../window/window.js'\n\n@customElement('schmancy-float')\nexport default class SchmancyFloat extends SchmancyWindow {}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-float': SchmancyFloat\n\t}\n}\n"],"mappings":"wJAWe,IAAA,EAAA,cAA4B,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAD5B,gBAAA,CAAA,EAAgB,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
@@ -1,5 +1,5 @@
1
- import { u as e } from "./SchmancyElement-OG71FtNv.js";
2
- import { t } from "./window-C76zstbV.js";
1
+ import { u as e } from "./SchmancyElement-Ob9yGkiG.js";
2
+ import { t } from "./window-CCmN4but.js";
3
3
  import { customElement as n } from "lit/decorators.js";
4
4
  var r = class extends t {}, i = r = e([n("schmancy-float")], r);
5
5
  export { i as t };
@@ -1 +1 @@
1
- {"version":3,"file":"float-zn3DgXBT.js","names":[],"sources":["../src/float/float.ts"],"sourcesContent":["/**\n * Backward compatibility alias — schmancy-float is now schmancy-window.\n *\n * Existing consumers using <schmancy-float> continue to work.\n * New code should use <schmancy-window> directly.\n */\n\nimport { customElement } from 'lit/decorators.js'\nimport SchmancyWindow from '../window/window.js'\n\n@customElement('schmancy-float')\nexport default class SchmancyFloat extends SchmancyWindow {}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-float': SchmancyFloat\n\t}\n}\n"],"mappings":";;;AAWe,IAAA,IAAA,cAA4B,EAAA,CAAA,GAAA,IAAA,IAAA,EAAA,CAD1C,EAAc,gBAAA,CAAA,GAAgB,CAAA;AAAA,SAAA,KAAA"}
1
+ {"version":3,"file":"float-BQcxj3i_.js","names":[],"sources":["../src/float/float.ts"],"sourcesContent":["/**\n * Backward compatibility alias — schmancy-float is now schmancy-window.\n *\n * Existing consumers using <schmancy-float> continue to work.\n * New code should use <schmancy-window> directly.\n */\n\nimport { customElement } from 'lit/decorators.js'\nimport SchmancyWindow from '../window/window.js'\n\n@customElement('schmancy-float')\nexport default class SchmancyFloat extends SchmancyWindow {}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-float': SchmancyFloat\n\t}\n}\n"],"mappings":";;;AAWe,IAAA,IAAA,cAA4B,EAAA,CAAA,GAAA,IAAA,IAAA,EAAA,CAD1C,EAAc,gBAAA,CAAA,GAAgB,CAAA;AAAA,SAAA,KAAA"}
package/dist/float.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./float-DkGyWSWy.cjs`);exports.SchmancyFloat=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./float-BPQlDyai.cjs`);exports.SchmancyFloat=e.t;
package/dist/float.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./float-zn3DgXBT.js";
1
+ import { t as e } from "./float-BQcxj3i_.js";
2
2
  export { e as SchmancyFloat };
@@ -1,12 +1,10 @@
1
- require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-PS1u0j1B.cjs`),t=require(`./mixins-BoMURWag.cjs`),n=require(`./state-CumAEPQH.cjs`);let r=require(`rxjs`),i=require(`lit/decorators.js`),a=require(`lit`);var o=n.a(`schmancy/form-submit`).memory({status:`idle`,error:null,submitCount:0}),s=e=>e instanceof HTMLElement&&(e.tagName===`BUTTON`||e.tagName===`SCHMANCY-BUTTON`),c=class extends e.t{constructor(...e){super(...e),this.novalidate=!0,this.fields=new Set,this.submitting=!1,this.liveStatus=`idle`,this.liveError=``,this.internals=(()=>{try{return this.attachInternals()}catch{return}})()}static{this.styles=a.css`
2
- :host { display: block; }
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-CeKrBW2j.cjs`),t=require(`./mixins-Cjn20BQH.cjs`),n=require(`./state-BWQiqN6I.cjs`);let r=require(`rxjs`),i=require(`lit/decorators.js`),a=require(`lit`);var o=n.a(`schmancy/form-submit`).memory({status:`idle`,error:null,submitCount:0}),s=e=>e instanceof HTMLElement&&(e.tagName===`BUTTON`||e.tagName===`SCHMANCY-BUTTON`),c=class extends e.t{constructor(...e){super(...e),this.novalidate=!0,this.fields=new Set,this.submitting=!1,this.liveStatus=`idle`,this.liveError=``,this.internals=(()=>{try{return this.attachInternals()}catch{return}})()}static{this.styles=a.css`
2
+ :host {
3
+ display: block;
4
+ }
3
5
  `}static{this.tagName=`schmancy-form`}connectedCallback(){super.connectedCallback(),this.parentElement?.closest(`schmancy-form`)||((0,r.fromEvent)(this,t.r).pipe((0,r.takeUntil)(this.disconnecting)).subscribe(e=>this.fields.add(e.detail)),(0,r.fromEvent)(this,`click`).pipe((0,r.takeUntil)(this.disconnecting)).subscribe(e=>this.maybeRequestSubmit(e)),(0,r.fromEvent)(this,`keydown`).pipe((0,r.takeUntil)(this.disconnecting)).subscribe(e=>{if(e.key!==`Enter`||e.shiftKey)return;let t=e.target;t?.tagName!==`TEXTAREA`&&(t?.isContentEditable||this.maybeRequestSubmit(e))}))}maybeRequestSubmit(e){if(e.type===`click`){let t=e.composedPath();if(t.find(e=>s(e)&&e.getAttribute(`type`)===`reset`))return e.preventDefault(),void(this.shadowRoot?.querySelector(`form`))?.reset();if(!t.find(e=>s(e)&&e.getAttribute(`type`)===`submit`))return;e.preventDefault()}(this.shadowRoot?.querySelector(`form`))?.requestSubmit()}get activeFields(){return[...this.fields].filter(e=>e.isConnected)}async onSubmit(e){if(e.preventDefault(),e.stopPropagation(),this.submitting)return;this.activeFields.filter(e=>e.isValidating).length>0&&(this.broadcastStatus(`submitting`),await new Promise(e=>{let t=()=>{this.activeFields.every(e=>!e.isValidating)?e():requestAnimationFrame(t)};t()})),this.activeFields.forEach(e=>e.markSubmitted());let t=this.activeFields.every(e=>e.checkValidity()),n=o.value;if(!t)return o.set({...n,status:`error`,error:{message:`Validation failed`}}),this.broadcastStatus(`error`,`Validation failed. Please correct the highlighted fields.`),void this.activeFields.find(e=>e.error)?.focus();this.submitting=!0,o.set({...n,status:`submitting`,error:null,submitCount:n.submitCount+1}),this.broadcastStatus(`submitting`);let r=new FormData;for(let e of this.activeFields)for(let[t,n]of e.toFormEntries())r.append(t,n);let i=Object.fromEntries(r),a=this.schema?this.schema.parse(i):i,s=[];this.dispatchEvent(new CustomEvent(`submit`,{detail:{data:a,formData:r,until:e=>s.push(e)}}));try{await Promise.all(s),o.set({...o.value,status:`success`,error:null}),this.broadcastStatus(`success`)}catch(e){let t=e instanceof Error?e.message:String(e);o.set({...o.value,status:`error`,error:{message:t}}),this.broadcastStatus(`error`,t)}finally{this.submitting=!1}}onReset(e){e.stopPropagation(),this.activeFields.forEach(e=>e.resetForm()),o.set({status:`idle`,error:null,submitCount:0}),this.broadcastStatus(`idle`),this.dispatchEvent(new CustomEvent(`reset`))}broadcastStatus(e,t){this.liveStatus=e,this.liveError=t??``;let n=this.internals?.states;if(n){for(let e of[`submitting`,`success`,`error`,`idle`])n.delete(e);n.add(e)}e===`submitting`?this.setAttribute(`aria-busy`,`true`):this.removeAttribute(`aria-busy`),this.dispatchEvent(new CustomEvent(`formstate`,{detail:{...o.value},bubbles:!0,composed:!0}))}setFieldError(e,t){let n=this.activeFields.find(t=>t.name===e);return!!n&&(n.setCustomValidity(t),n.markSubmitted(),!0)}setFormError(e,t){o.set({...o.value,status:`error`,error:{message:e,code:t}}),this.broadcastStatus(`error`,e)}clearSubmitted(){this.activeFields.forEach(e=>e.clearSubmitted()),o.set({...o.value,status:`idle`,error:null}),this.broadcastStatus(`idle`)}submit(){let e=this.shadowRoot?.querySelector(`form`);return!!e&&(e.requestSubmit(),!0)}reset(){(this.shadowRoot?.querySelector(`form`))?.reset()}reportValidity(){return this.activeFields.every(e=>e.reportValidity())}checkValidity(){return this.activeFields.every(e=>e.checkValidity())}getFormData(){let e=new FormData;for(let t of this.activeFields)for(let[n,r]of t.toFormEntries())e.append(n,r);return e}render(){return a.html`
4
6
  <schmancy-context .provides=${[o]}>
5
- <form
6
- ?novalidate=${this.novalidate}
7
- @submit=${this.onSubmit}
8
- @reset=${this.onReset}
9
- >
7
+ <form ?novalidate=${this.novalidate} @submit=${this.onSubmit} @reset=${this.onReset}>
10
8
  <slot></slot>
11
9
  </form>
12
10
  <!--
@@ -17,11 +15,8 @@ require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-PS1u0j1B.cjs`
17
15
  want one. Empty content while idle/submitting/success — only
18
16
  error states populate the region. WCAG 4.1.3 (Status Messages).
19
17
  -->
20
- <div
21
- role="status"
22
- aria-live="assertive"
23
- aria-atomic="true"
24
- class="sr-only"
25
- >${this.liveStatus===`error`?this.liveError:``}</div>
18
+ <div role="status" aria-live="assertive" aria-atomic="true" class="sr-only">
19
+ ${this.liveStatus===`error`?this.liveError:``}
20
+ </div>
26
21
  </schmancy-context>
27
22
  `}};e.u([(0,i.property)({attribute:!1})],c.prototype,`schema`,void 0),e.u([(0,i.property)({type:Boolean})],c.prototype,`novalidate`,void 0),e.u([(0,i.state)()],c.prototype,`liveStatus`,void 0),e.u([(0,i.state)()],c.prototype,`liveError`,void 0);var l=c=e.u([(0,i.customElement)(`schmancy-form`)],c);Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return l}});
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-CoWFnClb.cjs","names":[],"sources":["../src/form/form-state.ts","../src/form/form.ts"],"sourcesContent":["/**\n * Form-level submit state — consumed by `<schmancy-form>` and any descendant\n * (e.g. `<schmancy-button type=\"submit\">` to drive its loading/aria-busy).\n *\n * `<schmancy-form>` wraps its render output in `<schmancy-context\n * .provides=${[formSubmitState]}>` so each instance gets an isolated copy\n * via the schmancy state library's resolveContextual mechanism. Reads of\n * `formSubmitState.value` and writes via `formSubmitState.set(...)` inside\n * the form's subtree resolve to the per-form copy automatically — no\n * `@lit/context` plumbing in user code.\n */\n\nimport { state } from '../state'\n\nexport type FormError = {\n\tmessage: string\n\tcode?: string\n}\n\nexport type FormSubmitState = {\n\tstatus: 'idle' | 'submitting' | 'success' | 'error'\n\terror: FormError | null\n\t/** Increments on every submit attempt — RHF parity. */\n\tsubmitCount: number\n}\n\nexport const formSubmitState = state<FormSubmitState>('schmancy/form-submit').memory({\n\tstatus: 'idle',\n\terror: null,\n\tsubmitCount: 0,\n})\n","/**\n * `<schmancy-form>` — schmancy form owner with isolated submit state.\n *\n * Architecture:\n * - Extends `SchmancyElement` (shadow DOM, RxJS + `disconnecting` conventions).\n * - Renders content inside `<schmancy-context .provides=${[formSubmitState]}>`\n * so each form instance gets an isolated copy of the submit state via the\n * schmancy state library — no `@lit/context` plumbing in user code.\n * - Inner `<form novalidate>` is the native-semantics trigger for Enter-key\n * submit and `type=submit` button activation.\n * - Fields self-register via `FIELD_CONNECT_EVENT` (composed event from\n * `FormFieldMixin.connectedCallback`). Stale refs (from disconnected\n * fields) are filtered by `isConnected` at iteration time.\n *\n * Schema seam — pass any `{ parse(input): T }` object (zod, valibot, ArkType,\n * etc.) via the `schema` property to get typed `submit` event detail.\n */\n\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { fromEvent, takeUntil } from 'rxjs'\nimport { SchmancyElement } from '../../mixins'\nimport { FIELD_CONNECT_EVENT, type IFormFieldMixin } from '../../mixins/formField.mixin'\nimport { formSubmitState, type FormSubmitState, type FormError } from './form-state'\n\n/** Structural type matching zod, valibot, ArkType, etc. — any schema with `.parse()`. */\nexport interface ParseSchema<T = unknown> {\n\tparse(input: unknown): T\n}\n\nconst isButton = (node: EventTarget): node is HTMLElement => {\n\tif (!(node instanceof HTMLElement)) return false\n\treturn node.tagName === 'BUTTON' || node.tagName === 'SCHMANCY-BUTTON'\n}\n\n/** Submit event detail. `data` is typed when `schema` is set. */\nexport type SchmancyFormSubmitDetail<T = Record<string, FormDataEntryValue>> = {\n\tdata: T\n\tformData: FormData\n\t/**\n\t * Register a promise that gates the form's success/error state. If unused,\n\t * the form synchronously flips to `success` after dispatch. If used,\n\t * `success`/`error` reflect the promise's outcome.\n\t */\n\tuntil(p: Promise<unknown>): void\n}\n\n@customElement('schmancy-form')\nexport default class SchmancyForm<TSchema extends ParseSchema | undefined = undefined> extends SchmancyElement {\n\tstatic styles = css`\n\t\t:host {\n\t\t\tdisplay: block;\n\t\t}\n\t`\n\n\tpublic static readonly tagName: string = 'schmancy-form'\n\n\t/**\n\t * Optional schema for parsing FormData on submit. Anything with a\n\t * `.parse(input)` method works (zod, valibot, ArkType). When set, the\n\t * `submit` event's `detail.data` is typed `z.infer<TSchema>`.\n\t */\n\t@property({ attribute: false })\n\tschema?: TSchema\n\n\t/** Skip built-in browser constraint validation. Mirrors `<form novalidate>`. */\n\t@property({ type: Boolean })\n\tnovalidate: boolean = true\n\n\tprivate fields = new Set<IFormFieldMixin>()\n\tprivate submitting = false\n\n\t/**\n\t * Local mirror of the submit-state status — drives the inline live region\n\t * synchronously. Independent of the schmancy-state library's resolution\n\t * chain (which has known cross-await fallback semantics) so the AT-facing\n\t * announcement is always correct for this form instance.\n\t */\n\t@state() private liveStatus: 'idle' | 'submitting' | 'success' | 'error' = 'idle'\n\t@state() private liveError: string = ''\n\tprivate internals: ElementInternals | undefined = (() => {\n\t\ttry {\n\t\t\treturn this.attachInternals()\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t})()\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\n\t\t// Forbid nested <schmancy-form>.\n\t\tif (this.parentElement?.closest('schmancy-form')) {\n\t\t\tconsole.error('[schmancy-form] nested <schmancy-form> is not supported')\n\t\t\treturn\n\t\t}\n\n\t\t// Field registry — composed event from FormFieldMixin.connectedCallback.\n\t\tfromEvent<CustomEvent<IFormFieldMixin>>(this, FIELD_CONNECT_EVENT)\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => this.fields.add(e.detail))\n\n\t\t// Submit-trigger interception — slotted descendants live in light DOM\n\t\t// while the inner <form> is in shadow DOM, so native form-association\n\t\t// across the shadow boundary doesn't work for `<button type=submit>`.\n\t\t// Capture clicks on type=submit buttons (native + schmancy-button) and\n\t\t// Enter keys on registered fields, then call the inner form's\n\t\t// requestSubmit() which fires the same native submit event handler\n\t\t// chain that a directly-associated button would have triggered.\n\t\tfromEvent<MouseEvent>(this, 'click')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => this.maybeRequestSubmit(e))\n\t\tfromEvent<KeyboardEvent>(this, 'keydown')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.key !== 'Enter' || e.shiftKey) return\n\t\t\t\t// Skip Enter inside <textarea> (newline) and contenteditable.\n\t\t\t\tconst target = e.target as HTMLElement | null\n\t\t\t\tif (target?.tagName === 'TEXTAREA') return\n\t\t\t\tif (target?.isContentEditable) return\n\t\t\t\tthis.maybeRequestSubmit(e)\n\t\t\t})\n\t}\n\n\tprivate maybeRequestSubmit(e: Event): void {\n\t\t// On click: trigger only when the target is a type=submit button.\n\t\t// On keydown(Enter): always trigger if focus is on a registered field.\n\t\t// type=reset is handled separately in maybeReset.\n\t\tif (e.type === 'click') {\n\t\t\tconst path = e.composedPath()\n\t\t\tconst resetBtn = path.find(node => isButton(node) && node.getAttribute('type') === 'reset')\n\t\t\tif (resetBtn) {\n\t\t\t\te.preventDefault()\n\t\t\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\t\t\tform?.reset()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst submitBtn = path.find(node => isButton(node) && node.getAttribute('type') === 'submit')\n\t\t\tif (!submitBtn) return\n\t\t\te.preventDefault()\n\t\t}\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tform?.requestSubmit()\n\t}\n\n\t/** Active fields — drops stale refs from disconnected nodes. */\n\tprivate get activeFields(): IFormFieldMixin[] {\n\t\treturn [...this.fields].filter(f => f.isConnected)\n\t}\n\n\tprivate async onSubmit(e: SubmitEvent): Promise<void> {\n\t\te.preventDefault()\n\t\te.stopPropagation()\n\t\tif (this.submitting) return\n\n\t\t// If any field has an async validator pending, wait for them all to\n\t\t// settle before deciding validity. This is the hard-block model: the\n\t\t// user clicks submit, the form holds (aria-busy=\"true\"), waits for\n\t\t// validators, then proceeds with the truth they reported.\n\t\tconst pendingValidators = this.activeFields.filter(f => f.isValidating)\n\t\tif (pendingValidators.length > 0) {\n\t\t\tthis.broadcastStatus('submitting')\n\t\t\tawait new Promise<void>(resolve => {\n\t\t\t\tconst tick = () => {\n\t\t\t\t\tif (this.activeFields.every(f => !f.isValidating)) resolve()\n\t\t\t\t\telse requestAnimationFrame(tick)\n\t\t\t\t}\n\t\t\t\ttick()\n\t\t\t})\n\t\t}\n\n\t\t// Phase 4 — submit forces error display on every field.\n\t\tthis.activeFields.forEach(f => f.markSubmitted())\n\n\t\t// Validate; success path entered ONLY if all valid.\n\t\tconst allValid = this.activeFields.every(f => f.checkValidity())\n\t\tconst fs = formSubmitState.value\n\t\tif (!allValid) {\n\t\t\tformSubmitState.set({\n\t\t\t\t...fs,\n\t\t\t\tstatus: 'error',\n\t\t\t\terror: { message: 'Validation failed' },\n\t\t\t})\n\t\t\tthis.broadcastStatus('error', 'Validation failed. Please correct the highlighted fields.')\n\t\t\tconst firstInvalid = this.activeFields.find(f => f.error) as unknown as HTMLElement | undefined\n\t\t\tfirstInvalid?.focus()\n\t\t\treturn\n\t\t}\n\n\t\tthis.submitting = true\n\t\tformSubmitState.set({\n\t\t\t...fs,\n\t\t\tstatus: 'submitting',\n\t\t\terror: null,\n\t\t\tsubmitCount: fs.submitCount + 1,\n\t\t})\n\t\tthis.broadcastStatus('submitting')\n\n\t\t// Build payload from the registered fields' contracted toFormEntries().\n\t\tconst formData = new FormData()\n\t\tfor (const field of this.activeFields) {\n\t\t\tfor (const [k, v] of field.toFormEntries()) formData.append(k, v)\n\t\t}\n\t\tconst raw = Object.fromEntries(formData)\n\t\tconst data = this.schema ? this.schema.parse(raw) : raw\n\n\t\t// Awaitable submit — consumers register promises via e.detail.until(p).\n\t\tconst pending: Promise<unknown>[] = []\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<SchmancyFormSubmitDetail<unknown>>('submit', {\n\t\t\t\tdetail: {\n\t\t\t\t\tdata,\n\t\t\t\t\tformData,\n\t\t\t\t\tuntil: (p: Promise<unknown>) => pending.push(p),\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\n\t\ttry {\n\t\t\tawait Promise.all(pending)\n\t\t\tformSubmitState.set({\n\t\t\t\t...formSubmitState.value,\n\t\t\t\tstatus: 'success',\n\t\t\t\terror: null,\n\t\t\t})\n\t\t\tthis.broadcastStatus('success')\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err)\n\t\t\tformSubmitState.set({\n\t\t\t\t...formSubmitState.value,\n\t\t\t\tstatus: 'error',\n\t\t\t\terror: { message },\n\t\t\t})\n\t\t\tthis.broadcastStatus('error', message)\n\t\t} finally {\n\t\t\tthis.submitting = false\n\t\t}\n\t}\n\n\tprivate onReset(e: Event): void {\n\t\te.stopPropagation()\n\t\tthis.activeFields.forEach(f => f.resetForm())\n\t\tformSubmitState.set({ status: 'idle', error: null, submitCount: 0 })\n\t\tthis.broadcastStatus('idle')\n\t\tthis.dispatchEvent(new CustomEvent('reset'))\n\t}\n\n\tprivate broadcastStatus(status: FormSubmitState['status'], errorMessage?: string): void {\n\t\tthis.liveStatus = status\n\t\tthis.liveError = errorMessage ?? ''\n\t\tconst states = this.internals?.states\n\t\tif (states) {\n\t\t\tfor (const s of ['submitting', 'success', 'error', 'idle']) states.delete(s)\n\t\t\tstates.add(status)\n\t\t}\n\t\t// aria-busy on the host while submitting (WCAG 2.2 AA — disabled buttons\n\t\t// drop from tab order; keep them focusable, signal busy via aria).\n\t\tif (status === 'submitting') this.setAttribute('aria-busy', 'true')\n\t\telse this.removeAttribute('aria-busy')\n\t\t// Public formstate event — external state stores subscribe without\n\t\t// having to consume formSubmitState directly.\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<FormSubmitState>('formstate', {\n\t\t\t\tdetail: { ...formSubmitState.value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\t/**\n\t * Server-side error mapping (RHF `setError(name, ...)`-equivalent).\n\t * Sets `setCustomValidity(message)` on the matching field and ensures the\n\t * error displays by marking it submitted.\n\t */\n\tpublic setFieldError(name: string, message: string): boolean {\n\t\tconst field = this.activeFields.find(f => f.name === name)\n\t\tif (!field) return false\n\t\tfield.setCustomValidity(message)\n\t\tfield.markSubmitted()\n\t\treturn true\n\t}\n\n\t/**\n\t * Top-of-form error (RHF `setError('root.serverError', ...)`-equivalent).\n\t * Flips form status to 'error' with a structured `FormError`.\n\t */\n\tpublic setFormError(message: string, code?: string): void {\n\t\tformSubmitState.set({\n\t\t\t...formSubmitState.value,\n\t\t\tstatus: 'error',\n\t\t\terror: { message, code } as FormError,\n\t\t})\n\t\tthis.broadcastStatus('error', message)\n\t}\n\n\t/**\n\t * Clear the `submitted` flag on every registered field without resetting\n\t * their values. Wizard pattern: stepping back from a later step should not\n\t * leave the earlier step's fields in aggressive \"show all errors\" mode\n\t * (which `submitted = true` triggers via the `shouldShowError()` gate).\n\t *\n\t * Pristine fields with `validateOn: 'dirty'` go quiet again. Fields the\n\t * user actually dirtied keep showing their errors (correct UX — those are\n\t * still genuine mistakes the user can see).\n\t */\n\tpublic clearSubmitted(): void {\n\t\tthis.activeFields.forEach(f => f.clearSubmitted())\n\t\tformSubmitState.set({\n\t\t\t...formSubmitState.value,\n\t\t\tstatus: 'idle',\n\t\t\terror: null,\n\t\t})\n\t\tthis.broadcastStatus('idle')\n\t}\n\n\t/** Programmatically submit via the native submitter pipeline. */\n\tpublic submit(): boolean {\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tif (!form) return false\n\t\tform.requestSubmit()\n\t\treturn true\n\t}\n\n\t/** Programmatically reset via native `form.reset()`. */\n\tpublic reset(): void {\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tform?.reset()\n\t}\n\n\tpublic reportValidity(): boolean {\n\t\treturn this.activeFields.every(f => f.reportValidity())\n\t}\n\n\tpublic checkValidity(): boolean {\n\t\treturn this.activeFields.every(f => f.checkValidity())\n\t}\n\n\t/** Snapshot of current form values from the registered fields. */\n\tpublic getFormData(): FormData {\n\t\tconst formData = new FormData()\n\t\tfor (const field of this.activeFields) {\n\t\t\tfor (const [k, v] of field.toFormEntries()) formData.append(k, v)\n\t\t}\n\t\treturn formData\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<schmancy-context .provides=${[formSubmitState]}>\n\t\t\t\t<form ?novalidate=${this.novalidate} @submit=${this.onSubmit} @reset=${this.onReset}>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</form>\n\t\t\t\t<!--\n\t\t\t\t\tForm-level live region — assistive tech announces server-side\n\t\t\t\t\tform errors (validation summary, network failure, server reject)\n\t\t\t\t\there. Visually hidden via the .sr-only convention; consumers\n\t\t\t\t\trender their own visible banner from formSubmitState if they\n\t\t\t\t\twant one. Empty content while idle/submitting/success — only\n\t\t\t\t\terror states populate the region. WCAG 4.1.3 (Status Messages).\n\t\t\t\t-->\n\t\t\t\t<div role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"sr-only\">\n\t\t\t\t\t${this.liveStatus === 'error' ? this.liveError : ''}\n\t\t\t\t</div>\n\t\t\t</schmancy-context>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form': SchmancyForm\n\t}\n}\n\n// Retained type surfaces — kept exported because downstream code may import\n// them as documentation. The new implementation no longer uses them\n// internally.\n\nexport interface FormElement extends HTMLElement {\n\tname?: string\n\tvalue?: string\n\tdisabled?: boolean\n\ttype?: string\n\tdefaultValue?: string\n}\n\nexport interface CheckableFormElement extends FormElement {\n\tchecked?: boolean\n}\n\nexport interface ValidatableFormElement extends FormElement {\n\treportValidity?: () => boolean\n\tcheckValidity?: () => boolean\n}\n\nexport interface FormEventMap {\n\tsubmit: CustomEvent<SchmancyFormSubmitDetail<unknown>>\n\treset: CustomEvent\n\tformstate: CustomEvent<FormSubmitState>\n}\n"],"mappings":"6NA0BA,IAAa,EAAkB,EAAA,EAAuB,sBAAA,EAAwB,OAAO,CACpF,OAAQ,OACR,MAAO,KACP,YAAa,CAAA,CAAA,ECCR,EAAY,GACX,aAAgB,cACf,EAAK,UAAY,UAAY,EAAK,UAAY,mBAgBvC,EAAA,cAAgF,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,WAAA,CAmBxE,EAAA,KAAA,OAEL,IAAI,IAAA,KAAA,WAAA,CACA,EAAA,KAAA,WAQsD,OAAA,KAAA,UACtC,GAAA,KAAA,eAAA,CAEpC,GAAA,CACC,OAAO,KAAK,gBAAA,CACb,MAAA,CACC,MACD,CACD,GAAA,CAAA,CAAA,OAAA,KAAA,OArCgB,EAAA,GAAG;;;;uBAMsB,eAAA,CAiCzC,mBAAA,CACC,MAAM,kBAAA,EAGF,KAAK,eAAe,QAAQ,eAAA,KAMhC,EAAA,EAAA,WAAwC,KAAM,EAAA,CAAA,EAC5C,MAAA,EAAA,EAAA,WAAe,KAAK,aAAA,CAAA,EACpB,UAAU,GAAK,KAAK,OAAO,IAAI,EAAE,MAAA,CAAA,GASnC,EAAA,EAAA,WAAsB,KAAM,OAAA,EAC1B,MAAA,EAAA,EAAA,WAAe,KAAK,aAAA,CAAA,EACpB,UAAU,GAAK,KAAK,mBAAmB,CAAA,CAAA,GACzC,EAAA,EAAA,WAAyB,KAAM,SAAA,EAC7B,MAAA,EAAA,EAAA,WAAe,KAAK,aAAA,CAAA,EACpB,UAAU,GAAA,CACV,GAAI,EAAE,MAAQ,SAAW,EAAE,SAAU,OAErC,IAAM,EAAS,EAAE,OACb,GAAQ,UAAY,aACpB,GAAQ,mBACZ,KAAK,mBAAmB,CAAA,EAAA,CAAA,EAE3B,CAEA,mBAA2B,EAAA,CAI1B,GAAI,EAAE,OAAS,QAAS,CACvB,IAAM,EAAO,EAAE,aAAA,EAEf,GADiB,EAAK,KAAK,GAAQ,EAAS,CAAA,GAAS,EAAK,aAAa,MAAA,IAAY,OAAZ,EAKtE,OAHA,EAAE,eAAA,EAAA,KACW,KAAK,YAAY,cAAc,MAAA,IACtC,MAAA,EAIP,GAAA,CADkB,EAAK,KAAK,GAAQ,EAAS,CAAA,GAAS,EAAK,aAAa,MAAA,IAAY,QAAZ,EACxD,OAChB,EAAE,eAAA,CACH,EACa,KAAK,YAAY,cAAc,MAAA,IACtC,cAAA,CACP,CAGA,IAAA,cAAY,CACX,MAAO,CAAA,GAAI,KAAK,MAAA,EAAQ,OAAO,GAAK,EAAE,WAAA,CACvC,CAEA,MAAA,SAAuB,EAAA,CAGtB,GAFA,EAAE,eAAA,EACF,EAAE,gBAAA,EACE,KAAK,WAAY,OAMK,KAAK,aAAa,OAAO,GAAK,EAAE,YAAA,EACpC,OAAS,IAC9B,KAAK,gBAAgB,YAAA,EAAA,MACf,IAAI,QAAc,GAAA,CACvB,IAAM,MAAA,CACD,KAAK,aAAa,MAAM,GAAA,CAAM,EAAE,YAAA,EAAe,EAAA,EAC9C,sBAAsB,CAAA,CAAA,EAE5B,EAAA,CAAA,CAAA,GAKF,KAAK,aAAa,QAAQ,GAAK,EAAE,cAAA,CAAA,EAGjC,IAAM,EAAW,KAAK,aAAa,MAAM,GAAK,EAAE,cAAA,CAAA,EAC1C,EAAK,EAAgB,MAC3B,GAAA,CAAK,EASJ,OARA,EAAgB,IAAI,CAAA,GAChB,EACH,OAAQ,QACR,MAAO,CAAE,QAAS,mBAAA,CAAA,CAAA,EAEnB,KAAK,gBAAgB,QAAS,2DAAA,EAAA,KAE9B,KAD0B,aAAa,KAAK,GAAK,EAAE,KAAA,GACrC,MAAA,EAIf,KAAK,WAAA,CAAa,EAClB,EAAgB,IAAI,CAAA,GAChB,EACH,OAAQ,aACR,MAAO,KACP,YAAa,EAAG,YAAc,CAAA,CAAA,EAE/B,KAAK,gBAAgB,YAAA,EAGrB,IAAM,EAAW,IAAI,SACrB,IAAK,IAAM,KAAS,KAAK,aACxB,IAAK,GAAA,CAAO,EAAG,KAAM,EAAM,cAAA,EAAiB,EAAS,OAAO,EAAG,CAAA,EAEhE,IAAM,EAAM,OAAO,YAAY,CAAA,EACzB,EAAO,KAAK,OAAS,KAAK,OAAO,MAAM,CAAA,EAAO,EAG9C,EAA8B,CAAA,EACpC,KAAK,cACJ,IAAI,YAA+C,SAAU,CAC5D,OAAQ,CACP,KAAA,EACA,SAAA,EACA,MAAQ,GAAwB,EAAQ,KAAK,CAAA,CAAA,CAAA,CAAA,CAAA,EAKhD,GAAA,CAAA,MACO,QAAQ,IAAI,CAAA,EAClB,EAAgB,IAAI,CAAA,GAChB,EAAgB,MACnB,OAAQ,UACR,MAAO,IAAA,CAAA,EAER,KAAK,gBAAgB,SAAA,CACtB,OAAS,EAAA,CACR,IAAM,EAAU,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAA,EAC5D,EAAgB,IAAI,CAAA,GAChB,EAAgB,MACnB,OAAQ,QACR,MAAO,CAAE,QAAA,CAAA,CAAA,CAAA,EAEV,KAAK,gBAAgB,QAAS,CAAA,CAC/B,QAAA,CACC,KAAK,WAAA,CAAa,CACnB,CACD,CAEA,QAAgB,EAAA,CACf,EAAE,gBAAA,EACF,KAAK,aAAa,QAAQ,GAAK,EAAE,UAAA,CAAA,EACjC,EAAgB,IAAI,CAAE,OAAQ,OAAQ,MAAO,KAAM,YAAa,CAAA,CAAA,EAChE,KAAK,gBAAgB,MAAA,EACrB,KAAK,cAAc,IAAI,YAAY,OAAA,CAAA,CACpC,CAEA,gBAAwB,EAAmC,EAAA,CAC1D,KAAK,WAAa,EAClB,KAAK,UAAY,GAAgB,GACjC,IAAM,EAAS,KAAK,WAAW,OAC/B,GAAI,EAAQ,CACX,IAAK,IAAM,IAAK,CAAC,aAAc,UAAW,QAAS,MAAA,EAAS,EAAO,OAAO,CAAA,EAC1E,EAAO,IAAI,CAAA,CACZ,CAGI,IAAW,aAAc,KAAK,aAAa,YAAa,MAAA,EACvD,KAAK,gBAAgB,WAAA,EAG1B,KAAK,cACJ,IAAI,YAA6B,YAAa,CAC7C,OAAQ,CAAA,GAAK,EAAgB,KAAA,EAC7B,QAAA,CAAS,EACT,SAAA,CAAU,CAAA,CAAA,CAAA,CAGb,CAOA,cAAqB,EAAc,EAAA,CAClC,IAAM,EAAQ,KAAK,aAAa,KAAK,GAAK,EAAE,OAAS,CAAA,EACrD,MAAA,CAAA,CAAK,IACL,EAAM,kBAAkB,CAAA,EACxB,EAAM,cAAA,EAAA,CACC,EACR,CAMA,aAAoB,EAAiB,EAAA,CACpC,EAAgB,IAAI,CAAA,GAChB,EAAgB,MACnB,OAAQ,QACR,MAAO,CAAE,QAAA,EAAS,KAAA,CAAA,CAAA,CAAA,EAEnB,KAAK,gBAAgB,QAAS,CAAA,CAC/B,CAYA,gBAAA,CACC,KAAK,aAAa,QAAQ,GAAK,EAAE,eAAA,CAAA,EACjC,EAAgB,IAAI,CAAA,GAChB,EAAgB,MACnB,OAAQ,OACR,MAAO,IAAA,CAAA,EAER,KAAK,gBAAgB,MAAA,CACtB,CAGA,QAAA,CACC,IAAM,EAAO,KAAK,YAAY,cAAc,MAAA,EAC5C,MAAA,CAAA,CAAK,IACL,EAAK,cAAA,EAAA,CACE,EACR,CAGA,OAAA,EACc,KAAK,YAAY,cAAc,MAAA,IACtC,MAAA,CACP,CAEA,gBAAA,CACC,OAAO,KAAK,aAAa,MAAM,GAAK,EAAE,eAAA,CAAA,CACvC,CAEA,eAAA,CACC,OAAO,KAAK,aAAa,MAAM,GAAK,EAAE,cAAA,CAAA,CACvC,CAGA,aAAA,CACC,IAAM,EAAW,IAAI,SACrB,IAAK,IAAM,KAAS,KAAK,aACxB,IAAK,GAAA,CAAO,EAAG,KAAM,EAAM,cAAA,EAAiB,EAAS,OAAO,EAAG,CAAA,EAEhE,OAAO,CACR,CAEA,QAAA,CACC,MAAO,GAAA,IAAI;iCACoB,CAAC,CAAA,EAAA;wBACV,KAAK,WAAA,WAAsB,KAAK,SAAA,UAAmB,KAAK,QAAA;;;;;;;;;;;;OAYzE,KAAK,aAAe,QAAU,KAAK,UAAY,GAAA;;;GAIrD,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAhTU,CAAE,UAAA,CAAW,CAAA,CAAA,CAAA,EAAO,EAAA,UAAA,SAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAIpB,CAAE,KAAM,OAAA,CAAA,CAAA,EAAS,EAAA,UAAA,aAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EAYpB,EAAA,UAAA,aAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EACA,EAAA,UAAA,YAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAhCO,eAAA,CAAA,EAAe,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
@@ -1,6 +1,6 @@
1
- import { t as e, u as t } from "./SchmancyElement-OG71FtNv.js";
2
- import { r as n } from "./mixins-bCEXbwJV.js";
3
- import { s as r } from "./state-DMd_FUeA.js";
1
+ import { t as e, u as t } from "./SchmancyElement-Ob9yGkiG.js";
2
+ import { r as n } from "./mixins-q4KAL8Xr.js";
3
+ import { s as r } from "./state-DBA_gzJO.js";
4
4
  import { fromEvent as i, takeUntil as a } from "rxjs";
5
5
  import { customElement as o, property as s, state as c } from "lit/decorators.js";
6
6
  import { css as l, html as u } from "lit";
@@ -20,7 +20,9 @@ var d = r("schmancy/form-submit").memory({
20
20
  }
21
21
  static {
22
22
  this.styles = l`
23
- :host { display: block; }
23
+ :host {
24
+ display: block;
25
+ }
24
26
  `;
25
27
  }
26
28
  static {
@@ -157,11 +159,7 @@ var d = r("schmancy/form-submit").memory({
157
159
  render() {
158
160
  return u`
159
161
  <schmancy-context .provides=${[d]}>
160
- <form
161
- ?novalidate=${this.novalidate}
162
- @submit=${this.onSubmit}
163
- @reset=${this.onReset}
164
- >
162
+ <form ?novalidate=${this.novalidate} @submit=${this.onSubmit} @reset=${this.onReset}>
165
163
  <slot></slot>
166
164
  </form>
167
165
  <!--
@@ -172,12 +170,9 @@ var d = r("schmancy/form-submit").memory({
172
170
  want one. Empty content while idle/submitting/success — only
173
171
  error states populate the region. WCAG 4.1.3 (Status Messages).
174
172
  -->
175
- <div
176
- role="status"
177
- aria-live="assertive"
178
- aria-atomic="true"
179
- class="sr-only"
180
- >${this.liveStatus === "error" ? this.liveError : ""}</div>
173
+ <div role="status" aria-live="assertive" aria-atomic="true" class="sr-only">
174
+ ${this.liveStatus === "error" ? this.liveError : ""}
175
+ </div>
181
176
  </schmancy-context>
182
177
  `;
183
178
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-hC2LvCHX.js","names":[],"sources":["../src/form/form-state.ts","../src/form/form.ts"],"sourcesContent":["/**\n * Form-level submit state — consumed by `<schmancy-form>` and any descendant\n * (e.g. `<schmancy-button type=\"submit\">` to drive its loading/aria-busy).\n *\n * `<schmancy-form>` wraps its render output in `<schmancy-context\n * .provides=${[formSubmitState]}>` so each instance gets an isolated copy\n * via the schmancy state library's resolveContextual mechanism. Reads of\n * `formSubmitState.value` and writes via `formSubmitState.set(...)` inside\n * the form's subtree resolve to the per-form copy automatically — no\n * `@lit/context` plumbing in user code.\n */\n\nimport { state } from '../state'\n\nexport type FormError = {\n\tmessage: string\n\tcode?: string\n}\n\nexport type FormSubmitState = {\n\tstatus: 'idle' | 'submitting' | 'success' | 'error'\n\terror: FormError | null\n\t/** Increments on every submit attempt — RHF parity. */\n\tsubmitCount: number\n}\n\nexport const formSubmitState = state<FormSubmitState>('schmancy/form-submit').memory({\n\tstatus: 'idle',\n\terror: null,\n\tsubmitCount: 0,\n})\n","/**\n * `<schmancy-form>` — schmancy form owner with isolated submit state.\n *\n * Architecture:\n * - Extends `SchmancyElement` (shadow DOM, RxJS + `disconnecting` conventions).\n * - Renders content inside `<schmancy-context .provides=${[formSubmitState]}>`\n * so each form instance gets an isolated copy of the submit state via the\n * schmancy state library — no `@lit/context` plumbing in user code.\n * - Inner `<form novalidate>` is the native-semantics trigger for Enter-key\n * submit and `type=submit` button activation.\n * - Fields self-register via `FIELD_CONNECT_EVENT` (composed event from\n * `FormFieldMixin.connectedCallback`). Stale refs (from disconnected\n * fields) are filtered by `isConnected` at iteration time.\n *\n * Schema seam — pass any `{ parse(input): T }` object (zod, valibot, ArkType,\n * etc.) via the `schema` property to get typed `submit` event detail.\n */\n\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { fromEvent, takeUntil } from 'rxjs'\nimport { SchmancyElement } from '../../mixins'\nimport { FIELD_CONNECT_EVENT, type IFormFieldMixin } from '../../mixins/formField.mixin'\nimport { formSubmitState, type FormSubmitState, type FormError } from './form-state'\n\n/** Structural type matching zod, valibot, ArkType, etc. — any schema with `.parse()`. */\nexport interface ParseSchema<T = unknown> {\n\tparse(input: unknown): T\n}\n\nconst isButton = (node: EventTarget): node is HTMLElement => {\n\tif (!(node instanceof HTMLElement)) return false\n\treturn node.tagName === 'BUTTON' || node.tagName === 'SCHMANCY-BUTTON'\n}\n\n/** Submit event detail. `data` is typed when `schema` is set. */\nexport type SchmancyFormSubmitDetail<T = Record<string, FormDataEntryValue>> = {\n\tdata: T\n\tformData: FormData\n\t/**\n\t * Register a promise that gates the form's success/error state. If unused,\n\t * the form synchronously flips to `success` after dispatch. If used,\n\t * `success`/`error` reflect the promise's outcome.\n\t */\n\tuntil(p: Promise<unknown>): void\n}\n\n@customElement('schmancy-form')\nexport default class SchmancyForm<TSchema extends ParseSchema | undefined = undefined> extends SchmancyElement {\n\tstatic styles = css`\n\t\t:host {\n\t\t\tdisplay: block;\n\t\t}\n\t`\n\n\tpublic static readonly tagName: string = 'schmancy-form'\n\n\t/**\n\t * Optional schema for parsing FormData on submit. Anything with a\n\t * `.parse(input)` method works (zod, valibot, ArkType). When set, the\n\t * `submit` event's `detail.data` is typed `z.infer<TSchema>`.\n\t */\n\t@property({ attribute: false })\n\tschema?: TSchema\n\n\t/** Skip built-in browser constraint validation. Mirrors `<form novalidate>`. */\n\t@property({ type: Boolean })\n\tnovalidate: boolean = true\n\n\tprivate fields = new Set<IFormFieldMixin>()\n\tprivate submitting = false\n\n\t/**\n\t * Local mirror of the submit-state status — drives the inline live region\n\t * synchronously. Independent of the schmancy-state library's resolution\n\t * chain (which has known cross-await fallback semantics) so the AT-facing\n\t * announcement is always correct for this form instance.\n\t */\n\t@state() private liveStatus: 'idle' | 'submitting' | 'success' | 'error' = 'idle'\n\t@state() private liveError: string = ''\n\tprivate internals: ElementInternals | undefined = (() => {\n\t\ttry {\n\t\t\treturn this.attachInternals()\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t})()\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\n\t\t// Forbid nested <schmancy-form>.\n\t\tif (this.parentElement?.closest('schmancy-form')) {\n\t\t\tconsole.error('[schmancy-form] nested <schmancy-form> is not supported')\n\t\t\treturn\n\t\t}\n\n\t\t// Field registry — composed event from FormFieldMixin.connectedCallback.\n\t\tfromEvent<CustomEvent<IFormFieldMixin>>(this, FIELD_CONNECT_EVENT)\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => this.fields.add(e.detail))\n\n\t\t// Submit-trigger interception — slotted descendants live in light DOM\n\t\t// while the inner <form> is in shadow DOM, so native form-association\n\t\t// across the shadow boundary doesn't work for `<button type=submit>`.\n\t\t// Capture clicks on type=submit buttons (native + schmancy-button) and\n\t\t// Enter keys on registered fields, then call the inner form's\n\t\t// requestSubmit() which fires the same native submit event handler\n\t\t// chain that a directly-associated button would have triggered.\n\t\tfromEvent<MouseEvent>(this, 'click')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => this.maybeRequestSubmit(e))\n\t\tfromEvent<KeyboardEvent>(this, 'keydown')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.key !== 'Enter' || e.shiftKey) return\n\t\t\t\t// Skip Enter inside <textarea> (newline) and contenteditable.\n\t\t\t\tconst target = e.target as HTMLElement | null\n\t\t\t\tif (target?.tagName === 'TEXTAREA') return\n\t\t\t\tif (target?.isContentEditable) return\n\t\t\t\tthis.maybeRequestSubmit(e)\n\t\t\t})\n\t}\n\n\tprivate maybeRequestSubmit(e: Event): void {\n\t\t// On click: trigger only when the target is a type=submit button.\n\t\t// On keydown(Enter): always trigger if focus is on a registered field.\n\t\t// type=reset is handled separately in maybeReset.\n\t\tif (e.type === 'click') {\n\t\t\tconst path = e.composedPath()\n\t\t\tconst resetBtn = path.find(node => isButton(node) && node.getAttribute('type') === 'reset')\n\t\t\tif (resetBtn) {\n\t\t\t\te.preventDefault()\n\t\t\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\t\t\tform?.reset()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst submitBtn = path.find(node => isButton(node) && node.getAttribute('type') === 'submit')\n\t\t\tif (!submitBtn) return\n\t\t\te.preventDefault()\n\t\t}\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tform?.requestSubmit()\n\t}\n\n\t/** Active fields — drops stale refs from disconnected nodes. */\n\tprivate get activeFields(): IFormFieldMixin[] {\n\t\treturn [...this.fields].filter(f => f.isConnected)\n\t}\n\n\tprivate async onSubmit(e: SubmitEvent): Promise<void> {\n\t\te.preventDefault()\n\t\te.stopPropagation()\n\t\tif (this.submitting) return\n\n\t\t// If any field has an async validator pending, wait for them all to\n\t\t// settle before deciding validity. This is the hard-block model: the\n\t\t// user clicks submit, the form holds (aria-busy=\"true\"), waits for\n\t\t// validators, then proceeds with the truth they reported.\n\t\tconst pendingValidators = this.activeFields.filter(f => f.isValidating)\n\t\tif (pendingValidators.length > 0) {\n\t\t\tthis.broadcastStatus('submitting')\n\t\t\tawait new Promise<void>(resolve => {\n\t\t\t\tconst tick = () => {\n\t\t\t\t\tif (this.activeFields.every(f => !f.isValidating)) resolve()\n\t\t\t\t\telse requestAnimationFrame(tick)\n\t\t\t\t}\n\t\t\t\ttick()\n\t\t\t})\n\t\t}\n\n\t\t// Phase 4 — submit forces error display on every field.\n\t\tthis.activeFields.forEach(f => f.markSubmitted())\n\n\t\t// Validate; success path entered ONLY if all valid.\n\t\tconst allValid = this.activeFields.every(f => f.checkValidity())\n\t\tconst fs = formSubmitState.value\n\t\tif (!allValid) {\n\t\t\tformSubmitState.set({\n\t\t\t\t...fs,\n\t\t\t\tstatus: 'error',\n\t\t\t\terror: { message: 'Validation failed' },\n\t\t\t})\n\t\t\tthis.broadcastStatus('error', 'Validation failed. Please correct the highlighted fields.')\n\t\t\tconst firstInvalid = this.activeFields.find(f => f.error) as unknown as HTMLElement | undefined\n\t\t\tfirstInvalid?.focus()\n\t\t\treturn\n\t\t}\n\n\t\tthis.submitting = true\n\t\tformSubmitState.set({\n\t\t\t...fs,\n\t\t\tstatus: 'submitting',\n\t\t\terror: null,\n\t\t\tsubmitCount: fs.submitCount + 1,\n\t\t})\n\t\tthis.broadcastStatus('submitting')\n\n\t\t// Build payload from the registered fields' contracted toFormEntries().\n\t\tconst formData = new FormData()\n\t\tfor (const field of this.activeFields) {\n\t\t\tfor (const [k, v] of field.toFormEntries()) formData.append(k, v)\n\t\t}\n\t\tconst raw = Object.fromEntries(formData)\n\t\tconst data = this.schema ? this.schema.parse(raw) : raw\n\n\t\t// Awaitable submit — consumers register promises via e.detail.until(p).\n\t\tconst pending: Promise<unknown>[] = []\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<SchmancyFormSubmitDetail<unknown>>('submit', {\n\t\t\t\tdetail: {\n\t\t\t\t\tdata,\n\t\t\t\t\tformData,\n\t\t\t\t\tuntil: (p: Promise<unknown>) => pending.push(p),\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\n\t\ttry {\n\t\t\tawait Promise.all(pending)\n\t\t\tformSubmitState.set({\n\t\t\t\t...formSubmitState.value,\n\t\t\t\tstatus: 'success',\n\t\t\t\terror: null,\n\t\t\t})\n\t\t\tthis.broadcastStatus('success')\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err)\n\t\t\tformSubmitState.set({\n\t\t\t\t...formSubmitState.value,\n\t\t\t\tstatus: 'error',\n\t\t\t\terror: { message },\n\t\t\t})\n\t\t\tthis.broadcastStatus('error', message)\n\t\t} finally {\n\t\t\tthis.submitting = false\n\t\t}\n\t}\n\n\tprivate onReset(e: Event): void {\n\t\te.stopPropagation()\n\t\tthis.activeFields.forEach(f => f.resetForm())\n\t\tformSubmitState.set({ status: 'idle', error: null, submitCount: 0 })\n\t\tthis.broadcastStatus('idle')\n\t\tthis.dispatchEvent(new CustomEvent('reset'))\n\t}\n\n\tprivate broadcastStatus(status: FormSubmitState['status'], errorMessage?: string): void {\n\t\tthis.liveStatus = status\n\t\tthis.liveError = errorMessage ?? ''\n\t\tconst states = this.internals?.states\n\t\tif (states) {\n\t\t\tfor (const s of ['submitting', 'success', 'error', 'idle']) states.delete(s)\n\t\t\tstates.add(status)\n\t\t}\n\t\t// aria-busy on the host while submitting (WCAG 2.2 AA — disabled buttons\n\t\t// drop from tab order; keep them focusable, signal busy via aria).\n\t\tif (status === 'submitting') this.setAttribute('aria-busy', 'true')\n\t\telse this.removeAttribute('aria-busy')\n\t\t// Public formstate event — external state stores subscribe without\n\t\t// having to consume formSubmitState directly.\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<FormSubmitState>('formstate', {\n\t\t\t\tdetail: { ...formSubmitState.value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\t/**\n\t * Server-side error mapping (RHF `setError(name, ...)`-equivalent).\n\t * Sets `setCustomValidity(message)` on the matching field and ensures the\n\t * error displays by marking it submitted.\n\t */\n\tpublic setFieldError(name: string, message: string): boolean {\n\t\tconst field = this.activeFields.find(f => f.name === name)\n\t\tif (!field) return false\n\t\tfield.setCustomValidity(message)\n\t\tfield.markSubmitted()\n\t\treturn true\n\t}\n\n\t/**\n\t * Top-of-form error (RHF `setError('root.serverError', ...)`-equivalent).\n\t * Flips form status to 'error' with a structured `FormError`.\n\t */\n\tpublic setFormError(message: string, code?: string): void {\n\t\tformSubmitState.set({\n\t\t\t...formSubmitState.value,\n\t\t\tstatus: 'error',\n\t\t\terror: { message, code } as FormError,\n\t\t})\n\t\tthis.broadcastStatus('error', message)\n\t}\n\n\t/**\n\t * Clear the `submitted` flag on every registered field without resetting\n\t * their values. Wizard pattern: stepping back from a later step should not\n\t * leave the earlier step's fields in aggressive \"show all errors\" mode\n\t * (which `submitted = true` triggers via the `shouldShowError()` gate).\n\t *\n\t * Pristine fields with `validateOn: 'dirty'` go quiet again. Fields the\n\t * user actually dirtied keep showing their errors (correct UX — those are\n\t * still genuine mistakes the user can see).\n\t */\n\tpublic clearSubmitted(): void {\n\t\tthis.activeFields.forEach(f => f.clearSubmitted())\n\t\tformSubmitState.set({\n\t\t\t...formSubmitState.value,\n\t\t\tstatus: 'idle',\n\t\t\terror: null,\n\t\t})\n\t\tthis.broadcastStatus('idle')\n\t}\n\n\t/** Programmatically submit via the native submitter pipeline. */\n\tpublic submit(): boolean {\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tif (!form) return false\n\t\tform.requestSubmit()\n\t\treturn true\n\t}\n\n\t/** Programmatically reset via native `form.reset()`. */\n\tpublic reset(): void {\n\t\tconst form = this.shadowRoot?.querySelector('form')\n\t\tform?.reset()\n\t}\n\n\tpublic reportValidity(): boolean {\n\t\treturn this.activeFields.every(f => f.reportValidity())\n\t}\n\n\tpublic checkValidity(): boolean {\n\t\treturn this.activeFields.every(f => f.checkValidity())\n\t}\n\n\t/** Snapshot of current form values from the registered fields. */\n\tpublic getFormData(): FormData {\n\t\tconst formData = new FormData()\n\t\tfor (const field of this.activeFields) {\n\t\t\tfor (const [k, v] of field.toFormEntries()) formData.append(k, v)\n\t\t}\n\t\treturn formData\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<schmancy-context .provides=${[formSubmitState]}>\n\t\t\t\t<form ?novalidate=${this.novalidate} @submit=${this.onSubmit} @reset=${this.onReset}>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</form>\n\t\t\t\t<!--\n\t\t\t\t\tForm-level live region — assistive tech announces server-side\n\t\t\t\t\tform errors (validation summary, network failure, server reject)\n\t\t\t\t\there. Visually hidden via the .sr-only convention; consumers\n\t\t\t\t\trender their own visible banner from formSubmitState if they\n\t\t\t\t\twant one. Empty content while idle/submitting/success — only\n\t\t\t\t\terror states populate the region. WCAG 4.1.3 (Status Messages).\n\t\t\t\t-->\n\t\t\t\t<div role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"sr-only\">\n\t\t\t\t\t${this.liveStatus === 'error' ? this.liveError : ''}\n\t\t\t\t</div>\n\t\t\t</schmancy-context>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form': SchmancyForm\n\t}\n}\n\n// Retained type surfaces — kept exported because downstream code may import\n// them as documentation. The new implementation no longer uses them\n// internally.\n\nexport interface FormElement extends HTMLElement {\n\tname?: string\n\tvalue?: string\n\tdisabled?: boolean\n\ttype?: string\n\tdefaultValue?: string\n}\n\nexport interface CheckableFormElement extends FormElement {\n\tchecked?: boolean\n}\n\nexport interface ValidatableFormElement extends FormElement {\n\treportValidity?: () => boolean\n\tcheckValidity?: () => boolean\n}\n\nexport interface FormEventMap {\n\tsubmit: CustomEvent<SchmancyFormSubmitDetail<unknown>>\n\treset: CustomEvent\n\tformstate: CustomEvent<FormSubmitState>\n}\n"],"mappings":";;;;;;AA0BA,IAAa,IAAkB,EAAuB,sBAAA,EAAwB,OAAO;CACpF,QAAQ;CACR,OAAO;CACP,aAAa;AAAA,CAAA,GCCR,KAAY,MACX,aAAgB,gBACf,EAAK,YAAY,YAAY,EAAK,YAAY,oBAgBvC,IAAA,cAAgF,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,aAAA,CAmBxE,GAAA,KAAA,yBAEL,IAAI,IAAA,GAAA,KAAA,aAAA,CACA,GAAA,KAAA,aAQsD,QAAA,KAAA,YACtC,IAAA,KAAA,mBAAA;GAEpC,IAAA;IACC,OAAO,KAAK,gBAAA;GACb,QAAA;IACC;GACD;EACD,GAAA;CAAA;CAAA;EAAA,KAAA,SArCgB,CAAG;;;;;;;iBAMsB;CAAA;CAiCzC,oBAAA;EACC,MAAM,kBAAA,GAGF,KAAK,eAAe,QAAQ,eAAA,MAMhC,EAAwC,MAAM,CAAA,EAC5C,KAAK,EAAU,KAAK,aAAA,CAAA,EACpB,WAAU,MAAK,KAAK,OAAO,IAAI,EAAE,MAAA,CAAA,GASnC,EAAsB,MAAM,OAAA,EAC1B,KAAK,EAAU,KAAK,aAAA,CAAA,EACpB,WAAU,MAAK,KAAK,mBAAmB,CAAA,CAAA,GACzC,EAAyB,MAAM,SAAA,EAC7B,KAAK,EAAU,KAAK,aAAA,CAAA,EACpB,WAAU,MAAA;GACV,IAAI,EAAE,QAAQ,WAAW,EAAE,UAAU;GAErC,IAAM,IAAS,EAAE;GACO,AAApB,GAAQ,YAAY,eACpB,GAAQ,qBACZ,KAAK,mBAAmB,CAAA;EAAA,CAAA;CAE3B;CAEA,mBAA2B,GAAA;EAI1B,IAAI,EAAE,SAAS,SAAS;GACvB,IAAM,IAAO,EAAE,aAAA;GAEf,IADiB,EAAK,MAAK,MAAQ,EAAS,CAAA,KAAS,EAAK,aAAa,MAAA,MAAY,OAAZ,GAKtE,OAHA,EAAE,eAAA,GAAA,MACW,KAAK,YAAY,cAAc,MAAA,IACtC,MAAA;GAIP,IAAA,CADkB,EAAK,MAAK,MAAQ,EAAS,CAAA,KAAS,EAAK,aAAa,MAAA,MAAY,QAAZ,GACxD;GAChB,EAAE,eAAA;EACH;EAAA,CACa,KAAK,YAAY,cAAc,MAAA,IACtC,cAAA;CACP;CAGA,IAAA,eAAY;EACX,OAAO,CAAA,GAAI,KAAK,MAAA,EAAQ,QAAO,MAAK,EAAE,WAAA;CACvC;CAEA,MAAA,SAAuB,GAAA;EAGtB,IAFA,EAAE,eAAA,GACF,EAAE,gBAAA,GACE,KAAK,YAAY;EAMK,KAAK,aAAa,QAAO,MAAK,EAAE,YAAA,EACpC,SAAS,MAC9B,KAAK,gBAAgB,YAAA,GAAA,MACf,IAAI,SAAc,MAAA;GACvB,IAAM,UAAA;IACD,KAAK,aAAa,OAAM,MAAA,CAAM,EAAE,YAAA,IAAe,EAAA,IAC9C,sBAAsB,CAAA;GAAA;GAE5B,EAAA;EAAA,CAAA,IAKF,KAAK,aAAa,SAAQ,MAAK,EAAE,cAAA,CAAA;EAGjC,IAAM,IAAW,KAAK,aAAa,OAAM,MAAK,EAAE,cAAA,CAAA,GAC1C,IAAK,EAAgB;EAC3B,IAAA,CAAK,GASJ,OARA,EAAgB,IAAI;GAAA,GAChB;GACH,QAAQ;GACR,OAAO,EAAE,SAAS,oBAAA;EAAA,CAAA,GAEnB,KAAK,gBAAgB,SAAS,2DAAA,GAAA,KAE9B,KAD0B,aAAa,MAAK,MAAK,EAAE,KAAA,GACrC,MAAA;EAIf,KAAK,aAAA,CAAa,GAClB,EAAgB,IAAI;GAAA,GAChB;GACH,QAAQ;GACR,OAAO;GACP,aAAa,EAAG,cAAc;EAAA,CAAA,GAE/B,KAAK,gBAAgB,YAAA;EAGrB,IAAM,IAAW,IAAI,SAAA;EACrB,KAAK,IAAM,KAAS,KAAK,cACxB,KAAK,IAAA,CAAO,GAAG,MAAM,EAAM,cAAA,GAAiB,EAAS,OAAO,GAAG,CAAA;EAEhE,IAAM,IAAM,OAAO,YAAY,CAAA,GACzB,IAAO,KAAK,SAAS,KAAK,OAAO,MAAM,CAAA,IAAO,GAG9C,IAA8B,CAAA;EACpC,KAAK,cACJ,IAAI,YAA+C,UAAU,EAC5D,QAAQ;GACP,MAAA;GACA,UAAA;GACA,QAAQ,MAAwB,EAAQ,KAAK,CAAA;EAAA,EAAA,CAAA,CAAA;EAKhD,IAAA;GAAA,MACO,QAAQ,IAAI,CAAA,GAClB,EAAgB,IAAI;IAAA,GAChB,EAAgB;IACnB,QAAQ;IACR,OAAO;GAAA,CAAA,GAER,KAAK,gBAAgB,SAAA;EACtB,SAAS,GAAA;GACR,IAAM,IAAU,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAA;GAC5D,EAAgB,IAAI;IAAA,GAChB,EAAgB;IACnB,QAAQ;IACR,OAAO,EAAE,SAAA,EAAA;GAAA,CAAA,GAEV,KAAK,gBAAgB,SAAS,CAAA;EAC/B,UAAA;GACC,KAAK,aAAA,CAAa;EACnB;CACD;CAEA,QAAgB,GAAA;EACf,EAAE,gBAAA,GACF,KAAK,aAAa,SAAQ,MAAK,EAAE,UAAA,CAAA,GACjC,EAAgB,IAAI;GAAE,QAAQ;GAAQ,OAAO;GAAM,aAAa;EAAA,CAAA,GAChE,KAAK,gBAAgB,MAAA,GACrB,KAAK,cAAc,IAAI,YAAY,OAAA,CAAA;CACpC;CAEA,gBAAwB,GAAmC,GAAA;EAC1D,KAAK,aAAa,GAClB,KAAK,YAAY,KAAgB;EACjC,IAAM,IAAS,KAAK,WAAW;EAC/B,IAAI,GAAQ;GACX,KAAK,IAAM,KAAK;IAAC;IAAc;IAAW;IAAS;GAAA,GAAS,EAAO,OAAO,CAAA;GAC1E,EAAO,IAAI,CAAA;EACZ;EAGe,AAAX,MAAW,eAAc,KAAK,aAAa,aAAa,MAAA,IACvD,KAAK,gBAAgB,WAAA,GAG1B,KAAK,cACJ,IAAI,YAA6B,aAAa;GAC7C,QAAQ,EAAA,GAAK,EAAgB,MAAA;GAC7B,SAAA,CAAS;GACT,UAAA,CAAU;EAAA,CAAA,CAAA;CAGb;CAOA,cAAqB,GAAc,GAAA;EAClC,IAAM,IAAQ,KAAK,aAAa,MAAK,MAAK,EAAE,SAAS,CAAA;EACrD,OAAA,CAAA,CAAK,MACL,EAAM,kBAAkB,CAAA,GACxB,EAAM,cAAA,GAAA,CACC;CACR;CAMA,aAAoB,GAAiB,GAAA;EACpC,EAAgB,IAAI;GAAA,GAChB,EAAgB;GACnB,QAAQ;GACR,OAAO;IAAE,SAAA;IAAS,MAAA;GAAA;EAAA,CAAA,GAEnB,KAAK,gBAAgB,SAAS,CAAA;CAC/B;CAYA,iBAAA;EACC,KAAK,aAAa,SAAQ,MAAK,EAAE,eAAA,CAAA,GACjC,EAAgB,IAAI;GAAA,GAChB,EAAgB;GACnB,QAAQ;GACR,OAAO;EAAA,CAAA,GAER,KAAK,gBAAgB,MAAA;CACtB;CAGA,SAAA;EACC,IAAM,IAAO,KAAK,YAAY,cAAc,MAAA;EAC5C,OAAA,CAAA,CAAK,MACL,EAAK,cAAA,GAAA,CACE;CACR;CAGA,QAAA;EAAA,CACc,KAAK,YAAY,cAAc,MAAA,IACtC,MAAA;CACP;CAEA,iBAAA;EACC,OAAO,KAAK,aAAa,OAAM,MAAK,EAAE,eAAA,CAAA;CACvC;CAEA,gBAAA;EACC,OAAO,KAAK,aAAa,OAAM,MAAK,EAAE,cAAA,CAAA;CACvC;CAGA,cAAA;EACC,IAAM,IAAW,IAAI,SAAA;EACrB,KAAK,IAAM,KAAS,KAAK,cACxB,KAAK,IAAA,CAAO,GAAG,MAAM,EAAM,cAAA,GAAiB,EAAS,OAAO,GAAG,CAAA;EAEhE,OAAO;CACR;CAEA,SAAA;EACC,OAAO,CAAI;iCACoB,CAAC,CAAA,EAAA;wBACV,KAAK,WAAA,WAAsB,KAAK,SAAA,UAAmB,KAAK,QAAA;;;;;;;;;;;;OAYzE,KAAK,eAAe,UAAU,KAAK,YAAY,GAAA;;;;CAIrD;AAAA;AAAA,EAAA,CAhTC,EAAS,EAAE,WAAA,CAAW,EAAA,CAAA,CAAA,GAAO,EAAA,WAAA,UAAA,KAAA,CAAA,GAAA,EAAA,CAI7B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,GAAS,EAAA,WAAA,cAAA,KAAA,CAAA,GAAA,EAAA,CAY1B,EAAA,CAAA,GAAM,EAAA,WAAA,cAAA,KAAA,CAAA,GAAA,EAAA,CACN,EAAA,CAAA,GAAM,EAAA,WAAA,aAAA,KAAA,CAAA;AAAA,IAAA,IAAA,IAAA,EAAA,CAhCP,EAAc,eAAA,CAAA,GAAe,CAAA;AAAA,SAAA,KAAA,GAAA,KAAA"}
package/dist/form.cjs CHANGED
@@ -1,18 +1,17 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-PS1u0j1B.cjs`);require(`./mixins-BoMURWag.cjs`),require(`./autocomplete-Dq3BkitV.cjs`);const t=require(`./input-chip-CV91URyU.cjs`),n=require(`./checkbox-DXKdxkXE.cjs`),r=require(`./chips-9eG-96_D.cjs`),i=require(`./date-range-Q2xj5Syc.cjs`),a=require(`./form-DowzVsgI.cjs`),o=require(`./input-DnmC6J1T.cjs`);require(`./input.cjs`);const s=require(`./radio-group-6kCgOgBL.cjs`),c=require(`./range.cjs`),l=require(`./select-MXsF8KsU.cjs`),u=require(`./switch.cjs`);require(`./textarea-BwYwH9fu.cjs`);let d=require(`lit/decorators.js`),f=require(`lit`);var p=class extends e.t{constructor(...e){super(...e),this.bump=0,this.form=null}connectedCallback(){super.connectedCallback(),this.form=this.closest(`schmancy-form`),this.form&&(this.formObserver=new MutationObserver(()=>{this.bump++}),this.formObserver.observe(this.form,{attributes:!0,subtree:!0}),(async()=>{await this.form?.updateComplete;let e=this.form?.shadowRoot?.querySelector(`[role="status"]`);e&&this.formObserver?.observe(e,{childList:!0,characterData:!0,subtree:!0}),this.bump++})())}disconnectedCallback(){this.formObserver?.disconnect(),this.formObserver=void 0,super.disconnectedCallback()}readFormStatus(){return this.form?this.form.matches(`:state(error)`)?`error`:this.form.matches(`:state(submitting)`)?`submitting`:this.form.matches(`:state(success)`)?`success`:`idle`:`idle`}readFormMessage(){return(this.form?.shadowRoot?.querySelector(`[role="status"]`))?.textContent?.trim()??``}readInvalidFields(){if(!this.form)return[];let e=[];for(let t of Array.from(this.form.querySelectorAll(`*`))){if(!(t instanceof HTMLElement))continue;let n=!1;try{n=t.matches(`:state(invalid)`)}catch{continue}if(!n)continue;let r=t;e.push({id:r.id,label:r.label||r.name||`(field)`,message:r.validationMessage||`Invalid value`})}return e}render(){if(this.bump,this.readFormStatus()!==`error`)return f.nothing;let e=this.readFormMessage(),t=this.readInvalidFields(),n=t.length;return f.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-CeKrBW2j.cjs`);require(`./mixins-Cjn20BQH.cjs`),require(`./autocomplete-CILzaDB7.cjs`);const t=require(`./input-chip-BUuFJUky.cjs`),n=require(`./checkbox-DZ2Wrz7Y.cjs`),r=require(`./chips-BHBVkxsa.cjs`),i=require(`./date-range-CVAWMdar.cjs`),a=require(`./form-CoWFnClb.cjs`),o=require(`./input-DSfwfhhj.cjs`);require(`./input.cjs`);const s=require(`./radio-group-CaAjg9UV.cjs`),c=require(`./range.cjs`),l=require(`./select-DcLcpPCh.cjs`),u=require(`./switch.cjs`);require(`./textarea-CGgznhd6.cjs`);let d=require(`lit/decorators.js`),f=require(`lit`);var p=class extends e.t{constructor(...e){super(...e),this.bump=0,this.form=null}connectedCallback(){super.connectedCallback(),this.form=this.closest(`schmancy-form`),this.form&&(this.formObserver=new MutationObserver(()=>{this.bump++}),this.formObserver.observe(this.form,{attributes:!0,subtree:!0}),(async()=>{await this.form?.updateComplete;let e=this.form?.shadowRoot?.querySelector(`[role="status"]`);e&&this.formObserver?.observe(e,{childList:!0,characterData:!0,subtree:!0}),this.bump++})())}disconnectedCallback(){this.formObserver?.disconnect(),this.formObserver=void 0,super.disconnectedCallback()}readFormStatus(){return this.form?this.form.matches(`:state(error)`)?`error`:this.form.matches(`:state(submitting)`)?`submitting`:this.form.matches(`:state(success)`)?`success`:`idle`:`idle`}readFormMessage(){return(this.form?.shadowRoot?.querySelector(`[role="status"]`))?.textContent?.trim()??``}readInvalidFields(){if(!this.form)return[];let e=[];for(let t of Array.from(this.form.querySelectorAll(`*`))){if(!(t instanceof HTMLElement))continue;let n=!1;try{n=t.matches(`:state(invalid)`)}catch{continue}if(!n)continue;let r=t;e.push({id:r.id,label:r.label||r.name||`(field)`,message:r.validationMessage||`Invalid value`})}return e}render(){if(this.bump,this.readFormStatus()!==`error`)return f.nothing;let e=this.readFormMessage(),t=this.readInvalidFields(),n=t.length;return f.html`
2
2
  <div role="alert" aria-labelledby="schmancy-form-summary-heading">
3
3
  <h2 id="schmancy-form-summary-heading">${this.heading??(n===0?`There is a problem with this form`:`There ${n===1?`is`:`are`} ${n} problem${n===1?``:`s`} with this form`)}</h2>
4
4
  ${e?f.html`<p>${e}</p>`:f.nothing}
5
5
  ${n>0?f.html`
6
- <ul>
7
- ${t.map(e=>f.html`
8
- <li>
9
- <a
10
- href="#${e.id}"
11
- @click=${t=>this.jumpToField(t,e.id)}
12
- >${e.label}: ${e.message}</a>
13
- </li>
14
- `)}
15
- </ul>
16
- `:f.nothing}
6
+ <ul>
7
+ ${t.map(e=>f.html`
8
+ <li>
9
+ <a href="#${e.id}" @click=${t=>this.jumpToField(t,e.id)}
10
+ >${e.label}: ${e.message}</a
11
+ >
12
+ </li>
13
+ `)}
14
+ </ul>
15
+ `:f.nothing}
17
16
  </div>
18
- `}jumpToField(e,t){e.preventDefault(),(this.form?.querySelector(`#${CSS.escape(t)}`))?.focus()}};e.u([(0,d.property)({type:String})],p.prototype,`heading`,void 0),e.u([(0,d.state)()],p.prototype,`bump`,void 0),p=e.u([(0,d.customElement)(`schmancy-form-summary`)],p),Object.defineProperty(exports,`RadioButton`,{enumerable:!0,get:function(){return s.t}}),Object.defineProperty(exports,`RadioGroup`,{enumerable:!0,get:function(){return s.n}}),Object.defineProperty(exports,`SchmancyAssistChip`,{enumerable:!0,get:function(){return r.r}}),Object.defineProperty(exports,`SchmancyCheckbox`,{enumerable:!0,get:function(){return n.t}}),exports.SchmancyChip=r.n,exports.SchmancyFilterChip=r.n,Object.defineProperty(exports,`SchmancyDateRange`,{enumerable:!0,get:function(){return i.t}}),exports.SchmancyForm=a.t,Object.defineProperty(exports,`SchmancyFormSummary`,{enumerable:!0,get:function(){return p}}),exports.SchmancyInput=o.n,Object.defineProperty(exports,`SchmancyInputChip`,{enumerable:!0,get:function(){return t.t}}),Object.defineProperty(exports,`SchmancyInputCompat`,{enumerable:!0,get:function(){return o.t}}),Object.defineProperty(exports,`SchmancyRange`,{enumerable:!0,get:function(){return c.SchmancyRange}}),Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return l.t}}),Object.defineProperty(exports,`SchmancySuggestionChip`,{enumerable:!0,get:function(){return r.t}}),Object.defineProperty(exports,`SchmancySwitch`,{enumerable:!0,get:function(){return u.SchmancySwitch}}),exports.formSubmitState=a.n,exports.validateInitialDateRange=i.n;
17
+ `}jumpToField(e,t){e.preventDefault(),(this.form?.querySelector(`#${CSS.escape(t)}`))?.focus()}};e.u([(0,d.property)({type:String})],p.prototype,`heading`,void 0),e.u([(0,d.state)()],p.prototype,`bump`,void 0),p=e.u([(0,d.customElement)(`schmancy-form-summary`)],p),Object.defineProperty(exports,`RadioButton`,{enumerable:!0,get:function(){return s.t}}),Object.defineProperty(exports,`RadioGroup`,{enumerable:!0,get:function(){return s.n}}),Object.defineProperty(exports,`SchmancyAssistChip`,{enumerable:!0,get:function(){return r.r}}),Object.defineProperty(exports,`SchmancyCheckbox`,{enumerable:!0,get:function(){return n.t}}),exports.SchmancyChip=r.n,exports.SchmancyFilterChip=r.n,Object.defineProperty(exports,`SchmancyDateRange`,{enumerable:!0,get:function(){return i.t}}),Object.defineProperty(exports,`SchmancyDateRangeDialog`,{enumerable:!0,get:function(){return i.n}}),exports.SchmancyForm=a.t,Object.defineProperty(exports,`SchmancyFormSummary`,{enumerable:!0,get:function(){return p}}),exports.SchmancyInput=o.n,Object.defineProperty(exports,`SchmancyInputChip`,{enumerable:!0,get:function(){return t.t}}),Object.defineProperty(exports,`SchmancyInputCompat`,{enumerable:!0,get:function(){return o.t}}),Object.defineProperty(exports,`SchmancyRange`,{enumerable:!0,get:function(){return c.SchmancyRange}}),Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return l.t}}),Object.defineProperty(exports,`SchmancySuggestionChip`,{enumerable:!0,get:function(){return r.t}}),Object.defineProperty(exports,`SchmancySwitch`,{enumerable:!0,get:function(){return u.SchmancySwitch}}),exports.formSubmitState=a.n;
package/dist/form.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"form.cjs","names":[],"sources":["../src/form/form-summary.ts"],"sourcesContent":["/**\n * `<schmancy-form-summary>` — top-of-form error summary with anchor links to\n * each invalid field. Linear / GOV.UK / GitHub pattern.\n *\n * Drop one inside any `<schmancy-form>`; on submit-failure or when\n * `<schmancy-form>.setFormError(...)` is called, the summary renders a\n * `role=\"alert\"` banner with the form-level error message and a list of\n * links pointing at each invalid field's `id`.\n *\n * Hidden when the form is idle, submitting, or successful — only `error`\n * populates it.\n *\n * @element schmancy-form-summary\n */\n\nimport { html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { SchmancyElement } from '../../mixins'\nimport type SchmancyForm from './form'\n\n@customElement('schmancy-form-summary')\nexport class SchmancyFormSummary extends SchmancyElement {\n\t/**\n\t * Optional heading text. Defaults to a count-based summary\n\t * (\"1 problem with this form\" / \"3 problems with this form\").\n\t */\n\t@property({ type: String }) heading?: string\n\n\t/**\n\t * Render bumper — incremented to force a re-render when the form's state\n\t * changes (the actual content is computed from the DOM in render()).\n\t */\n\t@state() private bump: number = 0\n\n\tprivate form: SchmancyForm | null = null\n\tprivate formObserver?: MutationObserver\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.form = this.closest('schmancy-form') as SchmancyForm | null\n\t\tif (!this.form) {\n\t\t\tconsole.error('[schmancy-form-summary] must be a descendant of <schmancy-form>')\n\t\t\treturn\n\t\t}\n\t\tconst bump = () => { this.bump++ }\n\t\tthis.formObserver = new MutationObserver(bump)\n\t\t// Form host attribute changes (aria-busy, :state class reflections,\n\t\t// descendant attribute changes for fields' aria-invalid). subtree:true\n\t\t// catches attribute mutations on every descendant including light-DOM\n\t\t// fields and the form's own host.\n\t\tthis.formObserver.observe(this.form, {\n\t\t\tattributes: true,\n\t\t\tsubtree: true,\n\t\t})\n\t\t// Defer live-region observation until the form has rendered its\n\t\t// shadow tree.\n\t\tconst attachLiveRegionObserver = async (): Promise<void> => {\n\t\t\tawait this.form?.updateComplete\n\t\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\t\tif (liveRegion) {\n\t\t\t\tthis.formObserver?.observe(liveRegion, {\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tcharacterData: true,\n\t\t\t\t\tsubtree: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Force a render so the initial state is reflected.\n\t\t\tthis.bump++\n\t\t}\n\t\tvoid attachLiveRegionObserver()\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.formObserver?.disconnect()\n\t\tthis.formObserver = undefined\n\t\tsuper.disconnectedCallback()\n\t}\n\n\tprivate readFormStatus(): 'idle' | 'submitting' | 'success' | 'error' {\n\t\tif (!this.form) return 'idle'\n\t\tif (this.form.matches(':state(error)')) return 'error'\n\t\tif (this.form.matches(':state(submitting)')) return 'submitting'\n\t\tif (this.form.matches(':state(success)')) return 'success'\n\t\treturn 'idle'\n\t}\n\n\tprivate readFormMessage(): string {\n\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\treturn liveRegion?.textContent?.trim() ?? ''\n\t}\n\n\tprivate readInvalidFields(): Array<{ id: string; label: string; message: string }> {\n\t\tif (!this.form) return []\n\t\tconst result: Array<{ id: string; label: string; message: string }> = []\n\t\tfor (const el of Array.from(this.form.querySelectorAll('*'))) {\n\t\t\tif (!(el instanceof HTMLElement)) continue\n\t\t\tlet isInvalid = false\n\t\t\ttry {\n\t\t\t\tisInvalid = el.matches(':state(invalid)')\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!isInvalid) continue\n\t\t\tconst f = el as HTMLElement & {\n\t\t\t\tlabel?: string\n\t\t\t\tname?: string\n\t\t\t\tvalidationMessage?: string\n\t\t\t}\n\t\t\tresult.push({\n\t\t\t\tid: f.id,\n\t\t\t\tlabel: f.label || f.name || '(field)',\n\t\t\t\tmessage: f.validationMessage || 'Invalid value',\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\trender() {\n\t\t// Read everything fresh from the DOM each render — no @state cache, no\n\t\t// re-render loops. The MutationObserver bumps `bump` to trigger this\n\t\t// render; `bump` itself is never read here.\n\t\tvoid this.bump\n\n\t\tconst status = this.readFormStatus()\n\t\tif (status !== 'error') return nothing\n\n\t\tconst formMessage = this.readFormMessage()\n\t\tconst invalid = this.readInvalidFields()\n\t\tconst count = invalid.length\n\t\tconst heading =\n\t\t\tthis.heading ??\n\t\t\t(count === 0\n\t\t\t\t? 'There is a problem with this form'\n\t\t\t\t: `There ${count === 1 ? 'is' : 'are'} ${count} problem${count === 1 ? '' : 's'} with this form`)\n\n\t\treturn html`\n\t\t\t<div role=\"alert\" aria-labelledby=\"schmancy-form-summary-heading\">\n\t\t\t\t<h2 id=\"schmancy-form-summary-heading\">${heading}</h2>\n\t\t\t\t${formMessage ? html`<p>${formMessage}</p>` : nothing}\n\t\t\t\t${count > 0\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t${invalid.map(\n\t\t\t\t\t\t\t\tf => html`\n\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\thref=\"#${f.id}\"\n\t\t\t\t\t\t\t\t\t\t\t@click=${(e: MouseEvent) => this.jumpToField(e, f.id)}\n\t\t\t\t\t\t\t\t\t\t>${f.label}: ${f.message}</a>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t`\n\t\t\t\t\t: nothing}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tprivate jumpToField(e: MouseEvent, fieldId: string): void {\n\t\te.preventDefault()\n\t\tconst target = this.form?.querySelector(`#${CSS.escape(fieldId)}`) as HTMLElement | null\n\t\ttarget?.focus()\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form-summary': SchmancyFormSummary\n\t}\n}\n"],"mappings":"6qBAqBO,IAAA,EAAA,cAAkC,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,KAWR,EAAA,KAAA,KAEI,IAAA,CAGpC,mBAAA,CACC,MAAM,kBAAA,EACN,KAAK,KAAO,KAAK,QAAQ,eAAA,EACpB,KAAK,OAKV,KAAK,aAAe,IAAI,qBADlB,CAAe,KAAK,MAAA,CAAA,EAM1B,KAAK,aAAa,QAAQ,KAAK,KAAM,CACpC,WAAA,CAAY,EACZ,QAAA,CAAS,CAAA,CAAA,GAIuB,SAAA,CAAA,MAC1B,KAAK,MAAM,eACjB,IAAM,EAAa,KAAK,MAAM,YAAY,cAAc,iBAAA,EACpD,GACH,KAAK,cAAc,QAAQ,EAAY,CACtC,UAAA,CAAW,EACX,cAAA,CAAe,EACf,QAAA,CAAS,CAAA,CAAA,EAIX,KAAK,MAAA,GAEN,EACD,CAEA,sBAAA,CACC,KAAK,cAAc,WAAA,EACnB,KAAK,aAAA,IAAe,GACpB,MAAM,qBAAA,CACP,CAEA,gBAAA,CACC,OAAK,KAAK,KACN,KAAK,KAAK,QAAQ,eAAA,EAAyB,QAC3C,KAAK,KAAK,QAAQ,oBAAA,EAA8B,aAChD,KAAK,KAAK,QAAQ,iBAAA,EAA2B,UAC1C,OAJgB,MAKxB,CAEA,iBAAA,CAEC,OADmB,KAAK,MAAM,YAAY,cAAc,iBAAA,IACrC,aAAa,KAAA,GAAU,EAC3C,CAEA,mBAAA,CACC,GAAA,CAAK,KAAK,KAAM,MAAO,CAAA,EACvB,IAAM,EAAgE,CAAA,EACtE,IAAK,IAAM,KAAM,MAAM,KAAK,KAAK,KAAK,iBAAiB,GAAA,CAAA,EAAO,CAC7D,GAAA,EAAM,aAAc,aAAc,SAClC,IAAI,EAAA,CAAY,EAChB,GAAA,CACC,EAAY,EAAG,QAAQ,iBAAA,CACxB,MAAA,CACC,QACD,CACA,GAAA,CAAK,EAAW,SAChB,IAAM,EAAI,EAKV,EAAO,KAAK,CACX,GAAI,EAAE,GACN,MAAO,EAAE,OAAS,EAAE,MAAQ,UAC5B,QAAS,EAAE,mBAAqB,eAAA,CAAA,CAElC,CACA,OAAO,CACR,CAEA,QAAA,CAOC,GAHA,KAAU,KAEK,KAAK,eAAA,IACL,QAAS,OAAO,EAAA,QAE/B,IAAM,EAAc,KAAK,gBAAA,EACnB,EAAU,KAAK,kBAAA,EACf,EAAQ,EAAQ,OAOtB,MAAO,GAAA,IAAI;;6CALV,KAAK,UACJ,IAAU,EACR,oCACA,SAAS,IAAU,EAAI,KAAO,MAAA,GAAS,EAAA,UAAgB,IAAU,EAAI,GAAK,IAAA,kBAAA;MAK1E,EAAc,EAAA,IAAI,MAAM,EAAA,MAAoB,EAAA,QAAA;MAC5C,EAAQ,EACP,EAAA,IAAI;;SAEF,EAAQ,IACT,GAAK,EAAA,IAAI;;;oBAGG,EAAE,GAAA;oBACD,GAAkB,KAAK,YAAY,EAAG,EAAE,EAAA,EAAA;aAChD,EAAE,MAAA,IAAU,EAAE,QAAA;;;;OAMpB,EAAA,QAAA;;GAGN,CAEA,YAAoB,EAAe,EAAA,CAClC,EAAE,eAAA,GACa,KAAK,MAAM,cAAc,IAAI,IAAI,OAAO,CAAA,GAAA,IAC/C,MAAA,CACT,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAzIU,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,UAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EAMnB,EAAA,UAAA,OAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAZO,uBAAA,CAAA,EAAuB,CAAA,EAAA,OAAA,eAAA,QAAA,cAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,aAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,qBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,mBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,QAAA,aAAA,EAAA,EAAA,QAAA,mBAAA,EAAA,EAAA,OAAA,eAAA,QAAA,oBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,QAAA,aAAA,EAAA,EAAA,OAAA,eAAA,QAAA,sBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA,EAAA,QAAA,cAAA,EAAA,EAAA,OAAA,eAAA,QAAA,oBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,sBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,gBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,aAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,iBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,yBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,iBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,cAAA,CAAA,CAAA,EAAA,QAAA,gBAAA,EAAA,EAAA,QAAA,yBAAA,EAAA"}
1
+ {"version":3,"file":"form.cjs","names":[],"sources":["../src/form/form-summary.ts"],"sourcesContent":["/**\n * `<schmancy-form-summary>` — top-of-form error summary with anchor links to\n * each invalid field. Linear / GOV.UK / GitHub pattern.\n *\n * Drop one inside any `<schmancy-form>`; on submit-failure or when\n * `<schmancy-form>.setFormError(...)` is called, the summary renders a\n * `role=\"alert\"` banner with the form-level error message and a list of\n * links pointing at each invalid field's `id`.\n *\n * Hidden when the form is idle, submitting, or successful — only `error`\n * populates it.\n *\n * @element schmancy-form-summary\n */\n\nimport { html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { SchmancyElement } from '../../mixins'\nimport type SchmancyForm from './form'\n\n@customElement('schmancy-form-summary')\nexport class SchmancyFormSummary extends SchmancyElement {\n\t/**\n\t * Optional heading text. Defaults to a count-based summary\n\t * (\"1 problem with this form\" / \"3 problems with this form\").\n\t */\n\t@property({ type: String }) heading?: string\n\n\t/**\n\t * Render bumper — incremented to force a re-render when the form's state\n\t * changes (the actual content is computed from the DOM in render()).\n\t */\n\t@state() private bump: number = 0\n\n\tprivate form: SchmancyForm | null = null\n\tprivate formObserver?: MutationObserver\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.form = this.closest('schmancy-form') as SchmancyForm | null\n\t\tif (!this.form) {\n\t\t\tconsole.error('[schmancy-form-summary] must be a descendant of <schmancy-form>')\n\t\t\treturn\n\t\t}\n\t\tconst bump = () => {\n\t\t\tthis.bump++\n\t\t}\n\t\tthis.formObserver = new MutationObserver(bump)\n\t\t// Form host attribute changes (aria-busy, :state class reflections,\n\t\t// descendant attribute changes for fields' aria-invalid). subtree:true\n\t\t// catches attribute mutations on every descendant including light-DOM\n\t\t// fields and the form's own host.\n\t\tthis.formObserver.observe(this.form, {\n\t\t\tattributes: true,\n\t\t\tsubtree: true,\n\t\t})\n\t\t// Defer live-region observation until the form has rendered its\n\t\t// shadow tree.\n\t\tconst attachLiveRegionObserver = async (): Promise<void> => {\n\t\t\tawait this.form?.updateComplete\n\t\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\t\tif (liveRegion) {\n\t\t\t\tthis.formObserver?.observe(liveRegion, {\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tcharacterData: true,\n\t\t\t\t\tsubtree: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Force a render so the initial state is reflected.\n\t\t\tthis.bump++\n\t\t}\n\t\tvoid attachLiveRegionObserver()\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.formObserver?.disconnect()\n\t\tthis.formObserver = undefined\n\t\tsuper.disconnectedCallback()\n\t}\n\n\tprivate readFormStatus(): 'idle' | 'submitting' | 'success' | 'error' {\n\t\tif (!this.form) return 'idle'\n\t\tif (this.form.matches(':state(error)')) return 'error'\n\t\tif (this.form.matches(':state(submitting)')) return 'submitting'\n\t\tif (this.form.matches(':state(success)')) return 'success'\n\t\treturn 'idle'\n\t}\n\n\tprivate readFormMessage(): string {\n\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\treturn liveRegion?.textContent?.trim() ?? ''\n\t}\n\n\tprivate readInvalidFields(): Array<{ id: string; label: string; message: string }> {\n\t\tif (!this.form) return []\n\t\tconst result: Array<{ id: string; label: string; message: string }> = []\n\t\tfor (const el of Array.from(this.form.querySelectorAll('*'))) {\n\t\t\tif (!(el instanceof HTMLElement)) continue\n\t\t\tlet isInvalid = false\n\t\t\ttry {\n\t\t\t\tisInvalid = el.matches(':state(invalid)')\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!isInvalid) continue\n\t\t\tconst f = el as HTMLElement & {\n\t\t\t\tlabel?: string\n\t\t\t\tname?: string\n\t\t\t\tvalidationMessage?: string\n\t\t\t}\n\t\t\tresult.push({\n\t\t\t\tid: f.id,\n\t\t\t\tlabel: f.label || f.name || '(field)',\n\t\t\t\tmessage: f.validationMessage || 'Invalid value',\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\trender() {\n\t\t// Read everything fresh from the DOM each render — no @state cache, no\n\t\t// re-render loops. The MutationObserver bumps `bump` to trigger this\n\t\t// render; `bump` itself is never read here.\n\t\tvoid this.bump\n\n\t\tconst status = this.readFormStatus()\n\t\tif (status !== 'error') return nothing\n\n\t\tconst formMessage = this.readFormMessage()\n\t\tconst invalid = this.readInvalidFields()\n\t\tconst count = invalid.length\n\t\tconst heading =\n\t\t\tthis.heading ??\n\t\t\t(count === 0\n\t\t\t\t? 'There is a problem with this form'\n\t\t\t\t: `There ${count === 1 ? 'is' : 'are'} ${count} problem${count === 1 ? '' : 's'} with this form`)\n\n\t\treturn html`\n\t\t\t<div role=\"alert\" aria-labelledby=\"schmancy-form-summary-heading\">\n\t\t\t\t<h2 id=\"schmancy-form-summary-heading\">${heading}</h2>\n\t\t\t\t${formMessage ? html`<p>${formMessage}</p>` : nothing}\n\t\t\t\t${count > 0\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t\t${invalid.map(\n\t\t\t\t\t\t\t\t\tf => html`\n\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#${f.id}\" @click=${(e: MouseEvent) => this.jumpToField(e, f.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t>${f.label}: ${f.message}</a\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t`\n\t\t\t\t\t: nothing}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tprivate jumpToField(e: MouseEvent, fieldId: string): void {\n\t\te.preventDefault()\n\t\tconst target = this.form?.querySelector(`#${CSS.escape(fieldId)}`) as HTMLElement | null\n\t\ttarget?.focus()\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form-summary': SchmancyFormSummary\n\t}\n}\n"],"mappings":"6qBAqBO,IAAA,EAAA,cAAkC,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,KAWR,EAAA,KAAA,KAEI,IAAA,CAGpC,mBAAA,CACC,MAAM,kBAAA,EACN,KAAK,KAAO,KAAK,QAAQ,eAAA,EACpB,KAAK,OAOV,KAAK,aAAe,IAAI,qBAHlB,CACL,KAAK,MAAA,CAAA,EAON,KAAK,aAAa,QAAQ,KAAK,KAAM,CACpC,WAAA,CAAY,EACZ,QAAA,CAAS,CAAA,CAAA,GAIuB,SAAA,CAAA,MAC1B,KAAK,MAAM,eACjB,IAAM,EAAa,KAAK,MAAM,YAAY,cAAc,iBAAA,EACpD,GACH,KAAK,cAAc,QAAQ,EAAY,CACtC,UAAA,CAAW,EACX,cAAA,CAAe,EACf,QAAA,CAAS,CAAA,CAAA,EAIX,KAAK,MAAA,GAEN,EACD,CAEA,sBAAA,CACC,KAAK,cAAc,WAAA,EACnB,KAAK,aAAA,IAAe,GACpB,MAAM,qBAAA,CACP,CAEA,gBAAA,CACC,OAAK,KAAK,KACN,KAAK,KAAK,QAAQ,eAAA,EAAyB,QAC3C,KAAK,KAAK,QAAQ,oBAAA,EAA8B,aAChD,KAAK,KAAK,QAAQ,iBAAA,EAA2B,UAC1C,OAJgB,MAKxB,CAEA,iBAAA,CAEC,OADmB,KAAK,MAAM,YAAY,cAAc,iBAAA,IACrC,aAAa,KAAA,GAAU,EAC3C,CAEA,mBAAA,CACC,GAAA,CAAK,KAAK,KAAM,MAAO,CAAA,EACvB,IAAM,EAAgE,CAAA,EACtE,IAAK,IAAM,KAAM,MAAM,KAAK,KAAK,KAAK,iBAAiB,GAAA,CAAA,EAAO,CAC7D,GAAA,EAAM,aAAc,aAAc,SAClC,IAAI,EAAA,CAAY,EAChB,GAAA,CACC,EAAY,EAAG,QAAQ,iBAAA,CACxB,MAAA,CACC,QACD,CACA,GAAA,CAAK,EAAW,SAChB,IAAM,EAAI,EAKV,EAAO,KAAK,CACX,GAAI,EAAE,GACN,MAAO,EAAE,OAAS,EAAE,MAAQ,UAC5B,QAAS,EAAE,mBAAqB,eAAA,CAAA,CAElC,CACA,OAAO,CACR,CAEA,QAAA,CAOC,GAHA,KAAU,KAEK,KAAK,eAAA,IACL,QAAS,OAAO,EAAA,QAE/B,IAAM,EAAc,KAAK,gBAAA,EACnB,EAAU,KAAK,kBAAA,EACf,EAAQ,EAAQ,OAOtB,MAAO,GAAA,IAAI;;6CALV,KAAK,UACJ,IAAU,EACR,oCACA,SAAS,IAAU,EAAI,KAAO,MAAA,GAAS,EAAA,UAAgB,IAAU,EAAI,GAAK,IAAA,kBAAA;MAK1E,EAAc,EAAA,IAAI,MAAM,EAAA,MAAoB,EAAA,QAAA;MAC5C,EAAQ,EACP,EAAA,IAAI;;UAED,EAAQ,IACT,GAAK,EAAA,IAAI;;uBAEK,EAAE,GAAA,WAAe,GAAkB,KAAK,YAAY,EAAG,EAAE,EAAA,EAAA;eACjE,EAAE,MAAA,IAAU,EAAE,QAAA;;;;;QAOtB,EAAA,QAAA;;GAGN,CAEA,YAAoB,EAAe,EAAA,CAClC,EAAE,eAAA,GACa,KAAK,MAAM,cAAc,IAAI,IAAI,OAAO,CAAA,GAAA,IAC/C,MAAA,CACT,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UA1IU,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,UAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EAMnB,EAAA,UAAA,OAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAZO,uBAAA,CAAA,EAAuB,CAAA,EAAA,OAAA,eAAA,QAAA,cAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,aAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,qBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,mBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,QAAA,aAAA,EAAA,EAAA,QAAA,mBAAA,EAAA,EAAA,OAAA,eAAA,QAAA,oBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,0BAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,QAAA,aAAA,EAAA,EAAA,OAAA,eAAA,QAAA,sBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA,EAAA,QAAA,cAAA,EAAA,EAAA,OAAA,eAAA,QAAA,oBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,sBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,gBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,aAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,iBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,yBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,iBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,EAAA,cAAA,CAAA,CAAA,EAAA,QAAA,gBAAA,EAAA"}
package/dist/form.js CHANGED
@@ -1,18 +1,18 @@
1
- import { t as e, u as t } from "./SchmancyElement-OG71FtNv.js";
2
- import "./mixins-bCEXbwJV.js";
3
- import "./autocomplete-UNOknYUz.js";
4
- import { t as n } from "./input-chip-CYI17YOq.js";
5
- import { t as r } from "./checkbox-7vEPZuGC.js";
6
- import { n as i, r as a, t as o } from "./chips-DF7akwz7.js";
7
- import { n as s, t as c } from "./date-range-C13_R3OA.js";
8
- import { n as l, t as u } from "./form-tG7LwDm4.js";
9
- import { n as d, t as f } from "./input-cTyDxW9L.js";
1
+ import { t as e, u as t } from "./SchmancyElement-Ob9yGkiG.js";
2
+ import "./mixins-q4KAL8Xr.js";
3
+ import "./autocomplete-DV9RxCun.js";
4
+ import { t as n } from "./input-chip-C3a1fwKB.js";
5
+ import { t as r } from "./checkbox-Bjp7kWuE.js";
6
+ import { n as i, r as a, t as o } from "./chips-DACeW7YL.js";
7
+ import { n as s, t as c } from "./date-range-D2NZU5Yg.js";
8
+ import { n as l, t as u } from "./form-hC2LvCHX.js";
9
+ import { n as d, t as f } from "./input-CPFCSQld.js";
10
10
  import "./input.js";
11
- import { n as p, t as m } from "./radio-group-bZtZHOj_.js";
11
+ import { n as p, t as m } from "./radio-group-Drpl6Pl8.js";
12
12
  import { SchmancyRange as h } from "./range.js";
13
- import { t as g } from "./select-CU3X-PIa.js";
13
+ import { t as g } from "./select-CTXkrrVZ.js";
14
14
  import { SchmancySwitch as _ } from "./switch.js";
15
- import "./textarea-kkYNk1ET.js";
15
+ import "./textarea-BjDx1w2g.js";
16
16
  import { customElement as v, property as y, state as b } from "lit/decorators.js";
17
17
  import { html as x, nothing as S } from "lit";
18
18
  var C = class extends e {
@@ -73,17 +73,16 @@ var C = class extends e {
73
73
  <h2 id="schmancy-form-summary-heading">${this.heading ?? (n === 0 ? "There is a problem with this form" : `There ${n === 1 ? "is" : "are"} ${n} problem${n === 1 ? "" : "s"} with this form`)}</h2>
74
74
  ${e ? x`<p>${e}</p>` : S}
75
75
  ${n > 0 ? x`
76
- <ul>
77
- ${t.map((e) => x`
78
- <li>
79
- <a
80
- href="#${e.id}"
81
- @click=${(t) => this.jumpToField(t, e.id)}
82
- >${e.label}: ${e.message}</a>
83
- </li>
84
- `)}
85
- </ul>
86
- ` : S}
76
+ <ul>
77
+ ${t.map((e) => x`
78
+ <li>
79
+ <a href="#${e.id}" @click=${(t) => this.jumpToField(t, e.id)}
80
+ >${e.label}: ${e.message}</a
81
+ >
82
+ </li>
83
+ `)}
84
+ </ul>
85
+ ` : S}
87
86
  </div>
88
87
  `;
89
88
  }
@@ -92,4 +91,4 @@ var C = class extends e {
92
91
  }
93
92
  };
94
93
  t([y({ type: String })], C.prototype, "heading", void 0), t([b()], C.prototype, "bump", void 0), C = t([v("schmancy-form-summary")], C);
95
- export { m as RadioButton, p as RadioGroup, a as SchmancyAssistChip, r as SchmancyCheckbox, i as SchmancyChip, i as SchmancyFilterChip, c as SchmancyDateRange, u as SchmancyForm, C as SchmancyFormSummary, d as SchmancyInput, n as SchmancyInputChip, f as SchmancyInputCompat, h as SchmancyRange, g as SchmancySelect, o as SchmancySuggestionChip, _ as SchmancySwitch, l as formSubmitState, s as validateInitialDateRange };
94
+ export { m as RadioButton, p as RadioGroup, a as SchmancyAssistChip, r as SchmancyCheckbox, i as SchmancyChip, i as SchmancyFilterChip, c as SchmancyDateRange, s as SchmancyDateRangeDialog, u as SchmancyForm, C as SchmancyFormSummary, d as SchmancyInput, n as SchmancyInputChip, f as SchmancyInputCompat, h as SchmancyRange, g as SchmancySelect, o as SchmancySuggestionChip, _ as SchmancySwitch, l as formSubmitState };
package/dist/form.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","names":[],"sources":["../src/form/form-summary.ts"],"sourcesContent":["/**\n * `<schmancy-form-summary>` — top-of-form error summary with anchor links to\n * each invalid field. Linear / GOV.UK / GitHub pattern.\n *\n * Drop one inside any `<schmancy-form>`; on submit-failure or when\n * `<schmancy-form>.setFormError(...)` is called, the summary renders a\n * `role=\"alert\"` banner with the form-level error message and a list of\n * links pointing at each invalid field's `id`.\n *\n * Hidden when the form is idle, submitting, or successful — only `error`\n * populates it.\n *\n * @element schmancy-form-summary\n */\n\nimport { html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { SchmancyElement } from '../../mixins'\nimport type SchmancyForm from './form'\n\n@customElement('schmancy-form-summary')\nexport class SchmancyFormSummary extends SchmancyElement {\n\t/**\n\t * Optional heading text. Defaults to a count-based summary\n\t * (\"1 problem with this form\" / \"3 problems with this form\").\n\t */\n\t@property({ type: String }) heading?: string\n\n\t/**\n\t * Render bumper — incremented to force a re-render when the form's state\n\t * changes (the actual content is computed from the DOM in render()).\n\t */\n\t@state() private bump: number = 0\n\n\tprivate form: SchmancyForm | null = null\n\tprivate formObserver?: MutationObserver\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.form = this.closest('schmancy-form') as SchmancyForm | null\n\t\tif (!this.form) {\n\t\t\tconsole.error('[schmancy-form-summary] must be a descendant of <schmancy-form>')\n\t\t\treturn\n\t\t}\n\t\tconst bump = () => { this.bump++ }\n\t\tthis.formObserver = new MutationObserver(bump)\n\t\t// Form host attribute changes (aria-busy, :state class reflections,\n\t\t// descendant attribute changes for fields' aria-invalid). subtree:true\n\t\t// catches attribute mutations on every descendant including light-DOM\n\t\t// fields and the form's own host.\n\t\tthis.formObserver.observe(this.form, {\n\t\t\tattributes: true,\n\t\t\tsubtree: true,\n\t\t})\n\t\t// Defer live-region observation until the form has rendered its\n\t\t// shadow tree.\n\t\tconst attachLiveRegionObserver = async (): Promise<void> => {\n\t\t\tawait this.form?.updateComplete\n\t\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\t\tif (liveRegion) {\n\t\t\t\tthis.formObserver?.observe(liveRegion, {\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tcharacterData: true,\n\t\t\t\t\tsubtree: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Force a render so the initial state is reflected.\n\t\t\tthis.bump++\n\t\t}\n\t\tvoid attachLiveRegionObserver()\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.formObserver?.disconnect()\n\t\tthis.formObserver = undefined\n\t\tsuper.disconnectedCallback()\n\t}\n\n\tprivate readFormStatus(): 'idle' | 'submitting' | 'success' | 'error' {\n\t\tif (!this.form) return 'idle'\n\t\tif (this.form.matches(':state(error)')) return 'error'\n\t\tif (this.form.matches(':state(submitting)')) return 'submitting'\n\t\tif (this.form.matches(':state(success)')) return 'success'\n\t\treturn 'idle'\n\t}\n\n\tprivate readFormMessage(): string {\n\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\treturn liveRegion?.textContent?.trim() ?? ''\n\t}\n\n\tprivate readInvalidFields(): Array<{ id: string; label: string; message: string }> {\n\t\tif (!this.form) return []\n\t\tconst result: Array<{ id: string; label: string; message: string }> = []\n\t\tfor (const el of Array.from(this.form.querySelectorAll('*'))) {\n\t\t\tif (!(el instanceof HTMLElement)) continue\n\t\t\tlet isInvalid = false\n\t\t\ttry {\n\t\t\t\tisInvalid = el.matches(':state(invalid)')\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!isInvalid) continue\n\t\t\tconst f = el as HTMLElement & {\n\t\t\t\tlabel?: string\n\t\t\t\tname?: string\n\t\t\t\tvalidationMessage?: string\n\t\t\t}\n\t\t\tresult.push({\n\t\t\t\tid: f.id,\n\t\t\t\tlabel: f.label || f.name || '(field)',\n\t\t\t\tmessage: f.validationMessage || 'Invalid value',\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\trender() {\n\t\t// Read everything fresh from the DOM each render — no @state cache, no\n\t\t// re-render loops. The MutationObserver bumps `bump` to trigger this\n\t\t// render; `bump` itself is never read here.\n\t\tvoid this.bump\n\n\t\tconst status = this.readFormStatus()\n\t\tif (status !== 'error') return nothing\n\n\t\tconst formMessage = this.readFormMessage()\n\t\tconst invalid = this.readInvalidFields()\n\t\tconst count = invalid.length\n\t\tconst heading =\n\t\t\tthis.heading ??\n\t\t\t(count === 0\n\t\t\t\t? 'There is a problem with this form'\n\t\t\t\t: `There ${count === 1 ? 'is' : 'are'} ${count} problem${count === 1 ? '' : 's'} with this form`)\n\n\t\treturn html`\n\t\t\t<div role=\"alert\" aria-labelledby=\"schmancy-form-summary-heading\">\n\t\t\t\t<h2 id=\"schmancy-form-summary-heading\">${heading}</h2>\n\t\t\t\t${formMessage ? html`<p>${formMessage}</p>` : nothing}\n\t\t\t\t${count > 0\n\t\t\t\t\t? html`\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t${invalid.map(\n\t\t\t\t\t\t\t\tf => html`\n\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\thref=\"#${f.id}\"\n\t\t\t\t\t\t\t\t\t\t\t@click=${(e: MouseEvent) => this.jumpToField(e, f.id)}\n\t\t\t\t\t\t\t\t\t\t>${f.label}: ${f.message}</a>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t`\n\t\t\t\t\t: nothing}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tprivate jumpToField(e: MouseEvent, fieldId: string): void {\n\t\te.preventDefault()\n\t\tconst target = this.form?.querySelector(`#${CSS.escape(fieldId)}`) as HTMLElement | null\n\t\ttarget?.focus()\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form-summary': SchmancyFormSummary\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"form.js","names":[],"sources":["../src/form/form-summary.ts"],"sourcesContent":["/**\n * `<schmancy-form-summary>` — top-of-form error summary with anchor links to\n * each invalid field. Linear / GOV.UK / GitHub pattern.\n *\n * Drop one inside any `<schmancy-form>`; on submit-failure or when\n * `<schmancy-form>.setFormError(...)` is called, the summary renders a\n * `role=\"alert\"` banner with the form-level error message and a list of\n * links pointing at each invalid field's `id`.\n *\n * Hidden when the form is idle, submitting, or successful — only `error`\n * populates it.\n *\n * @element schmancy-form-summary\n */\n\nimport { html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { SchmancyElement } from '../../mixins'\nimport type SchmancyForm from './form'\n\n@customElement('schmancy-form-summary')\nexport class SchmancyFormSummary extends SchmancyElement {\n\t/**\n\t * Optional heading text. Defaults to a count-based summary\n\t * (\"1 problem with this form\" / \"3 problems with this form\").\n\t */\n\t@property({ type: String }) heading?: string\n\n\t/**\n\t * Render bumper — incremented to force a re-render when the form's state\n\t * changes (the actual content is computed from the DOM in render()).\n\t */\n\t@state() private bump: number = 0\n\n\tprivate form: SchmancyForm | null = null\n\tprivate formObserver?: MutationObserver\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.form = this.closest('schmancy-form') as SchmancyForm | null\n\t\tif (!this.form) {\n\t\t\tconsole.error('[schmancy-form-summary] must be a descendant of <schmancy-form>')\n\t\t\treturn\n\t\t}\n\t\tconst bump = () => {\n\t\t\tthis.bump++\n\t\t}\n\t\tthis.formObserver = new MutationObserver(bump)\n\t\t// Form host attribute changes (aria-busy, :state class reflections,\n\t\t// descendant attribute changes for fields' aria-invalid). subtree:true\n\t\t// catches attribute mutations on every descendant including light-DOM\n\t\t// fields and the form's own host.\n\t\tthis.formObserver.observe(this.form, {\n\t\t\tattributes: true,\n\t\t\tsubtree: true,\n\t\t})\n\t\t// Defer live-region observation until the form has rendered its\n\t\t// shadow tree.\n\t\tconst attachLiveRegionObserver = async (): Promise<void> => {\n\t\t\tawait this.form?.updateComplete\n\t\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\t\tif (liveRegion) {\n\t\t\t\tthis.formObserver?.observe(liveRegion, {\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tcharacterData: true,\n\t\t\t\t\tsubtree: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Force a render so the initial state is reflected.\n\t\t\tthis.bump++\n\t\t}\n\t\tvoid attachLiveRegionObserver()\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.formObserver?.disconnect()\n\t\tthis.formObserver = undefined\n\t\tsuper.disconnectedCallback()\n\t}\n\n\tprivate readFormStatus(): 'idle' | 'submitting' | 'success' | 'error' {\n\t\tif (!this.form) return 'idle'\n\t\tif (this.form.matches(':state(error)')) return 'error'\n\t\tif (this.form.matches(':state(submitting)')) return 'submitting'\n\t\tif (this.form.matches(':state(success)')) return 'success'\n\t\treturn 'idle'\n\t}\n\n\tprivate readFormMessage(): string {\n\t\tconst liveRegion = this.form?.shadowRoot?.querySelector('[role=\"status\"]')\n\t\treturn liveRegion?.textContent?.trim() ?? ''\n\t}\n\n\tprivate readInvalidFields(): Array<{ id: string; label: string; message: string }> {\n\t\tif (!this.form) return []\n\t\tconst result: Array<{ id: string; label: string; message: string }> = []\n\t\tfor (const el of Array.from(this.form.querySelectorAll('*'))) {\n\t\t\tif (!(el instanceof HTMLElement)) continue\n\t\t\tlet isInvalid = false\n\t\t\ttry {\n\t\t\t\tisInvalid = el.matches(':state(invalid)')\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!isInvalid) continue\n\t\t\tconst f = el as HTMLElement & {\n\t\t\t\tlabel?: string\n\t\t\t\tname?: string\n\t\t\t\tvalidationMessage?: string\n\t\t\t}\n\t\t\tresult.push({\n\t\t\t\tid: f.id,\n\t\t\t\tlabel: f.label || f.name || '(field)',\n\t\t\t\tmessage: f.validationMessage || 'Invalid value',\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\trender() {\n\t\t// Read everything fresh from the DOM each render — no @state cache, no\n\t\t// re-render loops. The MutationObserver bumps `bump` to trigger this\n\t\t// render; `bump` itself is never read here.\n\t\tvoid this.bump\n\n\t\tconst status = this.readFormStatus()\n\t\tif (status !== 'error') return nothing\n\n\t\tconst formMessage = this.readFormMessage()\n\t\tconst invalid = this.readInvalidFields()\n\t\tconst count = invalid.length\n\t\tconst heading =\n\t\t\tthis.heading ??\n\t\t\t(count === 0\n\t\t\t\t? 'There is a problem with this form'\n\t\t\t\t: `There ${count === 1 ? 'is' : 'are'} ${count} problem${count === 1 ? '' : 's'} with this form`)\n\n\t\treturn html`\n\t\t\t<div role=\"alert\" aria-labelledby=\"schmancy-form-summary-heading\">\n\t\t\t\t<h2 id=\"schmancy-form-summary-heading\">${heading}</h2>\n\t\t\t\t${formMessage ? html`<p>${formMessage}</p>` : nothing}\n\t\t\t\t${count > 0\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t\t${invalid.map(\n\t\t\t\t\t\t\t\t\tf => html`\n\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#${f.id}\" @click=${(e: MouseEvent) => this.jumpToField(e, f.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t>${f.label}: ${f.message}</a\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t`\n\t\t\t\t\t: nothing}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tprivate jumpToField(e: MouseEvent, fieldId: string): void {\n\t\te.preventDefault()\n\t\tconst target = this.form?.querySelector(`#${CSS.escape(fieldId)}`) as HTMLElement | null\n\t\ttarget?.focus()\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-form-summary': SchmancyFormSummary\n\t}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"gravity-6pL6CfIr.cjs","names":[],"sources":["../src/directives/gravity.ts"],"sourcesContent":["import { directive, type ElementPart, PartType } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { from, EMPTY } from 'rxjs'\nimport { take, catchError, tap } from 'rxjs/operators'\nimport { SPRING_SMOOTH, SPRING_BOUNCY } from '../utils/animation'\nimport { reducedMotion$ } from './reduced-motion'\n\nexport interface GravityOptions {\n\t/** Mass: 0.5 (light/bouncy) to 2.0 (heavy/damped). Default: 1.0 */\n\tmass?: number\n\t/** Fall distance in pixels (default: 30) */\n\tdistance?: number\n\t/** Delay before falling in ms (default: 0) */\n\tdelay?: number\n\t/** Stagger delay per item for lists — multiply by index (default: 0) */\n\tstagger?: number\n}\n\n/**\n * Gravity directive — elements fall into place and settle with mass-based bounce.\n *\n * Only animates ONCE on first render. Re-renders do not re-trigger.\n * Disconnecting and reconnecting re-triggers the animation.\n *\n * @example\n * ```html\n * <schmancy-card ${gravity()}>content</schmancy-card>\n *\n * ${repeat(items, item => item.id, (item, i) => html`\n * <div ${gravity({ stagger: 50 * i, mass: 0.8 })}>...</div>\n * `)}\n * ```\n */\nclass GravityDirective extends AsyncDirective {\n\tprivate element!: HTMLElement\n\tprivate animation?: Animation\n\tprivate hasAnimated = false\n\tprivate options?: GravityOptions\n\n\trender(options?: GravityOptions) {\n\t\tvoid options\n\t\treturn undefined\n\t}\n\n\toverride update(part: ElementPart, [options]: [GravityOptions?]) {\n\t\tif (part.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('gravity directive must be used on an element')\n\t\t}\n\n\t\tthis.element = part.element as HTMLElement\n\t\tthis.options = options\n\n\t\tif (this.hasAnimated) return undefined\n\t\tif (reducedMotion$.value) {\n\t\t\tthis.hasAnimated = true\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst mass = Math.max(0.3, Math.min(3.0, options?.mass ?? 1.0))\n\t\tconst distance = options?.distance ?? 30\n\t\tconst delay = (options?.delay ?? 0) + (options?.stagger ?? 0)\n\n\t\tthis.animate(mass, distance, delay)\n\t\tthis.hasAnimated = true\n\n\t\treturn undefined\n\t}\n\n\toverride reconnected() {\n\t\tthis.hasAnimated = false\n\t\tif (this.options && !reducedMotion$.value) {\n\t\t\tconst mass = Math.max(0.3, Math.min(3.0, this.options.mass ?? 1.0))\n\t\t\tconst distance = this.options.distance ?? 30\n\t\t\tconst delay = (this.options.delay ?? 0) + (this.options.stagger ?? 0)\n\t\t\tthis.animate(mass, distance, delay)\n\t\t\tthis.hasAnimated = true\n\t\t}\n\t}\n\n\tprivate animate(mass: number, distance: number, delay: number) {\n\t\tconst preset = mass < 0.7 ? SPRING_BOUNCY : SPRING_SMOOTH\n\t\tconst duration = preset.duration * (1 / Math.sqrt(mass))\n\t\tconst fallDistance = distance * (1 / mass)\n\n\t\tthis.animation?.cancel()\n\n\t\tthis.element.style.willChange = 'transform, opacity'\n\t\tthis.animation = this.element.animate(\n\t\t\t[\n\t\t\t\t{ opacity: 0, transform: `translateY(-${fallDistance}px)` },\n\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration,\n\t\t\t\tdelay,\n\t\t\t\teasing: preset.easingFallback,\n\t\t\t\tfill: 'backwards',\n\t\t\t},\n\t\t)\n\n\t\t// RxJS cleanup instead of raw .then()\n\t\tfrom(this.animation.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.element.style.willChange = ''\n\t\t\t\tthis.animation = undefined\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY), // Animation cancelled — no cleanup needed\n\t\t).subscribe()\n\t}\n\n\toverride disconnected() {\n\t\tthis.animation?.cancel()\n\t\tthis.animation = undefined\n\t}\n}\n\nexport const gravity = directive(GravityDirective)\n"],"mappings":"2OAiCA,IAAM,EAAN,cAA+B,EAAA,cAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,YAAA,CAGR,CAAA,CAGtB,OAAO,EAAA,CAGP,CAEA,OAAgB,EAAA,CAAoB,GAAA,CACnC,GAAI,EAAK,OAAS,EAAA,SAAS,QAC1B,MAAU,MAAM,8CAAA,EAMjB,GAHA,KAAK,QAAU,EAAK,QACpB,KAAK,QAAU,EAEX,KAAK,YAAa,OACtB,GAAI,EAAA,EAAe,MAElB,OAAA,KADA,KAAK,YAAA,CAAc,GAIpB,IAAM,EAAO,KAAK,IAAI,GAAK,KAAK,IAAI,EAAK,GAAS,MAAQ,CAAA,CAAA,EACpD,EAAW,GAAS,UAAY,GAChC,GAAS,GAAS,OAAS,IAAM,GAAS,SAAW,GAE3D,KAAK,QAAQ,EAAM,EAAU,CAAA,EAC7B,KAAK,YAAA,CAAc,CAGpB,CAEA,aAAA,CAEC,GADA,KAAK,YAAA,CAAc,EACf,KAAK,SAAA,CAAY,EAAA,EAAe,MAAO,CAC1C,IAAM,EAAO,KAAK,IAAI,GAAK,KAAK,IAAI,EAAK,KAAK,QAAQ,MAAQ,CAAA,CAAA,EACxD,EAAW,KAAK,QAAQ,UAAY,GACpC,GAAS,KAAK,QAAQ,OAAS,IAAM,KAAK,QAAQ,SAAW,GACnE,KAAK,QAAQ,EAAM,EAAU,CAAA,EAC7B,KAAK,YAAA,CAAc,CACpB,CACD,CAEA,QAAgB,EAAc,EAAkB,EAAA,CAC/C,IAAM,EAAS,EAAO,GAAM,EAAA,EAAgB,EAAA,EACtC,EAAW,EAAO,UAAY,EAAI,KAAK,KAAK,CAAA,GAC5C,EAA2B,EAAI,EAAhB,EAErB,KAAK,WAAW,OAAA,EAEhB,KAAK,QAAQ,MAAM,WAAa,qBAChC,KAAK,UAAY,KAAK,QAAQ,QAC7B,CACC,CAAE,QAAS,EAAG,UAAW,eAAe,EAAA,IAAA,EACxC,CAAE,QAAS,EAAG,UAAW,eAAA,CAAA,EAE1B,CACC,SAAA,EACA,MAAA,EACA,OAAQ,EAAO,eACf,KAAM,WAAA,CAAA,GAKR,EAAA,EAAA,MAAK,KAAK,UAAU,QAAA,EAAU,MAAA,EAAA,EAAA,MACxB,CAAA,GAAC,EAAA,EAAA,SAAA,CAEL,KAAK,QAAQ,MAAM,WAAa,GAChC,KAAK,UAAA,IAAY,EAAA,CAAA,GACjB,EAAA,EAAA,gBACgB,EAAA,KAAA,CAAA,EAChB,UAAA,CACH,CAEA,cAAA,CACC,KAAK,WAAW,OAAA,EAChB,KAAK,UAAA,IAAY,EAClB,CAAA,EAGY,GAAA,EAAA,EAAA,WAAoB,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"gravity-6pL6CfIr.cjs","names":[],"sources":["../src/directives/gravity.ts"],"sourcesContent":["import { directive, type ElementPart, PartType } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { from, EMPTY } from 'rxjs'\nimport { take, catchError, tap } from 'rxjs/operators'\nimport { SPRING_SMOOTH, SPRING_BOUNCY } from '../utils/animation'\nimport { reducedMotion$ } from './reduced-motion'\n\nexport interface GravityOptions {\n\t/** Mass: 0.5 (light/bouncy) to 2.0 (heavy/damped). Default: 1.0 */\n\tmass?: number\n\t/** Fall distance in pixels (default: 30) */\n\tdistance?: number\n\t/** Delay before falling in ms (default: 0) */\n\tdelay?: number\n\t/** Stagger delay per item for lists — multiply by index (default: 0) */\n\tstagger?: number\n}\n\n/**\n * Gravity directive — elements fall into place and settle with mass-based bounce.\n *\n * Only animates ONCE on first render. Re-renders do not re-trigger.\n * Disconnecting and reconnecting re-triggers the animation.\n *\n * @example\n * ```html\n * <schmancy-card ${gravity()}>content</schmancy-card>\n *\n * ${repeat(items, item => item.id, (item, i) => html`\n * <div ${gravity({ stagger: 50 * i, mass: 0.8 })}>...</div>\n * `)}\n * ```\n */\nclass GravityDirective extends AsyncDirective {\n\tprivate element!: HTMLElement\n\tprivate animation?: Animation\n\tprivate hasAnimated = false\n\tprivate options?: GravityOptions\n\n\trender(options?: GravityOptions) {\n\t\tvoid options\n\t\treturn undefined\n\t}\n\n\toverride update(part: ElementPart, [options]: [GravityOptions?]) {\n\t\tif (part.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('gravity directive must be used on an element')\n\t\t}\n\n\t\tthis.element = part.element as HTMLElement\n\t\tthis.options = options\n\n\t\tif (this.hasAnimated) return undefined\n\t\tif (reducedMotion$.value) {\n\t\t\tthis.hasAnimated = true\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst mass = Math.max(0.3, Math.min(3.0, options?.mass ?? 1.0))\n\t\tconst distance = options?.distance ?? 30\n\t\tconst delay = (options?.delay ?? 0) + (options?.stagger ?? 0)\n\n\t\tthis.animate(mass, distance, delay)\n\t\tthis.hasAnimated = true\n\n\t\treturn undefined\n\t}\n\n\toverride reconnected() {\n\t\tthis.hasAnimated = false\n\t\tif (this.options && !reducedMotion$.value) {\n\t\t\tconst mass = Math.max(0.3, Math.min(3.0, this.options.mass ?? 1.0))\n\t\t\tconst distance = this.options.distance ?? 30\n\t\t\tconst delay = (this.options.delay ?? 0) + (this.options.stagger ?? 0)\n\t\t\tthis.animate(mass, distance, delay)\n\t\t\tthis.hasAnimated = true\n\t\t}\n\t}\n\n\tprivate animate(mass: number, distance: number, delay: number) {\n\t\tconst preset = mass < 0.7 ? SPRING_BOUNCY : SPRING_SMOOTH\n\t\tconst duration = preset.duration * (1 / Math.sqrt(mass))\n\t\tconst fallDistance = distance * (1 / mass)\n\n\t\tthis.animation?.cancel()\n\n\t\tthis.element.style.willChange = 'transform, opacity'\n\t\tthis.animation = this.element.animate(\n\t\t\t[\n\t\t\t\t{ opacity: 0, transform: `translateY(-${fallDistance}px)` },\n\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration,\n\t\t\t\tdelay,\n\t\t\t\teasing: preset.easingFallback,\n\t\t\t\tfill: 'backwards',\n\t\t\t},\n\t\t)\n\n\t\t// RxJS cleanup instead of raw .then()\n\t\tfrom(this.animation.finished)\n\t\t\t.pipe(\n\t\t\t\ttake(1),\n\t\t\t\ttap(() => {\n\t\t\t\t\tthis.element.style.willChange = ''\n\t\t\t\t\tthis.animation = undefined\n\t\t\t\t}),\n\t\t\t\tcatchError(() => EMPTY), // Animation cancelled — no cleanup needed\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\toverride disconnected() {\n\t\tthis.animation?.cancel()\n\t\tthis.animation = undefined\n\t}\n}\n\nexport const gravity = directive(GravityDirective)\n"],"mappings":"2OAiCA,IAAM,EAAN,cAA+B,EAAA,cAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,YAAA,CAGR,CAAA,CAGtB,OAAO,EAAA,CAGP,CAEA,OAAgB,EAAA,CAAoB,GAAA,CACnC,GAAI,EAAK,OAAS,EAAA,SAAS,QAC1B,MAAU,MAAM,8CAAA,EAMjB,GAHA,KAAK,QAAU,EAAK,QACpB,KAAK,QAAU,EAEX,KAAK,YAAa,OACtB,GAAI,EAAA,EAAe,MAElB,OAAA,KADA,KAAK,YAAA,CAAc,GAIpB,IAAM,EAAO,KAAK,IAAI,GAAK,KAAK,IAAI,EAAK,GAAS,MAAQ,CAAA,CAAA,EACpD,EAAW,GAAS,UAAY,GAChC,GAAS,GAAS,OAAS,IAAM,GAAS,SAAW,GAE3D,KAAK,QAAQ,EAAM,EAAU,CAAA,EAC7B,KAAK,YAAA,CAAc,CAGpB,CAEA,aAAA,CAEC,GADA,KAAK,YAAA,CAAc,EACf,KAAK,SAAA,CAAY,EAAA,EAAe,MAAO,CAC1C,IAAM,EAAO,KAAK,IAAI,GAAK,KAAK,IAAI,EAAK,KAAK,QAAQ,MAAQ,CAAA,CAAA,EACxD,EAAW,KAAK,QAAQ,UAAY,GACpC,GAAS,KAAK,QAAQ,OAAS,IAAM,KAAK,QAAQ,SAAW,GACnE,KAAK,QAAQ,EAAM,EAAU,CAAA,EAC7B,KAAK,YAAA,CAAc,CACpB,CACD,CAEA,QAAgB,EAAc,EAAkB,EAAA,CAC/C,IAAM,EAAS,EAAO,GAAM,EAAA,EAAgB,EAAA,EACtC,EAAW,EAAO,UAAY,EAAI,KAAK,KAAK,CAAA,GAC5C,EAA2B,EAAI,EAAhB,EAErB,KAAK,WAAW,OAAA,EAEhB,KAAK,QAAQ,MAAM,WAAa,qBAChC,KAAK,UAAY,KAAK,QAAQ,QAC7B,CACC,CAAE,QAAS,EAAG,UAAW,eAAe,EAAA,IAAA,EACxC,CAAE,QAAS,EAAG,UAAW,eAAA,CAAA,EAE1B,CACC,SAAA,EACA,MAAA,EACA,OAAQ,EAAO,eACf,KAAM,WAAA,CAAA,GAKR,EAAA,EAAA,MAAK,KAAK,UAAU,QAAA,EAClB,MAAA,EAAA,EAAA,MACK,CAAA,GAAC,EAAA,EAAA,SAAA,CAEL,KAAK,QAAQ,MAAM,WAAa,GAChC,KAAK,UAAA,IAAY,EAAA,CAAA,GACjB,EAAA,EAAA,gBACgB,EAAA,KAAA,CAAA,EAEjB,UAAA,CACH,CAEA,cAAA,CACC,KAAK,WAAW,OAAA,EAChB,KAAK,UAAA,IAAY,EAClB,CAAA,EAGY,GAAA,EAAA,EAAA,WAAoB,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}