@mhmo91/schmancy 0.10.20 → 0.10.21
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 +0 -49
- package/dist/agent/{overlay.confirm-body-mYm0zq4k.js → overlay.confirm-body-DXus8d-w.js} +1 -1
- package/dist/agent/{overlay.confirm-body-mYm0zq4k.js.map → overlay.confirm-body-DXus8d-w.js.map} +1 -1
- package/dist/agent/schmancy.agent.js +1291 -1257
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/agent/schmancy.manifest.json +0 -39
- package/dist/{area-C7MNn-3e.cjs → area-Cbkt0NX4.cjs} +12 -3
- package/dist/area-Cbkt0NX4.cjs.map +1 -0
- package/dist/{area-CRe41aIG.js → area-Ddk7P5wD.js} +14 -5
- package/dist/area-Ddk7P5wD.js.map +1 -0
- package/dist/area.cjs +1 -1
- package/dist/area.js +1 -1
- package/dist/{autocomplete-CqUl7o0e.cjs → autocomplete-CfBFDSc3.cjs} +1 -1
- package/dist/{autocomplete-CqUl7o0e.cjs.map → autocomplete-CfBFDSc3.cjs.map} +1 -1
- package/dist/{autocomplete-CRDFL4Ul.js → autocomplete-Ds3Q2cwR.js} +2 -2
- package/dist/{autocomplete-CRDFL4Ul.js.map → autocomplete-Ds3Q2cwR.js.map} +1 -1
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +1 -1
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/{boat-XajM8A3M.js → boat-BF5P6p_f.js} +1 -1
- package/dist/{boat-XajM8A3M.js.map → boat-BF5P6p_f.js.map} +1 -1
- package/dist/{boat-BHV5kOlN.cjs → boat-BPN8HLzZ.cjs} +1 -1
- package/dist/{boat-BHV5kOlN.cjs.map → boat-BPN8HLzZ.cjs.map} +1 -1
- package/dist/boat.cjs +1 -1
- package/dist/boat.js +1 -1
- package/dist/breadcrumb.cjs +1 -1
- package/dist/breadcrumb.js +1 -1
- package/dist/{busy-D8YsqVBf.js → busy-BuACDJy6.js} +1 -1
- package/dist/{busy-D8YsqVBf.js.map → busy-BuACDJy6.js.map} +1 -1
- package/dist/{busy-BlBZ5ZOs.cjs → busy-C7ejPa-Q.cjs} +1 -1
- package/dist/{busy-BlBZ5ZOs.cjs.map → busy-C7ejPa-Q.cjs.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{card-yT_St83D.cjs → card-BIzaLuEg.cjs} +1 -1
- package/dist/{card-yT_St83D.cjs.map → card-BIzaLuEg.cjs.map} +1 -1
- package/dist/{card-C9TljY2Z.js → card-CgQwXO8L.js} +1 -1
- package/dist/{card-C9TljY2Z.js.map → card-CgQwXO8L.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-Dz2lkJs0.cjs → checkbox-BAqE3sTx.cjs} +1 -1
- package/dist/{checkbox-Dz2lkJs0.cjs.map → checkbox-BAqE3sTx.cjs.map} +1 -1
- package/dist/{checkbox-BDgh4rge.js → checkbox-BNdg57Om.js} +1 -1
- package/dist/{checkbox-BDgh4rge.js.map → checkbox-BNdg57Om.js.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-M7Dr2npv.cjs → chips-DS3y4Lbn.cjs} +1 -1
- package/dist/{chips-M7Dr2npv.cjs.map → chips-DS3y4Lbn.cjs.map} +1 -1
- package/dist/{chips-N7fu0hA4.js → chips-DnqLaOb1.js} +2 -2
- package/dist/{chips-N7fu0hA4.js.map → chips-DnqLaOb1.js.map} +1 -1
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +1 -1
- package/dist/connectivity.js +1 -1
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/{date-range-D2vxD814.cjs → date-range-CsJfjbmi.cjs} +1 -1
- package/dist/{date-range-D2vxD814.cjs.map → date-range-CsJfjbmi.cjs.map} +1 -1
- package/dist/{date-range-DFWOMgI3.js → date-range-aPSmSBhk.js} +2 -2
- package/dist/{date-range-DFWOMgI3.js.map → date-range-aPSmSBhk.js.map} +1 -1
- package/dist/{date-range-inline-C5JuZ_Kw.cjs → date-range-inline-CAa0_4EI.cjs} +1 -1
- package/dist/{date-range-inline-C5JuZ_Kw.cjs.map → date-range-inline-CAa0_4EI.cjs.map} +1 -1
- package/dist/{date-range-inline-D3q1OoKk.js → date-range-inline-PeRt1iIF.js} +1 -1
- package/dist/{date-range-inline-D3q1OoKk.js.map → date-range-inline-PeRt1iIF.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 +1 -1
- package/dist/{details-DmDEInaL.cjs → details-BnXbDpt7.cjs} +1 -1
- package/dist/{details-DmDEInaL.cjs.map → details-BnXbDpt7.cjs.map} +1 -1
- package/dist/{details-BrUPmd92.js → details-BpFjVclg.js} +1 -1
- package/dist/{details-BrUPmd92.js.map → details-BpFjVclg.js.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/directives.cjs +3 -3
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.js +290 -203
- package/dist/directives.js.map +1 -1
- package/dist/{divider-B_Ts_-qz.cjs → divider-B84lt1A3.cjs} +1 -1
- package/dist/{divider-B_Ts_-qz.cjs.map → divider-B84lt1A3.cjs.map} +1 -1
- package/dist/{divider-BLijs8ba.js → divider-D8cBBkdG.js} +1 -1
- package/dist/{divider-BLijs8ba.js.map → divider-D8cBBkdG.js.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 +1 -1
- package/dist/{expand-C-xSpg7M.js → expand-BJiKggfg.js} +2 -2
- package/dist/{expand-C-xSpg7M.js.map → expand-BJiKggfg.js.map} +1 -1
- package/dist/{expand-DV5sWUB6.cjs → expand-DK-O37-j.cjs} +1 -1
- package/dist/{expand-DV5sWUB6.cjs.map → expand-DK-O37-j.cjs.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/{float-Y22yVBE2.js → float-B4FDN40h.js} +1 -1
- package/dist/{float-Y22yVBE2.js.map → float-B4FDN40h.js.map} +1 -1
- package/dist/{float-LyKef0LY.cjs → float-RWR6Q1Hh.cjs} +1 -1
- package/dist/{float-LyKef0LY.cjs.map → float-RWR6Q1Hh.cjs.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/{form-LFkEQkOX.js → form-Bz5WamuM.js} +8 -8
- package/dist/{form-LFkEQkOX.js.map → form-Bz5WamuM.js.map} +1 -1
- package/dist/{form-C_smXI2-.cjs → form-PioZDvzA.cjs} +1 -1
- package/dist/{form-C_smXI2-.cjs.map → form-PioZDvzA.cjs.map} +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.js +6 -6
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{icons-B3pFrwKC.js → icons-BgUbHwy8.js} +1 -1
- package/dist/{icons-B3pFrwKC.js.map → icons-BgUbHwy8.js.map} +1 -1
- package/dist/{icons-CCNy4Egc.cjs → icons-morK4hHz.cjs} +1 -1
- package/dist/{icons-CCNy4Egc.cjs.map → icons-morK4hHz.cjs.map} +1 -1
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-CCcmLZ_K.cjs → iframe-BXe1TPx1.cjs} +1 -1
- package/dist/{iframe-CCcmLZ_K.cjs.map → iframe-BXe1TPx1.cjs.map} +1 -1
- package/dist/{iframe-BbFlCEyP.js → iframe-CByrVlZy.js} +1 -1
- package/dist/{iframe-BbFlCEyP.js.map → iframe-CByrVlZy.js.map} +1 -1
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +55 -56
- package/dist/{input-sBZ89wz1.cjs → input-BY9OCQWr.cjs} +1 -1
- package/dist/{input-sBZ89wz1.cjs.map → input-BY9OCQWr.cjs.map} +1 -1
- package/dist/{input-Dkneo4uA.js → input-Q0fm34Co.js} +1 -1
- package/dist/{input-Dkneo4uA.js.map → input-Q0fm34Co.js.map} +1 -1
- package/dist/{input-chip-F5NEkkBU.cjs → input-chip-BwNf3GD0.cjs} +1 -1
- package/dist/{input-chip-F5NEkkBU.cjs.map → input-chip-BwNf3GD0.cjs.map} +1 -1
- package/dist/{input-chip-C1-TYu4v.js → input-chip-CytUirVS.js} +1 -1
- package/dist/{input-chip-C1-TYu4v.js.map → input-chip-CytUirVS.js.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 +2 -2
- package/dist/kbd.cjs +1 -1
- package/dist/kbd.js +1 -1
- package/dist/layout.cjs +26 -1
- package/dist/layout.cjs.map +1 -0
- package/dist/layout.js +115 -2
- package/dist/layout.js.map +1 -0
- package/dist/{lightbox-D7hYFspE.js → lightbox-Ckvn5YNF.js} +1 -1
- package/dist/{lightbox-D7hYFspE.js.map → lightbox-Ckvn5YNF.js.map} +1 -1
- package/dist/{lightbox-B4m5lxGs.cjs → lightbox-p2E0oVR0.cjs} +1 -1
- package/dist/{lightbox-B4m5lxGs.cjs.map → lightbox-p2E0oVR0.cjs.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-Ou72tSeq.js → list-CsrPVvmm.js} +1 -1
- package/dist/{list-Ou72tSeq.js.map → list-CsrPVvmm.js.map} +1 -1
- package/dist/{list-C2ycz-yr.cjs → list-r57UFHu3.cjs} +1 -1
- package/dist/{list-C2ycz-yr.cjs.map → list-r57UFHu3.cjs.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{menu-ComSx-T0.cjs → menu-BOZ2iwed.cjs} +1 -1
- package/dist/{menu-ComSx-T0.cjs.map → menu-BOZ2iwed.cjs.map} +1 -1
- package/dist/{menu-YHbpRa7x.js → menu-CxE16xur.js} +2 -2
- package/dist/{menu-YHbpRa7x.js.map → menu-CxE16xur.js.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/mixins-DTCHPEd4.cjs +254 -0
- package/dist/{mixins-BwGJwK7X.cjs.map → mixins-DTCHPEd4.cjs.map} +1 -1
- package/dist/mixins-pU53qf6R.js +636 -0
- package/dist/{mixins-B9kY_60p.js.map → mixins-pU53qf6R.js.map} +1 -1
- package/dist/mixins.cjs +1 -1
- package/dist/mixins.js +1 -1
- 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 +1 -1
- package/dist/navigation-rail.js +1 -1
- package/dist/{notification-DZhL0ZEg.cjs → notification-58tkVys8.cjs} +1 -1
- package/dist/{notification-DZhL0ZEg.cjs.map → notification-58tkVys8.cjs.map} +1 -1
- package/dist/{notification-O4Q5pyio.js → notification-CgTBiAdf.js} +2 -2
- package/dist/{notification-O4Q5pyio.js.map → notification-CgTBiAdf.js.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-C2VKw8Yt.cjs → option-61YE3gub.cjs} +1 -1
- package/dist/{option-C2VKw8Yt.cjs.map → option-61YE3gub.cjs.map} +1 -1
- package/dist/{option-BCks0a4i.js → option-Bicf6xpI.js} +1 -1
- package/dist/{option-BCks0a4i.js.map → option-Bicf6xpI.js.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-CG1gc1Jw.cjs → overlay-B3gKPWhu.cjs} +2 -2
- package/dist/{overlay-CG1gc1Jw.cjs.map → overlay-B3gKPWhu.cjs.map} +1 -1
- package/dist/{overlay-C0YSnxoV.js → overlay-D3mdWOLS.js} +7 -4
- package/dist/{overlay-C0YSnxoV.js.map → overlay-D3mdWOLS.js.map} +1 -1
- package/dist/overlay.cjs +1 -1
- package/dist/{overlay.confirm-body-BmOnrKbF.js → overlay.confirm-body-Czi6cMZq.js} +1 -1
- package/dist/{overlay.confirm-body-BmOnrKbF.js.map → overlay.confirm-body-Czi6cMZq.js.map} +1 -1
- package/dist/{overlay.confirm-body-B-Kmn7LF.cjs → overlay.confirm-body-yr0HzS_d.cjs} +1 -1
- package/dist/{overlay.confirm-body-B-Kmn7LF.cjs.map → overlay.confirm-body-yr0HzS_d.cjs.map} +1 -1
- package/dist/overlay.js +3 -3
- package/dist/{overlay.service-CRoq9Gu-.js → overlay.service-BfZf3xoD.js} +2 -2
- package/dist/{overlay.service-CRoq9Gu-.js.map → overlay.service-BfZf3xoD.js.map} +1 -1
- package/dist/{overlay.service-BPKV2a8w.cjs → overlay.service-DNs3AWqp.cjs} +1 -1
- package/dist/{overlay.service-BPKV2a8w.cjs.map → overlay.service-DNs3AWqp.cjs.map} +1 -1
- package/dist/{progress-B9RWAFv5.cjs → progress-D8XZJVl5.cjs} +1 -1
- package/dist/{progress-B9RWAFv5.cjs.map → progress-D8XZJVl5.cjs.map} +1 -1
- package/dist/{progress-CEEl7vdd.js → progress-Zqx-S9NZ.js} +1 -1
- package/dist/{progress-CEEl7vdd.js.map → progress-Zqx-S9NZ.js.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-VERF_8rC.js → radio-group-D9MU1Mxz.js} +1 -1
- package/dist/{radio-group-VERF_8rC.js.map → radio-group-D9MU1Mxz.js.map} +1 -1
- package/dist/{radio-group-C2y6H5YY.cjs → radio-group-bl8K4Gls.cjs} +1 -1
- package/dist/{radio-group-C2y6H5YY.cjs.map → radio-group-bl8K4Gls.cjs.map} +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +1 -1
- package/dist/range.js +1 -1
- package/dist/{rxjs-utils-Cs6XGwF6.js.map → rxjs-utils-BK8VMe3K.js.map} +1 -1
- package/dist/{rxjs-utils-Dsj75cJy.cjs.map → rxjs-utils-DhOKenkS.cjs.map} +1 -1
- package/dist/rxjs-utils.cjs +1 -1
- package/dist/rxjs-utils.js +1 -1
- package/dist/{select-ClJj_2AP.js → select-CMwkl-D6.js} +1 -1
- package/dist/{select-ClJj_2AP.js.map → select-CMwkl-D6.js.map} +1 -1
- package/dist/{select-CngphfDB.cjs → select-COIfVtZl.cjs} +1 -1
- package/dist/{select-CngphfDB.cjs.map → select-COIfVtZl.cjs.map} +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/skills/SKILL.md +6 -2
- package/dist/skills/area.md +13 -0
- package/dist/skills/overlay.md +13 -0
- package/dist/skills/page.md +71 -29
- package/dist/skills/schmancy/SKILL.md +6 -2
- package/dist/skills/schmancy/area.md +13 -0
- package/dist/skills/schmancy/overlay.md +13 -0
- package/dist/skills/schmancy/page.md +71 -29
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +1 -1
- package/dist/{splash-screen-CntIFk2h.cjs → splash-screen-2hxq8Sft.cjs} +1 -1
- package/dist/{splash-screen-CntIFk2h.cjs.map → splash-screen-2hxq8Sft.cjs.map} +1 -1
- package/dist/{splash-screen-BQsBy3O1.js → splash-screen-xrMNpzkm.js} +1 -1
- package/dist/{splash-screen-BQsBy3O1.js.map → splash-screen-xrMNpzkm.js.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-BAXhEv8f.js → src-CHd-U-w4.js} +34 -35
- package/dist/{src-BAXhEv8f.js.map → src-CHd-U-w4.js.map} +1 -1
- package/dist/{src-ChFa-FDD.cjs → src-ggWtvpDr.cjs} +1 -1
- package/dist/{src-ChFa-FDD.cjs.map → src-ggWtvpDr.cjs.map} +1 -1
- package/dist/steps.cjs +1 -1
- package/dist/steps.js +1 -1
- package/dist/{surface-CHUJSY1o.js → surface-3nnvlxeE.js} +1 -1
- package/dist/{surface-CHUJSY1o.js.map → surface-3nnvlxeE.js.map} +1 -1
- package/dist/{surface-CXmQuXun.cjs → surface-BkQ44Wuo.cjs} +1 -1
- package/dist/{surface-CXmQuXun.cjs.map → surface-BkQ44Wuo.cjs.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.js +1 -1
- package/dist/{tabs-DPVX21WM.js → tabs-CnLIe8nE.js} +1 -1
- package/dist/{tabs-DPVX21WM.js.map → tabs-CnLIe8nE.js.map} +1 -1
- package/dist/{tabs-Bku0sC0p.cjs → tabs-Dql0rcqZ.cjs} +1 -1
- package/dist/{tabs-Bku0sC0p.cjs.map → tabs-Dql0rcqZ.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-D6z1UZzs.js → textarea-BAogS_Ff.js} +1 -1
- package/dist/{textarea-D6z1UZzs.js.map → textarea-BAogS_Ff.js.map} +1 -1
- package/dist/{textarea-CqJNviYi.cjs → textarea-CGD6lAEe.cjs} +1 -1
- package/dist/{textarea-CqJNviYi.cjs.map → textarea-CGD6lAEe.cjs.map} +1 -1
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-DbHfINBV.js → theme-CUK0HrS3.js} +1 -1
- package/dist/{theme-DbHfINBV.js.map → theme-CUK0HrS3.js.map} +1 -1
- package/dist/{theme-BpKVBJCr.cjs → theme-DKrrQ-ic.cjs} +1 -1
- package/dist/{theme-BpKVBJCr.cjs.map → theme-DKrrQ-ic.cjs.map} +1 -1
- package/dist/{theme-button-BeU8Nbs2.js → theme-button-Bb8qW2IH.js} +1 -1
- package/dist/{theme-button-BeU8Nbs2.js.map → theme-button-Bb8qW2IH.js.map} +1 -1
- package/dist/{theme-button-Cof9I85G.cjs → theme-button-CmTwFm3l.cjs} +1 -1
- package/dist/{theme-button-Cof9I85G.cjs.map → theme-button-CmTwFm3l.cjs.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/theme.js +2 -2
- package/dist/tree.cjs +1 -1
- package/dist/tree.js +1 -1
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/dist/{utils-DXE5fBBd.js.map → utils-Cxg0Kfy5.js.map} +1 -1
- package/dist/{utils-C-Q8ePtG.cjs.map → utils-aCJYAGUr.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/dist/visually-hidden.cjs +1 -1
- package/dist/visually-hidden.js +1 -1
- package/dist/{window-Cql1aIX2.cjs → window-BbWlaPZv.cjs} +1 -1
- package/dist/{window-Cql1aIX2.cjs.map → window-BbWlaPZv.cjs.map} +1 -1
- package/dist/{window-DmMNsos0.js → window-DuDAQa6y.js} +1 -1
- package/dist/{window-DmMNsos0.js.map → window-DuDAQa6y.js.map} +1 -1
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/skills/schmancy/SKILL.md +6 -2
- package/skills/schmancy/area.md +13 -0
- package/skills/schmancy/overlay.md +13 -0
- package/skills/schmancy/page.md +71 -29
- package/src/area/area.component.ts +13 -1
- package/src/directives/fill.ts +137 -0
- package/src/directives/index.ts +2 -0
- package/src/directives/overflow-within.ts +186 -0
- package/src/index.ts +0 -1
- package/src/overlay/index.ts +1 -0
- package/src/overlay/overlay.component.ts +9 -0
- package/src/overlay/overlay.types.ts +10 -3
- package/types/src/directives/fill.d.ts +46 -0
- package/types/src/directives/index.d.ts +2 -0
- package/types/src/directives/overflow-within.d.ts +77 -0
- package/types/src/index.d.ts +0 -1
- package/types/src/overlay/index.d.ts +1 -1
- package/types/src/overlay/overlay.types.d.ts +9 -3
- package/dist/area-C7MNn-3e.cjs.map +0 -1
- package/dist/area-CRe41aIG.js.map +0 -1
- package/dist/mixins-B9kY_60p.js +0 -636
- package/dist/mixins-BwGJwK7X.cjs +0 -254
- package/dist/page.cjs +0 -20
- package/dist/page.cjs.map +0 -1
- package/dist/page.js +0 -74
- package/dist/page.js.map +0 -1
- package/dist/scroll-Bj7FsS08.js +0 -115
- package/dist/scroll-Bj7FsS08.js.map +0 -1
- package/dist/scroll-Djz3pJfX.cjs +0 -26
- package/dist/scroll-Djz3pJfX.cjs.map +0 -1
- package/src/page/index.ts +0 -1
- package/src/page/page.ts +0 -137
- package/types/src/page/index.d.ts +0 -1
- package/types/src/page/page.d.ts +0 -37
- /package/dist/{rxjs-utils-Cs6XGwF6.js → rxjs-utils-BK8VMe3K.js} +0 -0
- /package/dist/{rxjs-utils-Dsj75cJy.cjs → rxjs-utils-DhOKenkS.cjs} +0 -0
- /package/dist/{utils-DXE5fBBd.js → utils-Cxg0Kfy5.js} +0 -0
- /package/dist/{utils-C-Q8ePtG.cjs → utils-aCJYAGUr.cjs} +0 -0
package/skills/schmancy/page.md
CHANGED
|
@@ -1,42 +1,84 @@
|
|
|
1
1
|
# schmancy-page
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Viewport-locked layout primitive. Provides a definite-height frame so any composition inside it has a parent to resolve against.
|
|
4
|
+
|
|
5
|
+
## Contract
|
|
6
|
+
|
|
7
|
+
Two rules and one slot.
|
|
8
|
+
|
|
9
|
+
1. **Outermost lock.** A `<schmancy-page>` with no `<schmancy-page>` ancestor anchors itself to the visual viewport (`position: fixed; inset: 0`) and tracks `visualViewport.height` for iOS soft-keyboard correctness. It does not rely on `html`/`body` height — the cascade above it is irrelevant.
|
|
10
|
+
2. **Single-child stretch.** The slotted child fills the page box (`height: 100%; width: 100%; min-height: 0; min-width: 0`). More than one direct child produces a visible layout collision — fail-loud, not silent.
|
|
11
|
+
|
|
12
|
+
Composition shape is plain CSS grid / flex inside the slotted child. The primitive does not prescribe header / footer / sidebar conventions; consumers arrange regions in standard CSS. The contract is the locked frame.
|
|
4
13
|
|
|
5
14
|
## Usage
|
|
15
|
+
|
|
16
|
+
### App root
|
|
6
17
|
```html
|
|
7
|
-
<schmancy-page
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
<schmancy-page>
|
|
19
|
+
<schmancy-area name="root" .default=${landing}>
|
|
20
|
+
<schmancy-route when="landing-view" .component=${landing}></schmancy-route>
|
|
21
|
+
<schmancy-route when="app-home" .component=${appHome}></schmancy-route>
|
|
22
|
+
</schmancy-area>
|
|
11
23
|
</schmancy-page>
|
|
12
24
|
```
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
| Property | Type | Default | Description |
|
|
16
|
-
|----------|------|---------|-------------|
|
|
17
|
-
| `rows` | string | `'auto_1fr_auto'` | Grid template rows — underscores become spaces (e.g. `'1fr_2fr_auto'`) |
|
|
18
|
-
| `show-scrollbar` | boolean | `false` | Display scrollbar on scrollable area |
|
|
19
|
-
| `no-select` | boolean | `false` | Disable text selection |
|
|
20
|
-
|
|
21
|
-
## Behavior
|
|
22
|
-
- Listens to `visualViewport` resize/scroll + `orientationchange` + keyboard focus events to recompute height.
|
|
23
|
-
- Accounts for theme bottom offset (iOS safe area, home indicator).
|
|
24
|
-
- Auto-assigns semantic elements (`header`, `main`, `footer`) to slots.
|
|
25
|
-
- Inner scroll area uses `schmancy-scroll` for momentum-preserving scroll.
|
|
26
|
-
|
|
27
|
-
## When to Use
|
|
28
|
-
- Root of a mobile view or panel that should feel like a native page.
|
|
29
|
-
- Any container where viewport-aware height + scroll containment matters.
|
|
30
|
-
|
|
31
|
-
## Example — 3-row app shell
|
|
26
|
+
### Sidebar + sticky header + body
|
|
32
27
|
```html
|
|
33
|
-
<schmancy-page
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
28
|
+
<schmancy-page>
|
|
29
|
+
<div class="grid grid-cols-[auto_1fr]">
|
|
30
|
+
<app-rail></app-rail>
|
|
31
|
+
<schmancy-page>
|
|
32
|
+
<div class="grid grid-rows-[auto_1fr]">
|
|
33
|
+
<app-top-bar></app-top-bar>
|
|
34
|
+
<schmancy-area name="app">...</schmancy-area>
|
|
35
|
+
</div>
|
|
36
|
+
</schmancy-page>
|
|
37
|
+
</div>
|
|
38
|
+
</schmancy-page>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The inner `<schmancy-page>` detects the outer ancestor, skips the viewport lock, and fills its grid cell via `height: 100%; width: 100%`.
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
### Tabs page
|
|
44
|
+
```html
|
|
45
|
+
<div class="grid grid-rows-[auto_1fr]">
|
|
46
|
+
<schmancy-tabs></schmancy-tabs>
|
|
47
|
+
<schmancy-area name="settings">...</schmancy-area>
|
|
48
|
+
</div>
|
|
49
|
+
```
|
|
39
50
|
|
|
40
|
-
|
|
51
|
+
No `<schmancy-page>` here — this view is the routed body of a higher `<schmancy-page>`. The grid resolves against the area's `1fr` cell, which the area inherits from the page.
|
|
52
|
+
|
|
53
|
+
### Admin shell (four regions)
|
|
54
|
+
```html
|
|
55
|
+
<schmancy-page>
|
|
56
|
+
<div class="grid grid-rows-[auto_1fr]">
|
|
57
|
+
<admin-top-bar></admin-top-bar>
|
|
58
|
+
<div class="grid grid-cols-[240px_1fr_320px]">
|
|
59
|
+
<admin-sidebar></admin-sidebar>
|
|
60
|
+
<schmancy-area name="admin"></schmancy-area>
|
|
61
|
+
<admin-inspector></admin-inspector>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
41
64
|
</schmancy-page>
|
|
42
65
|
```
|
|
66
|
+
|
|
67
|
+
## Properties
|
|
68
|
+
|
|
69
|
+
`<schmancy-page>` has no public properties. Composition is expressed by what you nest inside its single slot.
|
|
70
|
+
|
|
71
|
+
The `outermost` attribute is set automatically on the page that owns the viewport lock. Consumers neither set nor read it.
|
|
72
|
+
|
|
73
|
+
## Edge cases
|
|
74
|
+
|
|
75
|
+
- **Print** — outermost page falls back to `position: static` so pagination works.
|
|
76
|
+
- **iOS soft keyboard** — outermost page reads `visualViewport.height` and applies it as inline `height`, so the locked box shrinks when the keyboard opens.
|
|
77
|
+
- **Long-form leaf (marketing, legal)** — opt out at the leaf, not at the page. The routed component declares its own `:host { height: auto; overflow: auto; min-height: 100% }`. The outer page stays locked; the leaf scrolls inside its `<schmancy-area>`.
|
|
78
|
+
- **Master-detail with two scroll regions** — render two `<schmancy-area>` slots inside a grid; each owns its scroll.
|
|
79
|
+
|
|
80
|
+
## Rules
|
|
81
|
+
|
|
82
|
+
- A `<schmancy-page>` has exactly one direct child. If you need multiple regions, wrap them in a grid / flex container.
|
|
83
|
+
- Do not put `class="h-full"`, `class="w-full"`, or `:host { height: 100% }` anywhere in your tree. The page and the area carry sizing; consumer code never does.
|
|
84
|
+
- Scroll lives in `<schmancy-area>`, not in `<schmancy-page>`. Pages provide the locked frame; areas provide the scrolling region for their mounted component.
|
|
@@ -25,9 +25,18 @@ export class SchmancyArea extends SchmancyElement {
|
|
|
25
25
|
:host {
|
|
26
26
|
position: relative;
|
|
27
27
|
display: block;
|
|
28
|
-
|
|
28
|
+
height: 100%;
|
|
29
|
+
width: 100%;
|
|
30
|
+
min-height: 0;
|
|
31
|
+
min-width: 0;
|
|
29
32
|
contain: layout style;
|
|
30
33
|
}
|
|
34
|
+
::slotted(:not(schmancy-route)) {
|
|
35
|
+
display: block;
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
min-height: 100%;
|
|
38
|
+
width: 100%;
|
|
39
|
+
}
|
|
31
40
|
`]
|
|
32
41
|
|
|
33
42
|
@property() name!: string
|
|
@@ -202,6 +211,7 @@ export class SchmancyArea extends SchmancyElement {
|
|
|
202
211
|
if (duration === 0) {
|
|
203
212
|
old?.remove()
|
|
204
213
|
this.appendChild(element)
|
|
214
|
+
this.scrollTop = 0
|
|
205
215
|
} else if (old) {
|
|
206
216
|
old.style.willChange = 'opacity'
|
|
207
217
|
element.style.willChange = 'opacity'
|
|
@@ -211,11 +221,13 @@ export class SchmancyArea extends SchmancyElement {
|
|
|
211
221
|
if (!this.isConnected) return
|
|
212
222
|
old.remove()
|
|
213
223
|
this.appendChild(element)
|
|
224
|
+
this.scrollTop = 0
|
|
214
225
|
return element.animate([{ opacity: 0 }, { opacity: 1 }], { duration, easing: 'ease-in' }).finished
|
|
215
226
|
})
|
|
216
227
|
.then(() => (element.style.willChange = 'auto'))
|
|
217
228
|
} else {
|
|
218
229
|
this.appendChild(element)
|
|
230
|
+
this.scrollTop = 0
|
|
219
231
|
element.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
220
232
|
duration: duration > 100 ? Math.max(100, duration * 0.66) : duration,
|
|
221
233
|
easing: 'ease-in',
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { AsyncDirective, directive } from 'lit/async-directive.js'
|
|
2
|
+
import { ElementPart, PartType } from 'lit/directive.js'
|
|
3
|
+
import { EMPTY, Subject, combineLatest, fromEvent, merge, timer } from 'rxjs'
|
|
4
|
+
import { debounceTime, distinctUntilChanged, filter, map, startWith, switchMap, takeUntil, tap } from 'rxjs/operators'
|
|
5
|
+
import { theme } from '../theme/theme.service'
|
|
6
|
+
import { fromResizeObserver } from './layout'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* fill directive — anchors an element to the viewport in both dimensions
|
|
10
|
+
* and contains overflow within its viewport-anchored box.
|
|
11
|
+
*
|
|
12
|
+
* The element's `getBoundingClientRect()` top/left are subtracted from the
|
|
13
|
+
* visual viewport size; the remaining pixels are applied as inline `height`
|
|
14
|
+
* and `width`. `overflow: hidden` ensures children cannot visually escape
|
|
15
|
+
* the box; inner scroll containers (apply `overflowWithin()` on the
|
|
16
|
+
* appropriate cell) handle scrolling.
|
|
17
|
+
*
|
|
18
|
+
* Layout is the consumer's responsibility — apply Tailwind classes
|
|
19
|
+
* (`grid grid-cols-[auto_1fr] grid-rows-[1fr]`, `flex`, etc.) on the same
|
|
20
|
+
* element to express the layout. The directive provides the definite-pixel
|
|
21
|
+
* box; the consumer decides how it's divided.
|
|
22
|
+
*
|
|
23
|
+
* Cascade-independent — measurement is taken in viewport coordinates
|
|
24
|
+
* rather than computed from CSS, so the directive works regardless of
|
|
25
|
+
* what the element's ancestors declare.
|
|
26
|
+
*
|
|
27
|
+
* Reactive sources: window/visualViewport resize + scroll, orientation
|
|
28
|
+
* change, iOS keyboard focus-out, parent/element ResizeObserver, theme
|
|
29
|
+
* fullscreen toggle, theme bottom offset (safe-area / nav-bar reservation).
|
|
30
|
+
*
|
|
31
|
+
* @example sidebar + main
|
|
32
|
+
* <app-shell
|
|
33
|
+
* ${fill()}
|
|
34
|
+
* class="grid grid-cols-[auto_1fr] grid-rows-[1fr]"
|
|
35
|
+
* >
|
|
36
|
+
* <app-rail></app-rail>
|
|
37
|
+
* <app-content></app-content>
|
|
38
|
+
* </app-shell>
|
|
39
|
+
*/
|
|
40
|
+
class Fill extends AsyncDirective {
|
|
41
|
+
private element: HTMLElement | null = null
|
|
42
|
+
private disconnecting$ = new Subject<void>()
|
|
43
|
+
|
|
44
|
+
private apply(bottomOffset: number, isFullscreen: boolean) {
|
|
45
|
+
if (!this.element) return
|
|
46
|
+
const vv = window.visualViewport
|
|
47
|
+
const vh = vv?.height ?? window.innerHeight
|
|
48
|
+
const vw = vv?.width ?? window.innerWidth
|
|
49
|
+
const rect = this.element.getBoundingClientRect()
|
|
50
|
+
const height = Math.max(0, vh - rect.top)
|
|
51
|
+
const width = Math.max(0, vw - rect.left)
|
|
52
|
+
const padding = isFullscreen ? 0 : bottomOffset
|
|
53
|
+
const s = this.element.style
|
|
54
|
+
s.boxSizing = 'border-box'
|
|
55
|
+
s.height = `${height}px`
|
|
56
|
+
s.width = `${width}px`
|
|
57
|
+
s.paddingBottom = `${padding}px`
|
|
58
|
+
s.minHeight = '0'
|
|
59
|
+
s.minWidth = '0'
|
|
60
|
+
s.overflow = 'hidden'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private subscribe() {
|
|
64
|
+
if (!this.element) return
|
|
65
|
+
|
|
66
|
+
const windowResize$ = fromEvent(window, 'resize', { passive: true })
|
|
67
|
+
const viewportEvents$ = window.visualViewport
|
|
68
|
+
? merge(
|
|
69
|
+
fromEvent(window.visualViewport, 'resize', { passive: true }),
|
|
70
|
+
fromEvent(window.visualViewport, 'scroll', { passive: true }),
|
|
71
|
+
)
|
|
72
|
+
: windowResize$
|
|
73
|
+
const orientation$ = fromEvent(window, 'orientationchange')
|
|
74
|
+
const focusOut$ = fromEvent(document, 'focusout', { passive: true }).pipe(
|
|
75
|
+
switchMap(() => timer(100)),
|
|
76
|
+
)
|
|
77
|
+
const elementResize$ = fromResizeObserver(this.element)
|
|
78
|
+
const parentResize$ = this.element.parentElement
|
|
79
|
+
? fromResizeObserver(this.element.parentElement)
|
|
80
|
+
: EMPTY
|
|
81
|
+
|
|
82
|
+
combineLatest([
|
|
83
|
+
merge(
|
|
84
|
+
windowResize$,
|
|
85
|
+
viewportEvents$,
|
|
86
|
+
orientation$,
|
|
87
|
+
focusOut$,
|
|
88
|
+
elementResize$,
|
|
89
|
+
parentResize$,
|
|
90
|
+
).pipe(debounceTime(16), startWith(null)),
|
|
91
|
+
theme.bottomOffset$,
|
|
92
|
+
theme.fullscreen$,
|
|
93
|
+
])
|
|
94
|
+
.pipe(
|
|
95
|
+
filter(() => {
|
|
96
|
+
const vv = window.visualViewport
|
|
97
|
+
return vv ? Math.abs(vv.scale - 1) <= 0.01 : true
|
|
98
|
+
}),
|
|
99
|
+
map(([, bottomOffset, isFullscreen]) => ({ bottomOffset, isFullscreen })),
|
|
100
|
+
distinctUntilChanged(
|
|
101
|
+
(a, b) => a.bottomOffset === b.bottomOffset && a.isFullscreen === b.isFullscreen,
|
|
102
|
+
),
|
|
103
|
+
tap(({ bottomOffset, isFullscreen }) => this.apply(bottomOffset, isFullscreen)),
|
|
104
|
+
takeUntil(this.disconnecting$),
|
|
105
|
+
)
|
|
106
|
+
.subscribe()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
render() {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
override update(part: ElementPart) {
|
|
114
|
+
if (part.type !== PartType.ELEMENT) {
|
|
115
|
+
throw new Error('fill directive can only be used on elements')
|
|
116
|
+
}
|
|
117
|
+
const el = part.element as HTMLElement
|
|
118
|
+
if (this.element !== el) {
|
|
119
|
+
this.element = el
|
|
120
|
+
this.subscribe()
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
protected override disconnected() {
|
|
125
|
+
this.disconnecting$.next()
|
|
126
|
+
this.element = null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
protected override reconnected() {
|
|
130
|
+
if (this.element) {
|
|
131
|
+
this.disconnecting$ = new Subject<void>()
|
|
132
|
+
this.subscribe()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const fill = directive(Fill)
|
package/src/directives/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './cursor-glow';
|
|
|
5
5
|
export * from './cycle-text';
|
|
6
6
|
export * from './depth-of-field';
|
|
7
7
|
export * from './drag';
|
|
8
|
+
export * from './fill';
|
|
8
9
|
export * from './gravity';
|
|
9
10
|
export * from './intersect';
|
|
10
11
|
export * from './layout';
|
|
@@ -16,3 +17,4 @@ export * from './nebula';
|
|
|
16
17
|
export * from './reduced-motion';
|
|
17
18
|
export * from './reveal';
|
|
18
19
|
export * from './ripple';
|
|
20
|
+
export * from './overflow-within';
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { noChange } from 'lit'
|
|
2
|
+
import { AsyncDirective, directive } from 'lit/async-directive.js'
|
|
3
|
+
import { ElementPart, PartType } from 'lit/directive.js'
|
|
4
|
+
import { Subject, debounceTime, filter, fromEvent, takeUntil } from 'rxjs'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Detail payload for the directive's enriched `scroll` event.
|
|
8
|
+
*/
|
|
9
|
+
export interface OverflowWithinEvent
|
|
10
|
+
extends CustomEvent<{
|
|
11
|
+
scrollTop: number
|
|
12
|
+
scrollHeight: number
|
|
13
|
+
clientHeight: number
|
|
14
|
+
scrollLeft: number
|
|
15
|
+
scrollWidth: number
|
|
16
|
+
clientWidth: number
|
|
17
|
+
e: Event
|
|
18
|
+
}> {}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Detail payload for the global `@schmancy:scrollTo` command.
|
|
22
|
+
*/
|
|
23
|
+
export interface OverflowWithinCommandEvent
|
|
24
|
+
extends CustomEvent<{
|
|
25
|
+
name: string
|
|
26
|
+
action: 'scrollTo'
|
|
27
|
+
top: number
|
|
28
|
+
left?: number
|
|
29
|
+
}> {}
|
|
30
|
+
|
|
31
|
+
export interface OverflowWithinOptions {
|
|
32
|
+
/** Hide native scrollbars while keeping scroll behavior intact. */
|
|
33
|
+
hide?: boolean
|
|
34
|
+
/** Which axis can scroll. Default `'both'`. */
|
|
35
|
+
direction?: 'vertical' | 'horizontal' | 'both'
|
|
36
|
+
/**
|
|
37
|
+
* Optional name for cross-component control via the global
|
|
38
|
+
* `@schmancy:scrollTo` event.
|
|
39
|
+
*/
|
|
40
|
+
name?: string
|
|
41
|
+
/** Debounce in ms for the dispatched `scroll` event. Default `10`. */
|
|
42
|
+
debounce?: number
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const SCROLLBAR_HIDE_CLASS = 'schmancy-overflow-within-hidden'
|
|
46
|
+
let stylesheetInstalled = false
|
|
47
|
+
|
|
48
|
+
function installHideStylesheet() {
|
|
49
|
+
if (stylesheetInstalled) return
|
|
50
|
+
stylesheetInstalled = true
|
|
51
|
+
const sheet = new CSSStyleSheet()
|
|
52
|
+
sheet.replaceSync(
|
|
53
|
+
`.${SCROLLBAR_HIDE_CLASS} { scrollbar-width: none; -ms-overflow-style: none; }
|
|
54
|
+
.${SCROLLBAR_HIDE_CLASS}::-webkit-scrollbar { display: none; }`,
|
|
55
|
+
)
|
|
56
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* overflowWithin directive — turns any element into a contained overflow
|
|
61
|
+
* boundary. Content stays *within* the element; what overflows scrolls
|
|
62
|
+
* inside, can't escape (overscroll contained, rubber-band suppressed).
|
|
63
|
+
*
|
|
64
|
+
* - Overflow per `direction` axis
|
|
65
|
+
* - Smooth scroll-behavior
|
|
66
|
+
* - Overscroll containment (no rubber-band escape)
|
|
67
|
+
* - Optional hidden scrollbar via a document-level stylesheet
|
|
68
|
+
* - Debounced enriched `scroll` event
|
|
69
|
+
* - Global `@schmancy:scrollTo` command listener (when `name` is set)
|
|
70
|
+
* - min-height / min-width 0 so the container can clip inside grid/flex cells
|
|
71
|
+
*
|
|
72
|
+
* Apply at the element where overflow should be contained; the consumer's
|
|
73
|
+
* layout grid/flex container can itself be the overflow boundary — no
|
|
74
|
+
* wrapper element needed.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* render() {
|
|
78
|
+
* return html`
|
|
79
|
+
* <div class="grid grid-rows-[auto_1fr]" ${overflowWithin({ hide: true })}>
|
|
80
|
+
* <header>...</header>
|
|
81
|
+
* <section>...scrollable content...</section>
|
|
82
|
+
* </div>
|
|
83
|
+
* `
|
|
84
|
+
* }
|
|
85
|
+
*/
|
|
86
|
+
class OverflowWithinDirective extends AsyncDirective {
|
|
87
|
+
private element: HTMLElement | null = null
|
|
88
|
+
private disconnecting$ = new Subject<void>()
|
|
89
|
+
private currentName?: string
|
|
90
|
+
|
|
91
|
+
render(_options?: OverflowWithinOptions) {
|
|
92
|
+
return noChange
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override update(part: ElementPart, [options = {}]: [OverflowWithinOptions?]) {
|
|
96
|
+
if (part.type !== PartType.ELEMENT) {
|
|
97
|
+
throw new Error('overflowWithin directive can only be used on elements')
|
|
98
|
+
}
|
|
99
|
+
const el = part.element as HTMLElement
|
|
100
|
+
const { hide = false, direction = 'both', name, debounce = 10 } = options
|
|
101
|
+
|
|
102
|
+
const s = el.style
|
|
103
|
+
s.minHeight = '0'
|
|
104
|
+
s.minWidth = '0'
|
|
105
|
+
s.boxSizing = 'border-box'
|
|
106
|
+
s.overflowY = direction === 'horizontal' ? 'hidden' : 'auto'
|
|
107
|
+
s.overflowX = direction === 'vertical' ? 'hidden' : 'auto'
|
|
108
|
+
s.scrollBehavior = 'smooth'
|
|
109
|
+
s.overscrollBehavior = 'contain'
|
|
110
|
+
|
|
111
|
+
if (hide) {
|
|
112
|
+
installHideStylesheet()
|
|
113
|
+
el.classList.add(SCROLLBAR_HIDE_CLASS)
|
|
114
|
+
} else {
|
|
115
|
+
el.classList.remove(SCROLLBAR_HIDE_CLASS)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const isNewElement = this.element !== el
|
|
119
|
+
const isNameChange = this.currentName !== name
|
|
120
|
+
|
|
121
|
+
if (isNewElement) {
|
|
122
|
+
this.element = el
|
|
123
|
+
this.subscribe(debounce, name)
|
|
124
|
+
} else if (isNameChange) {
|
|
125
|
+
// resubscribe with new name binding
|
|
126
|
+
this.disconnecting$.next()
|
|
127
|
+
this.disconnecting$ = new Subject<void>()
|
|
128
|
+
this.subscribe(debounce, name)
|
|
129
|
+
}
|
|
130
|
+
this.currentName = name
|
|
131
|
+
|
|
132
|
+
return noChange
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private subscribe(debounce: number, name: string | undefined) {
|
|
136
|
+
if (!this.element) return
|
|
137
|
+
const el = this.element
|
|
138
|
+
|
|
139
|
+
fromEvent(el, 'scroll', { passive: true })
|
|
140
|
+
.pipe(debounceTime(debounce), takeUntil(this.disconnecting$))
|
|
141
|
+
.subscribe((e) => {
|
|
142
|
+
el.dispatchEvent(
|
|
143
|
+
new CustomEvent('scroll', {
|
|
144
|
+
detail: {
|
|
145
|
+
scrollTop: el.scrollTop,
|
|
146
|
+
scrollHeight: el.scrollHeight,
|
|
147
|
+
clientHeight: el.clientHeight,
|
|
148
|
+
scrollLeft: el.scrollLeft,
|
|
149
|
+
scrollWidth: el.scrollWidth,
|
|
150
|
+
clientWidth: el.clientWidth,
|
|
151
|
+
e,
|
|
152
|
+
},
|
|
153
|
+
bubbles: true,
|
|
154
|
+
composed: true,
|
|
155
|
+
}) as OverflowWithinEvent,
|
|
156
|
+
)
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
if (name !== undefined) {
|
|
160
|
+
fromEvent<OverflowWithinCommandEvent>(window, '@schmancy:scrollTo')
|
|
161
|
+
.pipe(
|
|
162
|
+
filter((evt) => evt.detail.name === name && evt.detail.action === 'scrollTo'),
|
|
163
|
+
takeUntil(this.disconnecting$),
|
|
164
|
+
)
|
|
165
|
+
.subscribe((evt) => {
|
|
166
|
+
const options: ScrollToOptions = { behavior: 'smooth', top: evt.detail.top }
|
|
167
|
+
if (typeof evt.detail.left === 'number') options.left = evt.detail.left
|
|
168
|
+
el.scrollTo(options)
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
protected override disconnected() {
|
|
174
|
+
this.disconnecting$.next()
|
|
175
|
+
this.element = null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
protected override reconnected() {
|
|
179
|
+
if (this.element) {
|
|
180
|
+
this.disconnecting$ = new Subject<void>()
|
|
181
|
+
this.subscribe(10, this.currentName)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const overflowWithin = directive(OverflowWithinDirective)
|
package/src/index.ts
CHANGED
|
@@ -43,7 +43,6 @@ export * from './option';
|
|
|
43
43
|
// inside a federated context, the build-time check passes only if
|
|
44
44
|
// `show` is reachable from the main barrel.
|
|
45
45
|
export * from './overlay';
|
|
46
|
-
export * from './page';
|
|
47
46
|
export * from './progress';
|
|
48
47
|
export * from './form/fields/radio-group';
|
|
49
48
|
export * from './form/fields/range';
|
package/src/overlay/index.ts
CHANGED
|
@@ -593,6 +593,11 @@ async function mountContent(
|
|
|
593
593
|
host: HTMLElement,
|
|
594
594
|
props?: Record<string, unknown>,
|
|
595
595
|
): Promise<HTMLElement> {
|
|
596
|
+
// TemplateFactory — call at mount time so closed-over variables are read lazily.
|
|
597
|
+
if (isTemplateFactory(content)) {
|
|
598
|
+
return mountContent(content(), host, props)
|
|
599
|
+
}
|
|
600
|
+
|
|
596
601
|
// TemplateResult — render via lit's `render`.
|
|
597
602
|
if (isTemplateResult(content)) {
|
|
598
603
|
litRender(content, host)
|
|
@@ -632,6 +637,10 @@ async function mountContent(
|
|
|
632
637
|
throw new Error('schmancy-overlay: unsupported content type')
|
|
633
638
|
}
|
|
634
639
|
|
|
640
|
+
function isTemplateFactory(x: unknown): x is import('./overlay.types').TemplateFactory {
|
|
641
|
+
return typeof x === 'function' && !(x as { prototype?: unknown }).prototype
|
|
642
|
+
}
|
|
643
|
+
|
|
635
644
|
function isTemplateResult(x: unknown): x is TemplateResult {
|
|
636
645
|
return typeof x === 'object' && x !== null && '_$litType$' in x
|
|
637
646
|
}
|
|
@@ -3,15 +3,22 @@ import type { Observable } from 'rxjs'
|
|
|
3
3
|
import type { ComponentType } from '../area/router.types'
|
|
4
4
|
import type { THistoryStrategy } from '../area/router.types'
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Sync factory that returns a TemplateResult. Called at mount time so closed-over
|
|
8
|
+
* variables are evaluated lazily — no snapshot staleness.
|
|
9
|
+
*/
|
|
10
|
+
export type TemplateFactory = () => TemplateResult
|
|
11
|
+
|
|
6
12
|
/**
|
|
7
13
|
* What the caller is showing. Flat union — `typeof`-discriminated at runtime.
|
|
8
14
|
* Reuses area's `ComponentType` (class | tag name | HTMLElement | lazy loader)
|
|
9
|
-
* and adds Lit `TemplateResult` for inline templates
|
|
15
|
+
* and adds Lit `TemplateResult` for inline templates plus `TemplateFactory` for
|
|
16
|
+
* lazy template evaluation.
|
|
10
17
|
*
|
|
11
18
|
* The common case is one positional arg: `show(MyEditor)`, `show(html\`...\`)`,
|
|
12
|
-
* `show(el)`, `show('my-tag')`, `show(lazy(() => import('./x')))`.
|
|
19
|
+
* `show(() => html\`...\`)`, `show(el)`, `show('my-tag')`, `show(lazy(() => import('./x')))`.
|
|
13
20
|
*/
|
|
14
|
-
export type Content = ComponentType | TemplateResult
|
|
21
|
+
export type Content = ComponentType | TemplateResult | TemplateFactory
|
|
15
22
|
|
|
16
23
|
/**
|
|
17
24
|
* Virtual reference object — same contract Floating UI and CSS Anchor
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AsyncDirective } from 'lit/async-directive.js';
|
|
2
|
+
import { ElementPart } from 'lit/directive.js';
|
|
3
|
+
/**
|
|
4
|
+
* fill directive — anchors an element to the viewport in both dimensions
|
|
5
|
+
* and contains overflow within its viewport-anchored box.
|
|
6
|
+
*
|
|
7
|
+
* The element's `getBoundingClientRect()` top/left are subtracted from the
|
|
8
|
+
* visual viewport size; the remaining pixels are applied as inline `height`
|
|
9
|
+
* and `width`. `overflow: hidden` ensures children cannot visually escape
|
|
10
|
+
* the box; inner scroll containers (apply `overflowWithin()` on the
|
|
11
|
+
* appropriate cell) handle scrolling.
|
|
12
|
+
*
|
|
13
|
+
* Layout is the consumer's responsibility — apply Tailwind classes
|
|
14
|
+
* (`grid grid-cols-[auto_1fr] grid-rows-[1fr]`, `flex`, etc.) on the same
|
|
15
|
+
* element to express the layout. The directive provides the definite-pixel
|
|
16
|
+
* box; the consumer decides how it's divided.
|
|
17
|
+
*
|
|
18
|
+
* Cascade-independent — measurement is taken in viewport coordinates
|
|
19
|
+
* rather than computed from CSS, so the directive works regardless of
|
|
20
|
+
* what the element's ancestors declare.
|
|
21
|
+
*
|
|
22
|
+
* Reactive sources: window/visualViewport resize + scroll, orientation
|
|
23
|
+
* change, iOS keyboard focus-out, parent/element ResizeObserver, theme
|
|
24
|
+
* fullscreen toggle, theme bottom offset (safe-area / nav-bar reservation).
|
|
25
|
+
*
|
|
26
|
+
* @example sidebar + main
|
|
27
|
+
* <app-shell
|
|
28
|
+
* ${fill()}
|
|
29
|
+
* class="grid grid-cols-[auto_1fr] grid-rows-[1fr]"
|
|
30
|
+
* >
|
|
31
|
+
* <app-rail></app-rail>
|
|
32
|
+
* <app-content></app-content>
|
|
33
|
+
* </app-shell>
|
|
34
|
+
*/
|
|
35
|
+
declare class Fill extends AsyncDirective {
|
|
36
|
+
private element;
|
|
37
|
+
private disconnecting$;
|
|
38
|
+
private apply;
|
|
39
|
+
private subscribe;
|
|
40
|
+
render(): void;
|
|
41
|
+
update(part: ElementPart): void;
|
|
42
|
+
protected disconnected(): void;
|
|
43
|
+
protected reconnected(): void;
|
|
44
|
+
}
|
|
45
|
+
export declare const fill: () => import("lit-html/directive").DirectiveResult<typeof Fill>;
|
|
46
|
+
export {};
|
|
@@ -5,6 +5,7 @@ export * from './cursor-glow';
|
|
|
5
5
|
export * from './cycle-text';
|
|
6
6
|
export * from './depth-of-field';
|
|
7
7
|
export * from './drag';
|
|
8
|
+
export * from './fill';
|
|
8
9
|
export * from './gravity';
|
|
9
10
|
export * from './intersect';
|
|
10
11
|
export * from './layout';
|
|
@@ -16,3 +17,4 @@ export * from './nebula';
|
|
|
16
17
|
export * from './reduced-motion';
|
|
17
18
|
export * from './reveal';
|
|
18
19
|
export * from './ripple';
|
|
20
|
+
export * from './overflow-within';
|