@salla.sa/twilight-theme-engine 1.0.130 → 1.0.132

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.
Files changed (238) hide show
  1. package/dist/{AddToCartForm-ZJIIU4I4.js → AddToCartForm-LUVIZGH5.js} +3 -3
  2. package/dist/{AddToCartForm-ZJIIU4I4.js.map → AddToCartForm-LUVIZGH5.js.map} +1 -1
  3. package/dist/{BlogAuthorPage-DNZSR42D.js → BlogAuthorPage-UC5JFBRH.js} +18 -18
  4. package/dist/{BlogAuthorPage-DNZSR42D.js.map → BlogAuthorPage-UC5JFBRH.js.map} +1 -1
  5. package/dist/{BlogCategoryPage-AC4DDQ7N.js → BlogCategoryPage-YZ6BN4QV.js} +18 -18
  6. package/dist/{BlogCategoryPage-AC4DDQ7N.js.map → BlogCategoryPage-YZ6BN4QV.js.map} +1 -1
  7. package/dist/{BlogPage-F5OY24RP.js → BlogPage-ERPCNHQV.js} +16 -16
  8. package/dist/{BlogPage-F5OY24RP.js.map → BlogPage-ERPCNHQV.js.map} +1 -1
  9. package/dist/{BlogSinglePage-YXC5WU3N.js → BlogSinglePage-TNVS5VCF.js} +16 -16
  10. package/dist/{BlogSinglePage-YXC5WU3N.js.map → BlogSinglePage-TNVS5VCF.js.map} +1 -1
  11. package/dist/{BlogTagPage-6QQ2CF2B.js → BlogTagPage-DKWJM6GQ.js} +18 -18
  12. package/dist/{BlogTagPage-6QQ2CF2B.js.map → BlogTagPage-DKWJM6GQ.js.map} +1 -1
  13. package/dist/{BrandsPage-UXWNTTT3.js → BrandsPage-ALLXOEZ7.js} +17 -17
  14. package/dist/{BrandsPage-UXWNTTT3.js.map → BrandsPage-ALLXOEZ7.js.map} +1 -1
  15. package/dist/{Breadcrumb-TUXEVRZZ.js → Breadcrumb-2TWWY76F.js} +16 -16
  16. package/dist/{Breadcrumb-TUXEVRZZ.js.map → Breadcrumb-2TWWY76F.js.map} +1 -1
  17. package/dist/{CartItem-B7AYUFGZ.js → CartItem-XNCZZQ4X.js} +16 -16
  18. package/dist/{CartItem-B7AYUFGZ.js.map → CartItem-XNCZZQ4X.js.map} +1 -1
  19. package/dist/{CartSummary-LSFD7QUY.js → CartSummary-ROELC4AF.js} +16 -16
  20. package/dist/{CartSummary-LSFD7QUY.js.map → CartSummary-ROELC4AF.js.map} +1 -1
  21. package/dist/{Copyright-HH2S2KDM.js → Copyright-UPGI2I5D.js} +3 -3
  22. package/dist/{Copyright-HH2S2KDM.js.map → Copyright-UPGI2I5D.js.map} +1 -1
  23. package/dist/{CustomerLayout-2NVQ6G72.js → CustomerLayout-YXTOHATN.js} +16 -16
  24. package/dist/{CustomerLayout-2NVQ6G72.js.map → CustomerLayout-YXTOHATN.js.map} +1 -1
  25. package/dist/{Footer-4LQIBAHJ.js → Footer-J4V5UUCF.js} +4 -4
  26. package/dist/{Footer-4LQIBAHJ.js.map → Footer-J4V5UUCF.js.map} +1 -1
  27. package/dist/{Header-VQTPIQPS.js → Header-5ENK5VKP.js} +8 -8
  28. package/dist/{Header-VQTPIQPS.js.map → Header-5ENK5VKP.js.map} +1 -1
  29. package/dist/{LiveEditorBar-DOSRO35J.js → LiveEditorBar-4AWOAJYX.js} +58 -9
  30. package/dist/LiveEditorBar-4AWOAJYX.js.map +1 -0
  31. package/dist/{LoyaltyPage-NSHSLS4O.js → LoyaltyPage-J6GSLDVZ.js} +16 -16
  32. package/dist/{LoyaltyPage-NSHSLS4O.js.map → LoyaltyPage-J6GSLDVZ.js.map} +1 -1
  33. package/dist/{LoyaltyPointsPage-7CUUKDLR.js → LoyaltyPointsPage-XP2RCLZA.js} +6 -6
  34. package/dist/{LoyaltyPointsPage-7CUUKDLR.js.map → LoyaltyPointsPage-XP2RCLZA.js.map} +1 -1
  35. package/dist/{MainMenu-NTSSUK6R.js → MainMenu-RMM6ZJWZ.js} +5 -5
  36. package/dist/{MainMenu-NTSSUK6R.js.map → MainMenu-RMM6ZJWZ.js.map} +1 -1
  37. package/dist/{MasterLayout-ZOT7XICQ.js → MasterLayout-BIAXVZNR.js} +16 -16
  38. package/dist/{MasterLayout-ZOT7XICQ.js.map → MasterLayout-BIAXVZNR.js.map} +1 -1
  39. package/dist/{MobileMenu-RBTT3KLS.js → MobileMenu-HYKQCDTC.js} +17 -17
  40. package/dist/{MobileMenu-RBTT3KLS.js.map → MobileMenu-HYKQCDTC.js.map} +1 -1
  41. package/dist/{NotificationsPage-T775PMFX.js → NotificationsPage-Q6EDPEQX.js} +16 -16
  42. package/dist/{NotificationsPage-T775PMFX.js.map → NotificationsPage-Q6EDPEQX.js.map} +1 -1
  43. package/dist/{OrderSinglePage-T5SKWUNW.js → OrderSinglePage-HGEECI7Q.js} +17 -17
  44. package/dist/{OrderSinglePage-T5SKWUNW.js.map → OrderSinglePage-HGEECI7Q.js.map} +1 -1
  45. package/dist/{OrdersPage-PGAD6DDY.js → OrdersPage-CBHLD5XG.js} +16 -16
  46. package/dist/{OrdersPage-PGAD6DDY.js.map → OrdersPage-CBHLD5XG.js.map} +1 -1
  47. package/dist/{PageSingle-6W7U5YLG.js → PageSingle-S6IRM4Q5.js} +3 -3
  48. package/dist/{PageSingle-6W7U5YLG.js.map → PageSingle-S6IRM4Q5.js.map} +1 -1
  49. package/dist/{ProductDetails-JFOFLMLV.js → ProductDetails-DHY35UDT.js} +4 -4
  50. package/dist/{ProductDetails-JFOFLMLV.js.map → ProductDetails-DHY35UDT.js.map} +1 -1
  51. package/dist/{ProfilePage-2HZYDJBM.js → ProfilePage-3ES62QH7.js} +16 -16
  52. package/dist/{ProfilePage-2HZYDJBM.js.map → ProfilePage-3ES62QH7.js.map} +1 -1
  53. package/dist/{ReviewsPage-FYAZU7FT.js → ReviewsPage-RFEOWEVU.js} +3 -3
  54. package/dist/{ReviewsPage-FYAZU7FT.js.map → ReviewsPage-RFEOWEVU.js.map} +1 -1
  55. package/dist/{SeoCartWidget-7SUVC6MT.js → SeoCartWidget-WJCQ76TI.js} +16 -16
  56. package/dist/{SeoCartWidget-7SUVC6MT.js.map → SeoCartWidget-WJCQ76TI.js.map} +1 -1
  57. package/dist/{SettingsPage-IBWVB4ZJ.js → SettingsPage-BHIVN22T.js} +16 -16
  58. package/dist/{SettingsPage-IBWVB4ZJ.js.map → SettingsPage-BHIVN22T.js.map} +1 -1
  59. package/dist/{StoreClosedNotification-CMOHA4LU.js → StoreClosedNotification-IYVXVJJO.js} +17 -17
  60. package/dist/{StoreClosedNotification-CMOHA4LU.js.map → StoreClosedNotification-IYVXVJJO.js.map} +1 -1
  61. package/dist/{TestimonialsPage-WJMIDBRM.js → TestimonialsPage-E7IKEHCT.js} +3 -3
  62. package/dist/{TestimonialsPage-WJMIDBRM.js.map → TestimonialsPage-E7IKEHCT.js.map} +1 -1
  63. package/dist/{ThankYouPage-NILOPG4H.js → ThankYouPage-DAZOZH6Y.js} +16 -16
  64. package/dist/{ThankYouPage-NILOPG4H.js.map → ThankYouPage-DAZOZH6Y.js.map} +1 -1
  65. package/dist/{WalletPage-5O553SIT.js → WalletPage-ZBCGMDSP.js} +17 -17
  66. package/dist/{WalletPage-5O553SIT.js.map → WalletPage-ZBCGMDSP.js.map} +1 -1
  67. package/dist/{WishlistPage-JPLKEMDX.js → WishlistPage-HAUJQL2G.js} +18 -18
  68. package/dist/{WishlistPage-JPLKEMDX.js.map → WishlistPage-HAUJQL2G.js.map} +1 -1
  69. package/dist/api/advertisement.js +2 -2
  70. package/dist/api/apps.js +2 -2
  71. package/dist/api/blog.js +3 -3
  72. package/dist/api/brands.js +3 -3
  73. package/dist/api/cart.js +3 -3
  74. package/dist/api/category.js +3 -3
  75. package/dist/api/client.js +1 -1
  76. package/dist/api/home.js +2 -2
  77. package/dist/api/loyalty.js +3 -3
  78. package/dist/api/menu.js +2 -2
  79. package/dist/api/notification.js +2 -2
  80. package/dist/api/order.js +3 -3
  81. package/dist/api/page.js +3 -3
  82. package/dist/api/product.js +3 -3
  83. package/dist/api/profile.js +1 -1
  84. package/dist/api/store.js +2 -2
  85. package/dist/api/translations.js +2 -2
  86. package/dist/api/user.js +2 -2
  87. package/dist/api/wallet.js +2 -2
  88. package/dist/api/wishlist.js +4 -4
  89. package/dist/{chunk-5JN6P5L5.js → chunk-2MUBQOS5.js} +6 -6
  90. package/dist/{chunk-5JN6P5L5.js.map → chunk-2MUBQOS5.js.map} +1 -1
  91. package/dist/{chunk-YGCPRUT6.js → chunk-5DOMRYLF.js} +3 -3
  92. package/dist/{chunk-YGCPRUT6.js.map → chunk-5DOMRYLF.js.map} +1 -1
  93. package/dist/{chunk-AXPZEXJN.js → chunk-5NN4OICC.js} +3 -3
  94. package/dist/{chunk-AXPZEXJN.js.map → chunk-5NN4OICC.js.map} +1 -1
  95. package/dist/{chunk-5DVSAKNY.js → chunk-5RUFKW7T.js} +4 -4
  96. package/dist/{chunk-5DVSAKNY.js.map → chunk-5RUFKW7T.js.map} +1 -1
  97. package/dist/{chunk-RXWWNPCR.js → chunk-6LMS7IYL.js} +27 -12
  98. package/dist/chunk-6LMS7IYL.js.map +1 -0
  99. package/dist/{chunk-4FYLW5WS.js → chunk-7E7CA72E.js} +3 -3
  100. package/dist/{chunk-4FYLW5WS.js.map → chunk-7E7CA72E.js.map} +1 -1
  101. package/dist/{chunk-HH7WFQLN.js → chunk-BAS4BPSB.js} +3 -3
  102. package/dist/{chunk-HH7WFQLN.js.map → chunk-BAS4BPSB.js.map} +1 -1
  103. package/dist/{chunk-EDCRELH3.js → chunk-BL6DCALA.js} +3 -3
  104. package/dist/{chunk-EDCRELH3.js.map → chunk-BL6DCALA.js.map} +1 -1
  105. package/dist/{chunk-X4A3D5O4.js → chunk-CGAKEPEC.js} +3 -3
  106. package/dist/{chunk-X4A3D5O4.js.map → chunk-CGAKEPEC.js.map} +1 -1
  107. package/dist/{chunk-OR6HPFZT.js → chunk-CHMWAYVU.js} +4 -4
  108. package/dist/{chunk-OR6HPFZT.js.map → chunk-CHMWAYVU.js.map} +1 -1
  109. package/dist/{chunk-JLBDDH4N.js → chunk-CQY64PLJ.js} +3 -3
  110. package/dist/{chunk-JLBDDH4N.js.map → chunk-CQY64PLJ.js.map} +1 -1
  111. package/dist/{chunk-54FS47CL.js → chunk-D5SYOOE2.js} +3 -3
  112. package/dist/{chunk-54FS47CL.js.map → chunk-D5SYOOE2.js.map} +1 -1
  113. package/dist/{chunk-ORBMN52O.js → chunk-DCPQ4Z7N.js} +4 -4
  114. package/dist/{chunk-ORBMN52O.js.map → chunk-DCPQ4Z7N.js.map} +1 -1
  115. package/dist/chunk-DOTKJOVG.js +14 -0
  116. package/dist/{chunk-2A2NODLC.js.map → chunk-DOTKJOVG.js.map} +1 -1
  117. package/dist/{chunk-T55LMU5R.js → chunk-DROQER6S.js} +3 -3
  118. package/dist/{chunk-T55LMU5R.js.map → chunk-DROQER6S.js.map} +1 -1
  119. package/dist/{chunk-D423MW2M.js → chunk-E7YBFA3H.js} +3 -3
  120. package/dist/{chunk-D423MW2M.js.map → chunk-E7YBFA3H.js.map} +1 -1
  121. package/dist/{chunk-AN2PETFM.js → chunk-EANN5L2E.js} +6 -6
  122. package/dist/{chunk-AN2PETFM.js.map → chunk-EANN5L2E.js.map} +1 -1
  123. package/dist/{chunk-672DTSG4.js → chunk-EJIMEI36.js} +7 -7
  124. package/dist/{chunk-672DTSG4.js.map → chunk-EJIMEI36.js.map} +1 -1
  125. package/dist/{chunk-CGDUSBLK.js → chunk-EJV3NYBP.js} +17 -18
  126. package/dist/chunk-EJV3NYBP.js.map +1 -0
  127. package/dist/{chunk-BSGHOYMT.js → chunk-F5NB3H5P.js} +3 -3
  128. package/dist/{chunk-BSGHOYMT.js.map → chunk-F5NB3H5P.js.map} +1 -1
  129. package/dist/{chunk-WYWI77EA.js → chunk-GLDGDTVU.js} +3 -3
  130. package/dist/{chunk-WYWI77EA.js.map → chunk-GLDGDTVU.js.map} +1 -1
  131. package/dist/{chunk-K3PQSDGA.js → chunk-GY6G7S3N.js} +4 -4
  132. package/dist/{chunk-K3PQSDGA.js.map → chunk-GY6G7S3N.js.map} +1 -1
  133. package/dist/{chunk-FHAHE46U.js → chunk-H2QBHOF2.js} +2 -2
  134. package/dist/{chunk-FHAHE46U.js.map → chunk-H2QBHOF2.js.map} +1 -1
  135. package/dist/{chunk-4SMWY54W.js → chunk-HHHDPYMO.js} +3 -3
  136. package/dist/{chunk-4SMWY54W.js.map → chunk-HHHDPYMO.js.map} +1 -1
  137. package/dist/chunk-IXHM24Z4.js +28 -0
  138. package/dist/chunk-IXHM24Z4.js.map +1 -0
  139. package/dist/{chunk-YSSJ2CQC.js → chunk-JB5XMO4D.js} +4 -4
  140. package/dist/{chunk-YSSJ2CQC.js.map → chunk-JB5XMO4D.js.map} +1 -1
  141. package/dist/{chunk-52MZ4V5T.js → chunk-KLSRARPU.js} +4 -4
  142. package/dist/{chunk-52MZ4V5T.js.map → chunk-KLSRARPU.js.map} +1 -1
  143. package/dist/{chunk-NLT6YWUD.js → chunk-MPQ5NACW.js} +4 -4
  144. package/dist/{chunk-NLT6YWUD.js.map → chunk-MPQ5NACW.js.map} +1 -1
  145. package/dist/{chunk-QYHNS2KS.js → chunk-NXJ4KAJQ.js} +4 -4
  146. package/dist/{chunk-QYHNS2KS.js.map → chunk-NXJ4KAJQ.js.map} +1 -1
  147. package/dist/{chunk-3CNXPHJE.js → chunk-PCEKL6S3.js} +3 -121
  148. package/dist/chunk-PCEKL6S3.js.map +1 -0
  149. package/dist/{chunk-IUEYRDEI.js → chunk-PGXRNW3Y.js} +3 -3
  150. package/dist/{chunk-IUEYRDEI.js.map → chunk-PGXRNW3Y.js.map} +1 -1
  151. package/dist/{chunk-ITMXD75H.js → chunk-RSKVPOMJ.js} +11 -44
  152. package/dist/chunk-RSKVPOMJ.js.map +1 -0
  153. package/dist/{chunk-NITRRCQV.js → chunk-TBTQQM45.js} +4 -4
  154. package/dist/{chunk-NITRRCQV.js.map → chunk-TBTQQM45.js.map} +1 -1
  155. package/dist/{chunk-2UQKQTPB.js → chunk-THQDHZ4K.js} +4 -4
  156. package/dist/{chunk-2UQKQTPB.js.map → chunk-THQDHZ4K.js.map} +1 -1
  157. package/dist/{chunk-RQ72QOIC.js → chunk-TI3Q2B3H.js} +7 -7
  158. package/dist/{chunk-RQ72QOIC.js.map → chunk-TI3Q2B3H.js.map} +1 -1
  159. package/dist/{chunk-KME6DTES.js → chunk-TOJM4ZIF.js} +7 -7
  160. package/dist/{chunk-KME6DTES.js.map → chunk-TOJM4ZIF.js.map} +1 -1
  161. package/dist/{chunk-ELARAFMR.js → chunk-TTZKDTD5.js} +3 -3
  162. package/dist/{chunk-ELARAFMR.js.map → chunk-TTZKDTD5.js.map} +1 -1
  163. package/dist/{chunk-EZP2KOEL.js → chunk-YMXOKWNO.js} +4 -4
  164. package/dist/{chunk-EZP2KOEL.js.map → chunk-YMXOKWNO.js.map} +1 -1
  165. package/dist/{chunk-AIPIJWOC.js → chunk-YQELP5ND.js} +3 -3
  166. package/dist/{chunk-AIPIJWOC.js.map → chunk-YQELP5ND.js.map} +1 -1
  167. package/dist/{chunk-GSI42HHP.js → chunk-YZDL2P6T.js} +3 -3
  168. package/dist/{chunk-GSI42HHP.js.map → chunk-YZDL2P6T.js.map} +1 -1
  169. package/dist/{chunk-I5XU5BQH.js → chunk-Z4N3WJ6R.js} +3 -3
  170. package/dist/{chunk-I5XU5BQH.js.map → chunk-Z4N3WJ6R.js.map} +1 -1
  171. package/dist/{chunk-SCM4P6QG.js → chunk-ZVZPCDEU.js} +3 -3
  172. package/dist/{chunk-SCM4P6QG.js.map → chunk-ZVZPCDEU.js.map} +1 -1
  173. package/dist/components/cart/index.js +1 -1
  174. package/dist/components/common/index.js +1 -1
  175. package/dist/components/drawer/index.js +14 -14
  176. package/dist/components/home/index.js +18 -18
  177. package/dist/components/layout/index.js +4 -4
  178. package/dist/components/live-editor/LiveEditorBar.d.ts.map +1 -1
  179. package/dist/components/live-editor/frame.d.ts +2 -0
  180. package/dist/components/live-editor/frame.d.ts.map +1 -1
  181. package/dist/components/live-editor/moves.d.ts +14 -0
  182. package/dist/components/live-editor/moves.d.ts.map +1 -0
  183. package/dist/components/product/index.js +15 -15
  184. package/dist/components/snippets/AppsSnippets.d.ts.map +1 -1
  185. package/dist/components/store/index.js +15 -15
  186. package/dist/dev/editor/index.js +1 -1
  187. package/dist/dev/index.js +1 -1
  188. package/dist/{document-class-2SKG4YZE.js → document-class-G5XELNQN.js} +12 -12
  189. package/dist/{document-class-2SKG4YZE.js.map → document-class-G5XELNQN.js.map} +1 -1
  190. package/dist/hooks/index.js +14 -14
  191. package/dist/hooks/useGtm.js +14 -14
  192. package/dist/hooks/useMoney.js +14 -14
  193. package/dist/hooks/useStore.js +14 -14
  194. package/dist/hooks/useUser.js +3 -3
  195. package/dist/index.js +14 -14
  196. package/dist/{navigation-WVVYQOOZ.js → navigation-S6ZL2WSI.js} +5 -5
  197. package/dist/{navigation-WVVYQOOZ.js.map → navigation-S6ZL2WSI.js.map} +1 -1
  198. package/dist/{navigation-7HBHI524.js → navigation-ZPJHUO4Z.js} +4 -4
  199. package/dist/{navigation-7HBHI524.js.map → navigation-ZPJHUO4Z.js.map} +1 -1
  200. package/dist/{not-found-ZN7HOUO4.js → not-found-KME662CU.js} +17 -17
  201. package/dist/{not-found-ZN7HOUO4.js.map → not-found-KME662CU.js.map} +1 -1
  202. package/dist/providers/index.js +14 -14
  203. package/dist/routes/account/orders.js +4 -4
  204. package/dist/routes/account.js +13 -13
  205. package/dist/routes/blog.js +8 -8
  206. package/dist/routes/brands.js +4 -4
  207. package/dist/routes/cart.js +23 -22
  208. package/dist/routes/cart.js.map +1 -1
  209. package/dist/routes/home/HomePage.d.ts.map +1 -1
  210. package/dist/routes/home.js +20 -19
  211. package/dist/routes/index.js +3 -3
  212. package/dist/routes/loyalty.js +5 -5
  213. package/dist/routes/page.js +4 -4
  214. package/dist/routes/product-listing.js +20 -20
  215. package/dist/routes/product.js +18 -18
  216. package/dist/routes/seo-redirects.js +3 -3
  217. package/dist/routes/testimonials.js +2 -2
  218. package/dist/routes/thank-you.js +4 -4
  219. package/dist/skeleton.js +20 -19
  220. package/dist/{store-lookup-KSHMPOFT.js → store-lookup-R5KJS7Z3.js} +8 -8
  221. package/dist/{store-lookup-KSHMPOFT.js.map → store-lookup-R5KJS7Z3.js.map} +1 -1
  222. package/dist/tanstack/router.d.ts.map +1 -1
  223. package/dist/tanstack.js +12 -12
  224. package/dist/utils/index.js +2 -2
  225. package/package.json +1 -1
  226. package/tailwind/components/live-editor/LiveEditorBar.tsx.txt +80 -8
  227. package/tailwind/components/live-editor/frame.ts.txt +1 -1
  228. package/tailwind/components/live-editor/moves.ts.txt +38 -0
  229. package/tailwind/components/snippets/AppsSnippets.tsx.txt +0 -4
  230. package/tailwind/routes/home/HomePage.tsx.txt +32 -6
  231. package/dist/LiveEditorBar-DOSRO35J.js.map +0 -1
  232. package/dist/chunk-2A2NODLC.js +0 -14
  233. package/dist/chunk-3CNXPHJE.js.map +0 -1
  234. package/dist/chunk-CGDUSBLK.js.map +0 -1
  235. package/dist/chunk-ITMXD75H.js.map +0 -1
  236. package/dist/chunk-RXWWNPCR.js.map +0 -1
  237. package/dist/utils/snippet-page-compat.d.ts +0 -43
  238. package/dist/utils/snippet-page-compat.d.ts.map +0 -1
