@mhmo91/schmancy 0.10.14 → 0.10.16

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 (544) hide show
  1. package/custom-elements.json +2554 -3086
  2. package/dist/active-host-BP0zy_Y9.js +63 -0
  3. package/dist/{active-host-CvNYoprt.js.map → active-host-BP0zy_Y9.js.map} +1 -1
  4. package/dist/active-host-jH3iloCR.cjs +1 -0
  5. package/dist/{active-host-CcIa2tmW.cjs.map → active-host-jH3iloCR.cjs.map} +1 -1
  6. package/dist/agent/schmancy.agent.js +2579 -2385
  7. package/dist/agent/schmancy.agent.js.map +1 -1
  8. package/dist/agent/schmancy.manifest.json +971 -1189
  9. package/dist/{animation-CO_Csq84.cjs.map → animation-CCOIW4wJ.cjs.map} +1 -1
  10. package/dist/{animation-BK-8BwY8.js.map → animation-DCznELuT.js.map} +1 -1
  11. package/dist/{area-C_kgZZhN.js → area-ChxsDTu_.js} +2 -2
  12. package/dist/{area-C_kgZZhN.js.map → area-ChxsDTu_.js.map} +1 -1
  13. package/dist/{area-DFPtKzWy.cjs → area-Qt6yUnuA.cjs} +3 -3
  14. package/dist/{area-DFPtKzWy.cjs.map → area-Qt6yUnuA.cjs.map} +1 -1
  15. package/dist/area.cjs +1 -1
  16. package/dist/area.js +2 -2
  17. package/dist/{audio-CluX8Qpq.cjs → audio-D-TZzpXF.cjs} +1 -1
  18. package/dist/{audio-CluX8Qpq.cjs.map → audio-D-TZzpXF.cjs.map} +1 -1
  19. package/dist/{audio-DcXphulJ.js → audio-DS43uoRA.js} +1 -1
  20. package/dist/{audio-DcXphulJ.js.map → audio-DS43uoRA.js.map} +1 -1
  21. package/dist/audio.cjs +1 -1
  22. package/dist/audio.js +2 -2
  23. package/dist/{autocomplete-DWSuwSRS.js → autocomplete-CXvUjMD-.js} +46 -71
  24. package/dist/autocomplete-CXvUjMD-.js.map +1 -0
  25. package/dist/autocomplete-Ck2zbdF9.cjs +115 -0
  26. package/dist/autocomplete-Ck2zbdF9.cjs.map +1 -0
  27. package/dist/autocomplete.cjs +1 -1
  28. package/dist/autocomplete.js +1 -1
  29. package/dist/avatar.cjs +2 -2
  30. package/dist/avatar.cjs.map +1 -1
  31. package/dist/avatar.js +3 -3
  32. package/dist/badge.cjs +1 -1
  33. package/dist/badge.js +1 -1
  34. package/dist/{boat-CZma2ojF.js → boat-Bj0wVcZi.js} +5 -5
  35. package/dist/{boat-CZma2ojF.js.map → boat-Bj0wVcZi.js.map} +1 -1
  36. package/dist/{boat-Dy6cc3hB.cjs → boat-DpFkILFF.cjs} +2 -2
  37. package/dist/{boat-Dy6cc3hB.cjs.map → boat-DpFkILFF.cjs.map} +1 -1
  38. package/dist/boat.cjs +1 -1
  39. package/dist/boat.js +1 -1
  40. package/dist/breadcrumb.cjs +3 -3
  41. package/dist/breadcrumb.cjs.map +1 -1
  42. package/dist/breadcrumb.js +2 -2
  43. package/dist/{busy-DCsqryvq.cjs → busy-CtcnclA3.cjs} +3 -3
  44. package/dist/{busy-DCsqryvq.cjs.map → busy-CtcnclA3.cjs.map} +1 -1
  45. package/dist/{busy-DeV2ByMw.js → busy-CyZSBnZP.js} +2 -2
  46. package/dist/{busy-DeV2ByMw.js.map → busy-CyZSBnZP.js.map} +1 -1
  47. package/dist/busy.cjs +1 -1
  48. package/dist/busy.js +1 -1
  49. package/dist/button.cjs +4 -4
  50. package/dist/button.cjs.map +1 -1
  51. package/dist/button.js +19 -4
  52. package/dist/button.js.map +1 -1
  53. package/dist/{card--GgSX4X5.cjs → card-Cl6jp1yX.cjs} +5 -5
  54. package/dist/{card--GgSX4X5.cjs.map → card-Cl6jp1yX.cjs.map} +1 -1
  55. package/dist/{card-BTTsHzJJ.js → card-nYZCKmOO.js} +3 -3
  56. package/dist/{card-BTTsHzJJ.js.map → card-nYZCKmOO.js.map} +1 -1
  57. package/dist/card.cjs +1 -1
  58. package/dist/card.js +1 -1
  59. package/dist/{checkbox-NNReP9s_.cjs → checkbox-BeNo0ZGt.cjs} +4 -4
  60. package/dist/{checkbox-Cj5j-ppk.js.map → checkbox-BeNo0ZGt.cjs.map} +1 -1
  61. package/dist/{checkbox-Cj5j-ppk.js → checkbox-DiUrZiyc.js} +17 -30
  62. package/dist/checkbox-DiUrZiyc.js.map +1 -0
  63. package/dist/checkbox.cjs +1 -1
  64. package/dist/checkbox.js +1 -1
  65. package/dist/{chips-CP-CbfoZ.js → chips-CfPFXv7Z.js} +5 -5
  66. package/dist/{chips-CP-CbfoZ.js.map → chips-CfPFXv7Z.js.map} +1 -1
  67. package/dist/{chips-iporOXxK.cjs → chips-DK6m-VCM.cjs} +5 -5
  68. package/dist/{chips-iporOXxK.cjs.map → chips-DK6m-VCM.cjs.map} +1 -1
  69. package/dist/chips.cjs +1 -1
  70. package/dist/chips.js +2 -2
  71. package/dist/connectivity.cjs +2 -2
  72. package/dist/connectivity.cjs.map +1 -1
  73. package/dist/connectivity.js +3 -3
  74. package/dist/content-drawer.cjs +1 -1
  75. package/dist/content-drawer.js +1 -1
  76. package/dist/{context-DJTJnSK4.js.map → context-6oXCZmZN.js.map} +1 -1
  77. package/dist/{context-BpCETidA.cjs.map → context-CRZeiCqq.cjs.map} +1 -1
  78. package/dist/{cursor-glow-Bulq-38P.cjs → cursor-glow-C8LgCxpI.cjs} +1 -1
  79. package/dist/{cursor-glow-Bulq-38P.cjs.map → cursor-glow-C8LgCxpI.cjs.map} +1 -1
  80. package/dist/{cursor-glow-Ah7VXSj7.js → cursor-glow-Cs2XLDB9.js} +1 -1
  81. package/dist/{cursor-glow-Ah7VXSj7.js.map → cursor-glow-Cs2XLDB9.js.map} +1 -1
  82. package/dist/date-range-DA6anfcF.cjs +131 -0
  83. package/dist/date-range-DA6anfcF.cjs.map +1 -0
  84. package/dist/{date-range-CgNujP8r.js → date-range-DjlF2u7o.js} +124 -89
  85. package/dist/date-range-DjlF2u7o.js.map +1 -0
  86. package/dist/date-range-inline-BfYK795W.cjs +43 -0
  87. package/dist/{date-range-inline-D4IjOOO0.cjs.map → date-range-inline-BfYK795W.cjs.map} +1 -1
  88. package/dist/{date-range-inline-C2PXX_GY.js → date-range-inline-n7y_H6PJ.js} +2 -2
  89. package/dist/{date-range-inline-C2PXX_GY.js.map → date-range-inline-n7y_H6PJ.js.map} +1 -1
  90. package/dist/date-range-inline.cjs +1 -1
  91. package/dist/date-range-inline.js +1 -1
  92. package/dist/date-range.cjs +1 -1
  93. package/dist/date-range.js +1 -1
  94. package/dist/delay.cjs +2 -2
  95. package/dist/delay.cjs.map +1 -1
  96. package/dist/delay.js +3 -3
  97. package/dist/{details-DT2b3xOn.cjs → details-BdAVsLl-.cjs} +2 -2
  98. package/dist/{details-DT2b3xOn.cjs.map → details-BdAVsLl-.cjs.map} +1 -1
  99. package/dist/{details-VjaNwtfd.js → details-CS_ToAOj.js} +6 -6
  100. package/dist/{details-VjaNwtfd.js.map → details-CS_ToAOj.js.map} +1 -1
  101. package/dist/details.cjs +1 -1
  102. package/dist/details.js +1 -1
  103. package/dist/directives.cjs +1 -1
  104. package/dist/directives.js +5 -5
  105. package/dist/{divider-BMO8pzEO.js → divider-COLK0RbT.js} +2 -2
  106. package/dist/{divider-BMO8pzEO.js.map → divider-COLK0RbT.js.map} +1 -1
  107. package/dist/{divider-BW33TZ-X.cjs → divider-CvWAnvdO.cjs} +2 -2
  108. package/dist/{divider-BW33TZ-X.cjs.map → divider-CvWAnvdO.cjs.map} +1 -1
  109. package/dist/divider.cjs +1 -1
  110. package/dist/divider.js +1 -1
  111. package/dist/dropdown.cjs +3 -3
  112. package/dist/dropdown.cjs.map +1 -1
  113. package/dist/dropdown.js +2 -2
  114. package/dist/{expand-DbELKKOt.js → expand-D9LzmpoV.js} +5 -5
  115. package/dist/{expand-DbELKKOt.js.map → expand-D9LzmpoV.js.map} +1 -1
  116. package/dist/{expand-_f5EUKWB.cjs → expand-r2sATPUJ.cjs} +3 -3
  117. package/dist/{expand-_f5EUKWB.cjs.map → expand-r2sATPUJ.cjs.map} +1 -1
  118. package/dist/expand.cjs +1 -1
  119. package/dist/expand.js +1 -1
  120. package/dist/float-2nHYuBx-.cjs +1 -0
  121. package/dist/{float-CKmd-0-t.cjs.map → float-2nHYuBx-.cjs.map} +1 -1
  122. package/dist/{float-B6RBb2dN.js → float-BWy39CXr.js} +2 -2
  123. package/dist/{float-B6RBb2dN.js.map → float-BWy39CXr.js.map} +1 -1
  124. package/dist/float.cjs +1 -1
  125. package/dist/float.js +1 -1
  126. package/dist/form-DhjedCWm.js +258 -0
  127. package/dist/form-DhjedCWm.js.map +1 -0
  128. package/dist/form-g5c70rac.cjs +42 -0
  129. package/dist/form-g5c70rac.cjs.map +1 -0
  130. package/dist/form.cjs +1 -1
  131. package/dist/form.js +2 -2
  132. package/dist/handover/agent-runtime-followups.md +1 -1
  133. package/dist/handover/agent-runtime-v1.md +3 -3
  134. package/dist/{hashContent-Bobsobip.cjs.map → hashContent-Ck6laKlk.cjs.map} +1 -1
  135. package/dist/{hashContent-BU6jl5ih.js.map → hashContent-dJrI-9sc.js.map} +1 -1
  136. package/dist/{icons-r-S17M8U.cjs → icons-1HIENBco.cjs} +2 -2
  137. package/dist/{icons-r-S17M8U.cjs.map → icons-1HIENBco.cjs.map} +1 -1
  138. package/dist/{icons-CoDo95Cu.js → icons-3y0kr1aB.js} +3 -3
  139. package/dist/{icons-CoDo95Cu.js.map → icons-3y0kr1aB.js.map} +1 -1
  140. package/dist/icons.cjs +1 -1
  141. package/dist/icons.js +1 -1
  142. package/dist/{iframe-P9c_qg1-.cjs → iframe-CjqYuZG5.cjs} +2 -2
  143. package/dist/{iframe-P9c_qg1-.cjs.map → iframe-CjqYuZG5.cjs.map} +1 -1
  144. package/dist/{iframe-k4oI-TIj.js → iframe-Z5gTK-gd.js} +2 -2
  145. package/dist/{iframe-k4oI-TIj.js.map → iframe-Z5gTK-gd.js.map} +1 -1
  146. package/dist/iframe.cjs +1 -1
  147. package/dist/iframe.js +1 -1
  148. package/dist/index.cjs +1 -1
  149. package/dist/index.js +60 -60
  150. package/dist/{input-D95GjINh.js → input-B-fw6f_r.js} +103 -104
  151. package/dist/input-B-fw6f_r.js.map +1 -0
  152. package/dist/input-BtcIhu0Q.cjs +52 -0
  153. package/dist/input-BtcIhu0Q.cjs.map +1 -0
  154. package/dist/{input-chip-DpC_XEKN.js → input-chip-CtQ0pH5b.js} +2 -2
  155. package/dist/{input-chip-DpC_XEKN.js.map → input-chip-CtQ0pH5b.js.map} +1 -1
  156. package/dist/{input-chip-D0ZXqTt5.cjs → input-chip-DZktYohr.cjs} +2 -2
  157. package/dist/{input-chip-D0ZXqTt5.cjs.map → input-chip-DZktYohr.cjs.map} +1 -1
  158. package/dist/input.cjs +1 -1
  159. package/dist/input.js +1 -1
  160. package/dist/json.cjs +2 -2
  161. package/dist/json.cjs.map +1 -1
  162. package/dist/json.js +3 -3
  163. package/dist/kbd.cjs +2 -2
  164. package/dist/kbd.cjs.map +1 -1
  165. package/dist/kbd.js +2 -2
  166. package/dist/{layout-CXPNsUIo.js → layout-BH28sKGc.js} +1 -1
  167. package/dist/{layout-CXPNsUIo.js.map → layout-BH28sKGc.js.map} +1 -1
  168. package/dist/{layout-Zhe7wSZ_.cjs → layout-Delq-QvR.cjs} +1 -1
  169. package/dist/{layout-Zhe7wSZ_.cjs.map → layout-Delq-QvR.cjs.map} +1 -1
  170. package/dist/layout.cjs +1 -1
  171. package/dist/layout.js +1 -1
  172. package/dist/{lazy-Dq9mRRjT.cjs.map → lazy-CayEFyC3.cjs.map} +1 -1
  173. package/dist/{lazy-B0ia54tT.js.map → lazy-D-bO2r4m.js.map} +1 -1
  174. package/dist/{lightbox-C-yHeoK0.cjs → lightbox-BHTZOn8K.cjs} +3 -3
  175. package/dist/{lightbox-C-yHeoK0.cjs.map → lightbox-BHTZOn8K.cjs.map} +1 -1
  176. package/dist/{lightbox-CovQtmyn.js → lightbox-BL3LWp-P.js} +9 -9
  177. package/dist/{lightbox-CovQtmyn.js.map → lightbox-BL3LWp-P.js.map} +1 -1
  178. package/dist/lightbox.cjs +1 -1
  179. package/dist/lightbox.js +1 -1
  180. package/dist/{list-CAijuky4.cjs → list-CHYa5VGY.cjs} +3 -3
  181. package/dist/{list-CAijuky4.cjs.map → list-CHYa5VGY.cjs.map} +1 -1
  182. package/dist/{list-C1pR9vhu.js → list-DLJL1JQj.js} +2 -2
  183. package/dist/{list-C1pR9vhu.js.map → list-DLJL1JQj.js.map} +1 -1
  184. package/dist/list.cjs +1 -1
  185. package/dist/list.js +1 -1
  186. package/dist/{magnetic-BJgB1dVi.cjs → magnetic-Bgh7aHHI.cjs} +1 -1
  187. package/dist/{magnetic-BJgB1dVi.cjs.map → magnetic-Bgh7aHHI.cjs.map} +1 -1
  188. package/dist/{magnetic-YwCNvtbB.js → magnetic-DxvoEz8_.js} +2 -2
  189. package/dist/{magnetic-YwCNvtbB.js.map → magnetic-DxvoEz8_.js.map} +1 -1
  190. package/dist/{menu-B59vZv9n.js → menu-BNq93w6X.js} +3 -3
  191. package/dist/{menu-B59vZv9n.js.map → menu-BNq93w6X.js.map} +1 -1
  192. package/dist/{menu-BaHO3Cip.cjs → menu-DAikvkeV.cjs} +3 -3
  193. package/dist/{menu-BaHO3Cip.cjs.map → menu-DAikvkeV.cjs.map} +1 -1
  194. package/dist/menu.cjs +1 -1
  195. package/dist/menu.js +1 -1
  196. package/dist/mixins-BOOu6q2n.cjs +298 -0
  197. package/dist/mixins-BOOu6q2n.cjs.map +1 -0
  198. package/dist/mixins-BWb9_e1s.js +680 -0
  199. package/dist/mixins-BWb9_e1s.js.map +1 -0
  200. package/dist/mixins.cjs +1 -1
  201. package/dist/mixins.js +2 -2
  202. package/dist/nav-drawer.cjs +1 -1
  203. package/dist/nav-drawer.js +1 -1
  204. package/dist/navigation-bar.cjs +1 -1
  205. package/dist/navigation-bar.js +1 -1
  206. package/dist/navigation-rail.cjs +3 -3
  207. package/dist/navigation-rail.cjs.map +1 -1
  208. package/dist/navigation-rail.js +2 -2
  209. package/dist/{notification-BeLoVa47.js → notification-CUmb9c3Y.js} +4 -4
  210. package/dist/{notification-BeLoVa47.js.map → notification-CUmb9c3Y.js.map} +1 -1
  211. package/dist/notification-Dy2azMyt.cjs +23 -0
  212. package/dist/{notification-BC9nG8Sr.cjs.map → notification-Dy2azMyt.cjs.map} +1 -1
  213. package/dist/notification.cjs +1 -1
  214. package/dist/notification.js +1 -1
  215. package/dist/{option-BWF4GBp-.cjs → option-CDgIKifG.cjs} +2 -2
  216. package/dist/{option-BWF4GBp-.cjs.map → option-CDgIKifG.cjs.map} +1 -1
  217. package/dist/{option-UvlSAcC4.js → option-DFvQ551b.js} +2 -2
  218. package/dist/{option-UvlSAcC4.js.map → option-DFvQ551b.js.map} +1 -1
  219. package/dist/option.cjs +1 -1
  220. package/dist/option.js +1 -1
  221. package/dist/{overlay-stack-DCDS17uj.js.map → overlay-stack-BR4iYivO.js.map} +1 -1
  222. package/dist/{overlay-stack-DPIe_aYv.cjs.map → overlay-stack-Dk0xETTy.cjs.map} +1 -1
  223. package/dist/overlay.cjs +2 -2
  224. package/dist/overlay.cjs.map +1 -1
  225. package/dist/{overlay.confirm-body-URtE1gI3.cjs → overlay.confirm-body-BkhNvr0c.cjs} +2 -2
  226. package/dist/{overlay.confirm-body-URtE1gI3.cjs.map → overlay.confirm-body-BkhNvr0c.cjs.map} +1 -1
  227. package/dist/{overlay.confirm-body-9W0B5QGv.js → overlay.confirm-body-uFp-0Zfh.js} +2 -2
  228. package/dist/{overlay.confirm-body-9W0B5QGv.js.map → overlay.confirm-body-uFp-0Zfh.js.map} +1 -1
  229. package/dist/overlay.js +8 -8
  230. package/dist/{overlay.service-DnZTcKyJ.cjs → overlay.service-1YWfUD2S.cjs} +1 -1
  231. package/dist/{overlay.service-DnZTcKyJ.cjs.map → overlay.service-1YWfUD2S.cjs.map} +1 -1
  232. package/dist/{overlay.service-CVqs2Gu1.js → overlay.service-BcF12kGb.js} +2 -2
  233. package/dist/{overlay.service-CVqs2Gu1.js.map → overlay.service-BcF12kGb.js.map} +1 -1
  234. package/dist/page.cjs +2 -2
  235. package/dist/page.cjs.map +1 -1
  236. package/dist/page.js +5 -5
  237. package/dist/{progress-CwzwY8Oe.cjs → progress-C02sWkmE.cjs} +2 -2
  238. package/dist/{progress-CwzwY8Oe.cjs.map → progress-C02sWkmE.cjs.map} +1 -1
  239. package/dist/{progress-C29Uw-WJ.js → progress-bLbGRuQ1.js} +2 -2
  240. package/dist/{progress-C29Uw-WJ.js.map → progress-bLbGRuQ1.js.map} +1 -1
  241. package/dist/progress.cjs +1 -1
  242. package/dist/progress.js +1 -1
  243. package/dist/radio-group-BA-jRct5.cjs +40 -0
  244. package/dist/radio-group-BA-jRct5.cjs.map +1 -0
  245. package/dist/{radio-group-CW8airhZ.js → radio-group-DA4eIGCj.js} +4 -4
  246. package/dist/radio-group-DA4eIGCj.js.map +1 -0
  247. package/dist/radio-group.cjs +1 -1
  248. package/dist/radio-group.js +1 -1
  249. package/dist/range.cjs +6 -4
  250. package/dist/range.cjs.map +1 -1
  251. package/dist/range.js +19 -15
  252. package/dist/range.js.map +1 -1
  253. package/dist/{reduced-motion-D-L12p7G.js.map → reduced-motion-D7LqTUMn.js.map} +1 -1
  254. package/dist/{reduced-motion-Ds-HjMzn.cjs.map → reduced-motion-Dzfp_w5x.cjs.map} +1 -1
  255. package/dist/{rxjs-utils-CVeJQ9KG.js.map → rxjs-utils-D9U4MW0Q.js.map} +1 -1
  256. package/dist/{rxjs-utils-DCUHg_Ml.cjs.map → rxjs-utils-kWPShgKu.cjs.map} +1 -1
  257. package/dist/rxjs-utils.cjs +1 -1
  258. package/dist/rxjs-utils.js +1 -1
  259. package/dist/{scroll-BotoGcMU.js → scroll-CG5up5oy.js} +2 -2
  260. package/dist/{scroll-BotoGcMU.js.map → scroll-CG5up5oy.js.map} +1 -1
  261. package/dist/{scroll-CmhmUebp.cjs → scroll-D8vBF_gY.cjs} +2 -2
  262. package/dist/{scroll-CmhmUebp.cjs.map → scroll-D8vBF_gY.cjs.map} +1 -1
  263. package/dist/{search-BLCRsxIC.cjs.map → search-DPKoC-dT.cjs.map} +1 -1
  264. package/dist/{search-BTz7-Rev.js.map → search-MvIBA93K.js.map} +1 -1
  265. package/dist/{select-Dbn-CImU.js → select-BrK1BJoU.js} +52 -73
  266. package/dist/select-BrK1BJoU.js.map +1 -0
  267. package/dist/select-Dh2j7Qc-.cjs +56 -0
  268. package/dist/select-Dh2j7Qc-.cjs.map +1 -0
  269. package/dist/select.cjs +1 -1
  270. package/dist/select.js +1 -1
  271. package/dist/skeleton.cjs +2 -2
  272. package/dist/skeleton.cjs.map +1 -1
  273. package/dist/skeleton.js +2 -2
  274. package/dist/skills/autocomplete.md +16 -3
  275. package/dist/skills/button.md +19 -0
  276. package/dist/skills/checkbox.md +19 -0
  277. package/dist/skills/date-range.md +19 -0
  278. package/dist/skills/form-ux-rules.md +55 -0
  279. package/dist/skills/form.md +121 -25
  280. package/dist/skills/input.md +19 -4
  281. package/dist/skills/range.md +15 -1
  282. package/dist/skills/schmancy/autocomplete.md +16 -3
  283. package/dist/skills/schmancy/button.md +19 -0
  284. package/dist/skills/schmancy/checkbox.md +19 -0
  285. package/dist/skills/schmancy/date-range.md +19 -0
  286. package/dist/skills/schmancy/form-ux-rules.md +55 -0
  287. package/dist/skills/schmancy/form.md +121 -25
  288. package/dist/skills/schmancy/input.md +19 -4
  289. package/dist/skills/schmancy/range.md +15 -1
  290. package/dist/skills/schmancy/select.md +13 -1
  291. package/dist/skills/schmancy/state.md +5 -0
  292. package/dist/skills/schmancy/switch.md +21 -2
  293. package/dist/skills/schmancy/textarea.md +13 -0
  294. package/dist/skills/select.md +13 -1
  295. package/dist/skills/state.md +5 -0
  296. package/dist/skills/switch.md +21 -2
  297. package/dist/skills/textarea.md +13 -0
  298. package/dist/slider.cjs +3 -3
  299. package/dist/slider.cjs.map +1 -1
  300. package/dist/slider.js +2 -2
  301. package/dist/{sound.service-kKfsN0m-.js → sound.service-BIN2W7Rv.js} +1 -1
  302. package/dist/{sound.service-kKfsN0m-.js.map → sound.service-BIN2W7Rv.js.map} +1 -1
  303. package/dist/{sound.service-BGs6m0Cm.cjs → sound.service-DyY78ukR.cjs} +1 -1
  304. package/dist/{sound.service-BGs6m0Cm.cjs.map → sound.service-DyY78ukR.cjs.map} +1 -1
  305. package/dist/{splash-screen-DtkjCJYo.js → splash-screen-BcjjJSlK.js} +2 -2
  306. package/dist/{splash-screen-DtkjCJYo.js.map → splash-screen-BcjjJSlK.js.map} +1 -1
  307. package/dist/{splash-screen-DlQUv-kV.cjs → splash-screen-Kr1sPtME.cjs} +2 -2
  308. package/dist/{splash-screen-DlQUv-kV.cjs.map → splash-screen-Kr1sPtME.cjs.map} +1 -1
  309. package/dist/splash-screen.cjs +1 -1
  310. package/dist/splash-screen.js +1 -1
  311. package/dist/{src-DEUjlTsX.cjs → src-B2-CU8fu.cjs} +11 -11
  312. package/dist/{src-DEUjlTsX.cjs.map → src-B2-CU8fu.cjs.map} +1 -1
  313. package/dist/{src-D6e0adHi.js → src-DvywUq7l.js} +38 -38
  314. package/dist/{src-D6e0adHi.js.map → src-DvywUq7l.js.map} +1 -1
  315. package/dist/state-avic94Ft.cjs +1 -0
  316. package/dist/{state-DNdCPITt.cjs.map → state-avic94Ft.cjs.map} +1 -1
  317. package/dist/{state-BusMG6sM.js → state-nm8yzMPp.js} +1 -2
  318. package/dist/{state-BusMG6sM.js.map → state-nm8yzMPp.js.map} +1 -1
  319. package/dist/state.cjs +1 -1
  320. package/dist/state.js +2 -2
  321. package/dist/steps.cjs +3 -3
  322. package/dist/steps.cjs.map +1 -1
  323. package/dist/steps.js +2 -2
  324. package/dist/{surface-A82O1kgu.js → surface-BtMMHKol.js} +2 -2
  325. package/dist/{surface-A82O1kgu.js.map → surface-BtMMHKol.js.map} +1 -1
  326. package/dist/surface-CgXeKdGL.cjs +7 -0
  327. package/dist/{surface-BpppoNXN.cjs.map → surface-CgXeKdGL.cjs.map} +1 -1
  328. package/dist/surface.cjs +1 -1
  329. package/dist/surface.js +1 -1
  330. package/dist/switch.cjs +3 -3
  331. package/dist/switch.cjs.map +1 -1
  332. package/dist/switch.js +27 -43
  333. package/dist/switch.js.map +1 -1
  334. package/dist/table.cjs +3 -3
  335. package/dist/table.cjs.map +1 -1
  336. package/dist/table.js +2 -2
  337. package/dist/{tabs-cVHHd1dY.js → tabs-CikPr7by.js} +2 -2
  338. package/dist/{tabs-cVHHd1dY.js.map → tabs-CikPr7by.js.map} +1 -1
  339. package/dist/{tabs-TO3UiBsm.cjs → tabs-CitVls3_.cjs} +2 -2
  340. package/dist/{tabs-TO3UiBsm.cjs.map → tabs-CitVls3_.cjs.map} +1 -1
  341. package/dist/tabs.cjs +1 -1
  342. package/dist/tabs.js +1 -1
  343. package/dist/teleport.cjs +1 -1
  344. package/dist/teleport.js +1 -1
  345. package/dist/textarea-CqV1wvmB.cjs +43 -0
  346. package/dist/textarea-CqV1wvmB.cjs.map +1 -0
  347. package/dist/textarea-DVkwQSis.js +186 -0
  348. package/dist/textarea-DVkwQSis.js.map +1 -0
  349. package/dist/textarea.cjs +1 -1
  350. package/dist/textarea.js +1 -1
  351. package/dist/{theme-CT408FqH.js → theme-BIWS4TOW.js} +9 -9
  352. package/dist/{theme-CT408FqH.js.map → theme-BIWS4TOW.js.map} +1 -1
  353. package/dist/theme-DMgjiKda.cjs +181 -0
  354. package/dist/{theme-CpuF3D3q.cjs.map → theme-DMgjiKda.cjs.map} +1 -1
  355. package/dist/{theme-button-pTb5-Wxx.js → theme-button-DC_shZ_7.js} +2 -2
  356. package/dist/{theme-button-pTb5-Wxx.js.map → theme-button-DC_shZ_7.js.map} +1 -1
  357. package/dist/theme-button-ENKa3TPT.cjs +8 -0
  358. package/dist/{theme-button-B6Xf-EiH.cjs.map → theme-button-ENKa3TPT.cjs.map} +1 -1
  359. package/dist/theme-button.cjs +1 -1
  360. package/dist/theme-button.js +1 -1
  361. package/dist/theme.cjs +1 -1
  362. package/dist/{theme.interface-B9TjbSBF.js.map → theme.interface-C8OHheXg.js.map} +1 -1
  363. package/dist/{theme.interface-BujperTo.cjs.map → theme.interface-CYo4UpWK.cjs.map} +1 -1
  364. package/dist/theme.js +4 -4
  365. package/dist/{theme.service-DIUo1mBP.js → theme.service-BOWIT_5k.js} +1 -1
  366. package/dist/{theme.service-DIUo1mBP.js.map → theme.service-BOWIT_5k.js.map} +1 -1
  367. package/dist/{theme.service-Cfk88qHK.cjs → theme.service-DkdH1t60.cjs} +1 -1
  368. package/dist/{theme.service-Cfk88qHK.cjs.map → theme.service-DkdH1t60.cjs.map} +1 -1
  369. package/dist/tree.cjs +2 -2
  370. package/dist/tree.cjs.map +1 -1
  371. package/dist/tree.js +2 -2
  372. package/dist/typography.cjs +2 -2
  373. package/dist/typography.cjs.map +1 -1
  374. package/dist/typography.js +2 -2
  375. package/dist/{utils-kND2Z9Xg.js → utils-Cj_nRRyx.js} +2 -2
  376. package/dist/{utils-kND2Z9Xg.js.map → utils-Cj_nRRyx.js.map} +1 -1
  377. package/dist/{utils-Dt5PpmaQ.cjs → utils-D2QUu4-g.cjs} +1 -1
  378. package/dist/{utils-Dt5PpmaQ.cjs.map → utils-D2QUu4-g.cjs.map} +1 -1
  379. package/dist/utils.cjs +1 -1
  380. package/dist/utils.js +4 -4
  381. package/dist/visually-hidden.cjs +2 -2
  382. package/dist/visually-hidden.cjs.map +1 -1
  383. package/dist/visually-hidden.js +2 -2
  384. package/dist/{window-CuBcOxbc.js → window-BTecgE_U.js} +7 -7
  385. package/dist/{window-CuBcOxbc.js.map → window-BTecgE_U.js.map} +1 -1
  386. package/dist/{window-CSKvv4Ts.cjs → window-DGydMS0g.cjs} +2 -2
  387. package/dist/{window-CSKvv4Ts.cjs.map → window-DGydMS0g.cjs.map} +1 -1
  388. package/dist/window.cjs +1 -1
  389. package/dist/window.js +1 -1
  390. package/package.json +1 -1
  391. package/skills/schmancy/autocomplete.md +16 -3
  392. package/skills/schmancy/button.md +19 -0
  393. package/skills/schmancy/checkbox.md +19 -0
  394. package/skills/schmancy/date-range.md +19 -0
  395. package/skills/schmancy/form-ux-rules.md +55 -0
  396. package/skills/schmancy/form.md +121 -25
  397. package/skills/schmancy/input.md +19 -4
  398. package/skills/schmancy/range.md +15 -1
  399. package/skills/schmancy/select.md +13 -1
  400. package/skills/schmancy/state.md +5 -0
  401. package/skills/schmancy/switch.md +21 -2
  402. package/skills/schmancy/textarea.md +13 -0
  403. package/src/button/button.test.ts +122 -0
  404. package/src/button/button.ts +36 -0
  405. package/src/{autocomplete → form/fields/autocomplete}/autocomplete.ts +48 -75
  406. package/src/{checkbox → form/fields/checkbox}/checkbox.test.ts +1 -1
  407. package/src/form/fields/checkbox/checkbox.ts +126 -0
  408. package/src/form/fields/date-range/date-range.test.ts +102 -0
  409. package/src/{date-range → form/fields/date-range}/date-range.ts +90 -7
  410. package/src/form/fields/input/input.test.ts +201 -0
  411. package/src/{input → form/fields/input}/input.ts +153 -238
  412. package/src/{radio-group → form/fields/radio-group}/radio-button.ts +1 -1
  413. package/src/{radio-group → form/fields/radio-group}/radio-group.ts +1 -1
  414. package/src/form/fields/range/range.test.ts +90 -0
  415. package/src/{range → form/fields/range}/range.ts +34 -13
  416. package/src/{select → form/fields/select}/select.ts +77 -108
  417. package/src/{switch → form/fields/switch}/switch.test.ts +1 -1
  418. package/src/{switch → form/fields/switch}/switch.ts +71 -51
  419. package/src/form/fields/textarea/textarea.test.ts +54 -0
  420. package/src/{textarea → form/fields/textarea}/textarea.ts +33 -72
  421. package/src/form/form-state.ts +31 -0
  422. package/src/form/form-summary.test.ts +105 -0
  423. package/src/form/form-summary.ts +171 -0
  424. package/src/form/form.test.ts +218 -35
  425. package/src/form/form.ts +330 -99
  426. package/src/form/index.ts +2 -0
  427. package/src/index.ts +9 -9
  428. package/types/mixins/formField.mixin.d.ts +90 -0
  429. package/types/src/button/button.d.ts +9 -0
  430. package/types/src/button/button.test.d.ts +3 -0
  431. package/types/src/{autocomplete → form/fields/autocomplete}/autocomplete.d.ts +6 -15
  432. package/types/src/form/fields/checkbox/checkbox.d.ts +47 -0
  433. package/types/src/{date-range → form/fields/date-range}/date-range.d.ts +22 -4
  434. package/types/src/form/fields/date-range/date-range.test.d.ts +1 -0
  435. package/types/src/{input → form/fields/input}/input.d.ts +20 -45
  436. package/types/src/form/fields/input/input.test.d.ts +1 -0
  437. package/types/src/{radio-group → form/fields/radio-group}/radio-button.d.ts +1 -1
  438. package/types/src/{radio-group → form/fields/radio-group}/radio-group.d.ts +1 -1
  439. package/types/src/form/fields/range/range.d.ts +28 -0
  440. package/types/src/form/fields/range/range.test.d.ts +1 -0
  441. package/types/src/{select → form/fields/select}/select.d.ts +23 -24
  442. package/types/src/form/fields/switch/switch.d.ts +57 -0
  443. package/types/src/{textarea → form/fields/textarea}/textarea.d.ts +6 -39
  444. package/types/src/form/fields/textarea/textarea.test.d.ts +1 -0
  445. package/types/src/form/form-state.d.ts +22 -0
  446. package/types/src/form/form-summary.d.ts +42 -0
  447. package/types/src/form/form-summary.test.d.ts +4 -0
  448. package/types/src/form/form.d.ts +79 -34
  449. package/types/src/form/form.test.d.ts +2 -2
  450. package/types/src/form/index.d.ts +2 -0
  451. package/types/src/index.d.ts +9 -9
  452. package/dist/active-host-CcIa2tmW.cjs +0 -1
  453. package/dist/active-host-CvNYoprt.js +0 -57
  454. package/dist/autocomplete-DWSuwSRS.js.map +0 -1
  455. package/dist/autocomplete-iCJOia-q.cjs +0 -115
  456. package/dist/autocomplete-iCJOia-q.cjs.map +0 -1
  457. package/dist/checkbox-NNReP9s_.cjs.map +0 -1
  458. package/dist/date-range-CaOxwZDq.cjs +0 -131
  459. package/dist/date-range-CaOxwZDq.cjs.map +0 -1
  460. package/dist/date-range-CgNujP8r.js.map +0 -1
  461. package/dist/date-range-inline-D4IjOOO0.cjs +0 -43
  462. package/dist/decorate-23nYs4Le.js +0 -7
  463. package/dist/decorate-DpFmy0nm.cjs +0 -1
  464. package/dist/float-CKmd-0-t.cjs +0 -1
  465. package/dist/form-CFvwnfuJ.js +0 -68
  466. package/dist/form-CFvwnfuJ.js.map +0 -1
  467. package/dist/form-Ceijw1aA.cjs +0 -1
  468. package/dist/form-Ceijw1aA.cjs.map +0 -1
  469. package/dist/input-D95GjINh.js.map +0 -1
  470. package/dist/input-D9s4jDAb.cjs +0 -51
  471. package/dist/input-D9s4jDAb.cjs.map +0 -1
  472. package/dist/mixins-BV0w2yIE.js +0 -627
  473. package/dist/mixins-BV0w2yIE.js.map +0 -1
  474. package/dist/mixins-DvAYa-F7.cjs +0 -298
  475. package/dist/mixins-DvAYa-F7.cjs.map +0 -1
  476. package/dist/notification-BC9nG8Sr.cjs +0 -23
  477. package/dist/radio-group-ByMD6Lsj.cjs +0 -40
  478. package/dist/radio-group-ByMD6Lsj.cjs.map +0 -1
  479. package/dist/radio-group-CW8airhZ.js.map +0 -1
  480. package/dist/select-BdBThja4.cjs +0 -56
  481. package/dist/select-BdBThja4.cjs.map +0 -1
  482. package/dist/select-Dbn-CImU.js.map +0 -1
  483. package/dist/state-DNdCPITt.cjs +0 -1
  484. package/dist/surface-BpppoNXN.cjs +0 -7
  485. package/dist/textarea-B9dy-yec.js +0 -211
  486. package/dist/textarea-B9dy-yec.js.map +0 -1
  487. package/dist/textarea-DFY0Flgv.cjs +0 -39
  488. package/dist/textarea-DFY0Flgv.cjs.map +0 -1
  489. package/dist/theme-CpuF3D3q.cjs +0 -181
  490. package/dist/theme-button-B6Xf-EiH.cjs +0 -8
  491. package/src/checkbox/checkbox.ts +0 -162
  492. package/types/src/checkbox/checkbox.d.ts +0 -71
  493. package/types/src/range/range.d.ts +0 -25
  494. package/types/src/switch/switch.d.ts +0 -53
  495. /package/dist/{animation-CO_Csq84.cjs → animation-CCOIW4wJ.cjs} +0 -0
  496. /package/dist/{animation-BK-8BwY8.js → animation-DCznELuT.js} +0 -0
  497. /package/dist/{context-DJTJnSK4.js → context-6oXCZmZN.js} +0 -0
  498. /package/dist/{context-BpCETidA.cjs → context-CRZeiCqq.cjs} +0 -0
  499. /package/dist/{hashContent-Bobsobip.cjs → hashContent-Ck6laKlk.cjs} +0 -0
  500. /package/dist/{hashContent-BU6jl5ih.js → hashContent-dJrI-9sc.js} +0 -0
  501. /package/dist/{lazy-Dq9mRRjT.cjs → lazy-CayEFyC3.cjs} +0 -0
  502. /package/dist/{lazy-B0ia54tT.js → lazy-D-bO2r4m.js} +0 -0
  503. /package/dist/{overlay-stack-DCDS17uj.js → overlay-stack-BR4iYivO.js} +0 -0
  504. /package/dist/{overlay-stack-DPIe_aYv.cjs → overlay-stack-Dk0xETTy.cjs} +0 -0
  505. /package/dist/{reduced-motion-D-L12p7G.js → reduced-motion-D7LqTUMn.js} +0 -0
  506. /package/dist/{reduced-motion-Ds-HjMzn.cjs → reduced-motion-Dzfp_w5x.cjs} +0 -0
  507. /package/dist/{rxjs-utils-CVeJQ9KG.js → rxjs-utils-D9U4MW0Q.js} +0 -0
  508. /package/dist/{rxjs-utils-DCUHg_Ml.cjs → rxjs-utils-kWPShgKu.cjs} +0 -0
  509. /package/dist/{search-BLCRsxIC.cjs → search-DPKoC-dT.cjs} +0 -0
  510. /package/dist/{search-BTz7-Rev.js → search-MvIBA93K.js} +0 -0
  511. /package/dist/{theme.interface-B9TjbSBF.js → theme.interface-C8OHheXg.js} +0 -0
  512. /package/dist/{theme.interface-BujperTo.cjs → theme.interface-CYo4UpWK.cjs} +0 -0
  513. /package/src/{autocomplete → form/fields/autocomplete}/autocomplete.scss +0 -0
  514. /package/src/{autocomplete → form/fields/autocomplete}/index.ts +0 -0
  515. /package/src/{checkbox → form/fields/checkbox}/index.ts +0 -0
  516. /package/src/{date-range → form/fields/date-range}/date-range-dialog.ts +0 -0
  517. /package/src/{date-range → form/fields/date-range}/date-range-helpers.ts +0 -0
  518. /package/src/{date-range → form/fields/date-range}/date-range-presets.ts +0 -0
  519. /package/src/{date-range → form/fields/date-range}/date-utils.ts +0 -0
  520. /package/src/{date-range → form/fields/date-range}/index.ts +0 -0
  521. /package/src/{input → form/fields/input}/index.ts +0 -0
  522. /package/src/{input → form/fields/input}/input.scss +0 -0
  523. /package/src/{radio-group → form/fields/radio-group}/index.ts +0 -0
  524. /package/src/{radio-group → form/fields/radio-group}/radio-group.scss +0 -0
  525. /package/src/{range → form/fields/range}/index.ts +0 -0
  526. /package/src/{select → form/fields/select}/index.ts +0 -0
  527. /package/src/{switch → form/fields/switch}/index.ts +0 -0
  528. /package/src/{textarea → form/fields/textarea}/index.ts +0 -0
  529. /package/src/{textarea → form/fields/textarea}/textarea.scss +0 -0
  530. /package/types/src/{autocomplete → form/fields/autocomplete}/index.d.ts +0 -0
  531. /package/types/src/{checkbox → form/fields/checkbox}/checkbox.test.d.ts +0 -0
  532. /package/types/src/{checkbox → form/fields/checkbox}/index.d.ts +0 -0
  533. /package/types/src/{date-range → form/fields/date-range}/date-range-dialog.d.ts +0 -0
  534. /package/types/src/{date-range → form/fields/date-range}/date-range-helpers.d.ts +0 -0
  535. /package/types/src/{date-range → form/fields/date-range}/date-range-presets.d.ts +0 -0
  536. /package/types/src/{date-range → form/fields/date-range}/date-utils.d.ts +0 -0
  537. /package/types/src/{date-range → form/fields/date-range}/index.d.ts +0 -0
  538. /package/types/src/{input → form/fields/input}/index.d.ts +0 -0
  539. /package/types/src/{radio-group → form/fields/radio-group}/index.d.ts +0 -0
  540. /package/types/src/{range → form/fields/range}/index.d.ts +0 -0
  541. /package/types/src/{select → form/fields/select}/index.d.ts +0 -0
  542. /package/types/src/{switch → form/fields/switch}/index.d.ts +0 -0
  543. /package/types/src/{switch → form/fields/switch}/switch.test.d.ts +0 -0
  544. /package/types/src/{textarea → form/fields/textarea}/index.d.ts +0 -0
