@fayz-ai/storefront 0.9.0 → 0.11.0

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 (391) hide show
  1. package/README.md +3 -3
  2. package/dist/app/createStorefrontApp.d.ts +65 -0
  3. package/dist/app/createStorefrontApp.d.ts.map +1 -0
  4. package/dist/{define.d.ts → app/define.d.ts} +3 -3
  5. package/dist/app/define.d.ts.map +1 -0
  6. package/dist/app/hydration.d.ts +37 -0
  7. package/dist/app/hydration.d.ts.map +1 -0
  8. package/dist/app/prerender.d.ts +57 -0
  9. package/dist/app/prerender.d.ts.map +1 -0
  10. package/dist/{router.d.ts → app/router.d.ts} +140 -113
  11. package/dist/app/router.d.ts.map +1 -0
  12. package/dist/{scaffold.d.ts → app/scaffold.d.ts} +2 -2
  13. package/dist/app/scaffold.d.ts.map +1 -0
  14. package/dist/app/serving.d.ts +70 -0
  15. package/dist/app/serving.d.ts.map +1 -0
  16. package/dist/app/static-render.d.ts +46 -0
  17. package/dist/app/static-render.d.ts.map +1 -0
  18. package/dist/blocks/block-at-path.d.ts +59 -0
  19. package/dist/blocks/block-at-path.d.ts.map +1 -0
  20. package/dist/blocks/page-blocks.d.ts +163 -0
  21. package/dist/blocks/page-blocks.d.ts.map +1 -0
  22. package/dist/blocks/page-data.d.ts +105 -0
  23. package/dist/blocks/page-data.d.ts.map +1 -0
  24. package/dist/{blocks.d.ts → blocks/registry.d.ts} +1 -1
  25. package/dist/blocks/registry.d.ts.map +1 -0
  26. package/dist/{sections.d.ts → blocks/sections.d.ts} +40 -2
  27. package/dist/blocks/sections.d.ts.map +1 -0
  28. package/dist/chunk-6IXTENLB.js +162 -0
  29. package/dist/chunk-6IXTENLB.js.map +1 -0
  30. package/dist/chunk-SX3J3QIT.js +11046 -0
  31. package/dist/chunk-SX3J3QIT.js.map +1 -0
  32. package/dist/components/PaymentTerms.d.ts +34 -0
  33. package/dist/components/PaymentTerms.d.ts.map +1 -0
  34. package/dist/components/Skeleton.d.ts +17 -0
  35. package/dist/components/Skeleton.d.ts.map +1 -0
  36. package/dist/components/SmoothImage.d.ts +1 -1
  37. package/dist/components/SmoothImage.d.ts.map +1 -1
  38. package/dist/components/account/CustomerAccountShell.d.ts +17 -0
  39. package/dist/components/account/CustomerAccountShell.d.ts.map +1 -0
  40. package/dist/components/account/SignInModal.d.ts.map +1 -0
  41. package/dist/components/account/section.d.ts +15 -0
  42. package/dist/components/account/section.d.ts.map +1 -0
  43. package/dist/components/cart/CartDrawer.d.ts.map +1 -0
  44. package/dist/components/cart/QuantityInput.d.ts.map +1 -0
  45. package/dist/components/checkout/CheckoutPayment.d.ts +17 -0
  46. package/dist/components/checkout/CheckoutPayment.d.ts.map +1 -0
  47. package/dist/components/checkout/CheckoutSteps.d.ts +9 -0
  48. package/dist/components/checkout/CheckoutSteps.d.ts.map +1 -0
  49. package/dist/components/checkout/DeliveryEstimator.d.ts.map +1 -0
  50. package/dist/components/collection/CategoryShowcase.d.ts +44 -0
  51. package/dist/components/collection/CategoryShowcase.d.ts.map +1 -0
  52. package/dist/components/collection/FiltersPanel.d.ts +19 -0
  53. package/dist/components/collection/FiltersPanel.d.ts.map +1 -0
  54. package/dist/components/collection/ProductGrid.d.ts.map +1 -0
  55. package/dist/components/layout/PageBodyBlocks.d.ts +40 -0
  56. package/dist/components/layout/PageBodyBlocks.d.ts.map +1 -0
  57. package/dist/components/layout/SearchOverlay.d.ts +13 -0
  58. package/dist/components/layout/SearchOverlay.d.ts.map +1 -0
  59. package/dist/components/layout/StorefrontErrorBoundary.d.ts.map +1 -0
  60. package/dist/components/layout/StorefrontFooter.d.ts.map +1 -0
  61. package/dist/components/layout/StorefrontHeader.d.ts.map +1 -0
  62. package/dist/components/layout/Toaster.d.ts.map +1 -0
  63. package/dist/components/marketing/CollectionSections.d.ts +463 -0
  64. package/dist/components/marketing/CollectionSections.d.ts.map +1 -0
  65. package/dist/components/marketing/ConversionSections.d.ts +221 -0
  66. package/dist/components/marketing/ConversionSections.d.ts.map +1 -0
  67. package/dist/components/marketing/EditorialSections.d.ts +248 -0
  68. package/dist/components/marketing/EditorialSections.d.ts.map +1 -0
  69. package/dist/components/marketing/EntityList.d.ts +97 -0
  70. package/dist/components/marketing/EntityList.d.ts.map +1 -0
  71. package/dist/components/marketing/FormBlock.d.ts +167 -0
  72. package/dist/components/marketing/FormBlock.d.ts.map +1 -0
  73. package/dist/components/marketing/HeroSection.d.ts +125 -0
  74. package/dist/components/marketing/HeroSection.d.ts.map +1 -0
  75. package/dist/components/marketing/MediaCarousel.d.ts +135 -0
  76. package/dist/components/marketing/MediaCarousel.d.ts.map +1 -0
  77. package/dist/components/marketing/MiscSections.d.ts +252 -0
  78. package/dist/components/marketing/MiscSections.d.ts.map +1 -0
  79. package/dist/components/order/OrderTrackingTimeline.d.ts.map +1 -0
  80. package/dist/components/order/SuccessMark.d.ts +10 -0
  81. package/dist/components/order/SuccessMark.d.ts.map +1 -0
  82. package/dist/components/product/ProductCard.d.ts +14 -0
  83. package/dist/components/product/ProductCard.d.ts.map +1 -0
  84. package/dist/components/product/ProductEnquiryForm.d.ts.map +1 -0
  85. package/dist/components/product/ProductGallery.d.ts +36 -0
  86. package/dist/components/product/ProductGallery.d.ts.map +1 -0
  87. package/dist/components/{ProductOptionSelector.d.ts → product/ProductOptionSelector.d.ts} +1 -1
  88. package/dist/components/product/ProductOptionSelector.d.ts.map +1 -0
  89. package/dist/components/product/ProductRail.d.ts +93 -0
  90. package/dist/components/product/ProductRail.d.ts.map +1 -0
  91. package/dist/components/product/ProductReviews.d.ts +39 -0
  92. package/dist/components/product/ProductReviews.d.ts.map +1 -0
  93. package/dist/components/product/ProductSlider.d.ts +169 -0
  94. package/dist/components/product/ProductSlider.d.ts.map +1 -0
  95. package/dist/components/product/ProductSpecs.d.ts.map +1 -0
  96. package/dist/components/product/RelatedProducts.d.ts.map +1 -0
  97. package/dist/{auth.d.ts → data/auth.d.ts} +9 -0
  98. package/dist/data/auth.d.ts.map +1 -0
  99. package/dist/data/facets.d.ts +39 -0
  100. package/dist/data/facets.d.ts.map +1 -0
  101. package/dist/data/loaders.d.ts +52 -0
  102. package/dist/data/loaders.d.ts.map +1 -0
  103. package/dist/data/local-orders.d.ts +5 -0
  104. package/dist/data/local-orders.d.ts.map +1 -0
  105. package/dist/data/order-status.d.ts.map +1 -0
  106. package/dist/data/product-options.d.ts +36 -0
  107. package/dist/data/product-options.d.ts.map +1 -0
  108. package/dist/data/shipping-items.d.ts +20 -0
  109. package/dist/data/shipping-items.d.ts.map +1 -0
  110. package/dist/diagnostics/seo-audit.d.ts +54 -0
  111. package/dist/diagnostics/seo-audit.d.ts.map +1 -0
  112. package/dist/diagnostics/seo-audit.js +3 -0
  113. package/dist/diagnostics/seo-audit.js.map +1 -0
  114. package/dist/document/change.d.ts +100 -0
  115. package/dist/document/change.d.ts.map +1 -0
  116. package/dist/document/config.d.ts +311 -0
  117. package/dist/document/config.d.ts.map +1 -0
  118. package/dist/document/describe.d.ts +135 -0
  119. package/dist/document/describe.d.ts.map +1 -0
  120. package/dist/document/overlay.d.ts +58 -0
  121. package/dist/document/overlay.d.ts.map +1 -0
  122. package/dist/{presets.d.ts → document/presets.d.ts} +2 -2
  123. package/dist/document/presets.d.ts.map +1 -0
  124. package/dist/document/render.d.ts +171 -0
  125. package/dist/document/render.d.ts.map +1 -0
  126. package/dist/document/round-trip.d.ts +46 -0
  127. package/dist/document/round-trip.d.ts.map +1 -0
  128. package/dist/document/sections.d.ts +194 -0
  129. package/dist/document/sections.d.ts.map +1 -0
  130. package/dist/document/store-policy.d.ts +29 -0
  131. package/dist/document/store-policy.d.ts.map +1 -0
  132. package/dist/document/upgrade.d.ts +112 -0
  133. package/dist/document/upgrade.d.ts.map +1 -0
  134. package/dist/document/validate.d.ts +24 -0
  135. package/dist/document/validate.d.ts.map +1 -0
  136. package/dist/{component-contracts.d.ts → extend/component-contracts.d.ts} +74 -22
  137. package/dist/extend/component-contracts.d.ts.map +1 -0
  138. package/dist/extend/component-override.d.ts +38 -0
  139. package/dist/extend/component-override.d.ts.map +1 -0
  140. package/dist/extend/component-selectors.d.ts.map +1 -0
  141. package/dist/extend/editor-bridge.d.ts +59 -0
  142. package/dist/extend/editor-bridge.d.ts.map +1 -0
  143. package/dist/extend/extension-points.d.ts +103 -0
  144. package/dist/extend/extension-points.d.ts.map +1 -0
  145. package/dist/extend/slots.d.ts +216 -0
  146. package/dist/extend/slots.d.ts.map +1 -0
  147. package/dist/hooks/index.d.ts +25 -6
  148. package/dist/hooks/index.d.ts.map +1 -1
  149. package/dist/hooks/use-address.d.ts +26 -0
  150. package/dist/hooks/use-address.d.ts.map +1 -0
  151. package/dist/hooks/use-cart.d.ts +3 -0
  152. package/dist/hooks/use-cart.d.ts.map +1 -0
  153. package/dist/hooks/use-catalog.d.ts +24 -0
  154. package/dist/hooks/use-catalog.d.ts.map +1 -0
  155. package/dist/hooks/use-categories.d.ts +19 -0
  156. package/dist/hooks/use-categories.d.ts.map +1 -0
  157. package/dist/hooks/use-checkout.d.ts +41 -0
  158. package/dist/hooks/use-checkout.d.ts.map +1 -0
  159. package/dist/hooks/use-discount-validator.d.ts +20 -0
  160. package/dist/hooks/use-discount-validator.d.ts.map +1 -0
  161. package/dist/hooks/use-enquiry.d.ts +7 -0
  162. package/dist/hooks/use-enquiry.d.ts.map +1 -0
  163. package/dist/hooks/{useMyOrders.d.ts → use-my-orders.d.ts} +1 -1
  164. package/dist/hooks/use-my-orders.d.ts.map +1 -0
  165. package/dist/hooks/use-order.d.ts +17 -0
  166. package/dist/hooks/use-order.d.ts.map +1 -0
  167. package/dist/hooks/use-payment-methods.d.ts +19 -0
  168. package/dist/hooks/use-payment-methods.d.ts.map +1 -0
  169. package/dist/hooks/use-policies.d.ts +25 -0
  170. package/dist/hooks/use-policies.d.ts.map +1 -0
  171. package/dist/hooks/use-product.d.ts +15 -0
  172. package/dist/hooks/use-product.d.ts.map +1 -0
  173. package/dist/hooks/{useProducts.d.ts → use-products.d.ts} +1 -1
  174. package/dist/hooks/use-products.d.ts.map +1 -0
  175. package/dist/hooks/use-region.d.ts +15 -0
  176. package/dist/hooks/use-region.d.ts.map +1 -0
  177. package/dist/hooks/use-shipping.d.ts +32 -0
  178. package/dist/hooks/use-shipping.d.ts.map +1 -0
  179. package/dist/hooks/use-storefront-actions.d.ts +12 -0
  180. package/dist/hooks/use-storefront-actions.d.ts.map +1 -0
  181. package/dist/hooks/use-storefront-head.d.ts +19 -0
  182. package/dist/hooks/use-storefront-head.d.ts.map +1 -0
  183. package/dist/hooks/use-storefront.d.ts +3 -0
  184. package/dist/hooks/use-storefront.d.ts.map +1 -0
  185. package/dist/index.d.ts +124 -54
  186. package/dist/index.d.ts.map +1 -1
  187. package/dist/index.js +1310 -5010
  188. package/dist/index.js.map +1 -1
  189. package/dist/lib/errors.d.ts +9 -0
  190. package/dist/lib/errors.d.ts.map +1 -0
  191. package/dist/lib/format.d.ts.map +1 -0
  192. package/dist/lib/motion.d.ts.map +1 -0
  193. package/dist/lib/seo.d.ts +26 -0
  194. package/dist/lib/seo.d.ts.map +1 -0
  195. package/dist/{testids.d.ts → lib/testids.d.ts} +33 -0
  196. package/dist/lib/testids.d.ts.map +1 -0
  197. package/dist/{theme.d.ts → lib/theme.d.ts} +41 -3
  198. package/dist/lib/theme.d.ts.map +1 -0
  199. package/dist/render.d.ts +5 -0
  200. package/dist/render.d.ts.map +1 -0
  201. package/dist/render.js +359 -0
  202. package/dist/render.js.map +1 -0
  203. package/dist/stores/cart.store.d.ts +34 -2
  204. package/dist/stores/cart.store.d.ts.map +1 -1
  205. package/dist/stores/catalog.store.d.ts +11 -0
  206. package/dist/stores/catalog.store.d.ts.map +1 -1
  207. package/dist/stores/delivery.store.d.ts +9 -0
  208. package/dist/stores/delivery.store.d.ts.map +1 -1
  209. package/dist/views/CatalogPage.d.ts.map +1 -0
  210. package/dist/views/CheckoutPage.d.ts.map +1 -0
  211. package/dist/views/ContentPage.d.ts +11 -0
  212. package/dist/views/ContentPage.d.ts.map +1 -0
  213. package/dist/views/HomePage.d.ts +9 -0
  214. package/dist/views/HomePage.d.ts.map +1 -0
  215. package/dist/views/MyPurchasesPage.d.ts.map +1 -0
  216. package/dist/views/NotFoundPage.d.ts.map +1 -0
  217. package/dist/views/OrderConfirmationPage.d.ts.map +1 -0
  218. package/dist/{pages → views}/PolicyPage.d.ts.map +1 -1
  219. package/dist/views/ProductDetailPage.d.ts.map +1 -0
  220. package/dist/views/StorefrontPage.d.ts +35 -0
  221. package/dist/views/StorefrontPage.d.ts.map +1 -0
  222. package/dist/workflows/checkout.d.ts +1 -1
  223. package/dist/workflows/checkout.d.ts.map +1 -1
  224. package/package.json +21 -14
  225. package/dist/auth.d.ts.map +0 -1
  226. package/dist/blocks.d.ts.map +0 -1
  227. package/dist/component-contracts.d.ts.map +0 -1
  228. package/dist/component-selectors.d.ts.map +0 -1
  229. package/dist/components/CartDrawer.d.ts.map +0 -1
  230. package/dist/components/CustomerAccountShell.d.ts +0 -13
  231. package/dist/components/CustomerAccountShell.d.ts.map +0 -1
  232. package/dist/components/DeliveryEstimator.d.ts.map +0 -1
  233. package/dist/components/FiltersPanel.d.ts +0 -3
  234. package/dist/components/FiltersPanel.d.ts.map +0 -1
  235. package/dist/components/OrderTrackingTimeline.d.ts.map +0 -1
  236. package/dist/components/ProductCard.d.ts +0 -4
  237. package/dist/components/ProductCard.d.ts.map +0 -1
  238. package/dist/components/ProductEnquiryForm.d.ts.map +0 -1
  239. package/dist/components/ProductGallery.d.ts +0 -22
  240. package/dist/components/ProductGallery.d.ts.map +0 -1
  241. package/dist/components/ProductGrid.d.ts.map +0 -1
  242. package/dist/components/ProductOptionSelector.d.ts.map +0 -1
  243. package/dist/components/ProductSpecs.d.ts.map +0 -1
  244. package/dist/components/QuantityInput.d.ts.map +0 -1
  245. package/dist/components/RelatedProducts.d.ts.map +0 -1
  246. package/dist/components/SignInModal.d.ts.map +0 -1
  247. package/dist/components/StorefrontErrorBoundary.d.ts.map +0 -1
  248. package/dist/components/StorefrontFooter.d.ts.map +0 -1
  249. package/dist/components/StorefrontHeader.d.ts.map +0 -1
  250. package/dist/components/Toaster.d.ts.map +0 -1
  251. package/dist/components/sections/CategoryShowcase.d.ts +0 -6
  252. package/dist/components/sections/CategoryShowcase.d.ts.map +0 -1
  253. package/dist/components/sections/HeroSection.d.ts +0 -9
  254. package/dist/components/sections/HeroSection.d.ts.map +0 -1
  255. package/dist/components/sections/MediaCarousel.d.ts +0 -11
  256. package/dist/components/sections/MediaCarousel.d.ts.map +0 -1
  257. package/dist/components/sections/MiscSections.d.ts +0 -33
  258. package/dist/components/sections/MiscSections.d.ts.map +0 -1
  259. package/dist/components/sections/ProductRail.d.ts +0 -9
  260. package/dist/components/sections/ProductRail.d.ts.map +0 -1
  261. package/dist/components/sections/ProductSlider.d.ts +0 -15
  262. package/dist/components/sections/ProductSlider.d.ts.map +0 -1
  263. package/dist/config.d.ts +0 -174
  264. package/dist/config.d.ts.map +0 -1
  265. package/dist/createStorefrontApp.d.ts +0 -28
  266. package/dist/createStorefrontApp.d.ts.map +0 -1
  267. package/dist/define.d.ts.map +0 -1
  268. package/dist/format.d.ts.map +0 -1
  269. package/dist/hooks/useCategories.d.ts +0 -6
  270. package/dist/hooks/useCategories.d.ts.map +0 -1
  271. package/dist/hooks/useDiscountValidator.d.ts +0 -14
  272. package/dist/hooks/useDiscountValidator.d.ts.map +0 -1
  273. package/dist/hooks/useMyOrders.d.ts.map +0 -1
  274. package/dist/hooks/useProduct.d.ts +0 -7
  275. package/dist/hooks/useProduct.d.ts.map +0 -1
  276. package/dist/hooks/useProducts.d.ts.map +0 -1
  277. package/dist/hooks/useStorefront.d.ts +0 -35
  278. package/dist/hooks/useStorefront.d.ts.map +0 -1
  279. package/dist/hooks/useStorefrontHead.d.ts +0 -11
  280. package/dist/hooks/useStorefrontHead.d.ts.map +0 -1
  281. package/dist/motion.d.ts.map +0 -1
  282. package/dist/order-status.d.ts.map +0 -1
  283. package/dist/pages/CatalogPage.d.ts.map +0 -1
  284. package/dist/pages/CheckoutPage.d.ts.map +0 -1
  285. package/dist/pages/HomePage.d.ts +0 -9
  286. package/dist/pages/HomePage.d.ts.map +0 -1
  287. package/dist/pages/MyPurchasesPage.d.ts.map +0 -1
  288. package/dist/pages/NotFoundPage.d.ts.map +0 -1
  289. package/dist/pages/OrderConfirmationPage.d.ts.map +0 -1
  290. package/dist/pages/ProductDetailPage.d.ts.map +0 -1
  291. package/dist/presets.d.ts.map +0 -1
  292. package/dist/product-options.d.ts +0 -12
  293. package/dist/product-options.d.ts.map +0 -1
  294. package/dist/router.d.ts.map +0 -1
  295. package/dist/scaffold.d.ts.map +0 -1
  296. package/dist/sections.d.ts.map +0 -1
  297. package/dist/testids.d.ts.map +0 -1
  298. package/dist/theme.d.ts.map +0 -1
  299. package/src/auth.ts +0 -227
  300. package/src/blocks.tsx +0 -51
  301. package/src/catalog.ts +0 -3
  302. package/src/component-contracts.ts +0 -154
  303. package/src/component-selectors.ts +0 -31
  304. package/src/components/CartDrawer.tsx +0 -279
  305. package/src/components/CustomerAccountShell.tsx +0 -102
  306. package/src/components/DeliveryEstimator.tsx +0 -157
  307. package/src/components/FiltersPanel.tsx +0 -109
  308. package/src/components/OrderTrackingTimeline.tsx +0 -135
  309. package/src/components/Price.tsx +0 -32
  310. package/src/components/ProductCard.tsx +0 -120
  311. package/src/components/ProductEnquiryForm.tsx +0 -175
  312. package/src/components/ProductGallery.tsx +0 -174
  313. package/src/components/ProductGrid.tsx +0 -43
  314. package/src/components/ProductOptionSelector.tsx +0 -50
  315. package/src/components/ProductSpecs.tsx +0 -75
  316. package/src/components/QuantityInput.tsx +0 -52
  317. package/src/components/RelatedProducts.tsx +0 -40
  318. package/src/components/SignInModal.tsx +0 -120
  319. package/src/components/SmoothImage.tsx +0 -59
  320. package/src/components/StorefrontErrorBoundary.tsx +0 -51
  321. package/src/components/StorefrontFooter.tsx +0 -110
  322. package/src/components/StorefrontHeader.tsx +0 -477
  323. package/src/components/Toaster.tsx +0 -60
  324. package/src/components/sections/CategoryShowcase.tsx +0 -80
  325. package/src/components/sections/HeroSection.tsx +0 -193
  326. package/src/components/sections/MediaCarousel.tsx +0 -141
  327. package/src/components/sections/MiscSections.tsx +0 -158
  328. package/src/components/sections/ProductRail.tsx +0 -81
  329. package/src/components/sections/ProductSlider.tsx +0 -119
  330. package/src/config.ts +0 -229
  331. package/src/createStorefrontApp.tsx +0 -247
  332. package/src/define.ts +0 -34
  333. package/src/format.ts +0 -7
  334. package/src/hooks/index.ts +0 -6
  335. package/src/hooks/useCategories.ts +0 -26
  336. package/src/hooks/useDiscountValidator.ts +0 -43
  337. package/src/hooks/useMyOrders.ts +0 -41
  338. package/src/hooks/useProduct.ts +0 -36
  339. package/src/hooks/useProducts.ts +0 -39
  340. package/src/hooks/useStorefront.ts +0 -58
  341. package/src/hooks/useStorefrontHead.ts +0 -25
  342. package/src/index.ts +0 -202
  343. package/src/motion.tsx +0 -94
  344. package/src/order-status.ts +0 -33
  345. package/src/pages/CatalogPage.tsx +0 -118
  346. package/src/pages/CheckoutPage.tsx +0 -689
  347. package/src/pages/HomePage.tsx +0 -16
  348. package/src/pages/MyPurchasesPage.tsx +0 -311
  349. package/src/pages/NotFoundPage.tsx +0 -25
  350. package/src/pages/OrderConfirmationPage.tsx +0 -190
  351. package/src/pages/PolicyPage.tsx +0 -47
  352. package/src/pages/ProductDetailPage.tsx +0 -264
  353. package/src/presets.ts +0 -324
  354. package/src/product-options.ts +0 -63
  355. package/src/router.ts +0 -49
  356. package/src/scaffold.tsx +0 -115
  357. package/src/sections.ts +0 -116
  358. package/src/shop.ts +0 -4
  359. package/src/stores/cart.store.ts +0 -185
  360. package/src/stores/catalog.store.ts +0 -39
  361. package/src/stores/delivery.store.ts +0 -152
  362. package/src/stores/session.store.ts +0 -28
  363. package/src/stores/toast.store.ts +0 -43
  364. package/src/testids.ts +0 -136
  365. package/src/theme.ts +0 -194
  366. package/src/ui.ts +0 -5
  367. package/src/workflows/checkout.ts +0 -119
  368. /package/dist/components/{SignInModal.d.ts → account/SignInModal.d.ts} +0 -0
  369. /package/dist/components/{CartDrawer.d.ts → cart/CartDrawer.d.ts} +0 -0
  370. /package/dist/components/{QuantityInput.d.ts → cart/QuantityInput.d.ts} +0 -0
  371. /package/dist/components/{DeliveryEstimator.d.ts → checkout/DeliveryEstimator.d.ts} +0 -0
  372. /package/dist/components/{ProductGrid.d.ts → collection/ProductGrid.d.ts} +0 -0
  373. /package/dist/components/{StorefrontErrorBoundary.d.ts → layout/StorefrontErrorBoundary.d.ts} +0 -0
  374. /package/dist/components/{StorefrontFooter.d.ts → layout/StorefrontFooter.d.ts} +0 -0
  375. /package/dist/components/{StorefrontHeader.d.ts → layout/StorefrontHeader.d.ts} +0 -0
  376. /package/dist/components/{Toaster.d.ts → layout/Toaster.d.ts} +0 -0
  377. /package/dist/components/{OrderTrackingTimeline.d.ts → order/OrderTrackingTimeline.d.ts} +0 -0
  378. /package/dist/components/{ProductEnquiryForm.d.ts → product/ProductEnquiryForm.d.ts} +0 -0
  379. /package/dist/components/{ProductSpecs.d.ts → product/ProductSpecs.d.ts} +0 -0
  380. /package/dist/components/{RelatedProducts.d.ts → product/RelatedProducts.d.ts} +0 -0
  381. /package/dist/{order-status.d.ts → data/order-status.d.ts} +0 -0
  382. /package/dist/{component-selectors.d.ts → extend/component-selectors.d.ts} +0 -0
  383. /package/dist/{format.d.ts → lib/format.d.ts} +0 -0
  384. /package/dist/{motion.d.ts → lib/motion.d.ts} +0 -0
  385. /package/dist/{pages → views}/CatalogPage.d.ts +0 -0
  386. /package/dist/{pages → views}/CheckoutPage.d.ts +0 -0
  387. /package/dist/{pages → views}/MyPurchasesPage.d.ts +0 -0
  388. /package/dist/{pages → views}/NotFoundPage.d.ts +0 -0
  389. /package/dist/{pages → views}/OrderConfirmationPage.d.ts +0 -0
  390. /package/dist/{pages → views}/PolicyPage.d.ts +0 -0
  391. /package/dist/{pages → views}/ProductDetailPage.d.ts +0 -0
