@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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as e, i as t } from "./mixins-BWb9_e1s.js";
|
|
2
|
+
import { a as n } from "./active-host-BP0zy_Y9.js";
|
|
3
3
|
import { Subject as r, fromEvent as i, takeUntil as a } from "rxjs";
|
|
4
4
|
import { customElement as o, property as s } from "lit/decorators.js";
|
|
5
5
|
import { html as c, unsafeCSS as l } from "lit";
|
|
6
6
|
import { when as u } from "lit/directives/when.js";
|
|
7
|
-
var d = class extends e
|
|
7
|
+
var d = class extends t(e) {
|
|
8
8
|
constructor(...e) {
|
|
9
9
|
super(...e), this.label = "", this.name = "", this.value = "", this.options = [], this.required = !1, this.selection$ = new r();
|
|
10
10
|
}
|
|
@@ -60,7 +60,7 @@ var d = class extends e(t) {
|
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
62
|
n([s({ type: String })], d.prototype, "label", void 0), n([s({ type: String })], d.prototype, "name", void 0), n([s({ type: String })], d.prototype, "value", void 0), n([s({ type: Array })], d.prototype, "options", void 0), n([s({ type: Boolean })], d.prototype, "required", void 0), d = n([o("schmancy-radio-group")], d);
|
|
63
|
-
var f = class extends e
|
|
63
|
+
var f = class extends t(e) {
|
|
64
64
|
constructor(...e) {
|
|
65
65
|
super(...e), this.value = "", this.checked = !1, this.disabled = !1, this.name = "";
|
|
66
66
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-group-DA4eIGCj.js","names":[],"sources":["../src/form/fields/radio-group/radio-group.scss?inline","../src/form/fields/radio-group/radio-group.ts","../src/form/fields/radio-group/radio-button.ts"],"sourcesContent":[":host {\n\tdisplay: inherit;\n\tposition: inherit;\n}\n","import { html, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { Subject, fromEvent, takeUntil } from 'rxjs'\nimport style from './radio-group.scss?inline'\nimport { SchmancyElement } from '@mixins/index'\nimport { when } from 'lit/directives/when.js'\nimport { FormFieldMixin } from '@mixins/formField.mixin'\n\nexport type SchmancyRadioGroupOption = {\n\tlabel: string\n\tvalue: string\n}\nexport type SchmancyRadioGroupChangeEvent = CustomEvent<{\n\tvalue: string\n}>\n@customElement('schmancy-radio-group')\nexport class RadioGroup extends FormFieldMixin(SchmancyElement) {\n\tstatic styles = [unsafeCSS(style)];\n\t@property({ type: String }) override label = ''\n\t@property({ type: String }) override name = ''\n\t@property({ type: String }) override value = ''\n\t@property({ type: Array }) options: SchmancyRadioGroupOption[] = []\n\t@property({ type: Boolean }) override required: boolean = false\n\tprivate selection$ = new Subject<string>()\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tthis.selection$.pipe(takeUntil(this.disconnecting)).subscribe(value => {\n\t\t\tthis.value = value\n\t\t\tthis.emitChange({ value })\n\t\t\t// Update all child radio buttons\n\t\t\tthis.updateChildRadioButtons()\n\t\t})\n\n\t\t// Listen for radio button clicks from children\n\t\tfromEvent<CustomEvent>(this, 'radio-button-click')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe((e: CustomEvent) => {\n\t\t\t\tthis.selection$.next(e.detail.value)\n\t\t\t})\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\t// Subscriptions are automatically cleaned up via takeUntil(this.disconnecting)\n\t\tthis.selection$?.complete()\n\t}\n\t\n\tprivate handleSelection(value: string) {\n\t\tthis.selection$.next(value)\n\t}\n\t\n\tprivate updateChildRadioButtons() {\n\t\t// Update child radio buttons checked state\n\t\tconst radioButtons = this.querySelectorAll('schmancy-radio-button')\n\t\tradioButtons.forEach(button => {\n\t\t\tconst buttonValue = button.getAttribute('value')\n\t\t\tif (buttonValue === this.value) {\n\t\t\t\tbutton.setAttribute('checked', '')\n\t\t\t} else {\n\t\t\t\tbutton.removeAttribute('checked')\n\t\t\t}\n\t\t})\n\t}\n\t\n\t// For backwards compatibility with direct option setting\n\tupdated(changedProperties: Map<string, unknown>) {\n\t\tsuper.updated(changedProperties)\n\t\tif (changedProperties.has('value')) {\n\t\t\tthis.updateChildRadioButtons()\n\t\t}\n\t}\n\n\trender() {\n\t\t// Check if we have any slotted radio buttons\n\t\tconst hasSlottedContent = this.childElementCount > 0\n\t\t\n\t\treturn html`\n\t\t\t<div class=\"grid gap-4\">\n\t\t\t\t${when(this.label, () => html` <label class=\"text-base font-semibold text-surface-on\">${this.label}</label> `)}\n\t\t\t\t\n\t\t\t\t${hasSlottedContent ? \n\t\t\t\t\thtml`<slot></slot>` :\n\t\t\t\t\tthis.options?.map(option => html`\n\t\t\t\t\t\t<div class=\"flex items-center\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t.required=${this.required}\n\t\t\t\t\t\t\t\tid=${option.value}\n\t\t\t\t\t\t\t\tclass=\"h-4 w-4 border-outline text-primary-default focus:ring-primary-default\"\n\t\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\t\tname=${this.name}\n\t\t\t\t\t\t\t\t.value=${option.value}\n\t\t\t\t\t\t\t\t.checked=${option.value === this.value}\n\t\t\t\t\t\t\t\t@change=${() => this.handleSelection(option.value)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<label for=${option.value} class=\"ml-3 block text-sm font-medium leading-6 text-surface-on\">\n\t\t\t\t\t\t\t\t${option.label || option.value}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`)\n\t\t\t\t}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-radio-group': RadioGroup\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { FormFieldMixin } from '@mixins/formField.mixin'\nimport { fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Radio button component for use within radio groups.\n *\n * @prop {string} name - Name attribute for grouping radio buttons\n * @prop {string} value - Value of this radio button\n * @prop {boolean} checked - Whether the radio button is selected\n * @prop {boolean} disabled - Whether the radio button is disabled\n */\n@customElement('schmancy-radio-button')\nexport class RadioButton extends FormFieldMixin(SchmancyElement) {\n\t@property({ type: String }) override value = ''\n\t@property({ type: Boolean, reflect: true }) checked = false\n\t@property({ type: Boolean }) override disabled = false\n\t@property({ type: String }) override name = ''\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\t// Listen for click events\n\t\tfromEvent<MouseEvent>(this, 'click')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(this.handleClick)\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\t// Event listeners are automatically cleaned up via takeUntil(this.disconnecting)\n\t}\n\n\tprivate handleClick() {\n\t\tif (this.disabled) return\n\n\t\t// Find parent radio-group if exists\n\t\tconst radioGroup = this.closest('schmancy-radio-group')\n\t\tif (radioGroup) {\n\t\t\t// Let the radio-group handle the change\n\t\t\tconst event = new CustomEvent('radio-button-click', {\n\t\t\t\tdetail: { value: this.value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t})\n\t\t\tthis.dispatchEvent(event)\n\t\t} else {\n\t\t\t// Standalone usage\n\t\t\tthis.checked = true\n\t\t\tthis.emitChange({ value: this.value })\n\t\t}\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<label class=\"relative flex items-start cursor-pointer\">\n\t\t\t\t<div class=\"flex items-center h-6\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\tclass=\"h-4 w-4 text-primary-default focus:ring-primary-container border-outline\"\n\t\t\t\t\t\t.value=${this.value}\n\t\t\t\t\t\t.checked=${this.checked}\n\t\t\t\t\t\t.disabled=${this.disabled}\n\t\t\t\t\t\t.name=${this.name}\n\t\t\t\t\t\t@change=${() => {}}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"ml-3\">\n\t\t\t\t\t<slot name=\"label\"></slot>\n\t\t\t\t</div>\n\t\t\t</label>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-radio-button': RadioButton\n\t}\n}\n"],"mappings":"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"}
|
package/dist/radio-group.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./radio-group-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./radio-group-BA-jRct5.cjs`);Object.defineProperty(exports,`RadioButton`,{enumerable:!0,get:function(){return e.t}}),Object.defineProperty(exports,`RadioGroup`,{enumerable:!0,get:function(){return e.n}});
|
package/dist/radio-group.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./radio-group-
|
|
1
|
+
import { n as e, t } from "./radio-group-DA4eIGCj.js";
|
|
2
2
|
export { t as RadioButton, e as RadioGroup };
|
package/dist/range.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BOOu6q2n.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`lit/decorators.js`),r=require(`lit`),i=require(`lit/directives/when.js`);var a=class extends e.o(r.css`
|
|
2
2
|
input[type='range'] {
|
|
3
3
|
-webkit-appearance: none;
|
|
4
4
|
appearance: none;
|
|
@@ -40,7 +40,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
|
|
|
40
40
|
background: var(--color-primary, #6750a4);
|
|
41
41
|
cursor: pointer;
|
|
42
42
|
}
|
|
43
|
-
`
|
|
43
|
+
`){constructor(...e){super(...e),this.min=0,this.max=1,this.step=.01,this.value=0}get progress(){return(this.value-this.min)/(this.max-this.min)*100+`%`}willUpdate(e){super.willUpdate(e),(e.has(`value`)||e.has(`name`))&&this.internals?.setFormValue(String(this.value))}toFormEntries(){return!this.name||this.disabled?[]:[[this.name,String(this.value)]]}render(){return r.html`
|
|
44
44
|
<div class="flex flex-col gap-1 w-full">
|
|
45
45
|
${(0,i.when)(this.label,()=>r.html`
|
|
46
46
|
<div class="flex justify-between items-center">
|
|
@@ -55,8 +55,10 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
|
|
|
55
55
|
.step=${String(this.step)}
|
|
56
56
|
.value=${String(this.value)}
|
|
57
57
|
?disabled=${this.disabled}
|
|
58
|
+
aria-label=${this.label||`Range`}
|
|
59
|
+
aria-valuetext=${String(this.value)}
|
|
58
60
|
style="--range-progress: ${this.progress}"
|
|
59
|
-
@input=${e=>{this.value=Number(e.target.value),this.
|
|
61
|
+
@input=${e=>{this.value=Number(e.target.value),this.markTouched(),this.emitChange({value:this.value})}}
|
|
60
62
|
/>
|
|
61
63
|
</div>
|
|
62
|
-
`}};t.
|
|
64
|
+
`}};t.a([(0,n.property)({type:Number})],a.prototype,`min`,void 0),t.a([(0,n.property)({type:Number})],a.prototype,`max`,void 0),t.a([(0,n.property)({type:Number})],a.prototype,`step`,void 0),t.a([(0,n.property)({type:Number,reflect:!0})],a.prototype,`value`,void 0),a=t.a([(0,n.customElement)(`schmancy-range`)],a),Object.defineProperty(exports,`SchmancyRange`,{enumerable:!0,get:function(){return a}});
|
package/dist/range.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"range.cjs","names":[],"sources":["../src/range/range.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"range.cjs","names":[],"sources":["../src/form/fields/range/range.ts"],"sourcesContent":["import { css, html, type PropertyValues } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { when } from 'lit/directives/when.js'\nimport { SchmancyFormField } from '@mixins/index'\n\nexport type SchmancyRangeChangeEvent = CustomEvent<{ value: number }>\n\n/**\n * @element schmancy-range\n * Range input (numeric slider).\n * @fires change - Fires on value change with `{ value: number }`.\n */\n@customElement('schmancy-range')\nexport class SchmancyRange extends SchmancyFormField(css`\n\tinput[type='range'] {\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\twidth: 100%;\n\t\theight: 4px;\n\t\tborder-radius: 2px;\n\t\tbackground: linear-gradient(\n\t\t\tto right,\n\t\t\tvar(--color-primary, #6750a4) 0%,\n\t\t\tvar(--color-primary, #6750a4) var(--range-progress, 0%),\n\t\t\tcolor-mix(in srgb, var(--color-primary, #6750a4) 30%, transparent) var(--range-progress, 0%),\n\t\t\tcolor-mix(in srgb, var(--color-primary, #6750a4) 30%, transparent) 100%\n\t\t);\n\t\toutline: none;\n\t\tcursor: pointer;\n\t}\n\tinput[type='range']:disabled {\n\t\topacity: 0.38;\n\t\tcursor: not-allowed;\n\t}\n\tinput[type='range']::-webkit-slider-thumb {\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\twidth: 20px;\n\t\theight: 20px;\n\t\tborder-radius: 50%;\n\t\tbackground: var(--color-primary, #6750a4);\n\t\tcursor: pointer;\n\t\ttransition: box-shadow 0.1s ease;\n\t}\n\tinput[type='range']::-webkit-slider-thumb:hover {\n\t\tbox-shadow: 0 0 0 8px color-mix(in srgb, var(--color-primary, #6750a4) 12%, transparent);\n\t}\n\tinput[type='range']::-moz-range-thumb {\n\t\twidth: 20px;\n\t\theight: 20px;\n\t\tborder-radius: 50%;\n\t\tborder: none;\n\t\tbackground: var(--color-primary, #6750a4);\n\t\tcursor: pointer;\n\t}\n`) {\n\t// `formAssociated`, `internals`, `name`, `disabled`, `required`, `id`,\n\t// `label`, `error`, `validationMessage`, `validateOn`, touched/dirty/submitted,\n\t// `markTouched/markSubmitted`, `formResetCallback`, FIELD_CONNECT_EVENT\n\t// dispatch — all from the mixin.\n\n\t@property({ type: Number }) min: number = 0\n\t@property({ type: Number }) max: number = 1\n\t@property({ type: Number }) step: number = 0.01\n\n\t/** Numeric value — narrowed override of the mixin's wide value union. */\n\t@property({ type: Number, reflect: true })\n\toverride value: number = 0\n\n\tprivate get progress(): string {\n\t\treturn `${((this.value - this.min) / (this.max - this.min)) * 100}%`\n\t}\n\n\toverride willUpdate(changed: PropertyValues): void {\n\t\tsuper.willUpdate(changed)\n\t\tif (changed.has('value') || changed.has('name')) {\n\t\t\tthis.internals?.setFormValue(String(this.value))\n\t\t}\n\t}\n\n\t/** FormData contributes the value as a string (native range input convention). */\n\toverride toFormEntries(): Array<[string, FormDataEntryValue]> {\n\t\tif (!this.name || this.disabled) return []\n\t\treturn [[this.name, String(this.value)]]\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<div class=\"flex flex-col gap-1 w-full\">\n\t\t\t\t${when(\n\t\t\t\t\tthis.label,\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<div class=\"flex justify-between items-center\">\n\t\t\t\t\t\t\t<schmancy-typography type=\"label\" token=\"sm\" class=\"text-surface-on\">${this.label}</schmancy-typography>\n\t\t\t\t\t\t\t<schmancy-typography type=\"label\" token=\"sm\" class=\"text-surface-on opacity-60\">${this.value}</schmancy-typography>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\t\t\t\t<input\n\t\t\t\t\ttype=\"range\"\n\t\t\t\t\t.min=${String(this.min)}\n\t\t\t\t\t.max=${String(this.max)}\n\t\t\t\t\t.step=${String(this.step)}\n\t\t\t\t\t.value=${String(this.value)}\n\t\t\t\t\t?disabled=${this.disabled}\n\t\t\t\t\taria-label=${this.label || 'Range'}\n\t\t\t\t\taria-valuetext=${String(this.value)}\n\t\t\t\t\tstyle=\"--range-progress: ${this.progress}\"\n\t\t\t\t\t@input=${(e: Event) => {\n\t\t\t\t\t\tthis.value = Number((e.target as HTMLInputElement).value)\n\t\t\t\t\t\tthis.markTouched()\n\t\t\t\t\t\tthis.emitChange({ value: this.value })\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-range': SchmancyRange\n\t}\n}\n"],"mappings":"4QAaO,IAAA,EAAA,cAA4B,EAAA,EAAkB,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0CAgDb,EAAA,KAAA,IACA,EAAA,KAAA,KACC,IAAA,KAAA,MAIlB,EAEzB,IAAA,UAAY,CACX,OAAY,KAAK,MAAQ,KAAK,MAAQ,KAAK,IAAM,KAAK,KAAQ,IAAvD,IAGR,WAAoB,EAAA,CACnB,MAAM,WAAW,EAAA,EACb,EAAQ,IAAI,QAAA,EAAY,EAAQ,IAAI,OAAA,GACvC,KAAK,WAAW,aAAa,OAAO,KAAK,MAAA,CAAA,CAK3C,eAAA,CACC,MAAA,CAAK,KAAK,MAAQ,KAAK,SAAiB,EAAA,CACjC,CAAC,CAAC,KAAK,KAAM,OAAO,KAAK,MAAA,CAAA,CAAA,CAGjC,QAAA,CACC,MAAO,GAAA,IAAI;;iBAGR,KAAK,UACC,EAAA,IAAI;;8EAE+D,KAAK,MAAA;yFACM,KAAK,MAAA;;;;;YAMlF,OAAO,KAAK,IAAA,CAAA;YACZ,OAAO,KAAK,IAAA,CAAA;aACX,OAAO,KAAK,KAAA,CAAA;cACX,OAAO,KAAK,MAAA,CAAA;iBACT,KAAK,SAAA;kBACJ,KAAK,OAAS,QAAA;sBACV,OAAO,KAAK,MAAA,CAAA;gCACF,KAAK,SAAA;cACtB,GAAA,CACT,KAAK,MAAQ,OAAQ,EAAE,OAA4B,MAAA,CACnD,KAAK,aAAA,CACL,KAAK,WAAW,CAAE,MAAO,KAAK,MAAA,CAAA,EAAA;;;0BAlDzB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,MAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,MAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAGjB,CAAE,KAAM,OAAQ,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,QAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAtD5B,iBAAA,CAAA,CAAiB,EAAA,CAAA,OAAA,eAAA,QAAA,gBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
package/dist/range.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./
|
|
1
|
+
import { o as e } from "./mixins-BWb9_e1s.js";
|
|
2
|
+
import { a as t } from "./active-host-BP0zy_Y9.js";
|
|
3
3
|
import { customElement as n, property as r } from "lit/decorators.js";
|
|
4
4
|
import { css as i, html as a } from "lit";
|
|
5
5
|
import { when as o } from "lit/directives/when.js";
|
|
6
|
-
var s = class extends e
|
|
7
|
-
constructor(...e) {
|
|
8
|
-
super(...e), this.min = 0, this.max = 1, this.step = .01, this.value = 0, this.disabled = !1;
|
|
9
|
-
}
|
|
10
|
-
static {
|
|
11
|
-
this.styles = [i`
|
|
6
|
+
var s = class extends e(i`
|
|
12
7
|
input[type='range'] {
|
|
13
8
|
-webkit-appearance: none;
|
|
14
9
|
appearance: none;
|
|
@@ -50,11 +45,19 @@ var s = class extends e {
|
|
|
50
45
|
background: var(--color-primary, #6750a4);
|
|
51
46
|
cursor: pointer;
|
|
52
47
|
}
|
|
53
|
-
`
|
|
48
|
+
`) {
|
|
49
|
+
constructor(...e) {
|
|
50
|
+
super(...e), this.min = 0, this.max = 1, this.step = .01, this.value = 0;
|
|
54
51
|
}
|
|
55
52
|
get progress() {
|
|
56
53
|
return (this.value - this.min) / (this.max - this.min) * 100 + "%";
|
|
57
54
|
}
|
|
55
|
+
willUpdate(e) {
|
|
56
|
+
super.willUpdate(e), (e.has("value") || e.has("name")) && this.internals?.setFormValue(String(this.value));
|
|
57
|
+
}
|
|
58
|
+
toFormEntries() {
|
|
59
|
+
return !this.name || this.disabled ? [] : [[this.name, String(this.value)]];
|
|
60
|
+
}
|
|
58
61
|
render() {
|
|
59
62
|
return a`
|
|
60
63
|
<div class="flex flex-col gap-1 w-full">
|
|
@@ -71,18 +74,19 @@ var s = class extends e {
|
|
|
71
74
|
.step=${String(this.step)}
|
|
72
75
|
.value=${String(this.value)}
|
|
73
76
|
?disabled=${this.disabled}
|
|
77
|
+
aria-label=${this.label || "Range"}
|
|
78
|
+
aria-valuetext=${String(this.value)}
|
|
74
79
|
style="--range-progress: ${this.progress}"
|
|
75
80
|
@input=${(e) => {
|
|
76
|
-
this.value = Number(e.target.value), this.
|
|
77
|
-
detail: { value: this.value },
|
|
78
|
-
bubbles: !0,
|
|
79
|
-
composed: !0
|
|
80
|
-
}));
|
|
81
|
+
this.value = Number(e.target.value), this.markTouched(), this.emitChange({ value: this.value });
|
|
81
82
|
}}
|
|
82
83
|
/>
|
|
83
84
|
</div>
|
|
84
85
|
`;
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
|
-
t([r({ type: Number })], s.prototype, "min", void 0), t([r({ type: Number })], s.prototype, "max", void 0), t([r({ type: Number })], s.prototype, "step", void 0), t([r({
|
|
88
|
+
t([r({ type: Number })], s.prototype, "min", void 0), t([r({ type: Number })], s.prototype, "max", void 0), t([r({ type: Number })], s.prototype, "step", void 0), t([r({
|
|
89
|
+
type: Number,
|
|
90
|
+
reflect: !0
|
|
91
|
+
})], s.prototype, "value", void 0), s = t([n("schmancy-range")], s);
|
|
88
92
|
export { s as SchmancyRange };
|
package/dist/range.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"range.js","names":[],"sources":["../src/range/range.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"range.js","names":[],"sources":["../src/form/fields/range/range.ts"],"sourcesContent":["import { css, html, type PropertyValues } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { when } from 'lit/directives/when.js'\nimport { SchmancyFormField } from '@mixins/index'\n\nexport type SchmancyRangeChangeEvent = CustomEvent<{ value: number }>\n\n/**\n * @element schmancy-range\n * Range input (numeric slider).\n * @fires change - Fires on value change with `{ value: number }`.\n */\n@customElement('schmancy-range')\nexport class SchmancyRange extends SchmancyFormField(css`\n\tinput[type='range'] {\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\twidth: 100%;\n\t\theight: 4px;\n\t\tborder-radius: 2px;\n\t\tbackground: linear-gradient(\n\t\t\tto right,\n\t\t\tvar(--color-primary, #6750a4) 0%,\n\t\t\tvar(--color-primary, #6750a4) var(--range-progress, 0%),\n\t\t\tcolor-mix(in srgb, var(--color-primary, #6750a4) 30%, transparent) var(--range-progress, 0%),\n\t\t\tcolor-mix(in srgb, var(--color-primary, #6750a4) 30%, transparent) 100%\n\t\t);\n\t\toutline: none;\n\t\tcursor: pointer;\n\t}\n\tinput[type='range']:disabled {\n\t\topacity: 0.38;\n\t\tcursor: not-allowed;\n\t}\n\tinput[type='range']::-webkit-slider-thumb {\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\twidth: 20px;\n\t\theight: 20px;\n\t\tborder-radius: 50%;\n\t\tbackground: var(--color-primary, #6750a4);\n\t\tcursor: pointer;\n\t\ttransition: box-shadow 0.1s ease;\n\t}\n\tinput[type='range']::-webkit-slider-thumb:hover {\n\t\tbox-shadow: 0 0 0 8px color-mix(in srgb, var(--color-primary, #6750a4) 12%, transparent);\n\t}\n\tinput[type='range']::-moz-range-thumb {\n\t\twidth: 20px;\n\t\theight: 20px;\n\t\tborder-radius: 50%;\n\t\tborder: none;\n\t\tbackground: var(--color-primary, #6750a4);\n\t\tcursor: pointer;\n\t}\n`) {\n\t// `formAssociated`, `internals`, `name`, `disabled`, `required`, `id`,\n\t// `label`, `error`, `validationMessage`, `validateOn`, touched/dirty/submitted,\n\t// `markTouched/markSubmitted`, `formResetCallback`, FIELD_CONNECT_EVENT\n\t// dispatch — all from the mixin.\n\n\t@property({ type: Number }) min: number = 0\n\t@property({ type: Number }) max: number = 1\n\t@property({ type: Number }) step: number = 0.01\n\n\t/** Numeric value — narrowed override of the mixin's wide value union. */\n\t@property({ type: Number, reflect: true })\n\toverride value: number = 0\n\n\tprivate get progress(): string {\n\t\treturn `${((this.value - this.min) / (this.max - this.min)) * 100}%`\n\t}\n\n\toverride willUpdate(changed: PropertyValues): void {\n\t\tsuper.willUpdate(changed)\n\t\tif (changed.has('value') || changed.has('name')) {\n\t\t\tthis.internals?.setFormValue(String(this.value))\n\t\t}\n\t}\n\n\t/** FormData contributes the value as a string (native range input convention). */\n\toverride toFormEntries(): Array<[string, FormDataEntryValue]> {\n\t\tif (!this.name || this.disabled) return []\n\t\treturn [[this.name, String(this.value)]]\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<div class=\"flex flex-col gap-1 w-full\">\n\t\t\t\t${when(\n\t\t\t\t\tthis.label,\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<div class=\"flex justify-between items-center\">\n\t\t\t\t\t\t\t<schmancy-typography type=\"label\" token=\"sm\" class=\"text-surface-on\">${this.label}</schmancy-typography>\n\t\t\t\t\t\t\t<schmancy-typography type=\"label\" token=\"sm\" class=\"text-surface-on opacity-60\">${this.value}</schmancy-typography>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\t\t\t\t<input\n\t\t\t\t\ttype=\"range\"\n\t\t\t\t\t.min=${String(this.min)}\n\t\t\t\t\t.max=${String(this.max)}\n\t\t\t\t\t.step=${String(this.step)}\n\t\t\t\t\t.value=${String(this.value)}\n\t\t\t\t\t?disabled=${this.disabled}\n\t\t\t\t\taria-label=${this.label || 'Range'}\n\t\t\t\t\taria-valuetext=${String(this.value)}\n\t\t\t\t\tstyle=\"--range-progress: ${this.progress}\"\n\t\t\t\t\t@input=${(e: Event) => {\n\t\t\t\t\t\tthis.value = Number((e.target as HTMLInputElement).value)\n\t\t\t\t\t\tthis.markTouched()\n\t\t\t\t\t\tthis.emitChange({ value: this.value })\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-range': SchmancyRange\n\t}\n}\n"],"mappings":";;;;;AAaO,IAAA,IAAA,cAA4B,EAAkB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAgDb,GAAA,KAAA,MACA,GAAA,KAAA,OACC,KAAA,KAAA,QAIlB;;CAEzB,IAAA,WAAY;AACX,UAAY,KAAK,QAAQ,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAQ,MAAvD;;CAGR,WAAoB,GAAA;AACnB,QAAM,WAAW,EAAA,GACb,EAAQ,IAAI,QAAA,IAAY,EAAQ,IAAI,OAAA,KACvC,KAAK,WAAW,aAAa,OAAO,KAAK,MAAA,CAAA;;CAK3C,gBAAA;AACC,SAAA,CAAK,KAAK,QAAQ,KAAK,WAAiB,EAAA,GACjC,CAAC,CAAC,KAAK,MAAM,OAAO,KAAK,MAAA,CAAA,CAAA;;CAGjC,SAAA;AACC,SAAO,CAAI;;MAEP,EACD,KAAK,aACC,CAAI;;8EAE+D,KAAK,MAAA;yFACM,KAAK,MAAA;;;;;YAMlF,OAAO,KAAK,IAAA,CAAA;YACZ,OAAO,KAAK,IAAA,CAAA;aACX,OAAO,KAAK,KAAA,CAAA;cACX,OAAO,KAAK,MAAA,CAAA;iBACT,KAAK,SAAA;kBACJ,KAAK,SAAS,QAAA;sBACV,OAAO,KAAK,MAAA,CAAA;gCACF,KAAK,SAAA;eACtB,MAAA;AACT,QAAK,QAAQ,OAAQ,EAAE,OAA4B,MAAA,EACnD,KAAK,aAAA,EACL,KAAK,WAAW,EAAE,OAAO,KAAK,OAAA,CAAA;IAAA;;;;;;GAlDlC,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,OAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,OAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,QAAA,KAAA,EAAA,EAAA,EAAA,CAG1B,EAAS;CAAE,MAAM;CAAQ,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,SAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAtD1C,EAAc,iBAAA,CAAA,EAAiB,EAAA;AAAA,SAAA,KAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reduced-motion-
|
|
1
|
+
{"version":3,"file":"reduced-motion-D7LqTUMn.js","names":[],"sources":["../src/directives/reduced-motion.ts"],"sourcesContent":["import { BehaviorSubject, fromEvent } from 'rxjs'\nimport { map, startWith } from 'rxjs/operators'\n\n/**\n * Shared reactive reduced-motion preference.\n *\n * All physics directives observe this — if the user toggles reduced motion\n * while the page is open, directives respond immediately.\n *\n * @example\n * ```ts\n * import { reducedMotion$ } from './reduced-motion'\n * if (reducedMotion$.value) return // skip animation\n * ```\n */\nconst mediaQuery = typeof window !== 'undefined'\n\t? window.matchMedia('(prefers-reduced-motion: reduce)')\n\t: undefined\n\nexport const reducedMotion$ = new BehaviorSubject<boolean>(mediaQuery?.matches ?? false)\n\n// Reactively listen for changes via RxJS\nif (mediaQuery) {\n\tfromEvent<MediaQueryListEvent>(mediaQuery, 'change').pipe(\n\t\tmap(e => e.matches),\n\t\tstartWith(mediaQuery.matches),\n\t).subscribe(matches => {\n\t\treducedMotion$.next(matches)\n\t})\n}\n"],"mappings":";;AAeA,IAAM,IAA+B,OAAX,SAAW,MAClC,OAAO,WAAW,mCAAA,GAAA,KAClB,GAEU,IAAiB,IAAI,EAAyB,GAAY,WAAA,CAAW,EAAA;AAG9E,KACH,EAA+B,GAAY,SAAA,CAAU,KACpD,GAAI,MAAK,EAAE,QAAA,EACX,EAAU,EAAW,QAAA,CAAA,CACpB,WAAU,MAAA;AACX,GAAe,KAAK,EAAA;EAAA;AAAA,SAAA,KAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reduced-motion-
|
|
1
|
+
{"version":3,"file":"reduced-motion-Dzfp_w5x.cjs","names":[],"sources":["../src/directives/reduced-motion.ts"],"sourcesContent":["import { BehaviorSubject, fromEvent } from 'rxjs'\nimport { map, startWith } from 'rxjs/operators'\n\n/**\n * Shared reactive reduced-motion preference.\n *\n * All physics directives observe this — if the user toggles reduced motion\n * while the page is open, directives respond immediately.\n *\n * @example\n * ```ts\n * import { reducedMotion$ } from './reduced-motion'\n * if (reducedMotion$.value) return // skip animation\n * ```\n */\nconst mediaQuery = typeof window !== 'undefined'\n\t? window.matchMedia('(prefers-reduced-motion: reduce)')\n\t: undefined\n\nexport const reducedMotion$ = new BehaviorSubject<boolean>(mediaQuery?.matches ?? false)\n\n// Reactively listen for changes via RxJS\nif (mediaQuery) {\n\tfromEvent<MediaQueryListEvent>(mediaQuery, 'change').pipe(\n\t\tmap(e => e.matches),\n\t\tstartWith(mediaQuery.matches),\n\t).subscribe(matches => {\n\t\treducedMotion$.next(matches)\n\t})\n}\n"],"mappings":"kFAeA,IAAM,EAA+B,OAAX,OAAW,IAClC,OAAO,WAAW,mCAAA,CAAA,IAClB,GAEU,EAAiB,IAAI,EAAA,gBAAyB,GAAY,SAAA,CAAW,EAAA,CAG9E,IACH,EAAA,EAAA,WAA+B,EAAY,SAAA,CAAU,MAAA,EAAA,EAAA,KAChD,GAAK,EAAE,QAAA,EAAQ,EAAA,EAAA,WACT,EAAW,QAAA,CAAA,CACpB,UAAU,GAAA,CACX,EAAe,KAAK,EAAA,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rxjs-utils-
|
|
1
|
+
{"version":3,"file":"rxjs-utils-D9U4MW0Q.js","names":[],"sources":["../src/rxjs-utils/mutation-observer.ts","../node_modules/ts-is-present/lib/index.js","../src/rxjs-utils/waitForElements.ts"],"sourcesContent":["import { Observable } from 'rxjs'\n\nexport const mutationObserver = (\n\ttarget: HTMLElement,\n\tconfig: MutationObserverInit = {\n\t\tattributes: true,\n\t\tchildList: true,\n\t\tsubtree: true,\n\t},\n): Observable<MutationRecord[]> => {\n\treturn new Observable(observer => {\n\t\tconst mutation = new MutationObserver(mutations => {\n\t\t\tobserver.next(mutations)\n\t\t})\n\t\tmutation.observe(target, config)\n\t\tconst unsubscribe = () => {\n\t\t\tmutation.disconnect()\n\t\t}\n\t\treturn unsubscribe\n\t})\n}\nexport default mutationObserver\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.hasValueAtKey = exports.hasPresentKey = exports.isFilled = exports.isDefined = exports.isPresent = void 0;\nfunction isPresent(t) {\n return t !== undefined && t !== null;\n}\nexports.isPresent = isPresent;\nfunction isDefined(t) {\n return t !== undefined;\n}\nexports.isDefined = isDefined;\nfunction isFilled(t) {\n return t !== null;\n}\nexports.isFilled = isFilled;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a defined non-null value under the key `k`.\n *\n * @example\n * ```ts\n * const filesWithUrl = files.filter(file => file.url);\n * files[0].url // In this case, TS might still treat this as undefined/null\n *\n * const filesWithUrl = files.filter(hasPresentKey(\"url\"));\n * files[0].url // TS will know that this is present\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasPresentKey(k) {\n return function (a) {\n return a[k] !== undefined && a[k] !== null;\n };\n}\nexports.hasPresentKey = hasPresentKey;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a specific value V under a key `k`.\n *\n * @example\n * ```ts\n * type File = { type: \"image\", imageUrl: string } | { type: \"pdf\", pdfUrl: string };\n * const files: File[] = [];\n *\n * const imageFiles = files.filter(file => file.type === \"image\");\n * files[0].type // In this case, TS will still treat it as `\"image\" | \"pdf\"`\n *\n * const filesWithUrl = files.filter(hasValueKey(\"type\", \"image\" as const));\n * files[0].type // TS will now know that this is \"image\"\n * files[0].imageUrl // TS will know this is present, because already it excluded the other union members.\n *\n * Note: the cast `as const` is necessary, otherwise TS will only know that type is a string.\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasValueAtKey(k, v) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function (a) {\n return a[k] === v;\n };\n}\nexports.hasValueAtKey = hasValueAtKey;\n//# sourceMappingURL=index.js.map","import { filter, map, startWith, take, tap, timeout } from 'rxjs'\nimport { isPresent } from 'ts-is-present'\nimport observeOnMutation from './mutation-observer'\n\n/**\n * @returns An observable that emits the elements when they are found\n * @description This function is useful when you want to wait for multiple elements to appear\n * @example waitForElements(['button', 'input']).subscribe(([button, input]) => button.click())\n * @returns\n */\nexport default function waitForElements(\n /**\n * @param selectors The selectors to use to find the elements\n * @type { string[] }\n * @description The order of the elements in the array is the same as the order of the elements in the emitted array\n */\n selectors: string[],\n /**\n * @param timeoutAfter How long to wait for the elements to appear before throwing an error\n * @default 5000\n * @type { number | undefined }\n * @description If you don't want to wait for the elements to appear, pass `undefined` as the second argument\n */\n timeoutAfter = 5000,\n) {\n return observeOnMutation(document.body).pipe(\n startWith(document.body),\n filter(() => selectors.every(s => !!document.querySelector(s))),\n take(1),\n map(() => selectors.map(s => document.querySelector(s)).filter(isPresent)), // why filter again? see https://github.com/Microsoft/TypeScript/issues/16069\n map(elements => {\n if (elements.length === selectors.length) {\n return elements\n } else {\n throw new Error('Not all elements were found')\n }\n }),\n timeoutAfter ? timeout(timeoutAfter) : tap(),\n )\n}\n"],"x_google_ignoreList":[1],"mappings":";;AAEA,IAAa,KACZ,GACA,IAA+B;CAC9B,YAAA,CAAY;CACZ,WAAA,CAAW;CACX,SAAA,CAAS;CAAA,KAGH,IAAI,GAAW,MAAA;CACrB,IAAM,IAAW,IAAI,kBAAiB,MAAA;AACrC,IAAS,KAAK,EAAA;GAAA;AAMf,QAJA,EAAS,QAAQ,GAAQ,EAAA,QACnB;AACL,IAAS,YAAA;;EAAA;AAAA,GAAA,MAAA;ACfZ,QAAO,eAAe,GAAS,KAAc,EAAE,OAAA,CAAO,GAAA,CAAA,EACtD,EAAQ,gBAAgB,EAAQ,gBAAgB,EAAQ,WAAW,EAAQ,YAAY,EAAQ,YAAA,KAAiB,GAIhH,EAAQ,YAHR,SAAmB,GAAA;AACf,SAAO,KAAA;IAMX,EAAQ,YAHR,SAAmB,GAAA;AACf,SAAO,MAAP,KAAa;IAMjB,EAAQ,WAHR,SAAkB,GAAA;AACd,SAAO,MAAM;IAwBjB,EAAQ,gBALR,SAAuB,GAAA;AACnB,SAAO,SAAU,GAAA;AACb,UAAO,EAAE,OAAT,KAAgB,KAAa,EAAE,OAAO;;IAgC9C,EAAQ,gBANR,SAAuB,GAAG,GAAA;AAEtB,SAAO,SAAU,GAAA;AACb,UAAO,EAAE,OAAO;;;EAAA,EAAA;AAAA,SAAA,KAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rxjs-utils-
|
|
1
|
+
{"version":3,"file":"rxjs-utils-kWPShgKu.cjs","names":[],"sources":["../src/rxjs-utils/mutation-observer.ts","../node_modules/ts-is-present/lib/index.js","../src/rxjs-utils/waitForElements.ts"],"sourcesContent":["import { Observable } from 'rxjs'\n\nexport const mutationObserver = (\n\ttarget: HTMLElement,\n\tconfig: MutationObserverInit = {\n\t\tattributes: true,\n\t\tchildList: true,\n\t\tsubtree: true,\n\t},\n): Observable<MutationRecord[]> => {\n\treturn new Observable(observer => {\n\t\tconst mutation = new MutationObserver(mutations => {\n\t\t\tobserver.next(mutations)\n\t\t})\n\t\tmutation.observe(target, config)\n\t\tconst unsubscribe = () => {\n\t\t\tmutation.disconnect()\n\t\t}\n\t\treturn unsubscribe\n\t})\n}\nexport default mutationObserver\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.hasValueAtKey = exports.hasPresentKey = exports.isFilled = exports.isDefined = exports.isPresent = void 0;\nfunction isPresent(t) {\n return t !== undefined && t !== null;\n}\nexports.isPresent = isPresent;\nfunction isDefined(t) {\n return t !== undefined;\n}\nexports.isDefined = isDefined;\nfunction isFilled(t) {\n return t !== null;\n}\nexports.isFilled = isFilled;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a defined non-null value under the key `k`.\n *\n * @example\n * ```ts\n * const filesWithUrl = files.filter(file => file.url);\n * files[0].url // In this case, TS might still treat this as undefined/null\n *\n * const filesWithUrl = files.filter(hasPresentKey(\"url\"));\n * files[0].url // TS will know that this is present\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasPresentKey(k) {\n return function (a) {\n return a[k] !== undefined && a[k] !== null;\n };\n}\nexports.hasPresentKey = hasPresentKey;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a specific value V under a key `k`.\n *\n * @example\n * ```ts\n * type File = { type: \"image\", imageUrl: string } | { type: \"pdf\", pdfUrl: string };\n * const files: File[] = [];\n *\n * const imageFiles = files.filter(file => file.type === \"image\");\n * files[0].type // In this case, TS will still treat it as `\"image\" | \"pdf\"`\n *\n * const filesWithUrl = files.filter(hasValueKey(\"type\", \"image\" as const));\n * files[0].type // TS will now know that this is \"image\"\n * files[0].imageUrl // TS will know this is present, because already it excluded the other union members.\n *\n * Note: the cast `as const` is necessary, otherwise TS will only know that type is a string.\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasValueAtKey(k, v) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function (a) {\n return a[k] === v;\n };\n}\nexports.hasValueAtKey = hasValueAtKey;\n//# sourceMappingURL=index.js.map","import { filter, map, startWith, take, tap, timeout } from 'rxjs'\nimport { isPresent } from 'ts-is-present'\nimport observeOnMutation from './mutation-observer'\n\n/**\n * @returns An observable that emits the elements when they are found\n * @description This function is useful when you want to wait for multiple elements to appear\n * @example waitForElements(['button', 'input']).subscribe(([button, input]) => button.click())\n * @returns\n */\nexport default function waitForElements(\n /**\n * @param selectors The selectors to use to find the elements\n * @type { string[] }\n * @description The order of the elements in the array is the same as the order of the elements in the emitted array\n */\n selectors: string[],\n /**\n * @param timeoutAfter How long to wait for the elements to appear before throwing an error\n * @default 5000\n * @type { number | undefined }\n * @description If you don't want to wait for the elements to appear, pass `undefined` as the second argument\n */\n timeoutAfter = 5000,\n) {\n return observeOnMutation(document.body).pipe(\n startWith(document.body),\n filter(() => selectors.every(s => !!document.querySelector(s))),\n take(1),\n map(() => selectors.map(s => document.querySelector(s)).filter(isPresent)), // why filter again? see https://github.com/Microsoft/TypeScript/issues/16069\n map(elements => {\n if (elements.length === selectors.length) {\n return elements\n } else {\n throw new Error('Not all elements were found')\n }\n }),\n timeoutAfter ? timeout(timeoutAfter) : tap(),\n )\n}\n"],"x_google_ignoreList":[1],"mappings":"8DAEA,IAAa,GACZ,EACA,EAA+B,CAC9B,WAAA,CAAY,EACZ,UAAA,CAAW,EACX,QAAA,CAAS,EAAA,GAGH,IAAI,EAAA,WAAW,GAAA,CACrB,IAAM,EAAW,IAAI,iBAAiB,GAAA,CACrC,EAAS,KAAK,EAAA,EAAA,CAMf,OAJA,EAAS,QAAQ,EAAQ,EAAA,KACnB,CACL,EAAS,YAAA,GAAA,CAAA,EAAA,EAAA,GAAA,CCfZ,OAAO,eAAe,EAAS,IAAc,CAAE,MAAA,CAAO,EAAA,CAAA,CACtD,EAAQ,cAAgB,EAAQ,cAAgB,EAAQ,SAAW,EAAQ,UAAY,EAAQ,UAAA,IAAiB,GAIhH,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,GAAA,MAMX,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,IAAP,IAAa,IAMjB,EAAQ,SAHR,SAAkB,EAAA,CACd,OAAO,IAAM,MAwBjB,EAAQ,cALR,SAAuB,EAAA,CACnB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAT,IAAgB,IAAa,EAAE,KAAO,OAgC9C,EAAQ,cANR,SAAuB,EAAG,EAAA,CAEtB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAO,KAAA,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
package/dist/rxjs-utils.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rxjs-utils-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rxjs-utils-kWPShgKu.cjs`);exports.mutationObserver=e.t;
|
package/dist/rxjs-utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./rxjs-utils-
|
|
1
|
+
import { t as e } from "./rxjs-utils-D9U4MW0Q.js";
|
|
2
2
|
export { e as mutationObserver };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./
|
|
1
|
+
import { c as e } from "./mixins-BWb9_e1s.js";
|
|
2
|
+
import { a as t } from "./active-host-BP0zy_Y9.js";
|
|
3
3
|
import { debounceTime as n, filter as r, fromEvent as i, takeUntil as a } from "rxjs";
|
|
4
4
|
import { customElement as o, property as s } from "lit/decorators.js";
|
|
5
5
|
import { css as c, html as l } from "lit";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-BotoGcMU.js","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * A custom scrollable container with enhanced features.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`];\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scroll-CG5up5oy.js","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * A custom scrollable container with enhanced features.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`];\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-
|
|
1
|
+
require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BOOu6q2n.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`rxjs`),r=require(`lit/decorators.js`),i=require(`lit`);var a=class extends e.c{constructor(...e){super(...e),this.hide=!1,this.direction=`both`,this.debounce=10}static{this.styles=[i.css`
|
|
2
2
|
:host {
|
|
3
3
|
/* Flexible sizing for different layout contexts */
|
|
4
4
|
width: 100%;
|
|
@@ -23,4 +23,4 @@ require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-DvAYa-F7.cjs`),t=requi
|
|
|
23
23
|
:host([hide])::-webkit-scrollbar {
|
|
24
24
|
display: none; /* Chrome, Safari, and Opera */
|
|
25
25
|
}
|
|
26
|
-
`]}get scroller(){return this}scrollTo(e,t){typeof e==`number`?super.scrollTo({top:e,behavior:t?`smooth`:`auto`}):e?super.scrollTo(e):super.scrollTo({top:0,left:0,behavior:`auto`})}scrollToLeft(e,t=`auto`){super.scrollTo({left:e,behavior:t})}connectedCallback(){super.connectedCallback(),this.updateScrollingStyles(),this.updateLayoutContext(),this.setAttribute(`part`,`scroller`)}updateScrollingStyles(){this.direction===`horizontal`?(this.style.setProperty(`overflow-y`,`hidden`),this.style.setProperty(`overflow-x`,`auto`)):this.direction===`vertical`?(this.style.setProperty(`overflow-y`,`auto`),this.style.setProperty(`overflow-x`,`hidden`)):(this.style.setProperty(`overflow-y`,`auto`),this.style.setProperty(`overflow-x`,`auto`))}updateLayoutContext(){requestAnimationFrame(()=>{let e=this.parentElement;if(e){let t=getComputedStyle(e);t.display===`flex`||t.display===`inline-flex`?this.classList.remove(`explicit-height`):this.classList.add(`explicit-height`)}else this.classList.add(`explicit-height`)})}updated(e){super.updated(e),e.has(`direction`)&&this.updateScrollingStyles(),this.updateLayoutContext()}firstUpdated(){(0,n.fromEvent)(this.scroller,`scroll`,{passive:!0}).pipe((0,n.debounceTime)(this.debounce),(0,n.takeUntil)(this.disconnecting)).subscribe(e=>{let t=this.scroller.scrollTop,n=this.scroller.scrollHeight,r=this.scroller.clientHeight,i=this.scroller.scrollLeft,a=this.scroller.scrollWidth,o=this.scroller.clientWidth;this.dispatchEvent(new CustomEvent(`scroll`,{detail:{scrollTop:t,scrollHeight:n,clientHeight:r,e,scrollLeft:i,scrollWidth:a,clientWidth:o},bubbles:!0,composed:!0}))}),(0,n.fromEvent)(window,`@schmancy:scrollTo`).pipe((0,n.filter)(e=>this.name!==void 0&&e.detail.name===this.name),(0,n.takeUntil)(this.disconnecting)).subscribe(e=>{if(e.detail.action===`scrollTo`&&typeof e.detail.top==`number`){let t={behavior:`smooth`,top:e.detail.top};typeof e.detail.left==`number`&&(t.left=e.detail.left),this.scrollTo(t)}})}render(){return i.html`<slot></slot>`}};t.
|
|
26
|
+
`]}get scroller(){return this}scrollTo(e,t){typeof e==`number`?super.scrollTo({top:e,behavior:t?`smooth`:`auto`}):e?super.scrollTo(e):super.scrollTo({top:0,left:0,behavior:`auto`})}scrollToLeft(e,t=`auto`){super.scrollTo({left:e,behavior:t})}connectedCallback(){super.connectedCallback(),this.updateScrollingStyles(),this.updateLayoutContext(),this.setAttribute(`part`,`scroller`)}updateScrollingStyles(){this.direction===`horizontal`?(this.style.setProperty(`overflow-y`,`hidden`),this.style.setProperty(`overflow-x`,`auto`)):this.direction===`vertical`?(this.style.setProperty(`overflow-y`,`auto`),this.style.setProperty(`overflow-x`,`hidden`)):(this.style.setProperty(`overflow-y`,`auto`),this.style.setProperty(`overflow-x`,`auto`))}updateLayoutContext(){requestAnimationFrame(()=>{let e=this.parentElement;if(e){let t=getComputedStyle(e);t.display===`flex`||t.display===`inline-flex`?this.classList.remove(`explicit-height`):this.classList.add(`explicit-height`)}else this.classList.add(`explicit-height`)})}updated(e){super.updated(e),e.has(`direction`)&&this.updateScrollingStyles(),this.updateLayoutContext()}firstUpdated(){(0,n.fromEvent)(this.scroller,`scroll`,{passive:!0}).pipe((0,n.debounceTime)(this.debounce),(0,n.takeUntil)(this.disconnecting)).subscribe(e=>{let t=this.scroller.scrollTop,n=this.scroller.scrollHeight,r=this.scroller.clientHeight,i=this.scroller.scrollLeft,a=this.scroller.scrollWidth,o=this.scroller.clientWidth;this.dispatchEvent(new CustomEvent(`scroll`,{detail:{scrollTop:t,scrollHeight:n,clientHeight:r,e,scrollLeft:i,scrollWidth:a,clientWidth:o},bubbles:!0,composed:!0}))}),(0,n.fromEvent)(window,`@schmancy:scrollTo`).pipe((0,n.filter)(e=>this.name!==void 0&&e.detail.name===this.name),(0,n.takeUntil)(this.disconnecting)).subscribe(e=>{if(e.detail.action===`scrollTo`&&typeof e.detail.top==`number`){let t={behavior:`smooth`,top:e.detail.top};typeof e.detail.left==`number`&&(t.left=e.detail.left),this.scrollTo(t)}})}render(){return i.html`<slot></slot>`}};t.a([(0,r.property)({type:Boolean,reflect:!0})],a.prototype,`hide`,void 0),t.a([(0,r.property)({type:String,reflect:!0})],a.prototype,`name`,void 0),t.a([(0,r.property)({type:String,reflect:!0})],a.prototype,`direction`,void 0),t.a([(0,r.property)({type:Number})],a.prototype,`debounce`,void 0),a=t.a([(0,r.customElement)(`schmancy-scroll`)],a),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-CmhmUebp.cjs","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * A custom scrollable container with enhanced features.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`];\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scroll-D8vBF_gY.cjs","names":[],"sources":["../src/layout/scroll/scroll.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { debounceTime, filter, fromEvent, takeUntil } from 'rxjs'\n\n/**\n * Custom scroll event interface for the SchmancyScroll component.\n * Contains detailed information about the scroll state.\n */\nexport interface SchmancyScrollEvent\n\textends CustomEvent<{\n\t\t/** Current scroll position from the top */\n\t\tscrollTop: number\n\t\t/** Total scrollable height of the content */\n\t\tscrollHeight: number\n\t\t/** Visible height of the container */\n\t\tclientHeight: number\n\t\t/** Original scroll event */\n\t\te: Event\n\t\t/** Current scroll position from the left (for horizontal scrolling) */\n\t\tscrollLeft?: number\n\t\t/** Total scrollable width of the content (for horizontal scrolling) */\n\t\tscrollWidth?: number\n\t\t/** Visible width of the container (for horizontal scrolling) */\n\t\tclientWidth?: number\n\t}> {}\n\n/**\n * Command event interface for controlling SchmancyScroll components\n */\nexport interface SchmancyScrollCommandEvent\n\textends CustomEvent<{\n\t\t/** Target component name */\n\t\tname: string\n\t\t/** Command action to perform */\n\t\taction: 'scrollTo'\n\t\t/** Scroll position for scrollTo action */\n\t\ttop: number\n\t\t/** Horizontal scroll position for scrollTo action (optional) */\n\t\tleft?: number\n\t}> {}\n\n// Augment the HTMLElementEventMap to include our custom events\ndeclare global {\n\tinterface HTMLElementEventMap {\n\t\tscroll: SchmancyScrollEvent\n\t\t'schmancy-scroll-command': SchmancyScrollCommandEvent\n\t}\n}\n\n/**\n * A custom scrollable container with enhanced features.\n *\n * @fires {SchmancyScrollEvent} scroll - Fired when scrolling occurs (with a configurable debounce)\n * @slot - Default slot for content to be scrolled\n * @csspart scroller - The inner scrollable div element\n *\n * @example\n * ```html\n * <schmancy-scroll hide name=\"main-content\">\n * <div>Scrollable content goes here</div>\n * </schmancy-scroll>\n * ```\n *\n * @example\n * ```html\n * <schmancy-scroll direction=\"horizontal\" hide name=\"image-carousel\">\n * <div class=\"flex\">\n * <img src=\"image1.jpg\" alt=\"Image 1\">\n * <img src=\"image2.jpg\" alt=\"Image 2\">\n * </div>\n * </schmancy-scroll>\n * ```\n *\n * @example Programmatic scroll with Lit ref\n * ```typescript\n * private scrollRef = createRef<HTMLElement>()\n *\n * // In template:\n * html`<schmancy-scroll ${ref(this.scrollRef)}>...</schmancy-scroll>`\n *\n * // Scroll to top (smooth — host has scroll-behavior: smooth):\n * this.scrollRef.value?.scrollTo({ top: 0 })\n * ```\n */\n@customElement('schmancy-scroll')\nexport class SchmancyScroll extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\t/* Flexible sizing for different layout contexts */\n\t\twidth: 100%;\n\t\tmin-height: 0; /* Allow flex shrinking */\n\t\tflex: 1; /* Grow in flex containers */\n\t\tbox-sizing: border-box; /* Ensures proper sizing */\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tscroll-behavior: smooth;\n\t\toverscroll-behavior-x: contain;\n\t\toverscroll-behavior-y: auto;\n\t}\n\t/* Fallback for non-flex contexts */\n\t:host(.explicit-height) {\n\t\theight: 100%;\n\t\tflex: none;\n\t}\n\t:host([hide]) {\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t:host([hide])::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, and Opera */\n\t}\n`];\n\t/**\n\t * Determines whether the scrollbar is hidden.\n\t *\n\t * When `hide` is true, the host element's scrollbars are hidden\n\t * in supported browsers using CSS.\n\t *\n\t * @attr hide\n\t * @example <schmancy-scroll hide></schmancy-scroll>\n\t */\n\t@property({ type: Boolean, reflect: true })\n\tpublic hide = false\n\n\t/**\n\t * Optional name identifier for the component.\n\t * Used for targeting this specific component with global events.\n\t *\n\t * @attr name\n\t * @example <schmancy-scroll name=\"main-content\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic name?: string\n\n\t/**\n\t * Direction of scrolling: vertical, horizontal, or both.\n\t * - vertical: Only allows vertical scrolling\n\t * - horizontal: Only allows horizontal scrolling\n\t * - both: Allows both horizontal and vertical scrolling (default)\n\t *\n\t * @attr direction\n\t * @example <schmancy-scroll direction=\"horizontal\"></schmancy-scroll>\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic direction: 'vertical' | 'horizontal' | 'both' = 'both'\n\n\t/**\n\t * Reference to the scrollable element (the host element itself)\n\t * @public\n\t */\n\tget scroller(): HTMLElement {\n\t\treturn this\n\t}\n\n\t/**\n\t * Debounce time in milliseconds for the scroll event.\n\t * Higher values reduce the frequency of scroll events being dispatched.\n\t *\n\t * @attr debounce\n\t * @example <schmancy-scroll debounce=\"50\"></schmancy-scroll>\n\t */\n\t@property({ type: Number })\n\tpublic debounce = 10\n\n\t/**\n\t * Scrolls the container to the specified position\n\t * @param options - ScrollToOptions or a number representing the top position\n\t * @param top - For backward compatibility, if options is a number, this is treated as \"behavior\"\n\t */\n\tpublic override scrollTo(options?: ScrollToOptions | number, top?: number): void {\n\t\tif (typeof options === 'number') {\n\t\t\tsuper.scrollTo({ top: options, behavior: top ? 'smooth' : 'auto' })\n\t\t} else if (options) {\n\t\t\tsuper.scrollTo(options)\n\t\t} else {\n\t\t\tsuper.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the container horizontally to the specified position\n\t * @param left - The horizontal position to scroll to (in pixels)\n\t * @param behavior - The scroll behavior ('auto' or 'smooth')\n\t */\n\tpublic scrollToLeft(left: number, behavior: ScrollBehavior = 'auto'): void {\n\t\tsuper.scrollTo({ left, behavior })\n\t}\n\n\t/**\n\t * Called when the component is connected to the DOM\n\t * Applies scrolling styles directly to the host element\n\t * @protected\n\t */\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.updateScrollingStyles()\n\t\tthis.updateLayoutContext()\n\t\t// Set the part attribute on the host element\n\t\tthis.setAttribute('part', 'scroller')\n\t}\n\n\t/**\n\t * Updates the overflow styles based on the direction property\n\t * @private\n\t */\n\tprivate updateScrollingStyles(): void {\n\t\t// Apply overflow styles based on direction\n\t\tif (this.direction === 'horizontal') {\n\t\t\tthis.style.setProperty('overflow-y', 'hidden')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t} else if (this.direction === 'vertical') {\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'hidden')\n\t\t} else {\n\t\t\t// both\n\t\t\tthis.style.setProperty('overflow-y', 'auto')\n\t\t\tthis.style.setProperty('overflow-x', 'auto')\n\t\t}\n\t}\n\n\t/**\n\t * Updates the layout context based on parent container type\n\t * @private\n\t */\n\tprivate updateLayoutContext(): void {\n\t\t// Use requestAnimationFrame to ensure DOM is fully rendered\n\t\trequestAnimationFrame(() => {\n\t\t\t// Check if parent is a flex container\n\t\t\tconst parent = this.parentElement\n\t\t\tif (parent) {\n\t\t\t\tconst parentStyles = getComputedStyle(parent)\n\t\t\t\tconst isFlexParent = parentStyles.display === 'flex' || parentStyles.display === 'inline-flex'\n\n\t\t\t\t// For debugging - remove in production\n\t\t\t\tconsole.debug('schmancy-scroll parent detection:', {\n\t\t\t\t\tparent: parent.tagName,\n\t\t\t\t\tdisplay: parentStyles.display,\n\t\t\t\t\tisFlexParent,\n\t\t\t\t})\n\n\t\t\t\t// Apply appropriate class based on parent layout\n\t\t\t\tif (isFlexParent) {\n\t\t\t\t\tthis.classList.remove('explicit-height')\n\t\t\t\t} else {\n\t\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default to explicit height if no parent\n\t\t\t\tthis.classList.add('explicit-height')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Called when properties change\n\t * @protected\n\t */\n\tprotected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n\t\tsuper.updated(changedProperties)\n\t\t// Update styles if direction changes\n\t\tif (changedProperties.has('direction')) {\n\t\t\tthis.updateScrollingStyles()\n\t\t}\n\t\t// Always update layout context in case parent layout changed\n\t\tthis.updateLayoutContext()\n\t}\n\n\t/**\n\t * Called after the component's first update\n\t * Sets up the scroll event listener with debouncing\n\t * @protected\n\t */\n\tprotected firstUpdated(): void {\n\t\t// Set up scroll event listening with debounce\n\t\tfromEvent(this.scroller, 'scroll', {\n\t\t\tpassive: true,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tdebounceTime(this.debounce),\n\t\t\t\ttakeUntil(this.disconnecting), // Unsubscribe when the element is destroyed\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\t// Always include the original required properties for backward compatibility\n\t\t\t\tconst scrollTop = this.scroller.scrollTop\n\t\t\t\tconst scrollHeight = this.scroller.scrollHeight\n\t\t\t\tconst clientHeight = this.scroller.clientHeight\n\n\t\t\t\t// Include horizontal scroll information as optional properties\n\t\t\t\tconst scrollLeft = this.scroller.scrollLeft\n\t\t\t\tconst scrollWidth = this.scroller.scrollWidth\n\t\t\t\tconst clientWidth = this.scroller.clientWidth\n\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('scroll', {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\t// Original required properties first\n\t\t\t\t\t\t\tscrollTop,\n\t\t\t\t\t\t\tscrollHeight,\n\t\t\t\t\t\t\tclientHeight,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t// New optional properties last\n\t\t\t\t\t\t\tscrollLeft,\n\t\t\t\t\t\t\tscrollWidth,\n\t\t\t\t\t\t\tclientWidth,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}) as SchmancyScrollEvent,\n\t\t\t\t)\n\t\t\t})\n\n\t\t// Set up global command event listener\n\t\tfromEvent<SchmancyScrollCommandEvent>(window, '@schmancy:scrollTo')\n\t\t\t.pipe(\n\t\t\t\t// Only process events targeting this component by name\n\t\t\t\tfilter(e => this.name !== undefined && e.detail.name === this.name),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(e => {\n\t\t\t\tif (e.detail.action === 'scrollTo' && typeof e.detail.top === 'number') {\n\t\t\t\t\tconst options: ScrollToOptions = {\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t\ttop: e.detail.top, // Required for backward compatibility\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add optional left position if provided\n\t\t\t\t\tif (typeof e.detail.left === 'number') {\n\t\t\t\t\t\toptions.left = e.detail.left\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scrollTo(options)\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t/**\n\t * Renders the component template\n\t * @returns {TemplateResult} The template to render\n\t * @protected\n\t */\n\tprotected render() {\n\t\t// Only render the slot, all styling is applied to the host\n\t\treturn html`<slot></slot>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-scroll': SchmancyScroll\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-BLCRsxIC.cjs","names":[],"sources":["../src/utils/search.ts"],"sourcesContent":["/**\n * Options for configuring similarity calculation behavior.\n */\nexport interface SimilarityOptions {\n\t/**\n\t * Whether to remove accents/diacritics during normalization.\n\t * @default true\n\t */\n\tnormalizeAccents?: boolean\n\n\t/**\n\t * Whether to include word-level Jaccard similarity in fuzzy matching.\n\t * Useful for matching phrases with different word orders.\n\t * @default true\n\t */\n\tincludeWordJaccard?: boolean\n\n\t/**\n\t * Maximum Levenshtein distance threshold for early termination.\n\t * Improves performance for very dissimilar strings.\n\t * Set to 0 to disable early termination.\n\t * @default 0 (disabled)\n\t */\n\tmaxLevenshteinDistance?: number\n}\n\n// Scoring weights as named constants for clarity and maintainability\nconst SCORE_WEIGHT_DICE = 0.45\nconst SCORE_WEIGHT_LEVENSHTEIN = 0.45\nconst SCORE_WEIGHT_ANAGRAM = 0.3\nconst SCORE_WEIGHT_JACCARD = 0.4\n\n// Word splitting pattern - defined once for reuse\nconst WORD_SPLIT_PATTERN = /[\\s\\-_.,;:!?()[\\]{}]+/\n\n/**\n * Calculate similarity score between two strings.\n * Returns a value between 0 (no match) and 1 (exact match).\n * Optimized for autocomplete with prioritization of start matches and whole words.\n *\n * Scoring tiers (higher scores = better matches):\n * - 1.00: Exact match\n * - 0.95-1.00: Target starts with query (autocomplete-style)\n * - 0.765-0.85: Query matches start of a word in target\n * - 0.56-0.70: Query is substring of target\n * - 0.50: Query is subsequence of target\n * - 0.00-0.50: Fuzzy matching (typos, similar words, character overlap)\n *\n * @param query The search query string\n * @param target The target string to compare against\n * @param options Optional configuration for similarity calculation\n * @returns A similarity score from 0 to 1\n *\n * @example\n * similarity('john', 'John Doe') // 0.975+ (starts with)\n * similarity('doe', 'John Doe') // 0.765+ (word boundary)\n * similarity('jo', 'John Doe') // 0.95+ (starts with)\n * similarity('jhn', 'John Doe') // 0.3-0.5 (subsequence/fuzzy)\n */\nexport function similarity(query: string, target: string, options?: SimilarityOptions): number {\n\t// Handle edge cases\n\tif (!query || !target) return 0\n\tif (query === target) return 1\n\n\t// Default options\n\tconst opts: Required<SimilarityOptions> = {\n\t\tnormalizeAccents: options?.normalizeAccents ?? true,\n\t\tincludeWordJaccard: options?.includeWordJaccard ?? true,\n\t\tmaxLevenshteinDistance: options?.maxLevenshteinDistance ?? 0,\n\t}\n\n\t// Normalize strings for comparison\n\tconst normalizedQuery = normalizeString(query, opts.normalizeAccents)\n\tconst normalizedTarget = normalizeString(target, opts.normalizeAccents)\n\n\t// 1. Exact match (case-insensitive, accent-insensitive)\n\tif (normalizedQuery === normalizedTarget) return 1\n\n\t// 2. Target starts with query (highest priority for autocomplete)\n\tif (normalizedTarget.startsWith(normalizedQuery)) {\n\t\t// Give higher score to shorter targets (more precise matches)\n\t\tconst lengthRatio = normalizedQuery.length / normalizedTarget.length\n\t\treturn 0.95 + (lengthRatio * 0.05) // Score between 0.95 and 1.0\n\t}\n\n\t// 3. Word boundary match (query matches start of any word in target)\n\tconst words = normalizedTarget.split(WORD_SPLIT_PATTERN).filter(w => w.length > 0)\n\tfor (let i = 0; i < words.length; i++) {\n\t\tif (words[i].startsWith(normalizedQuery)) {\n\t\t\t// Score based on which word matched (earlier words score higher)\n\t\t\tconst wordPositionScore = 1 - (i / words.length) * 0.1\n\t\t\treturn 0.85 * wordPositionScore // Score between 0.765 and 0.85\n\t\t}\n\t}\n\n\t// 4. Direct substring match (query appears anywhere in target)\n\tif (normalizedTarget.includes(normalizedQuery)) {\n\t\t// Score based on position (earlier position scores higher)\n\t\tconst position = normalizedTarget.indexOf(normalizedQuery)\n\t\tconst positionScore = 1 - (position / normalizedTarget.length) * 0.2\n\t\treturn 0.7 * positionScore // Score between 0.56 and 0.7\n\t}\n\n\t// 5. Subsequence check (all query chars appear in order)\n\tif (isSubsequence(normalizedQuery, normalizedTarget)) {\n\t\treturn 0.5\n\t}\n\n\t// 6. Fuzzy matching for typos and similar words\n\t// Calculate all scores and return the maximum (avoid array allocation)\n\tlet maxScore = 0\n\n\t// 6a. Dice coefficient (good for character-level similarity)\n\tconst diceScore = diceCoefficient(normalizedQuery, normalizedTarget) * SCORE_WEIGHT_DICE\n\tif (diceScore > maxScore) maxScore = diceScore\n\n\t// 6b. Levenshtein distance (good for typos)\n\tconst maxLength = Math.max(normalizedQuery.length, normalizedTarget.length)\n\tconst levenshteinDistance = calculateLevenshtein(\n\t\tnormalizedQuery,\n\t\tnormalizedTarget,\n\t\topts.maxLevenshteinDistance\n\t)\n\tconst levenshteinScore = maxLength ? (1 - levenshteinDistance / maxLength) * SCORE_WEIGHT_LEVENSHTEIN : 0\n\tif (levenshteinScore > maxScore) maxScore = levenshteinScore\n\n\t// 6c. Character frequency match (anagram-like)\n\tif (hasAllCharacters(normalizedQuery, normalizedTarget)) {\n\t\tif (SCORE_WEIGHT_ANAGRAM > maxScore) maxScore = SCORE_WEIGHT_ANAGRAM\n\t}\n\n\t// 6d. Word-level Jaccard similarity (good for phrase matching)\n\tif (opts.includeWordJaccard && words.length > 1) {\n\t\tconst queryWords = normalizedQuery.split(WORD_SPLIT_PATTERN).filter(w => w.length > 0)\n\t\tif (queryWords.length > 0) {\n\t\t\tconst jaccardScore = wordJaccardSimilarity(queryWords, words) * SCORE_WEIGHT_JACCARD\n\t\t\tif (jaccardScore > maxScore) maxScore = jaccardScore\n\t\t}\n\t}\n\n\treturn maxScore\n}\n\n/**\n * Normalize a string for comparison.\n * - Converts to lowercase\n * - Trims whitespace\n * - Optionally removes accents/diacritics\n *\n * @param str The string to normalize\n * @param removeAccents Whether to remove accents/diacritics\n * @returns The normalized string\n */\nfunction normalizeString(str: string, removeAccents: boolean): string {\n\tlet normalized = str.toLowerCase().trim()\n\n\tif (removeAccents) {\n\t\t// Remove accents using NFD normalization and removing combining marks\n\t\tnormalized = normalized.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\t}\n\n\treturn normalized\n}\n\n/**\n * Calculate Jaccard similarity between two sets of words.\n * Returns a value between 0 (no overlap) and 1 (identical sets).\n * Optimized to avoid unnecessary array conversions.\n *\n * @param words1 Array of words from first string\n * @param words2 Array of words from second string\n * @returns Jaccard similarity score (0-1)\n */\nfunction wordJaccardSimilarity(words1: string[], words2: string[]): number {\n\tif (words1.length === 0 || words2.length === 0) return 0\n\n\tconst set1 = new Set(words1)\n\tconst set2 = new Set(words2)\n\n\t// Count intersection\n\tlet intersectionSize = 0\n\tset1.forEach(word => {\n\t\tif (set2.has(word)) intersectionSize++\n\t})\n\n\t// Union size = size1 + size2 - intersection\n\tconst unionSize = set1.size + set2.size - intersectionSize\n\n\treturn unionSize > 0 ? intersectionSize / unionSize : 0\n}\n\n/**\n * Check if string 'sub' is a subsequence of string 'str'.\n * All characters in 'sub' must appear in order in 'str'.\n */\nfunction isSubsequence(sub: string, str: string): boolean {\n\tlet i = 0,\n\t\tj = 0\n\twhile (i < sub.length && j < str.length) {\n\t\tif (sub[i] === str[j]) i++\n\t\tj++\n\t}\n\treturn i === sub.length\n}\n\n/**\n * Check if all characters in 'query' are present in 'target'.\n * For example, \"aovc\" matches \"avocados\" (anagram subset matching).\n * Optimized with Map for O(n+m) single-pass performance.\n */\nfunction hasAllCharacters(query: string, target: string): boolean {\n\t// Build character frequency map for target (single pass)\n\tconst targetCount = new Map<string, number>()\n\tfor (let i = 0; i < target.length; i++) {\n\t\tconst char = target[i]\n\t\ttargetCount.set(char, (targetCount.get(char) || 0) + 1)\n\t}\n\n\t// Check query characters against target (single pass)\n\tconst queryCount = new Map<string, number>()\n\tfor (let i = 0; i < query.length; i++) {\n\t\tconst char = query[i]\n\t\tqueryCount.set(char, (queryCount.get(char) || 0) + 1)\n\t}\n\n\t// Verify all query chars exist in target with sufficient count\n\tlet hasAll = true\n\tqueryCount.forEach((count, char) => {\n\t\tif ((targetCount.get(char) || 0) < count) hasAll = false\n\t})\n\n\treturn hasAll\n}\n\n/**\n * Compute Dice's coefficient for two strings based on bigrams.\n * Returns a value between 0 (no similarity) and 1 (perfect match).\n * Optimized with Map for O(n) performance instead of O(n²).\n */\nfunction diceCoefficient(s1: string, s2: string): number {\n\tif (s1.length < 2 || s2.length < 2) return 0\n\n\t// Build bigram frequency map for s2 (O(n))\n\tconst bigrams2Map = new Map<string, number>()\n\tfor (let i = 0; i < s2.length - 1; i++) {\n\t\tconst bigram = s2.substring(i, i + 2)\n\t\tbigrams2Map.set(bigram, (bigrams2Map.get(bigram) || 0) + 1)\n\t}\n\n\t// Count intersections while iterating s1 bigrams (O(n))\n\tlet intersection = 0\n\tlet bigrams1Count = 0\n\tfor (let i = 0; i < s1.length - 1; i++) {\n\t\tconst bigram = s1.substring(i, i + 2)\n\t\tbigrams1Count++\n\t\tconst count = bigrams2Map.get(bigram)\n\t\tif (count && count > 0) {\n\t\t\tintersection++\n\t\t\tbigrams2Map.set(bigram, count - 1)\n\t\t}\n\t}\n\n\tconst bigrams2Count = s2.length - 1\n\treturn (2 * intersection) / (bigrams1Count + bigrams2Count)\n}\n\n/**\n * Calculate Levenshtein distance between two strings.\n * Optimized with O(min(n,m)) space complexity using rolling arrays.\n * Supports early termination when distance exceeds threshold.\n *\n * @param a First string\n * @param b Second string\n * @param maxDistance Maximum distance threshold for early termination (0 = disabled)\n * @returns The Levenshtein distance between the strings\n */\nfunction calculateLevenshtein(a: string, b: string, maxDistance = 0): number {\n\t// Ensure a is the shorter string for space optimization\n\tif (a.length > b.length) [a, b] = [b, a]\n\n\tif (a.length === 0) return b.length\n\n\t// Early termination: if length difference exceeds max distance\n\tif (maxDistance > 0 && b.length - a.length > maxDistance) {\n\t\treturn maxDistance + 1\n\t}\n\n\t// Use two rolling arrays instead of full matrix: O(n) space instead of O(n*m)\n\tlet prevRow = Array.from({ length: a.length + 1 }) as number[]\n\tlet currRow = Array.from({ length: a.length + 1 }) as number[]\n\n\t// Initialize first row\n\tfor (let j = 0; j <= a.length; j++) {\n\t\tprevRow[j] = j\n\t}\n\n\t// Calculate distances row by row\n\tfor (let i = 1; i <= b.length; i++) {\n\t\tcurrRow[0] = i\n\t\tlet minRowValue = i\n\n\t\tfor (let j = 1; j <= a.length; j++) {\n\t\t\tconst cost = a[j - 1] === b[i - 1] ? 0 : 1\n\t\t\tcurrRow[j] = Math.min(\n\t\t\t\tprevRow[j] + 1, // deletion\n\t\t\t\tcurrRow[j - 1] + 1, // insertion\n\t\t\t\tprevRow[j - 1] + cost // substitution\n\t\t\t)\n\t\t\tif (currRow[j] < minRowValue) minRowValue = currRow[j]\n\t\t}\n\n\t\t// Early termination: if minimum value in row exceeds threshold\n\t\tif (maxDistance > 0 && minRowValue > maxDistance) {\n\t\t\treturn maxDistance + 1\n\t\t}\n\n\t\t// Swap arrays for next iteration (O(1) operation)\n\t\t;[prevRow, currRow] = [currRow, prevRow]\n\t}\n\n\treturn prevRow[a.length]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search-DPKoC-dT.cjs","names":[],"sources":["../src/utils/search.ts"],"sourcesContent":["/**\n * Options for configuring similarity calculation behavior.\n */\nexport interface SimilarityOptions {\n\t/**\n\t * Whether to remove accents/diacritics during normalization.\n\t * @default true\n\t */\n\tnormalizeAccents?: boolean\n\n\t/**\n\t * Whether to include word-level Jaccard similarity in fuzzy matching.\n\t * Useful for matching phrases with different word orders.\n\t * @default true\n\t */\n\tincludeWordJaccard?: boolean\n\n\t/**\n\t * Maximum Levenshtein distance threshold for early termination.\n\t * Improves performance for very dissimilar strings.\n\t * Set to 0 to disable early termination.\n\t * @default 0 (disabled)\n\t */\n\tmaxLevenshteinDistance?: number\n}\n\n// Scoring weights as named constants for clarity and maintainability\nconst SCORE_WEIGHT_DICE = 0.45\nconst SCORE_WEIGHT_LEVENSHTEIN = 0.45\nconst SCORE_WEIGHT_ANAGRAM = 0.3\nconst SCORE_WEIGHT_JACCARD = 0.4\n\n// Word splitting pattern - defined once for reuse\nconst WORD_SPLIT_PATTERN = /[\\s\\-_.,;:!?()[\\]{}]+/\n\n/**\n * Calculate similarity score between two strings.\n * Returns a value between 0 (no match) and 1 (exact match).\n * Optimized for autocomplete with prioritization of start matches and whole words.\n *\n * Scoring tiers (higher scores = better matches):\n * - 1.00: Exact match\n * - 0.95-1.00: Target starts with query (autocomplete-style)\n * - 0.765-0.85: Query matches start of a word in target\n * - 0.56-0.70: Query is substring of target\n * - 0.50: Query is subsequence of target\n * - 0.00-0.50: Fuzzy matching (typos, similar words, character overlap)\n *\n * @param query The search query string\n * @param target The target string to compare against\n * @param options Optional configuration for similarity calculation\n * @returns A similarity score from 0 to 1\n *\n * @example\n * similarity('john', 'John Doe') // 0.975+ (starts with)\n * similarity('doe', 'John Doe') // 0.765+ (word boundary)\n * similarity('jo', 'John Doe') // 0.95+ (starts with)\n * similarity('jhn', 'John Doe') // 0.3-0.5 (subsequence/fuzzy)\n */\nexport function similarity(query: string, target: string, options?: SimilarityOptions): number {\n\t// Handle edge cases\n\tif (!query || !target) return 0\n\tif (query === target) return 1\n\n\t// Default options\n\tconst opts: Required<SimilarityOptions> = {\n\t\tnormalizeAccents: options?.normalizeAccents ?? true,\n\t\tincludeWordJaccard: options?.includeWordJaccard ?? true,\n\t\tmaxLevenshteinDistance: options?.maxLevenshteinDistance ?? 0,\n\t}\n\n\t// Normalize strings for comparison\n\tconst normalizedQuery = normalizeString(query, opts.normalizeAccents)\n\tconst normalizedTarget = normalizeString(target, opts.normalizeAccents)\n\n\t// 1. Exact match (case-insensitive, accent-insensitive)\n\tif (normalizedQuery === normalizedTarget) return 1\n\n\t// 2. Target starts with query (highest priority for autocomplete)\n\tif (normalizedTarget.startsWith(normalizedQuery)) {\n\t\t// Give higher score to shorter targets (more precise matches)\n\t\tconst lengthRatio = normalizedQuery.length / normalizedTarget.length\n\t\treturn 0.95 + (lengthRatio * 0.05) // Score between 0.95 and 1.0\n\t}\n\n\t// 3. Word boundary match (query matches start of any word in target)\n\tconst words = normalizedTarget.split(WORD_SPLIT_PATTERN).filter(w => w.length > 0)\n\tfor (let i = 0; i < words.length; i++) {\n\t\tif (words[i].startsWith(normalizedQuery)) {\n\t\t\t// Score based on which word matched (earlier words score higher)\n\t\t\tconst wordPositionScore = 1 - (i / words.length) * 0.1\n\t\t\treturn 0.85 * wordPositionScore // Score between 0.765 and 0.85\n\t\t}\n\t}\n\n\t// 4. Direct substring match (query appears anywhere in target)\n\tif (normalizedTarget.includes(normalizedQuery)) {\n\t\t// Score based on position (earlier position scores higher)\n\t\tconst position = normalizedTarget.indexOf(normalizedQuery)\n\t\tconst positionScore = 1 - (position / normalizedTarget.length) * 0.2\n\t\treturn 0.7 * positionScore // Score between 0.56 and 0.7\n\t}\n\n\t// 5. Subsequence check (all query chars appear in order)\n\tif (isSubsequence(normalizedQuery, normalizedTarget)) {\n\t\treturn 0.5\n\t}\n\n\t// 6. Fuzzy matching for typos and similar words\n\t// Calculate all scores and return the maximum (avoid array allocation)\n\tlet maxScore = 0\n\n\t// 6a. Dice coefficient (good for character-level similarity)\n\tconst diceScore = diceCoefficient(normalizedQuery, normalizedTarget) * SCORE_WEIGHT_DICE\n\tif (diceScore > maxScore) maxScore = diceScore\n\n\t// 6b. Levenshtein distance (good for typos)\n\tconst maxLength = Math.max(normalizedQuery.length, normalizedTarget.length)\n\tconst levenshteinDistance = calculateLevenshtein(\n\t\tnormalizedQuery,\n\t\tnormalizedTarget,\n\t\topts.maxLevenshteinDistance\n\t)\n\tconst levenshteinScore = maxLength ? (1 - levenshteinDistance / maxLength) * SCORE_WEIGHT_LEVENSHTEIN : 0\n\tif (levenshteinScore > maxScore) maxScore = levenshteinScore\n\n\t// 6c. Character frequency match (anagram-like)\n\tif (hasAllCharacters(normalizedQuery, normalizedTarget)) {\n\t\tif (SCORE_WEIGHT_ANAGRAM > maxScore) maxScore = SCORE_WEIGHT_ANAGRAM\n\t}\n\n\t// 6d. Word-level Jaccard similarity (good for phrase matching)\n\tif (opts.includeWordJaccard && words.length > 1) {\n\t\tconst queryWords = normalizedQuery.split(WORD_SPLIT_PATTERN).filter(w => w.length > 0)\n\t\tif (queryWords.length > 0) {\n\t\t\tconst jaccardScore = wordJaccardSimilarity(queryWords, words) * SCORE_WEIGHT_JACCARD\n\t\t\tif (jaccardScore > maxScore) maxScore = jaccardScore\n\t\t}\n\t}\n\n\treturn maxScore\n}\n\n/**\n * Normalize a string for comparison.\n * - Converts to lowercase\n * - Trims whitespace\n * - Optionally removes accents/diacritics\n *\n * @param str The string to normalize\n * @param removeAccents Whether to remove accents/diacritics\n * @returns The normalized string\n */\nfunction normalizeString(str: string, removeAccents: boolean): string {\n\tlet normalized = str.toLowerCase().trim()\n\n\tif (removeAccents) {\n\t\t// Remove accents using NFD normalization and removing combining marks\n\t\tnormalized = normalized.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\t}\n\n\treturn normalized\n}\n\n/**\n * Calculate Jaccard similarity between two sets of words.\n * Returns a value between 0 (no overlap) and 1 (identical sets).\n * Optimized to avoid unnecessary array conversions.\n *\n * @param words1 Array of words from first string\n * @param words2 Array of words from second string\n * @returns Jaccard similarity score (0-1)\n */\nfunction wordJaccardSimilarity(words1: string[], words2: string[]): number {\n\tif (words1.length === 0 || words2.length === 0) return 0\n\n\tconst set1 = new Set(words1)\n\tconst set2 = new Set(words2)\n\n\t// Count intersection\n\tlet intersectionSize = 0\n\tset1.forEach(word => {\n\t\tif (set2.has(word)) intersectionSize++\n\t})\n\n\t// Union size = size1 + size2 - intersection\n\tconst unionSize = set1.size + set2.size - intersectionSize\n\n\treturn unionSize > 0 ? intersectionSize / unionSize : 0\n}\n\n/**\n * Check if string 'sub' is a subsequence of string 'str'.\n * All characters in 'sub' must appear in order in 'str'.\n */\nfunction isSubsequence(sub: string, str: string): boolean {\n\tlet i = 0,\n\t\tj = 0\n\twhile (i < sub.length && j < str.length) {\n\t\tif (sub[i] === str[j]) i++\n\t\tj++\n\t}\n\treturn i === sub.length\n}\n\n/**\n * Check if all characters in 'query' are present in 'target'.\n * For example, \"aovc\" matches \"avocados\" (anagram subset matching).\n * Optimized with Map for O(n+m) single-pass performance.\n */\nfunction hasAllCharacters(query: string, target: string): boolean {\n\t// Build character frequency map for target (single pass)\n\tconst targetCount = new Map<string, number>()\n\tfor (let i = 0; i < target.length; i++) {\n\t\tconst char = target[i]\n\t\ttargetCount.set(char, (targetCount.get(char) || 0) + 1)\n\t}\n\n\t// Check query characters against target (single pass)\n\tconst queryCount = new Map<string, number>()\n\tfor (let i = 0; i < query.length; i++) {\n\t\tconst char = query[i]\n\t\tqueryCount.set(char, (queryCount.get(char) || 0) + 1)\n\t}\n\n\t// Verify all query chars exist in target with sufficient count\n\tlet hasAll = true\n\tqueryCount.forEach((count, char) => {\n\t\tif ((targetCount.get(char) || 0) < count) hasAll = false\n\t})\n\n\treturn hasAll\n}\n\n/**\n * Compute Dice's coefficient for two strings based on bigrams.\n * Returns a value between 0 (no similarity) and 1 (perfect match).\n * Optimized with Map for O(n) performance instead of O(n²).\n */\nfunction diceCoefficient(s1: string, s2: string): number {\n\tif (s1.length < 2 || s2.length < 2) return 0\n\n\t// Build bigram frequency map for s2 (O(n))\n\tconst bigrams2Map = new Map<string, number>()\n\tfor (let i = 0; i < s2.length - 1; i++) {\n\t\tconst bigram = s2.substring(i, i + 2)\n\t\tbigrams2Map.set(bigram, (bigrams2Map.get(bigram) || 0) + 1)\n\t}\n\n\t// Count intersections while iterating s1 bigrams (O(n))\n\tlet intersection = 0\n\tlet bigrams1Count = 0\n\tfor (let i = 0; i < s1.length - 1; i++) {\n\t\tconst bigram = s1.substring(i, i + 2)\n\t\tbigrams1Count++\n\t\tconst count = bigrams2Map.get(bigram)\n\t\tif (count && count > 0) {\n\t\t\tintersection++\n\t\t\tbigrams2Map.set(bigram, count - 1)\n\t\t}\n\t}\n\n\tconst bigrams2Count = s2.length - 1\n\treturn (2 * intersection) / (bigrams1Count + bigrams2Count)\n}\n\n/**\n * Calculate Levenshtein distance between two strings.\n * Optimized with O(min(n,m)) space complexity using rolling arrays.\n * Supports early termination when distance exceeds threshold.\n *\n * @param a First string\n * @param b Second string\n * @param maxDistance Maximum distance threshold for early termination (0 = disabled)\n * @returns The Levenshtein distance between the strings\n */\nfunction calculateLevenshtein(a: string, b: string, maxDistance = 0): number {\n\t// Ensure a is the shorter string for space optimization\n\tif (a.length > b.length) [a, b] = [b, a]\n\n\tif (a.length === 0) return b.length\n\n\t// Early termination: if length difference exceeds max distance\n\tif (maxDistance > 0 && b.length - a.length > maxDistance) {\n\t\treturn maxDistance + 1\n\t}\n\n\t// Use two rolling arrays instead of full matrix: O(n) space instead of O(n*m)\n\tlet prevRow = Array.from({ length: a.length + 1 }) as number[]\n\tlet currRow = Array.from({ length: a.length + 1 }) as number[]\n\n\t// Initialize first row\n\tfor (let j = 0; j <= a.length; j++) {\n\t\tprevRow[j] = j\n\t}\n\n\t// Calculate distances row by row\n\tfor (let i = 1; i <= b.length; i++) {\n\t\tcurrRow[0] = i\n\t\tlet minRowValue = i\n\n\t\tfor (let j = 1; j <= a.length; j++) {\n\t\t\tconst cost = a[j - 1] === b[i - 1] ? 0 : 1\n\t\t\tcurrRow[j] = Math.min(\n\t\t\t\tprevRow[j] + 1, // deletion\n\t\t\t\tcurrRow[j - 1] + 1, // insertion\n\t\t\t\tprevRow[j - 1] + cost // substitution\n\t\t\t)\n\t\t\tif (currRow[j] < minRowValue) minRowValue = currRow[j]\n\t\t}\n\n\t\t// Early termination: if minimum value in row exceeds threshold\n\t\tif (maxDistance > 0 && minRowValue > maxDistance) {\n\t\t\treturn maxDistance + 1\n\t\t}\n\n\t\t// Swap arrays for next iteration (O(1) operation)\n\t\t;[prevRow, currRow] = [currRow, prevRow]\n\t}\n\n\treturn prevRow[a.length]\n}\n"],"mappings":"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"}
|