@@ -1,9 +1,9 @@
1
- import { html, LitElement, nothing, PropertyValueMap, unsafeCSS } from 'lit'
1
+ import { html, LitElement, nothing, unsafeCSS } from 'lit'
2
2
  import { customElement, property, query, state } from 'lit/decorators.js'
3
3
  import { ifDefined } from 'lit/directives/if-defined.js'
4
4
  import { createRef, ref } from 'lit/directives/ref.js'
5
5
  import { when } from 'lit/directives/when.js'
6
- import { distinctUntilChanged, filter, fromEvent, map, takeUntil } from 'rxjs'
6
+ import { distinctUntilChanged, filter, fromEvent, map, takeUntil, timer } from 'rxjs'
7
7
 
8
8
  import { SchmancyFormField } from '@mixins/index'
9
9
 
@@ -147,16 +147,6 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
147
147
  @property({ type: String, reflect: true })
148
148
  public size: InputSize = 'md'
149
149
 
150
- /**
151
- * Controls when validation should show.
152
- * - 'always' - Always show validation
153
- * - 'touched' - Only show after field has been focused and then blurred
154
- * - 'dirty' - Only show after value has changed
155
- * - 'submitted' - Only show after form submission
156
- */
157
- @property({ type: String })
158
- public validateOn: 'always' | 'touched' | 'dirty' | 'submitted' = 'touched'
159
-
160
150
  /**
161
151
  * For datalist support
162
152
  */