package/dist/skeleton.js CHANGED
@@ -1,30 +1,31 @@
1
1
  export { BlogSkeleton, BreadcrumbSkeleton, CartSkeleton, CustomerLayoutSkeleton, CustomerPageSkeleton, PageSkeleton, ProductCardSkeleton, ProductDetailSkeleton, ProductGridSkeleton, SkeletonPulse } from './chunk-N7CCSGZF.js';
2
- export { HomeSkeleton } from './chunk-RXWWNPCR.js';
3
- import './chunk-AN2PETFM.js';
4
- import './chunk-T55LMU5R.js';
5
- import './chunk-K3PQSDGA.js';
6
- import './chunk-5JN6P5L5.js';
2
+ export { HomeSkeleton } from './chunk-6LMS7IYL.js';
3
+ import './chunk-IXHM24Z4.js';
4
+ import './chunk-EANN5L2E.js';
5
+ import './chunk-DROQER6S.js';
6
+ import './chunk-GY6G7S3N.js';
7
+ import './chunk-2MUBQOS5.js';
7
8
  import './chunk-Y32RHCOH.js';
8
- import './chunk-CGDUSBLK.js';
9
- import './chunk-FHAHE46U.js';
10
- import './chunk-672DTSG4.js';
11
- import './chunk-HH7WFQLN.js';
12
- import './chunk-3CNXPHJE.js';
9
+ import './chunk-EJV3NYBP.js';
10
+ import './chunk-H2QBHOF2.js';
11
+ import './chunk-EJIMEI36.js';
12
+ import './chunk-BAS4BPSB.js';
13
+ import './chunk-PCEKL6S3.js';
13
14
  import './chunk-JYV25VNZ.js';
