@faststore/core 2.1.14 → 2.1.17

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 (167) hide show
  1. package/.turbo/turbo-build.log +9 -9
  2. package/lighthouserc.js +1 -0
  3. package/package.json +4 -4
  4. package/src/components/common/Alert/Alert.tsx +14 -2
  5. package/src/components/navigation/Navbar/Navbar.tsx +9 -7
  6. package/src/components/product/ProductCard/ProductCard.tsx +5 -2
  7. package/src/components/region/RegionBar/RegionBar.tsx +22 -6
  8. package/src/components/sections/Alert/Alert.tsx +23 -7
  9. package/src/components/sections/Alert/Overrides.tsx +27 -0
  10. package/src/components/sections/EmptyState/EmptyState.tsx +12 -5
  11. package/src/components/sections/EmptyState/Overrides.tsx +26 -0
  12. package/src/components/sections/Newsletter/Overrides.tsx +35 -0
  13. package/src/components/sections/RegionBar/Overrides.tsx +28 -0
  14. package/src/components/ui/Newsletter/Newsletter.tsx +62 -17
  15. package/src/customizations/components/overrides/Alert.tsx +15 -0
  16. package/src/customizations/components/overrides/EmptyState.tsx +13 -0
  17. package/src/customizations/components/overrides/Newsletter.tsx +19 -0
  18. package/src/customizations/components/overrides/RegionBar.tsx +16 -0
  19. package/src/typings/overrides.d.ts +19 -0
  20. package/.next/BUILD_ID +0 -1
  21. package/.next/build-manifest.json +0 -125
  22. package/.next/cache/.tsbuildinfo +0 -1
  23. package/.next/cache/config.json +0 -7
  24. package/.next/cache/eslint/.cache_1gneedd +0 -1
  25. package/.next/cache/next-server.js.nft.json +0 -1
  26. package/.next/cache/webpack/client-production/0.pack +0 -0
  27. package/.next/cache/webpack/client-production/index.pack +0 -0
  28. package/.next/cache/webpack/server-production/0.pack +0 -0
  29. package/.next/cache/webpack/server-production/index.pack +0 -0
  30. package/.next/export-marker.json +0 -1
  31. package/.next/images-manifest.json +0 -1
  32. package/.next/next-server.js.nft.json +0 -1
  33. package/.next/package.json +0 -1
  34. package/.next/prerender-manifest.json +0 -1
  35. package/.next/react-loadable-manifest.json +0 -44
  36. package/.next/required-server-files.json +0 -1
  37. package/.next/routes-manifest.json +0 -1
  38. package/.next/server/chunks/123.js +0 -58
  39. package/.next/server/chunks/143.js +0 -106
  40. package/.next/server/chunks/183.js +0 -90
  41. package/.next/server/chunks/184.js +0 -61
  42. package/.next/server/chunks/205.js +0 -722
  43. package/.next/server/chunks/247.js +0 -61
  44. package/.next/server/chunks/253.js +0 -535
  45. package/.next/server/chunks/269.js +0 -516
  46. package/.next/server/chunks/287.js +0 -58
  47. package/.next/server/chunks/289.js +0 -242
  48. package/.next/server/chunks/312.js +0 -697
  49. package/.next/server/chunks/350.js +0 -143
  50. package/.next/server/chunks/487.js +0 -9142
  51. package/.next/server/chunks/502.js +0 -626
  52. package/.next/server/chunks/513.js +0 -257
  53. package/.next/server/chunks/576.js +0 -90
  54. package/.next/server/chunks/597.js +0 -211
  55. package/.next/server/chunks/650.js +0 -9142
  56. package/.next/server/chunks/676.js +0 -32
  57. package/.next/server/chunks/701.js +0 -87
  58. package/.next/server/chunks/74.js +0 -3949
  59. package/.next/server/chunks/825.js +0 -4039
  60. package/.next/server/chunks/854.js +0 -72
  61. package/.next/server/chunks/859.js +0 -959
  62. package/.next/server/chunks/886.js +0 -120
  63. package/.next/server/chunks/90.js +0 -539
  64. package/.next/server/chunks/907.js +0 -1957
  65. package/.next/server/chunks/98.js +0 -124
  66. package/.next/server/chunks/font-manifest.json +0 -1
  67. package/.next/server/font-manifest.json +0 -1
  68. package/.next/server/middleware-build-manifest.js +0 -1
  69. package/.next/server/middleware-manifest.json +0 -6
  70. package/.next/server/middleware-react-loadable-manifest.js +0 -1
  71. package/.next/server/pages/404.js +0 -386
  72. package/.next/server/pages/404.js.nft.json +0 -1
  73. package/.next/server/pages/500.js +0 -388
  74. package/.next/server/pages/500.js.nft.json +0 -1
  75. package/.next/server/pages/[...slug].js +0 -778
  76. package/.next/server/pages/[...slug].js.nft.json +0 -1
  77. package/.next/server/pages/[slug]/p.js +0 -2388
  78. package/.next/server/pages/[slug]/p.js.nft.json +0 -1
  79. package/.next/server/pages/_app.js +0 -281
  80. package/.next/server/pages/_app.js.nft.json +0 -1
  81. package/.next/server/pages/_document.js +0 -340
  82. package/.next/server/pages/_document.js.nft.json +0 -1
  83. package/.next/server/pages/_error.js +0 -164
  84. package/.next/server/pages/_error.js.nft.json +0 -1
  85. package/.next/server/pages/account.js +0 -363
  86. package/.next/server/pages/account.js.nft.json +0 -1
  87. package/.next/server/pages/api/graphql.js +0 -365
  88. package/.next/server/pages/api/graphql.js.nft.json +0 -1
  89. package/.next/server/pages/api/preview.js +0 -119
  90. package/.next/server/pages/api/preview.js.nft.json +0 -1
  91. package/.next/server/pages/checkout.js +0 -363
  92. package/.next/server/pages/checkout.js.nft.json +0 -1
  93. package/.next/server/pages/en-US/404.html +0 -81
  94. package/.next/server/pages/en-US/404.json +0 -1
  95. package/.next/server/pages/en-US/500.html +0 -81
  96. package/.next/server/pages/en-US/500.json +0 -1
  97. package/.next/server/pages/en-US/account.html +0 -81
  98. package/.next/server/pages/en-US/account.json +0 -1
  99. package/.next/server/pages/en-US/checkout.html +0 -81
  100. package/.next/server/pages/en-US/checkout.json +0 -1
  101. package/.next/server/pages/en-US/login.html +0 -81
  102. package/.next/server/pages/en-US/login.json +0 -1
  103. package/.next/server/pages/en-US/s.html +0 -81
  104. package/.next/server/pages/en-US/s.json +0 -1
  105. package/.next/server/pages/en-US.html +0 -81
  106. package/.next/server/pages/en-US.json +0 -1
  107. package/.next/server/pages/index.js +0 -911
  108. package/.next/server/pages/index.js.nft.json +0 -1
  109. package/.next/server/pages/login.js +0 -368
  110. package/.next/server/pages/login.js.nft.json +0 -1
  111. package/.next/server/pages/s.js +0 -466
  112. package/.next/server/pages/s.js.nft.json +0 -1
  113. package/.next/server/pages-manifest.json +0 -16
  114. package/.next/server/webpack-api-runtime.js +0 -229
  115. package/.next/server/webpack-runtime.js +0 -229
  116. package/.next/static/chunks/143.dd8a556e6957baa1.js +0 -1
  117. package/.next/static/chunks/483-eda59544da21c849.js +0 -1
  118. package/.next/static/chunks/495.0ecd099878b2a36d.js +0 -1
  119. package/.next/static/chunks/502.2270ffae48e3dccd.js +0 -1
  120. package/.next/static/chunks/548-6b23e7ad82cd22b9.js +0 -1
  121. package/.next/static/chunks/597.f8d0595b113c70af.js +0 -1
  122. package/.next/static/chunks/64.7ea3677ac3a10e00.js +0 -1
  123. package/.next/static/chunks/651.7142f31ce1e052b3.js +0 -1
  124. package/.next/static/chunks/682-5cfea9ed52851ed1.js +0 -1
  125. package/.next/static/chunks/738-a5ff304828f20cbf.js +0 -1
  126. package/.next/static/chunks/741.52f7fb873418346f.js +0 -1
  127. package/.next/static/chunks/791-727eda8f766aa791.js +0 -1
  128. package/.next/static/chunks/98.97381d2021f86cd9.js +0 -1
  129. package/.next/static/chunks/framework-dfd14d7ce6600b03.js +0 -1
  130. package/.next/static/chunks/main-fd466221927468fd.js +0 -1
  131. package/.next/static/chunks/pages/404-c3b320b915df45bb.js +0 -1
  132. package/.next/static/chunks/pages/500-d37a3a2e931f6995.js +0 -1
  133. package/.next/static/chunks/pages/[...slug]-7370214f166e8584.js +0 -1
  134. package/.next/static/chunks/pages/[slug]/p-7b946d76b9f0d9db.js +0 -1
  135. package/.next/static/chunks/pages/_app-79d333aa6001a806.js +0 -1
  136. package/.next/static/chunks/pages/_error-a7a0c1d9bfbb4f38.js +0 -1
  137. package/.next/static/chunks/pages/account-86a1b6e7db03bab6.js +0 -1
  138. package/.next/static/chunks/pages/checkout-c77dbc66c0b35ec3.js +0 -1
  139. package/.next/static/chunks/pages/index-4f3314ad44c30b8f.js +0 -1
  140. package/.next/static/chunks/pages/login-bbf85bc59afce37c.js +0 -1
  141. package/.next/static/chunks/pages/s-dd486933e8ba7fbf.js +0 -1
  142. package/.next/static/chunks/polyfills-c67a75d1b6f99dc8.js +0 -1
  143. package/.next/static/chunks/webpack-3eefca84f4c29194.js +0 -1
  144. package/.next/static/css/0cb9134bc2d237e2.css +0 -1
  145. package/.next/static/css/0d62ff2d64099b84.css +0 -1
  146. package/.next/static/css/0f8ce5203de8ae6f.css +0 -1
  147. package/.next/static/css/104f0f3ce3be32c6.css +0 -1
  148. package/.next/static/css/23a9d5dfc051ec6e.css +0 -1
  149. package/.next/static/css/2e00f7ba49c754b3.css +0 -1
  150. package/.next/static/css/6e41f1b6078c14c1.css +0 -1
  151. package/.next/static/css/7d822a137c54a781.css +0 -1
  152. package/.next/static/css/d4a0d9df8c6df555.css +0 -1
  153. package/.next/static/css/e02cdad8fc000339.css +0 -1
  154. package/.next/static/pDkGOqwrvVbN2os-F1GC4/_buildManifest.js +0 -1
  155. package/.next/static/pDkGOqwrvVbN2os-F1GC4/_ssgManifest.js +0 -1
  156. package/.next/trace +0 -76
  157. package/public/~partytown/debug/partytown-atomics.js +0 -556
  158. package/public/~partytown/debug/partytown-media.js +0 -374
  159. package/public/~partytown/debug/partytown-sandbox-sw.js +0 -543
  160. package/public/~partytown/debug/partytown-sw.js +0 -59
  161. package/public/~partytown/debug/partytown-ww-atomics.js +0 -1789
  162. package/public/~partytown/debug/partytown-ww-sw.js +0 -1781
  163. package/public/~partytown/debug/partytown.js +0 -72
  164. package/public/~partytown/partytown-atomics.js +0 -2
  165. package/public/~partytown/partytown-media.js +0 -2
  166. package/public/~partytown/partytown-sw.js +0 -2
  167. package/public/~partytown/partytown.js +0 -2