@@ -1,477 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { CreditCard, LogOut, Mail, Menu, Package, Phone, Search, ShoppingBag, User, UserCircle, X } from 'lucide-react'
3
- import { signOutCustomer } from '../auth'
4
- import { useCartStore, selectCount } from '../stores/cart.store'
5
- import { useCatalogStore } from '../stores/catalog.store'
6
- import { useSessionStore } from '../stores/session.store'
7
- import { useCategories } from '../hooks/useCategories'
8
- import { useStorefrontConfig } from '../config'
9
- import { useScrolled, usePopOnChange } from '../motion'
10
- import { Link, navigateTo, useHashPath } from '../router'
11
- import { TID } from '../testids'
12
-
13
- // Header tokens come from the theme (--sf-header-bg/fg) so dark headers
14
- // (Brasília pattern) work without component changes. Dividers derive from the
15
- // header FOREGROUND (not the page --border token, which is light and shows as
16
- // white lines on dark headers).
17
- const headerStyle: React.CSSProperties = {
18
- backgroundColor: 'hsl(var(--sf-header-bg, var(--background)))',
19
- color: 'hsl(var(--sf-header-fg, var(--foreground)))',
20
- borderColor: 'hsl(var(--sf-header-fg, var(--foreground)) / 0.14)',
21
- }
22
-
23
- const headerDivider: React.CSSProperties = {
24
- borderColor: 'hsl(var(--sf-header-fg, var(--foreground)) / 0.14)',
25
- }
26
-
27
- const ANNOUNCEMENT_KEY = 'fayz.storefront.announcement.dismissed'
28
-
29
- function AnnouncementBar() {
30
- const config = useStorefrontConfig()
31
- const [dismissed, setDismissed] = useState(() => {
32
- try {
33
- return localStorage.getItem(ANNOUNCEMENT_KEY) === config.announcement
34
- } catch {
35
- return false
36
- }
37
- })
38
- if (!config.announcement || dismissed) return null
39
-
40
- const dismiss = () => {
41
- setDismissed(true)
42
- try {
43
- localStorage.setItem(ANNOUNCEMENT_KEY, config.announcement ?? '')
44
- } catch {
45
- /* storage unavailable — dismiss for this session only */
46
- }
47
- }
48
-
49
- return (
50
- <div
51
- data-testid={TID.announcementBar}
52
- className="relative px-4 py-2 text-center text-xs font-semibold tracking-wide"
53
- style={{
54
- backgroundColor: 'hsl(var(--sf-announcement-bg, var(--primary)))',
55
- color: 'hsl(var(--sf-announcement-fg, var(--primary-foreground)))',
56
- }}
57
- >
58
- {config.announcement}
59
- <button
60
- type="button"
61
- aria-label="Fechar aviso"
62
- onClick={dismiss}
63
- className="absolute right-2 top-1/2 -translate-y-1/2 rounded-full p-1 opacity-70 transition-opacity hover:opacity-100"
64
- >
65
- <X className="h-3.5 w-3.5" />
66
- </button>
67
- </div>
68
- )
69
- }
70
-
71
- /** Slim utility strip (Flex pattern): contact on the left, social on the right. */
72
- function UtilityBar() {
73
- const config = useStorefrontConfig()
74
- const contact = config.footer?.contact
75
- const social = config.footer?.social
76
- if (!contact?.phone && !contact?.email && !social?.length) return null
77
- return (
78
- <div className="hidden border-b text-xs opacity-80 md:block" style={headerDivider}>
79
- <div className="mx-auto flex h-8 max-w-7xl items-center gap-5 px-4 sm:px-6">
80
- {contact?.phone && (
81
- <span className="inline-flex items-center gap-1.5">
82
- <Phone className="h-3 w-3" /> {contact.phone}
83
- </span>
84
- )}
85
- {contact?.email && (
86
- <span className="inline-flex items-center gap-1.5">
87
- <Mail className="h-3 w-3" /> {contact.email}
88
- </span>
89
- )}
90
- <span className="ml-auto flex items-center gap-4">
91
- {social?.map((s) => (
92
- <a key={s.href} href={s.href} target="_blank" rel="noreferrer" className="hover:underline">
93
- {s.label}
94
- </a>
95
- ))}
96
- </span>
97
- </div>
98
- </div>
99
- )
100
- }
101
-
102
- function SearchInput({ className, iconOnly = false }: { className?: string; iconOnly?: boolean }) {
103
- const config = useStorefrontConfig()
104
- const search = useCatalogStore((s) => s.search)
105
- const setSearch = useCatalogStore((s) => s.setSearch)
106
- const path = useHashPath()
107
- const [open, setOpen] = useState(false)
108
-
109
- // Icon-only: a compact search button that expands into the input on click and
110
- // collapses again on Escape / blur-when-empty.
111
- if (iconOnly && !open) {
112
- return (
113
- <button
114
- type="button"
115
- aria-label="Buscar produtos"
116
- data-testid={TID.headerSearchToggle}
117
- onClick={() => setOpen(true)}
118
- className="rounded-full p-2.5 transition-opacity hover:opacity-70"
119
- >
120
- <Search className="h-5 w-5" />
121
- </button>
122
- )
123
- }
124
-
125
- return (
126
- <div className={`relative ${iconOnly ? 'w-full max-w-xs' : (className ?? '')}`}>
127
- <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 opacity-60" />
128
- <input
129
- data-testid={TID.headerSearch}
130
- type="search"
131
- placeholder="Buscar produtos..."
132
- value={search}
133
- autoFocus={iconOnly}
134
- onChange={(e) => {
135
- setSearch(e.target.value)
136
- if (path !== config.catalogPath) navigateTo(config.catalogPath)
137
- }}
138
- onKeyDown={(e) => {
139
- if (e.key === 'Escape' && iconOnly) setOpen(false)
140
- }}
141
- onBlur={() => {
142
- if (iconOnly && !search) setOpen(false)
143
- }}
144
- className="w-full border bg-white/10 py-2 pl-9 pr-4 text-sm outline-none transition-colors placeholder:opacity-60 focus:border-primary focus:bg-white focus:text-gray-900"
145
- style={{
146
- borderRadius: 'var(--sf-radius-input)',
147
- borderColor: 'hsl(var(--sf-header-fg, var(--foreground)) / 0.25)',
148
- }}
149
- />
150
- </div>
151
- )
152
- }
153
-
154
- function HeaderActions({ onMenuClick }: { onMenuClick?: () => void }) {
155
- const config = useStorefrontConfig()
156
- const count = useCartStore(selectCount)
157
- const openDrawer = useCartStore((s) => s.openDrawer)
158
- const session = useSessionStore()
159
- const [accountOpen, setAccountOpen] = useState(false)
160
- const pop = usePopOnChange(count)
161
- const firstName = session.name?.split(/\s+/)[0]
162
- const initial = (firstName ?? session.email ?? 'C').slice(0, 1).toUpperCase()
163
- return (
164
- <nav className="flex items-center gap-1">
165
- {config.features.accounts && (
166
- <div className="relative">
167
- {session.email ? (
168
- <button
169
- type="button"
170
- data-testid={TID.accountLink}
171
- aria-label="Abrir menu da conta"
172
- aria-expanded={accountOpen}
173
- onClick={() => setAccountOpen((open) => !open)}
174
- className="flex items-center gap-1.5 rounded-full p-1.5 transition-opacity hover:opacity-80"
175
- >
176
- <span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary text-sm font-bold text-primary-foreground">
177
- {initial}
178
- </span>
179
- {firstName && (
180
- <span data-testid={TID.accountName} className="hidden max-w-24 truncate text-sm font-medium lg:inline">
181
- {firstName}
182
- </span>
183
- )}
184
- </button>
185
- ) : (
186
- <Link
187
- to="/account"
188
- data-testid={TID.accountLink}
189
- aria-label="Minhas compras"
190
- className="flex items-center gap-1.5 rounded-full p-2.5 transition-opacity hover:opacity-70"
191
- >
192
- <User className="h-5 w-5" />
193
- </Link>
194
- )}
195
- {accountOpen && session.email && (
196
- <div
197
- data-testid={TID.accountDropdown}
198
- className="absolute right-0 top-full z-50 mt-3 w-72 overflow-hidden rounded-xl border bg-background text-foreground shadow-xl"
199
- >
200
- <div className="border-b p-4">
201
- <p className="font-semibold">{session.name || firstName || 'Cliente'}</p>
202
- <p className="truncate text-sm text-muted-foreground">{session.email}</p>
203
- </div>
204
- <div className="p-2">
205
- <Link to="/account" className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-semibold hover:bg-muted">
206
- <UserCircle className="h-4 w-4" />
207
- Perfil
208
- </Link>
209
- <Link to="/account" className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-semibold hover:bg-muted">
210
- <Package className="h-4 w-4" />
211
- Meus pedidos
212
- </Link>
213
- <Link to="/account" className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-semibold hover:bg-muted">
214
- <CreditCard className="h-4 w-4" />
215
- Pagamentos
216
- </Link>
217
- <button
218
- type="button"
219
- onClick={() => {
220
- setAccountOpen(false)
221
- void signOutCustomer()
222
- }}
223
- className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm font-semibold hover:bg-muted"
224
- >
225
- <LogOut className="h-4 w-4" />
226
- Sair
227
- </button>
228
- </div>
229
- </div>
230
- )}
231
- </div>
232
- )}
233
- {config.features.cart && (
234
- <button
235
- type="button"
236
- data-testid={TID.cartButton}
237
- aria-label="Carrinho"
238
- onClick={openDrawer}
239
- className="relative rounded-full p-2.5 transition-opacity hover:opacity-70"
240
- >
241
- <ShoppingBag className="h-5 w-5" />
242
- {count > 0 && (
243
- <span
244
- data-testid={TID.cartCount}
245
- className={`absolute -right-0.5 -top-0.5 flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1 text-xs font-semibold text-primary-foreground ${
246
- pop ? 'animate-badge-pop' : ''
247
- }`}
248
- >
249
- {count}
250
- </span>
251
- )}
252
- </button>
253
- )}
254
- {onMenuClick && (
255
- <button
256
- type="button"
257
- aria-label="Abrir menu"
258
- onClick={onMenuClick}
259
- className="relative rounded-full p-2.5 transition-opacity hover:opacity-70 md:hidden"
260
- >
261
- <Menu className="h-5 w-5" />
262
- </button>
263
- )}
264
- </nav>
265
- )
266
- }
267
-
268
- function NavLinks({ className }: { className?: string }) {
269
- const config = useStorefrontConfig()
270
- const { categories } = useCategories()
271
- const setCategoryId = useCatalogStore((s) => s.setCategoryId)
272
- const showCategories = config.theme?.header?.showCategories !== false
273
-
274
- const goCategory = (categoryId: string) => {
275
- useCatalogStore.getState().reset()
276
- setCategoryId(categoryId)
277
- navigateTo(config.catalogPath)
278
- }
279
-
280
- return (
281
- <nav className={`flex min-w-max items-center gap-6 ${className ?? ''}`}>
282
- {config.nav.map((link) => (
283
- <Link
284
- key={link.to}
285
- to={link.to}
286
- data-testid={TID.navLink(link.label)}
287
- className="sf-nav-link text-sm font-medium transition-opacity hover:opacity-70"
288
- >
289
- {link.label}
290
- </Link>
291
- ))}
292
- {showCategories &&
293
- categories.slice(0, 6).map((c) => (
294
- <button
295
- key={c.id}
296
- type="button"
297
- data-testid={TID.navCategory(c.slug)}
298
- onClick={() => goCategory(c.id)}
299
- className="sf-nav-link group relative hidden text-sm font-medium transition-opacity hover:opacity-80 lg:inline"
300
- >
301
- {c.name}
302
- <span className="absolute -bottom-1 left-0 h-0.5 w-0 bg-primary transition-all duration-300 group-hover:w-full" />
303
- </button>
304
- ))}
305
- </nav>
306
- )
307
- }
308
-
309
- function MobileMenuDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
310
- const config = useStorefrontConfig()
311
- const { categories } = useCategories()
312
- const setCategoryId = useCatalogStore((s) => s.setCategoryId)
313
- const showCategories = config.theme?.header?.showCategories !== false
314
-
315
- const goCategory = (categoryId: string) => {
316
- useCatalogStore.getState().reset()
317
- setCategoryId(categoryId)
318
- navigateTo(config.catalogPath)
319
- onClose()
320
- }
321
-
322
- // a11y: close on Escape
323
- React.useEffect(() => {
324
- if (!open) return
325
- const onKey = (e: KeyboardEvent) => {
326
- if (e.key === 'Escape') onClose()
327
- }
328
- document.addEventListener('keydown', onKey)
329
- return () => document.removeEventListener('keydown', onKey)
330
- }, [open, onClose])
331
-
332
- if (!open) return null
333
-
334
- return (
335
- <div className="fixed inset-0 z-50 md:hidden">
336
- <div
337
- className="absolute inset-0 animate-fade-in bg-black/40"
338
- aria-hidden
339
- onClick={onClose}
340
- />
341
- <div
342
- data-testid="mobile-menu-drawer"
343
- role="dialog"
344
- aria-label="Menu Principal"
345
- className="absolute right-0 top-0 flex h-full w-full max-w-[280px] animate-slide-in-from-right flex-col bg-background shadow-2xl"
346
- >
347
- <div className="flex items-center justify-between border-b px-5 py-4">
348
- <h2 className="text-lg font-semibold">Menu</h2>
349
- <button
350
- type="button"
351
- aria-label="Fechar menu"
352
- onClick={onClose}
353
- className="rounded-full p-1.5 hover:bg-muted"
354
- >
355
- <X className="h-5 w-5" />
356
- </button>
357
- </div>
358
- <div className="flex-1 overflow-y-auto p-5">
359
- <nav className="flex flex-col gap-4">
360
- {config.nav.map((link) => (
361
- <Link
362
- key={link.to}
363
- to={link.to}
364
- onClick={onClose}
365
- className="text-base font-semibold transition-opacity hover:opacity-70"
366
- >
367
- {link.label}
368
- </Link>
369
- ))}
370
- {showCategories && categories.length > 0 && (
371
- <>
372
- <div className="my-2 border-t" />
373
- <div className="mb-2 text-xs font-bold uppercase tracking-wider text-muted-foreground">
374
- Categorias
375
- </div>
376
- {categories.map((c) => (
377
- <button
378
- key={c.id}
379
- type="button"
380
- onClick={() => goCategory(c.id)}
381
- className="text-left text-sm font-medium transition-opacity hover:opacity-80"
382
- >
383
- {c.name}
384
- </button>
385
- ))}
386
- </>
387
- )}
388
- </nav>
389
- </div>
390
- </div>
391
- </div>
392
- )
393
- }
394
-
395
- export function StorefrontHeader() {
396
- const config = useStorefrontConfig()
397
- const variant = config.theme?.header?.variant ?? 'classic'
398
- const scrolled = useScrolled()
399
- const showSearch = config.theme?.header?.showSearch !== false
400
- const iconSearch = config.theme?.header?.searchStyle === 'icon'
401
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
402
- const logo = (
403
- <Link to="/" className="sf-heading shrink-0 text-xl font-bold tracking-tight">
404
- {config.logo ?? config.name}
405
- </Link>
406
- )
407
-
408
- return (
409
- <header
410
- className={`sticky top-0 z-40 border-b transition-shadow duration-300 ${scrolled ? 'shadow-md' : ''}`}
411
- style={headerStyle}
412
- >
413
- <AnnouncementBar />
414
- <UtilityBar />
415
-
416
- {variant === 'centered' ? (
417
- // Rio/Flex pattern: centered logo row, nav row below
418
- <>
419
- <div className="mx-auto grid h-16 max-w-7xl grid-cols-[1fr_auto_1fr] items-center px-4 sm:px-6">
420
- {showSearch ? <SearchInput iconOnly={iconSearch} className="hidden w-full max-w-xs sm:block" /> : <div />}
421
- <div className="text-center">{logo}</div>
422
- <div className="justify-self-end">
423
- <HeaderActions />
424
- </div>
425
- </div>
426
- <div className="flex overflow-x-auto border-t py-2.5 sm:justify-center" style={headerDivider}>
427
- <NavLinks />
428
- </div>
429
- </>
430
- ) : variant === 'search' ? (
431
- // Brasília pattern: prominent search left, logo center, actions right; nav row below
432
- <>
433
- <div className="mx-auto grid h-16 max-w-7xl grid-cols-[1fr_auto_1fr] items-center gap-6 px-4 sm:px-6">
434
- {showSearch ? <SearchInput iconOnly={iconSearch} className="hidden w-full max-w-sm sm:block" /> : <div />}
435
- <div className="text-center">{logo}</div>
436
- <div className="justify-self-end">
437
- <HeaderActions />
438
- </div>
439
- </div>
440
- <div className="overflow-x-auto border-t" style={headerDivider}>
441
- <div className="mx-auto max-w-7xl px-4 py-2.5 sm:px-6">
442
- <NavLinks />
443
- </div>
444
- </div>
445
- </>
446
- ) : variant === 'minimal' ? (
447
- // Uyuni pattern: nav left, centered logo, actions right — single compact row
448
- <div className="mx-auto grid h-16 max-w-7xl grid-cols-[1fr_auto_1fr] items-center px-4 sm:px-6">
449
- <div className="flex items-center gap-5">
450
- <NavLinks className="hidden sm:flex" />
451
- </div>
452
- <div className="text-center">{logo}</div>
453
- <div className="flex items-center justify-end gap-3">
454
- {showSearch && <SearchInput iconOnly={iconSearch} className="hidden w-44 lg:block" />}
455
- <HeaderActions />
456
- </div>
457
- </div>
458
- ) : (
459
- // classic: logo left, nav, then a right-aligned search + actions cluster.
460
- // NavLinks is hidden below md in the primary row (no room for it there) —
461
- // below md a hamburger opens MobileMenuDrawer instead, otherwise mobile
462
- // has no way to reach nav/category links at all.
463
- <>
464
- <div className="mx-auto flex h-16 max-w-7xl items-center gap-6 px-4 sm:px-6">
465
- {logo}
466
- <NavLinks className="hidden md:flex" />
467
- <div className="ml-auto flex items-center gap-2 sm:gap-3">
468
- {showSearch && <SearchInput iconOnly={iconSearch} className={iconSearch ? '' : 'hidden w-full max-w-sm sm:block'} />}
469
- <HeaderActions onMenuClick={() => setMobileMenuOpen(true)} />
470
- </div>
471
- </div>
472
- <MobileMenuDrawer open={mobileMenuOpen} onClose={() => setMobileMenuOpen(false)} />
473
- </>
474
- )}
475
- </header>
476
- )
477
- }
@@ -1,60 +0,0 @@
1
- import React, { useEffect } from 'react'
2
- import { AlertCircle, Check, Info, X } from 'lucide-react'
3
- import { useToastStore, type Toast } from '../stores/toast.store'
4
-
5
- const ICON: Record<Toast['variant'], React.ComponentType<{ className?: string }>> = {
6
- success: Check,
7
- error: AlertCircle,
8
- info: Info,
9
- }
10
-
11
- const ACCENT: Record<Toast['variant'], string> = {
12
- success: 'bg-emerald-500/10 text-emerald-600',
13
- error: 'bg-destructive/10 text-destructive',
14
- info: 'bg-primary/10 text-primary',
15
- }
16
-
17
- function ToastCard({ toast }: { toast: Toast }) {
18
- const dismiss = useToastStore((s) => s.dismiss)
19
- const Icon = ICON[toast.variant]
20
-
21
- useEffect(() => {
22
- const timer = window.setTimeout(() => dismiss(toast.id), toast.durationMs)
23
- return () => window.clearTimeout(timer)
24
- }, [toast.id, toast.durationMs, dismiss])
25
-
26
- return (
27
- <div
28
- role="status"
29
- className="pointer-events-auto flex w-80 max-w-[calc(100vw-2rem)] animate-slide-in-from-right items-start gap-3 rounded-xl border bg-card p-3.5 shadow-lg"
30
- >
31
- <span className={`grid h-8 w-8 shrink-0 place-items-center rounded-full ${ACCENT[toast.variant]}`}>
32
- <Icon className="h-4 w-4" />
33
- </span>
34
- <div className="min-w-0 flex-1">
35
- <p className="text-sm font-semibold leading-tight">{toast.title}</p>
36
- {toast.description && <p className="mt-0.5 text-xs text-muted-foreground">{toast.description}</p>}
37
- </div>
38
- <button
39
- type="button"
40
- aria-label="Fechar"
41
- onClick={() => dismiss(toast.id)}
42
- className="text-muted-foreground transition-colors hover:text-foreground"
43
- >
44
- <X className="h-4 w-4" />
45
- </button>
46
- </div>
47
- )
48
- }
49
-
50
- export function Toaster() {
51
- const toasts = useToastStore((s) => s.toasts)
52
- if (toasts.length === 0) return null
53
- return (
54
- <div className="pointer-events-none fixed bottom-4 right-4 z-[70] flex flex-col gap-2">
55
- {toasts.map((t) => (
56
- <ToastCard key={t.id} toast={t} />
57
- ))}
58
- </div>
59
- )
60
- }
@@ -1,80 +0,0 @@
1
- import React from 'react'
2
- import { useCategories } from '../../hooks/useCategories'
3
- import { useCatalogStore } from '../../stores/catalog.store'
4
- import { useStorefrontConfig } from '../../config'
5
- import { bannerPlaceholder } from '../../sections'
6
- import { Reveal } from '../../motion'
7
- import { navigateTo } from '../../router'
8
- import { TID } from '../../testids'
9
- import { SmoothImage } from '../SmoothImage'
10
-
11
- export function CategoryShowcase({ style, title }: { style: 'bubbles' | 'tiles'; title?: string }) {
12
- const { categories } = useCategories()
13
- const config = useStorefrontConfig()
14
- const setCategoryId = useCatalogStore((s) => s.setCategoryId)
15
-
16
- if (categories.length === 0) return null
17
-
18
- const go = (categoryId: string) => {
19
- useCatalogStore.getState().reset()
20
- setCategoryId(categoryId)
21
- navigateTo(config.catalogPath)
22
- }
23
-
24
- if (style === 'bubbles') {
25
- return (
26
- <section data-testid={TID.categoryShowcase} className="mx-auto max-w-7xl px-4 py-12 sm:px-6">
27
- {title && (
28
- <Reveal>
29
- <h2 className="sf-heading mb-8 text-center text-3xl font-bold">{title}</h2>
30
- </Reveal>
31
- )}
32
- <div className="flex flex-wrap items-start justify-center gap-8">
33
- {categories.map((c, i) => (
34
- <Reveal key={c.id} delay={i * 80}>
35
- <button type="button" onClick={() => go(c.id)} className="group flex w-28 flex-col items-center gap-3">
36
- <span className="block h-24 w-24 overflow-hidden rounded-full border-2 border-transparent shadow-sm transition-all duration-300 group-hover:scale-105 group-hover:border-primary group-hover:shadow-md">
37
- <SmoothImage
38
- src={c.imageUrl ?? bannerPlaceholder(c.name, 30 + i * 70, 70 + i * 70, 200, 200)}
39
- alt={c.name}
40
- className="h-full w-full object-cover"
41
- />
42
- </span>
43
- <span className="text-center text-xs font-medium leading-tight">{c.name}</span>
44
- </button>
45
- </Reveal>
46
- ))}
47
- </div>
48
- </section>
49
- )
50
- }
51
-
52
- return (
53
- <section data-testid={TID.categoryShowcase} className="mx-auto max-w-7xl px-4 py-12 sm:px-6">
54
- {title && (
55
- <Reveal>
56
- <h2 className="sf-heading mb-8 text-center text-3xl font-bold">{title}</h2>
57
- </Reveal>
58
- )}
59
- <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
60
- {categories.map((c, i) => (
61
- <Reveal key={c.id} delay={i * 90}>
62
- <button type="button" onClick={() => go(c.id)} className="group relative block aspect-[4/5] w-full overflow-hidden" style={{ borderRadius: 'var(--sf-radius-card)' }}>
63
- <SmoothImage
64
- src={c.imageUrl ?? bannerPlaceholder(c.name, 30 + i * 70, 70 + i * 70, 480, 600)}
65
- alt={c.name}
66
- className="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-110"
67
- />
68
- <span className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent p-5 pt-12 text-left">
69
- <span className="sf-heading block text-lg font-semibold text-white">{c.name}</span>
70
- <span className="mt-0.5 block text-xs text-white/80 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
71
- Explorar →
72
- </span>
73
- </span>
74
- </button>
75
- </Reveal>
76
- ))}
77
- </div>
78
- </section>
79
- )
80
- }