14
- import './chunk-SCM4P6QG.js';
15
+ import './chunk-ZVZPCDEU.js';
15
16
  import './chunk-OXMUPNMH.js';
16
- import './chunk-AXPZEXJN.js';
17
+ import './chunk-5NN4OICC.js';
17
18
  import './chunk-VVZNW5CB.js';
18
19
  import './chunk-5FJFN3IW.js';
19
20
  import './chunk-GD26FI4J.js';
20
21
  import './chunk-FID76MUV.js';
21
22
  import './chunk-OM2GRPDH.js';
22
- import './chunk-WYWI77EA.js';
23
+ import './chunk-GLDGDTVU.js';
23
24
  import './chunk-OUW6WESU.js';
24
25
  import './chunk-BK5TBUGG.js';
25
26
  import './chunk-HI5V5X3S.js';
26
- import './chunk-GSI42HHP.js';
27
- import './chunk-ELARAFMR.js';
27
+ import './chunk-YZDL2P6T.js';
28
+ import './chunk-TTZKDTD5.js';
28
29
  import './chunk-MVT5AF2A.js';
29
30
  import './chunk-Z653O7MX.js';
30
31
  import './chunk-ZCH7W7DZ.js';
@@ -35,16 +36,16 @@ import './chunk-7V36I5GT.js';
35
36
  import './chunk-6WI7R2BD.js';
