@mhmo91/schmancy 0.10.37 → 0.10.39
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 +39 -0
- package/dist/{SchmancyElement-CDT2q1lA.js → SchmancyElement-BNnyBOwk.js} +9 -7
- package/dist/{SchmancyElement-CDT2q1lA.js.map → SchmancyElement-BNnyBOwk.js.map} +1 -1
- package/dist/{SchmancyElement-BHfQg3Tj.cjs → SchmancyElement-C41uPa6l.cjs} +2 -2
- package/dist/{SchmancyElement-BHfQg3Tj.cjs.map → SchmancyElement-C41uPa6l.cjs.map} +1 -1
- package/dist/agent/schmancy.agent.js +2334 -2297
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/area-2FrTZI_T.cjs +21 -0
- package/dist/area-2FrTZI_T.cjs.map +1 -0
- package/dist/{area-KtULlxuA.js → area-KVDzhT4s.js} +4 -4
- package/dist/area-KVDzhT4s.js.map +1 -0
- package/dist/area.cjs +1 -1
- package/dist/area.js +2 -2
- package/dist/{audio-zIJVTo_V.js → audio-D3gnp15Y.js} +1 -1
- package/dist/{audio-zIJVTo_V.js.map → audio-D3gnp15Y.js.map} +1 -1
- package/dist/{audio-CUMAv9D_.cjs → audio-EaD0Ggfh.cjs} +1 -1
- package/dist/{audio-CUMAv9D_.cjs.map → audio-EaD0Ggfh.cjs.map} +1 -1
- package/dist/audio.cjs +1 -1
- package/dist/audio.js +2 -2
- package/dist/autocomplete-DMmxsvUe.cjs +115 -0
- package/dist/autocomplete-DMmxsvUe.cjs.map +1 -0
- package/dist/{autocomplete-DIScyo8Q.js → autocomplete-DWiEqlQf.js} +96 -96
- package/dist/autocomplete-DWiEqlQf.js.map +1 -0
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +3 -3
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/{boat-OBZ77exO.cjs → boat-DsFJNfPH.cjs} +1 -1
- package/dist/{boat-OBZ77exO.cjs.map → boat-DsFJNfPH.cjs.map} +1 -1
- package/dist/{boat-BHPqSqJd.js → boat-fqodYt2n.js} +4 -4
- package/dist/{boat-BHPqSqJd.js.map → boat-fqodYt2n.js.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 +4 -4
- package/dist/breadcrumb.js.map +1 -1
- package/dist/{busy-BJNsKSCM.cjs → busy-Cj_PV7oC.cjs} +1 -1
- package/dist/{busy-BJNsKSCM.cjs.map → busy-Cj_PV7oC.cjs.map} +1 -1
- package/dist/{busy-Dut78y4L.js → busy-enYCTssB.js} +2 -2
- package/dist/{busy-Dut78y4L.js.map → busy-enYCTssB.js.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/button-B9RfBt-n.cjs +63 -0
- package/dist/button-B9RfBt-n.cjs.map +1 -0
- package/dist/{button-kcpPQavY.js → button-D6LJC-HC.js} +11 -9
- package/dist/button-D6LJC-HC.js.map +1 -0
- package/dist/button.cjs +7 -6
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +18 -16
- package/dist/button.js.map +1 -1
- package/dist/{card-DxSKxCid.js → card-BHTz1GwB.js} +16 -16
- package/dist/card-BHTz1GwB.js.map +1 -0
- package/dist/{card-BLxPLqdQ.cjs → card-ThG_ZaQE.cjs} +3 -3
- package/dist/card-ThG_ZaQE.cjs.map +1 -0
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-BCLkhp5G.cjs → checkbox-C4zeib84.cjs} +2 -2
- package/dist/{checkbox-BCLkhp5G.cjs.map → checkbox-C4zeib84.cjs.map} +1 -1
- package/dist/{checkbox-B1wiM3Dv.js → checkbox-Ce0DlAdW.js} +6 -6
- package/dist/{checkbox-B1wiM3Dv.js.map → checkbox-Ce0DlAdW.js.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-vWmwqQed.js → chips-BoZSpSh_.js} +21 -19
- package/dist/chips-BoZSpSh_.js.map +1 -0
- package/dist/{chips-C9dS1WKn.cjs → chips-wfJ7YtWv.cjs} +4 -3
- package/dist/chips-wfJ7YtWv.cjs.map +1 -0
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +1 -1
- package/dist/connectivity.js +3 -3
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/cursor-glow-Ah7VXSj7.js.map +1 -1
- package/dist/cursor-glow-Bulq-38P.cjs.map +1 -1
- package/dist/{date-range-BV6HuvLw.cjs → date-range-BHSzlwSL.cjs} +2 -2
- package/dist/date-range-BHSzlwSL.cjs.map +1 -0
- package/dist/{date-range-D3ge1b4c.js → date-range-DJrdpzev.js} +4 -4
- package/dist/date-range-DJrdpzev.js.map +1 -0
- package/dist/{date-range-inline-DpYgdLRv.cjs → date-range-inline-D0I6k84h.cjs} +1 -1
- package/dist/{date-range-inline-DpYgdLRv.cjs.map → date-range-inline-D0I6k84h.cjs.map} +1 -1
- package/dist/{date-range-inline-DuWQaWps.js → date-range-inline-DjRdMZ1z.js} +2 -2
- package/dist/{date-range-inline-DuWQaWps.js.map → date-range-inline-DjRdMZ1z.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 +1 -1
- package/dist/delay.js +2 -2
- package/dist/{details-C-GZaq3j.js → details-CY49XVfp.js} +43 -35
- package/dist/details-CY49XVfp.js.map +1 -0
- package/dist/details-DQNj2oaU.cjs +164 -0
- package/dist/details-DQNj2oaU.cjs.map +1 -0
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/{directives-D_l1E5H6.cjs → directives-Bb0S1DKZ.cjs} +3 -3
- package/dist/directives-Bb0S1DKZ.cjs.map +1 -0
- package/dist/{directives-DyS51FUh.js → directives-Bfm1lkoy.js} +6 -8
- package/dist/directives-Bfm1lkoy.js.map +1 -0
- package/dist/directives.cjs +1 -1
- package/dist/directives.js +2 -2
- package/dist/{divider-nQffE0AD.js → divider-BeyX_C0A.js} +2 -2
- package/dist/{divider-nQffE0AD.js.map → divider-BeyX_C0A.js.map} +1 -1
- package/dist/{divider-CBnAmHMZ.cjs → divider-Ck2C1sKl.cjs} +1 -1
- package/dist/{divider-CBnAmHMZ.cjs.map → divider-Ck2C1sKl.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/dropdown.cjs +1 -1
- package/dist/dropdown.js +2 -2
- package/dist/{expand-DvTb-UPR.js → expand-BYsSEtp6.js} +53 -53
- package/dist/expand-BYsSEtp6.js.map +1 -0
- package/dist/expand-CUF163mg.cjs +141 -0
- package/dist/expand-CUF163mg.cjs.map +1 -0
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/fab.cjs +2 -1
- package/dist/fab.cjs.map +1 -1
- package/dist/fab.js +3 -2
- package/dist/fab.js.map +1 -1
- package/dist/{float-C-Ko0Le3.js → float-Cgllk_H9.js} +2 -2
- package/dist/{float-C-Ko0Le3.js.map → float-Cgllk_H9.js.map} +1 -1
- package/dist/{float-C17xgMT1.cjs → float-OvqX0nqG.cjs} +1 -1
- package/dist/{float-C17xgMT1.cjs.map → float-OvqX0nqG.cjs.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/form-4GKROq2P.cjs +27 -0
- package/dist/form-4GKROq2P.cjs.map +1 -0
- package/dist/{form-DA0hUu2h.js → form-DxaV_Ose.js} +39 -39
- package/dist/form-DxaV_Ose.js.map +1 -0
- package/dist/form.cjs +3 -3
- package/dist/form.cjs.map +1 -1
- package/dist/form.js +34 -34
- package/dist/form.js.map +1 -1
- package/dist/gravity-6pL6CfIr.cjs.map +1 -1
- package/dist/gravity-sVK3zGBF.js.map +1 -1
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{icons-C6UfxmHZ.js → icons-CJ2mXcBi.js} +9 -9
- package/dist/icons-CJ2mXcBi.js.map +1 -0
- package/dist/icons-sZ-LybA9.cjs +24 -0
- package/dist/icons-sZ-LybA9.cjs.map +1 -0
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-BTjZfYyh.js → iframe-DWvN5nGB.js} +11 -11
- package/dist/iframe-DWvN5nGB.js.map +1 -0
- package/dist/{iframe-wuYT2xFz.cjs → iframe-DpCv-QH2.cjs} +7 -7
- package/dist/iframe-DpCv-QH2.cjs.map +1 -0
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +35 -35
- package/dist/{input-B_4g2ulO.js → input-BCCHz6tB.js} +7 -7
- package/dist/input-BCCHz6tB.js.map +1 -0
- package/dist/{input-BrDiIT60.cjs → input-Z-3N5JMv.cjs} +2 -2
- package/dist/input-Z-3N5JMv.cjs.map +1 -0
- package/dist/{input-chip-BlWhOruv.js → input-chip-BOrcKH-H.js} +2 -2
- package/dist/{input-chip-BlWhOruv.js.map → input-chip-BOrcKH-H.js.map} +1 -1
- package/dist/{input-chip-B-XWh4aE.cjs → input-chip-ChAgRCXZ.cjs} +1 -1
- package/dist/{input-chip-B-XWh4aE.cjs.map → input-chip-ChAgRCXZ.cjs.map} +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/json.cjs +1 -1
- package/dist/json.js +3 -3
- package/dist/kbd.cjs +1 -1
- package/dist/kbd.js +2 -2
- package/dist/{layout-Dxit9enO.js → layout-CFiG3lNT.js} +1 -1
- package/dist/{layout-Dxit9enO.js.map → layout-CFiG3lNT.js.map} +1 -1
- package/dist/{layout-BhyIcEVu.cjs → layout-DZ4dpLh9.cjs} +1 -1
- package/dist/{layout-BhyIcEVu.cjs.map → layout-DZ4dpLh9.cjs.map} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +2 -2
- package/dist/lazy-BaAiIUru.js +19 -0
- package/dist/lazy-BaAiIUru.js.map +1 -0
- package/dist/lazy-C-7a4FAe.cjs +1 -0
- package/dist/lazy-C-7a4FAe.cjs.map +1 -0
- package/dist/{lightbox-D85XAAuC.js → lightbox-B7Y4Nij_.js} +2 -2
- package/dist/lightbox-B7Y4Nij_.js.map +1 -0
- package/dist/{lightbox-CVBogswK.cjs → lightbox-Dpwsn8Qr.cjs} +1 -1
- package/dist/lightbox-Dpwsn8Qr.cjs.map +1 -0
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-nVjLskgx.cjs → list-BhM-6dAi.cjs} +1 -1
- package/dist/{list-nVjLskgx.cjs.map → list-BhM-6dAi.cjs.map} +1 -1
- package/dist/{list-DOF_yVn5.js → list-C5WVoIfJ.js} +2 -2
- package/dist/{list-DOF_yVn5.js.map → list-C5WVoIfJ.js.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/magnetic-DKtc4umC.cjs.map +1 -1
- package/dist/magnetic-DaOOv5Dz.js.map +1 -1
- package/dist/{menu-QrAK5Uu9.js → menu-Dvi_tQgH.js} +3 -3
- package/dist/{menu-QrAK5Uu9.js.map → menu-Dvi_tQgH.js.map} +1 -1
- package/dist/{menu-DqmNjLgY.cjs → menu-GZARYp6I.cjs} +1 -1
- package/dist/{menu-DqmNjLgY.cjs.map → menu-GZARYp6I.cjs.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/{mixins-De1zjyhy.js → mixins-DGBI7YPO.js} +11 -11
- package/dist/mixins-DGBI7YPO.js.map +1 -0
- package/dist/{mixins-DxHpyMHA.cjs → mixins-fIpzhVMd.cjs} +1 -1
- package/dist/mixins-fIpzhVMd.cjs.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 +11 -10
- package/dist/navigation-rail.js.map +1 -1
- package/dist/notification-B6yDL91t.cjs +24 -0
- package/dist/notification-B6yDL91t.cjs.map +1 -0
- package/dist/{notification-BtAK7NK8.js → notification-BB9OBRCr.js} +22 -22
- package/dist/notification-BB9OBRCr.js.map +1 -0
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-DHwA0miA.js → option-B21ImL0k.js} +2 -2
- package/dist/{option-DHwA0miA.js.map → option-B21ImL0k.js.map} +1 -1
- package/dist/{option-DnSPa8ro.cjs → option-CJQM5I9q.cjs} +1 -1
- package/dist/{option-DnSPa8ro.cjs.map → option-CJQM5I9q.cjs.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-Del1sBEB.js → overlay-DwJWVyk2.js} +75 -67
- package/dist/overlay-DwJWVyk2.js.map +1 -0
- package/dist/overlay-N0trD-4u.cjs +58 -0
- package/dist/overlay-N0trD-4u.cjs.map +1 -0
- package/dist/overlay.cjs +1 -1
- package/dist/{overlay.confirm-body-BV9umTAl.cjs → overlay.confirm-body-CtXIi421.cjs} +3 -3
- package/dist/overlay.confirm-body-CtXIi421.cjs.map +1 -0
- package/dist/{overlay.confirm-body-DSONXUzl.js → overlay.confirm-body-DwzKhXxM.js} +10 -10
- package/dist/overlay.confirm-body-DwzKhXxM.js.map +1 -0
- package/dist/overlay.js +4 -4
- package/dist/{overlay.service-BTp5Oq7f.js → overlay.service-BDLi0p5M.js} +4 -4
- package/dist/{overlay.service-BTp5Oq7f.js.map → overlay.service-BDLi0p5M.js.map} +1 -1
- package/dist/overlay.service-Dbu5uP9E.cjs +1 -0
- package/dist/{overlay.service-XLlrsSdA.cjs.map → overlay.service-Dbu5uP9E.cjs.map} +1 -1
- package/dist/{progress-DUbTL9g9.cjs → progress-B-Qg44XY.cjs} +1 -1
- package/dist/{progress-DUbTL9g9.cjs.map → progress-B-Qg44XY.cjs.map} +1 -1
- package/dist/{progress-DYA83CFU.js → progress-CUSS1sNz.js} +2 -2
- package/dist/{progress-DYA83CFU.js.map → progress-CUSS1sNz.js.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-DxX0iJBo.js → radio-group-AHLvrN8O.js} +7 -7
- package/dist/radio-group-AHLvrN8O.js.map +1 -0
- package/dist/{radio-group-B-ORNtvR.cjs → radio-group-BEtvCSS1.cjs} +2 -2
- package/dist/radio-group-BEtvCSS1.cjs.map +1 -0
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +1 -1
- package/dist/range.js +2 -2
- package/dist/select-BWpV2iv-.cjs +56 -0
- package/dist/select-BWpV2iv-.cjs.map +1 -0
- package/dist/{select-C7gkA-ab.js → select-Cawz88lG.js} +46 -46
- package/dist/select-Cawz88lG.js.map +1 -0
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.js +2 -2
- package/dist/skills/SKILL.md +9 -0
- package/dist/skills/overlay.md +14 -7
- package/dist/skills/schmancy/SKILL.md +9 -0
- package/dist/skills/schmancy/overlay.md +14 -7
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +2 -2
- package/dist/{sound.service-O0232os6.js → sound.service-CK-5zob-.js} +4 -3
- package/dist/sound.service-CK-5zob-.js.map +1 -0
- package/dist/{sound.service-C7FDY_yD.cjs → sound.service-D2GGaBXc.cjs} +1 -1
- package/dist/sound.service-D2GGaBXc.cjs.map +1 -0
- package/dist/{splash-screen-jfE47xl0.js → splash-screen-BUEtjHXC.js} +13 -13
- package/dist/splash-screen-BUEtjHXC.js.map +1 -0
- package/dist/{splash-screen-DIS4odDr.cjs → splash-screen-DqPuipox.cjs} +6 -6
- package/dist/splash-screen-DqPuipox.cjs.map +1 -0
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-BP3h-9d9.js → src-8VJ7eluk.js} +46 -45
- package/dist/src-8VJ7eluk.js.map +1 -0
- package/dist/{src-Um_pzb-U.cjs → src-GJA8uSAS.cjs} +7 -6
- package/dist/src-GJA8uSAS.cjs.map +1 -0
- package/dist/{state-Bj0M9a6T.cjs → state-BxDNox-2.cjs} +1 -1
- package/dist/{state-Bj0M9a6T.cjs.map → state-BxDNox-2.cjs.map} +1 -1
- package/dist/{state-DscWQpoM.js → state-CnZCDMT0.js} +9 -9
- package/dist/{state-DscWQpoM.js.map → state-CnZCDMT0.js.map} +1 -1
- package/dist/state.cjs +1 -1
- package/dist/state.js +2 -2
- package/dist/steps.cjs +1 -1
- package/dist/steps.js +2 -2
- package/dist/{surface-B4Wn4SOO.js → surface-BMdG3dKQ.js} +2 -2
- package/dist/{surface-B4Wn4SOO.js.map → surface-BMdG3dKQ.js.map} +1 -1
- package/dist/{surface-DRq6cVW6.cjs → surface-CWwYD_z2.cjs} +1 -1
- package/dist/{surface-DRq6cVW6.cjs.map → surface-CWwYD_z2.cjs.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +4 -4
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +11 -11
- package/dist/switch.js.map +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.js +2 -2
- package/dist/{tabs-CnQPo-XS.js → tabs-CDQYDc6v.js} +2 -2
- package/dist/{tabs-CnQPo-XS.js.map → tabs-CDQYDc6v.js.map} +1 -1
- package/dist/{tabs-Ca_fbHPW.cjs → tabs-CbD9E1gd.cjs} +1 -1
- package/dist/{tabs-Ca_fbHPW.cjs.map → tabs-CbD9E1gd.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-Brgi-vD2.cjs +43 -0
- package/dist/textarea-Brgi-vD2.cjs.map +1 -0
- package/dist/{textarea-BvqENhTW.js → textarea-MPyrMi-S.js} +4 -4
- package/dist/textarea-MPyrMi-S.js.map +1 -0
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-BSwJ2YZo.cjs → theme-BMbXoqi0.cjs} +1 -1
- package/dist/{theme-BSwJ2YZo.cjs.map → theme-BMbXoqi0.cjs.map} +1 -1
- package/dist/{theme-BV0EzHQ1.js → theme-DZu-xmVp.js} +5 -5
- package/dist/{theme-BV0EzHQ1.js.map → theme-DZu-xmVp.js.map} +1 -1
- package/dist/{theme-button-C6fpUzPM.cjs → theme-button-B0OLb-43.cjs} +1 -1
- package/dist/{theme-button-C6fpUzPM.cjs.map → theme-button-B0OLb-43.cjs.map} +1 -1
- package/dist/{theme-button-O_xNCgI7.js → theme-button-D_qGvEYs.js} +2 -2
- package/dist/{theme-button-O_xNCgI7.js.map → theme-button-D_qGvEYs.js.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.js +3 -3
- package/dist/{theme.service-DwLhhOmP.js → theme.service-7VkM-hVf.js} +15 -11
- package/dist/theme.service-7VkM-hVf.js.map +1 -0
- package/dist/theme.service-B15FdjOS.cjs +1 -0
- package/dist/theme.service-B15FdjOS.cjs.map +1 -0
- package/dist/tree.cjs +4 -4
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js +8 -8
- package/dist/tree.js.map +1 -1
- package/dist/{typography-opFYuUYS.cjs → typography-D4Fo1UGh.cjs} +3 -3
- package/dist/{typography-opFYuUYS.cjs.map → typography-D4Fo1UGh.cjs.map} +1 -1
- package/dist/{typography-Dtdooaic.js → typography-SZhjb_4R.js} +9 -9
- package/dist/{typography-Dtdooaic.js.map → typography-SZhjb_4R.js.map} +1 -1
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/dist/visually-hidden.cjs +1 -1
- package/dist/visually-hidden.js +2 -2
- package/dist/{window-ConcHirJ.js → window-BDVyrBnk.js} +101 -100
- package/dist/window-BDVyrBnk.js.map +1 -0
- package/dist/window-BbBYjm7R.cjs +59 -0
- package/dist/window-BbBYjm7R.cjs.map +1 -0
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/skills/schmancy/SKILL.md +9 -0
- package/skills/schmancy/overlay.md +14 -7
- package/src/area/area.component.ts +1 -1
- package/src/area/area.service.test.ts +2 -2
- package/src/area/area.service.ts +1 -1
- package/src/area/lazy.ts +87 -83
- package/src/audio/sound.service.ts +3 -3
- package/src/badge/badge.ts +1 -0
- package/src/breadcrumb/breadcrumb.ts +2 -2
- package/src/button/button.ts +12 -11
- package/src/button/icon-button.ts +19 -18
- package/src/card/card.ts +16 -16
- package/src/content-drawer/drawer.ts +6 -6
- package/src/details/details.ts +55 -55
- package/src/directives/ai-badge.ts +2 -1
- package/src/directives/animate-text.ts +2 -1
- package/src/directives/art/art.directive.ts +2 -1
- package/src/directives/battery.ts +2 -1
- package/src/directives/confirm-click.ts +5 -3
- package/src/directives/cursor-glow.ts +2 -1
- package/src/directives/cycle-text.ts +2 -1
- package/src/directives/depth-of-field.ts +2 -1
- package/src/directives/drag.ts +4 -2
- package/src/directives/fyi.ts +2 -1
- package/src/directives/gravity.ts +2 -1
- package/src/directives/hummingbird.ts +2 -1
- package/src/directives/intersect.ts +3 -2
- package/src/directives/liquid.ts +2 -1
- package/src/directives/living-border.ts +2 -1
- package/src/directives/long-press.ts +2 -1
- package/src/directives/magnetic.ts +2 -1
- package/src/directives/missed-punch.ts +2 -1
- package/src/directives/nebula.ts +6 -5
- package/src/directives/overflow-within.ts +2 -1
- package/src/directives/reveal.ts +2 -1
- package/src/directives/urgent.ts +2 -1
- package/src/directives/working-snake.ts +2 -1
- package/src/expand/expand-root.component.ts +27 -27
- package/src/expand/expand.component.ts +48 -48
- package/src/fab/fab.ts +1 -0
- package/src/form/fields/autocomplete/autocomplete.ts +154 -154
- package/src/form/fields/checkbox/checkbox.ts +4 -4
- package/src/form/fields/chips/chips.ts +2 -2
- package/src/form/fields/chips/filter-chip.ts +16 -15
- package/src/form/fields/date-range/date-range.ts +2 -2
- package/src/form/fields/input/input.ts +12 -12
- package/src/form/fields/radio-group/radio-button.ts +2 -2
- package/src/form/fields/radio-group/radio-group.ts +3 -3
- package/src/form/fields/select/select.ts +56 -56
- package/src/form/fields/switch/switch.ts +10 -10
- package/src/form/fields/textarea/textarea.ts +2 -2
- package/src/form/form-summary.ts +33 -33
- package/src/form/form.ts +45 -45
- package/src/icons/icon.ts +10 -8
- package/src/iframe/iframe.ts +11 -11
- package/src/lightbox/flip-directive.ts +2 -1
- package/src/lightbox/lightbox.directive.ts +2 -1
- package/src/nav-drawer/navbar.ts +3 -3
- package/src/navigation-rail/navigation-rail.ts +10 -10
- package/src/notification/notification.ts +22 -22
- package/src/overlay/overlay.component.ts +106 -83
- package/src/overlay/overlay.confirm-body.ts +4 -4
- package/src/overlay/overlay.service.ts +3 -3
- package/src/overlay/overlay.types.ts +4 -2
- package/src/splash-screen/splash-screen.ts +11 -11
- package/src/state/index.ts +12 -12
- package/src/state/schmancy-context.ts +9 -9
- package/src/teleport/teleport.component.ts +2 -2
- package/src/theme/theme.service.ts +17 -17
- package/src/tree/tree.ts +7 -7
- package/src/typography/typography.ts +7 -7
- package/src/window/window-manager.ts +20 -20
- package/src/window/window.ts +100 -100
- package/types/mixins/SchmancyElement.d.ts +3 -2
- package/types/mixins/formField.mixin.d.ts +1 -1
- package/types/src/area/area.service.d.ts +1 -1
- package/types/src/area/lazy.d.ts +0 -6
- package/types/src/audio/sound.service.d.ts +1 -2
- package/types/src/breadcrumb/breadcrumb.d.ts +1 -1
- package/types/src/button/button.d.ts +3 -3
- package/types/src/button/icon-button.d.ts +6 -7
- package/types/src/card/card.d.ts +5 -5
- package/types/src/content-drawer/drawer.d.ts +1 -1
- package/types/src/details/details.d.ts +2 -21
- package/types/src/directives/ai-badge.d.ts +2 -2
- package/types/src/directives/animate-text.d.ts +2 -2
- package/types/src/directives/art/art.directive.d.ts +2 -2
- package/types/src/directives/battery.d.ts +2 -2
- package/types/src/directives/confirm-click.d.ts +2 -2
- package/types/src/directives/cursor-glow.d.ts +2 -2
- package/types/src/directives/cycle-text.d.ts +2 -2
- package/types/src/directives/depth-of-field.d.ts +2 -2
- package/types/src/directives/drag.d.ts +4 -4
- package/types/src/directives/fyi.d.ts +2 -2
- package/types/src/directives/gravity.d.ts +2 -2
- package/types/src/directives/hummingbird.d.ts +2 -2
- package/types/src/directives/intersect.d.ts +2 -2
- package/types/src/directives/liquid.d.ts +2 -2
- package/types/src/directives/living-border.d.ts +2 -2
- package/types/src/directives/long-press.d.ts +2 -2
- package/types/src/directives/magnetic.d.ts +2 -2
- package/types/src/directives/missed-punch.d.ts +2 -2
- package/types/src/directives/nebula.d.ts +2 -2
- package/types/src/directives/overflow-within.d.ts +2 -2
- package/types/src/directives/reveal.d.ts +2 -2
- package/types/src/directives/urgent.d.ts +2 -2
- package/types/src/directives/working-snake.d.ts +2 -2
- package/types/src/expand/expand-root.component.d.ts +8 -8
- package/types/src/expand/expand.component.d.ts +11 -11
- package/types/src/form/fields/autocomplete/autocomplete.d.ts +29 -29
- package/types/src/form/fields/checkbox/checkbox.d.ts +1 -1
- package/types/src/form/fields/chips/chips.d.ts +1 -1
- package/types/src/form/fields/chips/filter-chip.d.ts +1 -2
- package/types/src/form/fields/input/input.d.ts +3 -3
- package/types/src/form/fields/radio-group/radio-button.d.ts +1 -1
- package/types/src/form/fields/radio-group/radio-group.d.ts +1 -1
- package/types/src/form/fields/select/select.d.ts +8 -8
- package/types/src/form/fields/switch/switch.d.ts +3 -3
- package/types/src/form/fields/textarea/textarea.d.ts +1 -1
- package/types/src/form/form-summary.d.ts +7 -7
- package/types/src/form/form.d.ts +11 -11
- package/types/src/icons/icon.d.ts +2 -2
- package/types/src/iframe/iframe.d.ts +3 -3
- package/types/src/lightbox/flip-directive.d.ts +2 -2
- package/types/src/lightbox/lightbox.directive.d.ts +2 -2
- package/types/src/nav-drawer/navbar.d.ts +1 -1
- package/types/src/navigation-rail/navigation-rail.d.ts +2 -2
- package/types/src/notification/notification.d.ts +8 -8
- package/types/src/overlay/overlay.component.d.ts +16 -16
- package/types/src/overlay/overlay.confirm-body.d.ts +1 -1
- package/types/src/overlay/overlay.types.d.ts +4 -2
- package/types/src/splash-screen/splash-screen.d.ts +2 -2
- package/types/src/state/index.d.ts +1 -1
- package/types/src/state/schmancy-context.d.ts +3 -3
- package/types/src/teleport/teleport.component.d.ts +1 -1
- package/types/src/theme/theme.service.d.ts +1 -4
- package/types/src/tree/tree.d.ts +3 -3
- package/types/src/typography/typography.d.ts +1 -1
- package/types/src/window/window-manager.d.ts +2 -2
- package/types/src/window/window.d.ts +20 -20
- package/dist/area-KtULlxuA.js.map +0 -1
- package/dist/area-fdKhYB6T.cjs +0 -21
- package/dist/area-fdKhYB6T.cjs.map +0 -1
- package/dist/autocomplete-DEZk6wBD.cjs +0 -115
- package/dist/autocomplete-DEZk6wBD.cjs.map +0 -1
- package/dist/autocomplete-DIScyo8Q.js.map +0 -1
- package/dist/button-DzlHLjWO.cjs +0 -62
- package/dist/button-DzlHLjWO.cjs.map +0 -1
- package/dist/button-kcpPQavY.js.map +0 -1
- package/dist/card-BLxPLqdQ.cjs.map +0 -1
- package/dist/card-DxSKxCid.js.map +0 -1
- package/dist/chips-C9dS1WKn.cjs.map +0 -1
- package/dist/chips-vWmwqQed.js.map +0 -1
- package/dist/date-range-BV6HuvLw.cjs.map +0 -1
- package/dist/date-range-D3ge1b4c.js.map +0 -1
- package/dist/details-C-GZaq3j.js.map +0 -1
- package/dist/details-Dp5rLIWk.cjs +0 -164
- package/dist/details-Dp5rLIWk.cjs.map +0 -1
- package/dist/directives-D_l1E5H6.cjs.map +0 -1
- package/dist/directives-DyS51FUh.js.map +0 -1
- package/dist/expand-DvTb-UPR.js.map +0 -1
- package/dist/expand-mlP_3XWz.cjs +0 -141
- package/dist/expand-mlP_3XWz.cjs.map +0 -1
- package/dist/form-CwPHcQYB.cjs +0 -27
- package/dist/form-CwPHcQYB.cjs.map +0 -1
- package/dist/form-DA0hUu2h.js.map +0 -1
- package/dist/icons-C6UfxmHZ.js.map +0 -1
- package/dist/icons-CW3-oMSb.cjs +0 -24
- package/dist/icons-CW3-oMSb.cjs.map +0 -1
- package/dist/iframe-BTjZfYyh.js.map +0 -1
- package/dist/iframe-wuYT2xFz.cjs.map +0 -1
- package/dist/input-B_4g2ulO.js.map +0 -1
- package/dist/input-BrDiIT60.cjs.map +0 -1
- package/dist/lazy-CayEFyC3.cjs +0 -1
- package/dist/lazy-CayEFyC3.cjs.map +0 -1
- package/dist/lazy-D-bO2r4m.js +0 -13
- package/dist/lazy-D-bO2r4m.js.map +0 -1
- package/dist/lightbox-CVBogswK.cjs.map +0 -1
- package/dist/lightbox-D85XAAuC.js.map +0 -1
- package/dist/mixins-De1zjyhy.js.map +0 -1
- package/dist/mixins-DxHpyMHA.cjs.map +0 -1
- package/dist/notification-BtAK7NK8.js.map +0 -1
- package/dist/notification-DYzbUb5C.cjs +0 -24
- package/dist/notification-DYzbUb5C.cjs.map +0 -1
- package/dist/overlay-BVkqZmoS.cjs +0 -58
- package/dist/overlay-BVkqZmoS.cjs.map +0 -1
- package/dist/overlay-Del1sBEB.js.map +0 -1
- package/dist/overlay.confirm-body-BV9umTAl.cjs.map +0 -1
- package/dist/overlay.confirm-body-DSONXUzl.js.map +0 -1
- package/dist/overlay.service-XLlrsSdA.cjs +0 -1
- package/dist/radio-group-B-ORNtvR.cjs.map +0 -1
- package/dist/radio-group-DxX0iJBo.js.map +0 -1
- package/dist/select-B9uj_u-s.cjs +0 -56
- package/dist/select-B9uj_u-s.cjs.map +0 -1
- package/dist/select-C7gkA-ab.js.map +0 -1
- package/dist/sound.service-C7FDY_yD.cjs.map +0 -1
- package/dist/sound.service-O0232os6.js.map +0 -1
- package/dist/splash-screen-DIS4odDr.cjs.map +0 -1
- package/dist/splash-screen-jfE47xl0.js.map +0 -1
- package/dist/src-BP3h-9d9.js.map +0 -1
- package/dist/src-Um_pzb-U.cjs.map +0 -1
- package/dist/textarea-BvqENhTW.js.map +0 -1
- package/dist/textarea-qr7oL8oU.cjs +0 -43
- package/dist/textarea-qr7oL8oU.cjs.map +0 -1
- package/dist/theme.service-DwLhhOmP.js.map +0 -1
- package/dist/theme.service-kn9MC025.cjs +0 -1
- package/dist/theme.service-kn9MC025.cjs.map +0 -1
- package/dist/window-BSAemI9J.cjs +0 -59
- package/dist/window-BSAemI9J.cjs.map +0 -1
- package/dist/window-ConcHirJ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-BDVyrBnk.js","names":["#state$"],"sources":["../src/window/window-manager.ts","../src/window/window-position.ts","../src/window/window.ts"],"sourcesContent":["/**\n * Window Manager — singleton service for multi-window coordination.\n *\n * Tracks all schmancy-window instances: positions, z-indices, focus, visual states.\n * Components register on connectedCallback, unregister on disconnectedCallback.\n * Focus changes, position updates, and overlap queries all flow through here.\n *\n * Follows the ThemeService singleton pattern (theme/theme.service.ts).\n *\n * Example:\n * windowManager.register('chat-1', bounds, 'bottom-right')\n * windowManager.focus('chat-1') // bumps z-index, updates focusedId\n * const overlaps = windowManager.findOverlaps(projectedBounds, 'chat-1')\n */\n\nimport { BehaviorSubject, Observable, distinctUntilChanged, map } from 'rxjs'\nimport { overlayStack } from '../utils/overlay-stack.js'\nimport type { WindowBounds, WindowRecord, WindowRegistryState, SnapTarget } from './window-registry.js'\n\nconst STORAGE_PREFIX = 'schmancy-window-'\nconst LEGACY_STORAGE_PREFIX = 'schmancy-float-'\n\nclass WindowManagerService {\n\tprivate static instance: WindowManagerService\n\n\treadonly #state$ = new BehaviorSubject<WindowRegistryState>({\n\t\twindows: new Map(),\n\t\tfocusedId: null,\n\t\tstackOrder: [],\n\t})\n\n\treadonly state$ = this.#state$.asObservable()\n\n\tprivate constructor() {}\n\n\tstatic getInstance(): WindowManagerService {\n\t\tif (!WindowManagerService.instance) {\n\t\t\tWindowManagerService.instance = new WindowManagerService()\n\t\t}\n\t\treturn WindowManagerService.instance\n\t}\n\n\t// ── Synchronous accessors ──────────────────────────────────────────\n\n\tget windows(): Map<string, WindowRecord> {\n\t\treturn this.#state$.value.windows\n\t}\n\n\tget focusedId(): string | null {\n\t\treturn this.#state$.value.focusedId\n\t}\n\n\t// ── Registration ───────────────────────────────────────────────────\n\n\tregister(id: string, initialBounds: WindowBounds, snapTarget: SnapTarget): void {\n\t\tconst state = this.#state$.value\n\t\tif (state.windows.has(id)) return\n\n\t\tconst zIndex = overlayStack.assignZIndex(id)\n\t\tconst record: WindowRecord = {\n\t\t\tid,\n\t\t\tbounds: initialBounds,\n\t\t\tvisualState: 'normal',\n\t\t\tzIndex,\n\t\t\topen: false,\n\t\t\tsnapTarget,\n\t\t}\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, record)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder })\n\t}\n\n\tunregister(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\n\t\toverlayStack.releaseId(id)\n\t\tconst windows = new Map(state.windows)\n\t\twindows.delete(id)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\t\tconst focusedId = state.focusedId === id ? null : state.focusedId\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId })\n\t}\n\n\t// ── State mutations ────────────────────────────────────────────────\n\n\tupdateBounds(id: string, bounds: WindowBounds): void {\n\t\tthis.updateRecord(id, { bounds })\n\t}\n\n\tupdateVisualState(id: string, visualState: WindowRecord['visualState']): void {\n\t\tthis.updateRecord(id, { visualState })\n\t}\n\n\tupdateOpen(id: string, open: boolean): void {\n\t\tthis.updateRecord(id, { open })\n\t}\n\n\tfocus(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\t\tif (state.focusedId === id) return\n\n\t\tconst zIndex = overlayStack.bringToFront(id)\n\t\tconst windows = new Map(state.windows)\n\t\tconst record = windows.get(id)\n\t\tif (record) {\n\t\t\twindows.set(id, { ...record, zIndex })\n\t\t}\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId: id })\n\t}\n\n\t// ── Queries ────────────────────────────────────────────────────────\n\n\tfindOverlaps(bounds: WindowBounds, excludeId: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [id, record] of this.#state$.value.windows) {\n\t\t\tif (id === excludeId) continue\n\t\t\tif (rectsOverlap(bounds, record.bounds)) {\n\t\t\t\tresult.push(record)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tgetNeighbors(id: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [otherId, record] of this.#state$.value.windows) {\n\t\t\tif (otherId !== id) result.push(record)\n\t\t}\n\t\treturn result\n\t}\n\n\t// ── Selectors ──────────────────────────────────────────────────────\n\n\tselectWindow(id: string): Observable<WindowRecord | undefined> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.windows.get(id)),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\tselectFocused(): Observable<string | null> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.focusedId),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\t// ── Persistence ────────────────────────────────────────────────────\n\n\tloadPosition(id: string): { x: number; y: number; anchor: string } | null {\n\t\ttry {\n\t\t\t// Try new key first, fall back to legacy\n\t\t\tconst raw = localStorage.getItem(STORAGE_PREFIX + id) ?? localStorage.getItem(LEGACY_STORAGE_PREFIX + id)\n\t\t\tif (!raw) return null\n\t\t\treturn JSON.parse(raw) as { x: number; y: number; anchor: string }\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\tsavePosition(id: string, data: { x: number; y: number; anchor: string }): void {\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_PREFIX + id, JSON.stringify(data))\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tclearPosition(id: string): void {\n\t\ttry {\n\t\t\tlocalStorage.removeItem(STORAGE_PREFIX + id)\n\t\t\tlocalStorage.removeItem(LEGACY_STORAGE_PREFIX + id)\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t// ── Internal ───────────────────────────────────────────────────────\n\n\tprivate updateRecord(id: string, updates: Partial<WindowRecord>): void {\n\t\tconst state = this.#state$.value\n\t\tconst record = state.windows.get(id)\n\t\tif (!record) return\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, { ...record, ...updates })\n\t\tthis.#state$.next({ ...state, windows })\n\t}\n}\n\n/** Simple rect overlap check (inline — no circular import with window-position) */\nfunction rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\nexport const windowManager = WindowManagerService.getInstance()\n","/**\n * Window Position — pure functions for overlap resolution, cascade, and snapping.\n *\n * All functions are stateless: they take window bounds and viewport dimensions,\n * return new bounds. No side effects, no DOM access, no subscriptions.\n *\n * Example:\n * const projected = { left: 100, top: 400, width: 360, height: 500 }\n * const neighbors = windowManager.findOverlaps(projected, 'my-id')\n * const resolved = resolveOverlap(projected, neighbors, { width: 1440, height: 900 })\n * // → { left: 144, top: 444, width: 360, height: 500 } (cascaded away from conflict)\n */\n\nimport type { WindowBounds, WindowRecord } from './window-registry.js'\n\nconst HEAD_HEIGHT = 44\nconst CASCADE_OFFSET = HEAD_HEIGHT\nconst MAX_CASCADE_ATTEMPTS = 10\n\n/** Check if two rectangles overlap (edges touching does NOT count as overlap) */\nexport function rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\n/**\n * Resolve overlap by cascading diagonally until no conflict.\n * Shifts by (HEAD_HEIGHT, HEAD_HEIGHT) per attempt, clamped to viewport.\n */\nexport function resolveOverlap(\n\tcandidate: WindowBounds,\n\texisting: WindowRecord[],\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\tconst bounds = { ...candidate }\n\n\tfor (let attempt = 0; attempt < MAX_CASCADE_ATTEMPTS; attempt++) {\n\t\tconst hasOverlap = existing.some(w => rectsOverlap(bounds, w.bounds))\n\t\tif (!hasOverlap) break\n\n\t\tbounds.left += CASCADE_OFFSET\n\t\tbounds.top += CASCADE_OFFSET\n\t}\n\n\treturn clampToViewport(bounds, viewport)\n}\n\n/**\n * Clamp bounds so the window stays fully within the viewport.\n */\nexport function clampToViewport(\n\tbounds: WindowBounds,\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\treturn {\n\t\twidth: bounds.width,\n\t\theight: bounds.height,\n\t\tleft: Math.max(0, Math.min(bounds.left, viewport.width - bounds.width)),\n\t\ttop: Math.max(0, Math.min(bounds.top, viewport.height - bounds.height)),\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport {\n\tanimationFrameScheduler,\n\tauditTime,\n\tcatchError,\n\tEMPTY,\n\tfilter,\n\tfinalize,\n\tfrom,\n\tfromEvent,\n\tmap,\n\tmerge,\n\tObservable,\n\tswitchMap,\n\ttake,\n\ttakeUntil,\n\ttap,\n} from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\nimport type { SnapCorner, WindowBounds, WindowVisualState } from './window-registry.js'\nimport { windowManager } from './window-manager.js'\nimport { resolveOverlap } from './window-position.js'\n\nconst HEAD_HEIGHT = 48\nconst DRAG_THRESHOLD = 5\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-window')\nexport default class SchmancyWindow extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** Override the expanded panel height (e.g. '400px', '50vh'). */\n\t@property({ type: String }) expandedHeight?: string\n\t/** When true, uses a lower elevation shadow in the collapsed state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the window is anchored to. */\n\t@property({ type: String }) corner: SnapCorner = 'bottom-right'\n\t/** When true, window can be resized by the user. */\n\t@property({ type: Boolean }) resizable = false\n\t/** When true, window stays at its dragged position instead of snapping to a corner. */\n\t@property({ type: Boolean }) freePosition = false\n\t/** Visual state of the window (minimized, normal, maximized). */\n\t@property({ type: String, reflect: true }) visualState: WindowVisualState = 'normal'\n\t/** Minimum width in pixels. */\n\t@property({ type: Number }) minWidth = 280\n\t/** Minimum height in pixels. */\n\t@property({ type: Number }) minHeight = 200\n\n\t/** Whether the body is expanded. */\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\tprivate currentAnimation?: Animation\n\n\t/** Lazy rendering: body content not in DOM until first expand. */\n\t@state() private hasOpened = false\n\n\t// Internal position -- plain fields, updated directly during drag\n\tprivate position: Position = { x: 16, y: 16 }\n\t@state() private currentCorner: SnapCorner = 'bottom-right'\n\n\t// Track applied corner to avoid unnecessary style.removeProperty calls during drag\n\tprivate appliedCorner: string = ''\n\n\t// Refs\n\tprivate containerRef = createRef<HTMLElement>()\n\tprivate bodyRef = createRef<HTMLElement>()\n\tprivate headRef = createRef<HTMLElement>()\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this.currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${HEAD_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${HEAD_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate applyContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\t// Only clear position properties when corner changes (avoids 4 style invalidations per drag frame)\n\t\tif (this.appliedCorner !== this.currentCorner) {\n\t\t\tcontainer.style.removeProperty('left')\n\t\t\tcontainer.style.removeProperty('right')\n\t\t\tcontainer.style.removeProperty('top')\n\t\t\tcontainer.style.removeProperty('bottom')\n\t\t\tthis.appliedCorner = this.currentCorner\n\t\t}\n\t\tconst { x, y } = this.position\n\t\tif (this.currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this.currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate static readonly VALID_CORNERS = new Set<string>(['top-left', 'top-right', 'bottom-left', 'bottom-right'])\n\n\tprivate loadPosition() {\n\t\tconst saved = windowManager.loadPosition(this.id)\n\t\tif (saved) {\n\t\t\tthis.position = { x: saved.x, y: saved.y }\n\t\t\tif (SchmancyWindow.VALID_CORNERS.has(saved.anchor)) {\n\t\t\t\tthis.currentCorner = saved.anchor as SnapCorner\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate savePosition() {\n\t\twindowManager.savePosition(this.id, { ...this.position, anchor: this.currentCorner })\n\t}\n\n\tprivate validateBounds() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this.currentCorner.includes('right')\n\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this.position.x - rect.width : this.position.x\n\t\tconst actualTop = isBottom ? vh - this.position.y - rect.height : this.position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis.position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis.applyContainerPosition()\n\t}\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate reorientToNearestCorner(skipAnimation = false): void {\n\t\t// Free position mode: skip corner snapping\n\t\tif (this.freePosition) {\n\t\t\tthis.savePosition()\n\t\t\tconst rect = this.containerRef.value?.getBoundingClientRect()\n\t\t\tif (rect) {\n\t\t\t\twindowManager.updateBounds(this.id, { left: rect.left, top: rect.top, width: rect.width, height: rect.height })\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// F -- record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L -- calculate nearest corner using head visual center\n\t\tconst currentIsBottom = this.currentCorner.includes('bottom')\n\t\tconst headCenterX = rect.left + rect.width / 2\n\t\tconst headCenterY = currentIsBottom\n\t\t\t? rect.bottom - HEAD_HEIGHT / 2\n\t\t\t: rect.top + HEAD_HEIGHT / 2\n\t\tconst side = headCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = headCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: SnapCorner = `${vert}-${side}` as SnapCorner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis.currentCorner = newCorner\n\t\tthis.position = { x: 16, y: 16 }\n\t\tthis.applyContainerPosition()\n\t\t// Sync clip-path to new corner\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis.savePosition()\n\t\t\tconst snapRect = container.getBoundingClientRect()\n\t\t\twindowManager.updateBounds(this.id, { left: snapRect.left, top: snapRect.top, width: snapRect.width, height: snapRect.height })\n\t\t\treturn\n\t\t}\n\n\t\t// I -- invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.translate = `${dx}px ${dy}px`\n\n\t\t// P -- play: animate from the inverse offset to natural resting position\n\t\tconst flipKeyframes: Keyframe[] = [{ translate: `${dx}px ${dy}px` }, { translate: '0px 0px' }]\n\t\tconst anim = container.animate(\n\t\t\tflipKeyframes,\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) container.style.translate = ''\n\t\t\t\t// Report final resting bounds after animation completes\n\t\t\t\tconst finalRect = container.getBoundingClientRect()\n\t\t\t\twindowManager.updateBounds(this.id, { left: finalRect.left, top: finalRect.top, width: finalRect.width, height: finalRect.height })\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate drag$(): Observable<never> {\n\t\treturn new Observable(() => {\n\t\t\tconst head = this.headRef.value\n\t\t\tconst container = this.containerRef.value\n\t\t\tif (!head || !container) return\n\n\t\t\tlet didDrag = false\n\n\t\t\tconst sub = fromEvent<PointerEvent>(head, 'pointerdown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\tfilter(e => {\n\t\t\t\t\tconst tag = (e.target as HTMLElement).tagName?.toLowerCase()\n\t\t\t\t\treturn !['input', 'textarea', 'select', 'button'].includes(tag)\n\t\t\t\t\t\t&& !(e.target as HTMLElement).closest('schmancy-input, schmancy-icon-button, button, a')\n\t\t\t\t}),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t)\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(e => {\n\t\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\t\trect,\n\t\t\t\t\t\t\tvw: window.innerWidth,\n\t\t\t\t\t\t\tvh: window.innerHeight,\n\t\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\t\twasOpen,\n\t\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, rect, vw, vh, isBottom, wasOpen, pointerId }) => {\n\t\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\t\t\t\tmap(e => ({ clientX: e.clientX, clientY: e.clientY })),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst end$ = fromEvent<PointerEvent>(window, 'pointerup').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(true)\n\t\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move\n\t\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\t\t\t\t\t\t\tif (body) {\n\t\t\t\t\t\t\t\t\t\t\tbody.inert = true\n\t\t\t\t\t\t\t\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t\tconst minTop = isBottom ? HEAD_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - HEAD_HEIGHT\n\t\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\t\tthis.position = {\n\t\t\t\t\t\t\t\t\tx: this.currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.applyContainerPosition()\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\t\tthis.reorientToNearestCorner()\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(false)\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe()\n\n\t\t\treturn () => sub.unsubscribe()\n\t\t})\n\t}\n\n\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Pipeline 1: DOM setup + manager registration + drag + z-index sync\n\t\tfrom(this.updateComplete).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.currentCorner = this.corner\n\t\t\t\tthis.loadPosition()\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t\tthis.initDOMState()\n\t\t\t\t// Register with window manager\n\t\t\t\tconst container = this.containerRef.value\n\t\t\t\tif (container) {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst bounds: WindowBounds = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n\t\t\t\t\twindowManager.register(this.id, bounds, this.freePosition ? 'free' : this.currentCorner)\n\t\t\t\t}\n\t\t\t}),\n\t\t\tswitchMap(() => merge(\n\t\t\t\tthis.drag$(),\n\t\t\t\twindowManager.selectWindow(this.id).pipe(\n\t\t\t\t\ttap(record => {\n\t\t\t\t\t\tif (!record) return\n\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\tif (container) container.style.zIndex = String(record.zIndex)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\n\t\t// Pipeline 3: Environment -- one subscription\n\t\tmerge(\n\t\t\tfromEvent(window, 'resize').pipe(\n\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\ttap(() => this.validateBounds()),\n\t\t\t),\n\t\t\ttheme.bottomOffset$.pipe(\n\t\t\t\ttap(() => this.applyContainerPosition()),\n\t\t\t),\n\t\t).pipe(takeUntil(this.disconnecting)).subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\twindowManager.unregister(this.id)\n\t}\n\n\tprivate initDOMState() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.applyContainerPosition()\n\n\t\tif (this.open) {\n\t\t\tthis.hasOpened = true\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (body) {\n\t\t\t\tbody.inert = false\n\t\t\t\tbody.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (body) {\n\t\t\t\tbody.inert = true\n\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate animateOpen() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.hasOpened = true\n\t\tthis.open = true\n\n\t\t// Overlap avoidance\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst projectedBounds: WindowBounds = {\n\t\t\tleft: rect.left,\n\t\t\ttop: this.isBottomCorner ? rect.top - 400 : rect.top,\n\t\t\twidth: rect.width,\n\t\t\theight: 400 + HEAD_HEIGHT,\n\t\t}\n\t\tconst overlaps = windowManager.findOverlaps(projectedBounds, this.id)\n\t\tif (overlaps.length > 0) {\n\t\t\tconst resolved = resolveOverlap(projectedBounds, overlaps, { width: window.innerWidth, height: window.innerHeight })\n\t\t\tif (Math.abs(resolved.left - projectedBounds.left) > 10 || Math.abs(resolved.top - projectedBounds.top) > 10) {\n\t\t\t\tconst isRight = this.currentCorner.includes('right')\n\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\tthis.position = {\n\t\t\t\t\tx: isRight ? window.innerWidth - resolved.left - resolved.width : resolved.left,\n\t\t\t\t\ty: isBottom ? window.innerHeight - resolved.top - resolved.height : resolved.top,\n\t\t\t\t}\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t}\n\t\t}\n\n\t\tif (body) {\n\t\t\tbody.style.visibility = 'visible'\n\t\t\tbody.inert = false\n\t\t}\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) {\n\t\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\t\tcontainer.style.overflow = ''\n\t\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\t}\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t}\n\n\tprivate animateClose() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst body = this.bodyRef.value\n\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.7),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.open = false\n\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t}\n\n\t// ============================================\n\t// VISUAL STATE HELPERS\n\t// ============================================\n\n\t/** Apply drag visuals directly on DOM refs — avoids full Lit re-render for cursor + opacity */\n\tprivate applyDragVisuals(dragging: boolean) {\n\t\tconst head = this.headRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (head) {\n\t\t\thead.classList.toggle('cursor-grabbing', dragging)\n\t\t\thead.classList.toggle('cursor-move', !dragging)\n\t\t}\n\t\tif (container) {\n\t\t\tcontainer.style.opacity = dragging ? '0.95' : ''\n\t\t}\n\t}\n\n\tprivate handleFocus = () => windowManager.focus(this.id)\n\n\tprivate handleHeadKeydown = (e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\te.preventDefault()\n\t\t\tthis.toggle()\n\t\t\treturn\n\t\t}\n\t\tif (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n\t\t\te.preventDefault()\n\t\t\tconst step = e.shiftKey ? 20 : 5\n\t\t\tconst dx = e.key === 'ArrowRight' ? step : e.key === 'ArrowLeft' ? -step : 0\n\t\t\tconst dy = e.key === 'ArrowDown' ? step : e.key === 'ArrowUp' ? -step : 0\n\t\t\tthis.position = { x: this.position.x + dx, y: this.position.y + dy }\n\t\t\tthis.applyContainerPosition()\n\t\t\tthis.savePosition()\n\t\t}\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this.animateClose()\n\t\telse this.animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.animateOpen()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tthis.animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this.currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tfixed: true,\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst bodyStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'cursor-move': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t\t@pointerdown=${this.handleFocus}\n\t\t\t>\n\t\t\t\t<!-- Details section (visually above summary for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this.bodyRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${bodyStyles}\n\t\t\t\t\trole=\"region\"\n\t\t\t\t\taria-label=\"Expandable content\"\n\t\t\t\t>\n\t\t\t\t\t${this.hasOpened ? html`<slot name=\"details\"></slot>` : nothing}\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Summary section -- always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-lowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${HEAD_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this.headRef)}\n\t\t\t\t\t\t${cursorGlow({ radius: 200, intensity: 0.10 })}\n\t\t\t\t\t\tclass=${headClasses}\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\ttitle=\"Drag to move, click to expand\"\n\t\t\t\t\t\taria-label=\"${this.open ? 'Collapse window' : 'Expand window'}\"\n\t\t\t\t\t\t@keydown=${this.handleHeadKeydown}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\twidth=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n\t\t\t\t\t\t\tclass=\"shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open ? 'rotate-180' : ''}\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-window': SchmancyWindow\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-C41uPa6l.cjs`);require(`./mixins-fIpzhVMd.cjs`);const t=require(`./animation-CCOIW4wJ.cjs`),n=require(`./reduced-motion-Ds-HjMzn.cjs`),r=require(`./cursor-glow-Bulq-38P.cjs`),i=require(`./theme.service-B15FdjOS.cjs`),a=require(`./overlay-stack-Bdr9lOqi.cjs`);let o=require(`rxjs`),s=require(`lit/directives/class-map.js`),c=require(`lit/directives/style-map.js`),l=require(`lit/decorators.js`),u=require(`lit`),d=require(`lit/directives/ref.js`);var f=`schmancy-window-`,p=`schmancy-float-`;function m(e,t){return!(e.left>=t.left+t.width||e.left+e.width<=t.left||e.top>=t.top+t.height||e.top+e.height<=t.top)}var h,g=class e{#e;constructor(){this.#e=new o.BehaviorSubject({windows:new Map,focusedId:null,stackOrder:[]}),this.state$=this.#e.asObservable()}static getInstance(){return e.instance||=new e,e.instance}get windows(){return this.#e.value.windows}get focusedId(){return this.#e.value.focusedId}register(e,t,n){let r=this.#e.value;if(r.windows.has(e))return;let i={id:e,bounds:t,visualState:`normal`,zIndex:a.t.assignZIndex(e),open:!1,snapTarget:n},o=new Map(r.windows);o.set(e,i);let s=a.t.getStackOrder();this.#e.next({...r,windows:o,stackOrder:s})}unregister(e){let t=this.#e.value;if(!t.windows.has(e))return;a.t.releaseId(e);let n=new Map(t.windows);n.delete(e);let r=a.t.getStackOrder(),i=t.focusedId===e?null:t.focusedId;this.#e.next({...t,windows:n,stackOrder:r,focusedId:i})}updateBounds(e,t){this.updateRecord(e,{bounds:t})}updateVisualState(e,t){this.updateRecord(e,{visualState:t})}updateOpen(e,t){this.updateRecord(e,{open:t})}focus(e){let t=this.#e.value;if(!t.windows.has(e)||t.focusedId===e)return;let n=a.t.bringToFront(e),r=new Map(t.windows),i=r.get(e);i&&r.set(e,{...i,zIndex:n});let o=a.t.getStackOrder();this.#e.next({...t,windows:r,stackOrder:o,focusedId:e})}findOverlaps(e,t){let n=[];for(let[r,i]of this.#e.value.windows)r!==t&&m(e,i.bounds)&&n.push(i);return n}getNeighbors(e){let t=[];for(let[n,r]of this.#e.value.windows)n!==e&&t.push(r);return t}selectWindow(e){return this.#e.pipe((0,o.map)(t=>t.windows.get(e)),(0,o.distinctUntilChanged)())}selectFocused(){return this.#e.pipe((0,o.map)(e=>e.focusedId),(0,o.distinctUntilChanged)())}loadPosition(e){try{let t=localStorage.getItem(f+e)??localStorage.getItem(p+e);return t?JSON.parse(t):null}catch{return null}}savePosition(e,t){try{localStorage.setItem(f+e,JSON.stringify(t))}catch{}}clearPosition(e){try{localStorage.removeItem(f+e),localStorage.removeItem(p+e)}catch{}}updateRecord(e,t){let n=this.#e.value,r=n.windows.get(e);if(!r)return;let i=new Map(n.windows);i.set(e,{...r,...t}),this.#e.next({...n,windows:i})}}.getInstance();function _(e,t,n){let r={...e};for(let e=0;e<10&&t.some(e=>{return t=r,n=e.bounds,!(t.left>=n.left+n.width||t.left+t.width<=n.left||t.top>=n.top+n.height||t.top+t.height<=n.top);var t,n});e++)r.left+=44,r.top+=44;return function(e,t){return{width:e.width,height:e.height,left:Math.max(0,Math.min(e.left,t.width-e.width)),top:Math.max(0,Math.min(e.top,t.height-e.height))}}(r,n)}var v=48,y=class extends e.t{static{h=this}constructor(...e){super(...e),this.id=`default`,this.lowered=!1,this.corner=`bottom-right`,this.resizable=!1,this.freePosition=!1,this.visualState=`normal`,this.minWidth=280,this.minHeight=200,this.open=!1,this.hasOpened=!1,this.position={x:16,y:16},this.currentCorner=`bottom-right`,this.appliedCorner=``,this.containerRef=(0,d.createRef)(),this.bodyRef=(0,d.createRef)(),this.headRef=(0,d.createRef)(),this.handleFocus=()=>g.focus(this.id),this.handleHeadKeydown=e=>{if(e.key===`Enter`||e.key===` `)return e.preventDefault(),void this.toggle();if(e.key===`ArrowUp`||e.key===`ArrowDown`||e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let t=e.shiftKey?20:5,n=e.key===`ArrowRight`?t:e.key===`ArrowLeft`?-t:0,r=e.key===`ArrowDown`?t:e.key===`ArrowUp`?-t:0;this.position={x:this.position.x+n,y:this.position.y+r},this.applyContainerPosition(),this.savePosition()}}}static{this.styles=[u.css`
|
|
2
|
+
:host {
|
|
3
|
+
display: contents;
|
|
4
|
+
position: relative;
|
|
5
|
+
z-index: 1000;
|
|
6
|
+
}
|
|
7
|
+
:host([hidden]) {
|
|
8
|
+
display: none !important;
|
|
9
|
+
}
|
|
10
|
+
`]}get panelWidth(){return this.expandedWidth??`min(360px, calc(100vw - 32px))`}get isBottomCorner(){return this.currentCorner.startsWith(`bottom`)}get closedClipPath(){return this.isBottomCorner?`inset(calc(100% - 48px) 0px 0px 0px round 22px)`:`inset(0px 0px calc(100% - 48px) 0px round 22px)`}get openClipPath(){return`inset(0px 0px 0px 0px round 12px)`}get elevation(){return this.open?4:this.lowered?1:3}applyContainerPosition(){let e=this.containerRef.value;if(!e)return;this.appliedCorner!==this.currentCorner&&(e.style.removeProperty(`left`),e.style.removeProperty(`right`),e.style.removeProperty(`top`),e.style.removeProperty(`bottom`),this.appliedCorner=this.currentCorner);let{x:t,y:n}=this.position;this.currentCorner.includes(`right`)?e.style.right=`${t}px`:e.style.left=`${t}px`,this.currentCorner.includes(`bottom`)?e.style.bottom=`${n+i.n.bottomOffset}px`:e.style.top=`${n}px`}static{this.VALID_CORNERS=new Set([`top-left`,`top-right`,`bottom-left`,`bottom-right`])}loadPosition(){let e=g.loadPosition(this.id);e&&(this.position={x:e.x,y:e.y},h.VALID_CORNERS.has(e.anchor)&&(this.currentCorner=e.anchor))}savePosition(){g.savePosition(this.id,{...this.position,anchor:this.currentCorner})}validateBounds(){let e=this.containerRef.value;if(!e)return;let t=e.getBoundingClientRect();if(t.width===0)return;let n=window.innerWidth,r=window.innerHeight,i=this.currentCorner.includes(`right`),a=this.currentCorner.includes(`bottom`),o=i?n-this.position.x-t.width:this.position.x,s=a?r-this.position.y-t.height:this.position.y,c=Math.max(0,Math.min(o,n-t.width)),l=Math.max(0,Math.min(s,r-t.height));this.position={x:i?n-c-t.width:c,y:a?r-l-t.height:l},this.applyContainerPosition()}reorientToNearestCorner(e=!1){if(this.freePosition){this.savePosition();let e=this.containerRef.value?.getBoundingClientRect();e&&g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height});return}let r=this.containerRef.value;if(!r)return;let i=r.getBoundingClientRect(),a=this.currentCorner.includes(`bottom`),s=i.left+i.width/2,c=a?i.bottom-24:i.top+24,l=s>window.innerWidth/2?`right`:`left`,u=`${c>window.innerHeight/2?`bottom`:`top`}-${l}`;if(this.currentCorner=u,this.position={x:16,y:16},this.applyContainerPosition(),this.open||(r.style.clipPath=this.closedClipPath),e||n.t.value){this.savePosition();let e=r.getBoundingClientRect();g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height});return}let d=r.getBoundingClientRect(),f=i.left-d.left,p=i.top-d.top;r.style.translate=`${f}px ${p}px`;let m=[{translate:`${f}px ${p}px`},{translate:`0px 0px`}];(0,o.from)(r.animate(m,{duration:t.d.duration,easing:t.d.easingFallback,fill:`forwards`}).finished).pipe((0,o.take)(1),(0,o.tap)(()=>{r.isConnected&&(r.style.translate=``);let e=r.getBoundingClientRect();g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height})}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.savePosition()}drag$(){return new o.Observable(()=>{let e=this.headRef.value,t=this.containerRef.value;if(!e||!t)return;let n=!1,r=(0,o.fromEvent)(e,`pointerdown`).pipe((0,o.filter)(e=>e.button===0),(0,o.filter)(e=>{let t=e.target.tagName?.toLowerCase();return![`input`,`textarea`,`select`,`button`].includes(t)&&!e.target.closest(`schmancy-input, schmancy-icon-button, button, a`)}),(0,o.tap)(e=>{e.preventDefault(),e.stopPropagation()})).pipe((0,o.map)(e=>{let r=t.getBoundingClientRect(),i=this.currentCorner.includes(`bottom`),a=this.open;return n=!1,{startX:e.clientX,startY:e.clientY,offsetX:e.clientX-r.left,offsetY:e.clientY-r.top,rect:r,vw:window.innerWidth,vh:window.innerHeight,isBottom:i,wasOpen:a,pointerId:e.pointerId}}),(0,o.switchMap)(({startX:e,startY:r,offsetX:i,offsetY:a,rect:s,vw:c,vh:l,isBottom:u,wasOpen:d,pointerId:f})=>{let p=(0,o.fromEvent)(window,`pointermove`).pipe((0,o.filter)(e=>e.pointerId===f),(0,o.auditTime)(0,o.animationFrameScheduler),(0,o.map)(e=>({clientX:e.clientX,clientY:e.clientY}))),m=(0,o.fromEvent)(window,`pointerup`).pipe((0,o.filter)(e=>e.pointerId===f));return p.pipe((0,o.tap)(({clientX:o,clientY:f})=>{let p=o-e,m=f-r;if(Math.sqrt(p*p+m*m)>5&&!n&&(n=!0,this.applyDragVisuals(!0),d)){this.open=!1,t.style.clipPath=this.closedClipPath,t.style.overflow=`hidden`;let e=this.bodyRef.value;e&&(e.inert=!0,e.style.visibility=`hidden`)}if(!n)return;let h=Math.max(0,Math.min(o-i,c-s.width)),g=u?v-s.height:0,_=u?l-s.height:l-v,y=Math.max(g,Math.min(f-a,_));this.position={x:this.currentCorner.includes(`right`)?c-h-s.width:h,y:u?l-y-s.height:y},this.applyContainerPosition()}),(0,o.takeUntil)(m),(0,o.finalize)(()=>{n?(this.reorientToNearestCorner(),this.applyDragVisuals(!1),n=!1):(n=!1,this.toggle())}))})).subscribe();return()=>r.unsubscribe()})}connectedCallback(){super.connectedCallback(),(0,o.from)(this.updateComplete).pipe((0,o.take)(1),(0,o.tap)(()=>{this.currentCorner=this.corner,this.loadPosition(),this.applyContainerPosition(),this.initDOMState();let e=this.containerRef.value;if(e){let t=e.getBoundingClientRect(),n={left:t.left,top:t.top,width:t.width,height:t.height};g.register(this.id,n,this.freePosition?`free`:this.currentCorner)}}),(0,o.switchMap)(()=>(0,o.merge)(this.drag$(),g.selectWindow(this.id).pipe((0,o.tap)(e=>{if(!e)return;let t=this.containerRef.value;t&&(t.style.zIndex=String(e.zIndex))})))),(0,o.takeUntil)(this.disconnecting)).subscribe(),(0,o.merge)((0,o.fromEvent)(window,`resize`).pipe((0,o.auditTime)(0,o.animationFrameScheduler),(0,o.tap)(()=>this.validateBounds())),i.n.bottomOffset$.pipe((0,o.tap)(()=>this.applyContainerPosition()))).pipe((0,o.takeUntil)(this.disconnecting)).subscribe()}disconnectedCallback(){super.disconnectedCallback(),g.unregister(this.id)}initDOMState(){let e=this.containerRef.value,t=this.bodyRef.value;e&&(this.applyContainerPosition(),this.open?(this.hasOpened=!0,e.style.overflow=``,t&&(t.inert=!1,t.style.visibility=`visible`)):(e.style.clipPath=this.closedClipPath,e.style.overflow=`hidden`,t&&(t.inert=!0,t.style.visibility=`hidden`)))}animateOpen(){let e=this.containerRef.value,r=this.bodyRef.value;if(!e)return;this.hasOpened=!0,this.open=!0;let i=e.getBoundingClientRect(),a={left:i.left,top:this.isBottomCorner?i.top-400:i.top,width:i.width,height:448},s=g.findOverlaps(a,this.id);if(s.length>0){let e=_(a,s,{width:window.innerWidth,height:window.innerHeight});if(Math.abs(e.left-a.left)>10||Math.abs(e.top-a.top)>10){let t=this.currentCorner.includes(`right`),n=this.currentCorner.includes(`bottom`);this.position={x:t?window.innerWidth-e.left-e.width:e.left,y:n?window.innerHeight-e.top-e.height:e.top},this.applyContainerPosition()}}if(r&&(r.style.visibility=`visible`,r.inert=!1),n.t.value)return e.style.clipPath=``,e.style.overflow=``,void this.dispatchScopedEvent(`window-toggle`,{state:`expanded`});this.currentAnimation?.cancel(),e.style.overflow=`hidden`,e.style.willChange=`opacity`;let c=[{clipPath:this.closedClipPath,opacity:.95},{clipPath:this.openClipPath,opacity:1}],l=e.animate(c,{duration:t.f.duration,easing:t.f.easingFallback,fill:`forwards`});this.currentAnimation=l,(0,o.from)(l.finished).pipe((0,o.take)(1),(0,o.tap)(()=>{e.isConnected&&(e.style.clipPath=``,e.style.overflow=``,e.style.willChange=``)}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.dispatchScopedEvent(`window-toggle`,{state:`expanded`})}animateClose(){let e=this.containerRef.value;if(!e)return;if(n.t.value){e.style.clipPath=this.closedClipPath,e.style.overflow=`hidden`,this.open=!1;let t=this.bodyRef.value;t&&(t.inert=!0,t.style.visibility=`hidden`),this.dispatchScopedEvent(`window-toggle`,{state:`collapsed`});return}this.currentAnimation?.cancel(),e.style.overflow=`hidden`,e.style.willChange=`opacity`;let r=[{clipPath:this.openClipPath,opacity:1},{clipPath:this.closedClipPath,opacity:.95}],i=e.animate(r,{duration:Math.round(.7*t.f.duration),easing:`cubic-bezier(0.4, 0, 0.8, 0.15)`,fill:`forwards`});this.currentAnimation=i,(0,o.from)(i.finished).pipe((0,o.take)(1),(0,o.tap)(()=>{this.open=!1,e.style.willChange=``;let t=this.bodyRef.value;t&&(t.inert=!0,t.style.visibility=`hidden`)}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.dispatchScopedEvent(`window-toggle`,{state:`collapsed`})}applyDragVisuals(e){let t=this.headRef.value,n=this.containerRef.value;t&&(t.classList.toggle(`cursor-grabbing`,e),t.classList.toggle(`cursor-move`,!e)),n&&(n.style.opacity=e?`0.95`:``)}toggle(){this.open?this.animateClose():this.animateOpen()}expand(){this.open||this.animateOpen()}close(){this.open&&this.animateClose()}render(){let e=this.currentCorner.startsWith(`bottom`),t=(0,s.classMap)({fixed:!0,flex:!0,"flex-col":e,"flex-col-reverse":!e,"z-1000":!0,"rounded-2xl":this.open,"rounded-[22px]":!this.open,"overflow-hidden":!0}),n=(0,c.styleMap)({width:this.panelWidth,"max-height":`calc(100vh - 32px)`,"pointer-events":`none`}),i=(0,c.styleMap)({"pointer-events":this.open?`auto`:`none`}),a=(0,s.classMap)({"h-full":!0,"px-3":!0,flex:!0,"items-center":!0,"gap-2":!0,"select-none":!0,"cursor-move":!0});return u.html`
|
|
11
|
+
<schmancy-surface
|
|
12
|
+
${(0,d.ref)(this.containerRef)}
|
|
13
|
+
type="glass"
|
|
14
|
+
.elevation=${this.elevation}
|
|
15
|
+
class=${t}
|
|
16
|
+
style=${n}
|
|
17
|
+
aria-expanded=${this.open}
|
|
18
|
+
@pointerdown=${this.handleFocus}
|
|
19
|
+
>
|
|
20
|
+
<!-- Details section (visually above summary for bottom corners) -->
|
|
21
|
+
<section
|
|
22
|
+
${(0,d.ref)(this.bodyRef)}
|
|
23
|
+
class="flex-1 min-h-0 overflow-hidden flex flex-col"
|
|
24
|
+
style=${i}
|
|
25
|
+
role="region"
|
|
26
|
+
aria-label="Expandable content"
|
|
27
|
+
>
|
|
28
|
+
${this.hasOpened?u.html`<slot name="details"></slot>`:u.nothing}
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
<!-- Summary section -- always interactive, always visible -->
|
|
32
|
+
<section
|
|
33
|
+
class="shrink-0 bg-surface-lowest"
|
|
34
|
+
style=${(0,c.styleMap)({"pointer-events":`auto`,height:`48px`})}
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
${(0,d.ref)(this.headRef)}
|
|
38
|
+
${r.t({radius:200,intensity:.1})}
|
|
39
|
+
class=${a}
|
|
40
|
+
role="button"
|
|
41
|
+
tabindex="0"
|
|
42
|
+
title="Drag to move, click to expand"
|
|
43
|
+
aria-label="${this.open?`Collapse window`:`Expand window`}"
|
|
44
|
+
@keydown=${this.handleHeadKeydown}
|
|
45
|
+
>
|
|
46
|
+
<div class="flex-1 min-w-0">
|
|
47
|
+
<slot></slot>
|
|
48
|
+
</div>
|
|
49
|
+
<svg
|
|
50
|
+
width="16" height="16" viewBox="0 0 24 24" fill="none"
|
|
51
|
+
class="shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open?`rotate-180`:``}"
|
|
52
|
+
aria-hidden="true"
|
|
53
|
+
>
|
|
54
|
+
<path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
55
|
+
</svg>
|
|
56
|
+
</div>
|
|
57
|
+
</section>
|
|
58
|
+
</schmancy-surface>
|
|
59
|
+
`}};e.u([(0,l.property)({type:String})],y.prototype,`id`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`expandedWidth`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`expandedHeight`,void 0),e.u([(0,l.property)({type:Boolean,reflect:!0})],y.prototype,`lowered`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`corner`,void 0),e.u([(0,l.property)({type:Boolean})],y.prototype,`resizable`,void 0),e.u([(0,l.property)({type:Boolean})],y.prototype,`freePosition`,void 0),e.u([(0,l.property)({type:String,reflect:!0})],y.prototype,`visualState`,void 0),e.u([(0,l.property)({type:Number})],y.prototype,`minWidth`,void 0),e.u([(0,l.property)({type:Number})],y.prototype,`minHeight`,void 0),e.u([(0,l.property)({type:Boolean,reflect:!0})],y.prototype,`open`,void 0),e.u([(0,l.state)()],y.prototype,`hasOpened`,void 0),e.u([(0,l.state)()],y.prototype,`currentCorner`,void 0);var b=y=h=e.u([(0,l.customElement)(`schmancy-window`)],y);Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return b}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-BbBYjm7R.cjs","names":["#state$"],"sources":["../src/window/window-manager.ts","../src/window/window-position.ts","../src/window/window.ts"],"sourcesContent":["/**\n * Window Manager — singleton service for multi-window coordination.\n *\n * Tracks all schmancy-window instances: positions, z-indices, focus, visual states.\n * Components register on connectedCallback, unregister on disconnectedCallback.\n * Focus changes, position updates, and overlap queries all flow through here.\n *\n * Follows the ThemeService singleton pattern (theme/theme.service.ts).\n *\n * Example:\n * windowManager.register('chat-1', bounds, 'bottom-right')\n * windowManager.focus('chat-1') // bumps z-index, updates focusedId\n * const overlaps = windowManager.findOverlaps(projectedBounds, 'chat-1')\n */\n\nimport { BehaviorSubject, Observable, distinctUntilChanged, map } from 'rxjs'\nimport { overlayStack } from '../utils/overlay-stack.js'\nimport type { WindowBounds, WindowRecord, WindowRegistryState, SnapTarget } from './window-registry.js'\n\nconst STORAGE_PREFIX = 'schmancy-window-'\nconst LEGACY_STORAGE_PREFIX = 'schmancy-float-'\n\nclass WindowManagerService {\n\tprivate static instance: WindowManagerService\n\n\treadonly #state$ = new BehaviorSubject<WindowRegistryState>({\n\t\twindows: new Map(),\n\t\tfocusedId: null,\n\t\tstackOrder: [],\n\t})\n\n\treadonly state$ = this.#state$.asObservable()\n\n\tprivate constructor() {}\n\n\tstatic getInstance(): WindowManagerService {\n\t\tif (!WindowManagerService.instance) {\n\t\t\tWindowManagerService.instance = new WindowManagerService()\n\t\t}\n\t\treturn WindowManagerService.instance\n\t}\n\n\t// ── Synchronous accessors ──────────────────────────────────────────\n\n\tget windows(): Map<string, WindowRecord> {\n\t\treturn this.#state$.value.windows\n\t}\n\n\tget focusedId(): string | null {\n\t\treturn this.#state$.value.focusedId\n\t}\n\n\t// ── Registration ───────────────────────────────────────────────────\n\n\tregister(id: string, initialBounds: WindowBounds, snapTarget: SnapTarget): void {\n\t\tconst state = this.#state$.value\n\t\tif (state.windows.has(id)) return\n\n\t\tconst zIndex = overlayStack.assignZIndex(id)\n\t\tconst record: WindowRecord = {\n\t\t\tid,\n\t\t\tbounds: initialBounds,\n\t\t\tvisualState: 'normal',\n\t\t\tzIndex,\n\t\t\topen: false,\n\t\t\tsnapTarget,\n\t\t}\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, record)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder })\n\t}\n\n\tunregister(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\n\t\toverlayStack.releaseId(id)\n\t\tconst windows = new Map(state.windows)\n\t\twindows.delete(id)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\t\tconst focusedId = state.focusedId === id ? null : state.focusedId\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId })\n\t}\n\n\t// ── State mutations ────────────────────────────────────────────────\n\n\tupdateBounds(id: string, bounds: WindowBounds): void {\n\t\tthis.updateRecord(id, { bounds })\n\t}\n\n\tupdateVisualState(id: string, visualState: WindowRecord['visualState']): void {\n\t\tthis.updateRecord(id, { visualState })\n\t}\n\n\tupdateOpen(id: string, open: boolean): void {\n\t\tthis.updateRecord(id, { open })\n\t}\n\n\tfocus(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\t\tif (state.focusedId === id) return\n\n\t\tconst zIndex = overlayStack.bringToFront(id)\n\t\tconst windows = new Map(state.windows)\n\t\tconst record = windows.get(id)\n\t\tif (record) {\n\t\t\twindows.set(id, { ...record, zIndex })\n\t\t}\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId: id })\n\t}\n\n\t// ── Queries ────────────────────────────────────────────────────────\n\n\tfindOverlaps(bounds: WindowBounds, excludeId: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [id, record] of this.#state$.value.windows) {\n\t\t\tif (id === excludeId) continue\n\t\t\tif (rectsOverlap(bounds, record.bounds)) {\n\t\t\t\tresult.push(record)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tgetNeighbors(id: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [otherId, record] of this.#state$.value.windows) {\n\t\t\tif (otherId !== id) result.push(record)\n\t\t}\n\t\treturn result\n\t}\n\n\t// ── Selectors ──────────────────────────────────────────────────────\n\n\tselectWindow(id: string): Observable<WindowRecord | undefined> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.windows.get(id)),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\tselectFocused(): Observable<string | null> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.focusedId),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\t// ── Persistence ────────────────────────────────────────────────────\n\n\tloadPosition(id: string): { x: number; y: number; anchor: string } | null {\n\t\ttry {\n\t\t\t// Try new key first, fall back to legacy\n\t\t\tconst raw = localStorage.getItem(STORAGE_PREFIX + id) ?? localStorage.getItem(LEGACY_STORAGE_PREFIX + id)\n\t\t\tif (!raw) return null\n\t\t\treturn JSON.parse(raw) as { x: number; y: number; anchor: string }\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\tsavePosition(id: string, data: { x: number; y: number; anchor: string }): void {\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_PREFIX + id, JSON.stringify(data))\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tclearPosition(id: string): void {\n\t\ttry {\n\t\t\tlocalStorage.removeItem(STORAGE_PREFIX + id)\n\t\t\tlocalStorage.removeItem(LEGACY_STORAGE_PREFIX + id)\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t// ── Internal ───────────────────────────────────────────────────────\n\n\tprivate updateRecord(id: string, updates: Partial<WindowRecord>): void {\n\t\tconst state = this.#state$.value\n\t\tconst record = state.windows.get(id)\n\t\tif (!record) return\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, { ...record, ...updates })\n\t\tthis.#state$.next({ ...state, windows })\n\t}\n}\n\n/** Simple rect overlap check (inline — no circular import with window-position) */\nfunction rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\nexport const windowManager = WindowManagerService.getInstance()\n","/**\n * Window Position — pure functions for overlap resolution, cascade, and snapping.\n *\n * All functions are stateless: they take window bounds and viewport dimensions,\n * return new bounds. No side effects, no DOM access, no subscriptions.\n *\n * Example:\n * const projected = { left: 100, top: 400, width: 360, height: 500 }\n * const neighbors = windowManager.findOverlaps(projected, 'my-id')\n * const resolved = resolveOverlap(projected, neighbors, { width: 1440, height: 900 })\n * // → { left: 144, top: 444, width: 360, height: 500 } (cascaded away from conflict)\n */\n\nimport type { WindowBounds, WindowRecord } from './window-registry.js'\n\nconst HEAD_HEIGHT = 44\nconst CASCADE_OFFSET = HEAD_HEIGHT\nconst MAX_CASCADE_ATTEMPTS = 10\n\n/** Check if two rectangles overlap (edges touching does NOT count as overlap) */\nexport function rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\n/**\n * Resolve overlap by cascading diagonally until no conflict.\n * Shifts by (HEAD_HEIGHT, HEAD_HEIGHT) per attempt, clamped to viewport.\n */\nexport function resolveOverlap(\n\tcandidate: WindowBounds,\n\texisting: WindowRecord[],\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\tconst bounds = { ...candidate }\n\n\tfor (let attempt = 0; attempt < MAX_CASCADE_ATTEMPTS; attempt++) {\n\t\tconst hasOverlap = existing.some(w => rectsOverlap(bounds, w.bounds))\n\t\tif (!hasOverlap) break\n\n\t\tbounds.left += CASCADE_OFFSET\n\t\tbounds.top += CASCADE_OFFSET\n\t}\n\n\treturn clampToViewport(bounds, viewport)\n}\n\n/**\n * Clamp bounds so the window stays fully within the viewport.\n */\nexport function clampToViewport(\n\tbounds: WindowBounds,\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\treturn {\n\t\twidth: bounds.width,\n\t\theight: bounds.height,\n\t\tleft: Math.max(0, Math.min(bounds.left, viewport.width - bounds.width)),\n\t\ttop: Math.max(0, Math.min(bounds.top, viewport.height - bounds.height)),\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport {\n\tanimationFrameScheduler,\n\tauditTime,\n\tcatchError,\n\tEMPTY,\n\tfilter,\n\tfinalize,\n\tfrom,\n\tfromEvent,\n\tmap,\n\tmerge,\n\tObservable,\n\tswitchMap,\n\ttake,\n\ttakeUntil,\n\ttap,\n} from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\nimport type { SnapCorner, WindowBounds, WindowVisualState } from './window-registry.js'\nimport { windowManager } from './window-manager.js'\nimport { resolveOverlap } from './window-position.js'\n\nconst HEAD_HEIGHT = 48\nconst DRAG_THRESHOLD = 5\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-window')\nexport default class SchmancyWindow extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** Override the expanded panel height (e.g. '400px', '50vh'). */\n\t@property({ type: String }) expandedHeight?: string\n\t/** When true, uses a lower elevation shadow in the collapsed state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the window is anchored to. */\n\t@property({ type: String }) corner: SnapCorner = 'bottom-right'\n\t/** When true, window can be resized by the user. */\n\t@property({ type: Boolean }) resizable = false\n\t/** When true, window stays at its dragged position instead of snapping to a corner. */\n\t@property({ type: Boolean }) freePosition = false\n\t/** Visual state of the window (minimized, normal, maximized). */\n\t@property({ type: String, reflect: true }) visualState: WindowVisualState = 'normal'\n\t/** Minimum width in pixels. */\n\t@property({ type: Number }) minWidth = 280\n\t/** Minimum height in pixels. */\n\t@property({ type: Number }) minHeight = 200\n\n\t/** Whether the body is expanded. */\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\tprivate currentAnimation?: Animation\n\n\t/** Lazy rendering: body content not in DOM until first expand. */\n\t@state() private hasOpened = false\n\n\t// Internal position -- plain fields, updated directly during drag\n\tprivate position: Position = { x: 16, y: 16 }\n\t@state() private currentCorner: SnapCorner = 'bottom-right'\n\n\t// Track applied corner to avoid unnecessary style.removeProperty calls during drag\n\tprivate appliedCorner: string = ''\n\n\t// Refs\n\tprivate containerRef = createRef<HTMLElement>()\n\tprivate bodyRef = createRef<HTMLElement>()\n\tprivate headRef = createRef<HTMLElement>()\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this.currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${HEAD_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${HEAD_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate applyContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\t// Only clear position properties when corner changes (avoids 4 style invalidations per drag frame)\n\t\tif (this.appliedCorner !== this.currentCorner) {\n\t\t\tcontainer.style.removeProperty('left')\n\t\t\tcontainer.style.removeProperty('right')\n\t\t\tcontainer.style.removeProperty('top')\n\t\t\tcontainer.style.removeProperty('bottom')\n\t\t\tthis.appliedCorner = this.currentCorner\n\t\t}\n\t\tconst { x, y } = this.position\n\t\tif (this.currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this.currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate static readonly VALID_CORNERS = new Set<string>(['top-left', 'top-right', 'bottom-left', 'bottom-right'])\n\n\tprivate loadPosition() {\n\t\tconst saved = windowManager.loadPosition(this.id)\n\t\tif (saved) {\n\t\t\tthis.position = { x: saved.x, y: saved.y }\n\t\t\tif (SchmancyWindow.VALID_CORNERS.has(saved.anchor)) {\n\t\t\t\tthis.currentCorner = saved.anchor as SnapCorner\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate savePosition() {\n\t\twindowManager.savePosition(this.id, { ...this.position, anchor: this.currentCorner })\n\t}\n\n\tprivate validateBounds() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this.currentCorner.includes('right')\n\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this.position.x - rect.width : this.position.x\n\t\tconst actualTop = isBottom ? vh - this.position.y - rect.height : this.position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis.position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis.applyContainerPosition()\n\t}\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate reorientToNearestCorner(skipAnimation = false): void {\n\t\t// Free position mode: skip corner snapping\n\t\tif (this.freePosition) {\n\t\t\tthis.savePosition()\n\t\t\tconst rect = this.containerRef.value?.getBoundingClientRect()\n\t\t\tif (rect) {\n\t\t\t\twindowManager.updateBounds(this.id, { left: rect.left, top: rect.top, width: rect.width, height: rect.height })\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// F -- record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L -- calculate nearest corner using head visual center\n\t\tconst currentIsBottom = this.currentCorner.includes('bottom')\n\t\tconst headCenterX = rect.left + rect.width / 2\n\t\tconst headCenterY = currentIsBottom\n\t\t\t? rect.bottom - HEAD_HEIGHT / 2\n\t\t\t: rect.top + HEAD_HEIGHT / 2\n\t\tconst side = headCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = headCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: SnapCorner = `${vert}-${side}` as SnapCorner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis.currentCorner = newCorner\n\t\tthis.position = { x: 16, y: 16 }\n\t\tthis.applyContainerPosition()\n\t\t// Sync clip-path to new corner\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis.savePosition()\n\t\t\tconst snapRect = container.getBoundingClientRect()\n\t\t\twindowManager.updateBounds(this.id, { left: snapRect.left, top: snapRect.top, width: snapRect.width, height: snapRect.height })\n\t\t\treturn\n\t\t}\n\n\t\t// I -- invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.translate = `${dx}px ${dy}px`\n\n\t\t// P -- play: animate from the inverse offset to natural resting position\n\t\tconst flipKeyframes: Keyframe[] = [{ translate: `${dx}px ${dy}px` }, { translate: '0px 0px' }]\n\t\tconst anim = container.animate(\n\t\t\tflipKeyframes,\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) container.style.translate = ''\n\t\t\t\t// Report final resting bounds after animation completes\n\t\t\t\tconst finalRect = container.getBoundingClientRect()\n\t\t\t\twindowManager.updateBounds(this.id, { left: finalRect.left, top: finalRect.top, width: finalRect.width, height: finalRect.height })\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate drag$(): Observable<never> {\n\t\treturn new Observable(() => {\n\t\t\tconst head = this.headRef.value\n\t\t\tconst container = this.containerRef.value\n\t\t\tif (!head || !container) return\n\n\t\t\tlet didDrag = false\n\n\t\t\tconst sub = fromEvent<PointerEvent>(head, 'pointerdown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\tfilter(e => {\n\t\t\t\t\tconst tag = (e.target as HTMLElement).tagName?.toLowerCase()\n\t\t\t\t\treturn !['input', 'textarea', 'select', 'button'].includes(tag)\n\t\t\t\t\t\t&& !(e.target as HTMLElement).closest('schmancy-input, schmancy-icon-button, button, a')\n\t\t\t\t}),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t)\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(e => {\n\t\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\t\trect,\n\t\t\t\t\t\t\tvw: window.innerWidth,\n\t\t\t\t\t\t\tvh: window.innerHeight,\n\t\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\t\twasOpen,\n\t\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, rect, vw, vh, isBottom, wasOpen, pointerId }) => {\n\t\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\t\t\t\tmap(e => ({ clientX: e.clientX, clientY: e.clientY })),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst end$ = fromEvent<PointerEvent>(window, 'pointerup').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(true)\n\t\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move\n\t\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\t\t\t\t\t\t\tif (body) {\n\t\t\t\t\t\t\t\t\t\t\tbody.inert = true\n\t\t\t\t\t\t\t\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t\tconst minTop = isBottom ? HEAD_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - HEAD_HEIGHT\n\t\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\t\tthis.position = {\n\t\t\t\t\t\t\t\t\tx: this.currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.applyContainerPosition()\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\t\tthis.reorientToNearestCorner()\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(false)\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe()\n\n\t\t\treturn () => sub.unsubscribe()\n\t\t})\n\t}\n\n\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Pipeline 1: DOM setup + manager registration + drag + z-index sync\n\t\tfrom(this.updateComplete).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.currentCorner = this.corner\n\t\t\t\tthis.loadPosition()\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t\tthis.initDOMState()\n\t\t\t\t// Register with window manager\n\t\t\t\tconst container = this.containerRef.value\n\t\t\t\tif (container) {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst bounds: WindowBounds = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n\t\t\t\t\twindowManager.register(this.id, bounds, this.freePosition ? 'free' : this.currentCorner)\n\t\t\t\t}\n\t\t\t}),\n\t\t\tswitchMap(() => merge(\n\t\t\t\tthis.drag$(),\n\t\t\t\twindowManager.selectWindow(this.id).pipe(\n\t\t\t\t\ttap(record => {\n\t\t\t\t\t\tif (!record) return\n\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\tif (container) container.style.zIndex = String(record.zIndex)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\n\t\t// Pipeline 3: Environment -- one subscription\n\t\tmerge(\n\t\t\tfromEvent(window, 'resize').pipe(\n\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\ttap(() => this.validateBounds()),\n\t\t\t),\n\t\t\ttheme.bottomOffset$.pipe(\n\t\t\t\ttap(() => this.applyContainerPosition()),\n\t\t\t),\n\t\t).pipe(takeUntil(this.disconnecting)).subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\twindowManager.unregister(this.id)\n\t}\n\n\tprivate initDOMState() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.applyContainerPosition()\n\n\t\tif (this.open) {\n\t\t\tthis.hasOpened = true\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (body) {\n\t\t\t\tbody.inert = false\n\t\t\t\tbody.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (body) {\n\t\t\t\tbody.inert = true\n\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate animateOpen() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.hasOpened = true\n\t\tthis.open = true\n\n\t\t// Overlap avoidance\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst projectedBounds: WindowBounds = {\n\t\t\tleft: rect.left,\n\t\t\ttop: this.isBottomCorner ? rect.top - 400 : rect.top,\n\t\t\twidth: rect.width,\n\t\t\theight: 400 + HEAD_HEIGHT,\n\t\t}\n\t\tconst overlaps = windowManager.findOverlaps(projectedBounds, this.id)\n\t\tif (overlaps.length > 0) {\n\t\t\tconst resolved = resolveOverlap(projectedBounds, overlaps, { width: window.innerWidth, height: window.innerHeight })\n\t\t\tif (Math.abs(resolved.left - projectedBounds.left) > 10 || Math.abs(resolved.top - projectedBounds.top) > 10) {\n\t\t\t\tconst isRight = this.currentCorner.includes('right')\n\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\tthis.position = {\n\t\t\t\t\tx: isRight ? window.innerWidth - resolved.left - resolved.width : resolved.left,\n\t\t\t\t\ty: isBottom ? window.innerHeight - resolved.top - resolved.height : resolved.top,\n\t\t\t\t}\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t}\n\t\t}\n\n\t\tif (body) {\n\t\t\tbody.style.visibility = 'visible'\n\t\t\tbody.inert = false\n\t\t}\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) {\n\t\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\t\tcontainer.style.overflow = ''\n\t\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\t}\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t}\n\n\tprivate animateClose() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst body = this.bodyRef.value\n\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.7),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.open = false\n\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t}\n\n\t// ============================================\n\t// VISUAL STATE HELPERS\n\t// ============================================\n\n\t/** Apply drag visuals directly on DOM refs — avoids full Lit re-render for cursor + opacity */\n\tprivate applyDragVisuals(dragging: boolean) {\n\t\tconst head = this.headRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (head) {\n\t\t\thead.classList.toggle('cursor-grabbing', dragging)\n\t\t\thead.classList.toggle('cursor-move', !dragging)\n\t\t}\n\t\tif (container) {\n\t\t\tcontainer.style.opacity = dragging ? '0.95' : ''\n\t\t}\n\t}\n\n\tprivate handleFocus = () => windowManager.focus(this.id)\n\n\tprivate handleHeadKeydown = (e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\te.preventDefault()\n\t\t\tthis.toggle()\n\t\t\treturn\n\t\t}\n\t\tif (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n\t\t\te.preventDefault()\n\t\t\tconst step = e.shiftKey ? 20 : 5\n\t\t\tconst dx = e.key === 'ArrowRight' ? step : e.key === 'ArrowLeft' ? -step : 0\n\t\t\tconst dy = e.key === 'ArrowDown' ? step : e.key === 'ArrowUp' ? -step : 0\n\t\t\tthis.position = { x: this.position.x + dx, y: this.position.y + dy }\n\t\t\tthis.applyContainerPosition()\n\t\t\tthis.savePosition()\n\t\t}\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this.animateClose()\n\t\telse this.animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.animateOpen()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tthis.animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this.currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tfixed: true,\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst bodyStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'cursor-move': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t\t@pointerdown=${this.handleFocus}\n\t\t\t>\n\t\t\t\t<!-- Details section (visually above summary for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this.bodyRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${bodyStyles}\n\t\t\t\t\trole=\"region\"\n\t\t\t\t\taria-label=\"Expandable content\"\n\t\t\t\t>\n\t\t\t\t\t${this.hasOpened ? html`<slot name=\"details\"></slot>` : nothing}\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Summary section -- always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-lowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${HEAD_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this.headRef)}\n\t\t\t\t\t\t${cursorGlow({ radius: 200, intensity: 0.10 })}\n\t\t\t\t\t\tclass=${headClasses}\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\ttitle=\"Drag to move, click to expand\"\n\t\t\t\t\t\taria-label=\"${this.open ? 'Collapse window' : 'Expand window'}\"\n\t\t\t\t\t\t@keydown=${this.handleHeadKeydown}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\twidth=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n\t\t\t\t\t\t\tclass=\"shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open ? 'rotate-180' : ''}\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-window': SchmancyWindow\n\t}\n}\n"],"mappings":"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"}
|
package/dist/window.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./window-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./window-BbBYjm7R.cjs`);exports.SchmancyWindow=e.t,exports.windowManager=e.n;
|
package/dist/window.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./window-
|
|
1
|
+
import { n as e, t } from "./window-BDVyrBnk.js";
|
|
2
2
|
export { t as SchmancyWindow, e as windowManager };
|
package/package.json
CHANGED
package/skills/schmancy/SKILL.md
CHANGED
|
@@ -99,6 +99,9 @@ A value-controlled `<schmancy-*>` component (`schmancy-steps`, `schmancy-input`,
|
|
|
99
99
|
- `await state.ready` (or `if (state.loaded)`) before reading persisted-backend values that hydrate asynchronously.
|
|
100
100
|
- Storage tiers: `.memory()` (regenerable) · `.session()` (per-tab) · `.local()` (user prefs) · `.idb()` (>100-entry collections).
|
|
101
101
|
|
|
102
|
+
**SIGNAL_TRACKING_BEYOND_RENDER**
|
|
103
|
+
A `SchmancyElement` makes any imperative side-effect reactive to signal changes by running it inside `this.updateEffect(fn, { manualDispose: true })`, which applies the same auto-tracking the component's `render()` receives to any arbitrary effect and returns a disposer for integration with the component's teardown path.
|
|
104
|
+
|
|
102
105
|
**Routing**
|
|
103
106
|
- Route guards are `Observable<boolean>`, never cached booleans.
|
|
104
107
|
- `when="tag-name"` must exactly match `@customElement('tag-name')`.
|
|
@@ -162,6 +165,12 @@ html`
|
|
|
162
165
|
|
|
163
166
|
See `layout.md` for the full shell pattern with rail + content area.
|
|
164
167
|
|
|
168
|
+
## Rules
|
|
169
|
+
|
|
170
|
+
### INLINE_FLEX_HOST_NO_SHRINK
|
|
171
|
+
|
|
172
|
+
A web-component host that establishes `inline-flex` layout declares `flex-shrink: 0` in its `:host` block so it preserves its intrinsic content size regardless of the flex container it lands in.
|
|
173
|
+
|
|
165
174
|
## Workflow
|
|
166
175
|
|
|
167
176
|
1. User describes a UI task.
|
|
@@ -14,17 +14,24 @@ import {
|
|
|
14
14
|
|
|
15
15
|
## The novel default — anchored
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Schmancy tracks the last user gesture automatically. When you call `show()` from a `@click` handler, the overlay positions itself near the interaction point without you passing anything:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
private handlePick = (
|
|
21
|
-
show(TemplatePicker, {
|
|
20
|
+
private handlePick = () => {
|
|
21
|
+
show(TemplatePicker, { props: { kind: 'email' } })
|
|
22
22
|
.pipe(takeUntil(this.disconnecting))
|
|
23
23
|
.subscribe(picked => { if (picked) this.template = picked })
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Pass `anchor` explicitly only when the gesture and the `show()` call are decoupled — e.g. the click fires in a child component but `show()` runs in a parent, or you're opening from a programmatic trigger with no gesture context:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
show(Picker, { anchor: ev }) // explicit — only when gesture context is lost
|
|
31
|
+
show(Picker) // idiomatic — gesture tracked automatically
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Centered is the fallback when there is genuinely no gesture context. Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout — the system does.
|
|
28
35
|
|
|
29
36
|
## Content forms
|
|
30
37
|
|
|
@@ -33,11 +40,11 @@ Centered is the fallback (no anchor given). Sheet is the responsive adaptation (
|
|
|
33
40
|
| Form | When to use |
|
|
34
41
|
|---|---|
|
|
35
42
|
| `show(MyComponent)` | Component class — most common |
|
|
36
|
-
| `show(html\`...\`)` | Inline template (eager —
|
|
37
|
-
| `show(() => html\`...\`)` | **
|
|
43
|
+
| `show(html\`...\`)` | Inline template (eager — a frozen one-shot snapshot, never re-renders) |
|
|
44
|
+
| `show(() => html\`...\`)` | **Reactive form** — factory re-invoked when any signal it reads changes (parity with a component's render()); closed-over variables always current |
|
|
38
45
|
| `show(lazy(() => import('./x')))` | Async / code-split component |
|
|
39
46
|
|
|
40
|
-
Always prefer `() => html\`...\`` over `html
|
|
47
|
+
Always prefer `() => html\`...\`` over `html\`...\``: the factory form is reactive — the overlay re-runs it whenever a signal it reads changes, exactly like a component's `render()`. The eager `html\`...\`` form is a frozen snapshot captured at the call site and never updates. Bind `.value=${someState.value}` inside a factory and the overlay content tracks the state live.
|
|
41
48
|
|
|
42
49
|
## Default padding
|
|
43
50
|
|
|
@@ -245,7 +245,7 @@ export class SchmancyArea extends SchmancyElement {
|
|
|
245
245
|
area.$current.next(area.current)
|
|
246
246
|
|
|
247
247
|
if (area.enableHistoryMode) {
|
|
248
|
-
area.
|
|
248
|
+
area.updateBrowserHistory(
|
|
249
249
|
this.name,
|
|
250
250
|
activeRoute,
|
|
251
251
|
carry.historyStrategy ?? HISTORY_STRATEGY.push,
|
|
@@ -938,8 +938,8 @@ describe('AreaService - Integration Tests', () => {
|
|
|
938
938
|
props: {}
|
|
939
939
|
})
|
|
940
940
|
|
|
941
|
-
// Call
|
|
942
|
-
area.
|
|
941
|
+
// Call updateBrowserHistory directly to test history behavior
|
|
942
|
+
area.updateBrowserHistory('main', {
|
|
943
943
|
area: 'main',
|
|
944
944
|
component: 'test',
|
|
945
945
|
state: {},
|
package/src/area/area.service.ts
CHANGED
|
@@ -352,7 +352,7 @@ class AreaService implements AreaSubscription {
|
|
|
352
352
|
/**
|
|
353
353
|
* Update browser history state (called by area components)
|
|
354
354
|
*/
|
|
355
|
-
|
|
355
|
+
updateBrowserHistory(areaName: string, route: ActiveRoute, historyStrategy?: string, clearQueryParams?: string[] | boolean | null, customPath?: string) {
|
|
356
356
|
if (!this.enableHistoryMode) return
|
|
357
357
|
|
|
358
358
|
try {
|