@salla.sa/twilight-theme-engine 1.0.119 → 1.0.122
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-2E25Z3JH.js → AddToCartForm-4Z6BBSU4.js} +3 -3
- package/dist/{AddToCartForm-2E25Z3JH.js.map → AddToCartForm-4Z6BBSU4.js.map} +1 -1
- package/dist/{BlogAuthorPage-DIQMXVKT.js → BlogAuthorPage-GIQL4YX6.js} +17 -16
- package/dist/BlogAuthorPage-GIQL4YX6.js.map +1 -0
- package/dist/{BlogCategoryPage-CIEC3I3C.js → BlogCategoryPage-UELJFSB2.js} +17 -16
- package/dist/BlogCategoryPage-UELJFSB2.js.map +1 -0
- package/dist/{BlogPage-SRBQBKLP.js → BlogPage-G6LPLQRM.js} +15 -14
- package/dist/BlogPage-G6LPLQRM.js.map +1 -0
- package/dist/{BlogSinglePage-5BD3OVXK.js → BlogSinglePage-SVTO3C5D.js} +15 -14
- package/dist/BlogSinglePage-SVTO3C5D.js.map +1 -0
- package/dist/{BlogTagPage-ZCDTNTKI.js → BlogTagPage-CFXXPULN.js} +17 -16
- package/dist/BlogTagPage-CFXXPULN.js.map +1 -0
- package/dist/{BrandsPage-XHWYHEQS.js → BrandsPage-IC26RKIG.js} +16 -15
- package/dist/BrandsPage-IC26RKIG.js.map +1 -0
- package/dist/{Breadcrumb-OODSTILO.js → Breadcrumb-OI2H6GVZ.js} +15 -14
- package/dist/Breadcrumb-OI2H6GVZ.js.map +1 -0
- package/dist/{CartItem-N7PX7K6E.js → CartItem-HTEPMUDS.js} +15 -14
- package/dist/CartItem-HTEPMUDS.js.map +1 -0
- package/dist/{CartSummary-FVM26G2M.js → CartSummary-OKLYOGJ3.js} +15 -14
- package/dist/CartSummary-OKLYOGJ3.js.map +1 -0
- package/dist/{Copyright-JCBJN5YN.js → Copyright-EJW3DGP7.js} +3 -3
- package/dist/{Copyright-JCBJN5YN.js.map → Copyright-EJW3DGP7.js.map} +1 -1
- package/dist/{CustomerLayout-B3W377Y4.js → CustomerLayout-YADC5GF7.js} +15 -14
- package/dist/CustomerLayout-YADC5GF7.js.map +1 -0
- package/dist/{Footer-JYJDPUSD.js → Footer-XJJIN5T3.js} +4 -4
- package/dist/{Footer-JYJDPUSD.js.map → Footer-XJJIN5T3.js.map} +1 -1
- package/dist/{Header-DETRFG6N.js → Header-WCRFWQIF.js} +8 -8
- package/dist/{Header-DETRFG6N.js.map → Header-WCRFWQIF.js.map} +1 -1
- package/dist/LiveEditorBar-6SKEWJOX.js +338 -0
- package/dist/LiveEditorBar-6SKEWJOX.js.map +1 -0
- package/dist/{LoyaltyPage-UBYNGW6Z.js → LoyaltyPage-CVNIZVMT.js} +15 -14
- package/dist/LoyaltyPage-CVNIZVMT.js.map +1 -0
- package/dist/{LoyaltyPointsPage-OMCCDBLI.js → LoyaltyPointsPage-UZT7LR5E.js} +6 -6
- package/dist/{LoyaltyPointsPage-OMCCDBLI.js.map → LoyaltyPointsPage-UZT7LR5E.js.map} +1 -1
- package/dist/{MainMenu-BNVH3EVF.js → MainMenu-T2OXHLEM.js} +5 -5
- package/dist/{MainMenu-BNVH3EVF.js.map → MainMenu-T2OXHLEM.js.map} +1 -1
- package/dist/{MasterLayout-OLB2JUUR.js → MasterLayout-MLEDURJK.js} +15 -14
- package/dist/{MasterLayout-OLB2JUUR.js.map → MasterLayout-MLEDURJK.js.map} +1 -1
- package/dist/{MobileMenu-2EAPAHX5.js → MobileMenu-RYICFJPO.js} +16 -15
- package/dist/MobileMenu-RYICFJPO.js.map +1 -0
- package/dist/{NotificationsPage-PIQJTEHJ.js → NotificationsPage-J2YNZPAN.js} +15 -14
- package/dist/NotificationsPage-J2YNZPAN.js.map +1 -0
- package/dist/{OrderSinglePage-YPNO5B3Z.js → OrderSinglePage-IIC6JKFX.js} +16 -15
- package/dist/OrderSinglePage-IIC6JKFX.js.map +1 -0
- package/dist/{OrdersPage-FYL73WZO.js → OrdersPage-FPUE5T6O.js} +15 -14
- package/dist/OrdersPage-FPUE5T6O.js.map +1 -0
- package/dist/{PageSingle-3VAW7S6B.js → PageSingle-BOZFETZ5.js} +3 -3
- package/dist/{PageSingle-3VAW7S6B.js.map → PageSingle-BOZFETZ5.js.map} +1 -1
- package/dist/{ProductDetails-UJ4MKTFM.js → ProductDetails-ERSDEM5Z.js} +4 -4
- package/dist/{ProductDetails-UJ4MKTFM.js.map → ProductDetails-ERSDEM5Z.js.map} +1 -1
- package/dist/{ProfilePage-5NZVZU2S.js → ProfilePage-MP4PE2LF.js} +15 -14
- package/dist/ProfilePage-MP4PE2LF.js.map +1 -0
- package/dist/{RenderWhenVisible-KWAXEJOJ.js → RenderWhenVisible-BQ7KVPHK.js} +5 -3
- package/dist/RenderWhenVisible-BQ7KVPHK.js.map +1 -0
- package/dist/{ReviewsPage-SYD5UUVN.js → ReviewsPage-5L6DLPN2.js} +3 -3
- package/dist/{ReviewsPage-SYD5UUVN.js.map → ReviewsPage-5L6DLPN2.js.map} +1 -1
- package/dist/{SeoCartWidget-R45K7M4U.js → SeoCartWidget-XU5LKBMF.js} +15 -14
- package/dist/SeoCartWidget-XU5LKBMF.js.map +1 -0
- package/dist/{SettingsPage-DWTUF5TO.js → SettingsPage-A2AI5CWI.js} +15 -14
- package/dist/SettingsPage-A2AI5CWI.js.map +1 -0
- package/dist/{StoreClosedNotification-2NARK6HJ.js → StoreClosedNotification-C6EZSOQF.js} +16 -15
- package/dist/{StoreClosedNotification-2NARK6HJ.js.map → StoreClosedNotification-C6EZSOQF.js.map} +1 -1
- package/dist/{TestimonialsPage-QAOBCMAV.js → TestimonialsPage-ZO6OIZMX.js} +3 -3
- package/dist/{TestimonialsPage-QAOBCMAV.js.map → TestimonialsPage-ZO6OIZMX.js.map} +1 -1
- package/dist/{ThankYouPage-GBAAHFWB.js → ThankYouPage-RZFWZZXI.js} +15 -14
- package/dist/ThankYouPage-RZFWZZXI.js.map +1 -0
- package/dist/{WalletPage-QWJM6DTB.js → WalletPage-BDMVFQ4G.js} +16 -15
- package/dist/WalletPage-BDMVFQ4G.js.map +1 -0
- package/dist/{WishlistPage-PCQR3DEF.js → WishlistPage-3OFBHANB.js} +17 -16
- package/dist/WishlistPage-3OFBHANB.js.map +1 -0
- package/dist/api/advertisement.js +2 -2
- package/dist/api/apps.js +2 -2
- package/dist/api/blog.js +3 -3
- package/dist/api/brands.js +3 -3
- package/dist/api/cart.js +3 -3
- package/dist/api/category.js +3 -3
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +1 -1
- package/dist/api/home.js +2 -2
- package/dist/api/loyalty.js +3 -3
- package/dist/api/menu.js +2 -2
- package/dist/api/notification.js +2 -2
- package/dist/api/order.js +3 -3
- package/dist/api/page.js +3 -3
- package/dist/api/product.js +3 -3
- package/dist/api/profile.js +1 -1
- package/dist/api/store.js +2 -2
- package/dist/api/translations.js +2 -2
- package/dist/api/user.js +2 -2
- package/dist/api/wallet.js +2 -2
- package/dist/api/wishlist.js +4 -4
- package/dist/chunk-3IBJ5QUW.js +14 -0
- package/dist/{chunk-UI625G7U.js.map → chunk-3IBJ5QUW.js.map} +1 -1
- package/dist/{chunk-B6JTC5R6.js → chunk-3PS2WFNQ.js} +4 -4
- package/dist/{chunk-B6JTC5R6.js.map → chunk-3PS2WFNQ.js.map} +1 -1
- package/dist/{chunk-I46KQSZH.js → chunk-3VOJOKQI.js} +6 -6
- package/dist/{chunk-I46KQSZH.js.map → chunk-3VOJOKQI.js.map} +1 -1
- package/dist/{chunk-JHTTTXTI.js → chunk-4IBG3GR6.js} +4 -4
- package/dist/{chunk-JHTTTXTI.js.map → chunk-4IBG3GR6.js.map} +1 -1
- package/dist/{chunk-3WGZZD2Y.js → chunk-5K53BZIN.js} +4 -4
- package/dist/{chunk-3WGZZD2Y.js.map → chunk-5K53BZIN.js.map} +1 -1
- package/dist/{chunk-PFAPRJVF.js → chunk-6BQN4JKH.js} +13 -4
- package/dist/chunk-6BQN4JKH.js.map +1 -0
- package/dist/{chunk-PRA6E6SQ.js → chunk-6F6VACX5.js} +4 -4
- package/dist/{chunk-PRA6E6SQ.js.map → chunk-6F6VACX5.js.map} +1 -1
- package/dist/{chunk-VI2WHQDR.js → chunk-6JS7UZ3S.js} +3 -3
- package/dist/{chunk-VI2WHQDR.js.map → chunk-6JS7UZ3S.js.map} +1 -1
- package/dist/{chunk-QWGSGNM7.js → chunk-7IQCF6GU.js} +7 -7
- package/dist/{chunk-QWGSGNM7.js.map → chunk-7IQCF6GU.js.map} +1 -1
- package/dist/{chunk-VSK2WS4G.js → chunk-ABDYSBBY.js} +3 -3
- package/dist/{chunk-VSK2WS4G.js.map → chunk-ABDYSBBY.js.map} +1 -1
- package/dist/{chunk-EFT442TN.js → chunk-ALHMPT6S.js} +3 -3
- package/dist/{chunk-EFT442TN.js.map → chunk-ALHMPT6S.js.map} +1 -1
- package/dist/{chunk-7K3AK6IC.js → chunk-BHCKUER2.js} +4 -4
- package/dist/{chunk-7K3AK6IC.js.map → chunk-BHCKUER2.js.map} +1 -1
- package/dist/{chunk-4EATTQQA.js → chunk-DEIABJV4.js} +3 -3
- package/dist/{chunk-4EATTQQA.js.map → chunk-DEIABJV4.js.map} +1 -1
- package/dist/{chunk-AVW4CLTB.js → chunk-E5OVMQIA.js} +4 -4
- package/dist/{chunk-AVW4CLTB.js.map → chunk-E5OVMQIA.js.map} +1 -1
- package/dist/{chunk-EFCIK5NI.js → chunk-EA334DDV.js} +3 -3
- package/dist/{chunk-EFCIK5NI.js.map → chunk-EA334DDV.js.map} +1 -1
- package/dist/{chunk-XMFVSBEO.js → chunk-EL6IDB5U.js} +3 -3
- package/dist/{chunk-XMFVSBEO.js.map → chunk-EL6IDB5U.js.map} +1 -1
- package/dist/{chunk-MQALPNFL.js → chunk-ESYRKX7T.js} +4 -4
- package/dist/{chunk-MQALPNFL.js.map → chunk-ESYRKX7T.js.map} +1 -1
- package/dist/{chunk-VT6FE3CB.js → chunk-F2MDQCTH.js} +3 -3
- package/dist/{chunk-VT6FE3CB.js.map → chunk-F2MDQCTH.js.map} +1 -1
- package/dist/{chunk-S4VVTUCI.js → chunk-HAH22L6T.js} +7 -7
- package/dist/{chunk-S4VVTUCI.js.map → chunk-HAH22L6T.js.map} +1 -1
- package/dist/{chunk-IRQJBRKV.js → chunk-JOY7HCIH.js} +3 -3
- package/dist/{chunk-IRQJBRKV.js.map → chunk-JOY7HCIH.js.map} +1 -1
- package/dist/{chunk-CKMLOJGM.js → chunk-KNUANWCR.js} +9 -6
- package/dist/chunk-KNUANWCR.js.map +1 -0
- package/dist/{chunk-RVPC4AYT.js → chunk-LCBETTJI.js} +3 -3
- package/dist/{chunk-RVPC4AYT.js.map → chunk-LCBETTJI.js.map} +1 -1
- package/dist/{chunk-VXSBJZ3E.js → chunk-LG5355UU.js} +4 -4
- package/dist/{chunk-VXSBJZ3E.js.map → chunk-LG5355UU.js.map} +1 -1
- package/dist/{chunk-3LJF7ECP.js → chunk-LNSMPXGR.js} +4 -4
- package/dist/{chunk-3LJF7ECP.js.map → chunk-LNSMPXGR.js.map} +1 -1
- package/dist/{chunk-UMTMIMH7.js → chunk-MWOP57ZR.js} +3 -3
- package/dist/{chunk-UMTMIMH7.js.map → chunk-MWOP57ZR.js.map} +1 -1
- package/dist/{chunk-CTNSIK3V.js → chunk-N6EWTAE4.js} +7 -7
- package/dist/{chunk-CTNSIK3V.js.map → chunk-N6EWTAE4.js.map} +1 -1
- package/dist/{chunk-EQ7I4AFL.js → chunk-NEPBUZ5S.js} +5 -5
- package/dist/{chunk-EQ7I4AFL.js.map → chunk-NEPBUZ5S.js.map} +1 -1
- package/dist/{chunk-D2RUSG36.js → chunk-P6X2QUYL.js} +4 -4
- package/dist/{chunk-D2RUSG36.js.map → chunk-P6X2QUYL.js.map} +1 -1
- package/dist/chunk-PDIFXQDX.js +63 -0
- package/dist/chunk-PDIFXQDX.js.map +1 -0
- package/dist/{chunk-NEHOBD4K.js → chunk-PO6PTKMN.js} +3 -3
- package/dist/{chunk-NEHOBD4K.js.map → chunk-PO6PTKMN.js.map} +1 -1
- package/dist/{chunk-ME4UKH7Y.js → chunk-PQNLRRWJ.js} +4 -4
- package/dist/{chunk-ME4UKH7Y.js.map → chunk-PQNLRRWJ.js.map} +1 -1
- package/dist/{chunk-E552K72T.js → chunk-QMKC7PA2.js} +3 -3
- package/dist/{chunk-E552K72T.js.map → chunk-QMKC7PA2.js.map} +1 -1
- package/dist/{chunk-R5TTR2G7.js → chunk-QTRV6N64.js} +38 -21
- package/dist/chunk-QTRV6N64.js.map +1 -0
- package/dist/{chunk-Y36VLQGV.js → chunk-UNDCL5EE.js} +10 -10
- package/dist/{chunk-Y36VLQGV.js.map → chunk-UNDCL5EE.js.map} +1 -1
- package/dist/{chunk-W6NQM4FQ.js → chunk-UQ7NS6BZ.js} +3 -3
- package/dist/{chunk-W6NQM4FQ.js.map → chunk-UQ7NS6BZ.js.map} +1 -1
- package/dist/{chunk-5CKTQAFX.js → chunk-V23ILNAK.js} +3 -3
- package/dist/{chunk-5CKTQAFX.js.map → chunk-V23ILNAK.js.map} +1 -1
- package/dist/{chunk-XM22O2B2.js → chunk-WZOWGICV.js} +3 -3
- package/dist/{chunk-XM22O2B2.js.map → chunk-WZOWGICV.js.map} +1 -1
- package/dist/{chunk-NU2LPGNB.js → chunk-XK6TXHVO.js} +3 -3
- package/dist/{chunk-NU2LPGNB.js.map → chunk-XK6TXHVO.js.map} +1 -1
- package/dist/{chunk-T23HXVW5.js → chunk-Y57KRLGY.js} +3 -3
- package/dist/{chunk-T23HXVW5.js.map → chunk-Y57KRLGY.js.map} +1 -1
- package/dist/{chunk-GEGB34LB.js → chunk-YC4CEVQO.js} +4 -4
- package/dist/{chunk-GEGB34LB.js.map → chunk-YC4CEVQO.js.map} +1 -1
- package/dist/components/cart/index.js +1 -1
- package/dist/components/common/RenderWhenVisible.d.ts +3 -1
- package/dist/components/common/RenderWhenVisible.d.ts.map +1 -1
- package/dist/components/common/index.js +1 -1
- package/dist/components/common/lazy.d.ts +1 -1
- package/dist/components/common/lazy.d.ts.map +1 -1
- package/dist/components/drawer/index.js +13 -12
- package/dist/components/home/HomePageRenderer.d.ts.map +1 -1
- package/dist/components/home/index.js +17 -16
- package/dist/components/layout/index.js +4 -4
- package/dist/components/live-editor/LiveEditorBar.d.ts +11 -0
- package/dist/components/live-editor/LiveEditorBar.d.ts.map +1 -0
- package/dist/components/live-editor/frame.d.ts +34 -0
- package/dist/components/live-editor/frame.d.ts.map +1 -0
- package/dist/components/live-editor/index.d.ts +9 -0
- package/dist/components/live-editor/index.d.ts.map +1 -0
- package/dist/components/product/index.js +14 -13
- package/dist/components/store/index.js +14 -13
- package/dist/dev/editor/index.js +1 -1
- package/dist/dev/index.js +1 -1
- package/dist/{document-class-TSDZIVXW.js → document-class-WRE36CKT.js} +11 -11
- package/dist/{document-class-TSDZIVXW.js.map → document-class-WRE36CKT.js.map} +1 -1
- package/dist/hooks/index.js +13 -12
- package/dist/hooks/useGtm.js +13 -12
- package/dist/hooks/useMoney.js +13 -12
- package/dist/hooks/useStore.js +13 -12
- package/dist/hooks/useUser.js +3 -3
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/{navigation-2V7R2ANX.js → navigation-F5YC4AN5.js} +5 -5
- package/dist/{navigation-2V7R2ANX.js.map → navigation-F5YC4AN5.js.map} +1 -1
- package/dist/{navigation-LRBZCNKS.js → navigation-KPN6OPJN.js} +4 -4
- package/dist/{navigation-LRBZCNKS.js.map → navigation-KPN6OPJN.js.map} +1 -1
- package/dist/{not-found-5DFPFQ4B.js → not-found-YZOISV3W.js} +16 -15
- package/dist/not-found-YZOISV3W.js.map +1 -0
- package/dist/providers/TwilightProvider.d.ts.map +1 -1
- package/dist/providers/index.js +13 -12
- package/dist/routes/account/orders.js +4 -4
- package/dist/routes/account.js +13 -13
- package/dist/routes/blog.js +8 -8
- package/dist/routes/brands.js +4 -4
- package/dist/routes/cart.js +21 -20
- package/dist/routes/cart.js.map +1 -1
- package/dist/routes/home.js +18 -17
- package/dist/routes/index.js +3 -3
- package/dist/routes/loyalty.js +5 -5
- package/dist/routes/page.js +4 -4
- package/dist/routes/product-listing.js +19 -18
- package/dist/routes/product-listing.js.map +1 -1
- package/dist/routes/product.js +17 -16
- package/dist/routes/product.js.map +1 -1
- package/dist/routes/seo-redirects.js +3 -3
- package/dist/routes/testimonials.js +2 -2
- package/dist/routes/thank-you.js +4 -4
- package/dist/skeleton.js +18 -17
- package/dist/{store-lookup-YUA66JS6.js → store-lookup-GXBNYGCM.js} +8 -8
- package/dist/{store-lookup-YUA66JS6.js.map → store-lookup-GXBNYGCM.js.map} +1 -1
- package/dist/tanstack.js +11 -11
- package/dist/utils/fast-checkout.d.ts +1 -1
- package/dist/utils/fast-checkout.d.ts.map +1 -1
- package/dist/utils/index.js +2 -2
- package/package.json +1 -1
- package/tailwind/components/common/RenderWhenVisible.tsx.txt +4 -0
- package/tailwind/components/home/HomePageRenderer.tsx.txt +7 -0
- package/tailwind/components/live-editor/LiveEditorBar.tsx.txt +417 -0
- package/tailwind/components/live-editor/frame.ts.txt +97 -0
- package/tailwind/components/live-editor/index.tsx.txt +37 -0
- package/dist/BlogAuthorPage-DIQMXVKT.js.map +0 -1
- package/dist/BlogCategoryPage-CIEC3I3C.js.map +0 -1
- package/dist/BlogPage-SRBQBKLP.js.map +0 -1
- package/dist/BlogSinglePage-5BD3OVXK.js.map +0 -1
- package/dist/BlogTagPage-ZCDTNTKI.js.map +0 -1
- package/dist/BrandsPage-XHWYHEQS.js.map +0 -1
- package/dist/Breadcrumb-OODSTILO.js.map +0 -1
- package/dist/CartItem-N7PX7K6E.js.map +0 -1
- package/dist/CartSummary-FVM26G2M.js.map +0 -1
- package/dist/CustomerLayout-B3W377Y4.js.map +0 -1
- package/dist/LoyaltyPage-UBYNGW6Z.js.map +0 -1
- package/dist/MobileMenu-2EAPAHX5.js.map +0 -1
- package/dist/NotificationsPage-PIQJTEHJ.js.map +0 -1
- package/dist/OrderSinglePage-YPNO5B3Z.js.map +0 -1
- package/dist/OrdersPage-FYL73WZO.js.map +0 -1
- package/dist/ProfilePage-5NZVZU2S.js.map +0 -1
- package/dist/RenderWhenVisible-KWAXEJOJ.js.map +0 -1
- package/dist/SeoCartWidget-R45K7M4U.js.map +0 -1
- package/dist/SettingsPage-DWTUF5TO.js.map +0 -1
- package/dist/ThankYouPage-GBAAHFWB.js.map +0 -1
- package/dist/WalletPage-QWJM6DTB.js.map +0 -1
- package/dist/WishlistPage-PCQR3DEF.js.map +0 -1
- package/dist/chunk-CKMLOJGM.js.map +0 -1
- package/dist/chunk-PFAPRJVF.js.map +0 -1
- package/dist/chunk-R5TTR2G7.js.map +0 -1
- package/dist/chunk-UI625G7U.js +0 -14
- package/dist/not-found-5DFPFQ4B.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { category } from './chunk-
|
|
2
|
-
import { blog } from './chunk-
|
|
3
|
-
import { brand } from './chunk-
|
|
4
|
-
import { product } from './chunk-
|
|
1
|
+
import { category } from './chunk-P6X2QUYL.js';
|
|
2
|
+
import { blog } from './chunk-YC4CEVQO.js';
|
|
3
|
+
import { brand } from './chunk-3PS2WFNQ.js';
|
|
4
|
+
import { product } from './chunk-ESYRKX7T.js';
|
|
5
5
|
import { DEV_LOOKUP_BUDGET_MS } from './chunk-OXMUPNMH.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-Y57KRLGY.js';
|
|
7
7
|
import './chunk-OUW6WESU.js';
|
|
8
|
-
import './chunk-
|
|
8
|
+
import './chunk-6BQN4JKH.js';
|
|
9
9
|
import './chunk-2TLIULJZ.js';
|
|
10
10
|
import './chunk-GYXUYHKO.js';
|
|
11
11
|
import './chunk-FHU2MXZA.js';
|
|
@@ -110,5 +110,5 @@ function lookupInStore(source, query) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
export { lookupInStore };
|
|
113
|
-
//# sourceMappingURL=store-lookup-
|
|
114
|
-
//# sourceMappingURL=store-lookup-
|
|
113
|
+
//# sourceMappingURL=store-lookup-GXBNYGCM.js.map
|
|
114
|
+
//# sourceMappingURL=store-lookup-GXBNYGCM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev/store-lookup.ts"],"names":["categories"],"mappings":"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","file":"store-lookup-
|
|
1
|
+
{"version":3,"sources":["../src/dev/store-lookup.ts"],"names":["categories"],"mappings":"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","file":"store-lookup-GXBNYGCM.js","sourcesContent":["/**\n * Runs in the editor's frame (the storefront), which has the engine's API\n * client set up for the dev store: answers the editor's pickers with the real\n * store's products, categories, brands and blog. Loaded with `import()` on the\n * first lookup, so a storefront never carries it.\n *\n * Each item's `data` is what a block receives for it, in the API's shape: a\n * product block reads only the ids and fetches the rest, while categories and\n * brands are drawn from what is saved.\n */\n\nimport { product } from '../api/product';\nimport { category } from '../api/category';\nimport { brand } from '../api/brands';\nimport { blog } from '../api/blog';\nimport type { Category } from '../types';\nimport { DEV_LOOKUP_BUDGET_MS, type DevLookupItem, type DevLookupSource } from './schema-types';\n\n/** Enough to choose from; a search narrows it further. */\nconst PER_PAGE = 20;\n/** How far a paged list is searched before giving up, so a big store can't stall the picker. */\nconst MAX_PAGES = 10;\n\ninterface Page<T> {\n items: T[];\n next: string | null;\n}\n\n/**\n * The matching items of a paged list, read page after page until there are\n * enough, the pages run out, or the time budget is spent: a brand or article on\n * page three is still found, and what was found so far always reaches the\n * editor before it stops waiting (`DEV_LOOKUP_BUDGET_MS` < its timeout).\n */\nasync function collect<T>(\n fetchPage: (page: number, cursor: string | null) => Promise<Page<T>>,\n keep: (item: T) => boolean\n): Promise<T[]> {\n const deadline = Date.now() + DEV_LOOKUP_BUDGET_MS;\n const found: T[] = [];\n let cursor: string | null = null;\n for (let page = 1; page <= MAX_PAGES; page += 1) {\n const { items, next } = await fetchPage(page, cursor);\n found.push(...items.filter(keep));\n if (found.length >= PER_PAGE || !next || Date.now() >= deadline) break;\n cursor = next;\n }\n return found.slice(0, PER_PAGE);\n}\n\nfunction matches(name: string, query: string): boolean {\n return !query || name.toLowerCase().includes(query.toLowerCase());\n}\n\n/** Categories with their subcategories, flattened, parents first. */\nfunction flatten(categories: Category[]): Category[] {\n return categories.flatMap((c) => [c, ...flatten(c.sub_categories ?? [])]);\n}\n\nasync function products(query: string): Promise<DevLookupItem[]> {\n const { items } = await product.list({\n source: query ? 'search' : 'latest',\n ...(query ? { keyword: query } : {}),\n perPage: PER_PAGE,\n });\n // List responses send the id as a numeric string; the block reads a number. Use it for both.\n return items.map((p) => ({\n id: Number(p.id),\n name: p.name,\n image: p.image?.url,\n url: p.url,\n data: { id: Number(p.id), name: p.name, url: p.url, image: p.image?.url ?? null },\n }));\n}\n\nasync function categories(query: string): Promise<DevLookupItem[]> {\n return flatten(await category.list())\n .filter((c) => matches(c.name, query))\n .slice(0, PER_PAGE)\n .map((c) => ({\n id: c.id,\n name: c.name,\n image: c.image ?? undefined,\n url: c.url,\n data: { id: c.id, name: c.name, url: c.url, image: c.image ?? null, icon: c.icon ?? null },\n }));\n}\n\nasync function brands(query: string): Promise<DevLookupItem[]> {\n const found = await collect(\n (page) => brand.list(page),\n (b) => matches(b.name, query)\n );\n return found.map((b) => ({\n id: b.id,\n name: b.name,\n image: b.logo,\n url: b.url,\n data: { id: b.id, name: b.name, url: b.url, logo: b.logo, banner: b.banner ?? null },\n }));\n}\n\nasync function blogArticles(query: string): Promise<DevLookupItem[]> {\n const found = await collect(\n async (_page, cursor) => {\n const { data, cursor: pages } = await blog.articles.list(cursor ? { cursor } : undefined);\n return { items: data, next: pages?.next ?? null };\n },\n (a) => matches(a.name, query)\n );\n return found.map((a) => ({\n id: a.id,\n name: a.name,\n image: a.image,\n url: a.url,\n data: { id: a.id, name: a.name, url: a.url },\n }));\n}\n\nasync function blogCategories(query: string): Promise<DevLookupItem[]> {\n const { categories: list } = await blog.get();\n return list\n .filter((c) => matches(c.name, query))\n .slice(0, PER_PAGE)\n .map((c) => ({\n id: c.id,\n name: c.name,\n url: c.url,\n data: { id: c.id, name: c.name, url: c.url },\n }));\n}\n\nconst LOOKUPS: Record<DevLookupSource, (query: string) => Promise<DevLookupItem[]>> = {\n products,\n categories,\n brands,\n blog_articles: blogArticles,\n blog_categories: blogCategories,\n};\n\nexport function lookupInStore(source: DevLookupSource, query: string): Promise<DevLookupItem[]> {\n const lookup = LOOKUPS[source];\n if (!lookup) return Promise.reject(new Error(`no lookup for ${source}`));\n return lookup(query.trim());\n}\n"]}
|
package/dist/tanstack.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
export { tanstackDocumentAdapter as attrs, createRouter, createTwilightRootRoute, useTanstackDocumentAttrs as useAttrs } from './chunk-
|
|
2
|
-
import { requestHostOf } from './chunk-
|
|
3
|
-
export { TanStackLinkAdapter, TanStackNavigationProvider, createTanStackLinkAdapter } from './chunk-
|
|
1
|
+
export { tanstackDocumentAdapter as attrs, createRouter, createTwilightRootRoute, useTanstackDocumentAttrs as useAttrs } from './chunk-UNDCL5EE.js';
|
|
2
|
+
import { requestHostOf } from './chunk-XK6TXHVO.js';
|
|
3
|
+
export { TanStackLinkAdapter, TanStackNavigationProvider, createTanStackLinkAdapter } from './chunk-XK6TXHVO.js';
|
|
4
4
|
import './chunk-Z4Y55HWX.js';
|
|
5
5
|
export { tanstackHeadAdapter as head, withHead } from './chunk-EHTLXK5F.js';
|
|
6
6
|
import { CRITICAL_STYLE_HREF } from './chunk-4FJGZQD3.js';
|
|
7
|
-
import './chunk-
|
|
8
|
-
import { readNativeAppHeaders } from './chunk-
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
7
|
+
import './chunk-EA334DDV.js';
|
|
8
|
+
import { readNativeAppHeaders } from './chunk-JOY7HCIH.js';
|
|
9
|
+
import './chunk-QMKC7PA2.js';
|
|
10
|
+
import './chunk-ESYRKX7T.js';
|
|
11
11
|
import { rootHead, maintenanceEvidence, MAINTENANCE_EVIDENCE_HEADER, maintenanceEvidenceHeader } from './chunk-D6XHL6VQ.js';
|
|
12
12
|
import './chunk-JYV25VNZ.js';
|
|
13
|
-
import './chunk-
|
|
13
|
+
import './chunk-MWOP57ZR.js';
|
|
14
14
|
import './chunk-5FJFN3IW.js';
|
|
15
15
|
import './chunk-GD26FI4J.js';
|
|
16
16
|
import './chunk-OM2GRPDH.js';
|
|
17
|
-
import './chunk-
|
|
17
|
+
import './chunk-Y57KRLGY.js';
|
|
18
18
|
import './chunk-OUW6WESU.js';
|
|
19
19
|
import './chunk-JWXJPJBO.js';
|
|
20
20
|
export { mergeDocumentDescriptors as mergeAttrs } from './chunk-CW625T2E.js';
|
|
21
|
-
import './chunk-
|
|
22
|
-
import './chunk-
|
|
21
|
+
import './chunk-6JS7UZ3S.js';
|
|
22
|
+
import './chunk-6BQN4JKH.js';
|
|
23
23
|
import './chunk-TYNZ5B2B.js';
|
|
24
24
|
import './chunk-BYMOPN2S.js';
|
|
25
25
|
import './chunk-2TLIULJZ.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* head, on idle elsewhere) and deduped by src, not by id.
|
|
6
6
|
*/
|
|
7
7
|
export declare const FAST_CHECKOUT_SCRIPT_ID = "fast-checkout-js";
|
|
8
|
-
export declare const FAST_CHECKOUT_SCRIPT_URL = "https://cdn.assets.salla.network/
|
|
8
|
+
export declare const FAST_CHECKOUT_SCRIPT_URL = "https://cdn.assets.salla.network/prod/@salla.sa/fast-checkout-widget/v0.0.47/widget.esm.js";
|
|
9
9
|
export declare const fastCheckoutScript: () => {
|
|
10
10
|
type: string;
|
|
11
11
|
src: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fast-checkout.d.ts","sourceRoot":"","sources":["../../src/utils/fast-checkout.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"fast-checkout.d.ts","sourceRoot":"","sources":["../../src/utils/fast-checkout.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAI1D,eAAO,MAAM,wBAAwB,+FACyD,CAAC;AAE/F,eAAO,MAAM,kBAAkB;;;CAA4D,CAAC;AAE5F;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAK/C"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { stripUnsafeHtml } from '../chunk-RUHSV4Z6.js';
|
|
2
2
|
export { formatSallaPlural } from '../chunk-BT6HEEAP.js';
|
|
3
|
-
export { dispatchRouteChanged } from '../chunk-
|
|
3
|
+
export { dispatchRouteChanged } from '../chunk-EA334DDV.js';
|
|
4
4
|
export { sortOptions } from '../chunk-3LZJXKVO.js';
|
|
5
5
|
export { color } from '../chunk-VVZNW5CB.js';
|
|
6
6
|
export { applyAppScopeMocks, registerThemeHookSlots } from '../chunk-5FJFN3IW.js';
|
|
@@ -8,7 +8,7 @@ export { mergeHead, resolveHead, setHeadAdapter } from '../chunk-GD26FI4J.js';
|
|
|
8
8
|
export { buildBaseHead, buildHreflangAlternates, localeToOgLocale } from '../chunk-OM2GRPDH.js';
|
|
9
9
|
export { asset, cdn, isPlaceholder } from '../chunk-ZCH7W7DZ.js';
|
|
10
10
|
export { mergeDocumentDescriptors, mergeElementAttrs, normalizeClasses, syncAttrsToElement, toReactProps } from '../chunk-CW625T2E.js';
|
|
11
|
-
import '../chunk-
|
|
11
|
+
import '../chunk-6BQN4JKH.js';
|
|
12
12
|
export { getSallaSDK, getStoreIdentifier, onSallaEvent, whenSallaLoaded, whenSallaReady } from '../chunk-GYXUYHKO.js';
|
|
13
13
|
export { AUTH_TOKEN_COOKIE_NAME, clearAuthTokenCookie, extractTokenFromCookies } from '../chunk-FHU2MXZA.js';
|
|
14
14
|
import '../chunk-7VNVCHID.js';
|
package/package.json
CHANGED
|
@@ -20,6 +20,8 @@ export interface RenderWhenVisibleProps {
|
|
|
20
20
|
renderOnMount?: boolean;
|
|
21
21
|
/** @internal Home block position, rendered as `data-home-block` for the dev editor's scroll-to. */
|
|
22
22
|
blockIndex?: number;
|
|
23
|
+
/** @internal The block's id in the store, rendered as `data-live-block` for the theme editor's action bar. */
|
|
24
|
+
liveBlockId?: string;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/**
|
|
@@ -45,6 +47,7 @@ export const RenderWhenVisible = memo(function RenderWhenVisible({
|
|
|
45
47
|
estimatedHeight = '400px',
|
|
46
48
|
renderOnMount = false,
|
|
47
49
|
blockIndex,
|
|
50
|
+
liveBlockId,
|
|
48
51
|
}: RenderWhenVisibleProps) {
|
|
49
52
|
const ref = useRef<HTMLElement>(null);
|
|
50
53
|
const [visible, setVisible] = useState(renderOnMount);
|
|
@@ -84,6 +87,7 @@ export const RenderWhenVisible = memo(function RenderWhenVisible({
|
|
|
84
87
|
className={className}
|
|
85
88
|
id={id}
|
|
86
89
|
data-home-block={blockIndex}
|
|
90
|
+
data-live-block={liveBlockId}
|
|
87
91
|
style={{ minHeight: mounted ? undefined : estimatedHeight }}
|
|
88
92
|
>
|
|
89
93
|
{visible ? (
|
|
@@ -253,6 +253,12 @@ export const HomeComponentRenderer = memo(function HomeComponentRenderer({
|
|
|
253
253
|
? config.id(data)
|
|
254
254
|
: config.id
|
|
255
255
|
: undefined;
|
|
256
|
+
// What the theme editor addresses the block by: its row id, or the uuid of one not saved yet.
|
|
257
|
+
const blockId = data.id ?? data.key;
|
|
258
|
+
const liveBlockId =
|
|
259
|
+
typeof blockId === 'number' || (typeof blockId === 'string' && blockId)
|
|
260
|
+
? String(blockId)
|
|
261
|
+
: undefined;
|
|
256
262
|
const height = config?.height || '400px';
|
|
257
263
|
// A theme's config replaces the engine's, but keeps its mount timing unless the theme sets one.
|
|
258
264
|
const renderOnMount = config?.renderOnMount ?? COMPONENT_CONFIG[data.path]?.renderOnMount;
|
|
@@ -279,6 +285,7 @@ export const HomeComponentRenderer = memo(function HomeComponentRenderer({
|
|
|
279
285
|
placeholder={config?.placeholder ?? <ProductsSliderSkeleton />}
|
|
280
286
|
// Dev only: lets the theme editor scroll the preview to a block.
|
|
281
287
|
blockIndex={import.meta.env.DEV ? index : undefined}
|
|
288
|
+
liveBlockId={liveBlockId}
|
|
282
289
|
>
|
|
283
290
|
{content}
|
|
284
291
|
</RenderWhenVisible>
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useRef,
|
|
5
|
+
useState,
|
|
6
|
+
type CSSProperties,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type RefObject,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { createPortal } from 'react-dom';
|
|
11
|
+
import { useTranslation } from '../../providers/I18nProvider';
|
|
12
|
+
import { BLOCK_ATTRIBUTE, areaOf, postToEditor, targetOf, type BlockAction } from './frame';
|
|
13
|
+
|
|
14
|
+
const ACCENT = '#5dd5c4';
|
|
15
|
+
const LAYER = 2147483000;
|
|
16
|
+
/** The editor reloads the preview after hide, duplicate and delete; stop waiting if it doesn't. */
|
|
17
|
+
const BUSY_TIMEOUT_MS = 10_000;
|
|
18
|
+
/** How long a link's click waits for a second one, so a double-click edits instead of navigating. */
|
|
19
|
+
const DOUBLE_CLICK_MS = 300;
|
|
20
|
+
|
|
21
|
+
/** Defaults for the `blocks.live_editor.*` keys, in the store's language. */
|
|
22
|
+
const DEFAULT_LABELS = {
|
|
23
|
+
ar: {
|
|
24
|
+
edit: 'تعديل',
|
|
25
|
+
hide: 'إخفاء',
|
|
26
|
+
moveup: 'تحريك لأعلى',
|
|
27
|
+
movedown: 'تحريك لأسفل',
|
|
28
|
+
duplicate: 'تكرار',
|
|
29
|
+
add: 'إضافة عنصر',
|
|
30
|
+
delete: 'حذف',
|
|
31
|
+
header: 'رأس الصفحة',
|
|
32
|
+
footer: 'ذيل الصفحة',
|
|
33
|
+
},
|
|
34
|
+
en: {
|
|
35
|
+
edit: 'Edit',
|
|
36
|
+
hide: 'Hide',
|
|
37
|
+
moveup: 'Move up',
|
|
38
|
+
movedown: 'Move down',
|
|
39
|
+
duplicate: 'Duplicate',
|
|
40
|
+
add: 'Add element',
|
|
41
|
+
delete: 'Delete',
|
|
42
|
+
header: 'Header',
|
|
43
|
+
footer: 'Footer',
|
|
44
|
+
},
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
/** Twig's order, read from the start of the line: edit first, delete last. */
|
|
48
|
+
const BLOCK_ACTIONS: BlockAction[] = [
|
|
49
|
+
'edit',
|
|
50
|
+
'hide',
|
|
51
|
+
'moveup',
|
|
52
|
+
'movedown',
|
|
53
|
+
'duplicate',
|
|
54
|
+
'add',
|
|
55
|
+
'delete',
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/** Lucide-style 24px stroke icons. */
|
|
59
|
+
const ICONS: Record<BlockAction, ReactElement> = {
|
|
60
|
+
edit: (
|
|
61
|
+
<>
|
|
62
|
+
<path d="M12 20h9" />
|
|
63
|
+
<path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" />
|
|
64
|
+
</>
|
|
65
|
+
),
|
|
66
|
+
hide: (
|
|
67
|
+
<>
|
|
68
|
+
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 10 8 10 8a13.16 13.16 0 0 1-1.67 2.68" />
|
|
69
|
+
<path d="M6.61 6.61A13.53 13.53 0 0 0 2 12s3 8 10 8a9.74 9.74 0 0 0 5.39-1.61" />
|
|
70
|
+
<path d="M9.88 9.88a3 3 0 1 0 4.24 4.24" />
|
|
71
|
+
<path d="m2 2 20 20" />
|
|
72
|
+
</>
|
|
73
|
+
),
|
|
74
|
+
moveup: <path d="m18 15-6-6-6 6" />,
|
|
75
|
+
movedown: <path d="m6 9 6 6 6-6" />,
|
|
76
|
+
duplicate: (
|
|
77
|
+
<>
|
|
78
|
+
<rect x="8" y="8" width="14" height="14" rx="2" />
|
|
79
|
+
<path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2" />
|
|
80
|
+
</>
|
|
81
|
+
),
|
|
82
|
+
add: <path d="M12 5v14M5 12h14" />,
|
|
83
|
+
delete: (
|
|
84
|
+
<>
|
|
85
|
+
<path d="M3 6h18" />
|
|
86
|
+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
|
|
87
|
+
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
|
88
|
+
</>
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const OUTLINE: CSSProperties = {
|
|
93
|
+
position: 'fixed',
|
|
94
|
+
zIndex: LAYER,
|
|
95
|
+
pointerEvents: 'none',
|
|
96
|
+
boxSizing: 'border-box',
|
|
97
|
+
border: `2px solid ${ACCENT}`,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const CHIP: CSSProperties = {
|
|
101
|
+
position: 'absolute',
|
|
102
|
+
top: 0,
|
|
103
|
+
insetInlineStart: 0,
|
|
104
|
+
padding: '4px 12px',
|
|
105
|
+
background: ACCENT,
|
|
106
|
+
color: '#0f172a',
|
|
107
|
+
font: '500 14px/1.4 system-ui, sans-serif',
|
|
108
|
+
whiteSpace: 'nowrap',
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const BAR: CSSProperties = {
|
|
112
|
+
position: 'fixed',
|
|
113
|
+
zIndex: LAYER + 1,
|
|
114
|
+
display: 'flex',
|
|
115
|
+
gap: 4,
|
|
116
|
+
padding: 6,
|
|
117
|
+
background: '#fff',
|
|
118
|
+
borderRadius: 8,
|
|
119
|
+
boxShadow: '0 4px 16px rgba(15, 23, 42, 0.18)',
|
|
120
|
+
transform: 'translateX(-50%)',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
function buttonStyle(action: BlockAction | 'area', disabled: boolean): CSSProperties {
|
|
124
|
+
return {
|
|
125
|
+
display: 'flex',
|
|
126
|
+
alignItems: 'center',
|
|
127
|
+
justifyContent: 'center',
|
|
128
|
+
gap: 6,
|
|
129
|
+
minWidth: 36,
|
|
130
|
+
height: 36,
|
|
131
|
+
padding: '0 8px',
|
|
132
|
+
border: 0,
|
|
133
|
+
borderRadius: 6,
|
|
134
|
+
background: 'transparent',
|
|
135
|
+
color: action === 'delete' ? '#e11d48' : action === 'edit' ? '#0d9488' : '#475569',
|
|
136
|
+
font: '500 14px/1 system-ui, sans-serif',
|
|
137
|
+
cursor: disabled ? 'default' : 'pointer',
|
|
138
|
+
opacity: disabled ? 0.35 : 1,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function Icon({ children }: { children: ReactElement }) {
|
|
143
|
+
return (
|
|
144
|
+
<svg
|
|
145
|
+
width="18"
|
|
146
|
+
height="18"
|
|
147
|
+
viewBox="0 0 24 24"
|
|
148
|
+
fill="none"
|
|
149
|
+
stroke="currentColor"
|
|
150
|
+
strokeWidth="2"
|
|
151
|
+
strokeLinecap="round"
|
|
152
|
+
strokeLinejoin="round"
|
|
153
|
+
aria-hidden="true"
|
|
154
|
+
>
|
|
155
|
+
{children}
|
|
156
|
+
</svg>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The blocks `el` can trade places with: its siblings in the same list. */
|
|
161
|
+
function blockSiblings(el: HTMLElement): HTMLElement[] {
|
|
162
|
+
const parent = el.parentElement;
|
|
163
|
+
if (!parent) return [el];
|
|
164
|
+
return Array.from(parent.children).filter(
|
|
165
|
+
(child): child is HTMLElement =>
|
|
166
|
+
child instanceof HTMLElement && child.hasAttribute(BLOCK_ATTRIBUTE)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function connected(el: HTMLElement | null): HTMLElement | null {
|
|
171
|
+
return el?.isConnected ? el : null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Re-renders on scroll, resize and layout shifts, so the overlay follows what it outlines. */
|
|
175
|
+
function useLayoutTick(active: boolean): void {
|
|
176
|
+
const [, setTick] = useState(0);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (!active) return;
|
|
179
|
+
let frame = 0;
|
|
180
|
+
const schedule = () => {
|
|
181
|
+
cancelAnimationFrame(frame);
|
|
182
|
+
frame = requestAnimationFrame(() => setTick((n) => n + 1));
|
|
183
|
+
};
|
|
184
|
+
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
185
|
+
window.addEventListener('resize', schedule);
|
|
186
|
+
const observer = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(schedule) : null;
|
|
187
|
+
observer?.observe(document.body);
|
|
188
|
+
return () => {
|
|
189
|
+
cancelAnimationFrame(frame);
|
|
190
|
+
window.removeEventListener('scroll', schedule, { capture: true });
|
|
191
|
+
window.removeEventListener('resize', schedule);
|
|
192
|
+
observer?.disconnect();
|
|
193
|
+
};
|
|
194
|
+
}, [active]);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
type LabelKey = keyof typeof DEFAULT_LABELS.en;
|
|
198
|
+
type Labels = Record<LabelKey, string>;
|
|
199
|
+
|
|
200
|
+
function useLabels(): Labels {
|
|
201
|
+
const { t, i18n } = useTranslation();
|
|
202
|
+
const defaults = i18n?.language?.startsWith('ar') ? DEFAULT_LABELS.ar : DEFAULT_LABELS.en;
|
|
203
|
+
return Object.fromEntries(
|
|
204
|
+
(Object.keys(defaults) as LabelKey[]).map((key) => [
|
|
205
|
+
key,
|
|
206
|
+
t(`blocks.live_editor.${key}`, { defaultValue: defaults[key] }),
|
|
207
|
+
])
|
|
208
|
+
) as Labels;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Holds a link's click inside a block, the header or the footer for
|
|
213
|
+
* {@link DOUBLE_CLICK_MS}: a second click on the same link makes it a
|
|
214
|
+
* double-click, which edits the area, and the link never navigates; otherwise
|
|
215
|
+
* the click is replayed. A click on another link drops the first one.
|
|
216
|
+
*/
|
|
217
|
+
function useHeldLinkClicks(barRef: RefObject<HTMLDivElement | null>): void {
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
let held: { link: HTMLAnchorElement; timer: number } | null = null;
|
|
220
|
+
let replaying = false;
|
|
221
|
+
|
|
222
|
+
const onClick = (event: MouseEvent) => {
|
|
223
|
+
if (replaying || event.button !== 0) return;
|
|
224
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
225
|
+
if (barRef.current?.contains(event.target as Node)) return;
|
|
226
|
+
const link = event.target instanceof Element ? event.target.closest('a[href]') : null;
|
|
227
|
+
if (!(link instanceof HTMLAnchorElement) || !targetOf(link)) return;
|
|
228
|
+
|
|
229
|
+
// Before the router's own handler, which sits below the document.
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
event.stopPropagation();
|
|
232
|
+
const previous = held;
|
|
233
|
+
if (previous) {
|
|
234
|
+
window.clearTimeout(previous.timer);
|
|
235
|
+
held = null;
|
|
236
|
+
if (previous.link === link) return;
|
|
237
|
+
}
|
|
238
|
+
const timer = window.setTimeout(() => {
|
|
239
|
+
held = null;
|
|
240
|
+
replaying = true;
|
|
241
|
+
link.click();
|
|
242
|
+
replaying = false;
|
|
243
|
+
}, DOUBLE_CLICK_MS);
|
|
244
|
+
held = { link, timer };
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
document.addEventListener('click', onClick, true);
|
|
248
|
+
return () => {
|
|
249
|
+
document.removeEventListener('click', onClick, true);
|
|
250
|
+
if (held) window.clearTimeout(held.timer);
|
|
251
|
+
};
|
|
252
|
+
}, [barRef]);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function Outline({ el, label }: { el: HTMLElement; label?: string }) {
|
|
256
|
+
const rect = el.getBoundingClientRect();
|
|
257
|
+
return (
|
|
258
|
+
<div
|
|
259
|
+
data-testid="live-editor-outline"
|
|
260
|
+
style={{ ...OUTLINE, top: rect.top, left: rect.left, width: rect.width, height: rect.height }}
|
|
261
|
+
>
|
|
262
|
+
{label && <span style={CHIP}>{label}</span>}
|
|
263
|
+
</div>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
interface ToolbarProps {
|
|
268
|
+
target: HTMLElement;
|
|
269
|
+
labels: Labels;
|
|
270
|
+
busy: BlockAction | null;
|
|
271
|
+
barRef: RefObject<HTMLDivElement | null>;
|
|
272
|
+
onAct: (el: HTMLElement, action: BlockAction) => void;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** One edit button for the header or footer; the full set for a block. */
|
|
276
|
+
function Toolbar({ target, labels, busy, barRef, onAct }: ToolbarProps) {
|
|
277
|
+
const rect = target.getBoundingClientRect();
|
|
278
|
+
const style: CSSProperties = {
|
|
279
|
+
...BAR,
|
|
280
|
+
top: Math.max(rect.top + 8, 8),
|
|
281
|
+
left: rect.left + rect.width / 2,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
if (areaOf(target)) {
|
|
285
|
+
return (
|
|
286
|
+
<div ref={barRef} data-testid="live-editor-bar" style={style}>
|
|
287
|
+
<button
|
|
288
|
+
type="button"
|
|
289
|
+
data-testid="live-editor-edit"
|
|
290
|
+
style={buttonStyle('area', false)}
|
|
291
|
+
onClick={() => onAct(target, 'edit')}
|
|
292
|
+
>
|
|
293
|
+
<Icon>{ICONS.edit}</Icon>
|
|
294
|
+
{labels.edit}
|
|
295
|
+
</button>
|
|
296
|
+
</div>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const siblings = blockSiblings(target);
|
|
301
|
+
const index = siblings.indexOf(target);
|
|
302
|
+
const isDisabled = (action: BlockAction) =>
|
|
303
|
+
busy !== null ||
|
|
304
|
+
(action === 'moveup' && index <= 0) ||
|
|
305
|
+
(action === 'movedown' && index >= siblings.length - 1);
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<div
|
|
309
|
+
ref={barRef}
|
|
310
|
+
data-testid="live-editor-bar"
|
|
311
|
+
role="toolbar"
|
|
312
|
+
aria-label={labels.edit}
|
|
313
|
+
style={style}
|
|
314
|
+
>
|
|
315
|
+
{BLOCK_ACTIONS.map((action) => (
|
|
316
|
+
<button
|
|
317
|
+
key={action}
|
|
318
|
+
type="button"
|
|
319
|
+
data-testid={`live-editor-${action}`}
|
|
320
|
+
title={labels[action]}
|
|
321
|
+
aria-label={labels[action]}
|
|
322
|
+
aria-busy={busy === action || undefined}
|
|
323
|
+
disabled={isDisabled(action)}
|
|
324
|
+
style={buttonStyle(action, isDisabled(action))}
|
|
325
|
+
onClick={() => onAct(target, action)}
|
|
326
|
+
>
|
|
327
|
+
<Icon>{ICONS[action]}</Icon>
|
|
328
|
+
</button>
|
|
329
|
+
))}
|
|
330
|
+
</div>
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* The live editor's action bar: hovering a home block outlines it and shows
|
|
336
|
+
* edit, hide, move, duplicate, add and delete; hovering the header or footer
|
|
337
|
+
* shows an edit button. Double-clicking either edits it. Each action is a
|
|
338
|
+
* message to the editor, which saves the change and reloads the preview.
|
|
339
|
+
*/
|
|
340
|
+
export function LiveEditorBar({ origin }: { origin: string }): ReactElement | null {
|
|
341
|
+
const [hovered, setHovered] = useState<HTMLElement | null>(null);
|
|
342
|
+
const [editing, setEditing] = useState<HTMLElement | null>(null);
|
|
343
|
+
const [busy, setBusy] = useState<BlockAction | null>(null);
|
|
344
|
+
const barRef = useRef<HTMLDivElement>(null);
|
|
345
|
+
// Taken after mount, so nothing reads the DOM while rendering.
|
|
346
|
+
const [host, setHost] = useState<HTMLElement | null>(null);
|
|
347
|
+
const labels = useLabels();
|
|
348
|
+
useHeldLinkClicks(barRef);
|
|
349
|
+
|
|
350
|
+
const act = useCallback(
|
|
351
|
+
(el: HTMLElement, action: BlockAction) => {
|
|
352
|
+
const area = areaOf(el);
|
|
353
|
+
if (area) {
|
|
354
|
+
postToEditor(origin, `preview::edit.${area}`, { id: `store-${area}` });
|
|
355
|
+
setEditing(el);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const id = el.getAttribute(BLOCK_ATTRIBUTE);
|
|
359
|
+
if (!id) return;
|
|
360
|
+
postToEditor(origin, `preview::${action}.component`, { id });
|
|
361
|
+
if (action === 'edit') setEditing(el);
|
|
362
|
+
else if (action === 'hide' || action === 'duplicate' || action === 'delete') setBusy(action);
|
|
363
|
+
},
|
|
364
|
+
[origin]
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
useEffect(() => {
|
|
368
|
+
const onOver = (event: MouseEvent) => {
|
|
369
|
+
// The bar sits over the block it acts on: reaching it keeps that block.
|
|
370
|
+
if (barRef.current?.contains(event.target as Node)) return;
|
|
371
|
+
setHovered(targetOf(event.target));
|
|
372
|
+
};
|
|
373
|
+
const onOut = (event: MouseEvent) => {
|
|
374
|
+
if (!event.relatedTarget) setHovered(null);
|
|
375
|
+
};
|
|
376
|
+
const onDoubleClick = (event: MouseEvent) => {
|
|
377
|
+
if (barRef.current?.contains(event.target as Node)) return;
|
|
378
|
+
const el = targetOf(event.target);
|
|
379
|
+
if (el) act(el, 'edit');
|
|
380
|
+
};
|
|
381
|
+
document.addEventListener('mouseover', onOver);
|
|
382
|
+
document.addEventListener('mouseout', onOut);
|
|
383
|
+
document.addEventListener('dblclick', onDoubleClick);
|
|
384
|
+
return () => {
|
|
385
|
+
document.removeEventListener('mouseover', onOver);
|
|
386
|
+
document.removeEventListener('mouseout', onOut);
|
|
387
|
+
document.removeEventListener('dblclick', onDoubleClick);
|
|
388
|
+
};
|
|
389
|
+
}, [act]);
|
|
390
|
+
|
|
391
|
+
useEffect(() => setHost(document.body), []);
|
|
392
|
+
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
if (!busy) return;
|
|
395
|
+
const timer = window.setTimeout(() => setBusy(null), BUSY_TIMEOUT_MS);
|
|
396
|
+
return () => window.clearTimeout(timer);
|
|
397
|
+
}, [busy]);
|
|
398
|
+
|
|
399
|
+
const target = connected(hovered);
|
|
400
|
+
const selected = connected(editing);
|
|
401
|
+
useLayoutTick(Boolean(target || selected));
|
|
402
|
+
|
|
403
|
+
if (!host || (!target && !selected)) return null;
|
|
404
|
+
|
|
405
|
+
const targetArea = target ? areaOf(target) : null;
|
|
406
|
+
|
|
407
|
+
return createPortal(
|
|
408
|
+
<>
|
|
409
|
+
{selected && selected !== target && <Outline el={selected} />}
|
|
410
|
+
{target && <Outline el={target} label={targetArea ? labels[targetArea] : undefined} />}
|
|
411
|
+
{target && (
|
|
412
|
+
<Toolbar target={target} labels={labels} busy={busy} barRef={barRef} onAct={act} />
|
|
413
|
+
)}
|
|
414
|
+
</>,
|
|
415
|
+
host
|
|
416
|
+
);
|
|
417
|
+
}
|