36
37
  import './chunk-JGVEGQHJ.js';
37
38
  import './chunk-OAMIDZKW.js';
38
- import './chunk-D423MW2M.js';
39
+ import './chunk-E7YBFA3H.js';
39
40
  import './chunk-OQIIJRAS.js';
40
41
  import './chunk-V2ZDTY6H.js';
41
- import './chunk-54FS47CL.js';
42
+ import './chunk-D5SYOOE2.js';
42
43
  import './chunk-5XDPAKF5.js';
43
44
  import './chunk-GCPEMNSU.js';
44
- import './chunk-BSGHOYMT.js';
45
+ import './chunk-F5NB3H5P.js';
45
46
  import './chunk-Z5M4YYWT.js';
46
47
  import './chunk-TYNZ5B2B.js';
47
- import './chunk-IUEYRDEI.js';
48
+ import './chunk-PGXRNW3Y.js';
48
49
  import './chunk-AXW67SY7.js';
49
50
  import './chunk-BYMOPN2S.js';
50
51
  import './chunk-SKLEJJ6M.js';
@@ -1,11 +1,11 @@
1
- import { category } from './chunk-5DVSAKNY.js';
2
- import { blog } from './chunk-QYHNS2KS.js';
3
- import { brand } from './chunk-EZP2KOEL.js';
4
- import { product } from './chunk-K3PQSDGA.js';
1
+ import { category } from './chunk-5RUFKW7T.js';
2
+ import { blog } from './chunk-NXJ4KAJQ.js';
3
+ import { brand } from './chunk-YMXOKWNO.js';
4
+ import { product } from './chunk-GY6G7S3N.js';
5
5
  import { DEV_LOOKUP_BUDGET_MS } from './chunk-OXMUPNMH.js';
6
- import './chunk-WYWI77EA.js';
6
+ import './chunk-GLDGDTVU.js';
7
7
  import './chunk-OUW6WESU.js';
8
- import './chunk-BSGHOYMT.js';
8
+ import './chunk-F5NB3H5P.js';
9
9
  import './chunk-Z5M4YYWT.js';
10
10
  import './chunk-2TLIULJZ.js';
11
11
  import './chunk-GYXUYHKO.js';
@@ -111,5 +111,5 @@ function lookupInStore(source, query) {
111
111
  }
112
112
 
113
113
  export { lookupInStore };