@@ -180,23 +170,8 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
180
170
  @state()
181
171
  private isAutofilled = false
182
172
 
183
- /**
184
- * Track user interaction state for validation
185
- */
186
- @state()
187
- private touched = false
188
-
189
- @state()
190
- private dirty = false
191
-
192
- @state()
193
- private submitted = false
194
-
195
- /**
196
- * Store the default value for reset behavior
197
- */
198
- @state()
199
- private defaultValue = ''
173
+ // `touched`, `dirty`, `submitted`, and `validateOn` come from FormFieldMixin.
174
+ // `_defaultValue` (mixin) replaces the old `defaultValue` field.
200
175
 
201
176
  // ----------------------------
202
177
  // D) Form-associated logic
@@ -206,95 +181,34 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
206
181
  delegatesFocus: true, // so focus() goes to <input>
207
182
  }
208
183
 
209
- private formResetObserver?: MutationObserver
210
-
211
184
  /**
212
185
  * If user did not provide an ID, auto-generate one so <label for="...">
213
186
  * and various aria-* attributes can reference it.
214
187
  */
215
- protected override willUpdate(changedProps: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
188
+ protected override willUpdate(changedProps: Map<PropertyKey, unknown>) {
216
189
  if (!this.id) {
217
190
  this.id = `sch-input-${SchmancyInput._idCounter++}`
218
191
  }
219
- super.willUpdate(changedProps)
192
+ super.willUpdate(changedProps as never)
220
193
  }
221
194
 
222
195
 
223
- protected override updated(changedProps: Map<string, unknown>) {
224
- super.updated(changedProps)
225
-
226
- // Handle value changes
227
- if (changedProps.has('value')) {
228
- // If value changes from original default, mark as dirty
229
- if (this.value !== this.defaultValue) {
230
- this.dirty = true
231
- }
232
-
233
- // Update validation state when value changes
234
- this.validateInput()
235
- }
236
-
237
- // Store default value if this is the first update
238
- if (!this.hasUpdated && changedProps.has('value')) {
239
- this.defaultValue = this.value
240
- }
241
- }
196
+ // `updated()` removed FormFieldMixin's `willUpdate` recomputes `dirty`,
197
+ // triggers `checkValidity()` when `_shouldShowError()` is true, and updates
198
+ // `:state(dirty)` automatically.
199
+ //
200
+ // Default value capture is also handled by the mixin (`firstUpdated` sets
201
+ // `_defaultValue` from `value`).
242
202
 
243
- /**
244
- * Connect to the closest form element and set up form integration
245
- */
246
203
  connectedCallback() {
247
204
  super.connectedCallback()
248
205
 
249
- // Store initial default value for form reset
250
- this.defaultValue = this.value
251
-
252
- // Set up form integration
253
- this.setupFormIntegration()
254
-
255
- // Setup for external label association
206
+ // Form reset and submit are now handled by the mixin via FACE callbacks
207
+ // (`formResetCallback`) and by `<schmancy-form>`'s submit sweep
208
+ // (`markSubmitted()`). No manual form listeners needed.
256
209
  this.setupExternalLabelAssociation()
257
210
  }
258
211
 
259
- /**
260
- * Set up form integration with ElementInternals
261
- */
262
- private setupFormIntegration() {
263
- if (this.form) {
264
- // Listen for form reset events
265
- this.formResetObserver = new MutationObserver(mutations => {
266
- for (const mutation of mutations) {
267
- if (mutation.type === 'attributes' && mutation.attributeName === 'reset') {
268
- this.resetToDefault()
269
- }
270
- }
271
- })
272
-
273
- // Observe the form for reset events
274
- this.formResetObserver.observe(this.form, {
275
- attributes: true,
276
- childList: false,
277
- subtree: false,
278
- })
279
-
280
- // Use RxJS for form reset events
281
- fromEvent(this.form, 'reset')
282
- .pipe(takeUntil(this.disconnecting))
283
- .subscribe(() => {
284
- this.resetToDefault()
285
- })
286
-
287
- // Use RxJS for form submit events to mark field as submitted
288
- fromEvent(this.form, 'submit')
289
- .pipe(takeUntil(this.disconnecting))
290
- .subscribe(() => {
291
- this.submitted = true
292
- // Validate on form submission
293
- this.validateInput(true)
294
- })
295
- }
296
- }
297
-
298
212
  /**
299
213
  * Set up external label association for native HTML label support
300
214
  */
@@ -324,149 +238,160 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
324
238
  }
