@faststore/core 0.2.1 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog),
6
6
  and this project adheres to [Calendar Versioning](https://calver.org/).
7
7
 
8
+ ## [0.3.0](https://github.com/vtex-sites/nextjs.store/compare/0.2.2...0.3.0) (2022-11-07)
9
+
10
+
11
+ ### Features
12
+
13
+ * Adds `Carousel` component ([#273](https://github.com/vtex-sites/nextjs.store/issues/273)) ([cbc0107](https://github.com/vtex-sites/nextjs.store/commit/cbc0107d5ef7b435c7a9e52756d0edc8cae03fe1))
14
+
15
+ ### [0.2.2](https://github.com/vtex-sites/nextjs.store/compare/0.2.1...0.2.2) (2022-10-28)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * Setting postal code a 2nd time doesn't work ([#291](https://github.com/vtex-sites/nextjs.store/issues/291)) ([bc7e834](https://github.com/vtex-sites/nextjs.store/commit/bc7e8344305dc3f9a00a58da6913e6694630aba1))
21
+
8
22
  ### [0.2.1](https://github.com/vtex-sites/nextjs.store/compare/0.2.0...0.2.1) (2022-10-28)
9
23
 
10
24
 
package/README.md CHANGED
@@ -434,4 +434,4 @@ export const onRenderBody = ({ setHeadComponents }) => {
434
434
  }
435
435
  ```
436
436
 
437
- For more information about integrating third-party scripts: [Partytown Wiki](https://github.com/BuilderIO/partytown/wiki)
437
+ For more information about integrating third-party scripts: [Partytown Wiki](https://github.com/BuilderIO/partytown/wiki).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "browserslist": "supports es6-module and not dead",
6
6
  "scripts": {
@@ -33,7 +33,7 @@
33
33
  "@faststore/api": "^1.12.17",
34
34
  "@faststore/graphql-utils": "^1.11.8",
35
35
  "@faststore/sdk": "^1.11.8",
36
- "@faststore/ui": "^1.12.13",
36
+ "@faststore/ui": "^1.12.23",
37
37
  "@vtex/client-cms": "^0.2.12",
38
38
  "graphql": "^15.0.0",
39
39
  "include-media": "^1.4.10",
@@ -14,24 +14,24 @@ function RegionInput({ closeModal }: Props) {
14
14
  const [input, setInput] = useState<string>('')
15
15
 
16
16
  const handleSubmit = async () => {
17
- const value = inputRef.current?.value
17
+ const postalCode = inputRef.current?.value
18
18
 
19
- if (typeof value !== 'string') {
19
+ if (typeof postalCode !== 'string') {
20
20
  return
21
21
  }
22
22
 
23
23
  setErrorMessage('')
24
24
 
25
25
  try {
26
- const newSession = await validateSession({
26
+ const newSession = {
27
27
  ...session,
28
- postalCode: value,
29
- })
30
-
31
- if (newSession) {
32
- sessionStore.set(newSession)
28
+ postalCode,
33
29
  }
34
30
 
31
+ const validatedSession = await validateSession(newSession)
32
+
33
+ sessionStore.set(validatedSession ?? newSession)
34
+
35
35
  closeModal()
36
36
  } catch (error) {
37
37
  setErrorMessage('You entered an invalid Postal Code')
@@ -0,0 +1,201 @@
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs'
2
+ import {
3
+ TokenTable,
4
+ TokenRow,
5
+ TokenDivider,
6
+ BestPractices,
7
+ BestPracticesRule,
8
+ } from 'src/../.storybook/components'
9
+
10
+ import Carousel from '.'
11
+ import ProductCard from 'src/components/product/ProductCard'
12
+
13
+ <Meta
14
+ component={Carousel}
15
+ title="Molecules/Carousel"
16
+ argTypes={{
17
+ itemsPerPage: {
18
+ control: 'number',
19
+ table: { type: 'number' },
20
+ },
21
+ }}
22
+ />
23
+
24
+ export const product = {
25
+ id: '15503951',
26
+ slug: 'handmade-steel-towels-practical-15503951',
27
+ sku: '15503951',
28
+ brand: { brandName: 'Brand', name: 'Brand' },
29
+ name: 'red',
30
+ gtin: '5595633577807',
31
+ isVariantOf: {
32
+ productGroupID: '130742',
33
+ name: 'Handmade Steel Towels Practical',
34
+ },
35
+ image: [
36
+ {
37
+ url: 'http://storeframework.vtexassets.com/arquivos/ids/190191/numquam.jpg?v=637755599170100000',
38
+ alternateName: 'est',
39
+ },
40
+ ],
41
+ offers: {
42
+ lowPrice: 181.71,
43
+ offers: [
44
+ {
45
+ availability: 'https://schema.org/InStock',
46
+ price: 181.71,
47
+ listPrice: 208.72,
48
+ quantity: 1,
49
+ seller: { identifier: '1' },
50
+ },
51
+ ],
52
+ },
53
+ }
54
+
55
+ export const Template = ({ ...args }) => (
56
+ <Carousel {...args}>
57
+ {Array.from({ length: 8 }, (_, index) => (
58
+ <ProductCard
59
+ index={index}
60
+ key={String(index)}
61
+ product={{ ...product, isVariantOf: { name: `Product ${index + 1}` } }}
62
+ />
63
+ ))}
64
+ </Carousel>
65
+ )
66
+
67
+ <header>
68
+
69
+ # Carousel
70
+
71
+ The `Carousel` component is great for swiping images.
72
+
73
+ </header>
74
+
75
+ ## Overview
76
+
77
+ The `Carousel` component uses [FastStore UI Carousel](https://www.faststore.dev/reference/ui/molecules/Carousel) as base.
78
+
79
+ ---
80
+
81
+ ## Usage
82
+
83
+ `import Carousel from 'src/components/ui/Carousel'`
84
+
85
+ <Canvas>
86
+ <Story name="usage" args={{ itemsPerPage: 5 }}>
87
+ {Template.bind({})}
88
+ </Story>
89
+ </Canvas>
90
+
91
+ <ArgsTable story="usage" />
92
+
93
+ ---
94
+
95
+ ## Nested Elements
96
+
97
+ ### Track
98
+
99
+ <TokenTable>
100
+ <TokenRow
101
+ token="--fs-carousel-padding-desktop"
102
+ value="var(--fs-spacing-0) 6.25rem"
103
+ />
104
+ </TokenTable>
105
+
106
+ ### Item
107
+
108
+ <TokenTable>
109
+ <TokenRow token="--fs-carousel-item-width-mobile" value="80%" />
110
+ <TokenRow token="--fs-carousel-item-width-desktop" value="15rem" />
111
+ <TokenRow
112
+ token="--fs-carousel-item-margin-right"
113
+ value="var(--fs-spacing-0)"
114
+ />
115
+ </TokenTable>
116
+
117
+ ### Controls
118
+
119
+ <TokenTable>
120
+ <TokenRow token="--fs-carousel-controls-width" value="3.125rem" />
121
+ <TokenRow
122
+ token="--fs-carousel-controls-height"
123
+ value="var(--fs-carousel-controls-width)"
124
+ />
125
+ <TokenRow
126
+ token="--fs-carousel-controls-position-top"
127
+ value="calc((100% - var(--fs-spacing-7) - var(--fs-spacing-1)) / 2)"
128
+ />
129
+ <TokenRow
130
+ token="--fs-carousel-controls-bkg-color"
131
+ value="var(--fs-color-neutral-0)"
132
+ isColor
133
+ />
134
+ <TokenRow
135
+ token="--fs-carousel-controls-border-radius"
136
+ value="var(--fs-border-radius-circle)"
137
+ />
138
+ <TokenRow
139
+ token="--fs-carousel-controls-box-shadow"
140
+ value="var(--fs-shadow-darker)"
141
+ />
142
+ <TokenDivider />
143
+ <TokenRow
144
+ token="--fs-carousel-controls-control-left"
145
+ value="var(--fs-spacing-5)"
146
+ />
147
+ <TokenRow
148
+ token="--fs-carousel-controls-control-right"
149
+ value="var(--fs-carousel-controls-control-left)"
150
+ />
151
+ </TokenTable>
152
+
153
+ ### Bullets
154
+
155
+ <TokenTable>
156
+ <TokenRow
157
+ token="--fs-carousel-bullets-padding-top"
158
+ value="var(--fs-carousel-controls-control-left)"
159
+ />
160
+ <TokenDivider />
161
+ <TokenRow token="--fs-carousel-bullet-width-mobile" value="100%" />
162
+ <TokenRow
163
+ token="--fs-carousel-bullet-width-desktop"
164
+ value="var(--fs-spacing-1)"
165
+ />
166
+ <TokenRow
167
+ token="--fs-carousel-bullet-height-mobile"
168
+ value="var(--fs-carousel-item-margin-right)"
169
+ />
170
+ <TokenRow
171
+ token="--fs-carousel-bullet-height-desktop"
172
+ value="var(--fs-carousel-bullet-width-desktop)"
173
+ />
174
+ <TokenRow
175
+ token="--fs-carousel-bullet-margin-right"
176
+ value="var(--fs-carousel-item-margin-right)"
177
+ />
178
+ <TokenRow
179
+ token="--fs-carousel-bullet-bkg-color"
180
+ value="var(--fs-color-neutral-3)"
181
+ isColor
182
+ />
183
+ <TokenRow
184
+ token="--fs-carousel-bullet-bkg-color-selected"
185
+ value="var(--fs-color-main-4)"
186
+ isColor
187
+ />
188
+ <TokenRow
189
+ token="--fs-carousel-bullet-border-radius"
190
+ value="var(--fs-carousel-controls-border-radius)"
191
+ />
192
+ </TokenTable>
193
+
194
+ ---
195
+
196
+ <BestPractices>
197
+ <BestPracticesRule
198
+ recommendedDescription="Always use more than 1 item per page so then the component keeps the proposed navigation behavior for both versions (mobile and desktop)."
199
+ discouragedDescription="Avoid using more items per page than the total number of items."
200
+ />
201
+ </BestPractices>
@@ -0,0 +1,41 @@
1
+ import type { PropsWithChildren } from 'react'
2
+ import { Carousel as UICarousel } from '@faststore/ui'
3
+ import type { CarouselProps as UICarouselProps } from '@faststore/ui'
4
+
5
+ import Icon from 'src/components/ui/Icon'
6
+
7
+ import styles from './carousel.module.scss'
8
+
9
+ export type CarouselProps = {
10
+ id?: string
11
+ testId?: string
12
+ itemsPerPage?: number
13
+ } & Pick<UICarouselProps, 'id' | 'testId' | 'itemsPerPage'>
14
+
15
+ function Carousel({
16
+ id,
17
+ testId,
18
+ children,
19
+ itemsPerPage = 5,
20
+ }: PropsWithChildren<CarouselProps>) {
21
+ const isMobile = window.innerWidth <= 768
22
+
23
+ return (
24
+ <UICarousel
25
+ id={id}
26
+ testId={testId}
27
+ variant="scroll"
28
+ infiniteMode={false}
29
+ className={styles.fsCarousel}
30
+ itemsPerPage={isMobile ? 1 : itemsPerPage}
31
+ navigationIcons={{
32
+ left: <Icon width={20} height={20} weight="bold" name="ArrowLeft" />,
33
+ right: <Icon width={20} height={20} weight="bold" name="ArrowRight" />,
34
+ }}
35
+ >
36
+ {children}
37
+ </UICarousel>
38
+ )
39
+ }
40
+
41
+ export default Carousel
@@ -0,0 +1,147 @@
1
+ @import "src/styles/scaffold";
2
+
3
+ .fs-carousel {
4
+ // --------------------------------------------------------
5
+ // Design Tokens for Carousel
6
+ // --------------------------------------------------------
7
+
8
+ // Track
9
+ --fs-carousel-padding-desktop : var(--fs-spacing-0) 6.25rem;
10
+
11
+ // Item
12
+ --fs-carousel-item-width-mobile : 80%;
13
+ --fs-carousel-item-width-desktop : 15rem;
14
+ --fs-carousel-item-margin-right : var(--fs-spacing-0);
15
+
16
+ // Controls
17
+ --fs-carousel-controls-width : 3.125rem;
18
+ --fs-carousel-controls-height : var(--fs-carousel-controls-width);
19
+ --fs-carousel-controls-position-top : calc((100% - var(--fs-spacing-7) - var(--fs-spacing-1)) / 2);
20
+ --fs-carousel-controls-bkg-color : var(--fs-color-neutral-0);
21
+ --fs-carousel-controls-border-radius : var(--fs-border-radius-circle);
22
+ --fs-carousel-controls-box-shadow : var(--fs-shadow-darker);
23
+ --fs-carousel-controls-icon-color : var(--fs-color-neutral-7);
24
+
25
+ --fs-carousel-controls-control-left : var(--fs-spacing-5);
26
+ --fs-carousel-controls-control-right : var(--fs-carousel-controls-control-left);
27
+
28
+ // Bullets
29
+ --fs-carousel-bullets-padding-top : var(--fs-carousel-controls-control-left);
30
+
31
+ --fs-carousel-bullet-width-mobile : 100%;
32
+ --fs-carousel-bullet-width-desktop : var(--fs-spacing-1);
33
+ --fs-carousel-bullet-height-mobile : var(--fs-carousel-item-margin-right);
34
+ --fs-carousel-bullet-height-desktop : var(--fs-carousel-bullet-width-desktop);
35
+ --fs-carousel-bullet-margin-right : var(--fs-carousel-item-margin-right);
36
+ --fs-carousel-bullet-bkg-color : var(--fs-color-neutral-3);
37
+ --fs-carousel-bullet-bkg-color-selected : var(--fs-color-main-4);
38
+ --fs-carousel-bullet-border-radius : var(--fs-carousel-controls-border-radius);
39
+
40
+ // --------------------------------------------------------
41
+ // Structural Styles
42
+ // --------------------------------------------------------
43
+
44
+ &:hover {
45
+ [data-fs-carousel-controls] {
46
+ @include media(">=tablet") {
47
+ display: flex;
48
+ width: 100%;
49
+
50
+ [data-fs-carousel-control] {
51
+ top: var(--fs-carousel-controls-position-top);
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ width: var(--fs-carousel-controls-width);
56
+ height: var(--fs-carousel-controls-height);
57
+ cursor: pointer;
58
+ background-color: var(--fs-carousel-controls-bkg-color);
59
+ border-color: transparent;
60
+ border-radius: var(--fs-carousel-controls-border-radius);
61
+ box-shadow: var(--fs-carousel-controls-box-shadow);
62
+ transform: translateY(-50%);
63
+ }
64
+
65
+ [data-fs-carousel-control="left"] {
66
+ position: absolute;
67
+ left: var(--fs-carousel-controls-control-left);
68
+ }
69
+
70
+ [data-fs-carousel-control="right"] {
71
+ position: absolute;
72
+ right: var(--fs-carousel-controls-control-right);
73
+ }
74
+
75
+ [data-fs-icon] { display: flex; }
76
+ }
77
+ }
78
+ }
79
+
80
+ [data-fs-carousel-track] {
81
+ &::-webkit-scrollbar {
82
+ display: none;
83
+ }
84
+
85
+ @include media(">=tablet") {
86
+ padding: var(--fs-carousel-padding-desktop);
87
+ }
88
+ }
89
+
90
+ [data-fs-carousel-item] {
91
+ width: var(--fs-carousel-item-width-mobile);
92
+
93
+ @include media(">=tablet") {
94
+ width: var(--fs-carousel-item-width-desktop);
95
+ height: 100%;
96
+ margin-right: var(--fs-carousel-item-margin-right);
97
+ }
98
+ }
99
+
100
+ [data-fs-icon] {
101
+ color: var(--fs-carousel-controls-icon-color);
102
+ }
103
+
104
+ [data-fs-carousel-controls] {
105
+ display: none;
106
+ }
107
+
108
+ [data-fs-carousel-bullets] {
109
+ width: 100%;
110
+ padding-top: var(--fs-carousel-bullets-padding-top);
111
+
112
+ @include media(">=tablet") {
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: center;
116
+ }
117
+
118
+ [data-fs-bullets] {
119
+ display: flex;
120
+ flex-flow: row nowrap;
121
+
122
+ @include media(">=tablet") {
123
+ column-gap: var(--fs-spacing-3);
124
+ }
125
+
126
+ [data-fs-bullet] {
127
+ width: var(--fs-carousel-bullet-width-mobile);
128
+ height: var(--fs-carousel-bullet-height-mobile);
129
+ padding: 0;
130
+ margin-right: var(--fs-carousel-bullet-margin-right);
131
+ background-color: var(--fs-carousel-bullet-bkg-color);
132
+ border-color: transparent;
133
+
134
+ &[aria-selected="true"] {
135
+ background-color: var(--fs-carousel-bullet-bkg-color-selected);
136
+ }
137
+
138
+ @include media(">=tablet") {
139
+ width: var(--fs-carousel-bullet-width-desktop);
140
+ height: var(--fs-carousel-bullet-height-desktop);
141
+ margin: 0;
142
+ border-radius: var(--fs-carousel-bullet-border-radius);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './Carousel'
2
+ export type { CarouselProps } from './Carousel'