@@ -33,23 +33,23 @@ Route (pages) Size First Load JS
33
33
  ┌ ● / 3.21 kB 197 kB
34
34
  ├ └ css/0d62ff2d64099b84.css 6.47 kB
35
35
  ├ /_app 0 B 77.9 kB
36
- ├ ● /[...slug] 8.8 kB 134 kB
36
+ ├ ● /[...slug] 8.8 kB 135 kB
37
37
  ├ └ css/6e41f1b6078c14c1.css 7.9 kB
38
- ├ ● /[slug]/p 11 kB 204 kB
38
+ ├ ● /[slug]/p 11 kB 205 kB
39
39
  ├ └ css/0f8ce5203de8ae6f.css 11.2 kB
40
- ├ ○ /404 1.09 kB 113 kB
41
- ├ ● /500 1.11 kB 113 kB
42
- ├ ● /account 668 B 113 kB
40
+ ├ ○ /404 1.27 kB 114 kB
41
+ ├ ● /500 1.29 kB 114 kB
42
+ ├ ● /account 669 B 113 kB
43
43
  ├ λ /api/graphql 0 B 77.9 kB
44
44
  ├ λ /api/preview 0 B 77.9 kB
45
- ├ ● /checkout 657 B 113 kB
46
- ├ ● /login 1.01 kB 113 kB
47
- └ ● /s 1.11 kB 126 kB
45
+ ├ ● /checkout 656 B 113 kB
46
+ ├ ● /login 1.19 kB 114 kB
47
+ └ ● /s 1.11 kB 127 kB
48
48
  + First Load JS shared by all 80.6 kB