114
- //# sourceMappingURL=store-lookup-KSHMPOFT.js.map
115
- //# sourceMappingURL=store-lookup-KSHMPOFT.js.map
114
+ //# sourceMappingURL=store-lookup-R5KJS7Z3.js.map
115
+ //# sourceMappingURL=store-lookup-R5KJS7Z3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev/store-lookup.ts"],"names":["categories"],"mappings":"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","file":"store-lookup-KSHMPOFT.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"]}
1
+ {"version":3,"sources":["../src/dev/store-lookup.ts"],"names":["categories"],"mappings":"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","file":"store-lookup-R5KJS7Z3.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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/tanstack/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAwC,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAMpD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBhE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA2C7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAoED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,KAG7B,SAAS,GAAG,kRAOrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,sCA4BlE;AAyBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAa1E;AAkND;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uBAAuB,CAAC,EAAE,CAAC,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,uGA+HzE;AAED,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,QAAQ;QAChB,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;KACzC;IAED,UAAU,aAAc,SAAQ,oBAAoB;KAAG;CACxD"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/tanstack/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAMpD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBhE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA2C7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAoED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,KAG7B,SAAS,GAAG,kRAOrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,sCA4BlE;AAyBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAa1E;AAoKD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uBAAuB,CAAC,EAAE,CAAC,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,uGA6HzE;AAED,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,QAAQ;QAChB,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;KACzC;IAED,UAAU,aAAc,SAAQ,oBAAoB;KAAG;CACxD"}
package/dist/tanstack.js CHANGED
@@ -1,26 +1,26 @@
1
- export { tanstackDocumentAdapter as attrs, createRouter, createTwilightRootRoute, useTanstackDocumentAttrs as useAttrs } from './chunk-ITMXD75H.js';
2
- import { requestHostOf } from './chunk-EDCRELH3.js';
3
- export { TanStackLinkAdapter, TanStackNavigationProvider, createTanStackLinkAdapter } from './chunk-EDCRELH3.js';
1
+ export { tanstackDocumentAdapter as attrs, createRouter, createTwilightRootRoute, useTanstackDocumentAttrs as useAttrs } from './chunk-RSKVPOMJ.js';
2
+ import { requestHostOf } from './chunk-BL6DCALA.js';
3
+ export { TanStackLinkAdapter, TanStackNavigationProvider, createTanStackLinkAdapter } from './chunk-BL6DCALA.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-AIPIJWOC.js';
8
- import { readNativeAppHeaders } from './chunk-YGCPRUT6.js';
9
- import './chunk-4FYLW5WS.js';
10
- import './chunk-K3PQSDGA.js';
11
- import { rootHead } from './chunk-3CNXPHJE.js';
7
+ import './chunk-YQELP5ND.js';
8
+ import { readNativeAppHeaders } from './chunk-5DOMRYLF.js';
9
+ import './chunk-7E7CA72E.js';
10
+ import './chunk-GY6G7S3N.js';
11
+ import { rootHead } from './chunk-PCEKL6S3.js';
12
12
  import './chunk-JYV25VNZ.js';
13
- import './chunk-AXPZEXJN.js';
13
+ import './chunk-5NN4OICC.js';
14
14
  import './chunk-5FJFN3IW.js';
15
15
  import './chunk-GD26FI4J.js';
16
16
  import { maintenanceEvidence, MAINTENANCE_EVIDENCE_HEADER, maintenanceEvidenceHeader } from './chunk-FID76MUV.js';
17
17
  import './chunk-OM2GRPDH.js';
18
- import './chunk-WYWI77EA.js';
18
+ import './chunk-GLDGDTVU.js';
19
19
  import './chunk-OUW6WESU.js';
20
20
  import './chunk-JWXJPJBO.js';
21
21
  export { mergeDocumentDescriptors as mergeAttrs } from './chunk-CW625T2E.js';
22
- import './chunk-54FS47CL.js';
23
- import './chunk-BSGHOYMT.js';
22
+ import './chunk-D5SYOOE2.js';
23
+ import './chunk-F5NB3H5P.js';
24
24
  import './chunk-Z5M4YYWT.js';
25
25
  import './chunk-TYNZ5B2B.js';
26
26
  import './chunk-BYMOPN2S.js';
@@ -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-AIPIJWOC.js';
3
+ export { dispatchRouteChanged } from '../chunk-YQELP5ND.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-BSGHOYMT.js';
11
+ import '../chunk-F5NB3H5P.js';
12
12
  import '../chunk-Z5M4YYWT.js';
13
13
  export { getSallaSDK, getStoreIdentifier, onSallaEvent, whenSallaLoaded, whenSallaReady } from '../chunk-GYXUYHKO.js';
14
14
  export { AUTH_TOKEN_COOKIE_NAME, clearAuthTokenCookie, extractTokenFromCookies } from '../chunk-FHU2MXZA.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salla.sa/twilight-theme-engine",
3
- "version": "1.0.130",
3
+ "version": "1.0.132",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -7,9 +7,10 @@ import {
7
7
  type ReactElement,
8
8
  type RefObject,
9
9
  } from 'react';
10
- import { createPortal } from 'react-dom';
10
+ import { createPortal, flushSync } from 'react-dom';
11
11
  import { useTranslation } from '../../providers/I18nProvider';
12
12
  import { BLOCK_ATTRIBUTE, areaOf, postToEditor, targetOf, type BlockAction } from './frame';
13
+ import { moveLiveBlock } from './moves';
13
14
 
14
15
  const ACCENT = '#5dd5c4';
15
16
  const LAYER = 2147483000;
@@ -17,6 +18,8 @@ const LAYER = 2147483000;
17
18
  const BUSY_TIMEOUT_MS = 10_000;
18
19
  /** How long a link's click waits for a second one, so a double-click edits instead of navigating. */
19
20
  const DOUBLE_CLICK_MS = 300;
21
+ /** How long a moved block, and the one it trades places with, slide to their new places. */
22
+ const MOVE_MS = 300;
20
23
 
21
24
  /** Defaults for the `blocks.live_editor.*` keys, in the store's language. */
22
25
  const DEFAULT_LABELS = {
@@ -169,6 +172,45 @@ function blockSiblings(el: HTMLElement): HTMLElement[] {
169
172
  );
170
173
  }
171
174
 
175
+ /** Each block's slide while it runs, so a move made meanwhile starts from where the block is seen. */
176
+ const slides = new WeakMap<Element, Animation>();
177
+
178
+ /**
179
+ * Moves the block one place up or down on the page while the editor saves the
180
+ * order, sliding the blocks that change places from where they are seen. The
181
+ * slides it starts, or `null` when it can't move, and the editor shows the
182
+ * saved order by reloading the page.
183
+ */
184
+ function moveInPlace(el: HTMLElement, action: 'moveup' | 'movedown'): Animation[] | null {
185
+ const siblings = blockSiblings(el);
186
+ const from = siblings.indexOf(el);
187
+ const to = action === 'moveup' ? from - 1 : from + 1;
188
+ if (from === -1 || to < 0 || to >= siblings.length) return null;
189
+
190
+ // Where each block is seen, mid-slide included; its slide then gives way to the new one.
191
+ const before = new Map(siblings.map((block) => [block, block.getBoundingClientRect().top]));
192
+ for (const block of siblings) slides.get(block)?.cancel();
193
+ let moved = false;
194
+ // Committed before measuring again, so the blocks start their slide from where they were.
195
+ flushSync(() => {
196
+ moved = moveLiveBlock(from, to);
197
+ });
198
+ if (!moved) return null;
199
+ if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return [];
200
+ const started: Animation[] = [];
201
+ for (const [block, top] of before) {
202
+ const shift = top - block.getBoundingClientRect().top;
203
+ if (!shift || typeof block.animate !== 'function') continue;
204
+ const slide = block.animate([{ transform: `translateY(${shift}px)` }, { transform: 'none' }], {
205
+ duration: MOVE_MS,
206
+ easing: 'ease-in-out',
207
+ });
208
+ slides.set(block, slide);
209
+ started.push(slide);
210
+ }
211
+ return started;
212
+ }
213
+
172
214
  function connected(el: HTMLElement | null): HTMLElement | null {
173
215
  return el?.isConnected ? el : null;
174
216
  }
@@ -197,8 +239,14 @@ function boxOf(el: Element): Box {
197
239
  return { top, left, width: right - left, height: bottom - top };
198
240
  }
199
241
 
200
- function useLayoutTick(active: boolean): void {
242
+ /**
243
+ * Re-renders the bar when the page scrolls or resizes, so it stays on its
244
+ * block. The returned `follow` re-renders it every frame until the given
245
+ * slides end: a move changes the page without resizing it.
246
+ */
247
+ function useLayoutTick(active: boolean): (slides: readonly Animation[]) => void {
201
248
  const [, setTick] = useState(0);
249
+ const following = useRef(0);
202
250
  useEffect(() => {
203
251
  if (!active) return;
204
252
  let frame = 0;
@@ -217,6 +265,23 @@ function useLayoutTick(active: boolean): void {
217
265
  observer?.disconnect();
218
266
  };
219
267
  }, [active]);
268
+ // Stop following when the bar goes away.
269
+ useEffect(() => () => void (following.current += 1), []);
270
+
271
+ return useCallback((slides: readonly Animation[]) => {
272
+ const run = ++following.current;
273
+ let ended = false;
274
+ void Promise.allSettled(slides.map((slide) => slide.finished)).then(() => {
275
+ ended = true;
276
+ if (following.current === run) setTick((n) => n + 1);
277
+ });
278
+ const step = () => {
279
+ if (following.current !== run) return;
280
+ setTick((n) => n + 1);
281
+ if (!ended) requestAnimationFrame(step);
282
+ };
283
+ step();
284
+ }, []);
220
285
  }
221
286
 
222
287
  type LabelKey = keyof typeof DEFAULT_LABELS.en;
@@ -393,6 +458,9 @@ export function LiveEditorBar({
393
458
  const [host, setHost] = useState<HTMLElement | null>(null);
394
459
  const labels = useLabels();
395
460
  useHeldLinkClicks(barRef);
461
+ const target = connected(hovered);
462
+ const selected = connected(editing);
463
+ const follow = useLayoutTick(Boolean(target || selected));
396
464
 
397
465
  const act = useCallback(
398
466
  (el: HTMLElement, action: BlockAction) => {
@@ -404,12 +472,20 @@ export function LiveEditorBar({
404
472
  }
405
473
  const id = el.getAttribute(BLOCK_ATTRIBUTE);
406
474
  if (!id) return;
407
- postToEditor(origin, `preview::${action}.component`, blockRefOf(el, id));
475
+ // Which copy it is, from where it is before it moves.
476
+ const ref = blockRefOf(el, id);
477
+ // `moved`: the page shows the new order, so the editor saves it without a reload. The dev editor's layout moves it.
478
+ const slid =
479
+ !dev && (action === 'moveup' || action === 'movedown') ? moveInPlace(el, action) : null;
480
+ const moved = slid !== null;
481
+ postToEditor(origin, `preview::${action}.component`, moved ? { ...ref, moved } : ref);
482
+ // The bar rides along with its block and knows its new place.
483
+ if (slid) follow(slid);
408
484
  if (action === 'edit') setEditing(el);
409
485
  else if (!dev && (action === 'hide' || action === 'duplicate' || action === 'delete'))
410
486
  setBusy(action);
411
487
  },
412
- [origin, dev]
488
+ [origin, dev, follow]
413
489
  );
414
490
 
415
491
  useEffect(() => {
@@ -444,10 +520,6 @@ export function LiveEditorBar({
444
520
  return () => window.clearTimeout(timer);
445
521
  }, [busy]);
446
522
 
447
- const target = connected(hovered);
448
- const selected = connected(editing);
449
- useLayoutTick(Boolean(target || selected));
450
-
451
523
  if (!host || (!target && !selected)) return null;
452
524
 
453
525
  const targetArea = target ? areaOf(target) : null;
@@ -105,7 +105,7 @@ export function previewTheme(theme: Theme): Theme {
105
105
  export function postToEditor(
106
106
  origin: string,
107
107
  action: LiveEditorMessage | typeof FRAME_LOADED_ACTION,
108
- data?: { id: string }
108
+ data?: { id: string; copy?: number; moved?: boolean }
109
109
  ): void {
110
110
  window.parent.postMessage({ action, data, is_salla: true }, origin);
111
111
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Moving a home block in the theme editor's preview without reloading it: the
3
+ * editor saves the new order, and the home page shows it right away, the way
4
+ * the twig themes' `live-themes-editor.js` moves a section on the page.
5
+ */
6
+
7
+ import { useEffect } from 'react';
8
+
9
+ type Mover = (from: number, to: number) => void;
10
+
11
+ /** The home page on screen, if any; it alone knows the order its blocks render in. */
12
+ let mover: Mover | null = null;
13
+
14
+ /** Lets the bar move the page's blocks while the page is mounted. */
15
+ export function useLiveBlockMoves(onMove: Mover): void {
16
+ useEffect(() => {
17
+ mover = onMove;
18
+ return () => {
19
+ if (mover === onMove) mover = null;
20
+ };
21
+ }, [onMove]);
22
+ }
23
+
24
+ /** Moves the block rendered at `from` to `to`; `false` when no home page is on screen. */
25
+ export function moveLiveBlock(from: number, to: number): boolean {
26
+ if (!mover) return false;
27
+ mover(from, to);
28
+ return true;
29
+ }
30
+
31
+ /** `order` with the entry at `from` moved to `to`; as it is when either is out of range. */
32
+ export function reorder(order: readonly number[], from: number, to: number): number[] {
33
+ const next = [...order];
34
+ if (from === to || from < 0 || to < 0 || from >= next.length || to >= next.length) return next;
35
+ const [moved] = next.splice(from, 1);
36
+ next.splice(to, 0, moved);
37
+ return next;
38
+ }
@@ -3,7 +3,6 @@ import { useQuery } from '@tanstack/react-query';
3
3
  import { apps, type AppSnippetRow } from '../../api/apps';
4
4
  import { installAppScope } from '../../utils/app-scope';
5
5
  import { applyThemeHookSlots } from '../../utils/theme-hook-slots';
6
- import { setSnippetPageTargets } from '../../utils/snippet-page-compat';
7
6
  import { getTwilightContext } from '../../twilight/context';
8
7
 
9
8
  /** How long to wait on the SDK / settings before injecting anyway. */
@@ -181,9 +180,6 @@ export function AppsSnippets() {
181
180
  [data]
182
181
  );
183
182
 
184
- // Pages these snippets check once on load: navigating to or from them reloads the document.
185
- useEffect(() => setSnippetPageTargets(owned), [owned]);
186
-
187
183
  // Every CDN snippet → a real `<script>` tag in the SSR body (rendered below).
188
184
  const ssrCdnScripts = useMemo<SsrCdnScript[]>(
189
185
  () =>
@@ -1,8 +1,10 @@
1
- import { memo } from 'react';
1
+ import { memo, useCallback, useState } from 'react';
2
2
  import { useDevHomeBlocks } from '../../dev/dev-settings-store';
3
3
  import { HookSlot } from '../../hooks';
4
4
  import { HomeComponentRenderer, ReorderProducts } from '../../components/home';
5
+ import { reorder, useLiveBlockMoves } from '../../components/live-editor/moves';
5
6
  import type { HomePageProps } from './types';
7
+ import type { HomeComponentData } from '../../types';
6
8
  import { Pulse } from '@salla.sa/twilight-components-react';
7
9
 
8
10
  export const HomeSkeleton = memo(function HomeSkeleton() {
@@ -31,20 +33,44 @@ export const HomeSkeleton = memo(function HomeSkeleton() {
31
33
  );
32
34
  });
33
35
 
36
+ /** The blocks' places in the store's order: 0, 1, 2… */
37
+ const storeOrder = (blocks: readonly unknown[]) => Array.from(blocks, (_, at) => at);
38
+
34
39
  export const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {
35
40
  // Dev-mode only: the dev editor's layout replaces the store's blocks while it
36
41
  // is on. No-op passthrough in production builds.
37
42
  const renderedComponents = useDevHomeBlocks(components);
43
+ // The theme editor's preview moves blocks in place while the editor saves the
44
+ // order; blocks from the server (a new page, a reload) start over from theirs.
45
+ const [moved, setMoved] = useState<{ source: HomeComponentData[]; order: number[] } | null>(null);
46
+ const order = moved?.source === renderedComponents ? moved.order : null;
47
+ const onMove = useCallback(
48
+ (from: number, to: number) =>
49
+ setMoved((prev) => ({
50
+ source: renderedComponents,
51
+ order: reorder(
52
+ prev?.source === renderedComponents ? prev.order : storeOrder(renderedComponents),
53
+ from,
54
+ to
55
+ ),
56
+ })),
57
+ [renderedComponents]
58
+ );
59
+ useLiveBlockMoves(onMove);
60
+ const placed = order ?? storeOrder(renderedComponents);
61
+
38
62
  return (
39
63
  <>
40
64
  <HookSlot name="home:start" />
41
65
  <HookSlot name="home:content" />
42
- {renderedComponents.map((data, index) => (
66
+ {placed.map((at, index) => {
67
+ const data = renderedComponents[at];
43
68
  // `data.key` is the twilight.json catalog id, shared by every placement
44
- // of that block. Platform blocks send null. Position is unique; a dev
45
- // layout block keeps its own id so a reorder doesn't remount the rest.
46
- <HomeComponentRenderer key={data.__dev_id ?? index} data={data} index={index} />
47
- ))}
69
+ // of that block. Platform blocks send null. The block's place in the
70
+ // store's order is unique and stays with it when the preview moves it, so
71
+ // a move keeps its state; a dev layout block keeps its own id.
72
+ return <HomeComponentRenderer key={data.__dev_id ?? at} data={data} index={index} />;
73
+ })}
48
74
  <HookSlot name="home:end" />
49
75
  <ReorderProducts />
50
76
  </>
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/live-editor/LiveEditorBar.tsx"],"names":[],"mappings":"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","file":"LiveEditorBar-DOSRO35J.js","sourcesContent":["import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactElement,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { BLOCK_ATTRIBUTE, areaOf, postToEditor, targetOf, type BlockAction } from './frame';\n\nconst ACCENT = '#5dd5c4';\nconst LAYER = 2147483000;\n/** The editor reloads the preview after hide, duplicate and delete; stop waiting if it doesn't. */\nconst BUSY_TIMEOUT_MS = 10_000;\n/** How long a link's click waits for a second one, so a double-click edits instead of navigating. */\nconst DOUBLE_CLICK_MS = 300;\n\n/** Defaults for the `blocks.live_editor.*` keys, in the store's language. */\nconst DEFAULT_LABELS = {\n ar: {\n edit: 'تعديل',\n hide: 'إخفاء',\n moveup: 'تحريك لأعلى',\n movedown: 'تحريك لأسفل',\n duplicate: 'تكرار',\n add: 'إضافة عنصر',\n delete: 'حذف',\n header: 'رأس الصفحة',\n footer: 'ذيل الصفحة',\n },\n en: {\n edit: 'Edit',\n hide: 'Hide',\n moveup: 'Move up',\n movedown: 'Move down',\n duplicate: 'Duplicate',\n add: 'Add element',\n delete: 'Delete',\n header: 'Header',\n footer: 'Footer',\n },\n} as const;\n\n/** Twig's order, read from the start of the line: edit first, delete last. */\nconst BLOCK_ACTIONS: BlockAction[] = [\n 'edit',\n 'hide',\n 'moveup',\n 'movedown',\n 'duplicate',\n 'add',\n 'delete',\n];\n\nconst DEV_ACTIONS = BLOCK_ACTIONS.filter((action) => action !== 'hide');\n\n/** Lucide-style 24px stroke icons. */\nconst ICONS: Record<BlockAction, ReactElement> = {\n edit: (\n <>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </>\n ),\n hide: (\n <>\n <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\" />\n <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\" />\n <path d=\"M9.88 9.88a3 3 0 1 0 4.24 4.24\" />\n <path d=\"m2 2 20 20\" />\n </>\n ),\n moveup: <path d=\"m18 15-6-6-6 6\" />,\n movedown: <path d=\"m6 9 6 6 6-6\" />,\n duplicate: (\n <>\n <rect x=\"8\" y=\"8\" width=\"14\" height=\"14\" rx=\"2\" />\n <path d=\"M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2\" />\n </>\n ),\n add: <path d=\"M12 5v14M5 12h14\" />,\n delete: (\n <>\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </>\n ),\n};\n\nconst OUTLINE: CSSProperties = {\n position: 'fixed',\n zIndex: LAYER,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n border: `2px solid ${ACCENT}`,\n};\n\nconst CHIP: CSSProperties = {\n position: 'absolute',\n top: 0,\n insetInlineStart: 0,\n padding: '4px 12px',\n background: ACCENT,\n color: '#0f172a',\n font: '500 14px/1.4 system-ui, sans-serif',\n whiteSpace: 'nowrap',\n};\n\nconst BAR: CSSProperties = {\n position: 'fixed',\n zIndex: LAYER + 1,\n display: 'flex',\n gap: 4,\n padding: 6,\n background: '#fff',\n borderRadius: 8,\n boxShadow: '0 4px 16px rgba(15, 23, 42, 0.18)',\n transform: 'translateX(-50%)',\n};\n\nfunction buttonStyle(action: BlockAction | 'area', disabled: boolean): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 6,\n minWidth: 36,\n height: 36,\n padding: '0 8px',\n border: 0,\n borderRadius: 6,\n background: 'transparent',\n color: action === 'delete' ? '#e11d48' : action === 'edit' ? '#0d9488' : '#475569',\n font: '500 14px/1 system-ui, sans-serif',\n cursor: disabled ? 'default' : 'pointer',\n opacity: disabled ? 0.35 : 1,\n };\n}\n\nfunction Icon({ children }: { children: ReactElement }) {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n {children}\n </svg>\n );\n}\n\n/** The blocks `el` can trade places with: its siblings in the same list. */\nfunction blockSiblings(el: HTMLElement): HTMLElement[] {\n const parent = el.parentElement;\n if (!parent) return [el];\n return Array.from(parent.children).filter(\n (child): child is HTMLElement =>\n child instanceof HTMLElement && child.hasAttribute(BLOCK_ATTRIBUTE)\n );\n}\n\nfunction connected(el: HTMLElement | null): HTMLElement | null {\n return el?.isConnected ? el : null;\n}\n\n/** Re-renders on scroll, resize and layout shifts, so the overlay follows what it outlines. */\ninterface Box {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\n/**\n * Where `el` is on screen. One with no box of its own (`display: contents`, as\n * Raed's header) measures 0×0 at the corner, so it's measured by its children.\n */\nfunction boxOf(el: Element): Box {\n const rect = el.getBoundingClientRect();\n if (rect.width || rect.height) return rect;\n const boxes = Array.from(el.children, boxOf).filter((box) => box.width || box.height);\n if (!boxes.length) return rect;\n const top = Math.min(...boxes.map((box) => box.top));\n const left = Math.min(...boxes.map((box) => box.left));\n const right = Math.max(...boxes.map((box) => box.left + box.width));\n const bottom = Math.max(...boxes.map((box) => box.top + box.height));\n return { top, left, width: right - left, height: bottom - top };\n}\n\nfunction useLayoutTick(active: boolean): void {\n const [, setTick] = useState(0);\n useEffect(() => {\n if (!active) return;\n let frame = 0;\n const schedule = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => setTick((n) => n + 1));\n };\n window.addEventListener('scroll', schedule, { capture: true, passive: true });\n window.addEventListener('resize', schedule);\n const observer = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(schedule) : null;\n observer?.observe(document.body);\n return () => {\n cancelAnimationFrame(frame);\n window.removeEventListener('scroll', schedule, { capture: true });\n window.removeEventListener('resize', schedule);\n observer?.disconnect();\n };\n }, [active]);\n}\n\ntype LabelKey = keyof typeof DEFAULT_LABELS.en;\ntype Labels = Record<LabelKey, string>;\n\nfunction useLabels(): Labels {\n const { t, i18n } = useTranslation();\n const defaults = i18n?.language?.startsWith('ar') ? DEFAULT_LABELS.ar : DEFAULT_LABELS.en;\n return Object.fromEntries(\n (Object.keys(defaults) as LabelKey[]).map((key) => [\n key,\n t(`blocks.live_editor.${key}`, { defaultValue: defaults[key] }),\n ])\n ) as Labels;\n}\n\n/**\n * Holds a link's click inside a block, the header or the footer for\n * {@link DOUBLE_CLICK_MS}: a second click on the same link makes it a\n * double-click, which edits the area, and the link never navigates; otherwise\n * the click is replayed. A click on another link drops the first one.\n */\nfunction useHeldLinkClicks(barRef: RefObject<HTMLDivElement | null>): void {\n useEffect(() => {\n let held: { link: HTMLAnchorElement; timer: number } | null = null;\n let replaying = false;\n\n const onClick = (event: MouseEvent) => {\n if (replaying || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n if (barRef.current?.contains(event.target as Node)) return;\n const link = event.target instanceof Element ? event.target.closest('a[href]') : null;\n if (!(link instanceof HTMLAnchorElement) || !targetOf(link)) return;\n\n // Before the router's own handler, which sits below the document.\n event.preventDefault();\n event.stopPropagation();\n const previous = held;\n if (previous) {\n window.clearTimeout(previous.timer);\n held = null;\n if (previous.link === link) return;\n }\n const timer = window.setTimeout(() => {\n held = null;\n replaying = true;\n link.click();\n replaying = false;\n }, DOUBLE_CLICK_MS);\n held = { link, timer };\n };\n\n document.addEventListener('click', onClick, true);\n return () => {\n document.removeEventListener('click', onClick, true);\n if (held) window.clearTimeout(held.timer);\n };\n }, [barRef]);\n}\n\nfunction Outline({ el, label }: { el: HTMLElement; label?: string }) {\n const rect = boxOf(el);\n return (\n <div\n data-testid=\"live-editor-outline\"\n style={{ ...OUTLINE, top: rect.top, left: rect.left, width: rect.width, height: rect.height }}\n >\n {label && <span style={CHIP}>{label}</span>}\n </div>\n );\n}\n\ninterface ToolbarProps {\n target: HTMLElement;\n labels: Labels;\n busy: BlockAction | null;\n barRef: RefObject<HTMLDivElement | null>;\n actions: BlockAction[];\n onAct: (el: HTMLElement, action: BlockAction) => void;\n}\n\n/** One edit button for the header or footer; the full set for a block. */\nfunction Toolbar({ target, labels, busy, barRef, actions, onAct }: ToolbarProps) {\n const rect = boxOf(target);\n const style: CSSProperties = {\n ...BAR,\n top: Math.max(rect.top + 8, 8),\n left: rect.left + rect.width / 2,\n };\n\n if (areaOf(target)) {\n return (\n <div ref={barRef} data-testid=\"live-editor-bar\" style={style}>\n <button\n type=\"button\"\n data-testid=\"live-editor-edit\"\n style={buttonStyle('area', false)}\n onClick={() => onAct(target, 'edit')}\n >\n <Icon>{ICONS.edit}</Icon>\n {labels.edit}\n </button>\n </div>\n );\n }\n\n const siblings = blockSiblings(target);\n const index = siblings.indexOf(target);\n const isDisabled = (action: BlockAction) =>\n busy !== null ||\n (action === 'moveup' && index <= 0) ||\n (action === 'movedown' && index >= siblings.length - 1);\n\n return (\n <div\n ref={barRef}\n data-testid=\"live-editor-bar\"\n role=\"toolbar\"\n aria-label={labels.edit}\n style={style}\n >\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n data-testid={`live-editor-${action}`}\n title={labels[action]}\n aria-label={labels[action]}\n aria-busy={busy === action || undefined}\n disabled={isDisabled(action)}\n style={buttonStyle(action, isDisabled(action))}\n onClick={() => onAct(target, action)}\n >\n <Icon>{ICONS[action]}</Icon>\n </button>\n ))}\n </div>\n );\n}\n\n/**\n * The block an action names. A uuid is shared by every copy of one component,\n * so it comes with which copy, in page order; a row id is unique on its own.\n */\nfunction blockRefOf(el: HTMLElement, id: string): { id: string; copy?: number } {\n if (/^\\d+$/.test(id)) return { id };\n const copies = Array.from(document.querySelectorAll(`[${BLOCK_ATTRIBUTE}]`)).filter(\n (block) => block.getAttribute(BLOCK_ATTRIBUTE) === id\n );\n return { id, copy: copies.indexOf(el) };\n}\n\n/**\n * The live editor's action bar: hovering a home block outlines it and shows\n * edit, hide, move, duplicate, add and delete; hovering the header or footer\n * shows an edit button. Double-clicking either edits it. Each action is a\n * message to the editor, which saves the change and reloads the preview.\n *\n * In the engine's dev editor (`dev`) edits reach the page live, so nothing\n * waits for a reload, and there is no hide: its layout has no hidden blocks.\n */\nexport function LiveEditorBar({\n origin,\n dev = false,\n}: {\n origin: string;\n dev?: boolean;\n}): ReactElement | null {\n const [hovered, setHovered] = useState<HTMLElement | null>(null);\n const [editing, setEditing] = useState<HTMLElement | null>(null);\n const [busy, setBusy] = useState<BlockAction | null>(null);\n const barRef = useRef<HTMLDivElement>(null);\n // Taken after mount, so nothing reads the DOM while rendering.\n const [host, setHost] = useState<HTMLElement | null>(null);\n const labels = useLabels();\n useHeldLinkClicks(barRef);\n\n const act = useCallback(\n (el: HTMLElement, action: BlockAction) => {\n const area = areaOf(el);\n if (area) {\n postToEditor(origin, `preview::edit.${area}`, { id: `store-${area}` });\n setEditing(el);\n return;\n }\n const id = el.getAttribute(BLOCK_ATTRIBUTE);\n if (!id) return;\n postToEditor(origin, `preview::${action}.component`, blockRefOf(el, id));\n if (action === 'edit') setEditing(el);\n else if (!dev && (action === 'hide' || action === 'duplicate' || action === 'delete'))\n setBusy(action);\n },\n [origin, dev]\n );\n\n useEffect(() => {\n const onOver = (event: MouseEvent) => {\n // The bar sits over the block it acts on: reaching it keeps that block.\n if (barRef.current?.contains(event.target as Node)) return;\n setHovered(targetOf(event.target));\n };\n const onOut = (event: MouseEvent) => {\n if (!event.relatedTarget) setHovered(null);\n };\n const onDoubleClick = (event: MouseEvent) => {\n if (barRef.current?.contains(event.target as Node)) return;\n const el = targetOf(event.target);\n if (el) act(el, 'edit');\n };\n document.addEventListener('mouseover', onOver);\n document.addEventListener('mouseout', onOut);\n document.addEventListener('dblclick', onDoubleClick);\n return () => {\n document.removeEventListener('mouseover', onOver);\n document.removeEventListener('mouseout', onOut);\n document.removeEventListener('dblclick', onDoubleClick);\n };\n }, [act]);\n\n useEffect(() => setHost(document.body), []);\n\n useEffect(() => {\n if (!busy) return;\n const timer = window.setTimeout(() => setBusy(null), BUSY_TIMEOUT_MS);\n return () => window.clearTimeout(timer);\n }, [busy]);\n\n const target = connected(hovered);\n const selected = connected(editing);\n useLayoutTick(Boolean(target || selected));\n\n if (!host || (!target && !selected)) return null;\n\n const targetArea = target ? areaOf(target) : null;\n\n return createPortal(\n <>\n {selected && selected !== target && <Outline el={selected} />}\n {target && <Outline el={target} label={targetArea ? labels[targetArea] : undefined} />}\n {target && (\n <Toolbar\n target={target}\n labels={labels}\n busy={busy}\n barRef={barRef}\n actions={dev ? DEV_ACTIONS : BLOCK_ACTIONS}\n onAct={act}\n />\n )}\n </>,\n host\n );\n}\n"]}
@@ -1,14 +0,0 @@
1
- import { lazy } from 'react';
2
-
3
- // src/components/cart/lazy.ts
4
- var LazyCartItem = lazy(() => import('./CartItem-B7AYUFGZ.js').then((m) => ({ default: m.CartItem })));
5
- var LazyCartSummary = lazy(
6
- () => import('./CartSummary-LSFD7QUY.js').then((m) => ({ default: m.CartSummary }))
7
- );
8
- var LazySeoCartWidget = lazy(
9
- () => import('./SeoCartWidget-7SUVC6MT.js').then((m) => ({ default: m.SeoCartWidget }))
10
- );
11
-
12
- export { LazyCartItem, LazyCartSummary, LazySeoCartWidget };
13
- //# sourceMappingURL=chunk-2A2NODLC.js.map
14
- //# sourceMappingURL=chunk-2A2NODLC.js.map