@salla.sa/twilight-theme-engine 1.0.81 → 1.0.83
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/dist/{AddToCartForm-TX3QMS4O.js → AddToCartForm-37APRET4.js} +3 -3
- package/dist/{AddToCartForm-TX3QMS4O.js.map → AddToCartForm-37APRET4.js.map} +1 -1
- package/dist/{BlogAuthorPage-BNMZL5DW.js → BlogAuthorPage-562MX2LO.js} +23 -19
- package/dist/BlogAuthorPage-562MX2LO.js.map +1 -0
- package/dist/{BlogCategoryPage-4M52MRXH.js → BlogCategoryPage-Q5H5OKLS.js} +23 -19
- package/dist/BlogCategoryPage-Q5H5OKLS.js.map +1 -0
- package/dist/{BlogPage-5HWA2DQF.js → BlogPage-DTNPNV2B.js} +21 -17
- package/dist/BlogPage-DTNPNV2B.js.map +1 -0
- package/dist/{BlogSinglePage-AAXWX5P2.js → BlogSinglePage-T7P5I4C3.js} +21 -17
- package/dist/BlogSinglePage-T7P5I4C3.js.map +1 -0
- package/dist/{BlogTagPage-4N2BZSFE.js → BlogTagPage-K5IPJ7V2.js} +23 -19
- package/dist/BlogTagPage-K5IPJ7V2.js.map +1 -0
- package/dist/{BrandsPage-HMWHRDKS.js → BrandsPage-TSLY4GNB.js} +22 -18
- package/dist/BrandsPage-TSLY4GNB.js.map +1 -0
- package/dist/{Breadcrumb-FASP32PM.js → Breadcrumb-2WAXVVO4.js} +21 -17
- package/dist/Breadcrumb-2WAXVVO4.js.map +1 -0
- package/dist/{CartItem-WQ4L2YDN.js → CartItem-QST2C243.js} +21 -17
- package/dist/CartItem-QST2C243.js.map +1 -0
- package/dist/{CartSummary-P26475WT.js → CartSummary-IFZI2NFE.js} +21 -17
- package/dist/CartSummary-IFZI2NFE.js.map +1 -0
- package/dist/{Copyright-GCH5MMDB.js → Copyright-J7OL7EZS.js} +3 -3
- package/dist/{Copyright-GCH5MMDB.js.map → Copyright-J7OL7EZS.js.map} +1 -1
- package/dist/{CustomerLayout-LXQDPPTU.js → CustomerLayout-HADICNS2.js} +21 -17
- package/dist/CustomerLayout-HADICNS2.js.map +1 -0
- package/dist/{Footer-FBU4RZ6X.js → Footer-TTGSSHPD.js} +21 -17
- package/dist/{Footer-FBU4RZ6X.js.map → Footer-TTGSSHPD.js.map} +1 -1
- package/dist/GoogleTag-Y6N4BOCW.js +4 -0
- package/dist/{GoogleTag-HBGKI3VH.js.map → GoogleTag-Y6N4BOCW.js.map} +1 -1
- package/dist/{Header-YDW2ED77.js → Header-W232GUVN.js} +7 -7
- package/dist/{Header-YDW2ED77.js.map → Header-W232GUVN.js.map} +1 -1
- package/dist/{LoyaltyPage-SDWFURDQ.js → LoyaltyPage-GV37IVB5.js} +21 -17
- package/dist/LoyaltyPage-GV37IVB5.js.map +1 -0
- package/dist/{LoyaltyPointsPage-3Y2VZSDJ.js → LoyaltyPointsPage-XWPUI5XG.js} +3 -3
- package/dist/{LoyaltyPointsPage-3Y2VZSDJ.js.map → LoyaltyPointsPage-XWPUI5XG.js.map} +1 -1
- package/dist/{MainMenu-QSSHJ7PU.js → MainMenu-3D6TQ5MX.js} +6 -6
- package/dist/{MainMenu-QSSHJ7PU.js.map → MainMenu-3D6TQ5MX.js.map} +1 -1
- package/dist/{StoreClosedNotification-DVYG4MOV.js → MasterLayout-X3SRGN7P.js} +21 -18
- package/dist/{MasterLayout-GPD6K47U.js.map → MasterLayout-X3SRGN7P.js.map} +1 -1
- package/dist/{MobileMenu-UNFCBLYN.js → MobileMenu-GZNQH3NF.js} +22 -18
- package/dist/MobileMenu-GZNQH3NF.js.map +1 -0
- package/dist/{NotificationsPage-TRD5V4ZT.js → NotificationsPage-ZWX7URQ6.js} +21 -17
- package/dist/NotificationsPage-ZWX7URQ6.js.map +1 -0
- package/dist/{OrderSinglePage-ITTG63VH.js → OrderSinglePage-HADHBSZF.js} +22 -18
- package/dist/OrderSinglePage-HADHBSZF.js.map +1 -0
- package/dist/{OrdersPage-ETVDAHD4.js → OrdersPage-JMR5PSPX.js} +21 -17
- package/dist/OrdersPage-JMR5PSPX.js.map +1 -0
- package/dist/{PageSingle-ZBYRUSLH.js → PageSingle-FYN6UCT5.js} +5 -5
- package/dist/{PageSingle-ZBYRUSLH.js.map → PageSingle-FYN6UCT5.js.map} +1 -1
- package/dist/{ProductDetails-M5NRFG3I.js → ProductDetails-QONKMMI6.js} +6 -6
- package/dist/{ProductDetails-M5NRFG3I.js.map → ProductDetails-QONKMMI6.js.map} +1 -1
- package/dist/{ProfilePage-ICYN6WXG.js → ProfilePage-DBKJZEII.js} +21 -17
- package/dist/ProfilePage-DBKJZEII.js.map +1 -0
- package/dist/{ReviewsPage-G3PABBMM.js → ReviewsPage-6Y57FGOZ.js} +3 -3
- package/dist/{ReviewsPage-G3PABBMM.js.map → ReviewsPage-6Y57FGOZ.js.map} +1 -1
- package/dist/{SeoCartWidget-5R73R2CW.js → SeoCartWidget-YSCC2V65.js} +21 -17
- package/dist/SeoCartWidget-YSCC2V65.js.map +1 -0
- package/dist/{SettingsPage-VG3I3KLW.js → SettingsPage-EJG4JMOK.js} +21 -17
- package/dist/SettingsPage-EJG4JMOK.js.map +1 -0
- package/dist/{MasterLayout-GPD6K47U.js → StoreClosedNotification-4F3KJTA4.js} +22 -17
- package/dist/{StoreClosedNotification-DVYG4MOV.js.map → StoreClosedNotification-4F3KJTA4.js.map} +1 -1
- package/dist/{TestimonialsPage-6RYVIZP5.js → TestimonialsPage-RAMT7OZ4.js} +5 -5
- package/dist/{TestimonialsPage-6RYVIZP5.js.map → TestimonialsPage-RAMT7OZ4.js.map} +1 -1
- package/dist/{ThankYouPage-TZ4YMMZE.js → ThankYouPage-IODVASK5.js} +21 -17
- package/dist/ThankYouPage-IODVASK5.js.map +1 -0
- package/dist/{WalletPage-3DGNYRZ3.js → WalletPage-Q2M55EB2.js} +22 -18
- package/dist/WalletPage-Q2M55EB2.js.map +1 -0
- package/dist/{WishlistPage-HWLHAOJO.js → WishlistPage-YUPZ5JDV.js} +23 -19
- package/dist/WishlistPage-YUPZ5JDV.js.map +1 -0
- package/dist/api/apps.js +3 -3
- package/dist/api/blog.js +4 -4
- package/dist/api/brands.js +4 -4
- package/dist/api/cart.js +4 -4
- package/dist/api/category.js +4 -4
- package/dist/api/client.js +2 -2
- package/dist/api/home.js +3 -3
- package/dist/api/loyalty.js +4 -4
- package/dist/api/menu.js +3 -3
- package/dist/api/notification.js +3 -3
- package/dist/api/order.js +4 -4
- package/dist/api/page.js +4 -4
- package/dist/api/product.js +4 -4
- package/dist/api/profile.js +2 -2
- package/dist/api/store.js +3 -3
- package/dist/api/translations.js +3 -3
- package/dist/api/user.js +3 -3
- package/dist/api/wallet.js +3 -3
- package/dist/api/wishlist.js +5 -5
- package/dist/chunk-22SH7OVF.js +298 -0
- package/dist/chunk-22SH7OVF.js.map +1 -0
- package/dist/{chunk-J2VJGXIX.js → chunk-27Z442XF.js} +5 -5
- package/dist/{chunk-J2VJGXIX.js.map → chunk-27Z442XF.js.map} +1 -1
- package/dist/{chunk-RPPTJY25.js → chunk-37EW45F4.js} +8 -8
- package/dist/{chunk-RPPTJY25.js.map → chunk-37EW45F4.js.map} +1 -1
- package/dist/{chunk-BE3JDKE2.js → chunk-3LXB4VFK.js} +5 -37
- package/dist/chunk-3LXB4VFK.js.map +1 -0
- package/dist/{chunk-UJNHLV37.js → chunk-3NLO5SK3.js} +3 -3
- package/dist/{chunk-UJNHLV37.js.map → chunk-3NLO5SK3.js.map} +1 -1
- package/dist/{chunk-7FDT2IFI.js → chunk-46NBPXAI.js} +3 -3
- package/dist/{chunk-7FDT2IFI.js.map → chunk-46NBPXAI.js.map} +1 -1
- package/dist/chunk-4ENPEHYZ.js +64 -0
- package/dist/chunk-4ENPEHYZ.js.map +1 -0
- package/dist/{chunk-LLQE4JAW.js → chunk-4WAUITU2.js} +3 -3
- package/dist/{chunk-LLQE4JAW.js.map → chunk-4WAUITU2.js.map} +1 -1
- package/dist/{chunk-VKYXOAKU.js → chunk-5FGZZON5.js} +4 -4
- package/dist/{chunk-VKYXOAKU.js.map → chunk-5FGZZON5.js.map} +1 -1
- package/dist/{chunk-LCDSHSP7.js → chunk-5G7NYNX6.js} +3 -3
- package/dist/{chunk-LCDSHSP7.js.map → chunk-5G7NYNX6.js.map} +1 -1
- package/dist/chunk-5RAADM2K.js +14 -0
- package/dist/{chunk-3LTQKLKJ.js.map → chunk-5RAADM2K.js.map} +1 -1
- package/dist/{chunk-EUWKQJNI.js → chunk-5SD7BUSA.js} +4 -4
- package/dist/{chunk-EUWKQJNI.js.map → chunk-5SD7BUSA.js.map} +1 -1
- package/dist/{chunk-3UMHUKMJ.js → chunk-66K5P5ZX.js} +3 -3
- package/dist/{chunk-3UMHUKMJ.js.map → chunk-66K5P5ZX.js.map} +1 -1
- package/dist/{chunk-7HWX2PEO.js → chunk-6DMNJPLW.js} +3 -3
- package/dist/{chunk-7HWX2PEO.js.map → chunk-6DMNJPLW.js.map} +1 -1
- package/dist/{chunk-F4FCETQT.js → chunk-6N33IKYP.js} +3 -3
- package/dist/{chunk-F4FCETQT.js.map → chunk-6N33IKYP.js.map} +1 -1
- package/dist/{chunk-3GZ5OOAK.js → chunk-6OOTDFC7.js} +3 -3
- package/dist/{chunk-3GZ5OOAK.js.map → chunk-6OOTDFC7.js.map} +1 -1
- package/dist/{chunk-64L2L76T.js → chunk-6QMYSKUE.js} +6 -6
- package/dist/{chunk-64L2L76T.js.map → chunk-6QMYSKUE.js.map} +1 -1
- package/dist/{chunk-VPPSRRGK.js → chunk-6ZMNTJM3.js} +4 -4
- package/dist/{chunk-VPPSRRGK.js.map → chunk-6ZMNTJM3.js.map} +1 -1
- package/dist/{chunk-WV3B2FOG.js → chunk-7X4XGKXO.js} +4 -4
- package/dist/{chunk-WV3B2FOG.js.map → chunk-7X4XGKXO.js.map} +1 -1
- package/dist/{chunk-NJWKVTQD.js → chunk-B2G7S4UR.js} +4 -4
- package/dist/{chunk-NJWKVTQD.js.map → chunk-B2G7S4UR.js.map} +1 -1
- package/dist/{chunk-HZYFU3PZ.js → chunk-BNI6SKFL.js} +4 -4
- package/dist/{chunk-HZYFU3PZ.js.map → chunk-BNI6SKFL.js.map} +1 -1
- package/dist/{chunk-XON5AXAP.js → chunk-ENJ3CM5M.js} +3 -3
- package/dist/{chunk-XON5AXAP.js.map → chunk-ENJ3CM5M.js.map} +1 -1
- package/dist/{chunk-LL3X2N7L.js → chunk-FFCYACTA.js} +4 -4
- package/dist/{chunk-LL3X2N7L.js.map → chunk-FFCYACTA.js.map} +1 -1
- package/dist/{chunk-W3LADQOR.js → chunk-FZYR4BA2.js} +3 -3
- package/dist/{chunk-W3LADQOR.js.map → chunk-FZYR4BA2.js.map} +1 -1
- package/dist/{chunk-MHVR2OUR.js → chunk-GAXVDCMA.js} +4 -4
- package/dist/{chunk-MHVR2OUR.js.map → chunk-GAXVDCMA.js.map} +1 -1
- package/dist/{chunk-VPNKJFT7.js → chunk-HIZ2SEJE.js} +3 -3
- package/dist/{chunk-VPNKJFT7.js.map → chunk-HIZ2SEJE.js.map} +1 -1
- package/dist/{chunk-SLXGP6KF.js → chunk-HQAFPDJK.js} +3 -3
- package/dist/{chunk-SLXGP6KF.js.map → chunk-HQAFPDJK.js.map} +1 -1
- package/dist/{chunk-4A5IAMNL.js → chunk-HSWRYXC7.js} +2 -2
- package/dist/{chunk-4A5IAMNL.js.map → chunk-HSWRYXC7.js.map} +1 -1
- package/dist/{chunk-6BITDRR2.js → chunk-IBDMGZ23.js} +100 -44
- package/dist/chunk-IBDMGZ23.js.map +1 -0
- package/dist/{chunk-RQ5EAUPQ.js → chunk-ID5SIAGH.js} +5 -5
- package/dist/{chunk-RQ5EAUPQ.js.map → chunk-ID5SIAGH.js.map} +1 -1
- package/dist/{chunk-LDVEJNPH.js → chunk-LJUFGTG2.js} +7 -7
- package/dist/{chunk-LDVEJNPH.js.map → chunk-LJUFGTG2.js.map} +1 -1
- package/dist/{chunk-2APQP7KK.js → chunk-MKVCFBVF.js} +4 -4
- package/dist/{chunk-2APQP7KK.js.map → chunk-MKVCFBVF.js.map} +1 -1
- package/dist/{chunk-MYJL5MGW.js → chunk-OH2L4U2C.js} +3 -3
- package/dist/{chunk-MYJL5MGW.js.map → chunk-OH2L4U2C.js.map} +1 -1
- package/dist/{chunk-KEZMQRKI.js → chunk-OHXODJAA.js} +4 -4
- package/dist/{chunk-KEZMQRKI.js.map → chunk-OHXODJAA.js.map} +1 -1
- package/dist/{chunk-BP6LUZXJ.js → chunk-QGOPTVV5.js} +3 -3
- package/dist/{chunk-BP6LUZXJ.js.map → chunk-QGOPTVV5.js.map} +1 -1
- package/dist/{chunk-SAZEDKBS.js → chunk-R42T7UL7.js} +4 -4
- package/dist/{chunk-SAZEDKBS.js.map → chunk-R42T7UL7.js.map} +1 -1
- package/dist/chunk-RV54D2D7.js +38 -0
- package/dist/chunk-RV54D2D7.js.map +1 -0
- package/dist/{chunk-MOANE2YM.js → chunk-SAGXF3MU.js} +3 -3
- package/dist/{chunk-MOANE2YM.js.map → chunk-SAGXF3MU.js.map} +1 -1
- package/dist/{chunk-FSCIJ55A.js → chunk-TWJXVT6S.js} +4 -4
- package/dist/{chunk-FSCIJ55A.js.map → chunk-TWJXVT6S.js.map} +1 -1
- package/dist/{chunk-YJAMQRFS.js → chunk-UGLZPGPF.js} +5 -5
- package/dist/{chunk-YJAMQRFS.js.map → chunk-UGLZPGPF.js.map} +1 -1
- package/dist/{chunk-IEQQVBQ3.js → chunk-UHAI6CIG.js} +7 -7
- package/dist/{chunk-IEQQVBQ3.js.map → chunk-UHAI6CIG.js.map} +1 -1
- package/dist/{chunk-ODF4CAF4.js → chunk-WSBVUIRW.js} +4 -4
- package/dist/{chunk-ODF4CAF4.js.map → chunk-WSBVUIRW.js.map} +1 -1
- package/dist/{chunk-PKNHFIY4.js → chunk-YGJMUJVR.js} +4 -4
- package/dist/{chunk-PKNHFIY4.js.map → chunk-YGJMUJVR.js.map} +1 -1
- package/dist/{chunk-2KH7ZBXA.js → chunk-YNIALL22.js} +15 -309
- package/dist/chunk-YNIALL22.js.map +1 -0
- package/dist/{chunk-JVTAP4JW.js → chunk-ZUAR7FWG.js} +7 -7
- package/dist/{chunk-JVTAP4JW.js.map → chunk-ZUAR7FWG.js.map} +1 -1
- package/dist/{chunk-F2YLRVPH.js → chunk-ZVZGLEZ6.js} +3 -3
- package/dist/{chunk-F2YLRVPH.js.map → chunk-ZVZGLEZ6.js.map} +1 -1
- package/dist/components/cart/index.js +1 -1
- package/dist/components/common/index.js +1 -1
- package/dist/components/drawer/index.js +19 -15
- package/dist/components/home/index.js +23 -19
- package/dist/components/layout/index.js +1 -1
- package/dist/components/product/index.js +20 -16
- package/dist/components/snippets/SallaSdkScripts.d.ts +6 -0
- package/dist/components/snippets/SallaSdkScripts.d.ts.map +1 -0
- package/dist/components/store/index.js +21 -17
- package/dist/components/store/index.js.map +1 -1
- package/dist/components/toast/index.js +3 -3
- package/dist/components/tracking/GoogleTag.d.ts +3 -7
- package/dist/components/tracking/GoogleTag.d.ts.map +1 -1
- package/dist/components/tracking/index.js +2 -2
- package/dist/document-class-HEO4N5Z5.js +26 -0
- package/dist/{document-class-DEQYGHKC.js.map → document-class-HEO4N5Z5.js.map} +1 -1
- package/dist/hooks/index.js +19 -15
- package/dist/hooks/useComments.js +2 -2
- package/dist/hooks/useGtm.js +19 -15
- package/dist/hooks/useMoney.js +19 -15
- package/dist/hooks/useProduct.js +2 -2
- package/dist/hooks/useStore.js +19 -15
- package/dist/hooks/useUser.js +4 -4
- package/dist/hooks/useWishlist.js +2 -2
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/dist/native-app/index.js +2 -2
- package/dist/{navigation-KMDVLHXU.js → navigation-BRWTNATO.js} +7 -7
- package/dist/{navigation-KMDVLHXU.js.map → navigation-BRWTNATO.js.map} +1 -1
- package/dist/{navigation-WEV6XJJT.js → navigation-ZEY4KF4D.js} +5 -5
- package/dist/{navigation-WEV6XJJT.js.map → navigation-ZEY4KF4D.js.map} +1 -1
- package/dist/{not-found-YAVF7BEM.js → not-found-NHSV2Q5D.js} +22 -18
- package/dist/not-found-NHSV2Q5D.js.map +1 -0
- package/dist/providers/TwilightProvider.d.ts.map +1 -1
- package/dist/providers/index.js +19 -15
- package/dist/providers/twilight-init.d.ts.map +1 -1
- package/dist/providers/twilight-theme.d.ts +5 -1
- package/dist/providers/twilight-theme.d.ts.map +1 -1
- package/dist/routes/account/orders.js +5 -5
- package/dist/routes/account.js +14 -14
- package/dist/routes/blog.js +9 -9
- package/dist/routes/brands.js +5 -5
- package/dist/routes/cart.js +27 -24
- package/dist/routes/cart.js.map +1 -1
- package/dist/routes/home.js +24 -21
- package/dist/routes/index.js +4 -4
- package/dist/routes/loyalty.js +6 -6
- package/dist/routes/page.js +5 -5
- package/dist/routes/product-listing.js +25 -22
- package/dist/routes/product-listing.js.map +1 -1
- package/dist/routes/product.js +23 -20
- package/dist/routes/product.js.map +1 -1
- package/dist/routes/root/head.d.ts +1 -0
- package/dist/routes/root/head.d.ts.map +1 -1
- package/dist/routes/seo-redirects.js +4 -4
- package/dist/routes/testimonials.js +2 -2
- package/dist/routes/thank-you.js +5 -5
- package/dist/skeleton.js +24 -21
- package/dist/tanstack.js +16 -15
- package/dist/tanstack.js.map +1 -1
- package/dist/utils/apply-theme.d.ts +1 -0
- package/dist/utils/apply-theme.d.ts.map +1 -1
- package/dist/utils/index.js +6 -6
- package/dist/vite/index.js +2 -1
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/BlogAuthorPage-BNMZL5DW.js.map +0 -1
- package/dist/BlogCategoryPage-4M52MRXH.js.map +0 -1
- package/dist/BlogPage-5HWA2DQF.js.map +0 -1
- package/dist/BlogSinglePage-AAXWX5P2.js.map +0 -1
- package/dist/BlogTagPage-4N2BZSFE.js.map +0 -1
- package/dist/BrandsPage-HMWHRDKS.js.map +0 -1
- package/dist/Breadcrumb-FASP32PM.js.map +0 -1
- package/dist/CartItem-WQ4L2YDN.js.map +0 -1
- package/dist/CartSummary-P26475WT.js.map +0 -1
- package/dist/CustomerLayout-LXQDPPTU.js.map +0 -1
- package/dist/GoogleTag-HBGKI3VH.js +0 -4
- package/dist/LoyaltyPage-SDWFURDQ.js.map +0 -1
- package/dist/MobileMenu-UNFCBLYN.js.map +0 -1
- package/dist/NotificationsPage-TRD5V4ZT.js.map +0 -1
- package/dist/OrderSinglePage-ITTG63VH.js.map +0 -1
- package/dist/OrdersPage-ETVDAHD4.js.map +0 -1
- package/dist/ProfilePage-ICYN6WXG.js.map +0 -1
- package/dist/SeoCartWidget-5R73R2CW.js.map +0 -1
- package/dist/SettingsPage-VG3I3KLW.js.map +0 -1
- package/dist/ThankYouPage-TZ4YMMZE.js.map +0 -1
- package/dist/WalletPage-3DGNYRZ3.js.map +0 -1
- package/dist/WishlistPage-HWLHAOJO.js.map +0 -1
- package/dist/chunk-2KH7ZBXA.js.map +0 -1
- package/dist/chunk-3LTQKLKJ.js +0 -14
- package/dist/chunk-6BITDRR2.js.map +0 -1
- package/dist/chunk-BE3JDKE2.js.map +0 -1
- package/dist/chunk-DNCQIT6S.js +0 -52
- package/dist/chunk-DNCQIT6S.js.map +0 -1
- package/dist/document-class-DEQYGHKC.js +0 -24
- package/dist/not-found-YAVF7BEM.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-5FGZZON5.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useDate } from '../../hooks';\nimport { Image, Link } from '../../components/common';\nimport type { BlogCategory, ArticleSummary } from './types';\n\nexport function BlogCategoriesSidebar({ categories }: { categories: BlogCategory[] }) {\n const { t } = useTranslation();\n\n if (!categories.length) return null;\n\n return (\n <nav aria-label=\"Sidebar\" className=\"hidden lg:block lg:sticky shrink-0 top-24 col-span-2\">\n <h2 className=\"font-bold mb-3\">{t('pages.blog_categories.categories')}</h2>\n <ul>\n {categories.map((category) => (\n <li key={category.id} className={category.is_current ? 'text-primary' : ''}>\n <Link className=\"py-3 block text-sm hover:text-primary\" to={category.url}>\n {category.name}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function BlogArticleCard({\n article,\n showAuthor = false,\n}: {\n article: ArticleSummary;\n showAuthor?: boolean;\n}) {\n const { format: formatDate } = useDate();\n\n return (\n <div className=\"list-block post-entry relative h-full transition-shadow duration-500 bg-white hover:shadow-default rounded-lg justify-around overflow-hidden flex flex-col\">\n <Link\n to={article.url}\n className=\"post-entry__image relative overflow-hidden hover:opacity-90 w-full h-56 bg-border-color flex items-center justify-center\"\n >\n {article.image && (\n <Image\n className=\"h-full w-full object-cover\"\n src={article.image}\n alt={article.name}\n aspectRatio=\"16/9\"\n />\n )}\n </Link>\n <div className=\"flex-1 px-5 pt-5 pb-7\">\n <div className=\"mb-2.5 text-gray-500 rounded-md inline-flex text-sm rtl:space-x-reverse space-x-5\">\n <div className=\"flex items-center\">\n <i className=\"sicon-calendar-date rtl:ml-1 ltr:mr-1\"></i>\n <span>{formatDate(article.created_at)}</span>\n </div>\n {showAuthor && article.author && (\n <Link to={article.author.url} className=\"flex items-center hover:text-dark\">\n <i className=\"sicon-user rtl:ml-1 ltr:mr-1\"></i>\n <span>{article.author.name}</span>\n </Link>\n )}\n </div>\n <h3 className=\"post-entry__title text-sm font-bold text-gray-800 leading-6 mb-2.5\">\n <Link to={article.url}>{article.name}</Link>\n </h3>\n <p className=\"text-sm text-gray-500 leading-6 mb-2.5\">{article.description}</p>\n </div>\n </div>\n );\n}\n\nexport function BlogListLayout({\n categories,\n children,\n}: {\n categories: BlogCategory[];\n children: ReactNode;\n}) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-8 gap-8\">\n <BlogCategoriesSidebar categories={categories} />\n <div className=\"main-content lg:col-span-6\">{children}</div>\n </div>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { escapeForInlineScript } from './chunk-
|
|
1
|
+
import { escapeForInlineScript } from './chunk-HSWRYXC7.js';
|
|
2
2
|
|
|
3
3
|
// src/utils/app-scope.ts
|
|
4
4
|
var isBrowser = typeof window !== "undefined";
|
|
@@ -132,5 +132,5 @@ function renderThemeHookSlotsScript(names = getRegisteredThemeHookSlots()) {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export { applyAppScopeMocks, applyThemeHookSlots, installAppScope, registerThemeHookSlots, renderAppScopeInstallScript, renderThemeHookSlotsScript };
|
|
135
|
-
//# sourceMappingURL=chunk-
|
|
136
|
-
//# sourceMappingURL=chunk-
|
|
135
|
+
//# sourceMappingURL=chunk-5G7NYNX6.js.map
|
|
136
|
+
//# sourceMappingURL=chunk-5G7NYNX6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/app-scope.ts","../src/utils/theme-hook-slots.ts"],"names":[],"mappings":"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","file":"chunk-LCDSHSP7.js","sourcesContent":["import type { SallaSDK } from '../types/salla-sdk';\nimport { escapeForInlineScript } from './inline-script';\n\nconst isBrowser = typeof window !== 'undefined';\n\n/** One app's private `app.*` bag, keyed without the `app.` prefix (`app.color` → `color`). */\nexport type AppConfigBag = Record<string, unknown>;\n\n/** One public `app.*` bucket per app, keyed by appScopeId. Everything else is read from the\n * real `salla.config` at runtime. */\nexport interface AppScopeContexts {\n apps: Record<string, AppConfigBag>;\n}\n\n/** Builds the `scopeId → sandboxed SDK` factory over a live bucket bag. */\nexport type AppScopeFactoryBuilder = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n w: any,\n appCtx: Record<string, AppConfigBag>\n) => (scopeId: string) => SallaSDK;\n\n/**\n * The sandbox itself: proxies that resolve `app.*` against the app's own bucket and pass\n * everything else through to the real SDK.\n *\n * MUST stay self-contained (only `Object`/`Proxy` and its two arguments): it is serialized via\n * `.toString()` next to {@link appScopeBootstrap} and handed in as an argument, so anything it\n * closed over at module scope would be undefined in the inline head copy. Split out from the\n * bootstrap purely to keep both halves reviewable.\n */\nexport const createAppScopeFactory: AppScopeFactoryBuilder = (w, appCtx) => {\n const isAppKey = (key: unknown): key is string =>\n typeof key === 'string' && key.indexOf('app.') === 0;\n const bucketKey = (key: string): string => key.slice(4);\n const realSalla = (): Record<string, unknown> => w.salla || w.Salla || {};\n const realConfig = (): Record<string, unknown> =>\n (realSalla().config as Record<string, unknown>) || {};\n const passthrough = (obj: Record<string, unknown>, prop: string | symbol): unknown => {\n const member = obj[prop as string];\n return typeof member === 'function' ? member.bind(obj) : member;\n };\n\n const createAppScope = (scopeId: string): SallaSDK => {\n const bucket = (): AppConfigBag => (appCtx[scopeId] = appCtx[scopeId] || {});\n\n const getConfig = (key: string, fallback?: unknown): unknown => {\n if (isAppKey(key)) {\n const sub = bucketKey(key);\n const b = bucket();\n // `app.*` miss returns the caller default, never the real config — a missing app\n // setting must not resolve to a same-named global.\n return sub in b ? b[sub] : fallback;\n }\n const cfg = realConfig();\n return typeof cfg.get === 'function'\n ? (cfg.get as (k: string, d?: unknown) => unknown)(key, fallback)\n : fallback;\n };\n\n const setConfig = (key: string, value: unknown): unknown => {\n if (isAppKey(key)) {\n bucket()[bucketKey(key)] = value;\n return value;\n }\n const cfg = realConfig();\n return typeof cfg.set === 'function'\n ? (cfg.set as (k: string, v: unknown) => unknown)(key, value)\n : value;\n };\n\n const hasConfig = (key: string): boolean =>\n isAppKey(key) ? bucketKey(key) in bucket() : key in realConfig();\n\n const configProxy = new Proxy({} as Record<string, unknown>, {\n get(_t, prop) {\n if (prop === 'get') return getConfig;\n if (prop === 'set') return setConfig;\n if (prop === 'has') return hasConfig;\n if (isAppKey(prop)) return getConfig(prop);\n return passthrough(realConfig(), prop);\n },\n set(_t, prop, value) {\n setConfig(prop as string, value);\n return true;\n },\n has(_t, prop) {\n return hasConfig(prop as string);\n },\n });\n\n return new Proxy({} as Record<string, unknown>, {\n get(_t, prop) {\n return prop === 'config' ? configProxy : passthrough(realSalla(), prop);\n },\n set(_t, prop, value) {\n // Reassigning `salla.config` wholesale would escape the sandbox; swallow it.\n if (prop === 'config') return true;\n realSalla()[prop as string] = value;\n return true;\n },\n }) as unknown as SallaSDK;\n };\n\n return createAppScope;\n};\n\n/**\n * Installs `window.Salla.appScope`, seeded with `contexts` and sandboxed by `makeFactory`.\n *\n * MUST stay self-contained (only `window`/`Object` and its arguments): it's serialized via\n * `.toString()` and inlined into the SSR head so the factory exists at parse time — before the\n * SDK init/hydration a CDN snippet's `onReady` races, else it throws `Salla.appScope is not a\n * function`. `makeFactory` is passed in rather than imported for exactly that reason. Also\n * called directly by `installAppScope` (tests/fallback).\n *\n * Idempotent: the factory is first-write-wins, while buckets are merged per scope (also\n * first-write-wins) so a later call can seed scopes the first one had no data for. `appCtx` is\n * closure-private (namespacing, not security: buckets are public-only and the boundary is\n * server-side).\n */\nexport function appScopeBootstrap(\n contexts: AppScopeContexts,\n makeFactory: AppScopeFactoryBuilder\n): void {\n if (typeof window === 'undefined') return;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const w = window as any;\n const Salla = (w.Salla = w.Salla || {});\n if (Salla.appScope) {\n // Already installed (normally by the inline head copy). The factory is first-write-wins,\n // but buckets are not: the head may have installed with none of them — the settings\n // endpoint can fail or lag behind the snippets one — so hand them to the existing install.\n if (Salla.__appScopeSeed) Salla.__appScopeSeed(contexts);\n return;\n }\n\n // Live bag + pristine snapshot (for mock overlays). Copy, don't alias: a snippet may\n // `config.set('app.x')` and the payload can be a cached response.\n const appCtx: Record<string, AppConfigBag> = {};\n const base: Record<string, AppConfigBag> = {};\n // Which scopes already got their real bucket, so a later seed can't overwrite one.\n const seeded: Record<string, boolean> = {};\n const seed = (next: AppScopeContexts): void => {\n const bags = (next && next.apps) || {};\n Object.keys(bags).forEach((scopeId) => {\n if (seeded[scopeId]) return;\n seeded[scopeId] = true;\n appCtx[scopeId] = Object.assign({}, appCtx[scopeId] || {}, bags[scopeId] || {});\n base[scopeId] = Object.assign({}, appCtx[scopeId]);\n });\n };\n seed(contexts);\n\n const createAppScope = makeFactory(w, appCtx);\n Salla.appScope = (scopeId: string): SallaSDK => createAppScope(scopeId);\n\n // Fill in buckets for scopes not seeded yet (first-write-wins per scope). Lets the head\n // install the factory unconditionally — at parse time, before any snippet's onReady — and\n // still pick up buckets that only the client managed to fetch.\n Salla.__appScopeSeed = (next: AppScopeContexts): void => seed(next);\n\n // Overlay preview mocks onto an app's pristine baseline, so fields the partner did not mock\n // keep their real values. Returns false for an unknown scope or before install.\n Salla.__appScopeMock = (scopeId: string, mocks: AppConfigBag): boolean => {\n if (!(scopeId in base)) return false;\n appCtx[scopeId] = Object.assign({}, base[scopeId], mocks);\n return true;\n };\n}\n\n/** Overlay preview mocks onto one app's bucket (over its pristine values). Delegates to the\n * bootstrap's `__appScopeMock`, so it works for both install paths. False if unknown/uninstalled. */\nexport function applyAppScopeMocks(appScopeId: string, mocks: AppConfigBag): boolean {\n if (!isBrowser) return false;\n const mock = (window.Salla as unknown as { __appScopeMock?: MockApplier } | undefined)\n ?.__appScopeMock;\n return mock?.(appScopeId, mocks) ?? false;\n}\n\ntype MockApplier = (appScopeId: string, mocks: AppConfigBag) => boolean;\n\n/** Serialize the installer into an inline `<script>` body seeded with `contexts` — both halves\n * via `.toString()`, hence their self-contained requirement. See `rootHead`. */\nexport function renderAppScopeInstallScript(contexts: AppScopeContexts): string {\n // Bucket values are partner-set, so escape the JSON seed against a `</script>` breakout.\n // The function sources have no `<`, so they need no escaping.\n const json = escapeForInlineScript(JSON.stringify(contexts));\n return `(${appScopeBootstrap.toString()})(${json},${createAppScopeFactory.toString()});`;\n}\n\n/** Install `Salla.appScope` on the client, or seed buckets into the inline SSR head copy that\n * already installed it. No-op on the server. Fallback for unseeded loads + the unit-test entry\n * point. */\nexport function installAppScope(contexts: AppScopeContexts): void {\n if (!isBrowser) return;\n appScopeBootstrap(contexts, createAppScopeFactory);\n}\n","import { escapeForInlineScript } from './inline-script';\n\nconst registered = new Set<string>();\n\nlet retryArmed = false;\n\n/**\n * Declare hook slots the theme renders itself so apps may mount into them.\n *\n * The SDK rejects `mount()` for any name absent from its `_themeSlots` whitelist, so a theme\n * rendering its own `<salla-hook>` must register the name. Call at module scope; the engine\n * applies the names via {@link applyThemeHookSlots}.\n */\nexport function registerThemeHookSlots(...names: string[]): void {\n for (const name of names) registered.add(name);\n}\n\n/** Push the registered names in. Returns false if the SDK hasn't exposed the list yet. */\nfunction pushSlots(): boolean {\n const slots = window.salla?.hooks?._themeSlots;\n if (!Array.isArray(slots)) return false;\n for (const name of registered) if (!slots.includes(name)) slots.push(name);\n return true;\n}\n\n/**\n * Push every registered slot name into the SDK whitelist. Idempotent. Engine-only.\n *\n * The SDK's hooks module may attach after this runs, so a first no-op falls back to a\n * one-shot retry on `twilight::initiated` — still before apps mount from their own onReady.\n *\n * This is only the late backstop: the whitelist is primarily seeded at parse time by the\n * inline head script from {@link renderThemeHookSlotsScript}, because an app's snippet\n * registers its `onReady` callback before React ever hydrates.\n */\nexport function applyThemeHookSlots(): void {\n if (typeof window === 'undefined' || registered.size === 0) return;\n if (pushSlots() || retryArmed) return;\n\n retryArmed = true;\n window.addEventListener('twilight::initiated', () => void pushSlots(), { once: true });\n}\n\n/** The slot names registered so far. Read by `rootHead` when rendering the inline script. */\nexport function getRegisteredThemeHookSlots(): string[] {\n return [...registered];\n}\n\n/**\n * Serialize the whitelist push into an inline head `<script>` body, so the slots are\n * registered at parse time.\n *\n * Ordering is the whole point: CDN snippets are parser-inserted `<script defer>` tags in the\n * body, so an app's `Salla.onReady` callback is registered long before React hydrates and runs\n * {@link applyThemeHookSlots}. Whichever `twilight::initiated` listener was added first runs\n * first, so the push must be armed from the head — otherwise the SDK rejects the app's\n * `hooks.mount()` with \"Hook <name> is not allowed\" and the app never renders.\n *\n * Returns null when the theme registered no slots. Kept self-contained (only `window`) since\n * it ships as raw source, not as a bundled module.\n */\nexport function renderThemeHookSlotsScript(names: string[] = getRegisteredThemeHookSlots()) {\n if (!names.length) return null;\n const json = escapeForInlineScript(JSON.stringify(names));\n return (\n `(function(names){` +\n `var w=window;` +\n `function push(){` +\n `var h=w.salla&&w.salla.hooks;var slots=h&&h._themeSlots;` +\n `if(!Array.isArray(slots))return false;` +\n `for(var i=0;i<names.length;i++)if(slots.indexOf(names[i])<0)slots.push(names[i]);` +\n `return true}` +\n `if(push())return;` +\n `w.addEventListener('twilight::initiated',function(){push()},{once:true})` +\n `})(${json});`\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/app-scope.ts","../src/utils/theme-hook-slots.ts"],"names":[],"mappings":"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","file":"chunk-5G7NYNX6.js","sourcesContent":["import type { SallaSDK } from '../types/salla-sdk';\nimport { escapeForInlineScript } from './inline-script';\n\nconst isBrowser = typeof window !== 'undefined';\n\n/** One app's private `app.*` bag, keyed without the `app.` prefix (`app.color` → `color`). */\nexport type AppConfigBag = Record<string, unknown>;\n\n/** One public `app.*` bucket per app, keyed by appScopeId. Everything else is read from the\n * real `salla.config` at runtime. */\nexport interface AppScopeContexts {\n apps: Record<string, AppConfigBag>;\n}\n\n/** Builds the `scopeId → sandboxed SDK` factory over a live bucket bag. */\nexport type AppScopeFactoryBuilder = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n w: any,\n appCtx: Record<string, AppConfigBag>\n) => (scopeId: string) => SallaSDK;\n\n/**\n * The sandbox itself: proxies that resolve `app.*` against the app's own bucket and pass\n * everything else through to the real SDK.\n *\n * MUST stay self-contained (only `Object`/`Proxy` and its two arguments): it is serialized via\n * `.toString()` next to {@link appScopeBootstrap} and handed in as an argument, so anything it\n * closed over at module scope would be undefined in the inline head copy. Split out from the\n * bootstrap purely to keep both halves reviewable.\n */\nexport const createAppScopeFactory: AppScopeFactoryBuilder = (w, appCtx) => {\n const isAppKey = (key: unknown): key is string =>\n typeof key === 'string' && key.indexOf('app.') === 0;\n const bucketKey = (key: string): string => key.slice(4);\n const realSalla = (): Record<string, unknown> => w.salla || w.Salla || {};\n const realConfig = (): Record<string, unknown> =>\n (realSalla().config as Record<string, unknown>) || {};\n const passthrough = (obj: Record<string, unknown>, prop: string | symbol): unknown => {\n const member = obj[prop as string];\n return typeof member === 'function' ? member.bind(obj) : member;\n };\n\n const createAppScope = (scopeId: string): SallaSDK => {\n const bucket = (): AppConfigBag => (appCtx[scopeId] = appCtx[scopeId] || {});\n\n const getConfig = (key: string, fallback?: unknown): unknown => {\n if (isAppKey(key)) {\n const sub = bucketKey(key);\n const b = bucket();\n // `app.*` miss returns the caller default, never the real config — a missing app\n // setting must not resolve to a same-named global.\n return sub in b ? b[sub] : fallback;\n }\n const cfg = realConfig();\n return typeof cfg.get === 'function'\n ? (cfg.get as (k: string, d?: unknown) => unknown)(key, fallback)\n : fallback;\n };\n\n const setConfig = (key: string, value: unknown): unknown => {\n if (isAppKey(key)) {\n bucket()[bucketKey(key)] = value;\n return value;\n }\n const cfg = realConfig();\n return typeof cfg.set === 'function'\n ? (cfg.set as (k: string, v: unknown) => unknown)(key, value)\n : value;\n };\n\n const hasConfig = (key: string): boolean =>\n isAppKey(key) ? bucketKey(key) in bucket() : key in realConfig();\n\n const configProxy = new Proxy({} as Record<string, unknown>, {\n get(_t, prop) {\n if (prop === 'get') return getConfig;\n if (prop === 'set') return setConfig;\n if (prop === 'has') return hasConfig;\n if (isAppKey(prop)) return getConfig(prop);\n return passthrough(realConfig(), prop);\n },\n set(_t, prop, value) {\n setConfig(prop as string, value);\n return true;\n },\n has(_t, prop) {\n return hasConfig(prop as string);\n },\n });\n\n return new Proxy({} as Record<string, unknown>, {\n get(_t, prop) {\n return prop === 'config' ? configProxy : passthrough(realSalla(), prop);\n },\n set(_t, prop, value) {\n // Reassigning `salla.config` wholesale would escape the sandbox; swallow it.\n if (prop === 'config') return true;\n realSalla()[prop as string] = value;\n return true;\n },\n }) as unknown as SallaSDK;\n };\n\n return createAppScope;\n};\n\n/**\n * Installs `window.Salla.appScope`, seeded with `contexts` and sandboxed by `makeFactory`.\n *\n * MUST stay self-contained (only `window`/`Object` and its arguments): it's serialized via\n * `.toString()` and inlined into the SSR head so the factory exists at parse time — before the\n * SDK init/hydration a CDN snippet's `onReady` races, else it throws `Salla.appScope is not a\n * function`. `makeFactory` is passed in rather than imported for exactly that reason. Also\n * called directly by `installAppScope` (tests/fallback).\n *\n * Idempotent: the factory is first-write-wins, while buckets are merged per scope (also\n * first-write-wins) so a later call can seed scopes the first one had no data for. `appCtx` is\n * closure-private (namespacing, not security: buckets are public-only and the boundary is\n * server-side).\n */\nexport function appScopeBootstrap(\n contexts: AppScopeContexts,\n makeFactory: AppScopeFactoryBuilder\n): void {\n if (typeof window === 'undefined') return;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const w = window as any;\n const Salla = (w.Salla = w.Salla || {});\n if (Salla.appScope) {\n // Already installed (normally by the inline head copy). The factory is first-write-wins,\n // but buckets are not: the head may have installed with none of them — the settings\n // endpoint can fail or lag behind the snippets one — so hand them to the existing install.\n if (Salla.__appScopeSeed) Salla.__appScopeSeed(contexts);\n return;\n }\n\n // Live bag + pristine snapshot (for mock overlays). Copy, don't alias: a snippet may\n // `config.set('app.x')` and the payload can be a cached response.\n const appCtx: Record<string, AppConfigBag> = {};\n const base: Record<string, AppConfigBag> = {};\n // Which scopes already got their real bucket, so a later seed can't overwrite one.\n const seeded: Record<string, boolean> = {};\n const seed = (next: AppScopeContexts): void => {\n const bags = (next && next.apps) || {};\n Object.keys(bags).forEach((scopeId) => {\n if (seeded[scopeId]) return;\n seeded[scopeId] = true;\n appCtx[scopeId] = Object.assign({}, appCtx[scopeId] || {}, bags[scopeId] || {});\n base[scopeId] = Object.assign({}, appCtx[scopeId]);\n });\n };\n seed(contexts);\n\n const createAppScope = makeFactory(w, appCtx);\n Salla.appScope = (scopeId: string): SallaSDK => createAppScope(scopeId);\n\n // Fill in buckets for scopes not seeded yet (first-write-wins per scope). Lets the head\n // install the factory unconditionally — at parse time, before any snippet's onReady — and\n // still pick up buckets that only the client managed to fetch.\n Salla.__appScopeSeed = (next: AppScopeContexts): void => seed(next);\n\n // Overlay preview mocks onto an app's pristine baseline, so fields the partner did not mock\n // keep their real values. Returns false for an unknown scope or before install.\n Salla.__appScopeMock = (scopeId: string, mocks: AppConfigBag): boolean => {\n if (!(scopeId in base)) return false;\n appCtx[scopeId] = Object.assign({}, base[scopeId], mocks);\n return true;\n };\n}\n\n/** Overlay preview mocks onto one app's bucket (over its pristine values). Delegates to the\n * bootstrap's `__appScopeMock`, so it works for both install paths. False if unknown/uninstalled. */\nexport function applyAppScopeMocks(appScopeId: string, mocks: AppConfigBag): boolean {\n if (!isBrowser) return false;\n const mock = (window.Salla as unknown as { __appScopeMock?: MockApplier } | undefined)\n ?.__appScopeMock;\n return mock?.(appScopeId, mocks) ?? false;\n}\n\ntype MockApplier = (appScopeId: string, mocks: AppConfigBag) => boolean;\n\n/** Serialize the installer into an inline `<script>` body seeded with `contexts` — both halves\n * via `.toString()`, hence their self-contained requirement. See `rootHead`. */\nexport function renderAppScopeInstallScript(contexts: AppScopeContexts): string {\n // Bucket values are partner-set, so escape the JSON seed against a `</script>` breakout.\n // The function sources have no `<`, so they need no escaping.\n const json = escapeForInlineScript(JSON.stringify(contexts));\n return `(${appScopeBootstrap.toString()})(${json},${createAppScopeFactory.toString()});`;\n}\n\n/** Install `Salla.appScope` on the client, or seed buckets into the inline SSR head copy that\n * already installed it. No-op on the server. Fallback for unseeded loads + the unit-test entry\n * point. */\nexport function installAppScope(contexts: AppScopeContexts): void {\n if (!isBrowser) return;\n appScopeBootstrap(contexts, createAppScopeFactory);\n}\n","import { escapeForInlineScript } from './inline-script';\n\nconst registered = new Set<string>();\n\nlet retryArmed = false;\n\n/**\n * Declare hook slots the theme renders itself so apps may mount into them.\n *\n * The SDK rejects `mount()` for any name absent from its `_themeSlots` whitelist, so a theme\n * rendering its own `<salla-hook>` must register the name. Call at module scope; the engine\n * applies the names via {@link applyThemeHookSlots}.\n */\nexport function registerThemeHookSlots(...names: string[]): void {\n for (const name of names) registered.add(name);\n}\n\n/** Push the registered names in. Returns false if the SDK hasn't exposed the list yet. */\nfunction pushSlots(): boolean {\n const slots = window.salla?.hooks?._themeSlots;\n if (!Array.isArray(slots)) return false;\n for (const name of registered) if (!slots.includes(name)) slots.push(name);\n return true;\n}\n\n/**\n * Push every registered slot name into the SDK whitelist. Idempotent. Engine-only.\n *\n * The SDK's hooks module may attach after this runs, so a first no-op falls back to a\n * one-shot retry on `twilight::initiated` — still before apps mount from their own onReady.\n *\n * This is only the late backstop: the whitelist is primarily seeded at parse time by the\n * inline head script from {@link renderThemeHookSlotsScript}, because an app's snippet\n * registers its `onReady` callback before React ever hydrates.\n */\nexport function applyThemeHookSlots(): void {\n if (typeof window === 'undefined' || registered.size === 0) return;\n if (pushSlots() || retryArmed) return;\n\n retryArmed = true;\n window.addEventListener('twilight::initiated', () => void pushSlots(), { once: true });\n}\n\n/** The slot names registered so far. Read by `rootHead` when rendering the inline script. */\nexport function getRegisteredThemeHookSlots(): string[] {\n return [...registered];\n}\n\n/**\n * Serialize the whitelist push into an inline head `<script>` body, so the slots are\n * registered at parse time.\n *\n * Ordering is the whole point: CDN snippets are parser-inserted `<script defer>` tags in the\n * body, so an app's `Salla.onReady` callback is registered long before React hydrates and runs\n * {@link applyThemeHookSlots}. Whichever `twilight::initiated` listener was added first runs\n * first, so the push must be armed from the head — otherwise the SDK rejects the app's\n * `hooks.mount()` with \"Hook <name> is not allowed\" and the app never renders.\n *\n * Returns null when the theme registered no slots. Kept self-contained (only `window`) since\n * it ships as raw source, not as a bundled module.\n */\nexport function renderThemeHookSlotsScript(names: string[] = getRegisteredThemeHookSlots()) {\n if (!names.length) return null;\n const json = escapeForInlineScript(JSON.stringify(names));\n return (\n `(function(names){` +\n `var w=window;` +\n `function push(){` +\n `var h=w.salla&&w.salla.hooks;var slots=h&&h._themeSlots;` +\n `if(!Array.isArray(slots))return false;` +\n `for(var i=0;i<names.length;i++)if(slots.indexOf(names[i])<0)slots.push(names[i]);` +\n `return true}` +\n `if(push())return;` +\n `w.addEventListener('twilight::initiated',function(){push()},{once:true})` +\n `})(${json});`\n );\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { lazy } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/components/cart/lazy.ts
|
|
4
|
+
var LazyCartItem = lazy(() => import('./CartItem-QST2C243.js').then((m) => ({ default: m.CartItem })));
|
|
5
|
+
var LazyCartSummary = lazy(
|
|
6
|
+
() => import('./CartSummary-IFZI2NFE.js').then((m) => ({ default: m.CartSummary }))
|
|
7
|
+
);
|
|
8
|
+
var LazySeoCartWidget = lazy(
|
|
9
|
+
() => import('./SeoCartWidget-YSCC2V65.js').then((m) => ({ default: m.SeoCartWidget }))
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export { LazyCartItem, LazyCartSummary, LazySeoCartWidget };
|
|
13
|
+
//# sourceMappingURL=chunk-5RAADM2K.js.map
|
|
14
|
+
//# sourceMappingURL=chunk-5RAADM2K.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/cart/lazy.ts"],"names":[],"mappings":";;;AAMO,IAAM,YAAA,GAAe,IAAA,CAAK,MAAM,OAAO,wBAAY,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,QAAA,GAAW,CAAC;AAE3F,IAAM,eAAA,GAAkB,IAAA;AAAA,EAAK,MAClC,OAAO,2BAAe,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,WAAA,EAAY,CAAE;AAClE;AAEO,IAAM,iBAAA,GAAoB,IAAA;AAAA,EAAK,MACpC,OAAO,6BAAiB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,aAAA,EAAc,CAAE;AACtE","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/cart/lazy.ts"],"names":[],"mappings":";;;AAMO,IAAM,YAAA,GAAe,IAAA,CAAK,MAAM,OAAO,wBAAY,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,QAAA,GAAW,CAAC;AAE3F,IAAM,eAAA,GAAkB,IAAA;AAAA,EAAK,MAClC,OAAO,2BAAe,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,WAAA,EAAY,CAAE;AAClE;AAEO,IAAM,iBAAA,GAAoB,IAAA;AAAA,EAAK,MACpC,OAAO,6BAAiB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,aAAA,EAAc,CAAE;AACtE","file":"chunk-5RAADM2K.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded cart components\n * Use these for code-splitting cart sections\n */\nexport const LazyCartItem = lazy(() => import('./CartItem').then((m) => ({ default: m.CartItem })));\n\nexport const LazyCartSummary = lazy(() =>\n import('./CartSummary').then((m) => ({ default: m.CartSummary }))\n);\n\nexport const LazySeoCartWidget = lazy(() =>\n import('./SeoCartWidget').then((m) => ({ default: m.SeoCartWidget }))\n);\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { rememberProductPreview } from './chunk-
|
|
2
|
-
import { getActiveScope, api } from './chunk-
|
|
1
|
+
import { rememberProductPreview } from './chunk-TWJXVT6S.js';
|
|
2
|
+
import { getActiveScope, api } from './chunk-QGOPTVV5.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
5
5
|
var wishlist = {
|
|
@@ -31,5 +31,5 @@ var wishlist = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export { wishlist };
|
|
34
|
-
//# sourceMappingURL=chunk-
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-5SD7BUSA.js.map
|
|
35
|
+
//# sourceMappingURL=chunk-5SD7BUSA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/wishlist.ts"],"names":[],"mappings":";;;;AAmBO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,MAAA,GAA6B,EAAC,KAAmC;AAC5E,IAAA,MAAM,EAAE,IAAA,GAAO,CAAA,EAAG,UAAU,EAAA,EAAI,UAAA,EAAY,QAAO,GAAI,MAAA;AAEvD,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAU,UAAU,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAC,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAE5C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAA,GAAa,GAAA,GAAM,GAAG,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,UAAmC,EAAC;AAC1C,IAAA,IAAI,MAAA,UAAgB,MAAA,GAAS,MAAA;AAE7B,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CACpB,GAAA,CAAI,CAAA,SAAA,EAAY,YAAA,CAAa,QAAA,EAAU,CAAA,CAAA,EAAI,OAAc,CAAA,CACzD,IAAA,EAA2B;AAE9B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,IAAQ,EAAC;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,sBAAA,CAAuB,IAAI,CAAA;AAErD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM,QAAA,CAAS,MAAA,EAAQ,IAAA,IAAQ;AAAA,KACjC;AAAA,EACF,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,MAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AAAA,MAClE,OAAA,EAAS,CAAC,EAAE,MAAA,EAAO,KAAM,QAAA,CAAS,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KAC7D;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/wishlist.ts"],"names":[],"mappings":";;;;AAmBO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,MAAA,GAA6B,EAAC,KAAmC;AAC5E,IAAA,MAAM,EAAE,IAAA,GAAO,CAAA,EAAG,UAAU,EAAA,EAAI,UAAA,EAAY,QAAO,GAAI,MAAA;AAEvD,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAU,UAAU,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAC,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAE5C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAA,GAAa,GAAA,GAAM,GAAG,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,UAAmC,EAAC;AAC1C,IAAA,IAAI,MAAA,UAAgB,MAAA,GAAS,MAAA;AAE7B,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CACpB,GAAA,CAAI,CAAA,SAAA,EAAY,YAAA,CAAa,QAAA,EAAU,CAAA,CAAA,EAAI,OAAc,CAAA,CACzD,IAAA,EAA2B;AAE9B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,IAAQ,EAAC;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,sBAAA,CAAuB,IAAI,CAAA;AAErD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM,QAAA,CAAS,MAAA,EAAQ,IAAA,IAAQ;AAAA,KACjC;AAAA,EACF,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,MAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AAAA,MAClE,OAAA,EAAS,CAAC,EAAE,MAAA,EAAO,KAAM,QAAA,CAAS,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KAC7D;AAAA;AAEP","file":"chunk-5SD7BUSA.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport {\n rememberProductPreview,\n type ProductsListResult,\n type ProductsListResponse,\n} from './product';\n\nexport interface WishlistListParams {\n page?: number;\n perPage?: number;\n filterable?: boolean;\n signal?: AbortSignal;\n}\n\n/**\n * Wishlist API — page-based pagination only.\n * Kept separate from product.list to avoid mixing cursor and page pagination strategies.\n */\nexport const wishlist = {\n list: async (params: WishlistListParams = {}): Promise<ProductsListResult> => {\n const { page = 1, perPage = 15, filterable, signal } = params;\n\n const searchParams = new URLSearchParams();\n searchParams.set('source', 'wishlist');\n searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n for (const item of items) rememberProductPreview(item);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n };\n },\n\n queries: {\n list: (params: Omit<WishlistListParams, 'signal'>) =>\n queryOptions({\n queryKey: ['wishlist', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => wishlist.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { user } from './chunk-
|
|
1
|
+
import { user } from './chunk-ENJ3CM5M.js';
|
|
2
2
|
import { getTwilightContext } from './chunk-N2S25NXP.js';
|
|
3
3
|
import { useQuery } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -13,5 +13,5 @@ function useUser() {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { useUser };
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-66K5P5ZX.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-66K5P5ZX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useUser.ts"],"names":[],"mappings":";;;;AAUO,SAAS,OAAA,GAAyB;AACvC,EAAA,MAAM,KAAA,GAAQ,oBAAmB,CAAE,SAAA;AAEnC,EAAA,MAAM,QAAQ,QAAA,CAAS;AAAA,IACrB,GAAG,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACxB,OAAA,EAAS,CAAC,CAAC,KAAA;AAAA,IACX,eAAA,EAAiB;AAAA,GAClB,CAAA;AAED,EAAA,OAAO,EAAE,GAAG,KAAA,EAAO,UAAA,EAAY,CAAC,CAAC,KAAA,EAAM;AACzC","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useUser.ts"],"names":[],"mappings":";;;;AAUO,SAAS,OAAA,GAAyB;AACvC,EAAA,MAAM,KAAA,GAAQ,oBAAmB,CAAE,SAAA;AAEnC,EAAA,MAAM,QAAQ,QAAA,CAAS;AAAA,IACrB,GAAG,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACxB,OAAA,EAAS,CAAC,CAAC,KAAA;AAAA,IACX,eAAA,EAAiB;AAAA,GAClB,CAAA;AAED,EAAA,OAAO,EAAE,GAAG,KAAA,EAAO,UAAA,EAAY,CAAC,CAAC,KAAA,EAAM;AACzC","file":"chunk-66K5P5ZX.js","sourcesContent":["import { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport { getTwilightContext } from '../twilight/context';\nimport { user } from '../api/user';\nimport type { User } from '../types';\n\nexport type UseUserReturn = UseQueryResult<User | null> & {\n /** True when an auth token exists (regardless of query state). */\n isLoggedIn: boolean;\n};\n\nexport function useUser(): UseUserReturn {\n const token = getTwilightContext().authToken;\n\n const query = useQuery({\n ...user.queries.current(),\n enabled: !!token,\n placeholderData: null,\n });\n\n return { ...query, isLoggedIn: !!token };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { api } from './chunk-
|
|
1
|
+
import { api } from './chunk-QGOPTVV5.js';
|
|
2
2
|
import { getTwilightContext } from './chunk-N2S25NXP.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -23,5 +23,5 @@ var menu = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export { menu };
|
|
26
|
-
//# sourceMappingURL=chunk-
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
26
|
+
//# sourceMappingURL=chunk-6DMNJPLW.js.map
|
|
27
|
+
//# sourceMappingURL=chunk-6DMNJPLW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/menu.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,UAAU,CAAC,OAAA,EAAS,QAAA,EAAU,kBAAA,GAAqB,MAAM,CAAA;AAAA,MACzD,OAAA,EAAS,MAAM,IAAA,CAAK,MAAA,EAAO;AAAA,MAC3B,SAAA,EAAW,IAAI,EAAA,GAAK;AAAA,KACrB;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/menu.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,UAAU,CAAC,OAAA,EAAS,QAAA,EAAU,kBAAA,GAAqB,MAAM,CAAA;AAAA,MACzD,OAAA,EAAS,MAAM,IAAA,CAAK,MAAA,EAAO;AAAA,MAC3B,SAAA,EAAW,IAAI,EAAA,GAAK;AAAA,KACrB;AAAA;AAEP","file":"chunk-6DMNJPLW.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport { getTwilightContext } from '../twilight/context';\nimport type { MenuItem } from '../types';\n\nexport const menu = {\n header: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/header?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n footer: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/footer?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n queries: {\n header: () =>\n queryOptions({\n queryKey: ['menus', 'header', getTwilightContext().locale],\n queryFn: () => menu.header(),\n staleTime: 5 * 60 * 1000,\n }),\n },\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getSallaSDK, whenSallaReady } from './chunk-
|
|
1
|
+
import { getSallaSDK, whenSallaReady } from './chunk-HSWRYXC7.js';
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
function isNativeApp() {
|
|
@@ -29,5 +29,5 @@ function useNativeStatusBarColor() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export { hapticImpact, isNativeApp, useIsNativeApp, useNativeStatusBarColor };
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-6N33IKYP.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-6N33IKYP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/native-app/index.ts"],"names":[],"mappings":";;;AAQO,SAAS,WAAA,GAAuB;AACrC,EAAA,OAAO,OAAA,CAAQ,WAAA,EAAY,EAAG,MAAA,EAAQ,aAAa,CAAA;AACrD;AAOO,SAAS,cAAA,GAA0B;AACxC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,KAAK,CAAA;AAExC,EAAA,SAAA,CAAU,MAAM,eAAe,MAAM,QAAA,CAAS,aAAa,CAAC,CAAA,EAAG,EAAE,CAAA;AAEjE,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,aAAa,MAAA,EAA4B;AACvD,EAAA,WAAA,IAAe,MAAA,EAAQ,MAAA,GAAS,iBAAiB,EAAE,WAAA,EAAa,QAAQ,CAAA;AAC1E;AAOA,SAAS,SAAS,GAAA,EAA4B;AAC5C,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,oDAAoD,CAAA;AAC5E,EAAA,IAAI,CAAC,SAAS,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,KAAM,GAAG,OAAO,IAAA;AAC7C,EAAA,OAAO,CAAA,CAAA,EAAI,MACR,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,OAAA,KAAY,MAAA,CAAO,OAAO,EAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC9D,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACb;AAWO,SAAS,uBAAA,GAAiE;AAC/E,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAmB,IAAI,CAAA;AACrD,EAAA,MAAM,QAAQ,cAAA,EAAe;AAE7B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,OAAA,EAAS;AACxB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,gBAAA,CAAiB,OAAO,EAAE,eAAe,CAAA;AAChE,IAAA,IAAI,KAAA,eAAmB,EAAG,KAAA,CAAM,SAAS,yBAAA,EAA2B,EAAE,OAAO,CAAA;AAAA,EAC/E,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnB,EAAA,OAAO,UAAA;AACT","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/native-app/index.ts"],"names":[],"mappings":";;;AAQO,SAAS,WAAA,GAAuB;AACrC,EAAA,OAAO,OAAA,CAAQ,WAAA,EAAY,EAAG,MAAA,EAAQ,aAAa,CAAA;AACrD;AAOO,SAAS,cAAA,GAA0B;AACxC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,KAAK,CAAA;AAExC,EAAA,SAAA,CAAU,MAAM,eAAe,MAAM,QAAA,CAAS,aAAa,CAAC,CAAA,EAAG,EAAE,CAAA;AAEjE,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,aAAa,MAAA,EAA4B;AACvD,EAAA,WAAA,IAAe,MAAA,EAAQ,MAAA,GAAS,iBAAiB,EAAE,WAAA,EAAa,QAAQ,CAAA;AAC1E;AAOA,SAAS,SAAS,GAAA,EAA4B;AAC5C,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,oDAAoD,CAAA;AAC5E,EAAA,IAAI,CAAC,SAAS,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,KAAM,GAAG,OAAO,IAAA;AAC7C,EAAA,OAAO,CAAA,CAAA,EAAI,MACR,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,OAAA,KAAY,MAAA,CAAO,OAAO,EAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC9D,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACb;AAWO,SAAS,uBAAA,GAAiE;AAC/E,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAmB,IAAI,CAAA;AACrD,EAAA,MAAM,QAAQ,cAAA,EAAe;AAE7B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,OAAA,EAAS;AACxB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,gBAAA,CAAiB,OAAO,EAAE,eAAe,CAAA;AAChE,IAAA,IAAI,KAAA,eAAmB,EAAG,KAAA,CAAM,SAAS,yBAAA,EAA2B,EAAE,OAAO,CAAA;AAAA,EAC/E,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnB,EAAA,OAAO,UAAA;AACT","file":"chunk-6N33IKYP.js","sourcesContent":["import { useEffect, useState, type RefCallback } from 'react';\nimport { getSallaSDK, whenSallaReady } from '../utils/sdk-helpers';\n\n/**\n * True inside the Salla native app's webview, read at call time: the SDK's\n * `salla.mobile.isEnabled()`. False on the server and until the SDK has loaded, so call it\n * from an event handler or an effect, and use {@link useIsNativeApp} to decide what to render.\n */\nexport function isNativeApp(): boolean {\n return Boolean(getSallaSDK()?.mobile?.isEnabled?.());\n}\n\n/**\n * {@link isNativeApp} as state, for a render decision. False on the server and on the first\n * client render, then true once the SDK is ready inside the app: an app that identifies\n * itself through its config has not said so before `init`.\n */\nexport function useIsNativeApp(): boolean {\n const [inApp, setInApp] = useState(false);\n\n useEffect(() => whenSallaReady(() => setInApp(isNativeApp())), []);\n\n return inApp;\n}\n\nexport type HapticImpact = 'light' | 'medium' | 'heavy';\n\n/** Asks the native app for a tap vibration. The SDK ignores it outside the app. */\nexport function hapticImpact(impact: HapticImpact): void {\n getSallaSDK()?.mobile?.action?.('haptic.impact', { impact_type: impact });\n}\n\n/**\n * `rgb(232, 245, 255)`, what `getComputedStyle` returns, as `#e8f5ff`. A partial alpha is\n * dropped. A fully transparent colour is no colour at all: an element with no background\n * of its own computes to `rgba(0, 0, 0, 0)`, which would otherwise read as black.\n */\nfunction rgbToHex(rgb: string): string | null {\n const match = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/);\n if (!match || Number(match[4]) === 0) return null;\n return `#${match\n .slice(1, 4)\n .map((channel) => Number(channel).toString(16).padStart(2, '0'))\n .join('')}`;\n}\n\n/**\n * Tells the native app to paint its status bar with the rendered background of the element\n * the returned ref is attached to. The colour is read from the DOM, because a theme's tint\n * is often a relative CSS colour (`hsl(from …)`) with no hex to pass. Does nothing outside\n * the app, and for an element with no background of its own.\n *\n * The ref is a callback, kept in state, so an element that mounts after the app has been\n * recognised still reports its colour.\n */\nexport function useNativeStatusBarColor<T extends HTMLElement>(): RefCallback<T> {\n const [element, setElement] = useState<T | null>(null);\n const inApp = useIsNativeApp();\n\n useEffect(() => {\n if (!inApp || !element) return;\n const color = rgbToHex(getComputedStyle(element).backgroundColor);\n if (color) getSallaSDK()?.event.dispatch('mobile::statusbar.color', { color });\n }, [inApp, element]);\n\n return setElement;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { api } from './chunk-
|
|
1
|
+
import { api } from './chunk-QGOPTVV5.js';
|
|
2
2
|
import { queryOptions } from '@tanstack/react-query';
|
|
3
3
|
|
|
4
4
|
var notification = {
|
|
@@ -24,5 +24,5 @@ var notification = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export { notification };
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-6OOTDFC7.js.map
|
|
28
|
+
//# sourceMappingURL=chunk-6OOTDFC7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/notification.ts"],"names":[],"mappings":";;;AAcO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAM,YAAgD;AACpD,IAAA,MAAM,WAAW,MAAM,GAAA,CACpB,GAAA,CAAI,eAAe,EACnB,IAAA,EAAmF;AACtF,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,QAAA,CAAS,IAAA,IAAQ,EAAC;AAAA,MACxB,QAAQ,QAAA,CAAS;AAAA,KACnB;AAAA,EACF,CAAA;AAAA,EAEA,UAAA,EAAY,OAAO,EAAA,KAA8B;AAC/C,IAAA,MAAM,IAAI,GAAA,CAAI,CAAA,cAAA,EAAiB,EAAE,CAAA,KAAA,CAAO,EAAE,IAAA,EAAK;AAAA,EACjD,CAAA;AAAA,EAEA,eAAe,YAA2B;AACxC,IAAA,MAAM,GAAA,CAAI,GAAA,CAAI,wBAAwB,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,eAAA,EAAiB,MAAM,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA;AAAK,KAClC;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/notification.ts"],"names":[],"mappings":";;;AAcO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAM,YAAgD;AACpD,IAAA,MAAM,WAAW,MAAM,GAAA,CACpB,GAAA,CAAI,eAAe,EACnB,IAAA,EAAmF;AACtF,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,QAAA,CAAS,IAAA,IAAQ,EAAC;AAAA,MACxB,QAAQ,QAAA,CAAS;AAAA,KACnB;AAAA,EACF,CAAA;AAAA,EAEA,UAAA,EAAY,OAAO,EAAA,KAA8B;AAC/C,IAAA,MAAM,IAAI,GAAA,CAAI,CAAA,cAAA,EAAiB,EAAE,CAAA,KAAA,CAAO,EAAE,IAAA,EAAK;AAAA,EACjD,CAAA;AAAA,EAEA,eAAe,YAA2B;AACxC,IAAA,MAAM,GAAA,CAAI,GAAA,CAAI,wBAAwB,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,eAAA,EAAiB,MAAM,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA;AAAK,KAClC;AAAA;AAEP","file":"chunk-6OOTDFC7.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Notification } from '../routes/account/notifications/types';\n\nexport interface NotificationsListResponse {\n data: Notification[];\n cursor: {\n current: number;\n previous: number | null;\n next: number | null;\n count: number;\n };\n}\n\nexport const notification = {\n list: async (): Promise<NotificationsListResponse> => {\n const response = await api\n .get('notifications')\n .json<{ data: Notification[] | null; cursor: NotificationsListResponse['cursor'] }>();\n return {\n data: response.data ?? [],\n cursor: response.cursor,\n };\n },\n\n markAsRead: async (id: number): Promise<void> => {\n await api.put(`notifications/${id}/read`).json();\n },\n\n markAllAsRead: async (): Promise<void> => {\n await api.put('notifications/read-all').json();\n },\n\n queries: {\n list: () =>\n queryOptions({\n queryKey: ['notifications', 'list'],\n queryFn: () => notification.list(),\n }),\n },\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useIsHome } from './chunk-
|
|
1
|
+
import { useIsHome } from './chunk-6ZMNTJM3.js';
|
|
2
2
|
import { useTranslation } from './chunk-TYNZ5B2B.js';
|
|
3
3
|
import { HookSlot } from './chunk-5XDPAKF5.js';
|
|
4
|
-
import { Image } from './chunk-
|
|
4
|
+
import { Image } from './chunk-3NLO5SK3.js';
|
|
5
5
|
import { useTwilight } from './chunk-DF6FBKDN.js';
|
|
6
6
|
import { lazy, useState } from 'react';
|
|
7
7
|
import { SallaAdvertisement } from '@salla.sa/twilight-components-react/advertisement';
|
|
@@ -13,9 +13,9 @@ import { SallaSearch } from '@salla.sa/twilight-components-react/search';
|
|
|
13
13
|
import { SallaUserMenu } from '@salla.sa/twilight-components-react/user-menu';
|
|
14
14
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
15
15
|
|
|
16
|
-
var LazyMainMenu = lazy(() => import('./MainMenu-
|
|
16
|
+
var LazyMainMenu = lazy(() => import('./MainMenu-3D6TQ5MX.js').then((m) => ({ default: m.MainMenu })));
|
|
17
17
|
var LazyMobileMenu = lazy(
|
|
18
|
-
() => import('./MobileMenu-
|
|
18
|
+
() => import('./MobileMenu-GZNQH3NF.js').then((m) => ({ default: m.MobileMenu }))
|
|
19
19
|
);
|
|
20
20
|
function Header(_props) {
|
|
21
21
|
const { currency, theme, store } = useTwilight();
|
|
@@ -120,5 +120,5 @@ function Header(_props) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
export { Header };
|
|
123
|
-
//# sourceMappingURL=chunk-
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
123
|
+
//# sourceMappingURL=chunk-6QMYSKUE.js.map
|
|
124
|
+
//# sourceMappingURL=chunk-6QMYSKUE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/navigation/lazy.ts","../src/components/layout/Header.tsx"],"names":[],"mappings":"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","file":"chunk-64L2L76T.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded navigation components\n * Use these for code-splitting navigation sections\n */\nexport const LazyMainMenu = lazy(() => import('./MainMenu').then((m) => ({ default: m.MainMenu })));\n\nexport const LazyMobileMenu = lazy(() =>\n import('./MobileMenu').then((m) => ({ default: m.MobileMenu }))\n);\n","import { useState } from 'react';\nimport { useIsHome } from '../../providers/NavigationProvider';\nimport { SallaAdvertisement } from '@salla.sa/twilight-components-react/advertisement';\nimport { SallaCartSummary } from '@salla.sa/twilight-components-react/cart-summary';\nimport { SallaContacts } from '@salla.sa/twilight-components-react/contacts';\nimport { SallaLocalizationModal } from '@salla.sa/twilight-components-react/localization-modal';\nimport { SallaMenu } from '@salla.sa/twilight-components-react/menu';\nimport { SallaSearch } from '@salla.sa/twilight-components-react/search';\nimport { SallaUserMenu } from '@salla.sa/twilight-components-react/user-menu';\nimport { useTwilight } from '../../providers/twilight-context';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { HookSlot } from '../../hooks/HookSlot';\nimport { MainMenu, MobileMenu } from '../navigation';\nimport { Image } from '../common';\nimport type { Cart } from '../../types';\n\ninterface HeaderProps {\n cart?: Cart;\n}\n\nexport function Header(_props: HeaderProps) {\n const { currency, theme, store } = useTwilight();\n const { locale, languageName } = useTranslation();\n const settings = theme?.settings || {};\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n\n // Check if we're on homepage\n const isHomepage = useIsHome();\n\n const StoreTitle = isHomepage ? 'h1' : 'span';\n\n return (\n <header className=\"store-header\" suppressHydrationWarning>\n <HookSlot name=\"header:start\" />\n <div className=\"advertisement-slot\">\n <SallaAdvertisement />\n </div>\n {/* Top Nav */}\n <div className={`top-navbar${settings.topnav_is_dark ? ' top-navbar--dark' : ''}`}>\n <div className=\"container flex justify-between\">\n <div className=\"flex-1 flex items-center gap-2\">\n {/* Footer Menu */}\n {settings.important_links && <SallaMenu source=\"footer\" topnav />}\n\n {/* Language & Currency */}\n <div className=\"header-buttons\">\n {(store?.settings?.is_multilingual || store?.settings?.currencies_enabled) && (\n <>\n <button\n type=\"button\"\n onClick={() => window.salla?.event.dispatch('localization::open')}\n className=\"btn--rounded-gray basis-0\"\n >\n <span>{languageName}</span>\n <span className=\"mx-1.5\">|</span>\n <span className={`flag iti__flag iti__${store?.country.toLowerCase()}`}></span>\n\n <span>\n {store?.settings?.use_sar_symbol && currency?.code === 'SAR' ? (\n <i className=\"sicon-sar\"></i>\n ) : (\n <>{currency?.symbol}</>\n )}\n </span>\n </button>\n {/* TODO:: support switch the lang without hit the web API, by set it in the sdk and local storage */}\n {/* TODO:: Support switch the curency without hit the web API, by set it in the sdk and local storage */}\n <SallaLocalizationModal\n language={locale}\n currency={currency?.code || 'SAR'}\n suppressHydrationWarning\n />\n </>\n )}\n </div>\n\n {/* Scopes / Branches */}\n {store?.scope && (\n <button\n type=\"button\"\n className=\"btn--rounded-gray\"\n onClick={() =>\n window.salla?.event.dispatch('scopes::open', {\n mode: 'default',\n })\n }\n >\n <i className=\"sicon-location rtl:ml-1 ltr:mr-1\"></i>\n {store.scope.name}\n </button>\n )}\n\n {/* Search bar */}\n <div className=\"header-search flex-1\">\n {/* todo:: use a search icon insted with open the search popup */}\n <SallaSearch inline oval height={36} />\n </div>\n </div>\n\n <SallaContacts contacts={store?.contacts} contactsTitle=\"N/A\" isHeader />\n </div>\n </div>\n\n {/* Main Nav */}\n <div\n id=\"mainnav\"\n className={`main-nav-container shadow-default bg-white flex items-center relative z-50${settings.header_is_sticky ? ' sticky top-0' : ''}`}\n >\n <div className=\"inner bg-inherit w-full\">\n <div className=\"container\">\n <div className=\"flex items-stretch justify-between relative\">\n <div className=\"flex items-center\">\n <a\n className=\"lg:hidden mburger mburger--collapse leading-none rtl:ml-4 ltr:mr-4\"\n href=\"#mobile-menu\"\n aria-label=\"Open-menu\"\n onClick={(e) => {\n e.preventDefault();\n setIsMobileMenuOpen(true);\n }}\n >\n <i className=\"sicon-menu text-primary text-2xl\"></i>\n </a>\n <a className=\"navbar-brand\" href={store?.url || '/'}>\n <div className=\"logo-wrapper\">\n <Image\n src={store?.logo}\n alt={`${store?.name || 'Store'} logo`}\n priority\n width={120}\n height={48}\n />\n </div>\n <StoreTitle className=\"sr-only\">{store?.name || 'Store'}</StoreTitle>\n </a>\n <MainMenu />\n </div>\n <div className=\"flex items-center justify-end my-2.5\">\n <SallaUserMenu avatarOnly showHeader className=\"header-btn\" />\n <SallaCartSummary className=\"ml-4 rtl:ml-[unset] rtl:mr-4\">\n <i slot=\"icon\" className=\"header-btn__icon icon sicon-shopping-bag\"></i>\n </SallaCartSummary>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Mobile Menu */}\n <MobileMenu isOpen={isMobileMenuOpen} onClose={() => setIsMobileMenuOpen(false)} />\n <HookSlot name=\"header:end\" />\n </header>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/navigation/lazy.ts","../src/components/layout/Header.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAMO,IAAM,YAAA,GAAe,IAAA,CAAK,MAAM,OAAO,wBAAY,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,QAAA,GAAW,CAAC,CAAA;AAE3F,IAAM,cAAA,GAAiB,IAAA;AAAA,EAAK,MACjC,OAAO,0BAAc,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,UAAA,EAAW,CAAE;AAChE,CAAA;ACUO,SAAS,OAAO,MAAA,EAAqB;AAC1C,EAAA,MAAM,EAAE,QAAA,EAAU,KAAA,EAAO,KAAA,KAAU,WAAA,EAAY;AAC/C,EAAA,MAAM,EAAE,MAAA,EAAQ,YAAA,EAAa,GAAI,cAAA,EAAe;AAChD,EAAA,MAAM,QAAA,GAAW,KAAA,EAAO,QAAA,IAAY,EAAC;AACrC,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,KAAK,CAAA;AAG9D,EAAA,MAAM,aAAa,SAAA,EAAU;AAE7B,EAAA,MAAM,UAAA,GAAa,aAAa,IAAA,GAAO,MAAA;AAEvC,EAAA,uBACE,IAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,cAAA,EAAe,0BAAwB,IAAA,EACvD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,MAAK,cAAA,EAAe,CAAA;AAAA,wBAC7B,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACb,QAAA,kBAAA,GAAA,CAAC,sBAAmB,CAAA,EACtB,CAAA;AAAA,oBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,UAAA,EAAa,QAAA,CAAS,cAAA,GAAiB,mBAAA,GAAsB,EAAE,CAAA,CAAA,EAC7E,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gCAAA,EAEZ,QAAA,EAAA;AAAA,QAAA,QAAA,CAAS,mCAAmB,GAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAO,QAAA,EAAS,QAAM,IAAA,EAAC,CAAA;AAAA,wBAG/D,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACX,QAAA,EAAA,CAAA,KAAA,EAAO,UAAU,eAAA,IAAmB,KAAA,EAAO,QAAA,EAAU,kBAAA,qBACrD,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAA,IAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAS,MAAM,MAAA,CAAO,KAAA,EAAO,KAAA,CAAM,SAAS,oBAAoB,CAAA;AAAA,cAChE,SAAA,EAAU,2BAAA;AAAA,cAEV,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,UAAM,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,gCACpB,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,gCAC1B,GAAA,CAAC,UAAK,SAAA,EAAW,CAAA,qBAAA,EAAwB,OAAO,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA,EAAI,CAAA;AAAA,oCAExE,MAAA,EAAA,EACE,QAAA,EAAA,KAAA,EAAO,QAAA,EAAU,cAAA,IAAkB,UAAU,IAAA,KAAS,KAAA,mBACrD,GAAA,CAAC,GAAA,EAAA,EAAE,WAAU,WAAA,EAAY,CAAA,mBAEzB,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,QAAA,EAAU,QAAO,CAAA,EAExB;AAAA;AAAA;AAAA,WACF;AAAA,0BAGA,GAAA;AAAA,YAAC,sBAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAU,MAAA;AAAA,cACV,QAAA,EAAU,UAAU,IAAA,IAAQ,KAAA;AAAA,cAC5B,wBAAA,EAAwB;AAAA;AAAA;AAC1B,SAAA,EACF,CAAA,EAEJ,CAAA;AAAA,QAGC,OAAO,KAAA,oBACN,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,mBAAA;AAAA,YACV,SAAS,MACP,MAAA,CAAO,KAAA,EAAO,KAAA,CAAM,SAAS,cAAA,EAAgB;AAAA,cAC3C,IAAA,EAAM;AAAA,aACP,CAAA;AAAA,YAGH,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,GAAA,EAAA,EAAE,WAAU,kCAAA,EAAmC,CAAA;AAAA,cAC/C,MAAM,KAAA,CAAM;AAAA;AAAA;AAAA,SACf;AAAA,wBAIF,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EAEb,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,MAAA,EAAM,IAAA,EAAC,IAAA,EAAI,IAAA,EAAC,MAAA,EAAQ,EAAA,EAAI,CAAA,EACvC;AAAA,OAAA,EACF,CAAA;AAAA,sBAEA,GAAA,CAAC,iBAAc,QAAA,EAAU,KAAA,EAAO,UAAU,aAAA,EAAc,KAAA,EAAM,UAAQ,IAAA,EAAC;AAAA,KAAA,EACzE,CAAA,EACF,CAAA;AAAA,oBAGA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAG,SAAA;AAAA,QACH,SAAA,EAAW,CAAA,0EAAA,EAA6E,QAAA,CAAS,gBAAA,GAAmB,kBAAkB,EAAE,CAAA,CAAA;AAAA,QAExI,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6CAAA,EACb,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,oEAAA;AAAA,gBACV,IAAA,EAAK,cAAA;AAAA,gBACL,YAAA,EAAW,WAAA;AAAA,gBACX,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,kBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,kBAAA,mBAAA,CAAoB,IAAI,CAAA;AAAA,gBAC1B,CAAA;AAAA,gBAEA,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,kCAAA,EAAmC;AAAA;AAAA,aAClD;AAAA,iCACC,GAAA,EAAA,EAAE,SAAA,EAAU,gBAAe,IAAA,EAAM,KAAA,EAAO,OAAO,GAAA,EAC9C,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,cAAA,EACb,QAAA,kBAAA,GAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,KAAK,KAAA,EAAO,IAAA;AAAA,kBACZ,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,IAAA,IAAQ,OAAO,CAAA,KAAA,CAAA;AAAA,kBAC9B,QAAA,EAAQ,IAAA;AAAA,kBACR,KAAA,EAAO,GAAA;AAAA,kBACP,MAAA,EAAQ;AAAA;AAAA,eACV,EACF,CAAA;AAAA,kCACC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,EAAO,QAAQ,OAAA,EAAQ;AAAA,aAAA,EAC1D,CAAA;AAAA,gCACC,YAAA,EAAA,EAAS;AAAA,WAAA,EACZ,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,iBAAc,UAAA,EAAU,IAAA,EAAC,UAAA,EAAU,IAAA,EAAC,WAAU,YAAA,EAAa,CAAA;AAAA,4BAC5D,GAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAU,8BAAA,EAC1B,QAAA,kBAAA,GAAA,CAAC,OAAE,IAAA,EAAK,MAAA,EAAO,SAAA,EAAU,0CAAA,EAA2C,CAAA,EACtE;AAAA,WAAA,EACF;AAAA,SAAA,EACF,GACF,CAAA,EACF;AAAA;AAAA,KACF;AAAA,oBAGA,GAAA,CAAC,kBAAW,MAAA,EAAQ,gBAAA,EAAkB,SAAS,MAAM,mBAAA,CAAoB,KAAK,CAAA,EAAG,CAAA;AAAA,oBACjF,GAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAK,YAAA,EAAa;AAAA,GAAA,EAC9B,CAAA;AAEJ","file":"chunk-6QMYSKUE.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded navigation components\n * Use these for code-splitting navigation sections\n */\nexport const LazyMainMenu = lazy(() => import('./MainMenu').then((m) => ({ default: m.MainMenu })));\n\nexport const LazyMobileMenu = lazy(() =>\n import('./MobileMenu').then((m) => ({ default: m.MobileMenu }))\n);\n","import { useState } from 'react';\nimport { useIsHome } from '../../providers/NavigationProvider';\nimport { SallaAdvertisement } from '@salla.sa/twilight-components-react/advertisement';\nimport { SallaCartSummary } from '@salla.sa/twilight-components-react/cart-summary';\nimport { SallaContacts } from '@salla.sa/twilight-components-react/contacts';\nimport { SallaLocalizationModal } from '@salla.sa/twilight-components-react/localization-modal';\nimport { SallaMenu } from '@salla.sa/twilight-components-react/menu';\nimport { SallaSearch } from '@salla.sa/twilight-components-react/search';\nimport { SallaUserMenu } from '@salla.sa/twilight-components-react/user-menu';\nimport { useTwilight } from '../../providers/twilight-context';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { HookSlot } from '../../hooks/HookSlot';\nimport { MainMenu, MobileMenu } from '../navigation';\nimport { Image } from '../common';\nimport type { Cart } from '../../types';\n\ninterface HeaderProps {\n cart?: Cart;\n}\n\nexport function Header(_props: HeaderProps) {\n const { currency, theme, store } = useTwilight();\n const { locale, languageName } = useTranslation();\n const settings = theme?.settings || {};\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n\n // Check if we're on homepage\n const isHomepage = useIsHome();\n\n const StoreTitle = isHomepage ? 'h1' : 'span';\n\n return (\n <header className=\"store-header\" suppressHydrationWarning>\n <HookSlot name=\"header:start\" />\n <div className=\"advertisement-slot\">\n <SallaAdvertisement />\n </div>\n {/* Top Nav */}\n <div className={`top-navbar${settings.topnav_is_dark ? ' top-navbar--dark' : ''}`}>\n <div className=\"container flex justify-between\">\n <div className=\"flex-1 flex items-center gap-2\">\n {/* Footer Menu */}\n {settings.important_links && <SallaMenu source=\"footer\" topnav />}\n\n {/* Language & Currency */}\n <div className=\"header-buttons\">\n {(store?.settings?.is_multilingual || store?.settings?.currencies_enabled) && (\n <>\n <button\n type=\"button\"\n onClick={() => window.salla?.event.dispatch('localization::open')}\n className=\"btn--rounded-gray basis-0\"\n >\n <span>{languageName}</span>\n <span className=\"mx-1.5\">|</span>\n <span className={`flag iti__flag iti__${store?.country.toLowerCase()}`}></span>\n\n <span>\n {store?.settings?.use_sar_symbol && currency?.code === 'SAR' ? (\n <i className=\"sicon-sar\"></i>\n ) : (\n <>{currency?.symbol}</>\n )}\n </span>\n </button>\n {/* TODO:: support switch the lang without hit the web API, by set it in the sdk and local storage */}\n {/* TODO:: Support switch the curency without hit the web API, by set it in the sdk and local storage */}\n <SallaLocalizationModal\n language={locale}\n currency={currency?.code || 'SAR'}\n suppressHydrationWarning\n />\n </>\n )}\n </div>\n\n {/* Scopes / Branches */}\n {store?.scope && (\n <button\n type=\"button\"\n className=\"btn--rounded-gray\"\n onClick={() =>\n window.salla?.event.dispatch('scopes::open', {\n mode: 'default',\n })\n }\n >\n <i className=\"sicon-location rtl:ml-1 ltr:mr-1\"></i>\n {store.scope.name}\n </button>\n )}\n\n {/* Search bar */}\n <div className=\"header-search flex-1\">\n {/* todo:: use a search icon insted with open the search popup */}\n <SallaSearch inline oval height={36} />\n </div>\n </div>\n\n <SallaContacts contacts={store?.contacts} contactsTitle=\"N/A\" isHeader />\n </div>\n </div>\n\n {/* Main Nav */}\n <div\n id=\"mainnav\"\n className={`main-nav-container shadow-default bg-white flex items-center relative z-50${settings.header_is_sticky ? ' sticky top-0' : ''}`}\n >\n <div className=\"inner bg-inherit w-full\">\n <div className=\"container\">\n <div className=\"flex items-stretch justify-between relative\">\n <div className=\"flex items-center\">\n <a\n className=\"lg:hidden mburger mburger--collapse leading-none rtl:ml-4 ltr:mr-4\"\n href=\"#mobile-menu\"\n aria-label=\"Open-menu\"\n onClick={(e) => {\n e.preventDefault();\n setIsMobileMenuOpen(true);\n }}\n >\n <i className=\"sicon-menu text-primary text-2xl\"></i>\n </a>\n <a className=\"navbar-brand\" href={store?.url || '/'}>\n <div className=\"logo-wrapper\">\n <Image\n src={store?.logo}\n alt={`${store?.name || 'Store'} logo`}\n priority\n width={120}\n height={48}\n />\n </div>\n <StoreTitle className=\"sr-only\">{store?.name || 'Store'}</StoreTitle>\n </a>\n <MainMenu />\n </div>\n <div className=\"flex items-center justify-end my-2.5\">\n <SallaUserMenu avatarOnly showHeader className=\"header-btn\" />\n <SallaCartSummary className=\"ml-4 rtl:ml-[unset] rtl:mr-4\">\n <i slot=\"icon\" className=\"header-btn__icon icon sicon-shopping-bag\"></i>\n </SallaCartSummary>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Mobile Menu */}\n <MobileMenu isOpen={isMobileMenuOpen} onClose={() => setIsMobileMenuOpen(false)} />\n <HookSlot name=\"header:end\" />\n </header>\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RouteId } from './chunk-OUW6WESU.js';
|
|
2
|
-
import { getActiveScope } from './chunk-
|
|
3
|
-
import { withoutStoreUrlBase, extractScopeFromUrl } from './chunk-
|
|
2
|
+
import { getActiveScope } from './chunk-QGOPTVV5.js';
|
|
3
|
+
import { withoutStoreUrlBase, extractScopeFromUrl } from './chunk-HSWRYXC7.js';
|
|
4
4
|
import { subscribeTwilight, getTwilightContext } from './chunk-N2S25NXP.js';
|
|
5
5
|
import { useTwilight } from './chunk-DF6FBKDN.js';
|
|
6
6
|
import { createContext, createElement, useContext, useSyncExternalStore, useRef, useEffect, useCallback } from 'react';
|
|
@@ -282,5 +282,5 @@ function useNavigationInterceptor(navigate, storeUrl, username) {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
export { NavigationInterceptor, NavigationProvider, NotFoundError, RedirectError, UnauthorizedError, configureNavigation, defaultNavigate, notFound, orThrow, orUnauthorized, redirect, resolveRelativePath, unauthorized, useIsBlog, useIsBrands, useIsCart, useIsCustomer, useIsHome, useIsProduct, useIsSearch, useLocation, useNavigate, useRouteId };
|
|
285
|
-
//# sourceMappingURL=chunk-
|
|
286
|
-
//# sourceMappingURL=chunk-
|
|
285
|
+
//# sourceMappingURL=chunk-6ZMNTJM3.js.map
|
|
286
|
+
//# sourceMappingURL=chunk-6ZMNTJM3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/NavigationProvider.ts"],"names":[],"mappings":"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","file":"chunk-VPPSRRGK.js","sourcesContent":["import {\n createElement,\n createContext,\n useContext,\n useCallback,\n useRef,\n useEffect,\n useSyncExternalStore,\n type ReactNode,\n} from 'react';\nimport { useTwilight } from './twilight-context';\nimport { getTwilightContext, subscribeTwilight, type TwilightLocation } from '../twilight/context';\nimport { RouteId } from '../router/route-ids';\nimport { withoutStoreUrlBase } from '../utils/store-base';\nimport { extractScopeFromUrl } from '../utils/cookies';\nimport { getActiveScope } from '../api/client';\n\n// Re-export RouteId from centralized location\nexport { RouteId } from '../router/route-ids';\nexport type { RouteIdType } from '../router/route-ids';\n\n// Re-export TwilightLocation as Location for convenience\nexport type { TwilightLocation as Location } from '../twilight/context';\n\nexport type NavigateOptions = { replace?: boolean };\nexport type NavigateFn = (to: string, opts?: NavigateOptions) => void;\n\n/** Redirect error - thrown to trigger a redirect */\nexport class RedirectError extends Error {\n constructor(\n public path: string,\n public replace = false\n ) {\n super(`Redirect to ${path}`);\n this.name = 'RedirectError';\n }\n}\n\n/** NotFound error - thrown to trigger 404 */\nexport class NotFoundError extends Error {\n constructor(message?: string) {\n super(message ?? 'Not Found');\n this.name = 'NotFoundError';\n }\n}\n\n/** Unauthorized error - thrown to trigger 401 */\nexport class UnauthorizedError extends Error {\n constructor(message?: string) {\n super(message ?? 'Unauthorized');\n this.name = 'UnauthorizedError';\n }\n}\n\nexport { SettingsError } from '../utils/errors';\n\nexport const defaultNavigate: NavigateFn = (to, opts) => {\n if (opts?.replace) window.location.replace(to);\n else window.location.href = to;\n};\n\nexport interface RedirectOptions {\n replace?: boolean;\n /** HTTP status of a server redirect, e.g. 301 for a URL that moved for good. Defaults to 307. */\n statusCode?: number;\n}\n\n/** Default redirect - throws RedirectError with browser navigation as fallback */\nexport const defaultRedirect = (path: string, opts?: RedirectOptions): never => {\n const replace = opts?.replace ?? false;\n\n // In browser, perform actual navigation before throwing\n if (typeof window !== 'undefined') {\n if (replace) window.location.replace(path);\n else window.location.href = path;\n }\n\n throw new RedirectError(path, replace);\n};\n\n/** Default notFound - throws generic error */\nexport const defaultNotFound = (message?: string): never => {\n throw new NotFoundError(message);\n};\n\n/** Default unauthorized - throws generic error */\nexport const defaultUnauthorized = (message?: string): never => {\n throw new UnauthorizedError(message);\n};\n\n// ─── Framework-agnostic functions for loaders (outside React context) ──────\n\ninterface NavigationHandlers {\n notFound: (message?: string) => never;\n redirect: (path: string, opts?: RedirectOptions) => never;\n unauthorized: (message?: string) => never;\n}\n\n// One set per isolate, so a loader in another copy of this module (a separate\n// package entry, a dev reload) still throws what the framework adapter configured.\nconst HANDLERS_KEY = Symbol.for('salla.twilight.navigation.handlers');\nconst registry = globalThis as { [HANDLERS_KEY]?: NavigationHandlers };\nconst handlers: NavigationHandlers = (registry[HANDLERS_KEY] ??= {\n notFound: defaultNotFound,\n redirect: defaultRedirect,\n unauthorized: defaultUnauthorized,\n});\n\n/**\n * Throw a notFound error. Use in route loaders.\n * Framework adapters will override this to throw framework-specific errors.\n *\n * @example\n * ```ts\n * // In loader\n * import { notFound } from '@salla.sa/twilight-theme-engine/providers';\n *\n * if (!data) throw notFound();\n * ```\n */\nexport function notFound(message?: string): never {\n return handlers.notFound(message);\n}\n\n/**\n * Throw an unauthorized error. Use in route loaders to protect authenticated routes.\n * Framework adapters will override this to throw framework-specific errors.\n *\n * @example\n * ```ts\n * import { unauthorized } from '@salla.sa/twilight-theme-engine/providers';\n *\n * if (!user) throw unauthorized();\n * ```\n */\nexport function unauthorized(message?: string): never {\n return handlers.unauthorized(message);\n}\n\n/**\n * Throw a redirect. Use in route loaders.\n * Framework adapters will override this to throw framework-specific redirects.\n *\n * @param path - Path to redirect to\n * @param opts - Redirect options\n *\n * @example\n * ```ts\n * // In loader\n * import { redirect } from '@salla.sa/twilight-theme-engine/providers';\n *\n * throw redirect('/ar/cart');\n * ```\n */\nexport function redirect(path: string, opts?: RedirectOptions): never {\n return handlers.redirect(path, opts);\n}\n\n/**\n * Configure navigation functions for a specific framework.\n * Called by framework adapters during setup.\n */\nexport function configureNavigation(config: {\n notFound?: (message?: string) => never;\n redirect?: (path: string, opts?: RedirectOptions) => never;\n unauthorized?: (_message?: string) => never;\n}): void {\n if (config.notFound) handlers.notFound = config.notFound;\n if (config.redirect) handlers.redirect = config.redirect;\n if (config.unauthorized) handlers.unauthorized = config.unauthorized;\n}\n\n// ─── Loader Error Handling Helpers ─────────────────────────────────────────────\n\n/**\n * Wraps an API promise with error handling for route loaders.\n * On a 404/410 response throws notFound(); other errors propagate.\n *\n * @example\n * ```ts\n * findOrThrow: (id, locale) => orThrow(product.find(id, locale)),\n * const data = await product.findOrThrow(id, locale);\n * ```\n */\nexport async function orThrow<T>(promise: Promise<T>): Promise<T> {\n try {\n return await promise;\n } catch (error) {\n console.debug('[loader error]', error);\n const status = (error as unknown as { response?: { status?: number } })?.response?.status;\n // The API answers a missing resource with 410, sometimes 404.\n if (status === 404 || status === 410) return notFound();\n throw error;\n }\n}\n\n/**\n * Wraps an API promise with error handling for authenticated route loaders.\n * On a 401/403 response throws unauthorized(); other errors propagate.\n *\n * @example\n * ```ts\n * const data = await orUnauthorized(order.find(id, locale));\n * ```\n */\nexport async function orUnauthorized<T>(promise: Promise<T>): Promise<T> {\n try {\n return await promise;\n } catch (error) {\n const status = (error as unknown as { response?: { status?: number } })?.response?.status;\n if (status === 401 || status === 403) {\n throw unauthorized();\n }\n throw error;\n }\n}\n\n// ─── Navigation Context ──────────────────────────────────────────────────────\n\ninterface NavigationContextValue {\n navigate: NavigateFn;\n}\n\nconst NavigationContext = createContext<NavigationContextValue>({\n navigate: defaultNavigate,\n});\n\nexport function NavigationProvider({\n navigate,\n children,\n}: {\n navigate: NavigateFn;\n children: ReactNode;\n}) {\n return createElement(NavigationContext.Provider, { value: { navigate } }, children);\n}\n\n// ─── Primary Hooks (High Compatibility) ───────────────────────────────────────\n\n/**\n * Get the navigate function.\n * Matches React Router, TanStack Router, and Remix naming convention.\n *\n * @returns Navigate function\n *\n * @example\n * ```tsx\n * const navigate = useNavigate();\n * navigate('/cart');\n * navigate('/cart', { replace: true });\n * ```\n */\nexport function useNavigate(): NavigateFn {\n return useContext(NavigationContext).navigate;\n}\n\n/**\n * Get the current route ID.\n * Used for route detection (isHome, isProduct, etc.)\n *\n * @returns Current route ID string\n *\n * @example\n * ```tsx\n * const routeId = useRouteId();\n * if (routeId === RouteId.INDEX) { ... }\n * ```\n */\nexport function useRouteId(): string {\n return useSyncExternalStore(\n subscribeTwilight,\n () => getTwilightContext().routeId,\n () => getTwilightContext().routeId\n );\n}\n\n/**\n * Get the current location (TanStack Router compatible).\n * Reads from the router context for SSR compatibility.\n *\n * @returns Location object matching TanStack's ParsedLocation\n *\n * @example\n * ```tsx\n * const location = useLocation();\n * console.log(location.pathname); // '/ar/products'\n * console.log(location.searchStr); // '?q=shoes&page=2'\n * console.log(location.search); // { q: 'shoes', page: '2' }\n * console.log(location.href); // 'https://store.com/ar/products?q=shoes'\n * console.log(location.hash); // '#section-1'\n * console.log(location.state); // { scrollY: 100 }\n * ```\n */\nexport function useLocation<TSearch = Record<string, unknown>>(): TwilightLocation<TSearch> {\n useTwilight();\n return getTwilightContext().location as TwilightLocation<TSearch>;\n}\n\n// ─── Selector Hooks ───────────────────────────────────────────────────────────\n\n/**\n * Check if current page is homepage */\nexport function useIsHome(): boolean {\n return useRouteId() === RouteId.INDEX;\n}\n\n/** Check if current page is product detail */\nexport function useIsProduct(): boolean {\n return useRouteId() === RouteId.PRODUCT_SINGLE;\n}\n\n/** Check if current page is cart */\nexport function useIsCart(): boolean {\n return useRouteId() === RouteId.CART;\n}\n\n/** Check if current page is in customer area */\nexport function useIsCustomer(): boolean {\n return useRouteId().startsWith('customer');\n}\n\n/** Check if current page is blog related */\nexport function useIsBlog(): boolean {\n const routeId = useRouteId();\n return routeId === RouteId.BLOG_INDEX || routeId === RouteId.BLOG_SINGLE;\n}\n\n/** Check if current page is brands related */\nexport function useIsBrands(): boolean {\n const routeId = useRouteId();\n return routeId === RouteId.BRANDS_INDEX || routeId === RouteId.BRANDS_SINGLE;\n}\n\n/** Check if current page is search */\nexport function useIsSearch(): boolean {\n return useRouteId() === RouteId.SEARCH;\n}\n\n// ─── Navigation Interceptor ──────────────────────────────────────────────────\n\n/**\n * NavigationInterceptor - Framework-agnostic SPA navigation interceptor.\n *\n * Uses navigate function from NavigationProvider context and store URL\n * from TwilightProvider to intercept same-origin navigations.\n */\nexport function NavigationInterceptor(): null {\n const navigate = useNavigate();\n const { store } = useTwilight();\n useNavigationInterceptor(navigate, store?.url, store?.username);\n return null;\n}\n\n/**\n * resolveRelativePath - Resolve href to store-relative path\n *\n * Returns `null` when the URL is not on the same origin as the store,\n * keeping this helper safe against open-redirect misuse.\n *\n * The path is the application's, not the address on Salla's host: a store served\n * under its username there (`https://demostore.salla.sa/ar/dev-…/`) hands out links\n * carrying that segment, and it is removed. On a host where the store is the root\n * of every URL, the router adds its own segment back when it navigates.\n *\n * @param href - The URL to resolve\n * @param storeUrl - The store's base URL\n * @param username - The store's username, which tells that segment apart from a\n * locale spelled the same way (see `withoutStoreUrlBase`)\n * @returns The relative path string, or null if the URL is external\n */\nexport function resolveRelativePath(\n href: string,\n storeUrl: string,\n username?: string | null\n): string | null {\n try {\n const target = new URL(href, window.location.href);\n const base = new URL(storeUrl);\n\n if (target.origin !== base.origin) return null;\n\n const pathname = withoutStoreUrlBase(target.pathname, base.pathname, username);\n const path = pathname + target.search + target.hash;\n return path || '/';\n } catch {\n return null;\n }\n}\n\n/**\n * EXTERNAL_TARGETS - Target attribute values that indicate external navigation\n */\nconst EXTERNAL_TARGETS = new Set(['_blank', '_parent', '_top']);\n\n/**\n * shouldIntercept - Determine if an anchor click should be intercepted by SPA router\n *\n * Follows browser conventions: modifier keys, external targets, downloads,\n * and non-HTTP(S) protocols are left to the browser's default behavior.\n *\n * @param anchor - The anchor element that was clicked\n * @param event - The click event\n * @returns true if the click should be intercepted by the router\n */\nexport function shouldIntercept(anchor: HTMLAnchorElement, event: MouseEvent): boolean {\n if (event.defaultPrevented) return false;\n\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false;\n\n const targetAttr = anchor.getAttribute('target');\n if (targetAttr && EXTERNAL_TARGETS.has(targetAttr)) return false;\n\n if (anchor.hasAttribute('download')) return false;\n\n const rel = (anchor.getAttribute('rel') ?? '').split(/\\s+/);\n if (rel.includes('external')) return false;\n\n const href = anchor.getAttribute('href') ?? '';\n if (!href) return false;\n\n try {\n const url = new URL(href, window.location.href);\n if (url.protocol.startsWith('javascript:')) return false;\n } catch {\n return false;\n }\n\n return true;\n}\n\n/**\n * Whether `href` switches market: its `?scope=` names another scope than the active one,\n * or the same scope with another branch (`allocation_type` / `allocation_id`).\n *\n * Twig switches market with a full load (the SDK's scopes modal calls\n * `location.replace('?scope=<id>')`), and only a document request lets the server render\n * the new market and record it in the `scope` cookie. Left to the browser, not the router.\n */\nexport function switchesScope(href: string): boolean {\n let url: URL;\n try {\n url = new URL(href, window.location.href);\n } catch {\n return false;\n }\n const requested = extractScopeFromUrl(url.href);\n if (!requested) return false;\n const active = getActiveScope();\n if (requested.id !== active?.id) return true;\n return (\n requested.allocation_id != null &&\n (requested.allocation_id !== active.allocation_id ||\n requested.allocation_type !== active.allocation_type)\n );\n}\n\nfunction isSamePage(href: string): boolean {\n const url = new URL(href, window.location.href);\n return url.pathname === window.location.pathname && url.search === window.location.search;\n}\n\nfunction closeEnclosingModal(path: EventTarget[]): void {\n const modal = path.find(\n (el): el is HTMLElement & { close?: () => unknown } =>\n el instanceof HTMLElement && el.localName === 'salla-modal'\n );\n void modal?.close?.();\n}\n\n// ─── Navigation Interceptor Hook (framework-agnostic) ─────────────────────────\n\n/**\n * Hook for navigation interception using framework-agnostic navigate function.\n * Framework adapters call this with their navigate implementation.\n */\nexport function useNavigationInterceptor(\n navigate: NavigateFn,\n storeUrl: string | undefined,\n username?: string\n): void {\n const storeUrlRef = useRef<string | undefined>(storeUrl);\n const usernameRef = useRef<string | undefined>(username);\n\n useEffect(() => {\n storeUrlRef.current = storeUrl;\n usernameRef.current = username;\n }, [storeUrl, username]);\n\n const tryNavigate = useCallback(\n (href: string, replace = false): boolean => {\n const currentStoreUrl = storeUrlRef.current;\n if (!currentStoreUrl || switchesScope(href)) return false;\n\n const relativePath = resolveRelativePath(href, currentStoreUrl, usernameRef.current);\n if (!relativePath) return false;\n\n navigate(relativePath, { replace });\n return true;\n },\n [navigate]\n );\n\n useEffect(() => {\n // ── Pointer movement tracking ────────────────────────────────────────────\n // Detect drag/scroll gestures to avoid intercepting clicks from swipes.\n let pointerStartX = 0;\n let pointerStartY = 0;\n let pointerSwiped = false;\n const MOVE_THRESHOLD = 10;\n\n function handlePointerDown(event: PointerEvent): void {\n pointerStartX = event.clientX;\n pointerStartY = event.clientY;\n pointerSwiped = false;\n }\n\n function handlePointerUp(event: PointerEvent): void {\n const dx = Math.abs(event.clientX - pointerStartX);\n const dy = Math.abs(event.clientY - pointerStartY);\n pointerSwiped = dx > MOVE_THRESHOLD || dy > MOVE_THRESHOLD;\n }\n\n // ── Anchor click interception ────────────────────────────────────────────\n function handleClick(event: MouseEvent): void {\n // Ignore clicks that resulted from swipe/drag gestures.\n if (pointerSwiped) {\n pointerSwiped = false;\n return;\n }\n\n const path = event.composedPath();\n const anchor = path.find((el): el is HTMLAnchorElement => el instanceof HTMLAnchorElement);\n\n if (!anchor || !shouldIntercept(anchor, event)) return;\n\n const samePage = isSamePage(anchor.href);\n if (tryNavigate(anchor.href, false)) {\n event.preventDefault();\n // A page load would close a web component's modal; an in-app navigation leaves it open.\n if (!samePage) closeEnclosingModal(path);\n }\n }\n\n // ── window.location.assign patch ─────────────────────────────────────────\n const origAssign = window.location.assign;\n function patchedAssign(url: string): void {\n if (!tryNavigate(url, false)) origAssign.call(window.location, url);\n }\n\n // ── window.location.replace patch ────────────────────────────────────────\n const origReplace = window.location.replace;\n function patchedReplace(url: string): void {\n if (!tryNavigate(url, true)) origReplace.call(window.location, url);\n }\n\n let assignPatched = false;\n let replacePatched = false;\n try {\n window.location.assign = patchedAssign;\n assignPatched = true;\n } catch {\n /* non-writable in this environment */\n }\n try {\n window.location.replace = patchedReplace;\n replacePatched = true;\n } catch {\n /* non-writable in this environment */\n }\n\n document.addEventListener('click', handleClick, { capture: true });\n document.addEventListener('pointerdown', handlePointerDown, { passive: true });\n document.addEventListener('pointerup', handlePointerUp, { passive: true });\n\n return () => {\n document.removeEventListener('click', handleClick, { capture: true });\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('pointerup', handlePointerUp);\n if (assignPatched) {\n try {\n window.location.assign = origAssign;\n } catch {\n /* ignore */\n }\n }\n if (replacePatched) {\n try {\n window.location.replace = origReplace;\n } catch {\n /* ignore */\n }\n }\n };\n }, [tryNavigate]);\n}\n\n// ─── Client navigation config ─────────────────────────────────────────────────\n\nexport interface ClientNav {\n /** Framework adapter to use for client-side navigation. @default 'tanstack' */\n framework?: 'tanstack' | 'nextjs';\n /**\n * Intercept same-origin `<a>` clicks and `window.location` calls from web\n * components and route them through the framework router.\n * @default true\n */\n interceptLinks?: boolean;\n}\n\n// Framework adapter setups are registered in navigation-setups.ts to avoid circular imports.\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/providers/NavigationProvider.ts"],"names":[],"mappings":"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","file":"chunk-6ZMNTJM3.js","sourcesContent":["import {\n createElement,\n createContext,\n useContext,\n useCallback,\n useRef,\n useEffect,\n useSyncExternalStore,\n type ReactNode,\n} from 'react';\nimport { useTwilight } from './twilight-context';\nimport { getTwilightContext, subscribeTwilight, type TwilightLocation } from '../twilight/context';\nimport { RouteId } from '../router/route-ids';\nimport { withoutStoreUrlBase } from '../utils/store-base';\nimport { extractScopeFromUrl } from '../utils/cookies';\nimport { getActiveScope } from '../api/client';\n\n// Re-export RouteId from centralized location\nexport { RouteId } from '../router/route-ids';\nexport type { RouteIdType } from '../router/route-ids';\n\n// Re-export TwilightLocation as Location for convenience\nexport type { TwilightLocation as Location } from '../twilight/context';\n\nexport type NavigateOptions = { replace?: boolean };\nexport type NavigateFn = (to: string, opts?: NavigateOptions) => void;\n\n/** Redirect error - thrown to trigger a redirect */\nexport class RedirectError extends Error {\n constructor(\n public path: string,\n public replace = false\n ) {\n super(`Redirect to ${path}`);\n this.name = 'RedirectError';\n }\n}\n\n/** NotFound error - thrown to trigger 404 */\nexport class NotFoundError extends Error {\n constructor(message?: string) {\n super(message ?? 'Not Found');\n this.name = 'NotFoundError';\n }\n}\n\n/** Unauthorized error - thrown to trigger 401 */\nexport class UnauthorizedError extends Error {\n constructor(message?: string) {\n super(message ?? 'Unauthorized');\n this.name = 'UnauthorizedError';\n }\n}\n\nexport { SettingsError } from '../utils/errors';\n\nexport const defaultNavigate: NavigateFn = (to, opts) => {\n if (opts?.replace) window.location.replace(to);\n else window.location.href = to;\n};\n\nexport interface RedirectOptions {\n replace?: boolean;\n /** HTTP status of a server redirect, e.g. 301 for a URL that moved for good. Defaults to 307. */\n statusCode?: number;\n}\n\n/** Default redirect - throws RedirectError with browser navigation as fallback */\nexport const defaultRedirect = (path: string, opts?: RedirectOptions): never => {\n const replace = opts?.replace ?? false;\n\n // In browser, perform actual navigation before throwing\n if (typeof window !== 'undefined') {\n if (replace) window.location.replace(path);\n else window.location.href = path;\n }\n\n throw new RedirectError(path, replace);\n};\n\n/** Default notFound - throws generic error */\nexport const defaultNotFound = (message?: string): never => {\n throw new NotFoundError(message);\n};\n\n/** Default unauthorized - throws generic error */\nexport const defaultUnauthorized = (message?: string): never => {\n throw new UnauthorizedError(message);\n};\n\n// ─── Framework-agnostic functions for loaders (outside React context) ──────\n\ninterface NavigationHandlers {\n notFound: (message?: string) => never;\n redirect: (path: string, opts?: RedirectOptions) => never;\n unauthorized: (message?: string) => never;\n}\n\n// One set per isolate, so a loader in another copy of this module (a separate\n// package entry, a dev reload) still throws what the framework adapter configured.\nconst HANDLERS_KEY = Symbol.for('salla.twilight.navigation.handlers');\nconst registry = globalThis as { [HANDLERS_KEY]?: NavigationHandlers };\nconst handlers: NavigationHandlers = (registry[HANDLERS_KEY] ??= {\n notFound: defaultNotFound,\n redirect: defaultRedirect,\n unauthorized: defaultUnauthorized,\n});\n\n/**\n * Throw a notFound error. Use in route loaders.\n * Framework adapters will override this to throw framework-specific errors.\n *\n * @example\n * ```ts\n * // In loader\n * import { notFound } from '@salla.sa/twilight-theme-engine/providers';\n *\n * if (!data) throw notFound();\n * ```\n */\nexport function notFound(message?: string): never {\n return handlers.notFound(message);\n}\n\n/**\n * Throw an unauthorized error. Use in route loaders to protect authenticated routes.\n * Framework adapters will override this to throw framework-specific errors.\n *\n * @example\n * ```ts\n * import { unauthorized } from '@salla.sa/twilight-theme-engine/providers';\n *\n * if (!user) throw unauthorized();\n * ```\n */\nexport function unauthorized(message?: string): never {\n return handlers.unauthorized(message);\n}\n\n/**\n * Throw a redirect. Use in route loaders.\n * Framework adapters will override this to throw framework-specific redirects.\n *\n * @param path - Path to redirect to\n * @param opts - Redirect options\n *\n * @example\n * ```ts\n * // In loader\n * import { redirect } from '@salla.sa/twilight-theme-engine/providers';\n *\n * throw redirect('/ar/cart');\n * ```\n */\nexport function redirect(path: string, opts?: RedirectOptions): never {\n return handlers.redirect(path, opts);\n}\n\n/**\n * Configure navigation functions for a specific framework.\n * Called by framework adapters during setup.\n */\nexport function configureNavigation(config: {\n notFound?: (message?: string) => never;\n redirect?: (path: string, opts?: RedirectOptions) => never;\n unauthorized?: (_message?: string) => never;\n}): void {\n if (config.notFound) handlers.notFound = config.notFound;\n if (config.redirect) handlers.redirect = config.redirect;\n if (config.unauthorized) handlers.unauthorized = config.unauthorized;\n}\n\n// ─── Loader Error Handling Helpers ─────────────────────────────────────────────\n\n/**\n * Wraps an API promise with error handling for route loaders.\n * On a 404/410 response throws notFound(); other errors propagate.\n *\n * @example\n * ```ts\n * findOrThrow: (id, locale) => orThrow(product.find(id, locale)),\n * const data = await product.findOrThrow(id, locale);\n * ```\n */\nexport async function orThrow<T>(promise: Promise<T>): Promise<T> {\n try {\n return await promise;\n } catch (error) {\n console.debug('[loader error]', error);\n const status = (error as unknown as { response?: { status?: number } })?.response?.status;\n // The API answers a missing resource with 410, sometimes 404.\n if (status === 404 || status === 410) return notFound();\n throw error;\n }\n}\n\n/**\n * Wraps an API promise with error handling for authenticated route loaders.\n * On a 401/403 response throws unauthorized(); other errors propagate.\n *\n * @example\n * ```ts\n * const data = await orUnauthorized(order.find(id, locale));\n * ```\n */\nexport async function orUnauthorized<T>(promise: Promise<T>): Promise<T> {\n try {\n return await promise;\n } catch (error) {\n const status = (error as unknown as { response?: { status?: number } })?.response?.status;\n if (status === 401 || status === 403) {\n throw unauthorized();\n }\n throw error;\n }\n}\n\n// ─── Navigation Context ──────────────────────────────────────────────────────\n\ninterface NavigationContextValue {\n navigate: NavigateFn;\n}\n\nconst NavigationContext = createContext<NavigationContextValue>({\n navigate: defaultNavigate,\n});\n\nexport function NavigationProvider({\n navigate,\n children,\n}: {\n navigate: NavigateFn;\n children: ReactNode;\n}) {\n return createElement(NavigationContext.Provider, { value: { navigate } }, children);\n}\n\n// ─── Primary Hooks (High Compatibility) ───────────────────────────────────────\n\n/**\n * Get the navigate function.\n * Matches React Router, TanStack Router, and Remix naming convention.\n *\n * @returns Navigate function\n *\n * @example\n * ```tsx\n * const navigate = useNavigate();\n * navigate('/cart');\n * navigate('/cart', { replace: true });\n * ```\n */\nexport function useNavigate(): NavigateFn {\n return useContext(NavigationContext).navigate;\n}\n\n/**\n * Get the current route ID.\n * Used for route detection (isHome, isProduct, etc.)\n *\n * @returns Current route ID string\n *\n * @example\n * ```tsx\n * const routeId = useRouteId();\n * if (routeId === RouteId.INDEX) { ... }\n * ```\n */\nexport function useRouteId(): string {\n return useSyncExternalStore(\n subscribeTwilight,\n () => getTwilightContext().routeId,\n () => getTwilightContext().routeId\n );\n}\n\n/**\n * Get the current location (TanStack Router compatible).\n * Reads from the router context for SSR compatibility.\n *\n * @returns Location object matching TanStack's ParsedLocation\n *\n * @example\n * ```tsx\n * const location = useLocation();\n * console.log(location.pathname); // '/ar/products'\n * console.log(location.searchStr); // '?q=shoes&page=2'\n * console.log(location.search); // { q: 'shoes', page: '2' }\n * console.log(location.href); // 'https://store.com/ar/products?q=shoes'\n * console.log(location.hash); // '#section-1'\n * console.log(location.state); // { scrollY: 100 }\n * ```\n */\nexport function useLocation<TSearch = Record<string, unknown>>(): TwilightLocation<TSearch> {\n useTwilight();\n return getTwilightContext().location as TwilightLocation<TSearch>;\n}\n\n// ─── Selector Hooks ───────────────────────────────────────────────────────────\n\n/**\n * Check if current page is homepage */\nexport function useIsHome(): boolean {\n return useRouteId() === RouteId.INDEX;\n}\n\n/** Check if current page is product detail */\nexport function useIsProduct(): boolean {\n return useRouteId() === RouteId.PRODUCT_SINGLE;\n}\n\n/** Check if current page is cart */\nexport function useIsCart(): boolean {\n return useRouteId() === RouteId.CART;\n}\n\n/** Check if current page is in customer area */\nexport function useIsCustomer(): boolean {\n return useRouteId().startsWith('customer');\n}\n\n/** Check if current page is blog related */\nexport function useIsBlog(): boolean {\n const routeId = useRouteId();\n return routeId === RouteId.BLOG_INDEX || routeId === RouteId.BLOG_SINGLE;\n}\n\n/** Check if current page is brands related */\nexport function useIsBrands(): boolean {\n const routeId = useRouteId();\n return routeId === RouteId.BRANDS_INDEX || routeId === RouteId.BRANDS_SINGLE;\n}\n\n/** Check if current page is search */\nexport function useIsSearch(): boolean {\n return useRouteId() === RouteId.SEARCH;\n}\n\n// ─── Navigation Interceptor ──────────────────────────────────────────────────\n\n/**\n * NavigationInterceptor - Framework-agnostic SPA navigation interceptor.\n *\n * Uses navigate function from NavigationProvider context and store URL\n * from TwilightProvider to intercept same-origin navigations.\n */\nexport function NavigationInterceptor(): null {\n const navigate = useNavigate();\n const { store } = useTwilight();\n useNavigationInterceptor(navigate, store?.url, store?.username);\n return null;\n}\n\n/**\n * resolveRelativePath - Resolve href to store-relative path\n *\n * Returns `null` when the URL is not on the same origin as the store,\n * keeping this helper safe against open-redirect misuse.\n *\n * The path is the application's, not the address on Salla's host: a store served\n * under its username there (`https://demostore.salla.sa/ar/dev-…/`) hands out links\n * carrying that segment, and it is removed. On a host where the store is the root\n * of every URL, the router adds its own segment back when it navigates.\n *\n * @param href - The URL to resolve\n * @param storeUrl - The store's base URL\n * @param username - The store's username, which tells that segment apart from a\n * locale spelled the same way (see `withoutStoreUrlBase`)\n * @returns The relative path string, or null if the URL is external\n */\nexport function resolveRelativePath(\n href: string,\n storeUrl: string,\n username?: string | null\n): string | null {\n try {\n const target = new URL(href, window.location.href);\n const base = new URL(storeUrl);\n\n if (target.origin !== base.origin) return null;\n\n const pathname = withoutStoreUrlBase(target.pathname, base.pathname, username);\n const path = pathname + target.search + target.hash;\n return path || '/';\n } catch {\n return null;\n }\n}\n\n/**\n * EXTERNAL_TARGETS - Target attribute values that indicate external navigation\n */\nconst EXTERNAL_TARGETS = new Set(['_blank', '_parent', '_top']);\n\n/**\n * shouldIntercept - Determine if an anchor click should be intercepted by SPA router\n *\n * Follows browser conventions: modifier keys, external targets, downloads,\n * and non-HTTP(S) protocols are left to the browser's default behavior.\n *\n * @param anchor - The anchor element that was clicked\n * @param event - The click event\n * @returns true if the click should be intercepted by the router\n */\nexport function shouldIntercept(anchor: HTMLAnchorElement, event: MouseEvent): boolean {\n if (event.defaultPrevented) return false;\n\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false;\n\n const targetAttr = anchor.getAttribute('target');\n if (targetAttr && EXTERNAL_TARGETS.has(targetAttr)) return false;\n\n if (anchor.hasAttribute('download')) return false;\n\n const rel = (anchor.getAttribute('rel') ?? '').split(/\\s+/);\n if (rel.includes('external')) return false;\n\n const href = anchor.getAttribute('href') ?? '';\n if (!href) return false;\n\n try {\n const url = new URL(href, window.location.href);\n if (url.protocol.startsWith('javascript:')) return false;\n } catch {\n return false;\n }\n\n return true;\n}\n\n/**\n * Whether `href` switches market: its `?scope=` names another scope than the active one,\n * or the same scope with another branch (`allocation_type` / `allocation_id`).\n *\n * Twig switches market with a full load (the SDK's scopes modal calls\n * `location.replace('?scope=<id>')`), and only a document request lets the server render\n * the new market and record it in the `scope` cookie. Left to the browser, not the router.\n */\nexport function switchesScope(href: string): boolean {\n let url: URL;\n try {\n url = new URL(href, window.location.href);\n } catch {\n return false;\n }\n const requested = extractScopeFromUrl(url.href);\n if (!requested) return false;\n const active = getActiveScope();\n if (requested.id !== active?.id) return true;\n return (\n requested.allocation_id != null &&\n (requested.allocation_id !== active.allocation_id ||\n requested.allocation_type !== active.allocation_type)\n );\n}\n\nfunction isSamePage(href: string): boolean {\n const url = new URL(href, window.location.href);\n return url.pathname === window.location.pathname && url.search === window.location.search;\n}\n\nfunction closeEnclosingModal(path: EventTarget[]): void {\n const modal = path.find(\n (el): el is HTMLElement & { close?: () => unknown } =>\n el instanceof HTMLElement && el.localName === 'salla-modal'\n );\n void modal?.close?.();\n}\n\n// ─── Navigation Interceptor Hook (framework-agnostic) ─────────────────────────\n\n/**\n * Hook for navigation interception using framework-agnostic navigate function.\n * Framework adapters call this with their navigate implementation.\n */\nexport function useNavigationInterceptor(\n navigate: NavigateFn,\n storeUrl: string | undefined,\n username?: string\n): void {\n const storeUrlRef = useRef<string | undefined>(storeUrl);\n const usernameRef = useRef<string | undefined>(username);\n\n useEffect(() => {\n storeUrlRef.current = storeUrl;\n usernameRef.current = username;\n }, [storeUrl, username]);\n\n const tryNavigate = useCallback(\n (href: string, replace = false): boolean => {\n const currentStoreUrl = storeUrlRef.current;\n if (!currentStoreUrl || switchesScope(href)) return false;\n\n const relativePath = resolveRelativePath(href, currentStoreUrl, usernameRef.current);\n if (!relativePath) return false;\n\n navigate(relativePath, { replace });\n return true;\n },\n [navigate]\n );\n\n useEffect(() => {\n // ── Pointer movement tracking ────────────────────────────────────────────\n // Detect drag/scroll gestures to avoid intercepting clicks from swipes.\n let pointerStartX = 0;\n let pointerStartY = 0;\n let pointerSwiped = false;\n const MOVE_THRESHOLD = 10;\n\n function handlePointerDown(event: PointerEvent): void {\n pointerStartX = event.clientX;\n pointerStartY = event.clientY;\n pointerSwiped = false;\n }\n\n function handlePointerUp(event: PointerEvent): void {\n const dx = Math.abs(event.clientX - pointerStartX);\n const dy = Math.abs(event.clientY - pointerStartY);\n pointerSwiped = dx > MOVE_THRESHOLD || dy > MOVE_THRESHOLD;\n }\n\n // ── Anchor click interception ────────────────────────────────────────────\n function handleClick(event: MouseEvent): void {\n // Ignore clicks that resulted from swipe/drag gestures.\n if (pointerSwiped) {\n pointerSwiped = false;\n return;\n }\n\n const path = event.composedPath();\n const anchor = path.find((el): el is HTMLAnchorElement => el instanceof HTMLAnchorElement);\n\n if (!anchor || !shouldIntercept(anchor, event)) return;\n\n const samePage = isSamePage(anchor.href);\n if (tryNavigate(anchor.href, false)) {\n event.preventDefault();\n // A page load would close a web component's modal; an in-app navigation leaves it open.\n if (!samePage) closeEnclosingModal(path);\n }\n }\n\n // ── window.location.assign patch ─────────────────────────────────────────\n const origAssign = window.location.assign;\n function patchedAssign(url: string): void {\n if (!tryNavigate(url, false)) origAssign.call(window.location, url);\n }\n\n // ── window.location.replace patch ────────────────────────────────────────\n const origReplace = window.location.replace;\n function patchedReplace(url: string): void {\n if (!tryNavigate(url, true)) origReplace.call(window.location, url);\n }\n\n let assignPatched = false;\n let replacePatched = false;\n try {\n window.location.assign = patchedAssign;\n assignPatched = true;\n } catch {\n /* non-writable in this environment */\n }\n try {\n window.location.replace = patchedReplace;\n replacePatched = true;\n } catch {\n /* non-writable in this environment */\n }\n\n document.addEventListener('click', handleClick, { capture: true });\n document.addEventListener('pointerdown', handlePointerDown, { passive: true });\n document.addEventListener('pointerup', handlePointerUp, { passive: true });\n\n return () => {\n document.removeEventListener('click', handleClick, { capture: true });\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('pointerup', handlePointerUp);\n if (assignPatched) {\n try {\n window.location.assign = origAssign;\n } catch {\n /* ignore */\n }\n }\n if (replacePatched) {\n try {\n window.location.replace = origReplace;\n } catch {\n /* ignore */\n }\n }\n };\n }, [tryNavigate]);\n}\n\n// ─── Client navigation config ─────────────────────────────────────────────────\n\nexport interface ClientNav {\n /** Framework adapter to use for client-side navigation. @default 'tanstack' */\n framework?: 'tanstack' | 'nextjs';\n /**\n * Intercept same-origin `<a>` clicks and `window.location` calls from web\n * components and route them through the framework router.\n * @default true\n */\n interceptLinks?: boolean;\n}\n\n// Framework adapter setups are registered in navigation-setups.ts to avoid circular imports.\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
2
|
-
import { api } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-6ZMNTJM3.js';
|
|
2
|
+
import { api } from './chunk-QGOPTVV5.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
5
5
|
var brand = {
|
|
@@ -25,5 +25,5 @@ var brand = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export { brand };
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
28
|
+
//# sourceMappingURL=chunk-7X4XGKXO.js.map
|
|
29
|
+
//# sourceMappingURL=chunk-7X4XGKXO.js.map
|