@mhmo91/schmancy 0.10.15 → 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.
- package/custom-elements.json +2554 -3086
- package/dist/active-host-BP0zy_Y9.js +63 -0
- package/dist/{active-host-CvNYoprt.js.map → active-host-BP0zy_Y9.js.map} +1 -1
- package/dist/active-host-jH3iloCR.cjs +1 -0
- package/dist/{active-host-CcIa2tmW.cjs.map → active-host-jH3iloCR.cjs.map} +1 -1
- package/dist/agent/schmancy.agent.js +2579 -2385
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/agent/schmancy.manifest.json +971 -1189
- package/dist/{animation-CO_Csq84.cjs.map → animation-CCOIW4wJ.cjs.map} +1 -1
- package/dist/{animation-BK-8BwY8.js.map → animation-DCznELuT.js.map} +1 -1
- package/dist/{area-C_kgZZhN.js → area-ChxsDTu_.js} +2 -2
- package/dist/{area-C_kgZZhN.js.map → area-ChxsDTu_.js.map} +1 -1
- package/dist/{area-DFPtKzWy.cjs → area-Qt6yUnuA.cjs} +3 -3
- package/dist/{area-DFPtKzWy.cjs.map → area-Qt6yUnuA.cjs.map} +1 -1
- package/dist/area.cjs +1 -1
- package/dist/area.js +2 -2
- package/dist/{audio-CluX8Qpq.cjs → audio-D-TZzpXF.cjs} +1 -1
- package/dist/{audio-CluX8Qpq.cjs.map → audio-D-TZzpXF.cjs.map} +1 -1
- package/dist/{audio-DcXphulJ.js → audio-DS43uoRA.js} +1 -1
- package/dist/{audio-DcXphulJ.js.map → audio-DS43uoRA.js.map} +1 -1
- package/dist/audio.cjs +1 -1
- package/dist/audio.js +2 -2
- package/dist/{autocomplete-DWSuwSRS.js → autocomplete-CXvUjMD-.js} +46 -71
- package/dist/autocomplete-CXvUjMD-.js.map +1 -0
- package/dist/autocomplete-Ck2zbdF9.cjs +115 -0
- package/dist/autocomplete-Ck2zbdF9.cjs.map +1 -0
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +2 -2
- package/dist/avatar.cjs.map +1 -1
- package/dist/avatar.js +3 -3
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/{boat-CZma2ojF.js → boat-Bj0wVcZi.js} +5 -5
- package/dist/{boat-CZma2ojF.js.map → boat-Bj0wVcZi.js.map} +1 -1
- package/dist/{boat-Dy6cc3hB.cjs → boat-DpFkILFF.cjs} +2 -2
- package/dist/{boat-Dy6cc3hB.cjs.map → boat-DpFkILFF.cjs.map} +1 -1
- package/dist/boat.cjs +1 -1
- package/dist/boat.js +1 -1
- package/dist/breadcrumb.cjs +3 -3
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.js +2 -2
- package/dist/{busy-DCsqryvq.cjs → busy-CtcnclA3.cjs} +3 -3
- package/dist/{busy-DCsqryvq.cjs.map → busy-CtcnclA3.cjs.map} +1 -1
- package/dist/{busy-DeV2ByMw.js → busy-CyZSBnZP.js} +2 -2
- package/dist/{busy-DeV2ByMw.js.map → busy-CyZSBnZP.js.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/button.cjs +4 -4
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +19 -4
- package/dist/button.js.map +1 -1
- package/dist/{card--GgSX4X5.cjs → card-Cl6jp1yX.cjs} +5 -5
- package/dist/{card--GgSX4X5.cjs.map → card-Cl6jp1yX.cjs.map} +1 -1
- package/dist/{card-BTTsHzJJ.js → card-nYZCKmOO.js} +3 -3
- package/dist/{card-BTTsHzJJ.js.map → card-nYZCKmOO.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-NNReP9s_.cjs → checkbox-BeNo0ZGt.cjs} +4 -4
- package/dist/{checkbox-Cj5j-ppk.js.map → checkbox-BeNo0ZGt.cjs.map} +1 -1
- package/dist/{checkbox-Cj5j-ppk.js → checkbox-DiUrZiyc.js} +17 -30
- package/dist/checkbox-DiUrZiyc.js.map +1 -0
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-CP-CbfoZ.js → chips-CfPFXv7Z.js} +5 -5
- package/dist/{chips-CP-CbfoZ.js.map → chips-CfPFXv7Z.js.map} +1 -1
- package/dist/{chips-iporOXxK.cjs → chips-DK6m-VCM.cjs} +5 -5
- package/dist/{chips-iporOXxK.cjs.map → chips-DK6m-VCM.cjs.map} +1 -1
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +2 -2
- package/dist/connectivity.cjs.map +1 -1
- package/dist/connectivity.js +3 -3
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/{context-DJTJnSK4.js.map → context-6oXCZmZN.js.map} +1 -1
- package/dist/{context-BpCETidA.cjs.map → context-CRZeiCqq.cjs.map} +1 -1
- package/dist/{cursor-glow-Bulq-38P.cjs → cursor-glow-C8LgCxpI.cjs} +1 -1
- package/dist/{cursor-glow-Bulq-38P.cjs.map → cursor-glow-C8LgCxpI.cjs.map} +1 -1
- package/dist/{cursor-glow-Ah7VXSj7.js → cursor-glow-Cs2XLDB9.js} +1 -1
- package/dist/{cursor-glow-Ah7VXSj7.js.map → cursor-glow-Cs2XLDB9.js.map} +1 -1
- package/dist/date-range-DA6anfcF.cjs +131 -0
- package/dist/date-range-DA6anfcF.cjs.map +1 -0
- package/dist/{date-range-CgNujP8r.js → date-range-DjlF2u7o.js} +124 -89
- package/dist/date-range-DjlF2u7o.js.map +1 -0
- package/dist/date-range-inline-BfYK795W.cjs +43 -0
- package/dist/{date-range-inline-D4IjOOO0.cjs.map → date-range-inline-BfYK795W.cjs.map} +1 -1
- package/dist/{date-range-inline-C2PXX_GY.js → date-range-inline-n7y_H6PJ.js} +2 -2
- package/dist/{date-range-inline-C2PXX_GY.js.map → date-range-inline-n7y_H6PJ.js.map} +1 -1
- package/dist/date-range-inline.cjs +1 -1
- package/dist/date-range-inline.js +1 -1
- package/dist/date-range.cjs +1 -1
- package/dist/date-range.js +1 -1
- package/dist/delay.cjs +2 -2
- package/dist/delay.cjs.map +1 -1
- package/dist/delay.js +3 -3
- package/dist/{details-DT2b3xOn.cjs → details-BdAVsLl-.cjs} +2 -2
- package/dist/{details-DT2b3xOn.cjs.map → details-BdAVsLl-.cjs.map} +1 -1
- package/dist/{details-VjaNwtfd.js → details-CS_ToAOj.js} +6 -6
- package/dist/{details-VjaNwtfd.js.map → details-CS_ToAOj.js.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/directives.cjs +1 -1
- package/dist/directives.js +5 -5
- package/dist/{divider-BMO8pzEO.js → divider-COLK0RbT.js} +2 -2
- package/dist/{divider-BMO8pzEO.js.map → divider-COLK0RbT.js.map} +1 -1
- package/dist/{divider-BW33TZ-X.cjs → divider-CvWAnvdO.cjs} +2 -2
- package/dist/{divider-BW33TZ-X.cjs.map → divider-CvWAnvdO.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/dropdown.cjs +3 -3
- package/dist/dropdown.cjs.map +1 -1
- package/dist/dropdown.js +2 -2
- package/dist/{expand-DbELKKOt.js → expand-D9LzmpoV.js} +5 -5
- package/dist/{expand-DbELKKOt.js.map → expand-D9LzmpoV.js.map} +1 -1
- package/dist/{expand-_f5EUKWB.cjs → expand-r2sATPUJ.cjs} +3 -3
- package/dist/{expand-_f5EUKWB.cjs.map → expand-r2sATPUJ.cjs.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/float-2nHYuBx-.cjs +1 -0
- package/dist/{float-CKmd-0-t.cjs.map → float-2nHYuBx-.cjs.map} +1 -1
- package/dist/{float-B6RBb2dN.js → float-BWy39CXr.js} +2 -2
- package/dist/{float-B6RBb2dN.js.map → float-BWy39CXr.js.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/form-DhjedCWm.js +258 -0
- package/dist/form-DhjedCWm.js.map +1 -0
- package/dist/form-g5c70rac.cjs +42 -0
- package/dist/form-g5c70rac.cjs.map +1 -0
- package/dist/form.cjs +1 -1
- package/dist/form.js +2 -2
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{hashContent-Bobsobip.cjs.map → hashContent-Ck6laKlk.cjs.map} +1 -1
- package/dist/{hashContent-BU6jl5ih.js.map → hashContent-dJrI-9sc.js.map} +1 -1
- package/dist/{icons-r-S17M8U.cjs → icons-1HIENBco.cjs} +2 -2
- package/dist/{icons-r-S17M8U.cjs.map → icons-1HIENBco.cjs.map} +1 -1
- package/dist/{icons-CoDo95Cu.js → icons-3y0kr1aB.js} +3 -3
- package/dist/{icons-CoDo95Cu.js.map → icons-3y0kr1aB.js.map} +1 -1
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-P9c_qg1-.cjs → iframe-CjqYuZG5.cjs} +2 -2
- package/dist/{iframe-P9c_qg1-.cjs.map → iframe-CjqYuZG5.cjs.map} +1 -1
- package/dist/{iframe-k4oI-TIj.js → iframe-Z5gTK-gd.js} +2 -2
- package/dist/{iframe-k4oI-TIj.js.map → iframe-Z5gTK-gd.js.map} +1 -1
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +60 -60
- package/dist/{input-D95GjINh.js → input-B-fw6f_r.js} +103 -104
- package/dist/input-B-fw6f_r.js.map +1 -0
- package/dist/input-BtcIhu0Q.cjs +52 -0
- package/dist/input-BtcIhu0Q.cjs.map +1 -0
- package/dist/{input-chip-DpC_XEKN.js → input-chip-CtQ0pH5b.js} +2 -2
- package/dist/{input-chip-DpC_XEKN.js.map → input-chip-CtQ0pH5b.js.map} +1 -1
- package/dist/{input-chip-D0ZXqTt5.cjs → input-chip-DZktYohr.cjs} +2 -2
- package/dist/{input-chip-D0ZXqTt5.cjs.map → input-chip-DZktYohr.cjs.map} +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/json.cjs +2 -2
- package/dist/json.cjs.map +1 -1
- package/dist/json.js +3 -3
- package/dist/kbd.cjs +2 -2
- package/dist/kbd.cjs.map +1 -1
- package/dist/kbd.js +2 -2
- package/dist/{layout-CXPNsUIo.js → layout-BH28sKGc.js} +1 -1
- package/dist/{layout-CXPNsUIo.js.map → layout-BH28sKGc.js.map} +1 -1
- package/dist/{layout-Zhe7wSZ_.cjs → layout-Delq-QvR.cjs} +1 -1
- package/dist/{layout-Zhe7wSZ_.cjs.map → layout-Delq-QvR.cjs.map} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +1 -1
- package/dist/{lazy-Dq9mRRjT.cjs.map → lazy-CayEFyC3.cjs.map} +1 -1
- package/dist/{lazy-B0ia54tT.js.map → lazy-D-bO2r4m.js.map} +1 -1
- package/dist/{lightbox-C-yHeoK0.cjs → lightbox-BHTZOn8K.cjs} +3 -3
- package/dist/{lightbox-C-yHeoK0.cjs.map → lightbox-BHTZOn8K.cjs.map} +1 -1
- package/dist/{lightbox-CovQtmyn.js → lightbox-BL3LWp-P.js} +9 -9
- package/dist/{lightbox-CovQtmyn.js.map → lightbox-BL3LWp-P.js.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-CAijuky4.cjs → list-CHYa5VGY.cjs} +3 -3
- package/dist/{list-CAijuky4.cjs.map → list-CHYa5VGY.cjs.map} +1 -1
- package/dist/{list-C1pR9vhu.js → list-DLJL1JQj.js} +2 -2
- package/dist/{list-C1pR9vhu.js.map → list-DLJL1JQj.js.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{magnetic-BJgB1dVi.cjs → magnetic-Bgh7aHHI.cjs} +1 -1
- package/dist/{magnetic-BJgB1dVi.cjs.map → magnetic-Bgh7aHHI.cjs.map} +1 -1
- package/dist/{magnetic-YwCNvtbB.js → magnetic-DxvoEz8_.js} +2 -2
- package/dist/{magnetic-YwCNvtbB.js.map → magnetic-DxvoEz8_.js.map} +1 -1
- package/dist/{menu-B59vZv9n.js → menu-BNq93w6X.js} +3 -3
- package/dist/{menu-B59vZv9n.js.map → menu-BNq93w6X.js.map} +1 -1
- package/dist/{menu-BaHO3Cip.cjs → menu-DAikvkeV.cjs} +3 -3
- package/dist/{menu-BaHO3Cip.cjs.map → menu-DAikvkeV.cjs.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/mixins-BOOu6q2n.cjs +298 -0
- package/dist/mixins-BOOu6q2n.cjs.map +1 -0
- package/dist/mixins-BWb9_e1s.js +680 -0
- package/dist/mixins-BWb9_e1s.js.map +1 -0
- package/dist/mixins.cjs +1 -1
- package/dist/mixins.js +2 -2
- package/dist/nav-drawer.cjs +1 -1
- package/dist/nav-drawer.js +1 -1
- package/dist/navigation-bar.cjs +1 -1
- package/dist/navigation-bar.js +1 -1
- package/dist/navigation-rail.cjs +3 -3
- package/dist/navigation-rail.cjs.map +1 -1
- package/dist/navigation-rail.js +2 -2
- package/dist/{notification-BeLoVa47.js → notification-CUmb9c3Y.js} +4 -4
- package/dist/{notification-BeLoVa47.js.map → notification-CUmb9c3Y.js.map} +1 -1
- package/dist/notification-Dy2azMyt.cjs +23 -0
- package/dist/{notification-BC9nG8Sr.cjs.map → notification-Dy2azMyt.cjs.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-BWF4GBp-.cjs → option-CDgIKifG.cjs} +2 -2
- package/dist/{option-BWF4GBp-.cjs.map → option-CDgIKifG.cjs.map} +1 -1
- package/dist/{option-UvlSAcC4.js → option-DFvQ551b.js} +2 -2
- package/dist/{option-UvlSAcC4.js.map → option-DFvQ551b.js.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-stack-DCDS17uj.js.map → overlay-stack-BR4iYivO.js.map} +1 -1
- package/dist/{overlay-stack-DPIe_aYv.cjs.map → overlay-stack-Dk0xETTy.cjs.map} +1 -1
- package/dist/overlay.cjs +2 -2
- package/dist/overlay.cjs.map +1 -1
- package/dist/{overlay.confirm-body-URtE1gI3.cjs → overlay.confirm-body-BkhNvr0c.cjs} +2 -2
- package/dist/{overlay.confirm-body-URtE1gI3.cjs.map → overlay.confirm-body-BkhNvr0c.cjs.map} +1 -1
- package/dist/{overlay.confirm-body-9W0B5QGv.js → overlay.confirm-body-uFp-0Zfh.js} +2 -2
- package/dist/{overlay.confirm-body-9W0B5QGv.js.map → overlay.confirm-body-uFp-0Zfh.js.map} +1 -1
- package/dist/overlay.js +8 -8
- package/dist/{overlay.service-DnZTcKyJ.cjs → overlay.service-1YWfUD2S.cjs} +1 -1
- package/dist/{overlay.service-DnZTcKyJ.cjs.map → overlay.service-1YWfUD2S.cjs.map} +1 -1
- package/dist/{overlay.service-CVqs2Gu1.js → overlay.service-BcF12kGb.js} +2 -2
- package/dist/{overlay.service-CVqs2Gu1.js.map → overlay.service-BcF12kGb.js.map} +1 -1
- package/dist/page.cjs +2 -2
- package/dist/page.cjs.map +1 -1
- package/dist/page.js +5 -5
- package/dist/{progress-CwzwY8Oe.cjs → progress-C02sWkmE.cjs} +2 -2
- package/dist/{progress-CwzwY8Oe.cjs.map → progress-C02sWkmE.cjs.map} +1 -1
- package/dist/{progress-C29Uw-WJ.js → progress-bLbGRuQ1.js} +2 -2
- package/dist/{progress-C29Uw-WJ.js.map → progress-bLbGRuQ1.js.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/radio-group-BA-jRct5.cjs +40 -0
- package/dist/radio-group-BA-jRct5.cjs.map +1 -0
- package/dist/{radio-group-CW8airhZ.js → radio-group-DA4eIGCj.js} +4 -4
- package/dist/radio-group-DA4eIGCj.js.map +1 -0
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +6 -4
- package/dist/range.cjs.map +1 -1
- package/dist/range.js +19 -15
- package/dist/range.js.map +1 -1
- package/dist/{reduced-motion-D-L12p7G.js.map → reduced-motion-D7LqTUMn.js.map} +1 -1
- package/dist/{reduced-motion-Ds-HjMzn.cjs.map → reduced-motion-Dzfp_w5x.cjs.map} +1 -1
- package/dist/{rxjs-utils-CVeJQ9KG.js.map → rxjs-utils-D9U4MW0Q.js.map} +1 -1
- package/dist/{rxjs-utils-DCUHg_Ml.cjs.map → rxjs-utils-kWPShgKu.cjs.map} +1 -1
- package/dist/rxjs-utils.cjs +1 -1
- package/dist/rxjs-utils.js +1 -1
- package/dist/{scroll-BotoGcMU.js → scroll-CG5up5oy.js} +2 -2
- package/dist/{scroll-BotoGcMU.js.map → scroll-CG5up5oy.js.map} +1 -1
- package/dist/{scroll-CmhmUebp.cjs → scroll-D8vBF_gY.cjs} +2 -2
- package/dist/{scroll-CmhmUebp.cjs.map → scroll-D8vBF_gY.cjs.map} +1 -1
- package/dist/{search-BLCRsxIC.cjs.map → search-DPKoC-dT.cjs.map} +1 -1
- package/dist/{search-BTz7-Rev.js.map → search-MvIBA93K.js.map} +1 -1
- package/dist/{select-Dbn-CImU.js → select-BrK1BJoU.js} +52 -73
- package/dist/select-BrK1BJoU.js.map +1 -0
- package/dist/select-Dh2j7Qc-.cjs +56 -0
- package/dist/select-Dh2j7Qc-.cjs.map +1 -0
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +2 -2
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.js +2 -2
- package/dist/skills/autocomplete.md +16 -3
- package/dist/skills/button.md +19 -0
- package/dist/skills/checkbox.md +19 -0
- package/dist/skills/date-range.md +19 -0
- package/dist/skills/form-ux-rules.md +55 -0
- package/dist/skills/form.md +121 -25
- package/dist/skills/input.md +19 -4
- package/dist/skills/range.md +15 -1
- package/dist/skills/schmancy/autocomplete.md +16 -3
- package/dist/skills/schmancy/button.md +19 -0
- package/dist/skills/schmancy/checkbox.md +19 -0
- package/dist/skills/schmancy/date-range.md +19 -0
- package/dist/skills/schmancy/form-ux-rules.md +55 -0
- package/dist/skills/schmancy/form.md +121 -25
- package/dist/skills/schmancy/input.md +19 -4
- package/dist/skills/schmancy/range.md +15 -1
- package/dist/skills/schmancy/select.md +13 -1
- package/dist/skills/schmancy/switch.md +21 -2
- package/dist/skills/schmancy/textarea.md +13 -0
- package/dist/skills/select.md +13 -1
- package/dist/skills/switch.md +21 -2
- package/dist/skills/textarea.md +13 -0
- package/dist/slider.cjs +3 -3
- package/dist/slider.cjs.map +1 -1
- package/dist/slider.js +2 -2
- package/dist/{sound.service-kKfsN0m-.js → sound.service-BIN2W7Rv.js} +1 -1
- package/dist/{sound.service-kKfsN0m-.js.map → sound.service-BIN2W7Rv.js.map} +1 -1
- package/dist/{sound.service-BGs6m0Cm.cjs → sound.service-DyY78ukR.cjs} +1 -1
- package/dist/{sound.service-BGs6m0Cm.cjs.map → sound.service-DyY78ukR.cjs.map} +1 -1
- package/dist/{splash-screen-DtkjCJYo.js → splash-screen-BcjjJSlK.js} +2 -2
- package/dist/{splash-screen-DtkjCJYo.js.map → splash-screen-BcjjJSlK.js.map} +1 -1
- package/dist/{splash-screen-DlQUv-kV.cjs → splash-screen-Kr1sPtME.cjs} +2 -2
- package/dist/{splash-screen-DlQUv-kV.cjs.map → splash-screen-Kr1sPtME.cjs.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-DEUjlTsX.cjs → src-B2-CU8fu.cjs} +11 -11
- package/dist/{src-DEUjlTsX.cjs.map → src-B2-CU8fu.cjs.map} +1 -1
- package/dist/{src-D6e0adHi.js → src-DvywUq7l.js} +38 -38
- package/dist/{src-D6e0adHi.js.map → src-DvywUq7l.js.map} +1 -1
- package/dist/state-avic94Ft.cjs +1 -0
- package/dist/{state-DNdCPITt.cjs.map → state-avic94Ft.cjs.map} +1 -1
- package/dist/{state-BusMG6sM.js → state-nm8yzMPp.js} +1 -2
- package/dist/{state-BusMG6sM.js.map → state-nm8yzMPp.js.map} +1 -1
- package/dist/state.cjs +1 -1
- package/dist/state.js +2 -2
- package/dist/steps.cjs +3 -3
- package/dist/steps.cjs.map +1 -1
- package/dist/steps.js +2 -2
- package/dist/{surface-A82O1kgu.js → surface-BtMMHKol.js} +2 -2
- package/dist/{surface-A82O1kgu.js.map → surface-BtMMHKol.js.map} +1 -1
- package/dist/surface-CgXeKdGL.cjs +7 -0
- package/dist/{surface-BpppoNXN.cjs.map → surface-CgXeKdGL.cjs.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +3 -3
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +27 -43
- package/dist/switch.js.map +1 -1
- package/dist/table.cjs +3 -3
- package/dist/table.cjs.map +1 -1
- package/dist/table.js +2 -2
- package/dist/{tabs-cVHHd1dY.js → tabs-CikPr7by.js} +2 -2
- package/dist/{tabs-cVHHd1dY.js.map → tabs-CikPr7by.js.map} +1 -1
- package/dist/{tabs-TO3UiBsm.cjs → tabs-CitVls3_.cjs} +2 -2
- package/dist/{tabs-TO3UiBsm.cjs.map → tabs-CitVls3_.cjs.map} +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/dist/textarea-CqV1wvmB.cjs +43 -0
- package/dist/textarea-CqV1wvmB.cjs.map +1 -0
- package/dist/textarea-DVkwQSis.js +186 -0
- package/dist/textarea-DVkwQSis.js.map +1 -0
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-CT408FqH.js → theme-BIWS4TOW.js} +9 -9
- package/dist/{theme-CT408FqH.js.map → theme-BIWS4TOW.js.map} +1 -1
- package/dist/theme-DMgjiKda.cjs +181 -0
- package/dist/{theme-CpuF3D3q.cjs.map → theme-DMgjiKda.cjs.map} +1 -1
- package/dist/{theme-button-pTb5-Wxx.js → theme-button-DC_shZ_7.js} +2 -2
- package/dist/{theme-button-pTb5-Wxx.js.map → theme-button-DC_shZ_7.js.map} +1 -1
- package/dist/theme-button-ENKa3TPT.cjs +8 -0
- package/dist/{theme-button-B6Xf-EiH.cjs.map → theme-button-ENKa3TPT.cjs.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/{theme.interface-B9TjbSBF.js.map → theme.interface-C8OHheXg.js.map} +1 -1
- package/dist/{theme.interface-BujperTo.cjs.map → theme.interface-CYo4UpWK.cjs.map} +1 -1
- package/dist/theme.js +4 -4
- package/dist/{theme.service-DIUo1mBP.js → theme.service-BOWIT_5k.js} +1 -1
- package/dist/{theme.service-DIUo1mBP.js.map → theme.service-BOWIT_5k.js.map} +1 -1
- package/dist/{theme.service-Cfk88qHK.cjs → theme.service-DkdH1t60.cjs} +1 -1
- package/dist/{theme.service-Cfk88qHK.cjs.map → theme.service-DkdH1t60.cjs.map} +1 -1
- package/dist/tree.cjs +2 -2
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js +2 -2
- package/dist/typography.cjs +2 -2
- package/dist/typography.cjs.map +1 -1
- package/dist/typography.js +2 -2
- package/dist/{utils-kND2Z9Xg.js → utils-Cj_nRRyx.js} +2 -2
- package/dist/{utils-kND2Z9Xg.js.map → utils-Cj_nRRyx.js.map} +1 -1
- package/dist/{utils-Dt5PpmaQ.cjs → utils-D2QUu4-g.cjs} +1 -1
- package/dist/{utils-Dt5PpmaQ.cjs.map → utils-D2QUu4-g.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +4 -4
- package/dist/visually-hidden.cjs +2 -2
- package/dist/visually-hidden.cjs.map +1 -1
- package/dist/visually-hidden.js +2 -2
- package/dist/{window-CuBcOxbc.js → window-BTecgE_U.js} +7 -7
- package/dist/{window-CuBcOxbc.js.map → window-BTecgE_U.js.map} +1 -1
- package/dist/{window-CSKvv4Ts.cjs → window-DGydMS0g.cjs} +2 -2
- package/dist/{window-CSKvv4Ts.cjs.map → window-DGydMS0g.cjs.map} +1 -1
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/skills/schmancy/autocomplete.md +16 -3
- package/skills/schmancy/button.md +19 -0
- package/skills/schmancy/checkbox.md +19 -0
- package/skills/schmancy/date-range.md +19 -0
- package/skills/schmancy/form-ux-rules.md +55 -0
- package/skills/schmancy/form.md +121 -25
- package/skills/schmancy/input.md +19 -4
- package/skills/schmancy/range.md +15 -1
- package/skills/schmancy/select.md +13 -1
- package/skills/schmancy/switch.md +21 -2
- package/skills/schmancy/textarea.md +13 -0
- package/src/button/button.test.ts +122 -0
- package/src/button/button.ts +36 -0
- package/src/{autocomplete → form/fields/autocomplete}/autocomplete.ts +48 -75
- package/src/{checkbox → form/fields/checkbox}/checkbox.test.ts +1 -1
- package/src/form/fields/checkbox/checkbox.ts +126 -0
- package/src/form/fields/date-range/date-range.test.ts +102 -0
- package/src/{date-range → form/fields/date-range}/date-range.ts +90 -7
- package/src/form/fields/input/input.test.ts +201 -0
- package/src/{input → form/fields/input}/input.ts +153 -238
- package/src/{radio-group → form/fields/radio-group}/radio-button.ts +1 -1
- package/src/{radio-group → form/fields/radio-group}/radio-group.ts +1 -1
- package/src/form/fields/range/range.test.ts +90 -0
- package/src/{range → form/fields/range}/range.ts +34 -13
- package/src/{select → form/fields/select}/select.ts +77 -108
- package/src/{switch → form/fields/switch}/switch.test.ts +1 -1
- package/src/{switch → form/fields/switch}/switch.ts +71 -51
- package/src/form/fields/textarea/textarea.test.ts +54 -0
- package/src/{textarea → form/fields/textarea}/textarea.ts +33 -72
- package/src/form/form-state.ts +31 -0
- package/src/form/form-summary.test.ts +105 -0
- package/src/form/form-summary.ts +171 -0
- package/src/form/form.test.ts +218 -35
- package/src/form/form.ts +330 -99
- package/src/form/index.ts +2 -0
- package/src/index.ts +9 -9
- package/types/mixins/formField.mixin.d.ts +90 -0
- package/types/src/button/button.d.ts +9 -0
- package/types/src/button/button.test.d.ts +3 -0
- package/types/src/{autocomplete → form/fields/autocomplete}/autocomplete.d.ts +6 -15
- package/types/src/form/fields/checkbox/checkbox.d.ts +47 -0
- package/types/src/{date-range → form/fields/date-range}/date-range.d.ts +22 -4
- package/types/src/form/fields/date-range/date-range.test.d.ts +1 -0
- package/types/src/{input → form/fields/input}/input.d.ts +20 -45
- package/types/src/form/fields/input/input.test.d.ts +1 -0
- package/types/src/{radio-group → form/fields/radio-group}/radio-button.d.ts +1 -1
- package/types/src/{radio-group → form/fields/radio-group}/radio-group.d.ts +1 -1
- package/types/src/form/fields/range/range.d.ts +28 -0
- package/types/src/form/fields/range/range.test.d.ts +1 -0
- package/types/src/{select → form/fields/select}/select.d.ts +23 -24
- package/types/src/form/fields/switch/switch.d.ts +57 -0
- package/types/src/{textarea → form/fields/textarea}/textarea.d.ts +6 -39
- package/types/src/form/fields/textarea/textarea.test.d.ts +1 -0
- package/types/src/form/form-state.d.ts +22 -0
- package/types/src/form/form-summary.d.ts +42 -0
- package/types/src/form/form-summary.test.d.ts +4 -0
- package/types/src/form/form.d.ts +79 -34
- package/types/src/form/form.test.d.ts +2 -2
- package/types/src/form/index.d.ts +2 -0
- package/types/src/index.d.ts +9 -9
- package/dist/active-host-CcIa2tmW.cjs +0 -1
- package/dist/active-host-CvNYoprt.js +0 -57
- package/dist/autocomplete-DWSuwSRS.js.map +0 -1
- package/dist/autocomplete-iCJOia-q.cjs +0 -115
- package/dist/autocomplete-iCJOia-q.cjs.map +0 -1
- package/dist/checkbox-NNReP9s_.cjs.map +0 -1
- package/dist/date-range-CaOxwZDq.cjs +0 -131
- package/dist/date-range-CaOxwZDq.cjs.map +0 -1
- package/dist/date-range-CgNujP8r.js.map +0 -1
- package/dist/date-range-inline-D4IjOOO0.cjs +0 -43
- package/dist/decorate-23nYs4Le.js +0 -7
- package/dist/decorate-DpFmy0nm.cjs +0 -1
- package/dist/float-CKmd-0-t.cjs +0 -1
- package/dist/form-CFvwnfuJ.js +0 -68
- package/dist/form-CFvwnfuJ.js.map +0 -1
- package/dist/form-Ceijw1aA.cjs +0 -1
- package/dist/form-Ceijw1aA.cjs.map +0 -1
- package/dist/input-D95GjINh.js.map +0 -1
- package/dist/input-D9s4jDAb.cjs +0 -51
- package/dist/input-D9s4jDAb.cjs.map +0 -1
- package/dist/mixins-BV0w2yIE.js +0 -627
- package/dist/mixins-BV0w2yIE.js.map +0 -1
- package/dist/mixins-DvAYa-F7.cjs +0 -298
- package/dist/mixins-DvAYa-F7.cjs.map +0 -1
- package/dist/notification-BC9nG8Sr.cjs +0 -23
- package/dist/radio-group-ByMD6Lsj.cjs +0 -40
- package/dist/radio-group-ByMD6Lsj.cjs.map +0 -1
- package/dist/radio-group-CW8airhZ.js.map +0 -1
- package/dist/select-BdBThja4.cjs +0 -56
- package/dist/select-BdBThja4.cjs.map +0 -1
- package/dist/select-Dbn-CImU.js.map +0 -1
- package/dist/state-DNdCPITt.cjs +0 -1
- package/dist/surface-BpppoNXN.cjs +0 -7
- package/dist/textarea-B9dy-yec.js +0 -211
- package/dist/textarea-B9dy-yec.js.map +0 -1
- package/dist/textarea-DFY0Flgv.cjs +0 -39
- package/dist/textarea-DFY0Flgv.cjs.map +0 -1
- package/dist/theme-CpuF3D3q.cjs +0 -181
- package/dist/theme-button-B6Xf-EiH.cjs +0 -8
- package/src/checkbox/checkbox.ts +0 -162
- package/types/src/checkbox/checkbox.d.ts +0 -71
- package/types/src/range/range.d.ts +0 -25
- package/types/src/switch/switch.d.ts +0 -53
- /package/dist/{animation-CO_Csq84.cjs → animation-CCOIW4wJ.cjs} +0 -0
- /package/dist/{animation-BK-8BwY8.js → animation-DCznELuT.js} +0 -0
- /package/dist/{context-DJTJnSK4.js → context-6oXCZmZN.js} +0 -0
- /package/dist/{context-BpCETidA.cjs → context-CRZeiCqq.cjs} +0 -0
- /package/dist/{hashContent-Bobsobip.cjs → hashContent-Ck6laKlk.cjs} +0 -0
- /package/dist/{hashContent-BU6jl5ih.js → hashContent-dJrI-9sc.js} +0 -0
- /package/dist/{lazy-Dq9mRRjT.cjs → lazy-CayEFyC3.cjs} +0 -0
- /package/dist/{lazy-B0ia54tT.js → lazy-D-bO2r4m.js} +0 -0
- /package/dist/{overlay-stack-DCDS17uj.js → overlay-stack-BR4iYivO.js} +0 -0
- /package/dist/{overlay-stack-DPIe_aYv.cjs → overlay-stack-Dk0xETTy.cjs} +0 -0
- /package/dist/{reduced-motion-D-L12p7G.js → reduced-motion-D7LqTUMn.js} +0 -0
- /package/dist/{reduced-motion-Ds-HjMzn.cjs → reduced-motion-Dzfp_w5x.cjs} +0 -0
- /package/dist/{rxjs-utils-CVeJQ9KG.js → rxjs-utils-D9U4MW0Q.js} +0 -0
- /package/dist/{rxjs-utils-DCUHg_Ml.cjs → rxjs-utils-kWPShgKu.cjs} +0 -0
- /package/dist/{search-BLCRsxIC.cjs → search-DPKoC-dT.cjs} +0 -0
- /package/dist/{search-BTz7-Rev.js → search-MvIBA93K.js} +0 -0
- /package/dist/{theme.interface-B9TjbSBF.js → theme.interface-C8OHheXg.js} +0 -0
- /package/dist/{theme.interface-BujperTo.cjs → theme.interface-CYo4UpWK.cjs} +0 -0
- /package/src/{autocomplete → form/fields/autocomplete}/autocomplete.scss +0 -0
- /package/src/{autocomplete → form/fields/autocomplete}/index.ts +0 -0
- /package/src/{checkbox → form/fields/checkbox}/index.ts +0 -0
- /package/src/{date-range → form/fields/date-range}/date-range-dialog.ts +0 -0
- /package/src/{date-range → form/fields/date-range}/date-range-helpers.ts +0 -0
- /package/src/{date-range → form/fields/date-range}/date-range-presets.ts +0 -0
- /package/src/{date-range → form/fields/date-range}/date-utils.ts +0 -0
- /package/src/{date-range → form/fields/date-range}/index.ts +0 -0
- /package/src/{input → form/fields/input}/index.ts +0 -0
- /package/src/{input → form/fields/input}/input.scss +0 -0
- /package/src/{radio-group → form/fields/radio-group}/index.ts +0 -0
- /package/src/{radio-group → form/fields/radio-group}/radio-group.scss +0 -0
- /package/src/{range → form/fields/range}/index.ts +0 -0
- /package/src/{select → form/fields/select}/index.ts +0 -0
- /package/src/{switch → form/fields/switch}/index.ts +0 -0
- /package/src/{textarea → form/fields/textarea}/index.ts +0 -0
- /package/src/{textarea → form/fields/textarea}/textarea.scss +0 -0
- /package/types/src/{autocomplete → form/fields/autocomplete}/index.d.ts +0 -0
- /package/types/src/{checkbox → form/fields/checkbox}/checkbox.test.d.ts +0 -0
- /package/types/src/{checkbox → form/fields/checkbox}/index.d.ts +0 -0
- /package/types/src/{date-range → form/fields/date-range}/date-range-dialog.d.ts +0 -0
- /package/types/src/{date-range → form/fields/date-range}/date-range-helpers.d.ts +0 -0
- /package/types/src/{date-range → form/fields/date-range}/date-range-presets.d.ts +0 -0
- /package/types/src/{date-range → form/fields/date-range}/date-utils.d.ts +0 -0
- /package/types/src/{date-range → form/fields/date-range}/index.d.ts +0 -0
- /package/types/src/{input → form/fields/input}/index.d.ts +0 -0
- /package/types/src/{radio-group → form/fields/radio-group}/index.d.ts +0 -0
- /package/types/src/{range → form/fields/range}/index.d.ts +0 -0
- /package/types/src/{select → form/fields/select}/index.d.ts +0 -0
- /package/types/src/{switch → form/fields/switch}/index.d.ts +0 -0
- /package/types/src/{switch → form/fields/switch}/switch.test.d.ts +0 -0
- /package/types/src/{textarea → form/fields/textarea}/index.d.ts +0 -0
package/src/form/form.ts
CHANGED
|
@@ -1,146 +1,377 @@
|
|
|
1
|
-
import { customElement } from 'lit/decorators.js'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
* reparented into a `<form>` element in light DOM on connection, so:
|
|
6
|
-
*
|
|
7
|
-
* - Form-associated custom elements (FACE) resolve their `internals.form`
|
|
8
|
-
* correctly via native DOM ancestry.
|
|
9
|
-
* - `new FormData(form)` collects values from every FACE + native control
|
|
10
|
-
* without any manual walking.
|
|
11
|
-
* - `form.reset()` triggers `formResetCallback()` on every FACE.
|
|
12
|
-
* - `form.reportValidity()` runs native validation UI.
|
|
13
|
-
* - `<button type="submit">` and `<schmancy-button type="submit">` both
|
|
14
|
-
* submit the form via the native submitter pipeline.
|
|
2
|
+
* `<schmancy-form>` — schmancy form owner with isolated submit state.
|
|
15
3
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* - Extends `SchmancyElement` (shadow DOM, RxJS + `disconnecting` conventions).
|
|
6
|
+
* - Renders content inside `<schmancy-context .provides=${[formSubmitState]}>`
|
|
7
|
+
* so each form instance gets an isolated copy of the submit state via the
|
|
8
|
+
* schmancy state library — no `@lit/context` plumbing in user code.
|
|
9
|
+
* - Inner `<form novalidate>` is the native-semantics trigger for Enter-key
|
|
10
|
+
* submit and `type=submit` button activation.
|
|
11
|
+
* - Fields self-register via `FIELD_CONNECT_EVENT` (composed event from
|
|
12
|
+
* `FormFieldMixin.connectedCallback`). Stale refs (from disconnected
|
|
13
|
+
* fields) are filtered by `isConnected` at iteration time.
|
|
19
14
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* @fires reset - Emitted after the underlying form resets.
|
|
15
|
+
* Schema seam — pass any `{ parse(input): T }` object (zod, valibot, ArkType,
|
|
16
|
+
* etc.) via the `schema` property to get typed `submit` event detail.
|
|
23
17
|
*/
|
|
18
|
+
|
|
19
|
+
import { html } from 'lit'
|
|
20
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
21
|
+
import { fromEvent, takeUntil } from 'rxjs'
|
|
22
|
+
import { SchmancyElement } from '../../mixins'
|
|
23
|
+
import { FIELD_CONNECT_EVENT, type IFormFieldMixin } from '../../mixins/formField.mixin'
|
|
24
|
+
import { formSubmitState, type FormSubmitState, type FormError } from './form-state'
|
|
25
|
+
|
|
26
|
+
/** Structural type matching zod, valibot, ArkType, etc. — any schema with `.parse()`. */
|
|
27
|
+
export interface ParseSchema<T = unknown> {
|
|
28
|
+
parse(input: unknown): T
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const isButton = (node: EventTarget): node is HTMLElement => {
|
|
32
|
+
if (!(node instanceof HTMLElement)) return false
|
|
33
|
+
return node.tagName === 'BUTTON' || node.tagName === 'SCHMANCY-BUTTON'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Submit event detail. `data` is typed when `schema` is set. */
|
|
37
|
+
export type SchmancyFormSubmitDetail<T = Record<string, FormDataEntryValue>> = {
|
|
38
|
+
data: T
|
|
39
|
+
formData: FormData
|
|
40
|
+
/**
|
|
41
|
+
* Register a promise that gates the form's success/error state. If unused,
|
|
42
|
+
* the form synchronously flips to `success` after dispatch. If used,
|
|
43
|
+
* `success`/`error` reflect the promise's outcome.
|
|
44
|
+
*/
|
|
45
|
+
until(p: Promise<unknown>): void
|
|
46
|
+
}
|
|
47
|
+
|
|
24
48
|
@customElement('schmancy-form')
|
|
25
|
-
export default class SchmancyForm extends
|
|
49
|
+
export default class SchmancyForm<TSchema extends ParseSchema | undefined = undefined>
|
|
50
|
+
extends SchmancyElement {
|
|
26
51
|
public static readonly tagName: string = 'schmancy-form'
|
|
27
52
|
|
|
28
|
-
|
|
29
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Optional schema for parsing FormData on submit. Anything with a
|
|
55
|
+
* `.parse(input)` method works (zod, valibot, ArkType). When set, the
|
|
56
|
+
* `submit` event's `detail.data` is typed `z.infer<TSchema>`.
|
|
57
|
+
*/
|
|
58
|
+
@property({ attribute: false })
|
|
59
|
+
schema?: TSchema
|
|
30
60
|
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
})()
|
|
61
|
+
/** Skip built-in browser constraint validation. Mirrors `<form novalidate>`. */
|
|
62
|
+
@property({ type: Boolean })
|
|
63
|
+
novalidate: boolean = true
|
|
35
64
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return this.hasAttribute('novalidate')
|
|
39
|
-
}
|
|
40
|
-
set novalidate(value: boolean) {
|
|
41
|
-
if (value) this.setAttribute('novalidate', '')
|
|
42
|
-
else this.removeAttribute('novalidate')
|
|
43
|
-
}
|
|
65
|
+
private _fields = new Set<IFormFieldMixin>()
|
|
66
|
+
private _submitting = false
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Local mirror of the submit-state status — drives the inline live region
|
|
70
|
+
* synchronously. Independent of the schmancy-state library's resolution
|
|
71
|
+
* chain (which has known cross-await fallback semantics) so the AT-facing
|
|
72
|
+
* announcement is always correct for this form instance.
|
|
73
|
+
*/
|
|
74
|
+
@state() private _liveStatus: 'idle' | 'submitting' | 'success' | 'error' = 'idle'
|
|
75
|
+
@state() private _liveError: string = ''
|
|
76
|
+
private _internals: ElementInternals | undefined = (() => {
|
|
77
|
+
try {
|
|
78
|
+
return this.attachInternals()
|
|
79
|
+
} catch {
|
|
80
|
+
return undefined
|
|
81
|
+
}
|
|
82
|
+
})()
|
|
48
83
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
84
|
+
override connectedCallback(): void {
|
|
85
|
+
super.connectedCallback()
|
|
86
|
+
|
|
87
|
+
// Forbid nested <schmancy-form>.
|
|
88
|
+
if (this.parentElement?.closest('schmancy-form')) {
|
|
89
|
+
console.error('[schmancy-form] nested <schmancy-form> is not supported')
|
|
90
|
+
return
|
|
53
91
|
}
|
|
92
|
+
|
|
93
|
+
// Field registry — composed event from FormFieldMixin.connectedCallback.
|
|
94
|
+
fromEvent<CustomEvent<IFormFieldMixin>>(this, FIELD_CONNECT_EVENT)
|
|
95
|
+
.pipe(takeUntil(this.disconnecting))
|
|
96
|
+
.subscribe(e => this._fields.add(e.detail))
|
|
97
|
+
|
|
98
|
+
// Submit-trigger interception — slotted descendants live in light DOM
|
|
99
|
+
// while the inner <form> is in shadow DOM, so native form-association
|
|
100
|
+
// across the shadow boundary doesn't work for `<button type=submit>`.
|
|
101
|
+
// Capture clicks on type=submit buttons (native + schmancy-button) and
|
|
102
|
+
// Enter keys on registered fields, then call the inner form's
|
|
103
|
+
// requestSubmit() which fires the same native submit event handler
|
|
104
|
+
// chain that a directly-associated button would have triggered.
|
|
105
|
+
fromEvent<MouseEvent>(this, 'click')
|
|
106
|
+
.pipe(takeUntil(this.disconnecting))
|
|
107
|
+
.subscribe(e => this._maybeRequestSubmit(e))
|
|
108
|
+
fromEvent<KeyboardEvent>(this, 'keydown')
|
|
109
|
+
.pipe(takeUntil(this.disconnecting))
|
|
110
|
+
.subscribe(e => {
|
|
111
|
+
if (e.key !== 'Enter' || e.shiftKey) return
|
|
112
|
+
// Skip Enter inside <textarea> (newline) and contenteditable.
|
|
113
|
+
const target = e.target as HTMLElement | null
|
|
114
|
+
if (target?.tagName === 'TEXTAREA') return
|
|
115
|
+
if (target?.isContentEditable) return
|
|
116
|
+
this._maybeRequestSubmit(e)
|
|
117
|
+
})
|
|
54
118
|
}
|
|
55
119
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
120
|
+
private _maybeRequestSubmit(e: Event): void {
|
|
121
|
+
// On click: trigger only when the target is a type=submit button.
|
|
122
|
+
// On keydown(Enter): always trigger if focus is on a registered field.
|
|
123
|
+
// type=reset is handled separately in _maybeReset.
|
|
124
|
+
if (e.type === 'click') {
|
|
125
|
+
const path = e.composedPath()
|
|
126
|
+
const resetBtn = path.find(
|
|
127
|
+
node => isButton(node) && node.getAttribute('type') === 'reset',
|
|
128
|
+
)
|
|
129
|
+
if (resetBtn) {
|
|
130
|
+
e.preventDefault()
|
|
131
|
+
const form = this.shadowRoot?.querySelector('form')
|
|
132
|
+
form?.reset()
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
const submitBtn = path.find(
|
|
136
|
+
node => isButton(node) && node.getAttribute('type') === 'submit',
|
|
137
|
+
)
|
|
138
|
+
if (!submitBtn) return
|
|
139
|
+
e.preventDefault()
|
|
76
140
|
}
|
|
141
|
+
const form = this.shadowRoot?.querySelector('form')
|
|
142
|
+
form?.requestSubmit()
|
|
143
|
+
}
|
|
77
144
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this._form = form
|
|
82
|
-
this._wrapped = true
|
|
145
|
+
/** Active fields — drops stale refs from disconnected nodes. */
|
|
146
|
+
private get _activeFields(): IFormFieldMixin[] {
|
|
147
|
+
return [...this._fields].filter(f => f.isConnected)
|
|
83
148
|
}
|
|
84
149
|
|
|
85
|
-
private _onSubmit
|
|
86
|
-
// Prevent the default navigation AND stop the native submit from
|
|
87
|
-
// bubbling past this wrapper — otherwise consumers listening for
|
|
88
|
-
// `submit` on <schmancy-form> would see the native event plus our
|
|
89
|
-
// CustomEvent (two fires per submission).
|
|
150
|
+
private async _onSubmit(e: SubmitEvent): Promise<void> {
|
|
90
151
|
e.preventDefault()
|
|
91
152
|
e.stopPropagation()
|
|
92
|
-
if (
|
|
93
|
-
|
|
153
|
+
if (this._submitting) return
|
|
154
|
+
|
|
155
|
+
// If any field has an async validator pending, wait for them all to
|
|
156
|
+
// settle before deciding validity. This is the hard-block model: the
|
|
157
|
+
// user clicks submit, the form holds (aria-busy="true"), waits for
|
|
158
|
+
// validators, then proceeds with the truth they reported.
|
|
159
|
+
const pendingValidators = this._activeFields.filter(f => f.isValidating)
|
|
160
|
+
if (pendingValidators.length > 0) {
|
|
161
|
+
this._broadcastStatus('submitting')
|
|
162
|
+
await new Promise<void>(resolve => {
|
|
163
|
+
const tick = () => {
|
|
164
|
+
if (this._activeFields.every(f => !f.isValidating)) resolve()
|
|
165
|
+
else requestAnimationFrame(tick)
|
|
166
|
+
}
|
|
167
|
+
tick()
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Phase 4 — submit forces error display on every field.
|
|
172
|
+
this._activeFields.forEach(f => f.markSubmitted())
|
|
173
|
+
|
|
174
|
+
// Validate; success path entered ONLY if all valid.
|
|
175
|
+
const allValid = this._activeFields.every(f => f.checkValidity())
|
|
176
|
+
const fs = formSubmitState.value
|
|
177
|
+
if (!allValid) {
|
|
178
|
+
formSubmitState.set({
|
|
179
|
+
...fs,
|
|
180
|
+
status: 'error',
|
|
181
|
+
error: { message: 'Validation failed' },
|
|
182
|
+
})
|
|
183
|
+
this._broadcastStatus('error', 'Validation failed. Please correct the highlighted fields.')
|
|
184
|
+
const firstInvalid = this._activeFields.find(f => f.error) as unknown as
|
|
185
|
+
| HTMLElement
|
|
186
|
+
| undefined
|
|
187
|
+
firstInvalid?.focus()
|
|
94
188
|
return
|
|
95
189
|
}
|
|
96
|
-
|
|
97
|
-
this.
|
|
190
|
+
|
|
191
|
+
this._submitting = true
|
|
192
|
+
formSubmitState.set({
|
|
193
|
+
...fs,
|
|
194
|
+
status: 'submitting',
|
|
195
|
+
error: null,
|
|
196
|
+
submitCount: fs.submitCount + 1,
|
|
197
|
+
})
|
|
198
|
+
this._broadcastStatus('submitting')
|
|
199
|
+
|
|
200
|
+
// Build payload from the registered fields' contracted toFormEntries().
|
|
201
|
+
const formData = new FormData()
|
|
202
|
+
for (const field of this._activeFields) {
|
|
203
|
+
for (const [k, v] of field.toFormEntries()) formData.append(k, v)
|
|
204
|
+
}
|
|
205
|
+
const raw = Object.fromEntries(formData)
|
|
206
|
+
const data = this.schema ? this.schema.parse(raw) : raw
|
|
207
|
+
|
|
208
|
+
// Awaitable submit — consumers register promises via e.detail.until(p).
|
|
209
|
+
const pending: Promise<unknown>[] = []
|
|
210
|
+
this.dispatchEvent(
|
|
211
|
+
new CustomEvent<SchmancyFormSubmitDetail<unknown>>('submit', {
|
|
212
|
+
detail: {
|
|
213
|
+
data,
|
|
214
|
+
formData,
|
|
215
|
+
until: (p: Promise<unknown>) => pending.push(p),
|
|
216
|
+
},
|
|
217
|
+
}),
|
|
218
|
+
)
|
|
219
|
+
|
|
98
220
|
try {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
221
|
+
await Promise.all(pending)
|
|
222
|
+
formSubmitState.set({
|
|
223
|
+
...formSubmitState.value,
|
|
224
|
+
status: 'success',
|
|
225
|
+
error: null,
|
|
226
|
+
})
|
|
227
|
+
this._broadcastStatus('success')
|
|
228
|
+
} catch (err) {
|
|
229
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
230
|
+
formSubmitState.set({
|
|
231
|
+
...formSubmitState.value,
|
|
232
|
+
status: 'error',
|
|
233
|
+
error: { message },
|
|
234
|
+
})
|
|
235
|
+
this._broadcastStatus('error', message)
|
|
104
236
|
} finally {
|
|
105
|
-
this.
|
|
237
|
+
this._submitting = false
|
|
106
238
|
}
|
|
107
239
|
}
|
|
108
240
|
|
|
109
|
-
private _onReset
|
|
241
|
+
private _onReset(e: Event): void {
|
|
110
242
|
e.stopPropagation()
|
|
111
|
-
this.
|
|
243
|
+
this._activeFields.forEach(f => f.resetForm())
|
|
244
|
+
formSubmitState.set({ status: 'idle', error: null, submitCount: 0 })
|
|
245
|
+
this._broadcastStatus('idle')
|
|
112
246
|
this.dispatchEvent(new CustomEvent('reset'))
|
|
113
247
|
}
|
|
114
248
|
|
|
249
|
+
private _broadcastStatus(status: FormSubmitState['status'], errorMessage?: string): void {
|
|
250
|
+
this._liveStatus = status
|
|
251
|
+
this._liveError = errorMessage ?? ''
|
|
252
|
+
const states = this._internals?.states
|
|
253
|
+
if (states) {
|
|
254
|
+
for (const s of ['submitting', 'success', 'error', 'idle']) states.delete(s)
|
|
255
|
+
states.add(status)
|
|
256
|
+
}
|
|
257
|
+
// aria-busy on the host while submitting (WCAG 2.2 AA — disabled buttons
|
|
258
|
+
// drop from tab order; keep them focusable, signal busy via aria).
|
|
259
|
+
if (status === 'submitting') this.setAttribute('aria-busy', 'true')
|
|
260
|
+
else this.removeAttribute('aria-busy')
|
|
261
|
+
// Public formstate event — external state stores subscribe without
|
|
262
|
+
// having to consume formSubmitState directly.
|
|
263
|
+
this.dispatchEvent(
|
|
264
|
+
new CustomEvent<FormSubmitState>('formstate', {
|
|
265
|
+
detail: { ...formSubmitState.value },
|
|
266
|
+
bubbles: true,
|
|
267
|
+
composed: true,
|
|
268
|
+
}),
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Server-side error mapping (RHF `setError(name, ...)`-equivalent).
|
|
274
|
+
* Sets `setCustomValidity(message)` on the matching field and ensures the
|
|
275
|
+
* error displays by marking it submitted.
|
|
276
|
+
*/
|
|
277
|
+
public setFieldError(name: string, message: string): boolean {
|
|
278
|
+
const field = this._activeFields.find(f => f.name === name)
|
|
279
|
+
if (!field) return false
|
|
280
|
+
field.setCustomValidity(message)
|
|
281
|
+
field.markSubmitted()
|
|
282
|
+
return true
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Top-of-form error (RHF `setError('root.serverError', ...)`-equivalent).
|
|
287
|
+
* Flips form status to 'error' with a structured `FormError`.
|
|
288
|
+
*/
|
|
289
|
+
public setFormError(message: string, code?: string): void {
|
|
290
|
+
formSubmitState.set({
|
|
291
|
+
...formSubmitState.value,
|
|
292
|
+
status: 'error',
|
|
293
|
+
error: { message, code } as FormError,
|
|
294
|
+
})
|
|
295
|
+
this._broadcastStatus('error', message)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Clear the `submitted` flag on every registered field without resetting
|
|
300
|
+
* their values. Wizard pattern: stepping back from a later step should not
|
|
301
|
+
* leave the earlier step's fields in aggressive "show all errors" mode
|
|
302
|
+
* (which `submitted = true` triggers via the `_shouldShowError()` gate).
|
|
303
|
+
*
|
|
304
|
+
* Pristine fields with `validateOn: 'dirty'` go quiet again. Fields the
|
|
305
|
+
* user actually dirtied keep showing their errors (correct UX — those are
|
|
306
|
+
* still genuine mistakes the user can see).
|
|
307
|
+
*/
|
|
308
|
+
public clearSubmitted(): void {
|
|
309
|
+
this._activeFields.forEach(f => f.clearSubmitted())
|
|
310
|
+
formSubmitState.set({
|
|
311
|
+
...formSubmitState.value,
|
|
312
|
+
status: 'idle',
|
|
313
|
+
error: null,
|
|
314
|
+
})
|
|
315
|
+
this._broadcastStatus('idle')
|
|
316
|
+
}
|
|
317
|
+
|
|
115
318
|
/** Programmatically submit via the native submitter pipeline. */
|
|
116
319
|
public submit(): boolean {
|
|
117
|
-
|
|
118
|
-
if (!
|
|
119
|
-
|
|
320
|
+
const form = this.shadowRoot?.querySelector('form')
|
|
321
|
+
if (!form) return false
|
|
322
|
+
form.requestSubmit()
|
|
120
323
|
return true
|
|
121
324
|
}
|
|
122
325
|
|
|
123
326
|
/** Programmatically reset via native `form.reset()`. */
|
|
124
327
|
public reset(): void {
|
|
125
|
-
this.
|
|
328
|
+
const form = this.shadowRoot?.querySelector('form')
|
|
329
|
+
form?.reset()
|
|
126
330
|
}
|
|
127
331
|
|
|
128
332
|
public reportValidity(): boolean {
|
|
129
|
-
return this.
|
|
333
|
+
return this._activeFields.every(f => f.reportValidity())
|
|
130
334
|
}
|
|
131
335
|
|
|
132
336
|
public checkValidity(): boolean {
|
|
133
|
-
return this.
|
|
337
|
+
return this._activeFields.every(f => f.checkValidity())
|
|
134
338
|
}
|
|
135
339
|
|
|
136
|
-
/** Snapshot of current form values
|
|
340
|
+
/** Snapshot of current form values from the registered fields. */
|
|
137
341
|
public getFormData(): FormData {
|
|
138
|
-
|
|
342
|
+
const formData = new FormData()
|
|
343
|
+
for (const field of this._activeFields) {
|
|
344
|
+
for (const [k, v] of field.toFormEntries()) formData.append(k, v)
|
|
345
|
+
}
|
|
346
|
+
return formData
|
|
139
347
|
}
|
|
140
348
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
349
|
+
render() {
|
|
350
|
+
return html`
|
|
351
|
+
<schmancy-context .provides=${[formSubmitState]}>
|
|
352
|
+
<form
|
|
353
|
+
?novalidate=${this.novalidate}
|
|
354
|
+
@submit=${this._onSubmit}
|
|
355
|
+
@reset=${this._onReset}
|
|
356
|
+
>
|
|
357
|
+
<slot></slot>
|
|
358
|
+
</form>
|
|
359
|
+
<!--
|
|
360
|
+
Form-level live region — assistive tech announces server-side
|
|
361
|
+
form errors (validation summary, network failure, server reject)
|
|
362
|
+
here. Visually hidden via the .sr-only convention; consumers
|
|
363
|
+
render their own visible banner from formSubmitState if they
|
|
364
|
+
want one. Empty content while idle/submitting/success — only
|
|
365
|
+
error states populate the region. WCAG 4.1.3 (Status Messages).
|
|
366
|
+
-->
|
|
367
|
+
<div
|
|
368
|
+
role="status"
|
|
369
|
+
aria-live="assertive"
|
|
370
|
+
aria-atomic="true"
|
|
371
|
+
class="sr-only"
|
|
372
|
+
>${this._liveStatus === 'error' ? this._liveError : ''}</div>
|
|
373
|
+
</schmancy-context>
|
|
374
|
+
`
|
|
144
375
|
}
|
|
145
376
|
}
|
|
146
377
|
|
|
@@ -150,10 +381,9 @@ declare global {
|
|
|
150
381
|
}
|
|
151
382
|
}
|
|
152
383
|
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
// The new implementation no longer uses them internally.
|
|
384
|
+
// Retained type surfaces — kept exported because downstream code may import
|
|
385
|
+
// them as documentation. The new implementation no longer uses them
|
|
386
|
+
// internally.
|
|
157
387
|
|
|
158
388
|
export interface FormElement extends HTMLElement {
|
|
159
389
|
name?: string
|
|
@@ -173,6 +403,7 @@ export interface ValidatableFormElement extends FormElement {
|
|
|
173
403
|
}
|
|
174
404
|
|
|
175
405
|
export interface FormEventMap {
|
|
176
|
-
submit: CustomEvent<
|
|
406
|
+
submit: CustomEvent<SchmancyFormSubmitDetail<unknown>>
|
|
177
407
|
reset: CustomEvent
|
|
408
|
+
formstate: CustomEvent<FormSubmitState>
|
|
178
409
|
}
|
package/src/form/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export * from './area';
|
|
2
2
|
export * from './audio';
|
|
3
|
-
export * from './autocomplete';
|
|
3
|
+
export * from './form/fields/autocomplete';
|
|
4
4
|
export * from './badge';
|
|
5
5
|
export * from './boat';
|
|
6
6
|
export * from './busy';
|
|
7
7
|
export * from './button';
|
|
8
8
|
export * from './card';
|
|
9
|
-
export * from './checkbox';
|
|
9
|
+
export * from './form/fields/checkbox';
|
|
10
10
|
export * from './chips';
|
|
11
11
|
export * from './connectivity';
|
|
12
12
|
export * from './content-drawer';
|
|
13
|
-
export * from './date-range';
|
|
13
|
+
export * from './form/fields/date-range';
|
|
14
14
|
export * from './date-range-inline';
|
|
15
15
|
export * from './delay';
|
|
16
16
|
export * from './details';
|
|
@@ -24,7 +24,7 @@ export * from './window';
|
|
|
24
24
|
export * from './form';
|
|
25
25
|
export * from './icons';
|
|
26
26
|
export * from './iframe';
|
|
27
|
-
export * from './input';
|
|
27
|
+
export * from './form/fields/input';
|
|
28
28
|
export * from './json';
|
|
29
29
|
export * from './layout';
|
|
30
30
|
export * from './lightbox';
|
|
@@ -37,10 +37,10 @@ export * from './notification';
|
|
|
37
37
|
export * from './option';
|
|
38
38
|
export * from './page';
|
|
39
39
|
export * from './progress';
|
|
40
|
-
export * from './radio-group';
|
|
41
|
-
export * from './range';
|
|
40
|
+
export * from './form/fields/radio-group';
|
|
41
|
+
export * from './form/fields/range';
|
|
42
42
|
export * from './rxjs-utils';
|
|
43
|
-
export * from './select';
|
|
43
|
+
export * from './form/fields/select';
|
|
44
44
|
export * from './slider';
|
|
45
45
|
export * from './state';
|
|
46
46
|
export * from './steps';
|
|
@@ -48,7 +48,7 @@ export * from './surface';
|
|
|
48
48
|
export * from './table';
|
|
49
49
|
export * from './tabs';
|
|
50
50
|
export * from './teleport';
|
|
51
|
-
export * from './textarea';
|
|
51
|
+
export * from './form/fields/textarea';
|
|
52
52
|
export * from './theme';
|
|
53
53
|
export * from './theme-button';
|
|
54
54
|
export * from './tooltip';
|
|
@@ -62,5 +62,5 @@ export * from './breadcrumb';
|
|
|
62
62
|
export * from './kbd';
|
|
63
63
|
export * from './skeleton';
|
|
64
64
|
export * from './splash-screen';
|
|
65
|
-
export * from './switch';
|
|
65
|
+
export * from './form/fields/switch';
|
|
66
66
|
export * from './visually-hidden';
|
|
@@ -8,6 +8,38 @@ import { ITailwindElementMixin } from './tailwind.mixin';
|
|
|
8
8
|
* the global registry so detection works across module realms/bundles.
|
|
9
9
|
*/
|
|
10
10
|
export declare const SCHMANCY_FORM_FIELD: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* Composed event a field dispatches in `connectedCallback`. `<schmancy-form>`
|
|
13
|
+
* subscribes via `fromEvent(this, FIELD_CONNECT_EVENT)` and adds the field to
|
|
14
|
+
* its registry. No matching disconnect event — composed events from a
|
|
15
|
+
* disconnected node have an empty composed path; cleanup is via `isConnected`
|
|
16
|
+
* filter at iteration time.
|
|
17
|
+
*/
|
|
18
|
+
export declare const FIELD_CONNECT_EVENT = "schmancy:field:connect";
|
|
19
|
+
/**
|
|
20
|
+
* Validation modes.
|
|
21
|
+
* - `dirty` (default per Revolute) — show errors only after value diverged.
|
|
22
|
+
* - `touched` — show errors after first blur, even if value unchanged.
|
|
23
|
+
* - `always` — show errors immediately (live search).
|
|
24
|
+
* - `submitted` — hold all errors until submit (wizard step).
|
|
25
|
+
* - `length` — fire validation only when `value.length` reaches `maxlength`
|
|
26
|
+
* (Stripe pattern for predictable-length fields: ZIP, phone, card number).
|
|
27
|
+
*/
|
|
28
|
+
export type ValidateOn = 'always' | 'touched' | 'dirty' | 'submitted' | 'length';
|
|
29
|
+
/**
|
|
30
|
+
* Per-field error-message override map. Keys are `ValidityState` flag names;
|
|
31
|
+
* values are the message to display when that flag is set. Unset flags fall
|
|
32
|
+
* back to the mixin's hardcoded defaults (English).
|
|
33
|
+
*
|
|
34
|
+
* Use for i18n or domain-specific copy:
|
|
35
|
+
* ```ts
|
|
36
|
+
* <schmancy-input
|
|
37
|
+
* .errorMessages=${{ valueMissing: 'Adresse e-mail requise', typeMismatch: 'Format e-mail invalide' }}
|
|
38
|
+
* type="email" required
|
|
39
|
+
* ></schmancy-input>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export type ErrorMessages = Partial<Record<keyof ValidityState, string>>;
|
|
11
43
|
/**
|
|
12
44
|
* Interface defining the properties and methods that the FormFieldMixin adds.
|
|
13
45
|
*/
|
|
@@ -22,10 +54,68 @@ export interface IFormFieldMixin extends Element {
|
|
|
22
54
|
validationMessage: string;
|
|
23
55
|
hint?: string;
|
|
24
56
|
id: string;
|
|
57
|
+
/** Set to `true` once the user has blurred the field at least once. */
|
|
58
|
+
touched: boolean;
|
|
59
|
+
/** `true` when the current value differs from the captured default. */
|
|
60
|
+
dirty: boolean;
|
|
61
|
+
/** Inverse of `dirty`. */
|
|
62
|
+
pristine: boolean;
|
|
63
|
+
/** Set to `true` by `<schmancy-form>` on submit (forces error display). */
|
|
64
|
+
submitted: boolean;
|
|
65
|
+
/** Validation mode — controls when errors display. Default `'dirty'`. */
|
|
66
|
+
validateOn: ValidateOn;
|
|
67
|
+
/**
|
|
68
|
+
* Per-field error-message override map (i18n hook). See `ErrorMessages`.
|
|
69
|
+
* Unset keys fall back to the mixin's hardcoded English defaults.
|
|
70
|
+
*/
|
|
71
|
+
errorMessages?: ErrorMessages;
|
|
72
|
+
/**
|
|
73
|
+
* `ElementInternals` instance attached by the mixin. Exposed so subclasses
|
|
74
|
+
* with non-standard validity semantics (date-range, multi-select) can
|
|
75
|
+
* surface platform `ValidityStateFlags` directly via
|
|
76
|
+
* `internals.setValidity({ valueMissing: true })` rather than rolling their
|
|
77
|
+
* own `attachInternals` call.
|
|
78
|
+
*/
|
|
79
|
+
internals: ElementInternals | undefined;
|
|
25
80
|
form: HTMLFormElement | null;
|
|
26
81
|
checkValidity(): boolean;
|
|
27
82
|
reportValidity(): boolean;
|
|
28
83
|
setCustomValidity(message: string): void;
|
|
84
|
+
/** Mark the field as touched (component should call on blur). */
|
|
85
|
+
markTouched(): void;
|
|
86
|
+
/** Mark the field as submitted (called by `<schmancy-form>` on submit). */
|
|
87
|
+
markSubmitted(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Clear the `submitted` flag without resetting value/touched/error.
|
|
90
|
+
* Used by wizards: stepping back from step N to step N-1 should not
|
|
91
|
+
* leave step N-1's fields in aggressive "show all errors" mode.
|
|
92
|
+
*/
|
|
93
|
+
clearSubmitted(): void;
|
|
94
|
+
/**
|
|
95
|
+
* `true` while an async validator is in flight. Broadcast as
|
|
96
|
+
* `:state(validating)`. `<schmancy-form>` blocks submit until every
|
|
97
|
+
* registered field's `isValidating` is back to `false`.
|
|
98
|
+
*/
|
|
99
|
+
isValidating: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Run an async validator. While the promise is pending, `isValidating` is
|
|
102
|
+
* `true` and `:state(validating)` is broadcast. On resolve, the returned
|
|
103
|
+
* string is passed to `setCustomValidity` — empty string clears any
|
|
104
|
+
* existing custom error; non-empty marks the field invalid with that
|
|
105
|
+
* message.
|
|
106
|
+
*
|
|
107
|
+
* Submitting the form while a validator is pending is queued — the form
|
|
108
|
+
* waits for `Promise.all(pending validators)` to settle before proceeding.
|
|
109
|
+
*/
|
|
110
|
+
runAsyncValidator(fn: () => Promise<string>): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the gate for showing validation errors is open right now. Exposed
|
|
113
|
+
* so subclasses with custom error-display channels (e.g. select renders
|
|
114
|
+
* errors on a child input) can keep their gate consistent with the mixin's.
|
|
115
|
+
* Subclasses should not override this — extend the truth table by changing
|
|
116
|
+
* `validateOn` instead.
|
|
117
|
+
*/
|
|
118
|
+
_shouldShowError(): boolean;
|
|
29
119
|
toFormEntries(): Array<[string, FormDataEntryValue]>;
|
|
30
120
|
resetForm(): void;
|
|
31
121
|
emitChange(detail: any): void;
|