@faststore/core 22.42.6

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 (475) hide show
  1. package/.babelrc +4 -0
  2. package/.editorconfig +13 -0
  3. package/.eslintignore +8 -0
  4. package/.eslintrc +21 -0
  5. package/.github/CODEOWNERS +2 -0
  6. package/.github/workflows/release.yml +40 -0
  7. package/.husky/pre-commit +4 -0
  8. package/.prettierignore +8 -0
  9. package/.prettierrc +1 -0
  10. package/.release-it.json +31 -0
  11. package/.storybook/components/BestPractices.tsx +18 -0
  12. package/.storybook/components/BestPracticesRule.tsx +43 -0
  13. package/.storybook/components/Callout.tsx +12 -0
  14. package/.storybook/components/SectionItem.tsx +44 -0
  15. package/.storybook/components/SectionList.tsx +27 -0
  16. package/.storybook/components/TokenDivider.tsx +12 -0
  17. package/.storybook/components/TokenRow.tsx +32 -0
  18. package/.storybook/components/TokenTable.tsx +33 -0
  19. package/.storybook/components/index.ts +8 -0
  20. package/.storybook/main.js +59 -0
  21. package/.storybook/manager-head.html +9 -0
  22. package/.storybook/manager.js +6 -0
  23. package/.storybook/mocks/cart-sidebar.js +40 -0
  24. package/.storybook/mocks/filter-slider.js +59 -0
  25. package/.storybook/mocks/index.ts +5 -0
  26. package/.storybook/mocks/product.ts +67 -0
  27. package/.storybook/mocks/productGridItems.ts +334 -0
  28. package/.storybook/mocks/searchHistory.ts +8 -0
  29. package/.storybook/mocks/searchTerms.ts +5 -0
  30. package/.storybook/preview-head.html +1 -0
  31. package/.storybook/preview.js +89 -0
  32. package/.storybook/storybook.css +550 -0
  33. package/.storybook/theme.js +21 -0
  34. package/.stylelintignore +1 -0
  35. package/.vscode/settings.json +7 -0
  36. package/@generated/graphql/index.ts +1133 -0
  37. package/@generated/graphql/persisted.json +12 -0
  38. package/CHANGELOG.md +730 -0
  39. package/LICENSE +21 -0
  40. package/README.md +437 -0
  41. package/bun.lockb +0 -0
  42. package/cms/content-types.json +52 -0
  43. package/cms/sections.json +350 -0
  44. package/cms/translation-keys.json +1 -0
  45. package/cms-webhook-urls.json +5 -0
  46. package/codegen.yml +22 -0
  47. package/cypress/fixtures/example.json +5 -0
  48. package/cypress/global.js +15 -0
  49. package/cypress/integration/a11y.test.js +45 -0
  50. package/cypress/integration/analytics.test.js +381 -0
  51. package/cypress/integration/cart.test.js +100 -0
  52. package/cypress/integration/performance.test.js +65 -0
  53. package/cypress/integration/plp.test.js +224 -0
  54. package/cypress/integration/search.test.js +38 -0
  55. package/cypress/integration/seo.test.js +318 -0
  56. package/cypress/plugins/index.js +41 -0
  57. package/cypress/support/commands.js +70 -0
  58. package/cypress/support/index.js +3 -0
  59. package/cypress.json +9 -0
  60. package/lighthouserc.js +22 -0
  61. package/next-env.d.ts +5 -0
  62. package/next.config.js +35 -0
  63. package/package.json +114 -0
  64. package/postcss.config.js +5 -0
  65. package/public/brandless-negative.png +0 -0
  66. package/public/brandless-neutral.png +0 -0
  67. package/public/brandless-positive.png +0 -0
  68. package/public/brandless-storybook.png +0 -0
  69. package/public/favicon.ico +0 -0
  70. package/public/icons.svg +58 -0
  71. package/public/logo.svg +42 -0
  72. package/public/mockServiceWorker.js +367 -0
  73. package/public/robots.txt +5 -0
  74. package/pull_request_template.md +37 -0
  75. package/renovate.json +5 -0
  76. package/src/Layout.tsx +51 -0
  77. package/src/components/ThirdPartyScripts/GoogleTagManager.tsx +61 -0
  78. package/src/components/ThirdPartyScripts/ThirdPartyScripts.tsx +37 -0
  79. package/src/components/ThirdPartyScripts/index.ts +1 -0
  80. package/src/components/ThirdPartyScripts/vtex.tsx +23 -0
  81. package/src/components/cart/CartItem/CartItem.stories.mdx +134 -0
  82. package/src/components/cart/CartItem/CartItem.tsx +158 -0
  83. package/src/components/cart/CartItem/cart-item.module.scss +68 -0
  84. package/src/components/cart/CartItem/index.ts +1 -0
  85. package/src/components/cart/CartSidebar/CartSidebar.stories.mdx +119 -0
  86. package/src/components/cart/CartSidebar/CartSidebar.tsx +140 -0
  87. package/src/components/cart/CartSidebar/cart-sidebar.module.scss +69 -0
  88. package/src/components/cart/CartSidebar/index.ts +1 -0
  89. package/src/components/cart/CartToggle/CartToggle.tsx +20 -0
  90. package/src/components/cart/CartToggle/index.ts +1 -0
  91. package/src/components/cart/EmptyCart/EmptyCart.tsx +26 -0
  92. package/src/components/cart/EmptyCart/index.ts +1 -0
  93. package/src/components/cart/OrderSummary/OrderSummary.tsx +39 -0
  94. package/src/components/cart/OrderSummary/index.ts +1 -0
  95. package/src/components/cart/OrderSummary/order-summary.module.scss +22 -0
  96. package/src/components/cms/RenderPageSections.tsx +52 -0
  97. package/src/components/cms/SectionBoundary.tsx +34 -0
  98. package/src/components/common/Alert/Alert.tsx +53 -0
  99. package/src/components/common/Alert/index.ts +1 -0
  100. package/src/components/common/Footer/Footer.stories.mdx +158 -0
  101. package/src/components/common/Footer/Footer.tsx +160 -0
  102. package/src/components/common/Footer/FooterLinks.tsx +155 -0
  103. package/src/components/common/Footer/footer.module.scss +246 -0
  104. package/src/components/common/Footer/index.ts +2 -0
  105. package/src/components/common/Navbar/NavLinks.stories.mdx +122 -0
  106. package/src/components/common/Navbar/NavLinks.tsx +58 -0
  107. package/src/components/common/Navbar/Navbar.stories.mdx +179 -0
  108. package/src/components/common/Navbar/Navbar.tsx +97 -0
  109. package/src/components/common/Navbar/NavbarSlider.stories.mdx +108 -0
  110. package/src/components/common/Navbar/NavbarSlider.tsx +62 -0
  111. package/src/components/common/Navbar/index.ts +3 -0
  112. package/src/components/common/Navbar/navbar-slider.module.scss +60 -0
  113. package/src/components/common/Navbar/navbar.module.scss +204 -0
  114. package/src/components/common/Navbar/navlinks.module.scss +96 -0
  115. package/src/components/common/Toast/Toast.tsx +40 -0
  116. package/src/components/common/Toast/index.ts +1 -0
  117. package/src/components/product/OutOfStock/OutOfStock.stories.mdx +127 -0
  118. package/src/components/product/OutOfStock/OutOfStock.tsx +134 -0
  119. package/src/components/product/OutOfStock/index.ts +2 -0
  120. package/src/components/product/OutOfStock/out-of-stock.module.scss +55 -0
  121. package/src/components/product/ProductCard/ProductCard.stories.mdx +412 -0
  122. package/src/components/product/ProductCard/ProductCard.tsx +170 -0
  123. package/src/components/product/ProductCard/index.ts +2 -0
  124. package/src/components/product/ProductCard/product-card.module.scss +254 -0
  125. package/src/components/product/ProductGrid/ProductGrid.stories.mdx +97 -0
  126. package/src/components/product/ProductGrid/ProductGrid.tsx +37 -0
  127. package/src/components/product/ProductGrid/index.ts +1 -0
  128. package/src/components/product/ProductGrid/product-grid.module.scss +39 -0
  129. package/src/components/regionalization/Regionalization.stories.mdx +182 -0
  130. package/src/components/regionalization/RegionalizationBar/RegionalizationBar.stories.mdx +116 -0
  131. package/src/components/regionalization/RegionalizationBar/RegionalizationBar.tsx +40 -0
  132. package/src/components/regionalization/RegionalizationBar/index.ts +1 -0
  133. package/src/components/regionalization/RegionalizationBar/regionalization-bar.module.scss +56 -0
  134. package/src/components/regionalization/RegionalizationButton/RegionalizationButton.tsx +24 -0
  135. package/src/components/regionalization/RegionalizationButton/index.ts +1 -0
  136. package/src/components/regionalization/RegionalizationInput/RegionalizationInput.tsx +61 -0
  137. package/src/components/regionalization/RegionalizationInput/index.ts +1 -0
  138. package/src/components/regionalization/RegionalizationModal/RegionalizationModal.stories.mdx +161 -0
  139. package/src/components/regionalization/RegionalizationModal/RegionalizationModal.tsx +13 -0
  140. package/src/components/regionalization/RegionalizationModal/RegionalizationModalContent.tsx +48 -0
  141. package/src/components/regionalization/RegionalizationModal/index.ts +2 -0
  142. package/src/components/regionalization/RegionalizationModal/regionalization-modal-content.module.scss +79 -0
  143. package/src/components/search/Filter/Facets.stories.mdx +284 -0
  144. package/src/components/search/Filter/Facets.tsx +136 -0
  145. package/src/components/search/Filter/Filter.stories.mdx +209 -0
  146. package/src/components/search/Filter/Filter.tsx +91 -0
  147. package/src/components/search/Filter/FilterSlider.stories.mdx +226 -0
  148. package/src/components/search/Filter/FilterSlider.tsx +109 -0
  149. package/src/components/search/Filter/facets.module.scss +117 -0
  150. package/src/components/search/Filter/filter-slider.module.scss +63 -0
  151. package/src/components/search/Filter/index.ts +2 -0
  152. package/src/components/search/Filter/useFilter.ts +131 -0
  153. package/src/components/search/Search.stories.mdx +169 -0
  154. package/src/components/search/SearchDropdown/SearchDropdown.stories.mdx +62 -0
  155. package/src/components/search/SearchDropdown/SearchDropdown.tsx +44 -0
  156. package/src/components/search/SearchDropdown/index.ts +2 -0
  157. package/src/components/search/SearchHistory/SearchHistory.stories.mdx +59 -0
  158. package/src/components/search/SearchHistory/SearchHistory.tsx +51 -0
  159. package/src/components/search/SearchHistory/index.ts +1 -0
  160. package/src/components/search/SearchInput/SearchInput.stories.mdx +205 -0
  161. package/src/components/search/SearchInput/SearchInput.tsx +128 -0
  162. package/src/components/search/SearchInput/index.ts +2 -0
  163. package/src/components/search/SearchInput/search-input.module.scss +153 -0
  164. package/src/components/search/SearchProductCard/SearchProductCard.stories.mdx +96 -0
  165. package/src/components/search/SearchProductCard/SearchProductCard.tsx +103 -0
  166. package/src/components/search/SearchProductCard/index.ts +1 -0
  167. package/src/components/search/SearchProductCard/search-product-card.module.scss +54 -0
  168. package/src/components/search/SearchSharedTokenTable.mdx +98 -0
  169. package/src/components/search/SearchSuggestions/SearchSuggestions.stories.mdx +58 -0
  170. package/src/components/search/SearchSuggestions/SearchSuggestions.tsx +136 -0
  171. package/src/components/search/SearchSuggestions/index.ts +2 -0
  172. package/src/components/search/SearchTop/SearchTop.stories.mdx +58 -0
  173. package/src/components/search/SearchTop/SearchTop.tsx +78 -0
  174. package/src/components/search/SearchTop/index.ts +2 -0
  175. package/src/components/search/Sort/Sort.tsx +42 -0
  176. package/src/components/search/Sort/index.ts +1 -0
  177. package/src/components/search/search.module.scss +101 -0
  178. package/src/components/search/searchMock.ts +48 -0
  179. package/src/components/sections/BannerNewsletter/BannerNewsletter.tsx +28 -0
  180. package/src/components/sections/BannerNewsletter/banner-newsletter.module.scss +23 -0
  181. package/src/components/sections/BannerText/BannerText.stories.mdx +270 -0
  182. package/src/components/sections/BannerText/BannerText.tsx +87 -0
  183. package/src/components/sections/BannerText/banner-text.module.scss +127 -0
  184. package/src/components/sections/BannerText/index.ts +2 -0
  185. package/src/components/sections/Breadcrumb/Breadcrumb.tsx +24 -0
  186. package/src/components/sections/Breadcrumb/index.ts +1 -0
  187. package/src/components/sections/Hero/Hero.stories.mdx +277 -0
  188. package/src/components/sections/Hero/Hero.tsx +109 -0
  189. package/src/components/sections/Hero/hero.module.scss +180 -0
  190. package/src/components/sections/Hero/index.ts +2 -0
  191. package/src/components/sections/Incentives/Incentives.stories.mdx +159 -0
  192. package/src/components/sections/Incentives/Incentives.tsx +69 -0
  193. package/src/components/sections/Incentives/IncentivesFooter.tsx +8 -0
  194. package/src/components/sections/Incentives/IncentivesHeader.tsx +23 -0
  195. package/src/components/sections/Incentives/incentives.module.scss +122 -0
  196. package/src/components/sections/Incentives/incentivesMock.ts +55 -0
  197. package/src/components/sections/Incentives/index.ts +2 -0
  198. package/src/components/sections/Newsletter/Newsletter.stories.mdx +139 -0
  199. package/src/components/sections/Newsletter/Newsletter.tsx +151 -0
  200. package/src/components/sections/Newsletter/index.ts +2 -0
  201. package/src/components/sections/Newsletter/newsletter.module.scss +135 -0
  202. package/src/components/sections/ProducDetailsContent/ProductDetailsContent.stories.mdx +66 -0
  203. package/src/components/sections/ProducDetailsContent/ProductDetailsContent.tsx +278 -0
  204. package/src/components/sections/ProducDetailsContent/index.ts +1 -0
  205. package/src/components/sections/ProducDetailsContent/product-details-content.module.scss +50 -0
  206. package/src/components/sections/ProductDetails/ProductDetails.tsx +316 -0
  207. package/src/components/sections/ProductDetails/index.ts +1 -0
  208. package/src/components/sections/ProductDetails/product-details.module.scss +194 -0
  209. package/src/components/sections/ProductGallery/EmptyGallery.tsx +38 -0
  210. package/src/components/sections/ProductGallery/ProductGallery.tsx +186 -0
  211. package/src/components/sections/ProductGallery/ProductGalleryPage.tsx +70 -0
  212. package/src/components/sections/ProductGallery/index.ts +1 -0
  213. package/src/components/sections/ProductGallery/product-gallery.module.scss +184 -0
  214. package/src/components/sections/ProductGallery/useDelayedFacets.ts +18 -0
  215. package/src/components/sections/ProductGallery/useDelayedPagination.ts +16 -0
  216. package/src/components/sections/ProductGallery/useGalleryQuery.ts +58 -0
  217. package/src/components/sections/ProductGallery/usePageProducts.ts +48 -0
  218. package/src/components/sections/ProductShelf/ProductShelf.tsx +68 -0
  219. package/src/components/sections/ProductShelf/index.ts +1 -0
  220. package/src/components/sections/ProductShelf/product-shelf.module.scss +41 -0
  221. package/src/components/sections/ProductTiles/ProductTiles.tsx +83 -0
  222. package/src/components/sections/ProductTiles/index.ts +1 -0
  223. package/src/components/sections/ScrollToTopButton/ScrollToTopButton.tsx +45 -0
  224. package/src/components/sections/ScrollToTopButton/index.ts +1 -0
  225. package/src/components/sections/ScrollToTopButton/scroll-to-top-button.module.scss +12 -0
  226. package/src/components/sections/Section/Section.tsx +15 -0
  227. package/src/components/sections/Section/index.ts +1 -0
  228. package/src/components/sections/Section/section.scss +16 -0
  229. package/src/components/skeletons/FilterSkeleton/FilterSkeleton.stories.mdx +97 -0
  230. package/src/components/skeletons/FilterSkeleton/FilterSkeleton.tsx +34 -0
  231. package/src/components/skeletons/FilterSkeleton/filter-skeleton.module.scss +51 -0
  232. package/src/components/skeletons/FilterSkeleton/index.ts +1 -0
  233. package/src/components/skeletons/ProductCardSkeleton/ProductCardSkeleton.stories.mdx +176 -0
  234. package/src/components/skeletons/ProductCardSkeleton/ProductCardSkeleton.tsx +52 -0
  235. package/src/components/skeletons/ProductCardSkeleton/index.ts +1 -0
  236. package/src/components/skeletons/ProductCardSkeleton/product-card-skeleton.module.scss +97 -0
  237. package/src/components/skeletons/ProductGridSkeleton/ProductGridSkeleton.tsx +29 -0
  238. package/src/components/skeletons/ProductGridSkeleton/index.ts +1 -0
  239. package/src/components/skeletons/ProductShelfSkeleton/ProductShelfSkeleton.tsx +32 -0
  240. package/src/components/skeletons/ProductShelfSkeleton/index.ts +1 -0
  241. package/src/components/skeletons/ProductTilesSkeleton/ProductTileSkeleton/ProductTileSkeleton.tsx +57 -0
  242. package/src/components/skeletons/ProductTilesSkeleton/ProductTileSkeleton/index.ts +1 -0
  243. package/src/components/skeletons/ProductTilesSkeleton/ProductTileSkeleton/product-tile-skeleton.module.scss +218 -0
  244. package/src/components/skeletons/ProductTilesSkeleton/ProductTilesSkeleton.tsx +33 -0
  245. package/src/components/skeletons/ProductTilesSkeleton/index.ts +2 -0
  246. package/src/components/skeletons/Shimmer/Shimmer.tsx +11 -0
  247. package/src/components/skeletons/Shimmer/index.ts +1 -0
  248. package/src/components/skeletons/Shimmer/shimmer.module.scss +43 -0
  249. package/src/components/skeletons/Skeleton/Skeleton.tsx +49 -0
  250. package/src/components/skeletons/Skeleton/index.ts +1 -0
  251. package/src/components/skeletons/Skeleton/skeleton.module.scss +77 -0
  252. package/src/components/skeletons/Skeletons.stories.mdx +178 -0
  253. package/src/components/ui/Accordion/Accordion.stories.mdx +219 -0
  254. package/src/components/ui/Accordion/Accordion.tsx +39 -0
  255. package/src/components/ui/Accordion/AccordionItem.stories.mdx +116 -0
  256. package/src/components/ui/Accordion/AccordionItem.tsx +82 -0
  257. package/src/components/ui/Accordion/accordion.module.scss +65 -0
  258. package/src/components/ui/Accordion/index.ts +2 -0
  259. package/src/components/ui/Alert/Alert.stories.mdx +164 -0
  260. package/src/components/ui/Alert/Alert.tsx +78 -0
  261. package/src/components/ui/Alert/alert.module.scss +93 -0
  262. package/src/components/ui/Alert/index.ts +1 -0
  263. package/src/components/ui/Badge/Badge.stories.mdx +465 -0
  264. package/src/components/ui/Badge/Badge.tsx +76 -0
  265. package/src/components/ui/Badge/DiscountBadge.stories.mdx +191 -0
  266. package/src/components/ui/Badge/DiscountBadge.tsx +57 -0
  267. package/src/components/ui/Badge/badge.module.scss +252 -0
  268. package/src/components/ui/Badge/index.ts +4 -0
  269. package/src/components/ui/Breadcrumb/Breadcrumb.stories.mdx +197 -0
  270. package/src/components/ui/Breadcrumb/Breadcrumb.tsx +122 -0
  271. package/src/components/ui/Breadcrumb/breadcrumb.module.scss +144 -0
  272. package/src/components/ui/Breadcrumb/index.ts +2 -0
  273. package/src/components/ui/Button/Button.stories.mdx +685 -0
  274. package/src/components/ui/Button/Button.tsx +85 -0
  275. package/src/components/ui/Button/ButtonBuy/ButtonBuy.tsx +24 -0
  276. package/src/components/ui/Button/ButtonBuy/index.ts +1 -0
  277. package/src/components/ui/Button/ButtonLink/ButtonLink.tsx +49 -0
  278. package/src/components/ui/Button/ButtonLink/ButtonSignIn/ButtonSignIn.tsx +22 -0
  279. package/src/components/ui/Button/ButtonLink/ButtonSignIn/ButtonSignInFallback/ButtonSignInFallback.tsx +18 -0
  280. package/src/components/ui/Button/ButtonLink/ButtonSignIn/ButtonSignInFallback/index.ts +1 -0
  281. package/src/components/ui/Button/ButtonLink/ButtonSignIn/index.ts +1 -0
  282. package/src/components/ui/Button/ButtonLink/index.ts +1 -0
  283. package/src/components/ui/Button/button.module.scss +392 -0
  284. package/src/components/ui/Button/index.ts +6 -0
  285. package/src/components/ui/Checkbox/Checkbox.stories.mdx +268 -0
  286. package/src/components/ui/Checkbox/Checkbox.tsx +20 -0
  287. package/src/components/ui/Checkbox/checkbox.module.scss +157 -0
  288. package/src/components/ui/Checkbox/index.ts +2 -0
  289. package/src/components/ui/Dropdown/Dropdown.stories.mdx +232 -0
  290. package/src/components/ui/Dropdown/Dropdown.tsx +12 -0
  291. package/src/components/ui/Dropdown/DropdownButton.tsx +20 -0
  292. package/src/components/ui/Dropdown/DropdownItem.stories.mdx +139 -0
  293. package/src/components/ui/Dropdown/DropdownItem.tsx +26 -0
  294. package/src/components/ui/Dropdown/DropdownMenu.stories.mdx +115 -0
  295. package/src/components/ui/Dropdown/DropdownMenu.tsx +34 -0
  296. package/src/components/ui/Dropdown/dropdown.module.scss +101 -0
  297. package/src/components/ui/Dropdown/index.ts +4 -0
  298. package/src/components/ui/EmptyState/EmptyState.stories.mdx +146 -0
  299. package/src/components/ui/EmptyState/EmptyState.tsx +26 -0
  300. package/src/components/ui/EmptyState/empty-state.module.scss +63 -0
  301. package/src/components/ui/EmptyState/index.ts +1 -0
  302. package/src/components/ui/Gift/Gift.stories.mdx +99 -0
  303. package/src/components/ui/Gift/Gift.tsx +76 -0
  304. package/src/components/ui/Gift/gift.module.scss +94 -0
  305. package/src/components/ui/Gift/index.ts +2 -0
  306. package/src/components/ui/Icon/Icon.tsx +35 -0
  307. package/src/components/ui/Icon/index.ts +1 -0
  308. package/src/components/ui/Image/Image.tsx +59 -0
  309. package/src/components/ui/Image/index.ts +1 -0
  310. package/src/components/ui/Image/thumborUrlBuilder.ts +101 -0
  311. package/src/components/ui/Image/useImage.ts +46 -0
  312. package/src/components/ui/ImageGallery/ImageGallery.stories.mdx +173 -0
  313. package/src/components/ui/ImageGallery/ImageGallery.tsx +51 -0
  314. package/src/components/ui/ImageGallery/ImageGallerySelector.tsx +116 -0
  315. package/src/components/ui/ImageGallery/ImageZoom.tsx +12 -0
  316. package/src/components/ui/ImageGallery/image-gallery-selector.module.scss +131 -0
  317. package/src/components/ui/ImageGallery/image-gallery.module.scss +56 -0
  318. package/src/components/ui/ImageGallery/index.ts +4 -0
  319. package/src/components/ui/InputText/InputText.stories.mdx +311 -0
  320. package/src/components/ui/InputText/InputText.tsx +128 -0
  321. package/src/components/ui/InputText/index.ts +2 -0
  322. package/src/components/ui/InputText/input-text.module.scss +168 -0
  323. package/src/components/ui/Link/Link.stories.mdx +272 -0
  324. package/src/components/ui/Link/Link.tsx +68 -0
  325. package/src/components/ui/Link/index.ts +2 -0
  326. package/src/components/ui/Link/link.module.scss +98 -0
  327. package/src/components/ui/Logo/Logo.tsx +14 -0
  328. package/src/components/ui/Logo/index.ts +1 -0
  329. package/src/components/ui/Logo/logo.module.scss +12 -0
  330. package/src/components/ui/Modal/Modal.stories.mdx +142 -0
  331. package/src/components/ui/Modal/Modal.tsx +43 -0
  332. package/src/components/ui/Modal/index.ts +1 -0
  333. package/src/components/ui/Modal/modal.module.scss +46 -0
  334. package/src/components/ui/Price/Price.stories.mdx +194 -0
  335. package/src/components/ui/Price/Price.tsx +32 -0
  336. package/src/components/ui/Price/index.ts +1 -0
  337. package/src/components/ui/Price/price.module.scss +27 -0
  338. package/src/components/ui/PriceRange/PriceRange.stories.mdx +192 -0
  339. package/src/components/ui/PriceRange/PriceRange.tsx +138 -0
  340. package/src/components/ui/PriceRange/index.ts +1 -0
  341. package/src/components/ui/PriceRange/price-range.module.scss +176 -0
  342. package/src/components/ui/ProductTitle/ProductTitle.stories.mdx +107 -0
  343. package/src/components/ui/ProductTitle/ProductTitle.tsx +11 -0
  344. package/src/components/ui/ProductTitle/index.ts +1 -0
  345. package/src/components/ui/ProductTitle/product-title.module.scss +48 -0
  346. package/src/components/ui/QuantitySelector/QuantitySelector.stories.mdx +246 -0
  347. package/src/components/ui/QuantitySelector/QuantitySelector.tsx +103 -0
  348. package/src/components/ui/QuantitySelector/index.ts +1 -0
  349. package/src/components/ui/QuantitySelector/quantity-selector.module.scss +160 -0
  350. package/src/components/ui/Radio/Radio.stories.mdx +237 -0
  351. package/src/components/ui/Radio/Radio.tsx +36 -0
  352. package/src/components/ui/Radio/index.ts +2 -0
  353. package/src/components/ui/Radio/radio.module.scss +122 -0
  354. package/src/components/ui/SROnly/SROnly.tsx +20 -0
  355. package/src/components/ui/SROnly/index.ts +1 -0
  356. package/src/components/ui/SROnly/sr-only.module.scss +15 -0
  357. package/src/components/ui/Select/Select.stories.mdx +168 -0
  358. package/src/components/ui/Select/Select.tsx +70 -0
  359. package/src/components/ui/Select/index.ts +2 -0
  360. package/src/components/ui/Select/select.module.scss +85 -0
  361. package/src/components/ui/ShippingSimulation/ShippingSimulation.stories.mdx +140 -0
  362. package/src/components/ui/ShippingSimulation/ShippingSimulation.tsx +109 -0
  363. package/src/components/ui/ShippingSimulation/index.ts +1 -0
  364. package/src/components/ui/ShippingSimulation/shipping-simulation.module.scss +96 -0
  365. package/src/components/ui/ShippingSimulation/useShippingSimulation.ts +225 -0
  366. package/src/components/ui/SkuSelector/Selectors.stories.mdx +82 -0
  367. package/src/components/ui/SkuSelector/Selectors.tsx +87 -0
  368. package/src/components/ui/SkuSelector/SkuSelector.stories.mdx +345 -0
  369. package/src/components/ui/SkuSelector/SkuSelector.tsx +46 -0
  370. package/src/components/ui/SkuSelector/index.ts +3 -0
  371. package/src/components/ui/SkuSelector/sku-selector.module.scss +172 -0
  372. package/src/components/ui/SkuSelector/skuVariants.ts +59 -0
  373. package/src/components/ui/SlideOver/SlideOver.stories.mdx +285 -0
  374. package/src/components/ui/SlideOver/SlideOver.tsx +58 -0
  375. package/src/components/ui/SlideOver/index.ts +1 -0
  376. package/src/components/ui/SlideOver/overlay.scss +14 -0
  377. package/src/components/ui/SlideOver/slide-over.module.scss +63 -0
  378. package/src/components/ui/Tiles/Tiles.stories.mdx +153 -0
  379. package/src/components/ui/Tiles/Tiles.tsx +14 -0
  380. package/src/components/ui/Tiles/index.ts +5 -0
  381. package/src/components/ui/Tiles/tiles.module.scss +60 -0
  382. package/src/components/ui/Toast/Toast.stories.mdx +158 -0
  383. package/src/components/ui/Toast/Toast.tsx +56 -0
  384. package/src/components/ui/Toast/index.ts +1 -0
  385. package/src/components/ui/Toast/toast.module.scss +112 -0
  386. package/src/components/ui/Toggle/Toggle.stories.mdx +604 -0
  387. package/src/components/ui/Toggle/Toggle.tsx +75 -0
  388. package/src/components/ui/Toggle/index.ts +2 -0
  389. package/src/components/ui/Toggle/toggle.module.scss +200 -0
  390. package/src/constants.ts +2 -0
  391. package/src/fonts/WebFonts.tsx +15 -0
  392. package/src/images/icon.png +0 -0
  393. package/src/pages/404.tsx +27 -0
  394. package/src/pages/500.tsx +31 -0
  395. package/src/pages/[...slug].tsx +186 -0
  396. package/src/pages/[slug]/p.tsx +209 -0
  397. package/src/pages/_app.tsx +38 -0
  398. package/src/pages/_document.tsx +22 -0
  399. package/src/pages/account.tsx +20 -0
  400. package/src/pages/api/graphql.ts +72 -0
  401. package/src/pages/api/preview.ts +61 -0
  402. package/src/pages/checkout.tsx +20 -0
  403. package/src/pages/index.tsx +72 -0
  404. package/src/pages/login.tsx +20 -0
  405. package/src/pages/s.tsx +83 -0
  406. package/src/sdk/analytics/hooks/useViewItemListEvent.ts +51 -0
  407. package/src/sdk/analytics/index.tsx +30 -0
  408. package/src/sdk/analytics/platform/vtex/index.ts +11 -0
  409. package/src/sdk/analytics/platform/vtex/search.ts +102 -0
  410. package/src/sdk/analytics/types.ts +22 -0
  411. package/src/sdk/cart/index.ts +187 -0
  412. package/src/sdk/cart/useBuyButton.ts +62 -0
  413. package/src/sdk/cart/useCartToggleButton.ts +23 -0
  414. package/src/sdk/cart/useCheckoutButton.ts +22 -0
  415. package/src/sdk/cart/useRemoveButton.ts +56 -0
  416. package/src/sdk/error/ErrorBoundary/ErrorBoundary.tsx +67 -0
  417. package/src/sdk/error/ErrorBoundary/index.ts +1 -0
  418. package/src/sdk/graphql/prefetchQuery.ts +20 -0
  419. package/src/sdk/graphql/request.ts +25 -0
  420. package/src/sdk/graphql/useLazyQuery.ts +29 -0
  421. package/src/sdk/graphql/useQuery.ts +40 -0
  422. package/src/sdk/newsletter/useNewsletter.ts +31 -0
  423. package/src/sdk/product/useDiscountPercent.ts +10 -0
  424. package/src/sdk/product/useFormattedPrice.ts +27 -0
  425. package/src/sdk/product/useProduct.ts +46 -0
  426. package/src/sdk/product/useProductLink.ts +69 -0
  427. package/src/sdk/product/useProductsQuery.ts +107 -0
  428. package/src/sdk/search/Sentinel.tsx +78 -0
  429. package/src/sdk/search/state.ts +11 -0
  430. package/src/sdk/search/useSearchHistory.ts +40 -0
  431. package/src/sdk/search/useSearchInput.tsx +43 -0
  432. package/src/sdk/search/useSuggestions.ts +49 -0
  433. package/src/sdk/search/useTopSearch.ts +49 -0
  434. package/src/sdk/session/index.ts +71 -0
  435. package/src/sdk/tests/mark.tsx +10 -0
  436. package/src/sdk/ui/Provider.tsx +151 -0
  437. package/src/sdk/ui/useFadeEffect.ts +21 -0
  438. package/src/sdk/ui/useOnClickOutside.ts +39 -0
  439. package/src/sdk/ui/useScrollDirection.ts +31 -0
  440. package/src/sdk/useStore.ts +24 -0
  441. package/src/server/cms.ts +66 -0
  442. package/src/server/index.ts +105 -0
  443. package/src/stories/brandless.stories.mdx +85 -0
  444. package/src/stories/changelog-template.stories.mdx +10 -0
  445. package/src/stories/colors.stories.mdx +306 -0
  446. package/src/stories/customizing.stories.mdx +113 -0
  447. package/src/stories/getting-started.stories.mdx +65 -0
  448. package/src/stories/grid-layout.stories.mdx +53 -0
  449. package/src/stories/icons.stories.mdx +237 -0
  450. package/src/stories/interactive-controls.stories.mdx +50 -0
  451. package/src/stories/midnight.stories.mdx +56 -0
  452. package/src/stories/refinements.stories.mdx +96 -0
  453. package/src/stories/soft-blue.stories.mdx +56 -0
  454. package/src/stories/spacing.stories.mdx +38 -0
  455. package/src/stories/typography.stories.mdx +224 -0
  456. package/src/styles/global/components.scss +5 -0
  457. package/src/styles/global/layout.scss +80 -0
  458. package/src/styles/global/resets.scss +48 -0
  459. package/src/styles/global/storybook-components.scss +5 -0
  460. package/src/styles/global/tokens.scss +276 -0
  461. package/src/styles/global/typography.scss +66 -0
  462. package/src/styles/global/utilities.scss +69 -0
  463. package/src/styles/scaffold.scss +7 -0
  464. package/src/styles/themes/custom-theme.scss +36 -0
  465. package/src/styles/themes/midnight.scss +123 -0
  466. package/src/styles/themes/soft-blue.scss +79 -0
  467. package/src/styles/vendors/include-media.scss +4 -0
  468. package/src/styles/vendors/include-media_overwrite.scss +9 -0
  469. package/src/styles/vendors/modern-normalize.css +270 -0
  470. package/src/typings/global.d.ts +6 -0
  471. package/src/typings/module.css.d.ts +7 -0
  472. package/store.config.js +69 -0
  473. package/stylelint.config.js +82 -0
  474. package/tsconfig.json +25 -0
  475. package/vtex.env +14 -0