49
49
  ├ chunks/framework-dfd14d7ce6600b03.js 45.3 kB
50
50
  ├ chunks/main-fd466221927468fd.js 23.9 kB
51
51
  ├ chunks/pages/_app-79d333aa6001a806.js 6.38 kB
52
- ├ chunks/webpack-3eefca84f4c29194.js 2.28 kB
52
+ ├ chunks/webpack-ad7791015d101142.js 2.28 kB
53
53
  └ css/104f0f3ce3be32c6.css 2.79 kB
54
54
 
55
55
  λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
package/lighthouserc.js CHANGED
@@ -19,5 +19,6 @@ module.exports = lhConfig({
19
19
  deprecations: 'warn',
20
20
  'resource-summary:stylesheet:count': ['warn', { maxNumericValue: 400 }],
21
21
  'resource-summary:script:count': ['warn', { maxNumericValue: 20 }],
22
+ 'resource-summary:script:size': ['error', { maxNumericValue: 210 * 1024 }],
22
23
  },
23
24
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "2.1.14",
3
+ "version": "2.1.17",
4
4
  "license": "MIT",
5
5
  "browserslist": "supports es6-module and not dead",
6
6
  "scripts": {
@@ -30,10 +30,10 @@
30
30
  "@envelop/parser-cache": "^2.2.0",
31
31
  "@envelop/validation-cache": "^2.2.0",
32
32
  "@faststore/api": "^2.1.9",
33
- "@faststore/components": "^2.1.9",
33
+ "@faststore/components": "^2.1.16",
34
34
  "@faststore/graphql-utils": "^2.1.9",
35
35
  "@faststore/sdk": "^2.1.9",
36
- "@faststore/ui": "^2.1.9",
36
+ "@faststore/ui": "^2.1.16",
37
37
  "@types/react": "^18.0.14",
38
38
  "@vtex/client-cms": "^0.2.12",
39
39
  "autoprefixer": "^10.4.0",
@@ -110,5 +110,5 @@
110
110
  "msw": {
111
111
  "workerDirectory": "public"
112
112
  },
113
- "gitHead": "51ae4e321b9f68d9ec93d1b59d4b18b7d3f3e53e"
113
+ "gitHead": "fcb109880652472f2a72cebdb79f550075c23ecb"
114
114
  }
@@ -7,10 +7,16 @@ import { mark } from 'src/sdk/tests/mark'
7
7
  import Section from 'src/components/sections/Section/Section'
8
8
  import styles from './section.module.scss'
9
9
 
10
+ import { Components, Props } from 'src/components/sections/Alert/Overrides'
11
+
12
+ const { Alert: AlertWrapper } = Components
13
+
10
14
  export interface AlertProps extends UIAlertProps {
11
15
  /**
12
16
  * For CMS integration purposes, should be used to pass content through it
13
17
  * instead pass through children
18
+ *
19
+ * TODO: Remove it? It's not being used
14
20
  */
15
21
  content?: ReactNode
16
22
  }
@@ -32,9 +38,15 @@ function Alert({
32
38
 
33
39
  return (
34
40
  <Section className={`${styles.section} section-alert`}>
35
- <UIAlert onClose={onAlertClose} {...otherProps}>
41
+ <AlertWrapper
42
+ {...Props['Alert']}
43
+ // Dynamic props, shouldn't be overridable
44
+ // This decision can be reviewed later if needed
45
+ onClose={onAlertClose}
46
+ {...otherProps}
47
+ >
36
48
  {content ?? children}
37
- </UIAlert>
49
+ </AlertWrapper>
38
50
  </Section>
39
51
  )
40
52
  }
@@ -1,4 +1,4 @@
1
- import { useRef, useState } from 'react'
1
+ import { useRef, useState, useCallback } from 'react'
2
2
 
3
3
  import { useUI, useScrollDirection, Icon as UIIcon } from '@faststore/ui'
4
4
 
@@ -88,10 +88,15 @@ function Navbar({
88
88
  const searchMobileRef = useRef<SearchInputRef>(null)
89
89
  const [searchExpanded, setSearchExpanded] = useState(false)
90
90
 
91
- const handlerExpandSearch = () => {
91
+ const handlerExpandSearch = useCallback(() => {
92
92
  setSearchExpanded(true)
93
93
  searchMobileRef.current?.inputRef?.focus()
94
- }
94
+ }, [])
95
+
96
+ const handleCollapseSearch = useCallback(() => {
97
+ setSearchExpanded(false)
98
+ searchMobileRef.current?.resetSearchInput()
99
+ }, [])
95
100
 
96
101
  return (
97
102
  <NavbarWrapper scrollDirection={scrollDirection} {...Props['Navbar']}>
@@ -129,10 +134,7 @@ function Navbar({
129
134
  data-fs-button-collapse
130
135
  aria-label="Collapse search bar"
131
136
  icon={<UIIcon name="CaretLeft" width={32} height={32} />}
132
- onClick={() => {
133
- setSearchExpanded(false)
134
- searchMobileRef.current?.resetSearchInput()
135
- }}
137
+ onClick={handleCollapseSearch}
136
138
  {...Props['IconButton']}
137
139
  />
138
140
  )}
@@ -4,7 +4,7 @@ import {
4
4
  ProductCardContent as UIProductCardContent,
5
5
  ProductCardImage as UIProductCardImage,
6
6
  } from '@faststore/ui'
7
- import { memo } from 'react'
7
+ import { memo, useMemo } from 'react'
8
8
 
9
9
  import type { ProductSummary_ProductFragment } from '@generated/graphql'
10
10
  import { ImageProps } from 'next/future/image'
@@ -83,7 +83,10 @@ function ProductCard({
83
83
  prefetch: false,
84
84
  }
85
85
 
86
- const outOfStock = availability !== 'https://schema.org/InStock'
86
+ const outOfStock = useMemo(
87
+ () => availability !== 'https://schema.org/InStock',
88
+ [availability]
89
+ )
87
90
 
88
91
  return (
89
92
  <UIProductCard
@@ -1,9 +1,12 @@
1
1
  import type { RegionBarProps as UIRegionBarProps } from '@faststore/ui'
2
- import { Icon, RegionBar as UIRegionBar } from '@faststore/ui'
3
2
 
4
3
  import { useUI } from '@faststore/ui'
5
4
  import { useSession } from 'src/sdk/session'
6
5
 
6
+ import { Components, Props } from 'src/components/sections/RegionBar/Overrides'
7
+
8
+ const { RegionBar: RegionBarWrapper, LocationIcon, ButtonIcon } = Components
9
+
7
10
  export interface RegionBarProps {
8
11
  /**
9
12
  * A React component that will be rendered as an icon.
@@ -30,19 +33,32 @@ export interface RegionBarProps {
30
33
  }
31
34
 
32
35
  function RegionBar({
33
- icon: { icon: locationIcon, alt: locationIconAlt },
34
- buttonIcon: { icon: buttonIcon, alt: buttonIconAlt },
36
+ icon: {
37
+ icon: locationIcon = Props['LocationIcon'].name,
38
+ alt: locationIconAlt = Props['LocationIcon']['aria-label'],
39
+ },
40
+ buttonIcon: {
41
+ icon: buttonIcon = Props['ButtonIcon'].name,
42
+ alt: buttonIconAlt = Props['ButtonIcon']['aria-label'],
43
+ },
44
+ label = Props['RegionBar'].label,
45
+ editLabel = Props['RegionBar'].editLabel,
35
46
  ...otherProps
36
47
  }: RegionBarProps) {
37
48
  const { openModal } = useUI()
38
49
  const { postalCode } = useSession()
39
50
 
40
51
  return (
41
- <UIRegionBar
52
+ <RegionBarWrapper
53
+ icon={<LocationIcon name={locationIcon} aria-label={locationIconAlt} />}
54
+ buttonIcon={<ButtonIcon name={buttonIcon} aria-label={buttonIconAlt} />}
55
+ {...Props['RegionBar']}
56
+ label={label}
57
+ editLabel={editLabel}
58
+ // Dynamic props shouldn't be overridable
59
+ // This decision can be reviewed later if needed
42
60
  onButtonClick={openModal}
43
61
  postalCode={postalCode}
44
- icon={<Icon name={locationIcon} aria-label={locationIconAlt} />}
45
- buttonIcon={<Icon name={buttonIcon} aria-label={buttonIconAlt} />}
46
62
  {...otherProps}
47
63
  />
48
64
  )
@@ -1,5 +1,8 @@
1
- import { Icon as UIIcon } from '@faststore/ui'
2
- import UIAlert from 'src/components/common/Alert'
1
+ import CommonAlert from 'src/components/common/Alert'
2
+
3
+ import { Components, Props } from 'src/components/sections/Alert/Overrides'
4
+
5
+ const { Icon } = Components
3
6
 
4
7
  export interface AlertProps {
5
8
  icon: string
@@ -12,15 +15,28 @@ export interface AlertProps {
12
15
  }
13
16
 
14
17
  // TODO: Change actionPath and actionLabel with Link
15
- function Alert({ icon, content, link, dismissible }: AlertProps) {
18
+ function Alert({
19
+ icon = Props['Icon'].name,
20
+ content,
21
+ link: {
22
+ text = Props['Alert'].link?.text,
23
+ to = Props['Alert'].link?.to,
24
+ } = Props['Alert'].link,
25
+ dismissible = Props['Alert'].dismissible,
26
+ }: AlertProps) {
16
27
  return (
17
- <UIAlert
18
- icon={<UIIcon name={icon} />}
19
- link={{ children: link?.text, href: link?.to, target: '_self' }}
28
+ <CommonAlert
29
+ icon={<Icon {...Props['Icon']} name={icon} />}
30
+ link={{
31
+ ...(Props['Alert'].link ?? {}),
32
+ children: text,
33
+ href: to,
34
+ target: Props['Alert'].link?.target ?? '_self',
35
+ }}
20
36
  dismissible={dismissible}
21
37
  >
22
38
  {content}
23
- </UIAlert>
39
+ </CommonAlert>
24
40
  )
25
41
  }
26
42
 
@@ -0,0 +1,27 @@
1
+ import { Alert as UIAlert, Icon as UIIcon } from '@faststore/ui'
2
+
3
+ import AlertCustomizations from 'src/customizations/components/overrides/Alert'
4
+
5
+ const alertComponentsCustomization = {}
6
+
7
+ const alertPropsCustomization = {} as any
8
+
9
+ Object.entries(AlertCustomizations.components).forEach(([key, value]) => {
10
+ if (value.Component) {
11
+ alertComponentsCustomization[key] = value.Component
12
+ }
13
+ })
14
+
15
+ Object.entries(AlertCustomizations.components).forEach(([key, value]) => {
16
+ if (value.props) {
17
+ alertPropsCustomization[key] = value.props
18
+ }
19
+ })
20
+
21
+ const Components = {
22
+ Alert: UIAlert,
23
+ Icon: UIIcon,
24
+ ...alertComponentsCustomization,
25
+ }
26
+
27
+ export { Components, alertPropsCustomization as Props }
@@ -4,7 +4,9 @@ import type { PropsWithChildren } from 'react'
4
4
  import Section from '../Section'
5
5
  import styles from './section.module.scss'
6
6
 
7
- import { EmptyState as UIEmptyState } from '@faststore/ui'
7
+ import { Components, Props } from 'src/components/sections/EmptyState/Overrides'
8
+
9
+ const { EmptyState: EmptyStateWrapper } = Components
8
10
 
9
11
  export interface EmptyStateProps {
10
12
  title: string
@@ -12,15 +14,20 @@ export interface EmptyStateProps {
12
14
  }
13
15
 
14
16
  function EmptyState({
15
- title,
16
- titleIcon,
17
+ title = Props['EmptyState'].title,
18
+ titleIcon = Props['EmptyState'].titleIcon,
17
19
  children,
18
20
  }: PropsWithChildren<EmptyStateProps>) {
19
21
  return (
20
22
  <Section className={`${styles.section} section-empty-state`}>
21
- <UIEmptyState title={title} titleIcon={titleIcon} bkgColor="light">
23
+ <EmptyStateWrapper
24
+ bkgColor="light"
25
+ {...Props['EmptyState']}
26
+ title={title}
27
+ titleIcon={titleIcon}
28
+ >
22
29
  {children}
23
- </UIEmptyState>
30
+ </EmptyStateWrapper>
24
31
  </Section>
25
32
  )
26
33
  }
@@ -0,0 +1,26 @@
1
+ import { EmptyState as UIEmptyState } from '@faststore/ui'
2
+
3
+ import EmptyStateCustomizations from 'src/customizations/components/overrides/EmptyState'
4
+
5
+ const emptyStateComponentsCustomization = {}
6
+
7
+ const emptyStatePropsCustomization = {} as any
8
+
9
+ Object.entries(EmptyStateCustomizations.components).forEach(([key, value]) => {
10
+ if (value.Component) {
11
+ emptyStateComponentsCustomization[key] = value.Component
12
+ }
13
+ })
14
+
15
+ Object.entries(EmptyStateCustomizations.components).forEach(([key, value]) => {
16
+ if (value.props) {
17
+ emptyStatePropsCustomization[key] = value.props
18
+ }
19
+ })
20
+
21
+ const Components = {
22
+ EmptyState: UIEmptyState,
23
+ ...emptyStateComponentsCustomization,
24
+ }
25
+
26
+ export { Components, emptyStatePropsCustomization as Props }
@@ -0,0 +1,35 @@
1
+ import {
2
+ Button as UIButton,
3
+ InputField as UIInputField,
4
+ Icon as UIIcon,
5
+ } from '@faststore/ui'
6
+
7
+ import NewsletterCustomizations from 'src/customizations/components/overrides/Newsletter'
8
+
9
+ const newsletterComponentsCustomization = {}
10
+
11
+ const newsletterPropsCustomization = {} as any
12
+
13
+ Object.entries(NewsletterCustomizations.components).forEach(([key, value]) => {
14
+ if (value.Component) {
15
+ newsletterComponentsCustomization[key] = value.Component
16
+ }
17
+ })
18
+
19
+ Object.entries(NewsletterCustomizations.components).forEach(([key, value]) => {
20
+ if (value.props) {
21
+ newsletterPropsCustomization[key] = value.props
22
+ }
23
+ })
24
+
25
+ const Components = {
26
+ ToastIconSuccess: UIIcon,
27
+ ToastIconError: UIIcon,
28
+ HeaderIcon: UIIcon,
29
+ InputFieldName: UIInputField,
30
+ InputFieldEmail: UIInputField,
31
+ Button: UIButton,
32
+ ...newsletterComponentsCustomization,
33
+ }
34
+
35
+ export { Components, newsletterPropsCustomization as Props }
@@ -0,0 +1,28 @@
1
+ import { RegionBar as UIRegionBar, Icon as UIIcon } from '@faststore/ui'
2
+
3
+ import RegionBarCustomizations from 'src/customizations/components/overrides/RegionBar'
4
+
5
+ const regionBarComponentsCustomization = {}
6
+
7
+ const regionBarPropsCustomization = {} as any
8
+
9
+ Object.entries(RegionBarCustomizations.components).forEach(([key, value]) => {
10
+ if (value.Component) {
11
+ regionBarComponentsCustomization[key] = value.Component
12
+ }
13
+ })
14
+
15
+ Object.entries(RegionBarCustomizations.components).forEach(([key, value]) => {
16
+ if (value.props) {
17
+ regionBarPropsCustomization[key] = value.props
18
+ }
19
+ })
20
+
21
+ const Components = {
22
+ RegionBar: UIRegionBar,
23
+ LocationIcon: UIIcon,
24
+ ButtonIcon: UIIcon,
25
+ ...regionBarComponentsCustomization,
26
+ }
27
+
28
+ export { Components, regionBarPropsCustomization as Props }
@@ -1,21 +1,34 @@
1
- import { Button as UIButton, InputField as UIInputField } from '@faststore/ui'
2
- import { ComponentPropsWithRef, FormEvent } from 'react'
1
+ import { ComponentPropsWithRef, FormEvent, useMemo } from 'react'
3
2
  import { forwardRef, useRef } from 'react'
4
3
  import { convertFromRaw } from 'draft-js'
5
4
  import { stateToHTML } from 'draft-js-export-html'
6
- import { Icon, useUI } from '@faststore/ui'
5
+ import { useUI } from '@faststore/ui'
7
6
  import { useNewsletter } from 'src/sdk/newsletter/useNewsletter'
8
7
 
8
+ import { Components, Props } from 'src/components/sections/Newsletter/Overrides'
9
+
10
+ const {
11
+ ToastIconSuccess,
12
+ ToastIconError,
13
+ HeaderIcon,
14
+ InputFieldEmail,
15
+ InputFieldName,
16
+ Button,
17
+ } = Components
18
+
9
19
  const cmsToHtml = (content) => {
10
20
  if (!content) {
11
21
  return ''
12
22
  }
23
+
13
24
  const rawDraftContentState = JSON.parse(content)
14
25
  const html = stateToHTML(convertFromRaw(rawDraftContentState), {
15
26
  entityStyleFn: (entity) => {
16
27
  const entityType = entity.get('type').toLowerCase()
28
+
17
29
  if (entityType === 'link') {
18
30
  const data = entity.getData()
31
+
19
32
  return {
20
33
  element: 'a',
21
34
  attributes: {
@@ -106,13 +119,16 @@ const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
106
119
  card,
107
120
  toastSubscribe,
108
121
  toastSubscribeError,
109
- ...otherProps
110
122
  },
111
123
  ref
112
124
  ) {
113
125
  const { subscribeUser, loading, data } = useNewsletter()
114
126
  const nameInputRef = useRef<HTMLInputElement>(null)
115
127
  const emailInputRef = useRef<HTMLInputElement>(null)
128
+ const subscriptionButtonLabel = useMemo(
129
+ () => (loading ? subscribeButtonLoadingLabel : subscribeButtonLabel),
130
+ [loading, subscribeButtonLabel, subscribeButtonLoadingLabel]
131
+ )
116
132
 
117
133
  const { pushToast } = useUI()
118
134
 
@@ -129,13 +145,27 @@ const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
129
145
  pushToast({
130
146
  ...toastSubscribe,
131
147
  status: 'INFO',
132
- icon: <Icon name={toastSubscribe.icon} width={30} height={30} />,
148
+ icon: (
149
+ <ToastIconSuccess
150
+ width={30}
151
+ height={30}
152
+ {...Props['ToastIconSuccess']}
153
+ name={toastSubscribe.icon ?? Props['ToastIconSuccess'].name}
154
+ />
155
+ ),
133
156
  })
134
157
  } else {
135
158
  pushToast({
136
159
  ...toastSubscribeError,
137
160
  status: 'ERROR',
138
- icon: <Icon name={toastSubscribeError.icon} width={30} height={30} />,
161
+ icon: (
162
+ <ToastIconError
163
+ width={30}
164
+ height={30}
165
+ {...Props['ToastIconError']}
166
+ name={toastSubscribe.icon ?? Props['ToastIconError'].name}
167
+ />
168
+ ),
139
169
  })
140
170
  }
141
171
 
@@ -147,15 +177,19 @@ const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
147
177
  return (
148
178
  <div data-fs-newsletter={card ? 'card' : ''}>
149
179
  <form
150
- data-fs-newsletter-form
151
180
  ref={ref}
181
+ data-fs-newsletter-form
152
182
  onSubmit={handleSubmit}
153
- {...otherProps}
154
183
  className="layout__content"
155
184
  >
156
185
  <header data-fs-newsletter-header>
157
186
  <h3>
158
- <Icon name={icon?.icon} width={32} height={32} />
187
+ <HeaderIcon
188
+ width={32}
189
+ height={32}
190
+ {...Props['HeaderIcon']}
191
+ name={icon?.icon ?? Props['HeaderIcon'].name}
192
+ />
159
193
  {title}
160
194
  </h3>
161
195
  {description && <span> {description}</span>}
@@ -164,19 +198,25 @@ const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
164
198
  <div data-fs-newsletter-controls>
165
199
  <>
166
200
  {displayNameInput ? (
167
- <UIInputField
168
- inputRef={nameInputRef}
201
+ <InputFieldName
169
202
  id="newsletter-name"
170
- label={nameInputLabel}
171
203
  required
204
+ {...Props['InputFieldName']}
205
+ label={nameInputLabel ?? Props['InputFieldName'].label}
206
+ // Dynamic props shouldn't be overridable
207
+ // This decision can be reviewed later if needed
208
+ inputRef={nameInputRef}
172
209
  />
173
210
  ) : null}
174
- <UIInputField
175
- inputRef={emailInputRef}
211
+ <InputFieldEmail
176
212
  id="newsletter-email"
177
- label={emailInputLabel}
178
213
  type="email"
179
214
  required
215
+ {...Props['InputFieldEmail']}
216
+ label={emailInputLabel ?? Props['InputFieldEmail'].label}
217
+ // Dynamic props shouldn't be overridable
218
+ // This decision can be reviewed later if needed
219
+ inputRef={emailInputRef}
180
220
  />
181
221
  <span
182
222
  data-fs-newsletter-addendum
@@ -184,9 +224,14 @@ const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
184
224
  __html: cmsToHtml(privacyPolicy),
185
225
  }}
186
226
  ></span>
187
- <UIButton variant="secondary" inverse type="submit">
227
+ <Button
228
+ variant="secondary"
229
+ inverse
230
+ type="submit"
231
+ {...Props['Button']}
232
+ >
188
233
  {loading ? subscribeButtonLoadingLabel : subscribeButtonLabel}
189
- </UIButton>
234
+ </Button>
190
235
  </>
191
236
  </div>
192
237
  </form>
@@ -0,0 +1,15 @@
1
+ // This is an example of how it can be used on the starter.
2
+
3
+ import { SectionOverride } from 'src/typings/overrides'
4
+
5
+ const SECTION = 'Alert' as const
6
+
7
+ const overrides: SectionOverride[typeof SECTION] = {
8
+ name: SECTION,
9
+ components: {
10
+ Alert: { props: {} },
11
+ Icon: { props: {} },
12
+ },
13
+ }
14
+
15
+ export default overrides
@@ -0,0 +1,13 @@
1
+ // This is an example of how it can be used on the starter.
2
+ import { SectionOverride } from 'src/typings/overrides'
3
+
4
+ const SECTION = 'EmptyState' as const
5
+
6
+ const overrides: SectionOverride[typeof SECTION] = {
7
+ name: SECTION,
8
+ components: {
9
+ EmptyState: { props: {} },
10
+ },
11
+ }
12
+
13
+ export default overrides
@@ -0,0 +1,19 @@
1
+ // This is an example of how it can be used on the starter.
2
+
3
+ import { SectionOverride } from 'src/typings/overrides'
4
+
5
+ const SECTION = 'Newsletter' as const
6
+
7
+ const overrides: SectionOverride[typeof SECTION] = {
8
+ name: SECTION,
9
+ components: {
10
+ ToastIconSuccess: { props: {} },
11
+ ToastIconError: { props: {} },
12
+ HeaderIcon: { props: {} },
13
+ InputFieldName: { props: {} },
14
+ InputFieldEmail: { props: {} },
15
+ Button: { props: {} },
16
+ },
17
+ }
18
+
19
+ export default overrides
@@ -0,0 +1,16 @@
1
+ // This is an example of how it can be used on the starter.
2
+
3
+ import { SectionOverride } from 'src/typings/overrides'
4
+
5
+ const SECTION = 'RegionBar' as const
6
+
7
+ const overrides: SectionOverride[typeof SECTION] = {
8
+ name: SECTION,
9
+ components: {
10
+ RegionBar: { props: {} },
11
+ LocationIcon: { props: {} },
12
+ ButtonIcon: { props: {} },
13
+ },
14
+ }
15
+
16
+ export default overrides
@@ -62,6 +62,25 @@ export const SECTIONS = {
62
62
  '__experimentalProductCard',
63
63
  ],
64
64
  },
65
+ Alert: {
66
+ components: ['Alert', 'Icon'],
67
+ },
68
+ EmptyState: {
69
+ components: ['EmptyState'],
70
+ },
71
+ RegionBar: {
72
+ components: ['RegionBar', 'LocationIcon', 'ButtonIcon'],
73
+ },
74
+ Newsletter: {
75
+ components: [
76
+ 'ToastIconSuccess',
77
+ 'ToastIconError',
78
+ 'HeaderIcon',
79
+ 'InputFieldName',
80
+ 'InputFieldEmail',
81
+ 'Button',
82
+ ],
83
+ },
65
84
  } as const
66
85
 
67
86
  // export type ComponentOrProps =
package/.next/BUILD_ID DELETED
@@ -1 +0,0 @@
1
- pDkGOqwrvVbN2os-F1GC4