@faststore/core 0.2.2 → 0.3.1

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.1](https://github.com/vtex-sites/nextjs.store/compare/0.3.0...0.3.1) (2022-11-08)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * include necessary build dependencies with package ([#297](https://github.com/vtex-sites/nextjs.store/issues/297)) ([c7b2345](https://github.com/vtex-sites/nextjs.store/commit/c7b2345645a89c3edd74296a0fa06ade3653ff6d))
14
+
15
+ ## [0.3.0](https://github.com/vtex-sites/nextjs.store/compare/0.2.2...0.3.0) (2022-11-07)
16
+
17
+
18
+ ### Features
19
+
20
+ * Adds `Carousel` component ([#273](https://github.com/vtex-sites/nextjs.store/issues/273)) ([cbc0107](https://github.com/vtex-sites/nextjs.store/commit/cbc0107d5ef7b435c7a9e52756d0edc8cae03fe1))
21
+
8
22
  ### [0.2.2](https://github.com/vtex-sites/nextjs.store/compare/0.2.1...0.2.2) (2022-10-28)
9
23
 
10
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
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",
@@ -44,7 +44,20 @@
44
44
  "react-dom": "^18.2.0",
45
45
  "react-intersection-observer": "^8.32.5",
46
46
  "sass": "^1.44.0",
47
- "swr": "^1.3.0"
47
+ "swr": "^1.3.0",
48
+ "@types/react": "^18.0.14",
49
+ "@vtex/tsconfig": "0.6.0",
50
+ "autoprefixer": "^10.4.0",
51
+ "css-loader": "^6.7.1",
52
+ "eslint": "^7.22.0",
53
+ "eslint-config-next": "12.1.5",
54
+ "eslint-config-vtex-react": "^9.0.0",
55
+ "msw": "^0.43.1",
56
+ "postcss": "^8.4.4",
57
+ "sass-loader": "^12.6.0",
58
+ "style-loader": "^3.3.1",
59
+ "tsconfig-paths-webpack-plugin": "^3.5.2",
60
+ "typescript": "^4.7.3"
48
61
  },
49
62
  "devDependencies": {
50
63
  "@cypress/code-coverage": "^3.9.10",
@@ -63,37 +76,24 @@
63
76
  "@storybook/react": "^6.5.9",
64
77
  "@testing-library/cypress": "^8.0.0",
65
78
  "@types/cypress": "^1.1.3",
66
- "@types/react": "^18.0.14",
67
79
  "@vtex/prettier-config": "1.0.0",
68
- "@vtex/tsconfig": "0.6.0",
69
- "autoprefixer": "^10.4.0",
70
80
  "axe-core": "^4.3.3",
71
- "css-loader": "^6.7.1",
72
81
  "cypress": "9.6.0",
73
82
  "cypress-axe": "^0.13.0",
74
83
  "cypress-wait-until": "^1.7.2",
75
84
  "dotenv": "^8.2.0",
76
- "eslint": "^7.22.0",
77
- "eslint-config-next": "12.1.5",
78
- "eslint-config-vtex-react": "^9.0.0",
79
85
  "husky": "^5.2.0",
80
86
  "is-ci": "^3.0.0",
81
87
  "lint-staged": "^10.5.4",
82
- "msw": "^0.43.1",
83
88
  "msw-storybook-addon": "^1.6.3",
84
- "postcss": "^8.4.4",
85
89
  "prettier": "^2.2.0",
86
90
  "release-it": "^15.2.0",
87
- "sass-loader": "^12.6.0",
88
- "style-loader": "^3.3.1",
89
91
  "stylelint": "^14.6.0",
90
92
  "stylelint-config-recess-order": "^3.0.0",
91
93
  "stylelint-config-standard": "^24.0.0",
92
94
  "stylelint-config-standard-scss": "^3.0.0",
93
95
  "stylelint-order": "^5.0.0",
94
- "stylelint-scss": "^4.0.1",
95
- "tsconfig-paths-webpack-plugin": "^3.5.2",
96
- "typescript": "^4.7.3"
96
+ "stylelint-scss": "^4.0.1"
97
97
  },
98
98
  "lint-staged": {
99
99
  "*.{ts,js,tsx,jsx}": [
@@ -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'