325
239
  }
326
240
 
327
- disconnectedCallback() {
328
- super.disconnectedCallback()
329
-
330
- // Clean up the form observer
331
- if (this.formResetObserver) {
332
- this.formResetObserver.disconnect()
333
- }
334
-
335
- // Note: RxJS subscriptions are automatically cleaned up via takeUntil(this.disconnecting)
336
- // No manual removeEventListener calls needed for RxJS-managed events
337
- }
241
+ // `disconnectedCallback`, `resetToDefault`, `shouldShowValidation`, and
242
+ // `validateInput` are gone — the mixin's `willUpdate` runs `checkValidity()`
243
+ // at the right moments (Phase 2/3/4 of the validation contract) and
244
+ // `formResetCallback` `resetForm()` handles reset.
338
245
 
339
246
  /**
340
- * Reset the input to its default state
247
+ * Check validity. Folds in the inner native input's structured
248
+ * `ValidityState` flags (`typeMismatch`, `patternMismatch`, `tooShort`,
249
+ * `tooLong`, `rangeUnderflow`, `rangeOverflow`, `stepMismatch`, `badInput`)
250
+ * via `internals.setValidity` so consumers can target specific flags via
251
+ * `field.validity.<flag>` and `:state(value-missing|type-mismatch|…)`.
252
+ *
253
+ * The visual `error` flag is still gated by the mixin's `_shouldShowError()`.
341
254
  */
