@faststore/core 2.0.102-alpha.0 → 2.0.103-alpha.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/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +6 -0
- package/package.json +4 -4
- package/src/components/sections/ProductDetails/ProductDetails.tsx +1 -1
- package/src/components/ui/ImageGallery/ImageGallery.tsx +28 -24
- package/src/components/ui/ImageGallery/index.ts +2 -4
- package/src/components/ui/ImageGallery/ImageGallery.stories.mdx +0 -173
- package/src/components/ui/ImageGallery/ImageGallerySelector.tsx +0 -121
- package/src/components/ui/ImageGallery/ImageZoom.tsx +0 -12
- package/src/components/ui/ImageGallery/image-gallery-selector.module.scss +0 -137
- package/src/components/ui/ImageGallery/image-gallery.module.scss +0 -56
package/.turbo/turbo-build.log
CHANGED
|
@@ -27,8 +27,8 @@ Route (pages) Size First Load JS
|
|
|
27
27
|
├ /_app 0 B 96.7 kB
|
|
28
28
|
├ ● /[...slug] 9.48 kB 122 kB
|
|
29
29
|
├ └ css/8ea129ea90e49e98.css 1.83 kB
|
|
30
|
-
├ ● /[slug]/p 16.
|
|
31
|
-
├ └ css/
|
|
30
|
+
├ ● /[slug]/p 16.9 kB 125 kB
|
|
31
|
+
├ └ css/8d4cc2151b8e3693.css 1.99 kB
|
|
32
32
|
├ ○ /404 431 B 102 kB
|
|
33
33
|
├ ○ /500 439 B 102 kB
|
|
34
34
|
├ ○ /account 383 B 102 kB
|
|
@@ -38,12 +38,12 @@ Route (pages) Size First Load JS
|
|
|
38
38
|
├ ○ /login 385 B 102 kB
|
|
39
39
|
└ ○ /s 895 B 113 kB
|
|
40
40
|
└ css/db63ea05e98cb7e8.css 1.63 kB
|
|
41
|
-
+ First Load JS shared by all
|
|
41
|
+
+ First Load JS shared by all 120 kB
|
|
42
42
|
├ chunks/framework-dfd14d7ce6600b03.js 45.3 kB
|
|
43
43
|
├ chunks/main-9746772201fe3ac1.js 23.9 kB
|
|
44
|
-
├ chunks/pages/_app-
|
|
45
|
-
├ chunks/webpack-
|
|
46
|
-
└ css/
|
|
44
|
+
├ chunks/pages/_app-97338478d9610735.js 25.3 kB
|
|
45
|
+
├ chunks/webpack-83d8a1e4ecde9dde.js 2.19 kB
|
|
46
|
+
└ css/3802630cd2375b43.css 23.1 kB
|
|
47
47
|
|
|
48
48
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
|
49
49
|
○ (Static) automatically rendered as static HTML (uses no initial props)
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.103-alpha.0](https://github.com/vtex/faststore/compare/v2.0.102-alpha.0...v2.0.103-alpha.0) (2023-04-06)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- Add `ImageGallery` components ([#1681](https://github.com/vtex/faststore/issues/1681)) ([b44101c](https://github.com/vtex/faststore/commit/b44101c932b0758f9c1b09ee001d3221c338cf93)), closes [starter.store#37](https://github.com/vtex/starter.store/issues/37)
|
|
11
|
+
|
|
6
12
|
## [2.0.102-alpha.0](https://github.com/vtex/faststore/compare/v2.0.101-alpha.0...v2.0.102-alpha.0) (2023-04-06)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.103-alpha.0",
|
|
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.0.97-alpha.0",
|
|
33
|
-
"@faststore/components": "^2.0.
|
|
33
|
+
"@faststore/components": "^2.0.103-alpha.0",
|
|
34
34
|
"@faststore/graphql-utils": "^2.0.3-alpha.0",
|
|
35
35
|
"@faststore/sdk": "^2.0.3-alpha.0",
|
|
36
|
-
"@faststore/ui": "^2.0.
|
|
36
|
+
"@faststore/ui": "^2.0.103-alpha.0",
|
|
37
37
|
"@types/react": "^18.0.14",
|
|
38
38
|
"@vtex/client-cms": "^0.2.12",
|
|
39
39
|
"autoprefixer": "^10.4.0",
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"msw": {
|
|
109
109
|
"workerDirectory": "public"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "cac804588d1f91794f39bf7b7ce8e18234a7286a"
|
|
112
112
|
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import type { ProductDetailsFragment_ProductFragment } from '@generated/graphql'
|
|
14
14
|
import OutOfStock from 'src/components/product/OutOfStock'
|
|
15
15
|
import Breadcrumb from 'src/components/ui/Breadcrumb'
|
|
16
|
-
import
|
|
16
|
+
import ImageGallery from 'src/components/ui/ImageGallery'
|
|
17
17
|
import ShippingSimulation from 'src/components/ui/ShippingSimulation'
|
|
18
18
|
import Selectors from 'src/components/ui/SkuSelector'
|
|
19
19
|
import type { AnalyticsItem } from 'src/sdk/analytics/types'
|
|
@@ -1,29 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
ImageGallery as UIImageGallery,
|
|
4
|
+
ImageElementData,
|
|
5
|
+
ImageZoom,
|
|
6
|
+
} from '@faststore/ui'
|
|
3
7
|
|
|
4
8
|
import { Image } from 'src/components/ui/Image'
|
|
5
|
-
import
|
|
9
|
+
import { useRouter } from 'next/router'
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
const ImageComponent = ({ url, alternateName }) => (
|
|
12
|
+
<Image
|
|
13
|
+
src={url}
|
|
14
|
+
alt={alternateName}
|
|
15
|
+
sizes="(max-width: 72px) 25vw, 30vw"
|
|
16
|
+
width={72}
|
|
17
|
+
height={72}
|
|
18
|
+
/>
|
|
19
|
+
)
|
|
8
20
|
|
|
9
|
-
export interface
|
|
10
|
-
url: string
|
|
11
|
-
alternateName: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface ImageGalleryProps extends HTMLAttributes<HTMLDivElement> {
|
|
21
|
+
export interface ImageGalleryProps {
|
|
15
22
|
images: ImageElementData[]
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
const ImageGallery = ({ images, ...otherProps }: ImageGalleryProps) => {
|
|
19
26
|
const [selectedImageIdx, setSelectedImageIdx] = useState(0)
|
|
20
|
-
const currentImage = images[selectedImageIdx]
|
|
21
|
-
const
|
|
27
|
+
const currentImage = images[selectedImageIdx] ?? images[0]
|
|
28
|
+
const dynamicRoute = useRouter().asPath
|
|
29
|
+
|
|
30
|
+
useEffect(() => setSelectedImageIdx(0), [dynamicRoute])
|
|
22
31
|
|
|
23
32
|
return (
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
<UIImageGallery
|
|
34
|
+
images={images}
|
|
35
|
+
ImageComponent={ImageComponent}
|
|
36
|
+
selectedImageIdx={selectedImageIdx}
|
|
37
|
+
setSelectedImageIdx={setSelectedImageIdx}
|
|
27
38
|
{...otherProps}
|
|
28
39
|
>
|
|
29
40
|
<ImageZoom>
|
|
@@ -37,14 +48,7 @@ function ImageGallery({ images, ...otherProps }: ImageGalleryProps) {
|
|
|
37
48
|
priority
|
|
38
49
|
/>
|
|
39
50
|
</ImageZoom>
|
|
40
|
-
|
|
41
|
-
<ImageGallerySelector
|
|
42
|
-
images={images}
|
|
43
|
-
currentImageIdx={selectedImageIdx}
|
|
44
|
-
onSelect={setSelectedImageIdx}
|
|
45
|
-
/>
|
|
46
|
-
)}
|
|
47
|
-
</section>
|
|
51
|
+
</UIImageGallery>
|
|
48
52
|
)
|
|
49
53
|
}
|
|
50
54
|
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { default
|
|
2
|
-
export {
|
|
3
|
-
export { default as ImageZoom } from './ImageZoom'
|
|
4
|
-
export type { ImageElementData } from './ImageGallery'
|
|
1
|
+
export { default } from './ImageGallery'
|
|
2
|
+
export type { ImageGalleryProps } from './ImageGallery'
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { Meta, Canvas, Story, ArgsTable } from '@storybook/addon-docs'
|
|
2
|
-
|
|
3
|
-
import { ImageGallery } from '.'
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
TokenTable,
|
|
7
|
-
TokenRow,
|
|
8
|
-
TokenDivider,
|
|
9
|
-
} from 'src/../.storybook/components'
|
|
10
|
-
|
|
11
|
-
<Meta title="Organisms/ImageGallery" />
|
|
12
|
-
|
|
13
|
-
export const Template = () => {
|
|
14
|
-
const productImages = [
|
|
15
|
-
{
|
|
16
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190902/unsplash-magic-mouse.jpg?v=637800136963870000',
|
|
17
|
-
alternateName: 'Magicwhite',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190923/lena-de-fanti-nQ_j5d-klVU-unsplash.jpg?v=637867501523500000',
|
|
21
|
-
alternateName: 'magicbox',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190924/anthony-choren-e7dG26YCrZU-unsplash.jpg?v=637867501835430000',
|
|
25
|
-
alternateName: 'magicblackwhite',
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190925/maheshkumar-painam-GZdfLeL-MDk-unsplash.jpg?v=637867502064000000',
|
|
29
|
-
alternateName: 'magiccombo',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190926/math-0U9fBLGP3EY-unsplash.jpg?v=637867502325830000',
|
|
33
|
-
alternateName: 'magicback',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190927/marek-levak-YPeqMN_wfw0-unsplash.jpg?v=637867502641430000',
|
|
37
|
-
alternateName: 'magictable',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190928/mouse8.jpg?v=637867504048970000',
|
|
41
|
-
alternateName: 'magichand',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190929/harpal-singh-KuvEVL7lXYQ-unsplash.jpg?v=637867509459130000',
|
|
45
|
-
alternateName: 'magicstyle',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190930/chris-hardy-182PzOtcmWc-unsplash.jpg?v=637867509778300000',
|
|
49
|
-
alternateName: 'magicscale',
|
|
50
|
-
},
|
|
51
|
-
]
|
|
52
|
-
return <ImageGallery images={productImages} />
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const TemplateWithoutSelector = () => {
|
|
56
|
-
const productImages = [
|
|
57
|
-
{
|
|
58
|
-
url: 'https://storeframework.vtexassets.com/arquivos/ids/190902/unsplash-magic-mouse.jpg?v=637800136963870000',
|
|
59
|
-
alternateName: 'Magicwhite',
|
|
60
|
-
},
|
|
61
|
-
]
|
|
62
|
-
return <ImageGallery images={productImages} />
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
<header>
|
|
66
|
-
|
|
67
|
-
# Image Gallery
|
|
68
|
-
|
|
69
|
-
An `ImageGallery` is used when you want to display a series of photos in a gallery on a post or page.
|
|
70
|
-
|
|
71
|
-
</header>
|
|
72
|
-
|
|
73
|
-
## Overview
|
|
74
|
-
|
|
75
|
-
According to the quantity of `Image` to be displayed, the `ImageGallerySelector` will be displayed.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Usage
|
|
80
|
-
|
|
81
|
-
`import { ImageGallery } from 'src/components/ui/ImageGallery'`
|
|
82
|
-
|
|
83
|
-
<Canvas className="sbdocs-image-gallery">
|
|
84
|
-
<Story name="default">{Template.bind({})}</Story>
|
|
85
|
-
</Canvas>
|
|
86
|
-
|
|
87
|
-
<TokenTable>
|
|
88
|
-
<TokenRow
|
|
89
|
-
token="--fs-image-gallery-width"
|
|
90
|
-
value="calc(100% + (2 * var(--fs-grid-padding)))"
|
|
91
|
-
/>
|
|
92
|
-
<TokenDivider />
|
|
93
|
-
<TokenRow token="--fs-image-gallery-gap-mobile" value="var(--fs-spacing-2)" />
|
|
94
|
-
<TokenRow
|
|
95
|
-
token="--fs-image-gallery-gap-notebook"
|
|
96
|
-
value="var(--fs-spacing-3)"
|
|
97
|
-
/>
|
|
98
|
-
</TokenTable>
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Nested Elements
|
|
103
|
-
|
|
104
|
-
### Current Selected Image
|
|
105
|
-
|
|
106
|
-
<TokenTable>
|
|
107
|
-
<TokenRow token="--fs-image-gallery-current-height" value="33.125rem" />
|
|
108
|
-
<TokenRow
|
|
109
|
-
token="--fs-image-gallery-current-border-radius"
|
|
110
|
-
value="var(--fs-border-radius)"
|
|
111
|
-
/>
|
|
112
|
-
</TokenTable>
|
|
113
|
-
|
|
114
|
-
### Selector
|
|
115
|
-
|
|
116
|
-
<TokenTable>
|
|
117
|
-
<TokenRow token="--fs-image-gallery-selector-max-height" value="33.125rem" />
|
|
118
|
-
</TokenTable>
|
|
119
|
-
|
|
120
|
-
### Selector Elements
|
|
121
|
-
|
|
122
|
-
<TokenTable>
|
|
123
|
-
<TokenRow
|
|
124
|
-
token="--fs-image-gallery-selector-elements-gap"
|
|
125
|
-
value="var(--fs-spacing-1)"
|
|
126
|
-
/>
|
|
127
|
-
<TokenRow
|
|
128
|
-
token="--fs-image-gallery-selector-elements-gap-notebook"
|
|
129
|
-
value="var(--fs-spacing-2)"
|
|
130
|
-
/>
|
|
131
|
-
<TokenRow
|
|
132
|
-
token="--fs-image-gallery-selector-elements-padding"
|
|
133
|
-
value="var(--fs-spacing-0)"
|
|
134
|
-
/>
|
|
135
|
-
</TokenTable>
|
|
136
|
-
|
|
137
|
-
### Selector Thumbnail
|
|
138
|
-
|
|
139
|
-
<TokenTable>
|
|
140
|
-
<TokenRow
|
|
141
|
-
token="--fs-image-gallery-selector-thumbnail-width-mobile"
|
|
142
|
-
value="3.5rem"
|
|
143
|
-
/>
|
|
144
|
-
<TokenRow
|
|
145
|
-
token="--fs-image-gallery-selector-thumbnail-width-notebook"
|
|
146
|
-
value="4.5rem"
|
|
147
|
-
/>
|
|
148
|
-
<TokenRow
|
|
149
|
-
token="--fs-image-gallery-selector-thumbnail-border-radius"
|
|
150
|
-
value="var(--fs-border-radius)"
|
|
151
|
-
/>
|
|
152
|
-
<TokenRow
|
|
153
|
-
token="--fs-image-gallery-selector-thumbnail-selected-border-color"
|
|
154
|
-
value="var(--fs-border-color-active)"
|
|
155
|
-
isColor
|
|
156
|
-
/>
|
|
157
|
-
</TokenTable>
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## Variants
|
|
162
|
-
|
|
163
|
-
### With Selector (More than 1 Image)
|
|
164
|
-
|
|
165
|
-
<Canvas className="sbdocs-image-gallery">
|
|
166
|
-
<Story name="overview-default">{Template.bind({})}</Story>
|
|
167
|
-
</Canvas>
|
|
168
|
-
|
|
169
|
-
### Without Selector
|
|
170
|
-
|
|
171
|
-
<Canvas className="sbdocs-image-gallery">
|
|
172
|
-
<Story name="overview-default-2">{TemplateWithoutSelector.bind({})}</Story>
|
|
173
|
-
</Canvas>
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button as UIButton,
|
|
3
|
-
Icon,
|
|
4
|
-
IconButton as UIIconButton,
|
|
5
|
-
} from '@faststore/ui'
|
|
6
|
-
import { useRef } from 'react'
|
|
7
|
-
import { useInView } from 'react-intersection-observer'
|
|
8
|
-
|
|
9
|
-
import { Image } from 'src/components/ui/Image'
|
|
10
|
-
import styles from 'src/components/ui/ImageGallery/image-gallery-selector.module.scss'
|
|
11
|
-
|
|
12
|
-
import type { ImageElementData } from './ImageGallery'
|
|
13
|
-
|
|
14
|
-
interface Props {
|
|
15
|
-
images: ImageElementData[]
|
|
16
|
-
onSelect: React.Dispatch<React.SetStateAction<number>>
|
|
17
|
-
currentImageIdx: number
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const SCROLL_MARGIN_VALUE = 400
|
|
21
|
-
|
|
22
|
-
const moveScroll = (container: HTMLDivElement | null, value: number) => {
|
|
23
|
-
if (container) {
|
|
24
|
-
if (container.scrollHeight > container.clientHeight) {
|
|
25
|
-
// TODO: Temporary workaround for scroll-behavior with scrollTop – Safari 15.4) https://developer.apple.com/forums/thread/703294
|
|
26
|
-
container.style.overflow = 'auto'
|
|
27
|
-
window.requestAnimationFrame(() =>
|
|
28
|
-
container.scrollTo({ top: value, behavior: 'smooth' })
|
|
29
|
-
)
|
|
30
|
-
setTimeout(() => (container.style.overflow = 'hidden'), 2000)
|
|
31
|
-
} else {
|
|
32
|
-
container.scrollLeft += value
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const hasScroll = (container: HTMLDivElement | null): boolean => {
|
|
38
|
-
if (container) {
|
|
39
|
-
return (
|
|
40
|
-
container.scrollHeight > container.clientHeight ||
|
|
41
|
-
container.scrollWidth > container.clientWidth
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function ImageGallerySelector({ images, onSelect, currentImageIdx }: Props) {
|
|
49
|
-
const elementsRef = useRef<HTMLDivElement>(null)
|
|
50
|
-
const elementHasScroll = hasScroll(elementsRef.current)
|
|
51
|
-
const { ref: firstImageRef, inView: firstImageInView } = useInView({
|
|
52
|
-
threshold: 1,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const { ref: lastImageRef, inView: lastImageInView } = useInView({
|
|
56
|
-
threshold: 1,
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<section
|
|
61
|
-
data-fs-image-gallery-selector
|
|
62
|
-
className={styles.fsImageGallerySelector}
|
|
63
|
-
aria-roledescription="carousel"
|
|
64
|
-
aria-label="Product images"
|
|
65
|
-
>
|
|
66
|
-
{elementHasScroll && !firstImageInView && (
|
|
67
|
-
<UIIconButton
|
|
68
|
-
data-fs-image-gallery-selector-control-button
|
|
69
|
-
aria-label="backward slide image selector"
|
|
70
|
-
icon={<Icon name="ArrowLeft" width={24} height={24} />}
|
|
71
|
-
onClick={() => moveScroll(elementsRef.current, -SCROLL_MARGIN_VALUE)}
|
|
72
|
-
/>
|
|
73
|
-
)}
|
|
74
|
-
<div data-fs-image-gallery-selector-elements ref={elementsRef}>
|
|
75
|
-
{images.map((image, idx) => {
|
|
76
|
-
const ref =
|
|
77
|
-
idx === 0
|
|
78
|
-
? firstImageRef
|
|
79
|
-
: idx === images.length - 1
|
|
80
|
-
? lastImageRef
|
|
81
|
-
: null
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<UIButton
|
|
85
|
-
key={idx}
|
|
86
|
-
aria-label={`${image.alternateName} - Image ${idx + 1} of ${
|
|
87
|
-
images.length
|
|
88
|
-
}`}
|
|
89
|
-
onClick={() => onSelect(idx)}
|
|
90
|
-
data-fs-image-gallery-selector-thumbnail={
|
|
91
|
-
idx === currentImageIdx ? 'selected' : 'true'
|
|
92
|
-
}
|
|
93
|
-
>
|
|
94
|
-
<Image
|
|
95
|
-
onLoadingComplete={(img) => {
|
|
96
|
-
if (ref) ref(img)
|
|
97
|
-
}}
|
|
98
|
-
src={image.url}
|
|
99
|
-
alt={image.alternateName}
|
|
100
|
-
loading={idx === 0 ? 'eager' : 'lazy'}
|
|
101
|
-
sizes="(max-width: 72px) 25vw, 30vw"
|
|
102
|
-
width={72}
|
|
103
|
-
height={72}
|
|
104
|
-
/>
|
|
105
|
-
</UIButton>
|
|
106
|
-
)
|
|
107
|
-
})}
|
|
108
|
-
</div>
|
|
109
|
-
{elementHasScroll && !lastImageInView && (
|
|
110
|
-
<UIIconButton
|
|
111
|
-
data-fs-image-gallery-selector-control-button
|
|
112
|
-
aria-label="forward slide image selector"
|
|
113
|
-
icon={<Icon name="ArrowLeft" width={24} height={24} />}
|
|
114
|
-
onClick={() => moveScroll(elementsRef.current, +SCROLL_MARGIN_VALUE)}
|
|
115
|
-
/>
|
|
116
|
-
)}
|
|
117
|
-
</section>
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export default ImageGallerySelector
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { PropsWithChildren } from 'react'
|
|
2
|
-
|
|
3
|
-
interface ImageZoomProps {
|
|
4
|
-
helpMessage?: string
|
|
5
|
-
zoomFactor?: number
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const ImageZoom = ({ children }: PropsWithChildren<ImageZoomProps>) => {
|
|
9
|
-
return <> {children} </>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default ImageZoom
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
@import "src/styles/scaffold";
|
|
2
|
-
|
|
3
|
-
.fs-image-gallery-selector {
|
|
4
|
-
// --------------------------------------------------------
|
|
5
|
-
// Design Tokens for Image Gallery Selector
|
|
6
|
-
// --------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
// Default properties
|
|
9
|
-
--fs-image-gallery-selector-max-height : 33.125rem; // 530px
|
|
10
|
-
|
|
11
|
-
// Elements
|
|
12
|
-
--fs-image-gallery-selector-elements-gap : var(--fs-spacing-1);
|
|
13
|
-
--fs-image-gallery-selector-elements-gap-notebook : var(--fs-spacing-2);
|
|
14
|
-
--fs-image-gallery-selector-elements-padding : var(--fs-spacing-0);
|
|
15
|
-
|
|
16
|
-
// Thumbnail
|
|
17
|
-
--fs-image-gallery-selector-thumbnail-width-mobile : var(--fs-spacing-8);
|
|
18
|
-
--fs-image-gallery-selector-thumbnail-width-notebook : var(--fs-spacing-10);
|
|
19
|
-
--fs-image-gallery-selector-thumbnail-border-radius : var(--fs-border-radius);
|
|
20
|
-
--fs-image-gallery-selector-thumbnail-selected-border-color : var(--fs-border-color-active);
|
|
21
|
-
|
|
22
|
-
// --------------------------------------------------------
|
|
23
|
-
// Structural Styles
|
|
24
|
-
// --------------------------------------------------------
|
|
25
|
-
position: relative;
|
|
26
|
-
display: flex;
|
|
27
|
-
align-items: center;
|
|
28
|
-
justify-content: center;
|
|
29
|
-
max-height: var(--fs-image-gallery-selector-max-height);
|
|
30
|
-
|
|
31
|
-
@include media(">=notebook") {
|
|
32
|
-
flex-direction: column;
|
|
33
|
-
grid-row: 1;
|
|
34
|
-
justify-content: space-between;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
[data-fs-image-gallery-selector-elements] {
|
|
38
|
-
display: flex;
|
|
39
|
-
column-gap: var(--fs-image-gallery-selector-elements-gap);
|
|
40
|
-
padding: var(--fs-image-gallery-selector-elements-padding);
|
|
41
|
-
overflow-x: auto;
|
|
42
|
-
scroll-behavior: smooth;
|
|
43
|
-
|
|
44
|
-
&::-webkit-scrollbar {
|
|
45
|
-
display: none;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@include media(">=notebook") {
|
|
49
|
-
flex-direction: column;
|
|
50
|
-
row-gap: var(--fs-image-gallery-selector-elements-gap-notebook);
|
|
51
|
-
overflow-y: hidden;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
[data-fs-image-gallery-selector-thumbnail] {
|
|
56
|
-
flex-shrink: 0;
|
|
57
|
-
width: var(--fs-image-gallery-selector-thumbnail-width-mobile);
|
|
58
|
-
padding: 0;
|
|
59
|
-
overflow: hidden;
|
|
60
|
-
background-color: transparent;
|
|
61
|
-
border: var(--fs-border-width-thick) solid transparent;
|
|
62
|
-
border-radius: var(--fs-image-gallery-selector-thumbnail-border-radius);
|
|
63
|
-
transition: all var(--fs-transition-timing) var(--fs-transition-function);
|
|
64
|
-
|
|
65
|
-
&:hover:not([data-fs-image-gallery-selector-thumbnail="selected"]) {
|
|
66
|
-
border-color: var(--fs-image-gallery-selector-thumbnail-selected-border-color);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
&[data-fs-image-gallery-selector-thumbnail="selected"] {
|
|
70
|
-
border-color: var(--fs-image-gallery-selector-thumbnail-selected-border-color);
|
|
71
|
-
box-shadow: 0 0 0 var(--fs-border-width-thickest) var(--fs-color-focus-ring-outline);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
[data-fs-image] {
|
|
75
|
-
border: var(--fs-border-width-thick) solid var(--fs-color-body-bkg);
|
|
76
|
-
border-radius: var(--fs-image-gallery-selector-thumbnail-border-radius);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@include focus-ring-visible;
|
|
80
|
-
|
|
81
|
-
@include media(">=notebook") {
|
|
82
|
-
width: var(--fs-image-gallery-selector-thumbnail-width-notebook);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
[data-fs-image-gallery-selector-control-button] {
|
|
87
|
-
position: absolute;
|
|
88
|
-
z-index: 1;
|
|
89
|
-
color: var(--fs-color-text-display);
|
|
90
|
-
background: linear-gradient(90deg, var(--fs-color-body-bkg) 55%, transparent);
|
|
91
|
-
background-color: transparent;
|
|
92
|
-
border: none;
|
|
93
|
-
border-radius: var(--fs-border-radius-circle);
|
|
94
|
-
|
|
95
|
-
&:hover {
|
|
96
|
-
color: var(--fs-color-text-display);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
[data-fs-icon]span {
|
|
100
|
-
display: flex;
|
|
101
|
-
height: fit-content;
|
|
102
|
-
padding: var(--fs-spacing-1);
|
|
103
|
-
background-color: var(--fs-control-bkg);
|
|
104
|
-
border-radius: var(--fs-border-radius-circle);
|
|
105
|
-
box-shadow: var(--fs-shadow);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@include media("<notebook") {
|
|
109
|
-
height: 100%;
|
|
110
|
-
|
|
111
|
-
&:first-child {
|
|
112
|
-
left: 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
&:last-child {
|
|
116
|
-
right: 0;
|
|
117
|
-
transform: scaleX(-1);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
@include media(">=notebook") {
|
|
122
|
-
display: flex;
|
|
123
|
-
justify-content: center;
|
|
124
|
-
width: 100%;
|
|
125
|
-
background: linear-gradient(180deg, var(--fs-color-body-bkg) 55%, transparent);
|
|
126
|
-
|
|
127
|
-
[data-fs-icon]span {
|
|
128
|
-
transform: rotate(90deg);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
&:last-child {
|
|
132
|
-
bottom: 0;
|
|
133
|
-
transform: scaleY(-1);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
@import "src/styles/scaffold";
|
|
2
|
-
|
|
3
|
-
.fs-image-gallery {
|
|
4
|
-
// --------------------------------------------------------
|
|
5
|
-
// Design Tokens for Image Gallery
|
|
6
|
-
// --------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
// Default properties
|
|
9
|
-
--fs-image-gallery-width : calc(100% + (2 * var(--fs-grid-padding)));
|
|
10
|
-
|
|
11
|
-
--fs-image-gallery-gap-mobile : var(--fs-spacing-2);
|
|
12
|
-
--fs-image-gallery-gap-notebook : var(--fs-spacing-3);
|
|
13
|
-
|
|
14
|
-
// Current Selected Image
|
|
15
|
-
--fs-image-gallery-current-border-radius : var(--fs-border-radius);
|
|
16
|
-
--fs-image-gallery-current-height : 33.125rem; // 530px
|
|
17
|
-
|
|
18
|
-
// --------------------------------------------------------
|
|
19
|
-
// Structural Styles
|
|
20
|
-
// --------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
position: relative;
|
|
23
|
-
left: calc(-1 * var(--fs-grid-padding));
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: column;
|
|
26
|
-
row-gap: var(--fs-image-gallery-gap-mobile);
|
|
27
|
-
width: var(--fs-image-gallery-width);
|
|
28
|
-
|
|
29
|
-
@include media(">=tablet") {
|
|
30
|
-
left: 0;
|
|
31
|
-
width: 100%;
|
|
32
|
-
|
|
33
|
-
> [data-fs-image] {
|
|
34
|
-
grid-column: 2 / span 7;
|
|
35
|
-
border-radius: var(--fs-image-gallery-current-border-radius);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@include media(">=notebook") {
|
|
40
|
-
>[data-fs-image] {
|
|
41
|
-
height: var(--fs-image-gallery-current-height);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// --------------------------------------------------------
|
|
46
|
-
// Variants Styles
|
|
47
|
-
// --------------------------------------------------------
|
|
48
|
-
|
|
49
|
-
&[data-fs-image-gallery="with-selector"] {
|
|
50
|
-
@include media(">=notebook") {
|
|
51
|
-
display: grid;
|
|
52
|
-
grid-template-columns: repeat(8, 1fr);
|
|
53
|
-
column-gap: var(--fs-image-gallery-gap-notebook);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|