@@ -0,0 +1,367 @@
1
+ /* eslint-disable */
2
+ /* tslint:disable */
3
+
4
+ /**
5
+ * Mock Service Worker (0.43.1).
6
+ * @see https://github.com/mswjs/msw
7
+ * - Please do NOT modify this file.
8
+ * - Please do NOT serve this file on production.
9
+ */
10
+
11
+ const INTEGRITY_CHECKSUM = 'c9450df6e4dc5e45740c3b0b640727a2'
12
+ const activeClientIds = new Set()
13
+
14
+ self.addEventListener('install', function () {
15
+ self.skipWaiting()
16
+ })
17
+
18
+ self.addEventListener('activate', function (event) {
19
+ event.waitUntil(self.clients.claim())
20
+ })
21
+
22
+ self.addEventListener('message', async function (event) {
23
+ const clientId = event.source.id
24
+
25
+ if (!clientId || !self.clients) {
26
+ return
27
+ }
28
+
29
+ const client = await self.clients.get(clientId)
30
+
31
+ if (!client) {
32
+ return
33
+ }
34
+
35
+ const allClients = await self.clients.matchAll({
36
+ type: 'window',
37
+ })
38
+
39
+ switch (event.data) {
40
+ case 'KEEPALIVE_REQUEST': {
41
+ sendToClient(client, {
42
+ type: 'KEEPALIVE_RESPONSE',
43
+ })
44
+ break
45
+ }
46
+
47
+ case 'INTEGRITY_CHECK_REQUEST': {
48
+ sendToClient(client, {
49
+ type: 'INTEGRITY_CHECK_RESPONSE',
50
+ payload: INTEGRITY_CHECKSUM,
51
+ })
52
+ break
53
+ }
54
+
55
+ case 'MOCK_ACTIVATE': {
56
+ activeClientIds.add(clientId)
57
+
58
+ sendToClient(client, {
59
+ type: 'MOCKING_ENABLED',
60
+ payload: true,
61
+ })
62
+ break
63
+ }
64
+
65
+ case 'MOCK_DEACTIVATE': {
66
+ activeClientIds.delete(clientId)
67
+ break
68
+ }
69
+
70
+ case 'CLIENT_CLOSED': {
71
+ activeClientIds.delete(clientId)
72
+
73
+ const remainingClients = allClients.filter((client) => {
74
+ return client.id !== clientId
75
+ })
76
+
77
+ // Unregister itself when there are no more clients
78
+ if (remainingClients.length === 0) {
79
+ self.registration.unregister()
80
+ }
81
+
82
+ break
83
+ }
84
+ }
85
+ })
86
+
87
+ self.addEventListener('fetch', function (event) {
88
+ const { request } = event
89
+ const accept = request.headers.get('accept') || ''
90
+
91
+ // Bypass server-sent events.
92
+ if (accept.includes('text/event-stream')) {
93
+ return
94
+ }
95
+
96
+ // Bypass navigation requests.
97
+ if (request.mode === 'navigate') {
98
+ return
99
+ }
100
+
101
+ // Opening the DevTools triggers the "only-if-cached" request
102
+ // that cannot be handled by the worker. Bypass such requests.
103
+ if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
104
+ return
105
+ }
106
+
107
+ // Bypass all requests when there are no active clients.
108
+ // Prevents the self-unregistered worked from handling requests
109
+ // after it's been deleted (still remains active until the next reload).
110
+ if (activeClientIds.size === 0) {
111
+ return
112
+ }
113
+
114
+ // Generate unique request ID.
115
+ const requestId = Math.random().toString(16).slice(2)
116
+
117
+ event.respondWith(
118
+ handleRequest(event, requestId).catch((error) => {
119
+ if (error.name === 'NetworkError') {
120
+ console.warn(
121
+ '[MSW] Successfully emulated a network error for the "%s %s" request.',
122
+ request.method,
123
+ request.url,
124
+ )
125
+ return
126
+ }
127
+
128
+ // At this point, any exception indicates an issue with the original request/response.
129
+ console.error(
130
+ `\
131
+ [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
132
+ request.method,
133
+ request.url,
134
+ `${error.name}: ${error.message}`,
135
+ )
136
+ }),
137
+ )
138
+ })
139
+
140
+ async function handleRequest(event, requestId) {
141
+ const client = await resolveMainClient(event)
142
+ const response = await getResponse(event, client, requestId)
143
+
144
+ // Send back the response clone for the "response:*" life-cycle events.
145
+ // Ensure MSW is active and ready to handle the message, otherwise
146
+ // this message will pend indefinitely.
147
+ if (client && activeClientIds.has(client.id)) {
148
+ ;(async function () {
149
+ const clonedResponse = response.clone()
150
+ sendToClient(client, {
151
+ type: 'RESPONSE',
152
+ payload: {
153
+ requestId,
154
+ type: clonedResponse.type,
155
+ ok: clonedResponse.ok,
156
+ status: clonedResponse.status,
157
+ statusText: clonedResponse.statusText,
158
+ body:
159
+ clonedResponse.body === null ? null : await clonedResponse.text(),
160
+ headers: Object.fromEntries(clonedResponse.headers.entries()),
161
+ redirected: clonedResponse.redirected,
162
+ },
163
+ })
164
+ })()
165
+ }
166
+
167
+ return response
168
+ }
169
+
170
+ // Resolve the main client for the given event.
171
+ // Client that issues a request doesn't necessarily equal the client
172
+ // that registered the worker. It's with the latter the worker should
173
+ // communicate with during the response resolving phase.
174
+ async function resolveMainClient(event) {
175
+ const client = await self.clients.get(event.clientId)
176
+
177
+ if (client.frameType === 'top-level') {
178
+ return client
179
+ }
180
+
181
+ const allClients = await self.clients.matchAll({
182
+ type: 'window',
183
+ })
184
+
185
+ return allClients
186
+ .filter((client) => {
187
+ // Get only those clients that are currently visible.
188
+ return client.visibilityState === 'visible'
189
+ })
190
+ .find((client) => {
191
+ // Find the client ID that's recorded in the
192
+ // set of clients that have registered the worker.
193
+ return activeClientIds.has(client.id)
194
+ })
195
+ }
196
+
197
+ async function getResponse(event, client, requestId) {
198
+ const { request } = event
199
+ const clonedRequest = request.clone()
200
+
201
+ function passthrough() {
202
+ // Clone the request because it might've been already used
203
+ // (i.e. its body has been read and sent to the cilent).
204
+ const headers = Object.fromEntries(clonedRequest.headers.entries())
205
+
206
+ // Remove MSW-specific request headers so the bypassed requests
207
+ // comply with the server's CORS preflight check.
208
+ // Operate with the headers as an object because request "Headers"
209
+ // are immutable.
210
+ delete headers['x-msw-bypass']
211
+
212
+ return fetch(clonedRequest, { headers })
213
+ }
214
+
215
+ // Bypass mocking when the client is not active.
216
+ if (!client) {
217
+ return passthrough()
218
+ }
219
+
220
+ // Bypass initial page load requests (i.e. static assets).
221
+ // The absence of the immediate/parent client in the map of the active clients
222
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
223
+ // and is not ready to handle requests.
224
+ if (!activeClientIds.has(client.id)) {
225
+ return passthrough()
226
+ }
227
+
228
+ // Bypass requests with the explicit bypass header.
229
+ // Such requests can be issued by "ctx.fetch()".
230
+ if (request.headers.get('x-msw-bypass') === 'true') {
231
+ return passthrough()
232
+ }
233
+
234
+ // Create a communication channel scoped to the current request.
235
+ // This way events can be exchanged outside of the worker's global
236
+ // "message" event listener (i.e. abstracted into functions).
237
+ const operationChannel = new BroadcastChannel(
238
+ `msw-response-stream-${requestId}`,
239
+ )
240
+
241
+ // Notify the client that a request has been intercepted.
242
+ const clientMessage = await sendToClient(client, {
243
+ type: 'REQUEST',
244
+ payload: {
245
+ id: requestId,
246
+ url: request.url,
247
+ method: request.method,
248
+ headers: Object.fromEntries(request.headers.entries()),
249
+ cache: request.cache,
250
+ mode: request.mode,
251
+ credentials: request.credentials,
252
+ destination: request.destination,
253
+ integrity: request.integrity,
254
+ redirect: request.redirect,
255
+ referrer: request.referrer,
256
+ referrerPolicy: request.referrerPolicy,
257
+ body: await request.text(),
258
+ bodyUsed: request.bodyUsed,
259
+ keepalive: request.keepalive,
260
+ },
261
+ })
262
+
263
+ switch (clientMessage.type) {
264
+ case 'MOCK_RESPONSE': {
265
+ return respondWithMock(clientMessage.payload)
266
+ }
267
+
268
+ case 'MOCK_RESPONSE_START': {
269
+ return respondWithMockStream(operationChannel, clientMessage.payload)
270
+ }
271
+
272
+ case 'MOCK_NOT_FOUND': {
273
+ return passthrough()
274
+ }
275
+
276
+ case 'NETWORK_ERROR': {
277
+ const { name, message } = clientMessage.payload
278
+ const networkError = new Error(message)
279
+ networkError.name = name
280
+
281
+ // Rejecting a "respondWith" promise emulates a network error.
282
+ throw networkError
283
+ }
284
+
285
+ case 'INTERNAL_ERROR': {
286
+ const parsedBody = JSON.parse(clientMessage.payload.body)
287
+
288
+ console.error(
289
+ `\
290
+ [MSW] Uncaught exception in the request handler for "%s %s":
291
+
292
+ ${parsedBody.location}
293
+
294
+ This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\
295
+ `,
296
+ request.method,
297
+ request.url,
298
+ )
299
+
300
+ return respondWithMock(clientMessage.payload)
301
+ }
302
+ }
303
+
304
+ return passthrough()
305
+ }
306
+
307
+ function sendToClient(client, message) {
308
+ return new Promise((resolve, reject) => {
309
+ const channel = new MessageChannel()
310
+
311
+ channel.port1.onmessage = (event) => {
312
+ if (event.data && event.data.error) {
313
+ return reject(event.data.error)
314
+ }
315
+
316
+ resolve(event.data)
317
+ }
318
+
319
+ client.postMessage(JSON.stringify(message), [channel.port2])
320
+ })
321
+ }
322
+
323
+ function sleep(timeMs) {
324
+ return new Promise((resolve) => {
325
+ setTimeout(resolve, timeMs)
326
+ })
327
+ }
328
+
329
+ async function respondWithMock(response) {
330
+ await sleep(response.delay)
331
+ return new Response(response.body, response)
332
+ }
333
+
334
+ function respondWithMockStream(operationChannel, mockResponse) {
335
+ let streamCtrl
336
+ const stream = new ReadableStream({
337
+ start: (controller) => (streamCtrl = controller),
338
+ })
339
+
340
+ return new Promise(async (resolve, reject) => {
341
+ operationChannel.onmessageerror = (event) => {
342
+ operationChannel.close()
343
+ return reject(event.data.error)
344
+ }
345
+
346
+ operationChannel.onmessage = (event) => {
347
+ if (!event.data) {
348
+ return
349
+ }
350
+
351
+ switch (event.data.type) {
352
+ case 'MOCK_RESPONSE_CHUNK': {
353
+ streamCtrl.enqueue(event.data.payload)
354
+ break
355
+ }
356
+
357
+ case 'MOCK_RESPONSE_END': {
358
+ streamCtrl.close()
359
+ operationChannel.close()
360
+ }
361
+ }
362
+ }
363
+
364
+ await sleep(mockResponse.delay)
365
+ return resolve(new Response(stream, mockResponse))
366
+ })
367
+ }
@@ -0,0 +1,5 @@
1
+ User-agent: *
2
+ Allow: /
3
+ Disallow: /checkout/*
4
+ Sitemap: https://vtexfaststore.com/sitemap/sitemap-index.xml
5
+ Host: https://vtexfaststore.com
@@ -0,0 +1,37 @@
1
+ ## What's the purpose of this pull request?
2
+
3
+ <em>Considering the context, what is the problem we'll solve? Where in VTEX's big picture our issue fits in? Write a tweet about the context and the problem itself.</em>
4
+
5
+ ## How does it work?
6
+
7
+ <em>Tell us the role of the new feature, or component, in its context.</em>
8
+
9
+ ## How to test it?
10
+
11
+ <em>Describe the steps with bullet points. Is there any external reference, link, or example?</em>
12
+
13
+ ## References
14
+
15
+ <em>Spread the knowledge: is any content you used to create this PR worth sharing?</em>
16
+
17
+ <em>Extra tip: add references to related issues or mention people important to this PR may be good for the documentation and reviewing process</em>
18
+
19
+ ## Checklist
20
+
21
+ <em>You may erase this after checking them all :wink:</em>
22
+
23
+ **PR Title and Commit Messages**
24
+ - [ ] PR title and commit messages follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification
25
+ - Available prefixes: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `perf`, and `test`
26
+
27
+ **PR Description**
28
+ - [ ] Added a label according to the PR goal - `Breaking change`, `Features`, `Bug fixes`, `Chore`, `Documentation`, `Style changes`, `Refactoring`, `Performance`, and `Test`
29
+ - [ ] Added the component, hook, or path name in-between backticks (\`\`) - *if applicable, e.g., `ComponentName` component, `useWindowDimensions` hook*
30
+
31
+ **Dependencies**
32
+ - [ ] Committed the `yarn.lock` and `bun.lockb` file when there were changes to the packages
33
+
34
+ **Documentation**
35
+ - [ ] PR description
36
+ - [ ] Added to/Updated the Storybook - *if applicable*
37
+ - [ ] For documentation changes, ping `@carolinamenezes` or `@PedroAntunesCosta` to review and update
package/renovate.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": [
3
+ "@vtex"
4
+ ]
5
+ }
package/src/Layout.tsx ADDED
@@ -0,0 +1,51 @@
1
+ import { lazy, Suspense } from 'react'
2
+ import type { PropsWithChildren } from 'react'
3
+
4
+ import Alert from 'src/components/common/Alert'
5
+ import Footer from 'src/components/common/Footer'
6
+ import Navbar from 'src/components/common/Navbar'
7
+ import Toast from 'src/components/common/Toast'
8
+ import RegionalizationBar from 'src/components/regionalization/RegionalizationBar'
9
+ import { useUI } from 'src/sdk/ui/Provider'
10
+
11
+ const CartSidebar = lazy(() => import('src/components/cart/CartSidebar'))
12
+ const RegionModal = lazy(
13
+ () => import('src/components/regionalization/RegionalizationModal')
14
+ )
15
+
16
+ function Layout({ children }: PropsWithChildren) {
17
+ const { cart: displayCart, modal: displayModal } = useUI()
18
+
19
+ return (
20
+ <>
21
+ <Alert icon="Bell" link={{ text: 'Buy now', to: '/office' }} dismissible>
22
+ Get 10% off today:&nbsp;<span>NEW10</span>
23
+ </Alert>
24
+
25
+ <Navbar />
26
+
27
+ <Toast />
28
+
29
+ <main>
30
+ <RegionalizationBar classes="display-mobile" />
31
+ {children}
32
+ </main>
33
+
34
+ <Footer />
35
+
36
+ {displayCart && (
37
+ <Suspense fallback={null}>
38
+ <CartSidebar />
39
+ </Suspense>
40
+ )}
41
+
42
+ {displayModal && (
43
+ <Suspense fallback={null}>
44
+ <RegionModal />
45
+ </Suspense>
46
+ )}
47
+ </>
48
+ )
49
+ }
50
+
51
+ export default Layout
@@ -0,0 +1,61 @@
1
+ interface Props {
2
+ containerId: string
3
+ dataLayerName?: string
4
+ }
5
+
6
+ const GTM_DEBUG_QUERY_STRING = 'gtm_debug'
7
+
8
+ const useSnippet = (opts: Props & { partytownScript: boolean }) => `${
9
+ opts.partytownScript ? '!' : ''
10
+ }window.location.search.includes('${GTM_DEBUG_QUERY_STRING}=')&&
11
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
12
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
13
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
14
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
15
+ })(window,document,'script',${JSON.stringify(
16
+ opts.dataLayerName ?? 'dataLayer'
17
+ )},${JSON.stringify(opts.containerId)});`
18
+
19
+ /**
20
+ * Google Tag Manager script adapted to be executed only when necessary.
21
+ *
22
+ * The first script adds the GTM script to partytown. It is meant for when regular users
23
+ * are browsing the website, so that loading and executing it doesn't affect performance
24
+ *
25
+ * The second script is meant for GTM debugging. Since debugging GTM inside partytown still doesn't work,
26
+ * it is only executed when the url includes the gtm_debug query string.
27
+ *
28
+ * Since the query string isn't accessible during SSR, the decision of which script should be executed
29
+ * is bundled with the script, and that's why we need to include both. The script isn't GTM itself, but
30
+ * the code who will, after being executed, add the GTM script to the page.
31
+ *
32
+ * https://developers.google.com/tag-manager/quickstart
33
+ */
34
+ function GoogleTagManager(props: Props) {
35
+ return (
36
+ <>
37
+ <script
38
+ key="gtm.partytown"
39
+ type="text/partytown"
40
+ dangerouslySetInnerHTML={{
41
+ __html: useSnippet({
42
+ ...props,
43
+ partytownScript: true,
44
+ }),
45
+ }}
46
+ />
47
+ <script
48
+ key="gtm"
49
+ type="text/javascript"
50
+ dangerouslySetInnerHTML={{
51
+ __html: useSnippet({
52
+ ...props,
53
+ partytownScript: false,
54
+ }),
55
+ }}
56
+ />
57
+ </>
58
+ )
59
+ }
60
+
61
+ export default GoogleTagManager
@@ -0,0 +1,37 @@
1
+ import { Partytown } from '@builder.io/partytown/react'
2
+
3
+ import storeConfig from '../../../store.config'
4
+ import GoogleTagManager from './GoogleTagManager'
5
+ import VTEX from './vtex'
6
+
7
+ const isString = (obj: unknown): obj is string => typeof obj === 'string'
8
+
9
+ const gtmContainerId = storeConfig.analytics?.gtmContainerId
10
+
11
+ const includeGTM = typeof gtmContainerId === 'string'
12
+ const includeVTEX = storeConfig.platform === 'vtex'
13
+
14
+ if (process.env.NODE_ENV === 'development' && !includeGTM) {
15
+ console.warn(
16
+ 'No GTM container id found. Check the analytics section on your store.config.js file for enhanced observability of your store.'
17
+ )
18
+ }
19
+
20
+ function ThirdPartyScripts() {
21
+ return (
22
+ <>
23
+ {includeGTM && <GoogleTagManager containerId={gtmContainerId} />}
24
+ {includeVTEX && <VTEX />}
25
+ <Partytown
26
+ key="partytown"
27
+ // Variables to forward to from main to worker
28
+ forward={[
29
+ includeGTM && 'dataLayer.push',
30
+ includeVTEX && 'sendrc',
31
+ ].filter(isString)}
32
+ />
33
+ </>
34
+ )
35
+ }
36
+
37
+ export default ThirdPartyScripts
@@ -0,0 +1 @@
1
+ export { default } from './ThirdPartyScripts'
@@ -0,0 +1,23 @@
1
+ function VTEX() {
2
+ return (
3
+ <>
4
+ <script
5
+ key="vtexrc.js-init"
6
+ type="text/partytown"
7
+ dangerouslySetInnerHTML={{
8
+ __html: `
9
+ window.sendrc=function(en,ed){window.NavigationCapture&&window.NavigationCapture.sendEvent(en,ed)};
10
+ `,
11
+ }}
12
+ />
13
+ <script
14
+ key="vtexrc.js-script"
15
+ type="text/partytown"
16
+ async
17
+ src="https://io.vtex.com.br/rc/rc.js"
18
+ />
19
+ </>
20
+ )
21
+ }
22
+
23
+ export default VTEX