342
- private resetToDefault() {
343
- this.value = this.defaultValue
344
- this.touched = false
345
- this.dirty = false
346
- this.submitted = false
347
- this.error = false
348
- this.validationMessage = ''
349
- this.dispatchEvent(new CustomEvent('reset', { bubbles: true }))
350
- }
351
-
352
255
  /**
353
- * Determines if validation errors should be shown based on current state
354
- * and validation strategy
256
+ * Re-run checkValidity AFTER render so the native inner input's `.value`
257
+ * binding has propagated. The mixin's willUpdate fires checkValidity too
258
+ * early — at that point native.validity still reflects the previous value.
355
259
  */
356
- private shouldShowValidation(forceValidation = false): boolean {
357
- if (forceValidation) return true
358
-
359
- switch (this.validateOn) {
360
- case 'always':
361
- return true
362
- case 'touched':
363
- return this.touched
364
- case 'dirty':
365
- return this.dirty
366
- case 'submitted':
367
- return this.submitted
368
- default:
369
- return this.touched
260
+ protected override updated(changedProps: Map<PropertyKey, unknown>) {
261
+ super.updated?.(changedProps)
262
+ if (
263
+ changedProps.has('value') ||
264
+ changedProps.has('required') ||
265
+ changedProps.has('type') ||
266
+ changedProps.has('pattern') ||
267
+ changedProps.has('min') ||
268
+ changedProps.has('max') ||
269
+ changedProps.has('minlength') ||
270
+ changedProps.has('maxlength')
271
+ ) {
272
+ this.checkValidity()
370
273
  }
371
274
  }
372
275
 
373
-
374
276
  /**
375
- * Validate input based on required, pattern, etc.
376
- * This mimics native validation behavior
277
+ * Pick the first matching `errorMessages` override for the failing flags.
278
+ * Order matches the natural priority of validity flags (valueMissing
279
+ * before more specific ones — empty trumps malformed).
377
280
  */
378
- private validateInput(forceValidation = false) {
379
- // Skip validation for disabled inputs
380
- if (this.disabled) return
381
-
382
- // Only show validation errors if we should based on the validation strategy
383
- const shouldValidate = this.shouldShowValidation(forceValidation)
384
-
385
- // Get validity state from internal input if available
386
- const validity: ValidityState = this.inputElement?.validity ?? {
387
- badInput: false,
388
- customError: false,
389
- patternMismatch: false,
390
- rangeOverflow: false,
391
- rangeUnderflow: false,
392
- stepMismatch: false,
393
- tooLong: false,
394
- tooShort: false,
395
- typeMismatch: false,
396
- valid: true,
397
- valueMissing: false,
398
- }
399
-
400
- // Check if the input has an actual validation error (not a custom error)
401
- const hasError = !validity.valid && !validity.customError
402
-
403
- if (shouldValidate && hasError) {
404
- // There's an error and we should show it
405
- this.error = true
406
- this.validationMessage = this.inputElement?.validationMessage || ''
407
- } else if (validity.valid) {
408
- // Input is valid, so clear the error state
409
- this.error = false
410
-
411
- // Only clear validation message if there's no custom error
412
- if (!validity.customError) {
413
- this.validationMessage = ''
414
- }
415
- } else if (!shouldValidate) {
416
- // We shouldn't show validation yet, so clear visual error state
417
- this.error = false
418
- }
419
-
420
- // The mixin will handle updating internals based on error state
281
+ private _firstMatchingErrorMessage(v: ValidityState): string | undefined {
282
+ const m = this.errorMessages
283
+ if (!m) return undefined
284
+ if (v.valueMissing && m.valueMissing) return m.valueMissing
285
+ if (v.typeMismatch && m.typeMismatch) return m.typeMismatch
286
+ if (v.patternMismatch && m.patternMismatch) return m.patternMismatch
287
+ if (v.tooShort && m.tooShort) return m.tooShort
288
+ if (v.tooLong && m.tooLong) return m.tooLong
289
+ if (v.rangeUnderflow && m.rangeUnderflow) return m.rangeUnderflow
290
+ if (v.rangeOverflow && m.rangeOverflow) return m.rangeOverflow
291
+ if (v.stepMismatch && m.stepMismatch) return m.stepMismatch
292
+ if (v.badInput && m.badInput) return m.badInput
293
+ return undefined
421
294
  }
422
295
 
423
- /**
424
- * Check validity without showing validation UI
425
- */
426
296
  public override checkValidity() {
427
- // Check internal input first
428
- const inputValid = this.inputRef.value?.checkValidity() ?? true
297
+ // Prefer @query (always live) over @ref (may lag during initial paint).
298
+ const native = this.inputElement ?? this.inputRef.value
299
+ const v = native?.validity
300
+ if (v && !v.valid) {
301
+ // Surface the native flags. valueMissing also surfaces here when
302
+ // `required` + empty — overrides the mixin's coarse check.
303
+ const flags: ValidityStateFlags = {
304
+ valueMissing: v.valueMissing || undefined,
305
+ typeMismatch: v.typeMismatch || undefined,
306
+ patternMismatch: v.patternMismatch || undefined,
307
+ tooShort: v.tooShort || undefined,
308
+ tooLong: v.tooLong || undefined,
309
+ rangeUnderflow: v.rangeUnderflow || undefined,
310
+ rangeOverflow: v.rangeOverflow || undefined,
311
+ stepMismatch: v.stepMismatch || undefined,
312
+ badInput: v.badInput || undefined,
313
+ customError: v.customError || undefined,
314
+ }
315
+ // errorMessages override: pick the first matching flag and use the
316
+ // consumer-provided copy. Falls back to the native browser message.
317
+ const overrideMessage = this._firstMatchingErrorMessage(v)
318
+ this.internals?.setValidity(
319
+ flags,
320
+ overrideMessage || native.validationMessage || this.validationMessage || 'Invalid value',
321
+ )
322
+ if (this._shouldShowError()) {
323
+ this.error = true
324
+ // Always reflect the current flag's message — previous
325
+ // validationMessage may be stale (different flag).
326
+ const newMessage = overrideMessage || native.validationMessage
327
+ if (newMessage) this.validationMessage = newMessage
328
+ // Mirror flags into :state() so CSS can target specifics.
329
+ for (const flag of [
330
+ 'value-missing',
331
+ 'type-mismatch',
332
+ 'pattern-mismatch',
333
+ 'too-short',
334
+ 'too-long',
335
+ 'range-underflow',
336
+ 'range-overflow',
337
+ 'step-mismatch',
338
+ 'bad-input',
339
+ ]) {
340
+ this.internals?.states.delete(flag)
341
+ }
342
+ if (v.valueMissing) this.internals?.states.add('value-missing')
343
+ if (v.typeMismatch) this.internals?.states.add('type-mismatch')
344
+ if (v.patternMismatch) this.internals?.states.add('pattern-mismatch')
345
+ if (v.tooShort) this.internals?.states.add('too-short')
346
+ if (v.tooLong) this.internals?.states.add('too-long')
347
+ if (v.rangeUnderflow) this.internals?.states.add('range-underflow')
348
+ if (v.rangeOverflow) this.internals?.states.add('range-overflow')
349
+ if (v.stepMismatch) this.internals?.states.add('step-mismatch')
350
+ if (v.badInput) this.internals?.states.add('bad-input')
351
+ }
352
+ return false
353
+ }
429
354
 
430
- // Call parent implementation for basic validation
355
+ // Native says valid but the mixin's `required` check might still
356
+ // fire (mixin checks `value === ''` directly, native may treat empty
357
+ // differently for type=email/url with no value).
431
358
  const parentValid = super.checkValidity()
432
-
433
- return inputValid && parentValid
359
+ if (parentValid) {
360
+ // Clear specific-flag :state() entries.
361
+ for (const flag of [
362
+ 'value-missing',
363
+ 'type-mismatch',
364
+ 'pattern-mismatch',
365
+ 'too-short',
366
+ 'too-long',
367
+ 'range-underflow',
368
+ 'range-overflow',
369
+ 'step-mismatch',
370
+ 'bad-input',
371
+ ]) {
372
+ this.internals?.states.delete(flag)
373
+ }
374
+ }
375
+ return parentValid
434
376
  }
435
377
 
436
378
  /**
437
- * Show validation UI and check validity
379
+ * Show validation UI and check validity.
380
+ * Marks the field as submitted so the mixin's gate flips to "always show."
438
381
  */
439
382
  public override reportValidity() {
440
- // Mark as touched and submitted to show validation
441
- this.touched = true
442
- this.submitted = true
443
-
444
- // First check using native input
383
+ this.markSubmitted()
445
384
  const inputValid = this.inputRef.value?.reportValidity() ?? true
446
-
447
- // Update our component's validation state with force=true
448
- this.validateInput(true)
449
-
450
- // Call parent implementation
451
385
  const parentValid = super.reportValidity()
452
-
453
386
  return inputValid && parentValid
454
387
  }
455
388
 
456
- /**
457
- * Set a custom validation error message
458
- */
389
+ /** Set a custom validation error on both the inner input and the mixin. */
459
390
  public override setCustomValidity(message: string) {
460
- // Set on the native input
461
391
  if (this.inputRef.value) {
462
392
  this.inputRef.value.setCustomValidity(message)
463
393
  }
464
-
465
- // Call parent implementation
466
394
  super.setCustomValidity(message)
467
-
468
- // Update error state based on validation strategy
469
- this.error = message !== '' && this.shouldShowValidation()
470
395
  }
471
396
 
472
397
  // ----------------------------
@@ -475,10 +400,10 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
475
400
  firstUpdated() {
476
401
  // Autofocus if desired
477
402
  if (this.autofocus) {
478
- // Use setTimeout to match browser behavior - autofocus happens after initial rendering
479
- setTimeout(() => {
480
- this.focus()
481
- }, 0)
403
+ // Schedule focus after initial render RxJS timer for cancel-on-disconnect.
404
+ timer(0)
405
+ .pipe(takeUntil(this.disconnecting))
406
+ .subscribe(() => this.focus())
482
407
  }
483
408
 
484
409
  // Subscribe to input events
@@ -515,8 +440,7 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
515
440
  // Update component value
516
441
  this.value = eventData.value
517
442
 
518
- // Mark as dirty when user types
519
- this.dirty = this.value !== this.defaultValue
443
+ // `dirty` is a getter on the mixin (value vs _defaultValue) — no manual set.
520
444
 
521
445
  // Fire custom 'input' event with extended details
522
446
  const customEvent = new CustomEvent<EventDetails>('input', {
@@ -534,8 +458,8 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
534
458
 
535
459
  this.dispatchEvent(customEvent)
536
460
 
537
- // Run validation like native inputs do on input, but respect the validation strategy
538
- this.validateInput()
461
+ // Mixin's willUpdate runs checkValidity() on value-change when
462
+ // _shouldShowError() is true — no manual validateInput() call.
539
463
  })
540
464
 
541
465
  // Subscribe to native change events (usually on blur)
@@ -551,13 +475,8 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
551
475
  )
552
476
  .subscribe(value => {
553
477
  this.value = value
554
- this.dirty = this.value !== this.defaultValue
555
-
556
- // Fire regular change event using mixin helper
557
478
  this.emitChange({ value })
558
-
559
- // Run validation on change like native inputs
560
- this.validateInput()
479
+ // Validation runs automatically via mixin's willUpdate.
561
480
  })
562
481
  }
563
482
 
@@ -586,13 +505,9 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
586
505
  fromEvent<FocusEvent>(this.inputElement, 'blur')
587
506
  .pipe(takeUntil(this.disconnecting))
588
507
  .subscribe(ev => {
589
- // Mark as touched when field loses focus
590
- this.touched = true
591
-
592
- // Run validation on blur like native inputs, respecting validation strategy
593
- if (!this.disabled) {
594
- this.validateInput()
595
- }
508
+ // Mark as touched on blur mixin's willUpdate handles the rest
509
+ // (validates if dirty, broadcasts :state(touched), etc.).
510
+ this.markTouched()
596
511
 
597
512
  // Create a custom blur event that includes standard props
598
513
  const blurEvent = new CustomEvent('blur', {
@@ -624,7 +539,7 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
624
539
  const { value } = ev.target as HTMLInputElement
625
540
  this.value = value
626
541
  this.isAutofilled = true
627
- this.dirty = this.value !== this.defaultValue
542
+ // `dirty` is a getter on the mixin — recomputes from value vs _defaultValue.
628
543
 
629
544
  // Dispatch autofill event for integration with autofill systems
630
545
  this.dispatchEvent(
@@ -663,10 +578,9 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
663
578
  .subscribe(ev => {
664
579
  const { value } = ev.target as HTMLInputElement
665
580
 
666
- // Update value if changed
581
+ // Update value if changed (mixin recomputes dirty automatically)
667
582
  if (this.value !== value) {
668
583
  this.value = value
669
- this.dirty = this.value !== this.defaultValue
670
584
  }
671
585
 
672
586
  // Blur the input to trigger change event naturally
@@ -927,6 +841,7 @@ export default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {
927
841
  <div
928
842
  id="hint-${this.id}"
929
843
  class="mt-1 text-sm ${this.error ? 'text-error-default' : 'text-surface-onVariant'}"
844
+ role=${ifDefined(this.error ? 'alert' : undefined)}
930
845
  >
931
846
  ${this.error && this.validationMessage ? this.validationMessage : this.hint}
932
847
  </div>
@@ -1,7 +1,7 @@
1
1
  import { SchmancyElement } from '@mixins/index'
2
2
  import { html } from 'lit'
3
3
  import { customElement, property } from 'lit/decorators.js'
4
- import { FormFieldMixin } from '../../mixins/formField.mixin'
4
+ import { FormFieldMixin } from '@mixins/formField.mixin'
5
5
  import { fromEvent, takeUntil } from 'rxjs'
6
6
 
7
7
  /**
@@ -4,7 +4,7 @@ import { Subject, fromEvent, takeUntil } from 'rxjs'
4
4
  import style from './radio-group.scss?inline'
5
5
  import { SchmancyElement } from '@mixins/index'
6
6
  import { when } from 'lit/directives/when.js'
7
- import { FormFieldMixin } from '../../mixins/formField.mixin'
7
+ import { FormFieldMixin } from '@mixins/formField.mixin'
8
8
 
9
9
  export type SchmancyRadioGroupOption = {
10
10
  label: string
@@ -0,0 +1,90 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2
+ import './range'
3
+ import { expectNoA11yViolations } from '../../../test-utils/a11y'
4
+
5
+ const nextUpdate = () => new Promise(r => requestAnimationFrame(() => r(null)))
6
+
7
+ describe('schmancy-range', () => {
8
+ let host: HTMLDivElement
9
+
10
+ beforeEach(() => {
11
+ host = document.createElement('div')
12
+ document.body.appendChild(host)
13
+ })
14
+
15
+ afterEach(() => {
16
+ host.remove()
17
+ })
18
+
19
+ it('is form-associated and contributes its value to FormData', async () => {
20
+ host.innerHTML = `
21
+ <form>
22
+ <schmancy-range name="volume" min="0" max="100" value="42"></schmancy-range>
23
+ </form>
24
+ `
25
+ const form = host.querySelector('form') as HTMLFormElement
26
+ await nextUpdate()
27
+ await nextUpdate()
28
+ expect(new FormData(form).get('volume')).toBe('42')
29
+ })
30
+
31
+ it('reports value as number on the property', async () => {
32
+ host.innerHTML = `<schmancy-range value="0.5" min="0" max="1" step="0.01"></schmancy-range>`
33
+ const r = host.querySelector('schmancy-range') as HTMLElement & { value: number }
34
+ await nextUpdate()
35
+ expect(r.value).toBe(0.5)
36
+ expect(typeof r.value).toBe('number')
37
+ })
38
+
39
+ it('fires change with numeric detail on input', async () => {
40
+ host.innerHTML = `<schmancy-range min="0" max="10" step="1" value="3"></schmancy-range>`
41
+ const r = host.querySelector('schmancy-range') as HTMLElement & {
42
+ updateComplete: Promise<boolean>
43
+ }
44
+ await r.updateComplete
45
+ let detail: { value: number } | undefined
46
+ r.addEventListener('change', (e: Event) => {
47
+ detail = (e as CustomEvent).detail
48
+ })
49
+ const input = r.shadowRoot!.querySelector('input[type=range]') as HTMLInputElement
50
+ input.value = '7'
51
+ input.dispatchEvent(new Event('input', { bubbles: true }))
52
+ await nextUpdate()
53
+ expect(detail).toEqual({ value: 7 })
54
+ })
55
+
56
+ it('respects disabled attribute on inner input', async () => {
57
+ host.innerHTML = `<schmancy-range disabled value="5"></schmancy-range>`
58
+ const r = host.querySelector('schmancy-range') as HTMLElement & {
59
+ updateComplete: Promise<boolean>
60
+ }
61
+ await r.updateComplete
62
+ const input = r.shadowRoot!.querySelector('input[type=range]') as HTMLInputElement
63
+ expect(input.disabled).toBe(true)
64
+ })
65
+
66
+ it('has no axe-core a11y violations', async () => {
67
+ host.innerHTML = `<schmancy-range label="Volume" min="0" max="100" value="42"></schmancy-range>`
68
+ const r = host.querySelector('schmancy-range') as HTMLElement & { updateComplete: Promise<boolean> }
69
+ await r.updateComplete
70
+ await expectNoA11yViolations(host)
71
+ })
72
+
73
+ it('resets to default value on form reset', async () => {
74
+ host.innerHTML = `
75
+ <form>
76
+ <schmancy-range name="x" value="5" min="0" max="10"></schmancy-range>
77
+ </form>
78
+ `
79
+ const form = host.querySelector('form') as HTMLFormElement
80
+ const r = host.querySelector('schmancy-range') as HTMLElement & { value: number }
81
+ await nextUpdate()
82
+ await nextUpdate()
83
+ r.value = 8
84
+ await nextUpdate()
85
+ form.reset()
86
+ await nextUpdate()
87
+ await nextUpdate()
88
+ expect(r.value).toBe(5)
89
+ })
90
+ })