@mhmo91/schmancy 0.9.10 → 0.9.11
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 +4 -4
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/button.cjs +29 -29
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +52 -50
- package/dist/button.js.map +1 -1
- package/dist/{card-DUq_MsxC.cjs.map → card-Bht1QcYl.cjs.map} +1 -1
- package/dist/{card-C8Ns2mRo.js.map → card-DiNYPJ9b.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-qPH_5Viu.cjs → checkbox-CRzu7URt.cjs} +1 -1
- package/dist/{checkbox-qPH_5Viu.cjs.map → checkbox-CRzu7URt.cjs.map} +1 -1
- package/dist/{checkbox-D18r6c0V.js → checkbox-dRBf89qt.js} +1 -1
- package/dist/{checkbox-D18r6c0V.js.map → checkbox-dRBf89qt.js.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-0rKPqQt8.js.map → chips-Bma_B3J-.js.map} +1 -1
- package/dist/{chips-BI_kt5BS.cjs.map → chips-CXknD-vY.cjs.map} +1 -1
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +1 -1
- package/dist/{code-highlight-DGInmDAW.cjs.map → code-highlight-BROOsNA_.cjs.map} +1 -1
- package/dist/{code-highlight-ClzG4FL4.js.map → code-highlight-DjiyaDcX.js.map} +1 -1
- package/dist/code-highlight.cjs +1 -1
- package/dist/code-highlight.js +1 -1
- package/dist/{components-RbvrLE3U.js.map → components-DKgu88mm.js.map} +1 -1
- package/dist/{components-7hOtFi_q.cjs.map → components-ubXwQbGs.cjs.map} +1 -1
- package/dist/components.cjs +1 -1
- package/dist/components.js +1 -1
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/context-B81Q3U_1.cjs +1 -0
- package/dist/context-B81Q3U_1.cjs.map +1 -0
- package/dist/context-Dnj4ofbV.js +3 -0
- package/dist/context-Dnj4ofbV.js.map +1 -0
- package/dist/{date-range-CfIIPIA_.js → date-range-CwqFuGGK.js} +2 -2
- package/dist/{date-range-CfIIPIA_.js.map → date-range-CwqFuGGK.js.map} +1 -1
- package/dist/{date-range-inline-B87TDYI6.js.map → date-range-inline-B_g1YXu3.js.map} +1 -1
- package/dist/{date-range-inline-De-M0VmL.cjs.map → date-range-inline-LLC3Y0mi.cjs.map} +1 -1
- package/dist/date-range-inline.cjs +1 -1
- package/dist/date-range-inline.js +1 -1
- package/dist/{date-range-B0kW9np7.cjs → date-range-n_xPONd5.cjs} +1 -1
- package/dist/{date-range-B0kW9np7.cjs.map → date-range-n_xPONd5.cjs.map} +1 -1
- package/dist/date-range.cjs +1 -1
- package/dist/date-range.js +1 -1
- package/dist/{delay-k_HiVnhP.cjs → delay-BFpu_Yz9.cjs} +1 -1
- package/dist/{delay-k_HiVnhP.cjs.map → delay-BFpu_Yz9.cjs.map} +1 -1
- package/dist/{delay-CPoyWZuQ.js → delay-Bkd3SOTy.js} +1 -1
- package/dist/{delay-CPoyWZuQ.js.map → delay-Bkd3SOTy.js.map} +1 -1
- package/dist/delay.cjs +1 -1
- package/dist/delay.js +1 -1
- package/dist/{details-CQIbCUY0.cjs.map → details-Bal2g3J4.cjs.map} +1 -1
- package/dist/{details-BU5kx0Jh.js.map → details-DZq61CD5.js.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/{dialog-service-ClFrOWf4.js → dialog-service-CCFGpU7a.js} +1 -1
- package/dist/{dialog-service-ClFrOWf4.js.map → dialog-service-CCFGpU7a.js.map} +1 -1
- package/dist/{dialog-service-DcuAavp2.cjs → dialog-service-DXLGSshF.cjs} +1 -1
- package/dist/{dialog-service-DcuAavp2.cjs.map → dialog-service-DXLGSshF.cjs.map} +1 -1
- package/dist/dialog.cjs +1 -1
- package/dist/dialog.js +1 -1
- package/dist/{divider-D9borfuG.js.map → divider-ChK7lCQF.js.map} +1 -1
- package/dist/{divider-IX9sp29l.cjs.map → divider-RjZbewe8.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/{expand-Dw9tbuFG.js → expand-CUrWPZu-.js} +1 -1
- package/dist/{expand-Dw9tbuFG.js.map → expand-CUrWPZu-.js.map} +1 -1
- package/dist/{expand-dIrDcH9Y.cjs → expand-DwZKr9hD.cjs} +1 -1
- package/dist/{expand-dIrDcH9Y.cjs.map → expand-DwZKr9hD.cjs.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/{extra-BFpPepJn.cjs.map → extra-BE9p8l3U.cjs.map} +1 -1
- package/dist/{extra-D3sZLtFY.js.map → extra-C7xp1GQG.js.map} +1 -1
- package/dist/extra.cjs +1 -1
- package/dist/extra.js +1 -1
- package/dist/{float-CJ3SuEcG.cjs → float-DoHSvH7R.cjs} +1 -1
- package/dist/{float-CJ3SuEcG.cjs.map → float-DoHSvH7R.cjs.map} +1 -1
- package/dist/{float-BKd4pilD.js → float-kRCgEf_1.js} +1 -1
- package/dist/{float-BKd4pilD.js.map → float-kRCgEf_1.js.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/{flow-CqgDEIqK.js.map → flow-BPDtbhLe.js.map} +1 -1
- package/dist/{flow-DSu4PLt1.cjs.map → flow-Dn9AZktE.cjs.map} +1 -1
- package/dist/{form-D2cJ58TB.js.map → form-C1qS9uvS.js.map} +1 -1
- package/dist/{form-CAY9GSCd.cjs.map → form-CzD0JLxM.cjs.map} +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.js +1 -1
- package/dist/{hashContent-nD2uWwi2.js.map → hashContent-BUqULUiZ.js.map} +1 -1
- package/dist/{hashContent-kKvXKFa9.cjs.map → hashContent-CI39BY-_.cjs.map} +1 -1
- package/dist/{icons-1AkKNd7O.cjs → icons-Bz84Dr-q.cjs} +4 -4
- package/dist/icons-Bz84Dr-q.cjs.map +1 -0
- package/dist/{icons-DqIVrIIK.js → icons-D93IZn6-.js} +29 -25
- package/dist/icons-D93IZn6-.js.map +1 -0
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-CtDetaw3.cjs.map → iframe-Cmanzy9x.cjs.map} +1 -1
- package/dist/{iframe-D4R1Rq7G.js.map → iframe-DyOg96rn.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 +36 -36
- package/dist/{input-DMjpf6V8.cjs.map → input-DIuyi3Gm.cjs.map} +1 -1
- package/dist/{input-Ri72dn5t.js.map → input-HzweUBSn.js.map} +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/{intersection-LfEsy29T.js.map → intersection-C0JuW_7U.js.map} +1 -1
- package/dist/{intersection-D1v1UCVv.cjs.map → intersection-MvbRovUz.cjs.map} +1 -1
- package/dist/json.cjs +1 -1
- package/dist/json.js +1 -1
- package/dist/{layout-Dh0qW7XU.js → layout-D7OCZ8rE.js} +1 -1
- package/dist/{layout-Dh0qW7XU.js.map → layout-D7OCZ8rE.js.map} +1 -1
- package/dist/{layout-B1gXjlIO.cjs → layout-DIuACbuC.cjs} +1 -1
- package/dist/{layout-B1gXjlIO.cjs.map → layout-DIuACbuC.cjs.map} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +2 -2
- package/dist/{lightbox-BUuGltX9.cjs → lightbox-DFbqNGoX.cjs} +1 -1
- package/dist/{lightbox-BUuGltX9.cjs.map → lightbox-DFbqNGoX.cjs.map} +1 -1
- package/dist/{lightbox-BM_Bpk_l.js → lightbox-DL-v1tk9.js} +1 -1
- package/dist/{lightbox-BM_Bpk_l.js.map → lightbox-DL-v1tk9.js.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-C1GMiAi_.cjs.map → list-D99W7WvC.cjs.map} +1 -1
- package/dist/{list-DrF_av2K.js.map → list-DZTLJ-2e.js.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{mailbox-BjB502y9.js → mailbox-BBV6hDAa.js} +3 -3
- package/dist/{mailbox-BjB502y9.js.map → mailbox-BBV6hDAa.js.map} +1 -1
- package/dist/{mailbox-D0iXsqyx.cjs → mailbox-CW7zc0v-.cjs} +1 -1
- package/dist/{mailbox-D0iXsqyx.cjs.map → mailbox-CW7zc0v-.cjs.map} +1 -1
- package/dist/mailbox.cjs +1 -1
- package/dist/mailbox.js +1 -1
- package/dist/{map-uRYJeifl.cjs.map → map-CSQMA89X.cjs.map} +1 -1
- package/dist/{map-BZTxFRVH.js.map → map-PvojF8B3.js.map} +1 -1
- package/dist/map.cjs +1 -1
- package/dist/map.js +1 -1
- package/dist/{menu-CXFa_bk4.cjs → menu-3XXOfmrj.cjs} +1 -1
- package/dist/{menu-CXFa_bk4.cjs.map → menu-3XXOfmrj.cjs.map} +1 -1
- package/dist/{menu-BamT46lt.js → menu-B_o1fOPW.js} +1 -1
- package/dist/{menu-BamT46lt.js.map → menu-B_o1fOPW.js.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.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/{notification-COgjQodt.js → notification-BMtrJG-Y.js} +1 -1
- package/dist/{notification-COgjQodt.js.map → notification-BMtrJG-Y.js.map} +1 -1
- package/dist/{notification-Xid-o7gi.cjs → notification-NnsatHAh.cjs} +1 -1
- package/dist/{notification-Xid-o7gi.cjs.map → notification-NnsatHAh.cjs.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-DdYe_l1A.js.map → option-CNzW-sdU.js.map} +1 -1
- package/dist/{option-CNWUeHW3.cjs.map → option-DxIFpYpC.cjs.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-stack-Ca4EK2Mu.js.map → overlay-stack-BJt_r6aZ.js.map} +1 -1
- package/dist/{overlay-stack-CEYGD9T1.cjs.map → overlay-stack-J_eJCUTX.cjs.map} +1 -1
- package/dist/page.cjs +1 -1
- package/dist/page.js +1 -1
- package/dist/{progress-Bw-VD6wH.cjs.map → progress-Cw6Qn3Kb.cjs.map} +1 -1
- package/dist/{progress-OQvbUkDs.js.map → progress-DHmYCHmy.js.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-DI1JXW5r.js.map → radio-group-DneItRXU.js.map} +1 -1
- package/dist/{radio-group-D5t8f2Ob.cjs.map → radio-group-xgKQTd6h.cjs.map} +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/{rxjs-utils-Bldch1RO.js.map → rxjs-utils-CN9fv8Xq.js.map} +1 -1
- package/dist/{rxjs-utils-hAgKC7vk.cjs.map → rxjs-utils-Vn6DCKgL.cjs.map} +1 -1
- package/dist/rxjs-utils.cjs +1 -1
- package/dist/rxjs-utils.js +1 -1
- package/dist/{scroll-Dym-6yPI.js.map → scroll-D7QJYev7.js.map} +1 -1
- package/dist/{scroll-BG5qMncw.cjs.map → scroll-DZAB4JFv.cjs.map} +1 -1
- package/dist/{select-C3L3imJM.js → select-B2T3RZng.js} +1 -1
- package/dist/{select-C3L3imJM.js.map → select-B2T3RZng.js.map} +1 -1
- package/dist/{select-B1nN5Ac4.cjs → select-D2eLEDUT.cjs} +1 -1
- package/dist/{select-B1nN5Ac4.cjs.map → select-D2eLEDUT.cjs.map} +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/{sheet-BS9WlMaj.js → sheet-BiGXZPdu.js} +1 -1
- package/dist/{sheet-BS9WlMaj.js.map → sheet-BiGXZPdu.js.map} +1 -1
- package/dist/{sheet-BZRMpyXt.cjs → sheet-NaecDxuR.cjs} +1 -1
- package/dist/{sheet-BZRMpyXt.cjs.map → sheet-NaecDxuR.cjs.map} +1 -1
- package/dist/sheet.cjs +1 -1
- package/dist/sheet.js +2 -2
- package/dist/{sheet.service-l9jTUaot.cjs → sheet.service-CQq5hUNb.cjs} +1 -1
- package/dist/{sheet.service-l9jTUaot.cjs.map → sheet.service-CQq5hUNb.cjs.map} +1 -1
- package/dist/{sheet.service-DQWkiYEe.js → sheet.service-gek7Spb6.js} +1 -1
- package/dist/{sheet.service-DQWkiYEe.js.map → sheet.service-gek7Spb6.js.map} +1 -1
- package/dist/skills/SKILL.md +1 -1
- package/dist/skills/schmancy/SKILL.md +1 -1
- package/dist/{splash-screen-DuFJ0gbD.cjs.map → splash-screen-CxPHf-SC.cjs.map} +1 -1
- package/dist/{splash-screen-M-v_jiLs.js.map → splash-screen-Dc6LDIbK.js.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-Ba-S6DFW.cjs → src-BP8bYUHc.cjs} +1 -1
- package/dist/{src-Ba-S6DFW.cjs.map → src-BP8bYUHc.cjs.map} +1 -1
- package/dist/{src-CbR3znbw.js → src-BYrvfmFF.js} +39 -39
- package/dist/{src-CbR3znbw.js.map → src-BYrvfmFF.js.map} +1 -1
- package/dist/{surface-kM2aYH4g.js.map → surface-B2cmGNZ2.js.map} +1 -1
- package/dist/{surface-PECoCLgx.cjs.map → surface-C9plkl5F.cjs.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/{table-CENjXiu-.cjs → table-6xNLZh3K.cjs} +2 -2
- package/dist/{table-CENjXiu-.cjs.map → table-6xNLZh3K.cjs.map} +1 -1
- package/dist/{table-DrMgc8Aw.js → table-BCJgjSvq.js} +2 -2
- package/dist/{table-DrMgc8Aw.js.map → table-BCJgjSvq.js.map} +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.js +1 -1
- package/dist/{tabs-BvFiM0y-.js.map → tabs-BDqvhB54.js.map} +1 -1
- package/dist/{tabs-CRA9FMNl.cjs.map → tabs-pvevSaFB.cjs.map} +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/tailwind.mixin-Bug3G6K6.cjs.map +1 -1
- package/dist/tailwind.mixin-ywtUNG2c.js.map +1 -1
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/dist/{textarea-DD5gxIsG.js.map → textarea-BvZn41aa.js.map} +1 -1
- package/dist/{textarea-CfwGEIvf.cjs.map → textarea-D2v000gK.cjs.map} +1 -1
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-BiM_CUpn.cjs → theme-Dw9Ag_VS.cjs} +1 -1
- package/dist/{theme-BiM_CUpn.cjs.map → theme-Dw9Ag_VS.cjs.map} +1 -1
- package/dist/{theme-DNJmVFXF.js → theme-JvXazXJr.js} +1 -1
- package/dist/{theme-DNJmVFXF.js.map → theme-JvXazXJr.js.map} +1 -1
- package/dist/{theme-button-19T3SFrv.js.map → theme-button-Bh8wKXtV.js.map} +1 -1
- package/dist/{theme-button-BwJs6N4k.cjs.map → theme-button-qHd4AFsE.cjs.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/{theme.interface-CM26m9te.cjs.map → theme.interface-CCE3L1ql.cjs.map} +1 -1
- package/dist/{theme.interface-FAUIgbIq.js.map → theme.interface-Cyqv5XWY.js.map} +1 -1
- package/dist/theme.js +2 -2
- package/dist/{tslib.es6-Bd-92OW3.cjs.map → tslib.es6-PMITL0Z3.cjs.map} +1 -1
- package/dist/{tslib.es6-CI1onEZb.js.map → tslib.es6-vJQZBGJO.js.map} +1 -1
- package/dist/{typewriter-BH7nsW7R.cjs → typewriter-C5uDB2Lu.cjs} +1 -1
- package/dist/{typewriter-BH7nsW7R.cjs.map → typewriter-C5uDB2Lu.cjs.map} +1 -1
- package/dist/{typewriter-Z-8bbwOh.js → typewriter-PpYJFsVi.js} +3 -3
- package/dist/{typewriter-Z-8bbwOh.js.map → typewriter-PpYJFsVi.js.map} +1 -1
- package/dist/typewriter.cjs +1 -1
- package/dist/typewriter.js +1 -1
- package/dist/{utils-D2kE-6zc.cjs → utils-C8PD8So2.cjs} +1 -1
- package/dist/{utils-D2kE-6zc.cjs.map → utils-C8PD8So2.cjs.map} +1 -1
- package/dist/{utils-Cq0m3LYo.js → utils-DVuCPDfw.js} +2 -2
- package/dist/{utils-Cq0m3LYo.js.map → utils-DVuCPDfw.js.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +3 -3
- package/dist/{window-Du_ougyw.js → window-ChDgkb97.js} +1 -1
- package/dist/{window-Du_ougyw.js.map → window-ChDgkb97.js.map} +1 -1
- package/dist/{window-NDXXyj5v.cjs → window-Czfu-i4Y.cjs} +1 -1
- package/dist/{window-NDXXyj5v.cjs.map → window-Czfu-i4Y.cjs.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 +1 -1
- package/src/button/button.ts +6 -1
- package/src/button/context.ts +9 -0
- package/src/icons/icon.ts +19 -3
- package/types/src/button/button.d.ts +4 -1
- package/types/src/button/context.d.ts +8 -0
- package/types/src/icons/icon.d.ts +9 -0
- package/dist/icons-1AkKNd7O.cjs.map +0 -1
- package/dist/icons-DqIVrIIK.js.map +0 -1
- /package/dist/{card-DUq_MsxC.cjs → card-Bht1QcYl.cjs} +0 -0
- /package/dist/{card-C8Ns2mRo.js → card-DiNYPJ9b.js} +0 -0
- /package/dist/{chips-0rKPqQt8.js → chips-Bma_B3J-.js} +0 -0
- /package/dist/{chips-BI_kt5BS.cjs → chips-CXknD-vY.cjs} +0 -0
- /package/dist/{code-highlight-DGInmDAW.cjs → code-highlight-BROOsNA_.cjs} +0 -0
- /package/dist/{code-highlight-ClzG4FL4.js → code-highlight-DjiyaDcX.js} +0 -0
- /package/dist/{components-RbvrLE3U.js → components-DKgu88mm.js} +0 -0
- /package/dist/{components-7hOtFi_q.cjs → components-ubXwQbGs.cjs} +0 -0
- /package/dist/{date-range-inline-B87TDYI6.js → date-range-inline-B_g1YXu3.js} +0 -0
- /package/dist/{date-range-inline-De-M0VmL.cjs → date-range-inline-LLC3Y0mi.cjs} +0 -0
- /package/dist/{details-CQIbCUY0.cjs → details-Bal2g3J4.cjs} +0 -0
- /package/dist/{details-BU5kx0Jh.js → details-DZq61CD5.js} +0 -0
- /package/dist/{divider-D9borfuG.js → divider-ChK7lCQF.js} +0 -0
- /package/dist/{divider-IX9sp29l.cjs → divider-RjZbewe8.cjs} +0 -0
- /package/dist/{extra-BFpPepJn.cjs → extra-BE9p8l3U.cjs} +0 -0
- /package/dist/{extra-D3sZLtFY.js → extra-C7xp1GQG.js} +0 -0
- /package/dist/{flow-CqgDEIqK.js → flow-BPDtbhLe.js} +0 -0
- /package/dist/{flow-DSu4PLt1.cjs → flow-Dn9AZktE.cjs} +0 -0
- /package/dist/{form-D2cJ58TB.js → form-C1qS9uvS.js} +0 -0
- /package/dist/{form-CAY9GSCd.cjs → form-CzD0JLxM.cjs} +0 -0
- /package/dist/{hashContent-nD2uWwi2.js → hashContent-BUqULUiZ.js} +0 -0
- /package/dist/{hashContent-kKvXKFa9.cjs → hashContent-CI39BY-_.cjs} +0 -0
- /package/dist/{iframe-CtDetaw3.cjs → iframe-Cmanzy9x.cjs} +0 -0
- /package/dist/{iframe-D4R1Rq7G.js → iframe-DyOg96rn.js} +0 -0
- /package/dist/{input-DMjpf6V8.cjs → input-DIuyi3Gm.cjs} +0 -0
- /package/dist/{input-Ri72dn5t.js → input-HzweUBSn.js} +0 -0
- /package/dist/{intersection-LfEsy29T.js → intersection-C0JuW_7U.js} +0 -0
- /package/dist/{intersection-D1v1UCVv.cjs → intersection-MvbRovUz.cjs} +0 -0
- /package/dist/{list-C1GMiAi_.cjs → list-D99W7WvC.cjs} +0 -0
- /package/dist/{list-DrF_av2K.js → list-DZTLJ-2e.js} +0 -0
- /package/dist/{map-uRYJeifl.cjs → map-CSQMA89X.cjs} +0 -0
- /package/dist/{map-BZTxFRVH.js → map-PvojF8B3.js} +0 -0
- /package/dist/{option-DdYe_l1A.js → option-CNzW-sdU.js} +0 -0
- /package/dist/{option-CNWUeHW3.cjs → option-DxIFpYpC.cjs} +0 -0
- /package/dist/{overlay-stack-Ca4EK2Mu.js → overlay-stack-BJt_r6aZ.js} +0 -0
- /package/dist/{overlay-stack-CEYGD9T1.cjs → overlay-stack-J_eJCUTX.cjs} +0 -0
- /package/dist/{progress-Bw-VD6wH.cjs → progress-Cw6Qn3Kb.cjs} +0 -0
- /package/dist/{progress-OQvbUkDs.js → progress-DHmYCHmy.js} +0 -0
- /package/dist/{radio-group-DI1JXW5r.js → radio-group-DneItRXU.js} +0 -0
- /package/dist/{radio-group-D5t8f2Ob.cjs → radio-group-xgKQTd6h.cjs} +0 -0
- /package/dist/{rxjs-utils-Bldch1RO.js → rxjs-utils-CN9fv8Xq.js} +0 -0
- /package/dist/{rxjs-utils-hAgKC7vk.cjs → rxjs-utils-Vn6DCKgL.cjs} +0 -0
- /package/dist/{scroll-Dym-6yPI.js → scroll-D7QJYev7.js} +0 -0
- /package/dist/{scroll-BG5qMncw.cjs → scroll-DZAB4JFv.cjs} +0 -0
- /package/dist/{splash-screen-DuFJ0gbD.cjs → splash-screen-CxPHf-SC.cjs} +0 -0
- /package/dist/{splash-screen-M-v_jiLs.js → splash-screen-Dc6LDIbK.js} +0 -0
- /package/dist/{surface-kM2aYH4g.js → surface-B2cmGNZ2.js} +0 -0
- /package/dist/{surface-PECoCLgx.cjs → surface-C9plkl5F.cjs} +0 -0
- /package/dist/{tabs-BvFiM0y-.js → tabs-BDqvhB54.js} +0 -0
- /package/dist/{tabs-CRA9FMNl.cjs → tabs-pvevSaFB.cjs} +0 -0
- /package/dist/{textarea-DD5gxIsG.js → textarea-BvZn41aa.js} +0 -0
- /package/dist/{textarea-CfwGEIvf.cjs → textarea-D2v000gK.cjs} +0 -0
- /package/dist/{theme-button-19T3SFrv.js → theme-button-Bh8wKXtV.js} +0 -0
- /package/dist/{theme-button-BwJs6N4k.cjs → theme-button-qHd4AFsE.cjs} +0 -0
- /package/dist/{theme.interface-CM26m9te.cjs → theme.interface-CCE3L1ql.cjs} +0 -0
- /package/dist/{theme.interface-FAUIgbIq.js → theme.interface-Cyqv5XWY.js} +0 -0
- /package/dist/{tslib.es6-Bd-92OW3.cjs → tslib.es6-PMITL0Z3.cjs} +0 -0
- /package/dist/{tslib.es6-CI1onEZb.js → tslib.es6-vJQZBGJO.js} +0 -0
package/dist/mailbox.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./mailbox-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./mailbox-CW7zc0v-.cjs`);Object.defineProperty(exports,`SchmancyEmailEditor`,{enumerable:!0,get:function(){return e.r}}),Object.defineProperty(exports,`SchmancyEmailLayoutSelector`,{enumerable:!0,get:function(){return e.i}}),Object.defineProperty(exports,`SchmancyEmailRecipients`,{enumerable:!0,get:function(){return e.t}}),Object.defineProperty(exports,`SchmancyEmailViewer`,{enumerable:!0,get:function(){return e.n}}),Object.defineProperty(exports,`SchmancyMailbox`,{enumerable:!0,get:function(){return e.a}});
|
package/dist/mailbox.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "./mailbox-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./mailbox-BBV6hDAa.js";
|
|
2
2
|
export { r as SchmancyEmailEditor, t as SchmancyEmailLayoutSelector, i as SchmancyEmailRecipients, n as SchmancyEmailViewer, e as SchmancyMailbox };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-uRYJeifl.cjs","names":[],"sources":["../src/map/map.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ref, createRef } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { of, EMPTY, Observable } from 'rxjs'\nimport { switchMap, tap, catchError, takeUntil, finalize, shareReplay } from 'rxjs/operators'\n\ninterface GoogleMapsAPI {\n maps: {\n Map: new (element: HTMLElement, options: any) => any\n Marker: new (options: any) => any\n Geocoder: new () => any\n LatLng: new (lat: number, lng: number) => any\n MapTypeId: {\n ROADMAP: string\n SATELLITE: string\n HYBRID: string\n TERRAIN: string\n }\n }\n}\n\ndeclare global {\n interface Window {\n google?: GoogleMapsAPI\n initGoogleMaps?: () => void\n __schmancyGoogleMapsLoading?: Observable<boolean>\n }\n}\n\n// Singleton for managing Google Maps script loading\nclass GoogleMapsLoader {\n private static loading$?: Observable<boolean>\n\n static load(apiKey: string): Observable<boolean> {\n // If already loaded, return success\n if (window.google?.maps) {\n return of(true)\n }\n\n // If already loading, return the existing observable\n if (this.loading$) {\n return this.loading$\n }\n\n // Create a new loading observable\n this.loading$ = new Observable<boolean>(observer => {\n // Check again if loaded while waiting\n if (window.google?.maps) {\n observer.next(true)\n observer.complete()\n return\n }\n\n const script = document.createElement('script')\n // Using places library instead of geometry for geocoding\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMaps&v=weekly`\n script.async = true\n script.defer = true\n\n window.initGoogleMaps = () => {\n observer.next(true)\n observer.complete()\n }\n\n script.onerror = (error) => {\n console.error('Google Maps script loading error:', error)\n observer.error(new Error('Failed to load Google Maps. Please check API key configuration and ensure the domain is authorized.'))\n }\n\n document.head.appendChild(script)\n }).pipe(\n shareReplay(1) // Share the result among all subscribers\n )\n\n return this.loading$\n }\n}\n\n/**\n * `<schmancy-map>` component\n *\n * A Google Maps component with an intuitive API for displaying interactive or static maps.\n * Supports both address strings (with automatic geocoding) and precise coordinates.\n *\n * @element schmancy-map\n *\n * @example\n * <!-- Simple address -->\n * <schmancy-map address=\"Times Square, New York\"></schmancy-map>\n *\n * @example\n * <!-- With coordinates -->\n * <schmancy-map latitude=\"40.758\" longitude=\"-73.985\" zoom=\"17\"></schmancy-map>\n *\n * @example\n * <!-- Satellite view -->\n * <schmancy-map address=\"Grand Canyon\" type=\"satellite\" height=\"500px\"></schmancy-map>\n *\n * @example\n * <!-- Static map -->\n * <schmancy-map address=\"Eiffel Tower, Paris\" interactive=\"false\" controls=\"false\"></schmancy-map>\n */\n@customElement('schmancy-map')\nexport default class SchmancyMap extends TailwindElement(css`\n :host {\n display: block;\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: var(--schmancy-sys-color-surface-container);\n color: var(--schmancy-sys-color-surface-on);\n }\n \n :host([height]) {\n height: var(--map-height);\n }\n \n .map-container {\n width: 100%;\n height: 100%;\n min-height: 400px;\n }\n \n .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n padding: 24px;\n text-align: center;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-icon {\n width: 48px;\n height: 48px;\n margin-bottom: 16px;\n color: var(--schmancy-sys-color-error-default);\n }\n \n .error-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--schmancy-sys-color-surface-on);\n }\n \n .error-message {\n font-size: 14px;\n color: var(--schmancy-sys-color-surface-onVariant);\n line-height: 1.5;\n }\n`) {\n /**\n * Simple address string that automatically geocodes to display the location.\n * Takes precedence over latitude/longitude if both are provided.\n */\n @property({ type: String })\n address: string = ''\n\n /**\n * Latitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n latitude?: number\n\n /**\n * Longitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n longitude?: number\n\n /**\n * Map zoom level. Higher numbers show more detail.\n * @default 15\n */\n @property({ type: Number })\n zoom: number = 15\n\n /**\n * Height of the map with CSS unit (e.g., \"400px\", \"50vh\").\n * @default \"400px\"\n */\n @property({ type: String, reflect: true })\n height: string = '400px'\n\n /**\n * Whether to show a marker at the location.\n * @default true\n */\n @property({ type: Boolean })\n marker: boolean = true\n\n /**\n * Tooltip text for the location marker.\n */\n @property({ type: String })\n markerTitle: string = ''\n\n /**\n * Map display type.\n * Options: \"roadmap\", \"satellite\", \"hybrid\", \"terrain\"\n * @default \"roadmap\"\n */\n @property({ type: String })\n type: 'roadmap' | 'satellite' | 'hybrid' | 'terrain' = 'roadmap'\n\n /**\n * Whether users can interact with the map (pan, zoom, click).\n * @default true\n */\n @property({ type: Boolean })\n interactive: boolean = true\n\n /**\n * Whether to show map controls (zoom buttons, fullscreen, etc.).\n * @default true\n */\n @property({ type: Boolean })\n controls: boolean = true\n\n /**\n * Google Maps API key. Required for the map to load.\n */\n @property({ type: String })\n apiKey: string = ''\n\n @state() private loading: boolean = false\n @state() private error: string = ''\n\n private mapRef = createRef<HTMLDivElement>()\n private map?: any\n private mapMarker?: any\n private geocoder?: any\n private intersectionObserver?: IntersectionObserver\n private hasLoadedMap = false\n\n connectedCallback() {\n super.connectedCallback()\n \n // Set CSS custom property for height\n this.style.setProperty('--map-height', this.height)\n \n // Only load map when component becomes visible\n this.setupIntersectionObserver()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect()\n }\n }\n\n private setupIntersectionObserver() {\n // Load map only when it's visible in the viewport\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !this.hasLoadedMap) {\n this.hasLoadedMap = true\n this.loadMap()\n // Stop observing after loading\n this.intersectionObserver?.disconnect()\n }\n })\n },\n {\n root: null,\n rootMargin: '50px',\n threshold: 0.01\n }\n )\n \n this.intersectionObserver.observe(this)\n }\n\n private loadMap() {\n of(null).pipe(\n tap(() => {\n this.loading = true\n this.error = ''\n }),\n switchMap(() => {\n if (!this.apiKey) {\n throw new Error('Google Maps API key is required. Please provide it via the apiKey property.')\n }\n return GoogleMapsLoader.load(this.apiKey)\n }),\n switchMap(() => this.getCoordinates()),\n tap((coordinates) => {\n // Store coordinates for later use\n this.pendingCoordinates = coordinates\n }),\n catchError((error) => {\n console.error('Map loading error:', error)\n this.error = error.message || 'Failed to load map'\n return EMPTY\n }),\n finalize(() => {\n this.loading = false\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private pendingCoordinates?: { lat: number; lng: number }\n\n private getCoordinates() {\n if (this.address) {\n return this.geocodeAddress(this.address)\n }\n\n if (this.latitude !== undefined && this.longitude !== undefined) {\n return of({ lat: this.latitude, lng: this.longitude })\n }\n\n throw new Error('Either address or latitude/longitude coordinates are required')\n }\n\n private geocodeAddress(address: string) {\n if (!this.geocoder) {\n this.geocoder = new window.google!.maps.Geocoder()\n }\n\n return new Promise<{ lat: number; lng: number }>((resolve, reject) => {\n this.geocoder.geocode({ address }, (results: any[], status: string) => {\n if (status === 'OK' && results[0]) {\n const location = results[0].geometry.location\n resolve({\n lat: location.lat(),\n lng: location.lng()\n })\n } else {\n reject(new Error(`Geocoding failed: ${status}`))\n }\n })\n })\n }\n\n private initializeMap(coordinates: { lat: number; lng: number }) {\n if (!this.mapRef.value || !window.google?.maps) {\n return\n }\n\n const mapOptions = {\n center: coordinates,\n zoom: this.zoom,\n mapTypeId: this.getMapTypeId(),\n disableDefaultUI: !this.controls,\n gestureHandling: this.interactive ? 'cooperative' : 'none',\n zoomControl: this.controls,\n mapTypeControl: this.controls,\n scaleControl: this.controls,\n streetViewControl: this.controls,\n rotateControl: this.controls,\n fullscreenControl: this.controls,\n styles: this.interactive ? undefined : [\n {\n featureType: 'poi',\n stylers: [{ visibility: 'off' }]\n }\n ]\n }\n\n this.map = new window.google.maps.Map(this.mapRef.value, mapOptions)\n\n if (this.marker) {\n this.addMarker(coordinates)\n }\n }\n\n private getMapTypeId(): string {\n const typeMap = {\n roadmap: window.google!.maps.MapTypeId.ROADMAP,\n satellite: window.google!.maps.MapTypeId.SATELLITE,\n hybrid: window.google!.maps.MapTypeId.HYBRID,\n terrain: window.google!.maps.MapTypeId.TERRAIN\n }\n return typeMap[this.type] || typeMap.roadmap\n }\n\n private addMarker(coordinates: { lat: number; lng: number }) {\n if (!window.google?.maps || !this.map) {\n return\n }\n\n this.mapMarker = new window.google.maps.Marker({\n position: coordinates,\n map: this.map,\n title: this.markerTitle || this.address || 'Location'\n })\n }\n\n protected updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties)\n\n if (changedProperties.has('height')) {\n this.style.setProperty('--map-height', this.height)\n }\n\n // Initialize map when loading completes and container is ready\n if (changedProperties.has('loading') && !this.loading && this.pendingCoordinates && !this.map) {\n // Wait for next frame to ensure map container is rendered\n requestAnimationFrame(() => {\n if (this.mapRef.value && this.pendingCoordinates) {\n this.initializeMap(this.pendingCoordinates)\n this.pendingCoordinates = undefined\n }\n })\n }\n\n // Reload map if critical properties change (only if map was already loaded)\n if (\n changedProperties.has('address') ||\n changedProperties.has('latitude') ||\n changedProperties.has('longitude') ||\n changedProperties.has('type') ||\n changedProperties.has('zoom')\n ) {\n if (this.map && this.hasLoadedMap) {\n this.loadMap()\n }\n }\n\n // Update marker title if it changes\n if (changedProperties.has('markerTitle') && this.mapMarker) {\n this.mapMarker.setTitle(this.markerTitle || this.address || 'Location')\n }\n }\n\n protected render() {\n return html`\n ${when(\n this.loading,\n () => html`\n <div class=\"loading-container\">\n <schmancy-spinner></schmancy-spinner>\n </div>\n `,\n () => when(\n this.error,\n () => html`\n <div class=\"error-container\">\n <svg class=\"error-icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" \n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n <div class=\"error-title\">Map could not be loaded</div>\n <div class=\"error-message\">${this.error}</div>\n </div>\n `,\n () => html`\n <div class=\"map-container\" ${ref(this.mapRef)}></div>\n `\n )\n )}\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-map': SchmancyMap\n }\n}\n"],"mappings":"uTAgCA,IAAM,EAAN,KAAA,CAGE,OAAA,KAAY,EAAA,CAEV,OAAI,OAAO,QAAQ,MACjB,EAAA,EAAA,IAAA,CAAU,EAAA,EAIR,AAKJ,KAAK,WAAW,IAAI,EAAA,WAAoB,GAAA,CAEtC,GAAI,OAAO,QAAQ,KAGjB,OAFA,EAAS,KAAA,CAAK,EAAA,CAAA,KACd,EAAS,UAAA,CAIX,IAAM,EAAS,SAAS,cAAc,SAAA,CAEtC,EAAO,IAAM,+CAA+C,EAAA,oDAC5D,EAAO,MAAA,CAAQ,EACf,EAAO,MAAA,CAAQ,EAEf,OAAO,mBAAA,CACL,EAAS,KAAA,CAAK,EAAA,CACd,EAAS,UAAA,EAGX,EAAO,QAAW,GAAA,CAEhB,EAAS,MAAU,MAAM,sGAAA,CAAA,EAG3B,SAAS,KAAK,YAAY,EAAA,EAAA,CACzB,MAAA,EAAA,EAAA,aACW,EAAA,CAAA,CA9BL,KAAK,YA8DH,EAAA,cAA0B,EAAA,EAAgB,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAoExC,GAAA,KAAA,KAqBH,GAAA,KAAA,OAOE,QAAA,KAAA,OAAA,CAOC,EAAA,KAAA,YAMI,GAAA,KAAA,KAQiC,UAAA,KAAA,YAAA,CAOhC,EAAA,KAAA,SAAA,CAOH,EAAA,KAAA,OAMH,GAAA,KAAA,QAAA,CAEmB,EAAA,KAAA,MACH,GAAA,KAAA,QAAA,EAAA,EAAA,YAAA,CAAA,KAAA,aAAA,CAOV,EAEvB,mBAAA,CACE,MAAM,mBAAA,CAGN,KAAK,MAAM,YAAY,eAAgB,KAAK,OAAA,CAG5C,KAAK,2BAAA,CAGP,sBAAA,CACE,MAAM,sBAAA,CACF,KAAK,sBACP,KAAK,qBAAqB,YAAA,CAI9B,2BAAA,CAEE,KAAK,qBAAuB,IAAI,qBAC7B,GAAA,CACC,EAAQ,QAAQ,GAAA,CACV,EAAM,gBAAA,CAAmB,KAAK,eAChC,KAAK,aAAA,CAAe,EACpB,KAAK,SAAA,CAEL,KAAK,sBAAsB,YAAA,GAAA,EAIjC,CACE,KAAM,KACN,WAAY,OACZ,UAAW,IAAA,CAAA,CAIf,KAAK,qBAAqB,QAAQ,KAAA,CAGpC,SAAA,EACE,EAAA,EAAA,IAAG,KAAA,CAAM,MAAA,EAAA,EAAA,SAAA,CAEL,KAAK,QAAA,CAAU,EACf,KAAK,MAAQ,IAAA,EACb,EAAA,EAAA,eAAA,CAEA,GAAA,CAAK,KAAK,OACR,MAAU,MAAM,8EAAA,CAElB,OAAO,EAAiB,KAAK,KAAK,OAAA,EAAA,EAClC,EAAA,EAAA,eACc,KAAK,gBAAA,CAAA,EAAiB,EAAA,EAAA,KACjC,GAAA,CAEH,KAAK,mBAAqB,GAAA,EAC1B,EAAA,EAAA,YACU,IAEV,KAAK,MAAQ,EAAM,SAAW,qBACvB,EAAA,OAAA,EACP,EAAA,EAAA,cAAA,CAEA,KAAK,QAAA,CAAU,GAAA,EACf,EAAA,EAAA,WACQ,KAAK,cAAA,CAAA,CACf,WAAA,CAKJ,gBAAA,CACE,GAAI,KAAK,QACP,OAAO,KAAK,eAAe,KAAK,QAAA,CAGlC,GAAI,KAAK,WAAT,IAAsB,IAAa,KAAK,YAA/B,IAA6C,GACpD,OAAA,EAAA,EAAA,IAAU,CAAE,IAAK,KAAK,SAAU,IAAK,KAAK,UAAA,CAAA,CAG5C,MAAU,MAAM,gEAAA,CAGlB,eAAuB,EAAA,CAKrB,MAJK,CACH,KAAK,WAAW,IAAI,OAAO,OAAQ,KAAK,SAGnC,IAAI,SAAuC,EAAS,IAAA,CACzD,KAAK,SAAS,QAAQ,CAAE,QAAA,EAAA,EAAY,EAAgB,IAAA,CAClD,GAAI,IAAW,MAAQ,EAAQ,GAAI,CACjC,IAAM,EAAW,EAAQ,GAAG,SAAS,SACrC,EAAQ,CACN,IAAK,EAAS,KAAA,CACd,IAAK,EAAS,KAAA,CAAA,CAAA,MAGhB,EAAW,MAAM,qBAAqB,IAAA,CAAA,EAAA,EAAA,CAM9C,cAAsB,EAAA,CACpB,GAAA,CAAK,KAAK,OAAO,OAAA,CAAU,OAAO,QAAQ,KACxC,OAGF,IAAM,EAAa,CACjB,OAAQ,EACR,KAAM,KAAK,KACX,UAAW,KAAK,cAAA,CAChB,iBAAA,CAAmB,KAAK,SACxB,gBAAiB,KAAK,YAAc,cAAgB,OACpD,YAAa,KAAK,SAClB,eAAgB,KAAK,SACrB,aAAc,KAAK,SACnB,kBAAmB,KAAK,SACxB,cAAe,KAAK,SACpB,kBAAmB,KAAK,SACxB,OAAQ,KAAK,YAAA,IAAc,GAAY,CACrC,CACE,YAAa,MACb,QAAS,CAAC,CAAE,WAAY,MAAA,CAAA,CAAA,CAAA,CAAA,CAK9B,KAAK,IAAM,IAAI,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO,MAAO,EAAA,CAErD,KAAK,QACP,KAAK,UAAU,EAAA,CAInB,cAAA,CACE,IAAM,EAAU,CACd,QAAS,OAAO,OAAQ,KAAK,UAAU,QACvC,UAAW,OAAO,OAAQ,KAAK,UAAU,UACzC,OAAQ,OAAO,OAAQ,KAAK,UAAU,OACtC,QAAS,OAAO,OAAQ,KAAK,UAAU,QAAA,CAEzC,OAAO,EAAQ,KAAK,OAAS,EAAQ,QAGvC,UAAkB,EAAA,CACX,OAAO,QAAQ,MAAS,KAAK,MAIlC,KAAK,UAAY,IAAI,OAAO,OAAO,KAAK,OAAO,CAC7C,SAAU,EACV,IAAK,KAAK,IACV,MAAO,KAAK,aAAe,KAAK,SAAW,WAAA,CAAA,EAI/C,QAAkB,EAAA,CAChB,MAAM,QAAQ,EAAA,CAEV,EAAkB,IAAI,SAAA,EACxB,KAAK,MAAM,YAAY,eAAgB,KAAK,OAAA,CAI1C,EAAkB,IAAI,UAAA,EAAA,CAAe,KAAK,SAAW,KAAK,oBAAA,CAAuB,KAAK,KAExF,0BAAA,CACM,KAAK,OAAO,OAAS,KAAK,qBAC5B,KAAK,cAAc,KAAK,mBAAA,CACxB,KAAK,mBAAA,IAAqB,KAAA,EAO9B,EAAkB,IAAI,UAAA,EACtB,EAAkB,IAAI,WAAA,EACtB,EAAkB,IAAI,YAAA,EACtB,EAAkB,IAAI,OAAA,EACtB,EAAkB,IAAI,OAAA,GAElB,KAAK,KAAO,KAAK,cACnB,KAAK,SAAA,CAKL,EAAkB,IAAI,cAAA,EAAkB,KAAK,WAC/C,KAAK,UAAU,SAAS,KAAK,aAAe,KAAK,SAAW,WAAA,CAIhE,QAAA,CACE,MAAO,GAAA,IAAI;mBAEP,KAAK,YACC,EAAA,IAAI;;;;yBAMR,KAAK,UACC,EAAA,IAAI;;;;;;;2CAOuB,KAAK,MAAA;;gBAGhC,EAAA,IAAI;mDACyB,KAAK,OAAA,CAAA;;4BA1StC,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,YAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAQ,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOhC,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAMlB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,cAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAQjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,cAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOlB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAMlB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,QAAA,CAAA,CAGnB,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,QAAA,CAAA,CACA,EAAA,UAAA,QAAA,IAAA,GAAA,CAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA7IK,eAAA,CAAA,CAAe,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"map-CSQMA89X.cjs","names":[],"sources":["../src/map/map.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ref, createRef } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { of, EMPTY, Observable } from 'rxjs'\nimport { switchMap, tap, catchError, takeUntil, finalize, shareReplay } from 'rxjs/operators'\n\ninterface GoogleMapsAPI {\n maps: {\n Map: new (element: HTMLElement, options: any) => any\n Marker: new (options: any) => any\n Geocoder: new () => any\n LatLng: new (lat: number, lng: number) => any\n MapTypeId: {\n ROADMAP: string\n SATELLITE: string\n HYBRID: string\n TERRAIN: string\n }\n }\n}\n\ndeclare global {\n interface Window {\n google?: GoogleMapsAPI\n initGoogleMaps?: () => void\n __schmancyGoogleMapsLoading?: Observable<boolean>\n }\n}\n\n// Singleton for managing Google Maps script loading\nclass GoogleMapsLoader {\n private static loading$?: Observable<boolean>\n\n static load(apiKey: string): Observable<boolean> {\n // If already loaded, return success\n if (window.google?.maps) {\n return of(true)\n }\n\n // If already loading, return the existing observable\n if (this.loading$) {\n return this.loading$\n }\n\n // Create a new loading observable\n this.loading$ = new Observable<boolean>(observer => {\n // Check again if loaded while waiting\n if (window.google?.maps) {\n observer.next(true)\n observer.complete()\n return\n }\n\n const script = document.createElement('script')\n // Using places library instead of geometry for geocoding\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMaps&v=weekly`\n script.async = true\n script.defer = true\n\n window.initGoogleMaps = () => {\n observer.next(true)\n observer.complete()\n }\n\n script.onerror = (error) => {\n console.error('Google Maps script loading error:', error)\n observer.error(new Error('Failed to load Google Maps. Please check API key configuration and ensure the domain is authorized.'))\n }\n\n document.head.appendChild(script)\n }).pipe(\n shareReplay(1) // Share the result among all subscribers\n )\n\n return this.loading$\n }\n}\n\n/**\n * `<schmancy-map>` component\n *\n * A Google Maps component with an intuitive API for displaying interactive or static maps.\n * Supports both address strings (with automatic geocoding) and precise coordinates.\n *\n * @element schmancy-map\n *\n * @example\n * <!-- Simple address -->\n * <schmancy-map address=\"Times Square, New York\"></schmancy-map>\n *\n * @example\n * <!-- With coordinates -->\n * <schmancy-map latitude=\"40.758\" longitude=\"-73.985\" zoom=\"17\"></schmancy-map>\n *\n * @example\n * <!-- Satellite view -->\n * <schmancy-map address=\"Grand Canyon\" type=\"satellite\" height=\"500px\"></schmancy-map>\n *\n * @example\n * <!-- Static map -->\n * <schmancy-map address=\"Eiffel Tower, Paris\" interactive=\"false\" controls=\"false\"></schmancy-map>\n */\n@customElement('schmancy-map')\nexport default class SchmancyMap extends TailwindElement(css`\n :host {\n display: block;\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: var(--schmancy-sys-color-surface-container);\n color: var(--schmancy-sys-color-surface-on);\n }\n \n :host([height]) {\n height: var(--map-height);\n }\n \n .map-container {\n width: 100%;\n height: 100%;\n min-height: 400px;\n }\n \n .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n padding: 24px;\n text-align: center;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-icon {\n width: 48px;\n height: 48px;\n margin-bottom: 16px;\n color: var(--schmancy-sys-color-error-default);\n }\n \n .error-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--schmancy-sys-color-surface-on);\n }\n \n .error-message {\n font-size: 14px;\n color: var(--schmancy-sys-color-surface-onVariant);\n line-height: 1.5;\n }\n`) {\n /**\n * Simple address string that automatically geocodes to display the location.\n * Takes precedence over latitude/longitude if both are provided.\n */\n @property({ type: String })\n address: string = ''\n\n /**\n * Latitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n latitude?: number\n\n /**\n * Longitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n longitude?: number\n\n /**\n * Map zoom level. Higher numbers show more detail.\n * @default 15\n */\n @property({ type: Number })\n zoom: number = 15\n\n /**\n * Height of the map with CSS unit (e.g., \"400px\", \"50vh\").\n * @default \"400px\"\n */\n @property({ type: String, reflect: true })\n height: string = '400px'\n\n /**\n * Whether to show a marker at the location.\n * @default true\n */\n @property({ type: Boolean })\n marker: boolean = true\n\n /**\n * Tooltip text for the location marker.\n */\n @property({ type: String })\n markerTitle: string = ''\n\n /**\n * Map display type.\n * Options: \"roadmap\", \"satellite\", \"hybrid\", \"terrain\"\n * @default \"roadmap\"\n */\n @property({ type: String })\n type: 'roadmap' | 'satellite' | 'hybrid' | 'terrain' = 'roadmap'\n\n /**\n * Whether users can interact with the map (pan, zoom, click).\n * @default true\n */\n @property({ type: Boolean })\n interactive: boolean = true\n\n /**\n * Whether to show map controls (zoom buttons, fullscreen, etc.).\n * @default true\n */\n @property({ type: Boolean })\n controls: boolean = true\n\n /**\n * Google Maps API key. Required for the map to load.\n */\n @property({ type: String })\n apiKey: string = ''\n\n @state() private loading: boolean = false\n @state() private error: string = ''\n\n private mapRef = createRef<HTMLDivElement>()\n private map?: any\n private mapMarker?: any\n private geocoder?: any\n private intersectionObserver?: IntersectionObserver\n private hasLoadedMap = false\n\n connectedCallback() {\n super.connectedCallback()\n \n // Set CSS custom property for height\n this.style.setProperty('--map-height', this.height)\n \n // Only load map when component becomes visible\n this.setupIntersectionObserver()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect()\n }\n }\n\n private setupIntersectionObserver() {\n // Load map only when it's visible in the viewport\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !this.hasLoadedMap) {\n this.hasLoadedMap = true\n this.loadMap()\n // Stop observing after loading\n this.intersectionObserver?.disconnect()\n }\n })\n },\n {\n root: null,\n rootMargin: '50px',\n threshold: 0.01\n }\n )\n \n this.intersectionObserver.observe(this)\n }\n\n private loadMap() {\n of(null).pipe(\n tap(() => {\n this.loading = true\n this.error = ''\n }),\n switchMap(() => {\n if (!this.apiKey) {\n throw new Error('Google Maps API key is required. Please provide it via the apiKey property.')\n }\n return GoogleMapsLoader.load(this.apiKey)\n }),\n switchMap(() => this.getCoordinates()),\n tap((coordinates) => {\n // Store coordinates for later use\n this.pendingCoordinates = coordinates\n }),\n catchError((error) => {\n console.error('Map loading error:', error)\n this.error = error.message || 'Failed to load map'\n return EMPTY\n }),\n finalize(() => {\n this.loading = false\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private pendingCoordinates?: { lat: number; lng: number }\n\n private getCoordinates() {\n if (this.address) {\n return this.geocodeAddress(this.address)\n }\n\n if (this.latitude !== undefined && this.longitude !== undefined) {\n return of({ lat: this.latitude, lng: this.longitude })\n }\n\n throw new Error('Either address or latitude/longitude coordinates are required')\n }\n\n private geocodeAddress(address: string) {\n if (!this.geocoder) {\n this.geocoder = new window.google!.maps.Geocoder()\n }\n\n return new Promise<{ lat: number; lng: number }>((resolve, reject) => {\n this.geocoder.geocode({ address }, (results: any[], status: string) => {\n if (status === 'OK' && results[0]) {\n const location = results[0].geometry.location\n resolve({\n lat: location.lat(),\n lng: location.lng()\n })\n } else {\n reject(new Error(`Geocoding failed: ${status}`))\n }\n })\n })\n }\n\n private initializeMap(coordinates: { lat: number; lng: number }) {\n if (!this.mapRef.value || !window.google?.maps) {\n return\n }\n\n const mapOptions = {\n center: coordinates,\n zoom: this.zoom,\n mapTypeId: this.getMapTypeId(),\n disableDefaultUI: !this.controls,\n gestureHandling: this.interactive ? 'cooperative' : 'none',\n zoomControl: this.controls,\n mapTypeControl: this.controls,\n scaleControl: this.controls,\n streetViewControl: this.controls,\n rotateControl: this.controls,\n fullscreenControl: this.controls,\n styles: this.interactive ? undefined : [\n {\n featureType: 'poi',\n stylers: [{ visibility: 'off' }]\n }\n ]\n }\n\n this.map = new window.google.maps.Map(this.mapRef.value, mapOptions)\n\n if (this.marker) {\n this.addMarker(coordinates)\n }\n }\n\n private getMapTypeId(): string {\n const typeMap = {\n roadmap: window.google!.maps.MapTypeId.ROADMAP,\n satellite: window.google!.maps.MapTypeId.SATELLITE,\n hybrid: window.google!.maps.MapTypeId.HYBRID,\n terrain: window.google!.maps.MapTypeId.TERRAIN\n }\n return typeMap[this.type] || typeMap.roadmap\n }\n\n private addMarker(coordinates: { lat: number; lng: number }) {\n if (!window.google?.maps || !this.map) {\n return\n }\n\n this.mapMarker = new window.google.maps.Marker({\n position: coordinates,\n map: this.map,\n title: this.markerTitle || this.address || 'Location'\n })\n }\n\n protected updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties)\n\n if (changedProperties.has('height')) {\n this.style.setProperty('--map-height', this.height)\n }\n\n // Initialize map when loading completes and container is ready\n if (changedProperties.has('loading') && !this.loading && this.pendingCoordinates && !this.map) {\n // Wait for next frame to ensure map container is rendered\n requestAnimationFrame(() => {\n if (this.mapRef.value && this.pendingCoordinates) {\n this.initializeMap(this.pendingCoordinates)\n this.pendingCoordinates = undefined\n }\n })\n }\n\n // Reload map if critical properties change (only if map was already loaded)\n if (\n changedProperties.has('address') ||\n changedProperties.has('latitude') ||\n changedProperties.has('longitude') ||\n changedProperties.has('type') ||\n changedProperties.has('zoom')\n ) {\n if (this.map && this.hasLoadedMap) {\n this.loadMap()\n }\n }\n\n // Update marker title if it changes\n if (changedProperties.has('markerTitle') && this.mapMarker) {\n this.mapMarker.setTitle(this.markerTitle || this.address || 'Location')\n }\n }\n\n protected render() {\n return html`\n ${when(\n this.loading,\n () => html`\n <div class=\"loading-container\">\n <schmancy-spinner></schmancy-spinner>\n </div>\n `,\n () => when(\n this.error,\n () => html`\n <div class=\"error-container\">\n <svg class=\"error-icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" \n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n <div class=\"error-title\">Map could not be loaded</div>\n <div class=\"error-message\">${this.error}</div>\n </div>\n `,\n () => html`\n <div class=\"map-container\" ${ref(this.mapRef)}></div>\n `\n )\n )}\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-map': SchmancyMap\n }\n}\n"],"mappings":"uTAgCA,IAAM,EAAN,KAAA,CAGE,OAAA,KAAY,EAAA,CAEV,OAAI,OAAO,QAAQ,MACjB,EAAA,EAAA,IAAA,CAAU,EAAA,EAIR,AAKJ,KAAK,WAAW,IAAI,EAAA,WAAoB,GAAA,CAEtC,GAAI,OAAO,QAAQ,KAGjB,OAFA,EAAS,KAAA,CAAK,EAAA,CAAA,KACd,EAAS,UAAA,CAIX,IAAM,EAAS,SAAS,cAAc,SAAA,CAEtC,EAAO,IAAM,+CAA+C,EAAA,oDAC5D,EAAO,MAAA,CAAQ,EACf,EAAO,MAAA,CAAQ,EAEf,OAAO,mBAAA,CACL,EAAS,KAAA,CAAK,EAAA,CACd,EAAS,UAAA,EAGX,EAAO,QAAW,GAAA,CAEhB,EAAS,MAAU,MAAM,sGAAA,CAAA,EAG3B,SAAS,KAAK,YAAY,EAAA,EAAA,CACzB,MAAA,EAAA,EAAA,aACW,EAAA,CAAA,CA9BL,KAAK,YA8DH,EAAA,cAA0B,EAAA,EAAgB,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAoExC,GAAA,KAAA,KAqBH,GAAA,KAAA,OAOE,QAAA,KAAA,OAAA,CAOC,EAAA,KAAA,YAMI,GAAA,KAAA,KAQiC,UAAA,KAAA,YAAA,CAOhC,EAAA,KAAA,SAAA,CAOH,EAAA,KAAA,OAMH,GAAA,KAAA,QAAA,CAEmB,EAAA,KAAA,MACH,GAAA,KAAA,QAAA,EAAA,EAAA,YAAA,CAAA,KAAA,aAAA,CAOV,EAEvB,mBAAA,CACE,MAAM,mBAAA,CAGN,KAAK,MAAM,YAAY,eAAgB,KAAK,OAAA,CAG5C,KAAK,2BAAA,CAGP,sBAAA,CACE,MAAM,sBAAA,CACF,KAAK,sBACP,KAAK,qBAAqB,YAAA,CAI9B,2BAAA,CAEE,KAAK,qBAAuB,IAAI,qBAC7B,GAAA,CACC,EAAQ,QAAQ,GAAA,CACV,EAAM,gBAAA,CAAmB,KAAK,eAChC,KAAK,aAAA,CAAe,EACpB,KAAK,SAAA,CAEL,KAAK,sBAAsB,YAAA,GAAA,EAIjC,CACE,KAAM,KACN,WAAY,OACZ,UAAW,IAAA,CAAA,CAIf,KAAK,qBAAqB,QAAQ,KAAA,CAGpC,SAAA,EACE,EAAA,EAAA,IAAG,KAAA,CAAM,MAAA,EAAA,EAAA,SAAA,CAEL,KAAK,QAAA,CAAU,EACf,KAAK,MAAQ,IAAA,EACb,EAAA,EAAA,eAAA,CAEA,GAAA,CAAK,KAAK,OACR,MAAU,MAAM,8EAAA,CAElB,OAAO,EAAiB,KAAK,KAAK,OAAA,EAAA,EAClC,EAAA,EAAA,eACc,KAAK,gBAAA,CAAA,EAAiB,EAAA,EAAA,KACjC,GAAA,CAEH,KAAK,mBAAqB,GAAA,EAC1B,EAAA,EAAA,YACU,IAEV,KAAK,MAAQ,EAAM,SAAW,qBACvB,EAAA,OAAA,EACP,EAAA,EAAA,cAAA,CAEA,KAAK,QAAA,CAAU,GAAA,EACf,EAAA,EAAA,WACQ,KAAK,cAAA,CAAA,CACf,WAAA,CAKJ,gBAAA,CACE,GAAI,KAAK,QACP,OAAO,KAAK,eAAe,KAAK,QAAA,CAGlC,GAAI,KAAK,WAAT,IAAsB,IAAa,KAAK,YAA/B,IAA6C,GACpD,OAAA,EAAA,EAAA,IAAU,CAAE,IAAK,KAAK,SAAU,IAAK,KAAK,UAAA,CAAA,CAG5C,MAAU,MAAM,gEAAA,CAGlB,eAAuB,EAAA,CAKrB,MAJK,CACH,KAAK,WAAW,IAAI,OAAO,OAAQ,KAAK,SAGnC,IAAI,SAAuC,EAAS,IAAA,CACzD,KAAK,SAAS,QAAQ,CAAE,QAAA,EAAA,EAAY,EAAgB,IAAA,CAClD,GAAI,IAAW,MAAQ,EAAQ,GAAI,CACjC,IAAM,EAAW,EAAQ,GAAG,SAAS,SACrC,EAAQ,CACN,IAAK,EAAS,KAAA,CACd,IAAK,EAAS,KAAA,CAAA,CAAA,MAGhB,EAAW,MAAM,qBAAqB,IAAA,CAAA,EAAA,EAAA,CAM9C,cAAsB,EAAA,CACpB,GAAA,CAAK,KAAK,OAAO,OAAA,CAAU,OAAO,QAAQ,KACxC,OAGF,IAAM,EAAa,CACjB,OAAQ,EACR,KAAM,KAAK,KACX,UAAW,KAAK,cAAA,CAChB,iBAAA,CAAmB,KAAK,SACxB,gBAAiB,KAAK,YAAc,cAAgB,OACpD,YAAa,KAAK,SAClB,eAAgB,KAAK,SACrB,aAAc,KAAK,SACnB,kBAAmB,KAAK,SACxB,cAAe,KAAK,SACpB,kBAAmB,KAAK,SACxB,OAAQ,KAAK,YAAA,IAAc,GAAY,CACrC,CACE,YAAa,MACb,QAAS,CAAC,CAAE,WAAY,MAAA,CAAA,CAAA,CAAA,CAAA,CAK9B,KAAK,IAAM,IAAI,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO,MAAO,EAAA,CAErD,KAAK,QACP,KAAK,UAAU,EAAA,CAInB,cAAA,CACE,IAAM,EAAU,CACd,QAAS,OAAO,OAAQ,KAAK,UAAU,QACvC,UAAW,OAAO,OAAQ,KAAK,UAAU,UACzC,OAAQ,OAAO,OAAQ,KAAK,UAAU,OACtC,QAAS,OAAO,OAAQ,KAAK,UAAU,QAAA,CAEzC,OAAO,EAAQ,KAAK,OAAS,EAAQ,QAGvC,UAAkB,EAAA,CACX,OAAO,QAAQ,MAAS,KAAK,MAIlC,KAAK,UAAY,IAAI,OAAO,OAAO,KAAK,OAAO,CAC7C,SAAU,EACV,IAAK,KAAK,IACV,MAAO,KAAK,aAAe,KAAK,SAAW,WAAA,CAAA,EAI/C,QAAkB,EAAA,CAChB,MAAM,QAAQ,EAAA,CAEV,EAAkB,IAAI,SAAA,EACxB,KAAK,MAAM,YAAY,eAAgB,KAAK,OAAA,CAI1C,EAAkB,IAAI,UAAA,EAAA,CAAe,KAAK,SAAW,KAAK,oBAAA,CAAuB,KAAK,KAExF,0BAAA,CACM,KAAK,OAAO,OAAS,KAAK,qBAC5B,KAAK,cAAc,KAAK,mBAAA,CACxB,KAAK,mBAAA,IAAqB,KAAA,EAO9B,EAAkB,IAAI,UAAA,EACtB,EAAkB,IAAI,WAAA,EACtB,EAAkB,IAAI,YAAA,EACtB,EAAkB,IAAI,OAAA,EACtB,EAAkB,IAAI,OAAA,GAElB,KAAK,KAAO,KAAK,cACnB,KAAK,SAAA,CAKL,EAAkB,IAAI,cAAA,EAAkB,KAAK,WAC/C,KAAK,UAAU,SAAS,KAAK,aAAe,KAAK,SAAW,WAAA,CAIhE,QAAA,CACE,MAAO,GAAA,IAAI;mBAEP,KAAK,YACC,EAAA,IAAI;;;;yBAMR,KAAK,UACC,EAAA,IAAI;;;;;;;2CAOuB,KAAK,MAAA;;gBAGhC,EAAA,IAAI;mDACyB,KAAK,OAAA,CAAA;;4BA1StC,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,YAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,OAAQ,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOhC,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAMlB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,cAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAQjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,OAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOjB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,cAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAOlB,CAAE,KAAM,QAAA,CAAA,CAAA,CAAU,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAMlB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,QAAA,CAAA,CAGnB,EAAA,UAAA,UAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,QAAA,CAAA,CACA,EAAA,UAAA,QAAA,IAAA,GAAA,CAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA7IK,eAAA,CAAA,CAAe,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-BZTxFRVH.js","names":[],"sources":["../src/map/map.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ref, createRef } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { of, EMPTY, Observable } from 'rxjs'\nimport { switchMap, tap, catchError, takeUntil, finalize, shareReplay } from 'rxjs/operators'\n\ninterface GoogleMapsAPI {\n maps: {\n Map: new (element: HTMLElement, options: any) => any\n Marker: new (options: any) => any\n Geocoder: new () => any\n LatLng: new (lat: number, lng: number) => any\n MapTypeId: {\n ROADMAP: string\n SATELLITE: string\n HYBRID: string\n TERRAIN: string\n }\n }\n}\n\ndeclare global {\n interface Window {\n google?: GoogleMapsAPI\n initGoogleMaps?: () => void\n __schmancyGoogleMapsLoading?: Observable<boolean>\n }\n}\n\n// Singleton for managing Google Maps script loading\nclass GoogleMapsLoader {\n private static loading$?: Observable<boolean>\n\n static load(apiKey: string): Observable<boolean> {\n // If already loaded, return success\n if (window.google?.maps) {\n return of(true)\n }\n\n // If already loading, return the existing observable\n if (this.loading$) {\n return this.loading$\n }\n\n // Create a new loading observable\n this.loading$ = new Observable<boolean>(observer => {\n // Check again if loaded while waiting\n if (window.google?.maps) {\n observer.next(true)\n observer.complete()\n return\n }\n\n const script = document.createElement('script')\n // Using places library instead of geometry for geocoding\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMaps&v=weekly`\n script.async = true\n script.defer = true\n\n window.initGoogleMaps = () => {\n observer.next(true)\n observer.complete()\n }\n\n script.onerror = (error) => {\n console.error('Google Maps script loading error:', error)\n observer.error(new Error('Failed to load Google Maps. Please check API key configuration and ensure the domain is authorized.'))\n }\n\n document.head.appendChild(script)\n }).pipe(\n shareReplay(1) // Share the result among all subscribers\n )\n\n return this.loading$\n }\n}\n\n/**\n * `<schmancy-map>` component\n *\n * A Google Maps component with an intuitive API for displaying interactive or static maps.\n * Supports both address strings (with automatic geocoding) and precise coordinates.\n *\n * @element schmancy-map\n *\n * @example\n * <!-- Simple address -->\n * <schmancy-map address=\"Times Square, New York\"></schmancy-map>\n *\n * @example\n * <!-- With coordinates -->\n * <schmancy-map latitude=\"40.758\" longitude=\"-73.985\" zoom=\"17\"></schmancy-map>\n *\n * @example\n * <!-- Satellite view -->\n * <schmancy-map address=\"Grand Canyon\" type=\"satellite\" height=\"500px\"></schmancy-map>\n *\n * @example\n * <!-- Static map -->\n * <schmancy-map address=\"Eiffel Tower, Paris\" interactive=\"false\" controls=\"false\"></schmancy-map>\n */\n@customElement('schmancy-map')\nexport default class SchmancyMap extends TailwindElement(css`\n :host {\n display: block;\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: var(--schmancy-sys-color-surface-container);\n color: var(--schmancy-sys-color-surface-on);\n }\n \n :host([height]) {\n height: var(--map-height);\n }\n \n .map-container {\n width: 100%;\n height: 100%;\n min-height: 400px;\n }\n \n .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n padding: 24px;\n text-align: center;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-icon {\n width: 48px;\n height: 48px;\n margin-bottom: 16px;\n color: var(--schmancy-sys-color-error-default);\n }\n \n .error-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--schmancy-sys-color-surface-on);\n }\n \n .error-message {\n font-size: 14px;\n color: var(--schmancy-sys-color-surface-onVariant);\n line-height: 1.5;\n }\n`) {\n /**\n * Simple address string that automatically geocodes to display the location.\n * Takes precedence over latitude/longitude if both are provided.\n */\n @property({ type: String })\n address: string = ''\n\n /**\n * Latitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n latitude?: number\n\n /**\n * Longitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n longitude?: number\n\n /**\n * Map zoom level. Higher numbers show more detail.\n * @default 15\n */\n @property({ type: Number })\n zoom: number = 15\n\n /**\n * Height of the map with CSS unit (e.g., \"400px\", \"50vh\").\n * @default \"400px\"\n */\n @property({ type: String, reflect: true })\n height: string = '400px'\n\n /**\n * Whether to show a marker at the location.\n * @default true\n */\n @property({ type: Boolean })\n marker: boolean = true\n\n /**\n * Tooltip text for the location marker.\n */\n @property({ type: String })\n markerTitle: string = ''\n\n /**\n * Map display type.\n * Options: \"roadmap\", \"satellite\", \"hybrid\", \"terrain\"\n * @default \"roadmap\"\n */\n @property({ type: String })\n type: 'roadmap' | 'satellite' | 'hybrid' | 'terrain' = 'roadmap'\n\n /**\n * Whether users can interact with the map (pan, zoom, click).\n * @default true\n */\n @property({ type: Boolean })\n interactive: boolean = true\n\n /**\n * Whether to show map controls (zoom buttons, fullscreen, etc.).\n * @default true\n */\n @property({ type: Boolean })\n controls: boolean = true\n\n /**\n * Google Maps API key. Required for the map to load.\n */\n @property({ type: String })\n apiKey: string = ''\n\n @state() private loading: boolean = false\n @state() private error: string = ''\n\n private mapRef = createRef<HTMLDivElement>()\n private map?: any\n private mapMarker?: any\n private geocoder?: any\n private intersectionObserver?: IntersectionObserver\n private hasLoadedMap = false\n\n connectedCallback() {\n super.connectedCallback()\n \n // Set CSS custom property for height\n this.style.setProperty('--map-height', this.height)\n \n // Only load map when component becomes visible\n this.setupIntersectionObserver()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect()\n }\n }\n\n private setupIntersectionObserver() {\n // Load map only when it's visible in the viewport\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !this.hasLoadedMap) {\n this.hasLoadedMap = true\n this.loadMap()\n // Stop observing after loading\n this.intersectionObserver?.disconnect()\n }\n })\n },\n {\n root: null,\n rootMargin: '50px',\n threshold: 0.01\n }\n )\n \n this.intersectionObserver.observe(this)\n }\n\n private loadMap() {\n of(null).pipe(\n tap(() => {\n this.loading = true\n this.error = ''\n }),\n switchMap(() => {\n if (!this.apiKey) {\n throw new Error('Google Maps API key is required. Please provide it via the apiKey property.')\n }\n return GoogleMapsLoader.load(this.apiKey)\n }),\n switchMap(() => this.getCoordinates()),\n tap((coordinates) => {\n // Store coordinates for later use\n this.pendingCoordinates = coordinates\n }),\n catchError((error) => {\n console.error('Map loading error:', error)\n this.error = error.message || 'Failed to load map'\n return EMPTY\n }),\n finalize(() => {\n this.loading = false\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private pendingCoordinates?: { lat: number; lng: number }\n\n private getCoordinates() {\n if (this.address) {\n return this.geocodeAddress(this.address)\n }\n\n if (this.latitude !== undefined && this.longitude !== undefined) {\n return of({ lat: this.latitude, lng: this.longitude })\n }\n\n throw new Error('Either address or latitude/longitude coordinates are required')\n }\n\n private geocodeAddress(address: string) {\n if (!this.geocoder) {\n this.geocoder = new window.google!.maps.Geocoder()\n }\n\n return new Promise<{ lat: number; lng: number }>((resolve, reject) => {\n this.geocoder.geocode({ address }, (results: any[], status: string) => {\n if (status === 'OK' && results[0]) {\n const location = results[0].geometry.location\n resolve({\n lat: location.lat(),\n lng: location.lng()\n })\n } else {\n reject(new Error(`Geocoding failed: ${status}`))\n }\n })\n })\n }\n\n private initializeMap(coordinates: { lat: number; lng: number }) {\n if (!this.mapRef.value || !window.google?.maps) {\n return\n }\n\n const mapOptions = {\n center: coordinates,\n zoom: this.zoom,\n mapTypeId: this.getMapTypeId(),\n disableDefaultUI: !this.controls,\n gestureHandling: this.interactive ? 'cooperative' : 'none',\n zoomControl: this.controls,\n mapTypeControl: this.controls,\n scaleControl: this.controls,\n streetViewControl: this.controls,\n rotateControl: this.controls,\n fullscreenControl: this.controls,\n styles: this.interactive ? undefined : [\n {\n featureType: 'poi',\n stylers: [{ visibility: 'off' }]\n }\n ]\n }\n\n this.map = new window.google.maps.Map(this.mapRef.value, mapOptions)\n\n if (this.marker) {\n this.addMarker(coordinates)\n }\n }\n\n private getMapTypeId(): string {\n const typeMap = {\n roadmap: window.google!.maps.MapTypeId.ROADMAP,\n satellite: window.google!.maps.MapTypeId.SATELLITE,\n hybrid: window.google!.maps.MapTypeId.HYBRID,\n terrain: window.google!.maps.MapTypeId.TERRAIN\n }\n return typeMap[this.type] || typeMap.roadmap\n }\n\n private addMarker(coordinates: { lat: number; lng: number }) {\n if (!window.google?.maps || !this.map) {\n return\n }\n\n this.mapMarker = new window.google.maps.Marker({\n position: coordinates,\n map: this.map,\n title: this.markerTitle || this.address || 'Location'\n })\n }\n\n protected updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties)\n\n if (changedProperties.has('height')) {\n this.style.setProperty('--map-height', this.height)\n }\n\n // Initialize map when loading completes and container is ready\n if (changedProperties.has('loading') && !this.loading && this.pendingCoordinates && !this.map) {\n // Wait for next frame to ensure map container is rendered\n requestAnimationFrame(() => {\n if (this.mapRef.value && this.pendingCoordinates) {\n this.initializeMap(this.pendingCoordinates)\n this.pendingCoordinates = undefined\n }\n })\n }\n\n // Reload map if critical properties change (only if map was already loaded)\n if (\n changedProperties.has('address') ||\n changedProperties.has('latitude') ||\n changedProperties.has('longitude') ||\n changedProperties.has('type') ||\n changedProperties.has('zoom')\n ) {\n if (this.map && this.hasLoadedMap) {\n this.loadMap()\n }\n }\n\n // Update marker title if it changes\n if (changedProperties.has('markerTitle') && this.mapMarker) {\n this.mapMarker.setTitle(this.markerTitle || this.address || 'Location')\n }\n }\n\n protected render() {\n return html`\n ${when(\n this.loading,\n () => html`\n <div class=\"loading-container\">\n <schmancy-spinner></schmancy-spinner>\n </div>\n `,\n () => when(\n this.error,\n () => html`\n <div class=\"error-container\">\n <svg class=\"error-icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" \n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n <div class=\"error-title\">Map could not be loaded</div>\n <div class=\"error-message\">${this.error}</div>\n </div>\n `,\n () => html`\n <div class=\"map-container\" ${ref(this.mapRef)}></div>\n `\n )\n )}\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-map': SchmancyMap\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"map-PvojF8B3.js","names":[],"sources":["../src/map/map.ts"],"sourcesContent":["import { TailwindElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ref, createRef } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { of, EMPTY, Observable } from 'rxjs'\nimport { switchMap, tap, catchError, takeUntil, finalize, shareReplay } from 'rxjs/operators'\n\ninterface GoogleMapsAPI {\n maps: {\n Map: new (element: HTMLElement, options: any) => any\n Marker: new (options: any) => any\n Geocoder: new () => any\n LatLng: new (lat: number, lng: number) => any\n MapTypeId: {\n ROADMAP: string\n SATELLITE: string\n HYBRID: string\n TERRAIN: string\n }\n }\n}\n\ndeclare global {\n interface Window {\n google?: GoogleMapsAPI\n initGoogleMaps?: () => void\n __schmancyGoogleMapsLoading?: Observable<boolean>\n }\n}\n\n// Singleton for managing Google Maps script loading\nclass GoogleMapsLoader {\n private static loading$?: Observable<boolean>\n\n static load(apiKey: string): Observable<boolean> {\n // If already loaded, return success\n if (window.google?.maps) {\n return of(true)\n }\n\n // If already loading, return the existing observable\n if (this.loading$) {\n return this.loading$\n }\n\n // Create a new loading observable\n this.loading$ = new Observable<boolean>(observer => {\n // Check again if loaded while waiting\n if (window.google?.maps) {\n observer.next(true)\n observer.complete()\n return\n }\n\n const script = document.createElement('script')\n // Using places library instead of geometry for geocoding\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMaps&v=weekly`\n script.async = true\n script.defer = true\n\n window.initGoogleMaps = () => {\n observer.next(true)\n observer.complete()\n }\n\n script.onerror = (error) => {\n console.error('Google Maps script loading error:', error)\n observer.error(new Error('Failed to load Google Maps. Please check API key configuration and ensure the domain is authorized.'))\n }\n\n document.head.appendChild(script)\n }).pipe(\n shareReplay(1) // Share the result among all subscribers\n )\n\n return this.loading$\n }\n}\n\n/**\n * `<schmancy-map>` component\n *\n * A Google Maps component with an intuitive API for displaying interactive or static maps.\n * Supports both address strings (with automatic geocoding) and precise coordinates.\n *\n * @element schmancy-map\n *\n * @example\n * <!-- Simple address -->\n * <schmancy-map address=\"Times Square, New York\"></schmancy-map>\n *\n * @example\n * <!-- With coordinates -->\n * <schmancy-map latitude=\"40.758\" longitude=\"-73.985\" zoom=\"17\"></schmancy-map>\n *\n * @example\n * <!-- Satellite view -->\n * <schmancy-map address=\"Grand Canyon\" type=\"satellite\" height=\"500px\"></schmancy-map>\n *\n * @example\n * <!-- Static map -->\n * <schmancy-map address=\"Eiffel Tower, Paris\" interactive=\"false\" controls=\"false\"></schmancy-map>\n */\n@customElement('schmancy-map')\nexport default class SchmancyMap extends TailwindElement(css`\n :host {\n display: block;\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: var(--schmancy-sys-color-surface-container);\n color: var(--schmancy-sys-color-surface-on);\n }\n \n :host([height]) {\n height: var(--map-height);\n }\n \n .map-container {\n width: 100%;\n height: 100%;\n min-height: 400px;\n }\n \n .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n min-height: 400px;\n padding: 24px;\n text-align: center;\n background-color: var(--schmancy-sys-color-surface-containerLow);\n }\n \n .error-icon {\n width: 48px;\n height: 48px;\n margin-bottom: 16px;\n color: var(--schmancy-sys-color-error-default);\n }\n \n .error-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--schmancy-sys-color-surface-on);\n }\n \n .error-message {\n font-size: 14px;\n color: var(--schmancy-sys-color-surface-onVariant);\n line-height: 1.5;\n }\n`) {\n /**\n * Simple address string that automatically geocodes to display the location.\n * Takes precedence over latitude/longitude if both are provided.\n */\n @property({ type: String })\n address: string = ''\n\n /**\n * Latitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n latitude?: number\n\n /**\n * Longitude coordinate for precise location.\n * Used when address is not provided.\n */\n @property({ type: Number })\n longitude?: number\n\n /**\n * Map zoom level. Higher numbers show more detail.\n * @default 15\n */\n @property({ type: Number })\n zoom: number = 15\n\n /**\n * Height of the map with CSS unit (e.g., \"400px\", \"50vh\").\n * @default \"400px\"\n */\n @property({ type: String, reflect: true })\n height: string = '400px'\n\n /**\n * Whether to show a marker at the location.\n * @default true\n */\n @property({ type: Boolean })\n marker: boolean = true\n\n /**\n * Tooltip text for the location marker.\n */\n @property({ type: String })\n markerTitle: string = ''\n\n /**\n * Map display type.\n * Options: \"roadmap\", \"satellite\", \"hybrid\", \"terrain\"\n * @default \"roadmap\"\n */\n @property({ type: String })\n type: 'roadmap' | 'satellite' | 'hybrid' | 'terrain' = 'roadmap'\n\n /**\n * Whether users can interact with the map (pan, zoom, click).\n * @default true\n */\n @property({ type: Boolean })\n interactive: boolean = true\n\n /**\n * Whether to show map controls (zoom buttons, fullscreen, etc.).\n * @default true\n */\n @property({ type: Boolean })\n controls: boolean = true\n\n /**\n * Google Maps API key. Required for the map to load.\n */\n @property({ type: String })\n apiKey: string = ''\n\n @state() private loading: boolean = false\n @state() private error: string = ''\n\n private mapRef = createRef<HTMLDivElement>()\n private map?: any\n private mapMarker?: any\n private geocoder?: any\n private intersectionObserver?: IntersectionObserver\n private hasLoadedMap = false\n\n connectedCallback() {\n super.connectedCallback()\n \n // Set CSS custom property for height\n this.style.setProperty('--map-height', this.height)\n \n // Only load map when component becomes visible\n this.setupIntersectionObserver()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect()\n }\n }\n\n private setupIntersectionObserver() {\n // Load map only when it's visible in the viewport\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !this.hasLoadedMap) {\n this.hasLoadedMap = true\n this.loadMap()\n // Stop observing after loading\n this.intersectionObserver?.disconnect()\n }\n })\n },\n {\n root: null,\n rootMargin: '50px',\n threshold: 0.01\n }\n )\n \n this.intersectionObserver.observe(this)\n }\n\n private loadMap() {\n of(null).pipe(\n tap(() => {\n this.loading = true\n this.error = ''\n }),\n switchMap(() => {\n if (!this.apiKey) {\n throw new Error('Google Maps API key is required. Please provide it via the apiKey property.')\n }\n return GoogleMapsLoader.load(this.apiKey)\n }),\n switchMap(() => this.getCoordinates()),\n tap((coordinates) => {\n // Store coordinates for later use\n this.pendingCoordinates = coordinates\n }),\n catchError((error) => {\n console.error('Map loading error:', error)\n this.error = error.message || 'Failed to load map'\n return EMPTY\n }),\n finalize(() => {\n this.loading = false\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private pendingCoordinates?: { lat: number; lng: number }\n\n private getCoordinates() {\n if (this.address) {\n return this.geocodeAddress(this.address)\n }\n\n if (this.latitude !== undefined && this.longitude !== undefined) {\n return of({ lat: this.latitude, lng: this.longitude })\n }\n\n throw new Error('Either address or latitude/longitude coordinates are required')\n }\n\n private geocodeAddress(address: string) {\n if (!this.geocoder) {\n this.geocoder = new window.google!.maps.Geocoder()\n }\n\n return new Promise<{ lat: number; lng: number }>((resolve, reject) => {\n this.geocoder.geocode({ address }, (results: any[], status: string) => {\n if (status === 'OK' && results[0]) {\n const location = results[0].geometry.location\n resolve({\n lat: location.lat(),\n lng: location.lng()\n })\n } else {\n reject(new Error(`Geocoding failed: ${status}`))\n }\n })\n })\n }\n\n private initializeMap(coordinates: { lat: number; lng: number }) {\n if (!this.mapRef.value || !window.google?.maps) {\n return\n }\n\n const mapOptions = {\n center: coordinates,\n zoom: this.zoom,\n mapTypeId: this.getMapTypeId(),\n disableDefaultUI: !this.controls,\n gestureHandling: this.interactive ? 'cooperative' : 'none',\n zoomControl: this.controls,\n mapTypeControl: this.controls,\n scaleControl: this.controls,\n streetViewControl: this.controls,\n rotateControl: this.controls,\n fullscreenControl: this.controls,\n styles: this.interactive ? undefined : [\n {\n featureType: 'poi',\n stylers: [{ visibility: 'off' }]\n }\n ]\n }\n\n this.map = new window.google.maps.Map(this.mapRef.value, mapOptions)\n\n if (this.marker) {\n this.addMarker(coordinates)\n }\n }\n\n private getMapTypeId(): string {\n const typeMap = {\n roadmap: window.google!.maps.MapTypeId.ROADMAP,\n satellite: window.google!.maps.MapTypeId.SATELLITE,\n hybrid: window.google!.maps.MapTypeId.HYBRID,\n terrain: window.google!.maps.MapTypeId.TERRAIN\n }\n return typeMap[this.type] || typeMap.roadmap\n }\n\n private addMarker(coordinates: { lat: number; lng: number }) {\n if (!window.google?.maps || !this.map) {\n return\n }\n\n this.mapMarker = new window.google.maps.Marker({\n position: coordinates,\n map: this.map,\n title: this.markerTitle || this.address || 'Location'\n })\n }\n\n protected updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties)\n\n if (changedProperties.has('height')) {\n this.style.setProperty('--map-height', this.height)\n }\n\n // Initialize map when loading completes and container is ready\n if (changedProperties.has('loading') && !this.loading && this.pendingCoordinates && !this.map) {\n // Wait for next frame to ensure map container is rendered\n requestAnimationFrame(() => {\n if (this.mapRef.value && this.pendingCoordinates) {\n this.initializeMap(this.pendingCoordinates)\n this.pendingCoordinates = undefined\n }\n })\n }\n\n // Reload map if critical properties change (only if map was already loaded)\n if (\n changedProperties.has('address') ||\n changedProperties.has('latitude') ||\n changedProperties.has('longitude') ||\n changedProperties.has('type') ||\n changedProperties.has('zoom')\n ) {\n if (this.map && this.hasLoadedMap) {\n this.loadMap()\n }\n }\n\n // Update marker title if it changes\n if (changedProperties.has('markerTitle') && this.mapMarker) {\n this.mapMarker.setTitle(this.markerTitle || this.address || 'Location')\n }\n }\n\n protected render() {\n return html`\n ${when(\n this.loading,\n () => html`\n <div class=\"loading-container\">\n <schmancy-spinner></schmancy-spinner>\n </div>\n `,\n () => when(\n this.error,\n () => html`\n <div class=\"error-container\">\n <svg class=\"error-icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" \n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n <div class=\"error-title\">Map could not be loaded</div>\n <div class=\"error-message\">${this.error}</div>\n </div>\n `,\n () => html`\n <div class=\"map-container\" ${ref(this.mapRef)}></div>\n `\n )\n )}\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-map': SchmancyMap\n }\n}\n"],"mappings":"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"}
|
package/dist/map.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./map-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./map-CSQMA89X.cjs`);exports.SchmancyMap=e.t;
|
package/dist/map.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./map-
|
|
1
|
+
import { t as e } from "./map-PvojF8B3.js";
|
|
2
2
|
export { e as SchmancyMap };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require(`./chunk-BCfY8kxB.cjs`);const e=require(`./decorate-F9CuyeHg.cjs`),t=require(`./litElement.mixin-De5SG5z7.cjs`);require(`./mixins.cjs`);const n=require(`./dialog-service-
|
|
1
|
+
require(`./chunk-BCfY8kxB.cjs`);const e=require(`./decorate-F9CuyeHg.cjs`),t=require(`./litElement.mixin-De5SG5z7.cjs`);require(`./mixins.cjs`);const n=require(`./dialog-service-DXLGSshF.cjs`);let r=require(`lit/decorators.js`),i=require(`lit`);var a=class extends t.t(i.css`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-
|
|
1
|
+
{"version":3,"file":"menu-3XXOfmrj.cjs","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Menu Component\n *\n * CRITICAL: The dialog ONLY renders the raw menu items passed via the default slot.\n * NO <ul> wrapper, NO classes, NO additional markup in the dialog call.\n * The dialog service handles positioning and display - we just pass the pure content.\n *\n * @example Basic menu with auto-dismiss\n * ```typescript\n * <schmancy-menu>\n * <schmancy-button slot=\"trigger\">Actions</schmancy-button>\n * <schmancy-menu-item @click=${() => editItem()}>Edit</schmancy-menu-item>\n * <schmancy-menu-item @click=${() => deleteItem()}>Delete</schmancy-menu-item>\n * </schmancy-menu>\n * ```\n * Note: Dialog auto-dismisses when schmancy-menu-item is clicked\n *\n * @example Custom component (manual dismiss)\n * ```typescript\n * <schmancy-menu>\n * <schmancy-icon-button slot=\"trigger\">settings</schmancy-icon-button>\n * <my-settings-form @submit=${() => $dialog.dismiss()}></my-settings-form>\n * </schmancy-menu>\n * ```\n * Note: Custom components must call $dialog.dismiss() manually\n *\n * @slot trigger - Button to open menu (new naming)\n * @slot button - Button to open menu (backward compatible)\n * @slot default - Menu items or any custom component to display in dialog\n */\n@customElement('schmancy-menu')\nexport default class SchmancyMenu extends $LitElement(css`\n\t:host {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t}\n`) {\n\t@query('slot:not([name])')\n\tprivate menuSlot!: HTMLSlotElement\n\n\tprivate showMenu(event: MouseEvent) {\n\t\tconst menuItems = this.menuSlot?.assignedElements() || []\n\t\tif (menuItems.length === 0) return\n\n\t\t// Create container and move actual elements to preserve full functionality\n\t\tconst dialogContainer = document.createElement('div')\n\t\tmenuItems.forEach(item => dialogContainer.appendChild(item))\n\n\t\t$dialog\n\t\t\t.component(dialogContainer, {\n\t\t\t\tposition: event,\n\t\t\t\thideActions: true,\n\t\t})\n\t\t\t.finally(() => {\n\t\t\t\t// Restore elements as light DOM children (will be projected via slot)\n\t\t\t\tmenuItems.forEach(item => this.appendChild(item))\n\t\t\t})\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<slot name=\"trigger\" @click=${this.showMenu}>\n\t\t\t\t<slot name=\"button\" @click=${this.showMenu}>\n\t\t\t\t\t<schmancy-icon-button>more_vert</schmancy-icon-button>\n\t\t\t\t</slot>\n\t\t\t</slot>\n\t\t\t<div hidden>\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu': SchmancyMenu\n\t}\n}\n"],"mappings":"qPAMe,IAAA,EAAA,cAA+B,EAAA,EAAY,EAAA,GAAG;;;;GAM5D,QAAA,CACC,MAAO,GAAA,IAAI;oCACyB,EAAA,EAAQ,SAAA,CAAA;;;iCAT/B,qBAAA,CAAA,CAAqB,EAAA,CC+BrB,IAAA,EAAA,cAA2B,EAAA,EAAY,EAAA,GAAG;;;;;GASxD,SAAiB,EAAA,CAChB,IAAM,EAAY,KAAK,UAAU,kBAAA,EAAsB,EAAA,CACvD,GAAI,EAAU,SAAW,EAAG,OAG5B,IAAM,EAAkB,SAAS,cAAc,MAAA,CAC/C,EAAU,QAAQ,GAAQ,EAAgB,YAAY,EAAA,CAAA,CAEtD,EAAA,EACE,UAAU,EAAiB,CAC3B,SAAU,EACV,YAAA,CAAa,EAAA,CAAA,CAEb,YAAA,CAEA,EAAU,QAAQ,GAAQ,KAAK,YAAY,EAAA,CAAA,EAAA,CAI9C,QAAA,CACC,MAAO,GAAA,IAAI;iCACoB,KAAK,SAAA;iCACL,KAAK,SAAA;;;;;;;uBAzB9B,mBAAA,CAAA,CAAmB,EAAA,UAAA,WAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAPZ,gBAAA,CAAA,CAAgB,EAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as e } from "./decorate-D_utPUsC.js";
|
|
2
2
|
import { t } from "./litElement.mixin-D6ZHgGZv.js";
|
|
3
3
|
import "./mixins.js";
|
|
4
|
-
import { t as n } from "./dialog-service-
|
|
4
|
+
import { t as n } from "./dialog-service-CCFGpU7a.js";
|
|
5
5
|
import { customElement as r, query as i } from "lit/decorators.js";
|
|
6
6
|
import { css as a, html as o } from "lit";
|
|
7
7
|
var s = class extends t(a`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-
|
|
1
|
+
{"version":3,"file":"menu-B_o1fOPW.js","names":[],"sources":["../src/menu/menu-item.ts","../src/menu/menu.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n@customElement('schmancy-menu-item')\nexport default class SchmancyMenuItem extends $LitElement(css`\n\t:host {\n\t\tdisplay: block;\n\t}\n`) {\n\n\tprotected render(): unknown {\n\t\treturn html`\n\t\t\t<schmancy-list-item @click=${() => $dialog.dismiss()}>\n\t\t\t\t<slot></slot>\n\t\t\t</schmancy-list-item>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu-item': SchmancyMenuItem\n\t}\n}\n","import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\nimport { $dialog } from '../dialog/dialog-service'\n\n/**\n * Menu Component\n *\n * CRITICAL: The dialog ONLY renders the raw menu items passed via the default slot.\n * NO <ul> wrapper, NO classes, NO additional markup in the dialog call.\n * The dialog service handles positioning and display - we just pass the pure content.\n *\n * @example Basic menu with auto-dismiss\n * ```typescript\n * <schmancy-menu>\n * <schmancy-button slot=\"trigger\">Actions</schmancy-button>\n * <schmancy-menu-item @click=${() => editItem()}>Edit</schmancy-menu-item>\n * <schmancy-menu-item @click=${() => deleteItem()}>Delete</schmancy-menu-item>\n * </schmancy-menu>\n * ```\n * Note: Dialog auto-dismisses when schmancy-menu-item is clicked\n *\n * @example Custom component (manual dismiss)\n * ```typescript\n * <schmancy-menu>\n * <schmancy-icon-button slot=\"trigger\">settings</schmancy-icon-button>\n * <my-settings-form @submit=${() => $dialog.dismiss()}></my-settings-form>\n * </schmancy-menu>\n * ```\n * Note: Custom components must call $dialog.dismiss() manually\n *\n * @slot trigger - Button to open menu (new naming)\n * @slot button - Button to open menu (backward compatible)\n * @slot default - Menu items or any custom component to display in dialog\n */\n@customElement('schmancy-menu')\nexport default class SchmancyMenu extends $LitElement(css`\n\t:host {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t}\n`) {\n\t@query('slot:not([name])')\n\tprivate menuSlot!: HTMLSlotElement\n\n\tprivate showMenu(event: MouseEvent) {\n\t\tconst menuItems = this.menuSlot?.assignedElements() || []\n\t\tif (menuItems.length === 0) return\n\n\t\t// Create container and move actual elements to preserve full functionality\n\t\tconst dialogContainer = document.createElement('div')\n\t\tmenuItems.forEach(item => dialogContainer.appendChild(item))\n\n\t\t$dialog\n\t\t\t.component(dialogContainer, {\n\t\t\t\tposition: event,\n\t\t\t\thideActions: true,\n\t\t})\n\t\t\t.finally(() => {\n\t\t\t\t// Restore elements as light DOM children (will be projected via slot)\n\t\t\t\tmenuItems.forEach(item => this.appendChild(item))\n\t\t\t})\n\t}\n\n\trender() {\n\t\treturn html`\n\t\t\t<slot name=\"trigger\" @click=${this.showMenu}>\n\t\t\t\t<slot name=\"button\" @click=${this.showMenu}>\n\t\t\t\t\t<schmancy-icon-button>more_vert</schmancy-icon-button>\n\t\t\t\t</slot>\n\t\t\t</slot>\n\t\t\t<div hidden>\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-menu': SchmancyMenu\n\t}\n}\n"],"mappings":";;;;;;AAMe,IAAA,IAAA,cAA+B,EAAY,CAAG;;;;;CAM5D,SAAA;AACC,SAAO,CAAI;sCACyB,EAAQ,SAAA,CAAA;;;;;;OAT7C,EAAc,qBAAA,CAAA,EAAqB,EAAA;AC+BrB,IAAA,IAAA,cAA2B,EAAY,CAAG;;;;;;CASxD,SAAiB,GAAA;EAChB,IAAM,IAAY,KAAK,UAAU,kBAAA,IAAsB,EAAA;AACvD,MAAI,EAAU,WAAW,EAAG;EAG5B,IAAM,IAAkB,SAAS,cAAc,MAAA;AAC/C,IAAU,SAAQ,MAAQ,EAAgB,YAAY,EAAA,CAAA,EAEtD,EACE,UAAU,GAAiB;GAC3B,UAAU;GACV,aAAA,CAAa;GAAA,CAAA,CAEb,cAAA;AAEA,KAAU,SAAQ,MAAQ,KAAK,YAAY,EAAA,CAAA;IAAA;;CAI9C,SAAA;AACC,SAAO,CAAI;iCACoB,KAAK,SAAA;iCACL,KAAK,SAAA;;;;;;;;;;GAzBpC,EAAM,mBAAA,CAAA,EAAmB,EAAA,WAAA,YAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAP1B,EAAc,gBAAA,CAAA,EAAgB,EAAA"}
|
package/dist/menu.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`./menu-
|
|
1
|
+
require(`./menu-3XXOfmrj.cjs`);
|
package/dist/menu.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./menu-
|
|
1
|
+
import "./menu-B_o1fOPW.js";
|
package/dist/nav-drawer.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-BP8bYUHc.cjs`);exports.$drawer=e.m,Object.defineProperty(exports,`SchmancyDrawerAppbar`,{enumerable:!0,get:function(){return e.p}}),exports.SchmancyDrawerNavbarMode=e.u,exports.SchmancyDrawerNavbarState=e.d,Object.defineProperty(exports,`SchmancyNavigationDrawer`,{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(exports,`SchmancyNavigationDrawerContent`,{enumerable:!0,get:function(){return e.f}}),Object.defineProperty(exports,`SchmancyNavigationDrawerSidebar`,{enumerable:!0,get:function(){return e.c}}),exports.schmancyNavDrawer=e.h;
|
package/dist/nav-drawer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as e, d as t, f as n, h as r, l as i, m as a, p as o, u as s } from "./src-
|
|
1
|
+
import { c as e, d as t, f as n, h as r, l as i, m as a, p as o, u as s } from "./src-BYrvfmFF.js";
|
|
2
2
|
export { a as $drawer, o as SchmancyDrawerAppbar, s as SchmancyDrawerNavbarMode, t as SchmancyDrawerNavbarState, i as SchmancyNavigationDrawer, n as SchmancyNavigationDrawerContent, e as SchmancyNavigationDrawerSidebar, r as schmancyNavDrawer };
|
package/dist/navigation-bar.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-BP8bYUHc.cjs`);Object.defineProperty(exports,`SchmancyNavigationBar`,{enumerable:!0,get:function(){return e.o}}),Object.defineProperty(exports,`SchmancyNavigationBarItem`,{enumerable:!0,get:function(){return e.s}});
|
package/dist/navigation-bar.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { o as e, s as t } from "./src-
|
|
1
|
+
import { o as e, s as t } from "./src-BYrvfmFF.js";
|
|
2
2
|
export { e as SchmancyNavigationBar, t as SchmancyNavigationBarItem };
|
|
@@ -2,7 +2,7 @@ import { t as e } from "./decorate-D_utPUsC.js";
|
|
|
2
2
|
import { t } from "./litElement.mixin-D6ZHgGZv.js";
|
|
3
3
|
import "./mixins.js";
|
|
4
4
|
import { t as n } from "./audio-C7TzWI8M.js";
|
|
5
|
-
import "./progress-
|
|
5
|
+
import "./progress-DHmYCHmy.js";
|
|
6
6
|
import { BehaviorSubject as r, NEVER as i, catchError as a, finalize as o, interval as s, tap as c, timer as l } from "rxjs";
|
|
7
7
|
import { distinctUntilChanged as u, map as d, switchMap as f, takeUntil as p, tap as m } from "rxjs/operators";
|
|
8
8
|
import { customElement as h, property as g, state as _ } from "lit/decorators.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-COgjQodt.js","names":[],"sources":["../src/notification/notification.scss?inline","../src/notification/notification.ts","../src/notification/notification-service.ts","../src/notification/notify.ts"],"sourcesContent":[":host {\n\tdisplay: block;\n}\n\n.notification {\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 10px;\n\tpadding: 12px;\n\tpadding-right: 32px;\n\tbackground: var(--schmancy-sys-color-surface-container);\n\tborder-radius: var(--schmancy-sys-shape-corner-extraLarge, 16px);\n\tcolor: var(--schmancy-sys-color-surface-on);\n\tmax-width: 320px;\n\toverflow: hidden;\n\n\t/* Type-colored luminous glow */\n\t--notification-glow-color: var(--schmancy-sys-color-primary-default);\n\tbox-shadow: 0 4px 24px -6px color-mix(in srgb, var(--notification-glow-color) 18%, transparent);\n\tborder-left: 2px solid color-mix(in srgb, var(--notification-glow-color) 50%, transparent);\n\n\ttransition:\n\t\tbox-shadow 300ms ease,\n\t\ttransform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\n\t&.info { --notification-glow-color: var(--schmancy-sys-color-primary-default); }\n\t&.success { --notification-glow-color: var(--schmancy-sys-color-success-default); }\n\t&.warning { --notification-glow-color: var(--schmancy-sys-color-warning-default); }\n\t&.error { --notification-glow-color: var(--schmancy-sys-color-error-default); }\n\n\t&.hovered {\n\t\tbox-shadow: 0 8px 32px -4px color-mix(in srgb, var(--notification-glow-color) 28%, transparent);\n\t\ttransform: translateY(-2px);\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\ttransition: box-shadow 200ms ease;\n\t\t&.hovered { transform: none; }\n\t}\n}\n\n.emoji {\n\tfont-size: 20px;\n\tline-height: 1;\n\tflex-shrink: 0;\n\tmargin-top: 1px;\n}\n\n.content {\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.title {\n\tfont-weight: 500;\n\tfont-size: 13px;\n\tline-height: 1.4;\n\tmargin-bottom: 2px;\n\tletter-spacing: 0.01em;\n\n\t.info & {\n\t\tcolor: var(--schmancy-sys-color-primary-default);\n\t}\n\t.success & {\n\t\tcolor: var(--schmancy-sys-color-success-default);\n\t}\n\t.warning & {\n\t\tcolor: var(--schmancy-sys-color-tertiary-default);\n\t}\n\t.error & {\n\t\tcolor: var(--schmancy-sys-color-error-default);\n\t}\n}\n\n.message {\n\tfont-size: 13px;\n\tline-height: 1.4;\n\topacity: 0.75;\n\tletter-spacing: 0.01em;\n}\n\n.close {\n\tposition: absolute;\n\ttop: 8px;\n\tright: 6px;\n\tbackground: none;\n\tborder: none;\n\tfont-size: 16px;\n\tfont-weight: 300;\n\tcolor: var(--schmancy-sys-color-surface-onVariant);\n\tcursor: pointer;\n\tpadding: 4px 6px;\n\tline-height: 1;\n\topacity: 0.4;\n\tborder-radius: var(--schmancy-sys-shape-corner-full, 50%);\n\ttransition: opacity 200ms ease;\n\n\t&:hover {\n\t\topacity: 0.8;\n\t}\n\n\t&:focus-visible {\n\t\toutline: none;\n\t\topacity: 1;\n\t\tbox-shadow:\n\t\t\t0 0 0 2px var(--schmancy-sys-color-primary-default),\n\t\t\t0 0 8px -2px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 25%, transparent);\n\t}\n}\n\n.progress {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n}\n","import { $LitElement } from '@mixins/index'\nimport { html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { BehaviorSubject, timer, interval, NEVER } from 'rxjs'\nimport { switchMap, takeUntil, map, tap, distinctUntilChanged } from 'rxjs/operators'\nimport '../progress/progress'\nimport style from './notification.scss?inline'\n\nexport type NotificationType = 'info' | 'success' | 'warning' | 'error'\n\n/**\n * Calculate a point on an arc between two points\n */\nfunction calculateArcPoint(\n\tstart: { x: number; y: number },\n\tend: { x: number; y: number },\n\tarcDirection: 'up' | 'down' = 'up',\n\tintensity: number = 0.3,\n): { x: number; y: number } {\n\tconst midX = (start.x + end.x) / 2\n\tconst midY = (start.y + end.y) / 2\n\tconst distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))\n\tconst arcHeight = Math.min(distance * intensity, 150)\n\treturn {\n\t\tx: midX,\n\t\ty: arcDirection === 'up' ? midY - arcHeight : midY + arcHeight,\n\t}\n}\n\n/**\n * @fires close - When notification is closed\n */\n@customElement('sch-notification')\nexport default class SchmancyNotification extends $LitElement(style) {\n\t@property({ type: String }) title = ''\n\t@property({ type: String }) message = ''\n\t@property({ type: String }) type: NotificationType = 'info'\n\t@property({ type: Boolean }) closable = true\n\t@property({ type: Number }) duration = 5000 // 0 means no auto-close\n\t@property({ type: String }) id = `notification-${Date.now()}-${Math.floor(Math.random() * 10000)}`\n\t@property({ type: Boolean }) playSound = true\n\t@property({ type: Boolean }) showProgress = false // Show indeterminate progress bar\n\t@property({ type: Object }) startPosition: { x: number; y: number } = { x: 0, y: 0 }\n\n\t@state() private _visible = true\n\t@state() private _progress = 100\n\t@state() private _hovered = false\n\t@state() private _closing = false\n\n\tprivate paused$ = new BehaviorSubject<boolean>(false)\n\tprivate startTime = 0\n\tprivate pausedAt = 0\n\tprivate elapsedBeforePause = 0\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Set fixed positioning for blackbird animation\n\t\tthis.style.position = 'fixed'\n\t\tthis.style.top = '16px'\n\t\tthis.style.right = '16px'\n\t\tthis.style.zIndex = '10001'\n\t\tthis.style.opacity = '0'\n\n\t\t// Animate in after first render\n\t\tthis.updateComplete.then(() => {\n\t\t\tthis.animateIn()\n\t\t})\n\n\t\tif (this.duration > 0) {\n\t\t\tthis.setupAutoClose()\n\t\t\tthis.setupProgressUpdates()\n\t\t}\n\n\t\tif (this.playSound) {\n\t\t\tthis._playSound()\n\t\t}\n\t}\n\n\tprivate async animateIn() {\n\t\t// Get the notification element's final position\n\t\tconst rect = this.getBoundingClientRect()\n\t\tconst targetX = rect.left + rect.width / 2\n\t\tconst targetY = rect.top + rect.height / 2\n\n\t\t// Calculate arc point for upward arc\n\t\tconst arcPoint = calculateArcPoint(this.startPosition, { x: targetX, y: targetY }, 'up', 0.3)\n\n\t\t// Animate from click position to final position with arc\n\t\tawait this.animate(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\ttransform: `translate(${this.startPosition.x - targetX}px, ${this.startPosition.y - targetY}px) scale(0.1)`,\n\t\t\t\t\topacity: 0,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttransform: `translate(${arcPoint.x - targetX}px, ${arcPoint.y - targetY}px) scale(0.6)`,\n\t\t\t\t\topacity: 0.9,\n\t\t\t\t\toffset: 0.5,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\topacity: 1,\n\t\t\t\t},\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 400,\n\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t).finished\n\t}\n\n\tprivate setupAutoClose() {\n\t\tif (this.duration <= 0) return\n\n\t\tthis.startTime = Date.now()\n\t\tthis.elapsedBeforePause = 0\n\n\t\tthis.paused$\n\t\t\t.pipe(\n\t\t\t\tswitchMap(paused => {\n\t\t\t\t\tif (paused) {\n\t\t\t\t\t\tthis.pausedAt = Date.now()\n\t\t\t\t\t\tthis.elapsedBeforePause += this.pausedAt - this.startTime\n\t\t\t\t\t\treturn NEVER\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.startTime = Date.now()\n\t\t\t\t\t\tconst remaining = this.duration - this.elapsedBeforePause\n\t\t\t\t\t\tif (remaining <= 0) {\n\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\treturn NEVER\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn timer(remaining)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => this.close())\n\t}\n\n\tprivate setupProgressUpdates() {\n\t\tif (this.duration <= 0) return\n\n\t\tinterval(16)\n\t\t\t.pipe(\n\t\t\t\tswitchMap(() =>\n\t\t\t\t\tthis.paused$.pipe(\n\t\t\t\t\t\tmap(paused => {\n\t\t\t\t\t\t\tif (paused) return this._progress\n\t\t\t\t\t\t\tconst elapsed = this.elapsedBeforePause + (Date.now() - this.startTime)\n\t\t\t\t\t\t\tconst remaining = Math.max(0, this.duration - elapsed)\n\t\t\t\t\t\t\treturn (remaining / this.duration) * 100\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttap(progress => {\n\t\t\t\t\tthis._progress = progress\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate _playSound() {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('playsound', {\n\t\t\t\tdetail: { type: this.type },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate _handleMouseEnter() {\n\t\tthis._hovered = true\n\t\tthis.paused$.next(true)\n\t}\n\n\tprivate _handleMouseLeave() {\n\t\tthis._hovered = false\n\t\tthis.paused$.next(false)\n\t}\n\n\tpublic async close() {\n\t\tif (this._closing) return\n\t\tthis._closing = true\n\t\tthis._visible = false\n\n\t\t// Animate out before dispatching close event\n\t\tawait this.animate(\n\t\t\t[\n\t\t\t\t{ transform: 'translate(0, 0) scale(1)', opacity: 1 },\n\t\t\t\t{ transform: 'translate(0, -20px) scale(0.8)', opacity: 0 },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 200,\n\t\t\t\teasing: 'cubic-bezier(0.4, 0, 1, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t).finished\n\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('close', {\n\t\t\t\tdetail: { id: this.id },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate _getEmoji(): string {\n\t\tswitch (this.type) {\n\t\t\tcase 'success':\n\t\t\t\treturn '\\u2705'\n\t\t\tcase 'warning':\n\t\t\t\treturn '\\u26A0\\uFE0F'\n\t\t\tcase 'error':\n\t\t\t\treturn '\\u274C'\n\t\t\tdefault:\n\t\t\t\treturn '\\u{1F4A1}'\n\t\t}\n\t}\n\n\trender() {\n\t\tif (!this._visible && this._closing) return html``\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tclass=\"notification ${this.type} ${this._closing ? 'closing' : ''} ${this._hovered ? 'hovered' : ''}\"\n\t\t\t\trole=\"alert\"\n\t\t\t\t@mouseenter=${this._handleMouseEnter}\n\t\t\t\t@mouseleave=${this._handleMouseLeave}\n\t\t\t>\n\t\t\t\t<span class=\"emoji\">${this._getEmoji()}</span>\n\t\t\t\t<div class=\"content\">\n\t\t\t\t\t${this.title ? html`<div class=\"title\">${this.title}</div>` : ''}\n\t\t\t\t\t<div class=\"message\">${this.message}</div>\n\t\t\t\t</div>\n\t\t\t\t${this.closable\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<button class=\"close\" aria-label=\"Close notification\" @click=${this.close}>x</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t\t${this.showProgress || this.duration > 0\n\t\t\t\t\t? html`<schmancy-progress\n\t\t\t\t\t\tclass=\"progress\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t.value=${this._progress}\n\t\t\t\t\t\t?indeterminate=${this.showProgress && this.duration === 0}\n\t\t\t\t\t></schmancy-progress>`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sch-notification': SchmancyNotification\n\t}\n}\n","import { $sounds, type Feeling } from '../audio'\nimport SchmancyNotification, { NotificationType } from './notification'\n\nexport interface NotificationOptions {\n\tid?: string\n\ttitle?: string\n\tmessage: string\n\ttype?: NotificationType\n\tduration?: number\n\tclosable?: boolean\n\tplaySound?: boolean\n\tshowProgress?: boolean\n}\n\nconst typeToFeeling: Record<NotificationType, Feeling> = {\n\tinfo: 'curious',\n\tsuccess: 'content',\n\twarning: 'anxious',\n\terror: 'disappointed',\n}\n\n// Track last mouse position\nlet lastClickPosition = { x: window.innerWidth - 100, y: 50 }\n\n// Global mousedown listener to track click position\nif (typeof window !== 'undefined') {\n\twindow.addEventListener(\n\t\t'mousedown',\n\t\t(e: MouseEvent) => {\n\t\t\tlastClickPosition = { x: e.clientX, y: e.clientY }\n\t\t},\n\t\t{ capture: true, passive: true },\n\t)\n}\n\n// Track current notification element\nlet currentNotification: SchmancyNotification | null = null\n\n/**\n * Notification service for centralized notification management.\n * Provides a simple API for showing notifications.\n */\nexport class NotificationService {\n\tprivate static instance: NotificationService\n\tprivate notificationStack: string[] = []\n\tprivate audioVolume = 0.1\n\n\t// Default notification options\n\tprivate static DEFAULT_OPTIONS: Partial<NotificationOptions> = {\n\t\tduration: 1000, // 1 seconds - long enough to be readable\n\t\tclosable: true,\n\t\tplaySound: true,\n\t}\n\n\t// Type-specific default durations (in milliseconds)\n\tprivate static TYPE_DURATIONS: Record<NotificationType, number> = {\n\t\tsuccess: 1500, // 1.5 seconds - quick confirmation\n\t\tinfo: 2000, // 2 seconds - informational\n\t\twarning: 2500, // 2.5 seconds - needs attention\n\t\terror: 2500, // 2.5 seconds - important\n\t}\n\n\t// Private constructor for singleton pattern\n\tprivate constructor() {\n\t\t$sounds.setVolume(this.audioVolume)\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tpublic static getInstance(): NotificationService {\n\t\tif (!NotificationService.instance) {\n\t\t\tNotificationService.instance = new NotificationService()\n\t\t}\n\t\treturn NotificationService.instance\n\t}\n\n\t/**\n\t * Show a notification\n\t * @returns The ID of the created notification\n\t */\n\tpublic notify(options: NotificationOptions): string {\n\t\t// Apply default options\n\t\tconst completeOptions = {\n\t\t\t...NotificationService.DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t\t// Override with duraton from options if provided, otherwise use default\n\t\t\tduration: options.duration ?? NotificationService.DEFAULT_OPTIONS.duration,\n\t\t}\n\n\t\tconst id = completeOptions.id || `notification-${Date.now()}-${Math.floor(Math.random() * 10000)}`\n\n\t\t// Add to stack for tracking\n\t\tthis.notificationStack.push(id)\n\n\t\t// Remove existing notification if any (only 1 at a time)\n\t\tif (currentNotification) {\n\t\t\tcurrentNotification.remove()\n\t\t\tcurrentNotification = null\n\t\t}\n\n\t\t// Create the notification element directly\n\t\tconst notification = document.createElement('sch-notification') as SchmancyNotification\n\t\tnotification.id = id\n\t\tnotification.title = completeOptions.title || ''\n\t\tnotification.message = completeOptions.message\n\t\tnotification.type = completeOptions.type || 'info'\n\t\tnotification.duration = completeOptions.duration ?? 1000\n\t\tnotification.closable = completeOptions.closable !== false\n\t\tnotification.playSound = false // We handle sound here\n\t\tnotification.showProgress = completeOptions.showProgress || false\n\t\tnotification.startPosition = { ...lastClickPosition }\n\n\t\t// Play sound if enabled\n\t\tif (completeOptions.playSound !== false) {\n\t\t\t$sounds.play(typeToFeeling[notification.type])\n\t\t}\n\n\t\t// Listen for close event\n\t\tnotification.addEventListener('close', () => {\n\t\t\tconst index = this.notificationStack.indexOf(id)\n\t\t\tif (index > -1) {\n\t\t\t\tthis.notificationStack.splice(index, 1)\n\t\t\t}\n\t\t\tnotification.remove()\n\t\t\tif (currentNotification === notification) {\n\t\t\t\tcurrentNotification = null\n\t\t\t}\n\t\t})\n\n\t\t// Append to body\n\t\tdocument.body.appendChild(notification)\n\t\tcurrentNotification = notification\n\n\t\treturn id\n\t}\n\n\t/**\n\t * Dismiss a notification\n\t * @param id Optional notification ID. If not provided, dismisses the most recent notification\n\t */\n\tpublic dismiss(id?: string): void {\n\t\tlet targetId: string | undefined\n\n\t\tif (id) {\n\t\t\t// Remove specific notification from stack\n\t\t\tconst index = this.notificationStack.indexOf(id)\n\t\t\tif (index > -1) {\n\t\t\t\tthis.notificationStack.splice(index, 1)\n\t\t\t\ttargetId = id\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove most recent notification (last in stack)\n\t\t\ttargetId = this.notificationStack.pop()\n\t\t}\n\n\t\tif (targetId && currentNotification && currentNotification.id === targetId) {\n\t\t\tcurrentNotification.close()\n\t\t}\n\t}\n\n\t/**\n\t * Update a notification's content\n\t */\n\tpublic update(id: string, options: Partial<NotificationOptions>): void {\n\t\tif (currentNotification && currentNotification.id === id) {\n\t\t\tif (options.title !== undefined) currentNotification.title = options.title\n\t\t\tif (options.message !== undefined) currentNotification.message = options.message\n\t\t\tif (options.type !== undefined) currentNotification.type = options.type\n\t\t}\n\t}\n\n\t/**\n\t * Show an info notification\n\t */\n\tpublic info(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'info',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.info) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a success notification\n\t */\n\tpublic success(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'success',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.success) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a warning notification\n\t */\n\tpublic warning(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'warning',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.warning) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show an error notification\n\t */\n\tpublic error(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'error',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.error) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a notification with a custom duration\n\t */\n\tpublic customDuration(\n\t\tmessage: string,\n\t\tduration: number,\n\t\toptions: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {},\n\t): string {\n\t\treturn this.notify({\n\t\t\tmessage,\n\t\t\tduration,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a persistent notification (won't auto-dismiss)\n\t */\n\tpublic persistent(message: string, options: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage,\n\t\t\tduration: 0, // Zero duration means no auto-close\n\t\t\t...options,\n\t\t})\n\t}\n}\n\n/**\n * Global notification utility - provides a quick way to show notifications\n */\nexport const $notify = {\n\t/**\n\t * Show a notification\n\t */\n\tshow: (options: NotificationOptions): string => {\n\t\treturn NotificationService.getInstance().notify(options)\n\t},\n\n\t/**\n\t * Show an info notification\n\t */\n\tinfo: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().info(message, options)\n\t},\n\n\t/**\n\t * Show a success notification\n\t */\n\tsuccess: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().success(message, options)\n\t},\n\n\t/**\n\t * Show a warning notification\n\t */\n\twarning: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().warning(message, options)\n\t},\n\n\t/**\n\t * Show an error notification\n\t */\n\terror: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().error(message, options)\n\t},\n\n\t/**\n\t * Show a notification with a custom duration\n\t * @param message The notification message\n\t * @param duration Duration in milliseconds before auto-dismissing (0 for no auto-dismiss)\n\t * @param options Additional notification options\n\t */\n\tcustomDuration: (\n\t\tmessage: string,\n\t\tduration: number,\n\t\toptions: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {},\n\t): string => {\n\t\treturn NotificationService.getInstance().customDuration(message, duration, options)\n\t},\n\n\t/**\n\t * Show a persistent notification that won't auto-dismiss\n\t */\n\tpersistent: (message: string, options: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {}): string => {\n\t\treturn NotificationService.getInstance().persistent(message, options)\n\t},\n\n\t/**\n\t * Dismiss a notification\n\t * @param id Optional notification ID. If not provided, dismisses the most recent notification (queue-like behavior)\n\t */\n\tdismiss: (id?: string): void => {\n\t\treturn NotificationService.getInstance().dismiss(id)\n\t},\n\n\t/**\n\t * Update a notification's content\n\t */\n\tupdate: (id: string, options: Partial<NotificationOptions>): void => {\n\t\treturn NotificationService.getInstance().update(id, options)\n\t},\n}\n\nexport default NotificationService\n","import { Observable, tap, finalize, catchError } from 'rxjs'\r\nimport { $notify, NotificationOptions } from './notification-service'\r\n\r\nexport interface NotifyOptions {\r\n\t/**\r\n\t * Message to show while the operation is in progress\r\n\t */\r\n\tloadingMessage?: string\r\n\t/**\r\n\t * Message to show when the operation completes successfully\r\n\t */\r\n\tsuccessMessage?: string\r\n\t/**\r\n\t * Message to show when the operation fails (can be a function to format error)\r\n\t */\r\n\terrorMessage?: string | ((error: any) => string)\r\n\t/**\r\n\t * Type of notification for loading state\r\n\t */\r\n\tloadingType?: NotificationOptions['type']\r\n\t/**\r\n\t * Type of notification for success state\r\n\t */\r\n\tsuccessType?: NotificationOptions['type']\r\n\t/**\r\n\t * Type of notification for error state\r\n\t */\r\n\terrorType?: NotificationOptions['type']\r\n\t/**\r\n\t * Whether to auto-dismiss the loading notification on complete/error\r\n\t */\r\n\tautoDismissLoading?: boolean\r\n\t/**\r\n\t * Duration for success notification (ms). Use 0 for persistent\r\n\t */\r\n\tsuccessDuration?: number\r\n\t/**\r\n\t * Duration for error notification (ms). Use 0 for persistent\r\n\t */\r\n\terrorDuration?: number\r\n}\r\n\r\n/**\r\n * Wraps an Observable with notification lifecycle management.\r\n * Shows a loading notification with progress indicator, then auto-dismisses and shows success/error notification.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Basic usage with progress indicator\r\n * someApiCall().pipe(\r\n * notify({\r\n * loadingMessage: 'Loading data...',\r\n * successMessage: 'Data loaded successfully!',\r\n * errorMessage: 'Failed to load data'\r\n * })\r\n * ).subscribe()\r\n * \r\n * // With custom durations\r\n * saveData().pipe(\r\n * notify({\r\n * loadingMessage: 'Saving...',\r\n * successMessage: 'Saved!',\r\n * successDuration: 5000, // Success stays for 5 seconds\r\n * errorMessage: (err) => `Save failed: ${err.message}`,\r\n * errorDuration: 0 // Error is persistent until dismissed\r\n * })\r\n * ).subscribe()\r\n * \r\n * // Full configuration example\r\n * uploadFile().pipe(\r\n * notify({\r\n * loadingMessage: 'Uploading file...',\r\n * loadingType: 'info',\r\n * successMessage: 'Upload complete!',\r\n * successType: 'success',\r\n * successDuration: 3000,\r\n * errorMessage: (err) => `Upload failed: ${err.message}`,\r\n * errorType: 'error',\r\n * errorDuration: 10000,\r\n * autoDismissLoading: true\r\n * })\r\n * ).subscribe()\r\n * ```\r\n */\r\nexport function notify<T>(options: NotifyOptions) {\r\n\treturn (source: Observable<T>): Observable<T> => {\r\n\t\tlet loadingNotificationId: string | undefined\r\n\r\n\t\t// Show loading notification if message provided\r\n\t\tif (options.loadingMessage) {\r\n\t\t\tloadingNotificationId = $notify.show({\r\n\t\t\t\tmessage: options.loadingMessage,\r\n\t\t\t\ttype: options.loadingType || 'info',\r\n\t\t\t\tduration: 0, // Persistent until dismissed\r\n\t\t\t\tshowProgress: true, // Show indeterminate progress by default\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn source.pipe(\r\n\t\t\ttap((value) => {\r\n\t\t\t\t// Check if the emitted value contains progress information\r\n\t\t\t\t// Common patterns: { progress: number }, { loaded: number, total: number }, etc.\r\n\t\t\t\tif (loadingNotificationId && typeof value === 'object' && value !== null) {\r\n\t\t\t\t\tlet progress: number | undefined\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Check for different progress patterns\r\n\t\t\t\t\tif ('progress' in value && typeof (value as any).progress === 'number') {\r\n\t\t\t\t\t\tprogress = (value as any).progress\r\n\t\t\t\t\t} else if ('loaded' in value && 'total' in value) {\r\n\t\t\t\t\t\tconst loaded = (value as any).loaded\r\n\t\t\t\t\t\tconst total = (value as any).total\r\n\t\t\t\t\t\tif (typeof loaded === 'number' && typeof total === 'number' && total > 0) {\r\n\t\t\t\t\t\t\tprogress = (loaded / total) * 100\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Update notification with progress if available\r\n\t\t\t\t\tif (progress !== undefined) {\r\n\t\t\t\t\t\t// We need to update the progress of the notification\r\n\t\t\t\t\t\t// For now, we'll update the message to show progress percentage\r\n\t\t\t\t\t\t$notify.update?.(loadingNotificationId, {\r\n\t\t\t\t\t\t\tmessage: `${options.loadingMessage} (${Math.round(progress)}%)`,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t// Check if this is the final success emission (not a progress update)\r\n\t\t\t\t// Typically file uploads emit progress events then a final result\r\n\t\t\t\tconst isProgressUpdate = typeof value === 'object' && value !== null && \r\n\t\t\t\t\t('progress' in value || ('loaded' in value && 'total' in value))\r\n\t\t\t\t\r\n\t\t\t\tif (!isProgressUpdate) {\r\n\t\t\t\t\t// On successful final emission, dismiss loading and show success\r\n\t\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t\t\tloadingNotificationId = undefined\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (options.successMessage) {\r\n\t\t\t\t\t\t$notify.show({\r\n\t\t\t\t\t\t\tmessage: options.successMessage,\r\n\t\t\t\t\t\t\ttype: options.successType || 'success',\r\n\t\t\t\t\t\t\tduration: options.successDuration ?? 2000,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}),\r\n\t\t\tcatchError((error) => {\r\n\t\t\t\t// On error, dismiss loading and show error\r\n\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t\tloadingNotificationId = undefined\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (options.errorMessage) {\r\n\t\t\t\t\tconst message = typeof options.errorMessage === 'function' \r\n\t\t\t\t\t\t? options.errorMessage(error)\r\n\t\t\t\t\t\t: options.errorMessage\r\n\t\t\t\t\t\r\n\t\t\t\t\t$notify.show({\r\n\t\t\t\t\t\tmessage,\r\n\t\t\t\t\t\ttype: options.errorType || 'error',\r\n\t\t\t\t\t\tduration: options.errorDuration ?? 3000,\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Re-throw the error to maintain the error flow\r\n\t\t\t\tthrow error\r\n\t\t\t}),\r\n\t\t\tfinalize(() => {\r\n\t\t\t\t// Clean up any remaining loading notification\r\n\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t)\r\n\t}\r\n}\r\n\r\n/**\r\n * Simplified version for API calls that just need loading and auto-dismiss.\r\n * Perfect for fire-and-forget operations where you want to show progress.\r\n * \r\n * @example\r\n * ```typescript\r\n * downloadData().pipe(\r\n * notifyProgress('Downloading...')\r\n * ).subscribe()\r\n * \r\n * // With custom messages\r\n * saveDocument().pipe(\r\n * notifyProgress('Saving document...', 'Document saved!', 'Save failed')\r\n * ).subscribe()\r\n * ```\r\n */\r\nexport function notifyProgress<T>(\r\n\tloadingMessage: string,\r\n\tsuccessMessage?: string,\r\n\terrorMessage?: string\r\n) {\r\n\treturn notify<T>({\r\n\t\tloadingMessage,\r\n\t\tsuccessMessage: successMessage || undefined,\r\n\t\terrorMessage: errorMessage || undefined,\r\n\t\tautoDismissLoading: true,\r\n\t})\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"notification-BMtrJG-Y.js","names":[],"sources":["../src/notification/notification.scss?inline","../src/notification/notification.ts","../src/notification/notification-service.ts","../src/notification/notify.ts"],"sourcesContent":[":host {\n\tdisplay: block;\n}\n\n.notification {\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 10px;\n\tpadding: 12px;\n\tpadding-right: 32px;\n\tbackground: var(--schmancy-sys-color-surface-container);\n\tborder-radius: var(--schmancy-sys-shape-corner-extraLarge, 16px);\n\tcolor: var(--schmancy-sys-color-surface-on);\n\tmax-width: 320px;\n\toverflow: hidden;\n\n\t/* Type-colored luminous glow */\n\t--notification-glow-color: var(--schmancy-sys-color-primary-default);\n\tbox-shadow: 0 4px 24px -6px color-mix(in srgb, var(--notification-glow-color) 18%, transparent);\n\tborder-left: 2px solid color-mix(in srgb, var(--notification-glow-color) 50%, transparent);\n\n\ttransition:\n\t\tbox-shadow 300ms ease,\n\t\ttransform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\n\t&.info { --notification-glow-color: var(--schmancy-sys-color-primary-default); }\n\t&.success { --notification-glow-color: var(--schmancy-sys-color-success-default); }\n\t&.warning { --notification-glow-color: var(--schmancy-sys-color-warning-default); }\n\t&.error { --notification-glow-color: var(--schmancy-sys-color-error-default); }\n\n\t&.hovered {\n\t\tbox-shadow: 0 8px 32px -4px color-mix(in srgb, var(--notification-glow-color) 28%, transparent);\n\t\ttransform: translateY(-2px);\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\ttransition: box-shadow 200ms ease;\n\t\t&.hovered { transform: none; }\n\t}\n}\n\n.emoji {\n\tfont-size: 20px;\n\tline-height: 1;\n\tflex-shrink: 0;\n\tmargin-top: 1px;\n}\n\n.content {\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.title {\n\tfont-weight: 500;\n\tfont-size: 13px;\n\tline-height: 1.4;\n\tmargin-bottom: 2px;\n\tletter-spacing: 0.01em;\n\n\t.info & {\n\t\tcolor: var(--schmancy-sys-color-primary-default);\n\t}\n\t.success & {\n\t\tcolor: var(--schmancy-sys-color-success-default);\n\t}\n\t.warning & {\n\t\tcolor: var(--schmancy-sys-color-tertiary-default);\n\t}\n\t.error & {\n\t\tcolor: var(--schmancy-sys-color-error-default);\n\t}\n}\n\n.message {\n\tfont-size: 13px;\n\tline-height: 1.4;\n\topacity: 0.75;\n\tletter-spacing: 0.01em;\n}\n\n.close {\n\tposition: absolute;\n\ttop: 8px;\n\tright: 6px;\n\tbackground: none;\n\tborder: none;\n\tfont-size: 16px;\n\tfont-weight: 300;\n\tcolor: var(--schmancy-sys-color-surface-onVariant);\n\tcursor: pointer;\n\tpadding: 4px 6px;\n\tline-height: 1;\n\topacity: 0.4;\n\tborder-radius: var(--schmancy-sys-shape-corner-full, 50%);\n\ttransition: opacity 200ms ease;\n\n\t&:hover {\n\t\topacity: 0.8;\n\t}\n\n\t&:focus-visible {\n\t\toutline: none;\n\t\topacity: 1;\n\t\tbox-shadow:\n\t\t\t0 0 0 2px var(--schmancy-sys-color-primary-default),\n\t\t\t0 0 8px -2px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 25%, transparent);\n\t}\n}\n\n.progress {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n}\n","import { $LitElement } from '@mixins/index'\nimport { html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { BehaviorSubject, timer, interval, NEVER } from 'rxjs'\nimport { switchMap, takeUntil, map, tap, distinctUntilChanged } from 'rxjs/operators'\nimport '../progress/progress'\nimport style from './notification.scss?inline'\n\nexport type NotificationType = 'info' | 'success' | 'warning' | 'error'\n\n/**\n * Calculate a point on an arc between two points\n */\nfunction calculateArcPoint(\n\tstart: { x: number; y: number },\n\tend: { x: number; y: number },\n\tarcDirection: 'up' | 'down' = 'up',\n\tintensity: number = 0.3,\n): { x: number; y: number } {\n\tconst midX = (start.x + end.x) / 2\n\tconst midY = (start.y + end.y) / 2\n\tconst distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))\n\tconst arcHeight = Math.min(distance * intensity, 150)\n\treturn {\n\t\tx: midX,\n\t\ty: arcDirection === 'up' ? midY - arcHeight : midY + arcHeight,\n\t}\n}\n\n/**\n * @fires close - When notification is closed\n */\n@customElement('sch-notification')\nexport default class SchmancyNotification extends $LitElement(style) {\n\t@property({ type: String }) title = ''\n\t@property({ type: String }) message = ''\n\t@property({ type: String }) type: NotificationType = 'info'\n\t@property({ type: Boolean }) closable = true\n\t@property({ type: Number }) duration = 5000 // 0 means no auto-close\n\t@property({ type: String }) id = `notification-${Date.now()}-${Math.floor(Math.random() * 10000)}`\n\t@property({ type: Boolean }) playSound = true\n\t@property({ type: Boolean }) showProgress = false // Show indeterminate progress bar\n\t@property({ type: Object }) startPosition: { x: number; y: number } = { x: 0, y: 0 }\n\n\t@state() private _visible = true\n\t@state() private _progress = 100\n\t@state() private _hovered = false\n\t@state() private _closing = false\n\n\tprivate paused$ = new BehaviorSubject<boolean>(false)\n\tprivate startTime = 0\n\tprivate pausedAt = 0\n\tprivate elapsedBeforePause = 0\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Set fixed positioning for blackbird animation\n\t\tthis.style.position = 'fixed'\n\t\tthis.style.top = '16px'\n\t\tthis.style.right = '16px'\n\t\tthis.style.zIndex = '10001'\n\t\tthis.style.opacity = '0'\n\n\t\t// Animate in after first render\n\t\tthis.updateComplete.then(() => {\n\t\t\tthis.animateIn()\n\t\t})\n\n\t\tif (this.duration > 0) {\n\t\t\tthis.setupAutoClose()\n\t\t\tthis.setupProgressUpdates()\n\t\t}\n\n\t\tif (this.playSound) {\n\t\t\tthis._playSound()\n\t\t}\n\t}\n\n\tprivate async animateIn() {\n\t\t// Get the notification element's final position\n\t\tconst rect = this.getBoundingClientRect()\n\t\tconst targetX = rect.left + rect.width / 2\n\t\tconst targetY = rect.top + rect.height / 2\n\n\t\t// Calculate arc point for upward arc\n\t\tconst arcPoint = calculateArcPoint(this.startPosition, { x: targetX, y: targetY }, 'up', 0.3)\n\n\t\t// Animate from click position to final position with arc\n\t\tawait this.animate(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\ttransform: `translate(${this.startPosition.x - targetX}px, ${this.startPosition.y - targetY}px) scale(0.1)`,\n\t\t\t\t\topacity: 0,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttransform: `translate(${arcPoint.x - targetX}px, ${arcPoint.y - targetY}px) scale(0.6)`,\n\t\t\t\t\topacity: 0.9,\n\t\t\t\t\toffset: 0.5,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\topacity: 1,\n\t\t\t\t},\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 400,\n\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t).finished\n\t}\n\n\tprivate setupAutoClose() {\n\t\tif (this.duration <= 0) return\n\n\t\tthis.startTime = Date.now()\n\t\tthis.elapsedBeforePause = 0\n\n\t\tthis.paused$\n\t\t\t.pipe(\n\t\t\t\tswitchMap(paused => {\n\t\t\t\t\tif (paused) {\n\t\t\t\t\t\tthis.pausedAt = Date.now()\n\t\t\t\t\t\tthis.elapsedBeforePause += this.pausedAt - this.startTime\n\t\t\t\t\t\treturn NEVER\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.startTime = Date.now()\n\t\t\t\t\t\tconst remaining = this.duration - this.elapsedBeforePause\n\t\t\t\t\t\tif (remaining <= 0) {\n\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\treturn NEVER\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn timer(remaining)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => this.close())\n\t}\n\n\tprivate setupProgressUpdates() {\n\t\tif (this.duration <= 0) return\n\n\t\tinterval(16)\n\t\t\t.pipe(\n\t\t\t\tswitchMap(() =>\n\t\t\t\t\tthis.paused$.pipe(\n\t\t\t\t\t\tmap(paused => {\n\t\t\t\t\t\t\tif (paused) return this._progress\n\t\t\t\t\t\t\tconst elapsed = this.elapsedBeforePause + (Date.now() - this.startTime)\n\t\t\t\t\t\t\tconst remaining = Math.max(0, this.duration - elapsed)\n\t\t\t\t\t\t\treturn (remaining / this.duration) * 100\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttap(progress => {\n\t\t\t\t\tthis._progress = progress\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate _playSound() {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('playsound', {\n\t\t\t\tdetail: { type: this.type },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate _handleMouseEnter() {\n\t\tthis._hovered = true\n\t\tthis.paused$.next(true)\n\t}\n\n\tprivate _handleMouseLeave() {\n\t\tthis._hovered = false\n\t\tthis.paused$.next(false)\n\t}\n\n\tpublic async close() {\n\t\tif (this._closing) return\n\t\tthis._closing = true\n\t\tthis._visible = false\n\n\t\t// Animate out before dispatching close event\n\t\tawait this.animate(\n\t\t\t[\n\t\t\t\t{ transform: 'translate(0, 0) scale(1)', opacity: 1 },\n\t\t\t\t{ transform: 'translate(0, -20px) scale(0.8)', opacity: 0 },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 200,\n\t\t\t\teasing: 'cubic-bezier(0.4, 0, 1, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t).finished\n\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('close', {\n\t\t\t\tdetail: { id: this.id },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate _getEmoji(): string {\n\t\tswitch (this.type) {\n\t\t\tcase 'success':\n\t\t\t\treturn '\\u2705'\n\t\t\tcase 'warning':\n\t\t\t\treturn '\\u26A0\\uFE0F'\n\t\t\tcase 'error':\n\t\t\t\treturn '\\u274C'\n\t\t\tdefault:\n\t\t\t\treturn '\\u{1F4A1}'\n\t\t}\n\t}\n\n\trender() {\n\t\tif (!this._visible && this._closing) return html``\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tclass=\"notification ${this.type} ${this._closing ? 'closing' : ''} ${this._hovered ? 'hovered' : ''}\"\n\t\t\t\trole=\"alert\"\n\t\t\t\t@mouseenter=${this._handleMouseEnter}\n\t\t\t\t@mouseleave=${this._handleMouseLeave}\n\t\t\t>\n\t\t\t\t<span class=\"emoji\">${this._getEmoji()}</span>\n\t\t\t\t<div class=\"content\">\n\t\t\t\t\t${this.title ? html`<div class=\"title\">${this.title}</div>` : ''}\n\t\t\t\t\t<div class=\"message\">${this.message}</div>\n\t\t\t\t</div>\n\t\t\t\t${this.closable\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<button class=\"close\" aria-label=\"Close notification\" @click=${this.close}>x</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t\t${this.showProgress || this.duration > 0\n\t\t\t\t\t? html`<schmancy-progress\n\t\t\t\t\t\tclass=\"progress\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t.value=${this._progress}\n\t\t\t\t\t\t?indeterminate=${this.showProgress && this.duration === 0}\n\t\t\t\t\t></schmancy-progress>`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sch-notification': SchmancyNotification\n\t}\n}\n","import { $sounds, type Feeling } from '../audio'\nimport SchmancyNotification, { NotificationType } from './notification'\n\nexport interface NotificationOptions {\n\tid?: string\n\ttitle?: string\n\tmessage: string\n\ttype?: NotificationType\n\tduration?: number\n\tclosable?: boolean\n\tplaySound?: boolean\n\tshowProgress?: boolean\n}\n\nconst typeToFeeling: Record<NotificationType, Feeling> = {\n\tinfo: 'curious',\n\tsuccess: 'content',\n\twarning: 'anxious',\n\terror: 'disappointed',\n}\n\n// Track last mouse position\nlet lastClickPosition = { x: window.innerWidth - 100, y: 50 }\n\n// Global mousedown listener to track click position\nif (typeof window !== 'undefined') {\n\twindow.addEventListener(\n\t\t'mousedown',\n\t\t(e: MouseEvent) => {\n\t\t\tlastClickPosition = { x: e.clientX, y: e.clientY }\n\t\t},\n\t\t{ capture: true, passive: true },\n\t)\n}\n\n// Track current notification element\nlet currentNotification: SchmancyNotification | null = null\n\n/**\n * Notification service for centralized notification management.\n * Provides a simple API for showing notifications.\n */\nexport class NotificationService {\n\tprivate static instance: NotificationService\n\tprivate notificationStack: string[] = []\n\tprivate audioVolume = 0.1\n\n\t// Default notification options\n\tprivate static DEFAULT_OPTIONS: Partial<NotificationOptions> = {\n\t\tduration: 1000, // 1 seconds - long enough to be readable\n\t\tclosable: true,\n\t\tplaySound: true,\n\t}\n\n\t// Type-specific default durations (in milliseconds)\n\tprivate static TYPE_DURATIONS: Record<NotificationType, number> = {\n\t\tsuccess: 1500, // 1.5 seconds - quick confirmation\n\t\tinfo: 2000, // 2 seconds - informational\n\t\twarning: 2500, // 2.5 seconds - needs attention\n\t\terror: 2500, // 2.5 seconds - important\n\t}\n\n\t// Private constructor for singleton pattern\n\tprivate constructor() {\n\t\t$sounds.setVolume(this.audioVolume)\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tpublic static getInstance(): NotificationService {\n\t\tif (!NotificationService.instance) {\n\t\t\tNotificationService.instance = new NotificationService()\n\t\t}\n\t\treturn NotificationService.instance\n\t}\n\n\t/**\n\t * Show a notification\n\t * @returns The ID of the created notification\n\t */\n\tpublic notify(options: NotificationOptions): string {\n\t\t// Apply default options\n\t\tconst completeOptions = {\n\t\t\t...NotificationService.DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t\t// Override with duraton from options if provided, otherwise use default\n\t\t\tduration: options.duration ?? NotificationService.DEFAULT_OPTIONS.duration,\n\t\t}\n\n\t\tconst id = completeOptions.id || `notification-${Date.now()}-${Math.floor(Math.random() * 10000)}`\n\n\t\t// Add to stack for tracking\n\t\tthis.notificationStack.push(id)\n\n\t\t// Remove existing notification if any (only 1 at a time)\n\t\tif (currentNotification) {\n\t\t\tcurrentNotification.remove()\n\t\t\tcurrentNotification = null\n\t\t}\n\n\t\t// Create the notification element directly\n\t\tconst notification = document.createElement('sch-notification') as SchmancyNotification\n\t\tnotification.id = id\n\t\tnotification.title = completeOptions.title || ''\n\t\tnotification.message = completeOptions.message\n\t\tnotification.type = completeOptions.type || 'info'\n\t\tnotification.duration = completeOptions.duration ?? 1000\n\t\tnotification.closable = completeOptions.closable !== false\n\t\tnotification.playSound = false // We handle sound here\n\t\tnotification.showProgress = completeOptions.showProgress || false\n\t\tnotification.startPosition = { ...lastClickPosition }\n\n\t\t// Play sound if enabled\n\t\tif (completeOptions.playSound !== false) {\n\t\t\t$sounds.play(typeToFeeling[notification.type])\n\t\t}\n\n\t\t// Listen for close event\n\t\tnotification.addEventListener('close', () => {\n\t\t\tconst index = this.notificationStack.indexOf(id)\n\t\t\tif (index > -1) {\n\t\t\t\tthis.notificationStack.splice(index, 1)\n\t\t\t}\n\t\t\tnotification.remove()\n\t\t\tif (currentNotification === notification) {\n\t\t\t\tcurrentNotification = null\n\t\t\t}\n\t\t})\n\n\t\t// Append to body\n\t\tdocument.body.appendChild(notification)\n\t\tcurrentNotification = notification\n\n\t\treturn id\n\t}\n\n\t/**\n\t * Dismiss a notification\n\t * @param id Optional notification ID. If not provided, dismisses the most recent notification\n\t */\n\tpublic dismiss(id?: string): void {\n\t\tlet targetId: string | undefined\n\n\t\tif (id) {\n\t\t\t// Remove specific notification from stack\n\t\t\tconst index = this.notificationStack.indexOf(id)\n\t\t\tif (index > -1) {\n\t\t\t\tthis.notificationStack.splice(index, 1)\n\t\t\t\ttargetId = id\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove most recent notification (last in stack)\n\t\t\ttargetId = this.notificationStack.pop()\n\t\t}\n\n\t\tif (targetId && currentNotification && currentNotification.id === targetId) {\n\t\t\tcurrentNotification.close()\n\t\t}\n\t}\n\n\t/**\n\t * Update a notification's content\n\t */\n\tpublic update(id: string, options: Partial<NotificationOptions>): void {\n\t\tif (currentNotification && currentNotification.id === id) {\n\t\t\tif (options.title !== undefined) currentNotification.title = options.title\n\t\t\tif (options.message !== undefined) currentNotification.message = options.message\n\t\t\tif (options.type !== undefined) currentNotification.type = options.type\n\t\t}\n\t}\n\n\t/**\n\t * Show an info notification\n\t */\n\tpublic info(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'info',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.info) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a success notification\n\t */\n\tpublic success(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'success',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.success) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a warning notification\n\t */\n\tpublic warning(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'warning',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.warning) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show an error notification\n\t */\n\tpublic error(message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage: message ?? '',\n\t\t\ttype: 'error',\n\t\t\tduration: message ? (options.duration ?? NotificationService.TYPE_DURATIONS.error) : 1,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a notification with a custom duration\n\t */\n\tpublic customDuration(\n\t\tmessage: string,\n\t\tduration: number,\n\t\toptions: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {},\n\t): string {\n\t\treturn this.notify({\n\t\t\tmessage,\n\t\t\tduration,\n\t\t\t...options,\n\t\t})\n\t}\n\n\t/**\n\t * Show a persistent notification (won't auto-dismiss)\n\t */\n\tpublic persistent(message: string, options: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {}): string {\n\t\treturn this.notify({\n\t\t\tmessage,\n\t\t\tduration: 0, // Zero duration means no auto-close\n\t\t\t...options,\n\t\t})\n\t}\n}\n\n/**\n * Global notification utility - provides a quick way to show notifications\n */\nexport const $notify = {\n\t/**\n\t * Show a notification\n\t */\n\tshow: (options: NotificationOptions): string => {\n\t\treturn NotificationService.getInstance().notify(options)\n\t},\n\n\t/**\n\t * Show an info notification\n\t */\n\tinfo: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().info(message, options)\n\t},\n\n\t/**\n\t * Show a success notification\n\t */\n\tsuccess: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().success(message, options)\n\t},\n\n\t/**\n\t * Show a warning notification\n\t */\n\twarning: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().warning(message, options)\n\t},\n\n\t/**\n\t * Show an error notification\n\t */\n\terror: (message?: string, options: Partial<Omit<NotificationOptions, 'message' | 'type'>> = {}): string => {\n\t\treturn NotificationService.getInstance().error(message, options)\n\t},\n\n\t/**\n\t * Show a notification with a custom duration\n\t * @param message The notification message\n\t * @param duration Duration in milliseconds before auto-dismissing (0 for no auto-dismiss)\n\t * @param options Additional notification options\n\t */\n\tcustomDuration: (\n\t\tmessage: string,\n\t\tduration: number,\n\t\toptions: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {},\n\t): string => {\n\t\treturn NotificationService.getInstance().customDuration(message, duration, options)\n\t},\n\n\t/**\n\t * Show a persistent notification that won't auto-dismiss\n\t */\n\tpersistent: (message: string, options: Partial<Omit<NotificationOptions, 'message' | 'duration'>> = {}): string => {\n\t\treturn NotificationService.getInstance().persistent(message, options)\n\t},\n\n\t/**\n\t * Dismiss a notification\n\t * @param id Optional notification ID. If not provided, dismisses the most recent notification (queue-like behavior)\n\t */\n\tdismiss: (id?: string): void => {\n\t\treturn NotificationService.getInstance().dismiss(id)\n\t},\n\n\t/**\n\t * Update a notification's content\n\t */\n\tupdate: (id: string, options: Partial<NotificationOptions>): void => {\n\t\treturn NotificationService.getInstance().update(id, options)\n\t},\n}\n\nexport default NotificationService\n","import { Observable, tap, finalize, catchError } from 'rxjs'\r\nimport { $notify, NotificationOptions } from './notification-service'\r\n\r\nexport interface NotifyOptions {\r\n\t/**\r\n\t * Message to show while the operation is in progress\r\n\t */\r\n\tloadingMessage?: string\r\n\t/**\r\n\t * Message to show when the operation completes successfully\r\n\t */\r\n\tsuccessMessage?: string\r\n\t/**\r\n\t * Message to show when the operation fails (can be a function to format error)\r\n\t */\r\n\terrorMessage?: string | ((error: any) => string)\r\n\t/**\r\n\t * Type of notification for loading state\r\n\t */\r\n\tloadingType?: NotificationOptions['type']\r\n\t/**\r\n\t * Type of notification for success state\r\n\t */\r\n\tsuccessType?: NotificationOptions['type']\r\n\t/**\r\n\t * Type of notification for error state\r\n\t */\r\n\terrorType?: NotificationOptions['type']\r\n\t/**\r\n\t * Whether to auto-dismiss the loading notification on complete/error\r\n\t */\r\n\tautoDismissLoading?: boolean\r\n\t/**\r\n\t * Duration for success notification (ms). Use 0 for persistent\r\n\t */\r\n\tsuccessDuration?: number\r\n\t/**\r\n\t * Duration for error notification (ms). Use 0 for persistent\r\n\t */\r\n\terrorDuration?: number\r\n}\r\n\r\n/**\r\n * Wraps an Observable with notification lifecycle management.\r\n * Shows a loading notification with progress indicator, then auto-dismisses and shows success/error notification.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Basic usage with progress indicator\r\n * someApiCall().pipe(\r\n * notify({\r\n * loadingMessage: 'Loading data...',\r\n * successMessage: 'Data loaded successfully!',\r\n * errorMessage: 'Failed to load data'\r\n * })\r\n * ).subscribe()\r\n * \r\n * // With custom durations\r\n * saveData().pipe(\r\n * notify({\r\n * loadingMessage: 'Saving...',\r\n * successMessage: 'Saved!',\r\n * successDuration: 5000, // Success stays for 5 seconds\r\n * errorMessage: (err) => `Save failed: ${err.message}`,\r\n * errorDuration: 0 // Error is persistent until dismissed\r\n * })\r\n * ).subscribe()\r\n * \r\n * // Full configuration example\r\n * uploadFile().pipe(\r\n * notify({\r\n * loadingMessage: 'Uploading file...',\r\n * loadingType: 'info',\r\n * successMessage: 'Upload complete!',\r\n * successType: 'success',\r\n * successDuration: 3000,\r\n * errorMessage: (err) => `Upload failed: ${err.message}`,\r\n * errorType: 'error',\r\n * errorDuration: 10000,\r\n * autoDismissLoading: true\r\n * })\r\n * ).subscribe()\r\n * ```\r\n */\r\nexport function notify<T>(options: NotifyOptions) {\r\n\treturn (source: Observable<T>): Observable<T> => {\r\n\t\tlet loadingNotificationId: string | undefined\r\n\r\n\t\t// Show loading notification if message provided\r\n\t\tif (options.loadingMessage) {\r\n\t\t\tloadingNotificationId = $notify.show({\r\n\t\t\t\tmessage: options.loadingMessage,\r\n\t\t\t\ttype: options.loadingType || 'info',\r\n\t\t\t\tduration: 0, // Persistent until dismissed\r\n\t\t\t\tshowProgress: true, // Show indeterminate progress by default\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn source.pipe(\r\n\t\t\ttap((value) => {\r\n\t\t\t\t// Check if the emitted value contains progress information\r\n\t\t\t\t// Common patterns: { progress: number }, { loaded: number, total: number }, etc.\r\n\t\t\t\tif (loadingNotificationId && typeof value === 'object' && value !== null) {\r\n\t\t\t\t\tlet progress: number | undefined\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Check for different progress patterns\r\n\t\t\t\t\tif ('progress' in value && typeof (value as any).progress === 'number') {\r\n\t\t\t\t\t\tprogress = (value as any).progress\r\n\t\t\t\t\t} else if ('loaded' in value && 'total' in value) {\r\n\t\t\t\t\t\tconst loaded = (value as any).loaded\r\n\t\t\t\t\t\tconst total = (value as any).total\r\n\t\t\t\t\t\tif (typeof loaded === 'number' && typeof total === 'number' && total > 0) {\r\n\t\t\t\t\t\t\tprogress = (loaded / total) * 100\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Update notification with progress if available\r\n\t\t\t\t\tif (progress !== undefined) {\r\n\t\t\t\t\t\t// We need to update the progress of the notification\r\n\t\t\t\t\t\t// For now, we'll update the message to show progress percentage\r\n\t\t\t\t\t\t$notify.update?.(loadingNotificationId, {\r\n\t\t\t\t\t\t\tmessage: `${options.loadingMessage} (${Math.round(progress)}%)`,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t// Check if this is the final success emission (not a progress update)\r\n\t\t\t\t// Typically file uploads emit progress events then a final result\r\n\t\t\t\tconst isProgressUpdate = typeof value === 'object' && value !== null && \r\n\t\t\t\t\t('progress' in value || ('loaded' in value && 'total' in value))\r\n\t\t\t\t\r\n\t\t\t\tif (!isProgressUpdate) {\r\n\t\t\t\t\t// On successful final emission, dismiss loading and show success\r\n\t\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t\t\tloadingNotificationId = undefined\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (options.successMessage) {\r\n\t\t\t\t\t\t$notify.show({\r\n\t\t\t\t\t\t\tmessage: options.successMessage,\r\n\t\t\t\t\t\t\ttype: options.successType || 'success',\r\n\t\t\t\t\t\t\tduration: options.successDuration ?? 2000,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}),\r\n\t\t\tcatchError((error) => {\r\n\t\t\t\t// On error, dismiss loading and show error\r\n\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t\tloadingNotificationId = undefined\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (options.errorMessage) {\r\n\t\t\t\t\tconst message = typeof options.errorMessage === 'function' \r\n\t\t\t\t\t\t? options.errorMessage(error)\r\n\t\t\t\t\t\t: options.errorMessage\r\n\t\t\t\t\t\r\n\t\t\t\t\t$notify.show({\r\n\t\t\t\t\t\tmessage,\r\n\t\t\t\t\t\ttype: options.errorType || 'error',\r\n\t\t\t\t\t\tduration: options.errorDuration ?? 3000,\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Re-throw the error to maintain the error flow\r\n\t\t\t\tthrow error\r\n\t\t\t}),\r\n\t\t\tfinalize(() => {\r\n\t\t\t\t// Clean up any remaining loading notification\r\n\t\t\t\tif (loadingNotificationId && options.autoDismissLoading !== false) {\r\n\t\t\t\t\t$notify.dismiss(loadingNotificationId)\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t)\r\n\t}\r\n}\r\n\r\n/**\r\n * Simplified version for API calls that just need loading and auto-dismiss.\r\n * Perfect for fire-and-forget operations where you want to show progress.\r\n * \r\n * @example\r\n * ```typescript\r\n * downloadData().pipe(\r\n * notifyProgress('Downloading...')\r\n * ).subscribe()\r\n * \r\n * // With custom messages\r\n * saveDocument().pipe(\r\n * notifyProgress('Saving document...', 'Document saved!', 'Save failed')\r\n * ).subscribe()\r\n * ```\r\n */\r\nexport function notifyProgress<T>(\r\n\tloadingMessage: string,\r\n\tsuccessMessage?: string,\r\n\terrorMessage?: string\r\n) {\r\n\treturn notify<T>({\r\n\t\tloadingMessage,\r\n\t\tsuccessMessage: successMessage || undefined,\r\n\t\terrorMessage: errorMessage || undefined,\r\n\t\tautoDismissLoading: true,\r\n\t})\r\n}"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require(`./chunk-BCfY8kxB.cjs`);const e=require(`./decorate-F9CuyeHg.cjs`),t=require(`./litElement.mixin-De5SG5z7.cjs`);require(`./mixins.cjs`);const n=require(`./audio-DUVz7Ars.cjs`);require(`./progress-
|
|
1
|
+
require(`./chunk-BCfY8kxB.cjs`);const e=require(`./decorate-F9CuyeHg.cjs`),t=require(`./litElement.mixin-De5SG5z7.cjs`);require(`./mixins.cjs`);const n=require(`./audio-DUVz7Ars.cjs`);require(`./progress-Cw6Qn3Kb.cjs`);let r=require(`rxjs`),i=require(`rxjs/operators`),a=require(`lit/decorators.js`),o=require(`lit`);var s=class extends t.t(`:host{display:block}.notification{background:var(--schmancy-sys-color-surface-container);border-radius:var(--schmancy-sys-shape-corner-extraLarge,16px);color:var(--schmancy-sys-color-surface-on);--notification-glow-color:var(--schmancy-sys-color-primary-default);max-width:320px;box-shadow:0 4px 24px -6px color-mix(in srgb, var(--notification-glow-color) 18%, transparent);border-left:2px solid color-mix(in srgb, var(--notification-glow-color) 50%, transparent);align-items:flex-start;gap:10px;padding:12px 32px 12px 12px;transition:box-shadow .3s,transform .3s cubic-bezier(.34,1.56,.64,1);display:flex;position:relative;overflow:hidden}.notification.info{--notification-glow-color:var(--schmancy-sys-color-primary-default)}.notification.success{--notification-glow-color:var(--schmancy-sys-color-success-default)}.notification.warning{--notification-glow-color:var(--schmancy-sys-color-warning-default)}.notification.error{--notification-glow-color:var(--schmancy-sys-color-error-default)}.notification.hovered{box-shadow:0 8px 32px -4px color-mix(in srgb, var(--notification-glow-color) 28%, transparent);transform:translateY(-2px)}@media (prefers-reduced-motion:reduce){.notification{transition:box-shadow .2s}.notification.hovered{transform:none}}.emoji{flex-shrink:0;margin-top:1px;font-size:20px;line-height:1}.content{flex:1;min-width:0}.title{letter-spacing:.01em;margin-bottom:2px;font-size:13px;font-weight:500;line-height:1.4}.info .title{color:var(--schmancy-sys-color-primary-default)}.success .title{color:var(--schmancy-sys-color-success-default)}.warning .title{color:var(--schmancy-sys-color-tertiary-default)}.error .title{color:var(--schmancy-sys-color-error-default)}.message{opacity:.75;letter-spacing:.01em;font-size:13px;line-height:1.4}.close{color:var(--schmancy-sys-color-surface-onVariant);cursor:pointer;opacity:.4;border-radius:var(--schmancy-sys-shape-corner-full,50%);background:0 0;border:none;padding:4px 6px;font-size:16px;font-weight:300;line-height:1;transition:opacity .2s;position:absolute;top:8px;right:6px}.close:hover{opacity:.8}.close:focus-visible{opacity:1;box-shadow:0 0 0 2px var(--schmancy-sys-color-primary-default), 0 0 8px -2px color-mix(in srgb, var(--schmancy-sys-color-primary-default) 25%, transparent);outline:none}.progress{position:absolute;bottom:0;left:0;right:0}`){constructor(...e){super(...e),this.title=``,this.message=``,this.type=`info`,this.closable=!0,this.duration=5e3,this.id=`notification-${Date.now()}-${Math.floor(1e4*Math.random())}`,this.playSound=!0,this.showProgress=!1,this.startPosition={x:0,y:0},this._visible=!0,this._progress=100,this._hovered=!1,this._closing=!1,this.paused$=new r.BehaviorSubject(!1),this.startTime=0,this.pausedAt=0,this.elapsedBeforePause=0}connectedCallback(){super.connectedCallback(),this.style.position=`fixed`,this.style.top=`16px`,this.style.right=`16px`,this.style.zIndex=`10001`,this.style.opacity=`0`,this.updateComplete.then(()=>{this.animateIn()}),this.duration>0&&(this.setupAutoClose(),this.setupProgressUpdates()),this.playSound&&this._playSound()}async animateIn(){let e=this.getBoundingClientRect(),t=e.left+e.width/2,n=e.top+e.height/2,r=function(e,t,n=`up`,r=.3){let i=(e.x+t.x)/2,a=(e.y+t.y)/2,o=Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2),s=Math.min(o*r,150);return{x:i,y:n===`up`?a-s:a+s}}(this.startPosition,{x:t,y:n},`up`,.3);await this.animate([{transform:`translate(${this.startPosition.x-t}px, ${this.startPosition.y-n}px) scale(0.1)`,opacity:0},{transform:`translate(${r.x-t}px, ${r.y-n}px) scale(0.6)`,opacity:.9,offset:.5},{transform:`translate(0, 0) scale(1)`,opacity:1}],{duration:400,easing:`cubic-bezier(0.34, 1.2, 0.64, 1)`,fill:`forwards`}).finished}setupAutoClose(){this.duration<=0||(this.startTime=Date.now(),this.elapsedBeforePause=0,this.paused$.pipe((0,i.switchMap)(e=>{if(e)return this.pausedAt=Date.now(),this.elapsedBeforePause+=this.pausedAt-this.startTime,r.NEVER;{this.startTime=Date.now();let e=this.duration-this.elapsedBeforePause;return e<=0?(this.close(),r.NEVER):(0,r.timer)(e)}}),(0,i.takeUntil)(this.disconnecting)).subscribe(()=>this.close()))}setupProgressUpdates(){this.duration<=0||(0,r.interval)(16).pipe((0,i.switchMap)(()=>this.paused$.pipe((0,i.map)(e=>{if(e)return this._progress;let t=this.elapsedBeforePause+(Date.now()-this.startTime);return Math.max(0,this.duration-t)/this.duration*100}))),(0,i.distinctUntilChanged)(),(0,i.tap)(e=>{this._progress=e}),(0,i.takeUntil)(this.disconnecting)).subscribe()}_playSound(){this.dispatchEvent(new CustomEvent(`playsound`,{detail:{type:this.type},bubbles:!0,composed:!0}))}_handleMouseEnter(){this._hovered=!0,this.paused$.next(!0)}_handleMouseLeave(){this._hovered=!1,this.paused$.next(!1)}async close(){this._closing||(this._closing=!0,this._visible=!1,await this.animate([{transform:`translate(0, 0) scale(1)`,opacity:1},{transform:`translate(0, -20px) scale(0.8)`,opacity:0}],{duration:200,easing:`cubic-bezier(0.4, 0, 1, 1)`,fill:`forwards`}).finished,this.dispatchEvent(new CustomEvent(`close`,{detail:{id:this.id},bubbles:!0,composed:!0})))}_getEmoji(){switch(this.type){case`success`:return`✅`;case`warning`:return`⚠️`;case`error`:return`❌`;default:return`💡`}}render(){return!this._visible&&this._closing?o.html``:o.html`
|
|
2
2
|
<div
|
|
3
3
|
class="notification ${this.type} ${this._closing?`closing`:``} ${this._hovered?`hovered`:``}"
|
|
4
4
|
role="alert"
|