@faststore/components 2.0.102-alpha.0 → 2.0.104-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.
@@ -6,7 +6,7 @@ const Button = forwardRef(function Button({ children, variant, inverse, size = '
6
6
  loadingLabel,
7
7
  React.createElement(Loader, { variant: variant === 'primary' && !inverse ? 'light' : 'dark' }))),
8
8
  React.isValidElement(icon) && iconPosition === 'left' && React.createElement("span", { "data-fs-button-icon": true }, icon),
9
- React.createElement("span", null, children),
9
+ children && React.createElement("span", null, children),
10
10
  React.isValidElement(icon) && iconPosition === 'right' && React.createElement("span", { "data-fs-button-icon": true }, icon)));
11
11
  });
12
12
  export default Button;
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/atoms/Button/Button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AA6C/B,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CACvE,EACE,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,GAAG,SAAS,EAChB,MAAM,GAAG,WAAW,EACpB,OAAO,EACP,YAAY,EACZ,IAAI,EACJ,YAAY,GAAG,MAAM,EACrB,QAAQ,EACR,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,gCACE,GAAG,EAAE,GAAG,oDAEgB,OAAO,yBACV,IAAI,4BACD,OAAO,4BACP,OAAO,EAC/B,QAAQ,EAAE,QAAQ,iBACL,MAAM,KACf,UAAU;QAEb,OAAO,IAAI,CACV;YACG,YAAY;YACb,oBAAC,MAAM,IACL,OAAO,EAAE,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAC7D,CACA,CACL;QACA,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,YAAY,KAAK,MAAM,IAAI,6DAA2B,IAAI,CAAQ;QACjG,kCAAO,QAAQ,CAAQ;QACtB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,YAAY,KAAK,OAAO,IAAI,6DAA2B,IAAI,CAAQ,CAC3F,CACV,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/atoms/Button/Button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AA6C/B,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CACvE,EACE,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,GAAG,SAAS,EAChB,MAAM,GAAG,WAAW,EACpB,OAAO,EACP,YAAY,EACZ,IAAI,EACJ,YAAY,GAAG,MAAM,EACrB,QAAQ,EACR,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,gCACE,GAAG,EAAE,GAAG,oDAEgB,OAAO,yBACV,IAAI,4BACD,OAAO,4BACP,OAAO,EAC/B,QAAQ,EAAE,QAAQ,iBACL,MAAM,KACf,UAAU;QAEb,OAAO,IAAI,CACV;YACG,YAAY;YACb,oBAAC,MAAM,IACL,OAAO,EAAE,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAC7D,CACA,CACL;QACA,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,YAAY,KAAK,MAAM,IAAI,6DAA2B,IAAI,CAAQ;QAChG,QAAQ,IAAI,kCAAO,QAAQ,CAAQ;QACnC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,YAAY,KAAK,OAAO,IAAI,6DAA2B,IAAI,CAAQ,CAC3F,CACV,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,MAAM,CAAA"}
package/dist/index.d.ts CHANGED
@@ -103,6 +103,8 @@ export { default as Filter, FilterFacetBoolean, FilterFacetBooleanItem, FilterFa
103
103
  export type { FilterFacetBooleanItemProps, FilterFacetRangeProps, FilterFacetsProps, FilterProps, FilterSliderProps, } from './organisms/Filter';
104
104
  export { default as Hero, HeroImage, HeroHeader } from './organisms/Hero';
105
105
  export type { HeroProps, HeroImageProps, HeroHeaderProps, } from './organisms/Hero';
106
+ export { default as ImageGallery, ImageGallerySelector, ImageZoom, } from './organisms/ImageGallery';
107
+ export type { ImageElementData, ImageGalleryProps, ImageGallerySelectorProps, ImageZoomProps, } from './organisms/ImageGallery';
106
108
  export { default as OutOfStock } from './organisms/OutOfStock';
107
109
  export type { OutOfStockProps } from './organisms/OutOfStock';
108
110
  export { default as PaymentMethods } from './organisms/PaymentMethods';
package/dist/index.js CHANGED
@@ -57,6 +57,7 @@ export { default as QuantitySelector } from './molecules/QuantitySelector';
57
57
  export { default as CartSidebar, CartSidebarList, CartSidebarFooter, } from './organisms/CartSidebar';
58
58
  export { default as Filter, FilterFacetBoolean, FilterFacetBooleanItem, FilterFacetRange, FilterFacets, FilterSlider, } from './organisms/Filter';
59
59
  export { default as Hero, HeroImage, HeroHeader } from './organisms/Hero';
60
+ export { default as ImageGallery, ImageGallerySelector, ImageZoom, } from './organisms/ImageGallery';
60
61
  export { default as OutOfStock } from './organisms/OutOfStock';
61
62
  export { default as PaymentMethods } from './organisms/PaymentMethods';
62
63
  export { default as PriceRange } from './organisms/PriceRange';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import type { HTMLAttributes, FunctionComponent } from 'react';
3
+ type ImageComponentType = FunctionComponent<{
4
+ url: string;
5
+ alternateName?: string;
6
+ loading?: 'eager' | 'lazy';
7
+ }>;
8
+ export interface ImageElementData {
9
+ /**
10
+ * Image URL.
11
+ */
12
+ url: string;
13
+ /**
14
+ * Alternative text description of the image.
15
+ */
16
+ alternateName: string;
17
+ }
18
+ export interface ImageGalleryProps extends HTMLAttributes<HTMLDivElement> {
19
+ /**
20
+ * ID to find this component in testing tools (e.g.: cypress,
21
+ * testing-library, and jest).
22
+ */
23
+ testId?: string;
24
+ /**
25
+ * List of images that should be rendered.
26
+ */
27
+ images: ImageElementData[];
28
+ /**
29
+ * Function that returns a React component that will be used to render images.
30
+ */
31
+ ImageComponent: ImageComponentType;
32
+ /**
33
+ * The currently active thumbnail.
34
+ */
35
+ selectedImageIdx: number;
36
+ /**
37
+ * Event handler for clicks on each thumbnail.
38
+ */
39
+ setSelectedImageIdx: (idx: number) => void;
40
+ }
41
+ declare const ImageGallery: React.ForwardRefExoticComponent<ImageGalleryProps & React.RefAttributes<HTMLDivElement>>;
42
+ export default ImageGallery;
@@ -0,0 +1,10 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { ImageGallerySelector } from '../..';
3
+ const ImageGallery = forwardRef(function ImageGallery({ images, children, ImageComponent, selectedImageIdx, setSelectedImageIdx, testId = 'fs-image-gallery', ...otherProps }, ref) {
4
+ const hasSelector = images.length > 1;
5
+ return (React.createElement("section", { ref: ref, "data-fs-image-gallery": hasSelector ? 'with-selector' : 'without-selector', "data-testid": testId, ...otherProps },
6
+ children,
7
+ hasSelector && (React.createElement(ImageGallerySelector, { images: images, onSelect: setSelectedImageIdx, currentImageIdx: selectedImageIdx, ImageComponent: ImageComponent }))));
8
+ });
9
+ export default ImageGallery;
10
+ //# sourceMappingURL=ImageGallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageGallery.js","sourceRoot":"","sources":["../../../src/organisms/ImageGallery/ImageGallery.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AA2C5C,MAAM,YAAY,GAAG,UAAU,CAC7B,SAAS,YAAY,CACnB,EACE,MAAM,EACN,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,MAAM,GAAG,kBAAkB,EAC3B,GAAG,UAAU,EACd,EACD,GAAG;IAEH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;IAErC,OAAO,CACL,iCACE,GAAG,EAAE,GAAG,2BAEN,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,kBAAkB,iBAEvC,MAAM,KACf,UAAU;QAEb,QAAQ;QACR,WAAW,IAAI,CACd,oBAAC,oBAAoB,IACnB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,mBAAmB,EAC7B,eAAe,EAAE,gBAAgB,EACjC,cAAc,EAAE,cAAc,GAC9B,CACH,CACO,CACX,CAAA;AACH,CAAC,CACF,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,31 @@
1
+ import type { AriaAttributes } from 'react';
2
+ import type { ImageGalleryProps } from '.';
3
+ export interface ImageGallerySelectorProps extends Pick<ImageGalleryProps, 'images' | 'ImageComponent'> {
4
+ /**
5
+ * ID to find this component in testing tools (e.g.: cypress,
6
+ * testing-library, and jest).
7
+ */
8
+ testId?: string;
9
+ /**
10
+ * The currently active thumbnail.
11
+ */
12
+ currentImageIdx: number;
13
+ /**
14
+ * For accessibility purposes, define a string that labels the current element.
15
+ */
16
+ 'aria-label'?: AriaAttributes['aria-label'];
17
+ /**
18
+ * For accessibility purposes, define a string that labels the left navigation icon button.
19
+ */
20
+ navigationButtonLeftAriaLabel?: AriaAttributes['aria-label'];
21
+ /**
22
+ * For accessibility purposes, define a string that labels the right navigation button icon.
23
+ */
24
+ navigationButtonRightAriaLabel?: AriaAttributes['aria-label'];
25
+ /**
26
+ * Event handler for clicks on each thumbnail.
27
+ */
28
+ onSelect: (imageIdx: number) => void;
29
+ }
30
+ declare function ImageGallerySelector({ images, onSelect, ImageComponent, currentImageIdx, testId, 'aria-label': ariaLabel, navigationButtonLeftAriaLabel, navigationButtonRightAriaLabel, }: ImageGallerySelectorProps): JSX.Element;
31
+ export default ImageGallerySelector;
@@ -0,0 +1,46 @@
1
+ import React, { useRef, useState, useCallback } from 'react';
2
+ import { InView } from 'react-intersection-observer';
3
+ import { Button, Icon, IconButton } from '../..';
4
+ const SCROLL_MARGIN_VALUE = 400;
5
+ const moveScroll = (container, value) => {
6
+ if (container) {
7
+ if (container.scrollHeight > container.clientHeight) {
8
+ // TODO: Temporary workaround for scroll-behavior with scrollTop – Safari 15.4) https://developer.apple.com/forums/thread/703294
9
+ container.style.overflow = 'auto';
10
+ window.requestAnimationFrame(() => container.scrollTo({ top: value, behavior: 'smooth' }));
11
+ setTimeout(() => (container.style.overflow = 'hidden'), 2000);
12
+ }
13
+ else {
14
+ container.scrollLeft += value;
15
+ }
16
+ }
17
+ };
18
+ const hasScroll = (container) => {
19
+ if (container) {
20
+ return (container.scrollHeight > container.clientHeight ||
21
+ container.scrollWidth > container.clientWidth);
22
+ }
23
+ return false;
24
+ };
25
+ function ImageGallerySelector({ images, onSelect, ImageComponent, currentImageIdx, testId = 'fs-image-gallery-selector', 'aria-label': ariaLabel = 'Product Images', navigationButtonLeftAriaLabel = 'Backward slide image selector', navigationButtonRightAriaLabel = 'Forward slide image selector', }) {
26
+ const elementsRef = useRef(null);
27
+ const elementHasScroll = hasScroll(elementsRef.current);
28
+ const [firstImageInView, setFirstImageInView] = useState(true);
29
+ const [lastImageInView, setLastImageInView] = useState(true);
30
+ const inViewChange = useCallback((idx, inView) => {
31
+ idx === 0 && setFirstImageInView(inView);
32
+ idx === images.length - 1 && setLastImageInView(inView);
33
+ }, [images.length]);
34
+ return (React.createElement("section", { "data-fs-image-gallery-selector": true, "data-testid": testId, "aria-label": ariaLabel, "aria-roledescription": "carousel" },
35
+ elementHasScroll && !firstImageInView && (React.createElement("div", { "data-fs-image-gallery-selector-control": true },
36
+ React.createElement(IconButton, { "data-fs-image-gallery-selector-control-button": true, "aria-label": navigationButtonLeftAriaLabel, icon: React.createElement(Icon, { name: "ArrowLeft" }), size: "small", onClick: () => moveScroll(elementsRef.current, -SCROLL_MARGIN_VALUE) }))),
37
+ React.createElement("div", { "data-fs-image-gallery-selector-elements": true, ref: elementsRef }, images.map((image, idx) => {
38
+ return (React.createElement(InView, { key: idx, onChange: (inView) => inViewChange(idx, inView) },
39
+ React.createElement(Button, { key: idx, "aria-label": `${image.alternateName} - Image ${idx + 1} of ${images.length}`, onClick: () => onSelect(idx), "data-fs-image-gallery-selector-thumbnail": idx === currentImageIdx ? 'selected' : 'true' },
40
+ React.createElement(ImageComponent, { url: image.url ?? '', loading: idx === 0 ? 'eager' : 'lazy', alternateName: image.alternateName ?? '' }))));
41
+ })),
42
+ elementHasScroll && !lastImageInView && (React.createElement("div", { "data-fs-image-gallery-selector-control": true },
43
+ React.createElement(IconButton, { "data-fs-image-gallery-selector-control-button": true, "aria-label": navigationButtonRightAriaLabel, icon: React.createElement(Icon, { name: "ArrowLeft" }), size: "small", onClick: () => moveScroll(elementsRef.current, +SCROLL_MARGIN_VALUE) })))));
44
+ }
45
+ export default ImageGallerySelector;
46
+ //# sourceMappingURL=ImageGallerySelector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageGallerySelector.js","sourceRoot":"","sources":["../../../src/organisms/ImageGallery/ImageGallerySelector.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ export interface ImageZoomProps {
3
+ helpMessage?: string;
4
+ zoomFactor?: number;
5
+ }
6
+ declare const ImageZoom: ({ children }: PropsWithChildren<ImageZoomProps>) => JSX.Element;
7
+ export default ImageZoom;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ const ImageZoom = ({ children }) => {
3
+ return React.createElement(React.Fragment, null, children);
4
+ };
5
+ export default ImageZoom;
6
+ //# sourceMappingURL=ImageZoom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageZoom.js","sourceRoot":"","sources":["../../../src/organisms/ImageGallery/ImageZoom.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,MAAM,SAAS,GAAG,CAAC,EAAE,QAAQ,EAAqC,EAAE,EAAE;IACpE,OAAO,0CAAG,QAAQ,CAAI,CAAA;AACxB,CAAC,CAAA;AAED,eAAe,SAAS,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { default } from './ImageGallery';
2
+ export type { ImageGalleryProps, ImageElementData } from './ImageGallery';
3
+ export { default as ImageGallerySelector } from './ImageGallerySelector';
4
+ export type { ImageGallerySelectorProps } from './ImageGallerySelector';
5
+ export { default as ImageZoom } from './ImageZoom';
6
+ export type { ImageZoomProps } from './ImageZoom';
@@ -0,0 +1,4 @@
1
+ export { default } from './ImageGallery';
2
+ export { default as ImageGallerySelector } from './ImageGallerySelector';
3
+ export { default as ImageZoom } from './ImageZoom';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/organisms/ImageGallery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAGxC,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAGxE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/components",
3
- "version": "2.0.102-alpha.0",
3
+ "version": "2.0.104-alpha.0",
4
4
  "module": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "author": "Emerson Laurentino @emersonlaurentino",
@@ -21,8 +21,8 @@
21
21
  "src"
22
22
  ],
23
23
  "devDependencies": {
24
- "@faststore/eslint-config": "^2.0.91-alpha.0",
25
- "@faststore/shared": "^2.0.91-alpha.0",
24
+ "@faststore/eslint-config": "^2.0.104-alpha.0",
25
+ "@faststore/shared": "^2.0.104-alpha.0",
26
26
  "eslint": "7.32.0",
27
27
  "typescript": "^4.8.4"
28
28
  },
@@ -30,5 +30,5 @@
30
30
  "node": "16.18.0",
31
31
  "yarn": "1.19.1"
32
32
  },
33
- "gitHead": "c9841c86822020c65161193647edf280cd765efa"
33
+ "gitHead": "0db7f06c36c7c41ecec51f247b21866469977618"
34
34
  }
@@ -82,7 +82,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
82
82
  </p>
83
83
  )}
84
84
  {React.isValidElement(icon) && iconPosition === 'left' && <span data-fs-button-icon>{icon}</span>}
85
- <span>{children}</span>
85
+ {children && <span>{children}</span>}
86
86
  {React.isValidElement(icon) && iconPosition === 'right' && <span data-fs-button-icon>{icon}</span>}
87
87
  </button>
88
88
  )
package/src/index.ts CHANGED
@@ -221,6 +221,18 @@ export type {
221
221
  HeroHeaderProps,
222
222
  } from './organisms/Hero'
223
223
 
224
+ export {
225
+ default as ImageGallery,
226
+ ImageGallerySelector,
227
+ ImageZoom,
228
+ } from './organisms/ImageGallery'
229
+ export type {
230
+ ImageElementData,
231
+ ImageGalleryProps,
232
+ ImageGallerySelectorProps,
233
+ ImageZoomProps,
234
+ } from './organisms/ImageGallery'
235
+
224
236
  export { default as OutOfStock } from './organisms/OutOfStock'
225
237
  export type { OutOfStockProps } from './organisms/OutOfStock'
226
238
 
@@ -0,0 +1,85 @@
1
+ import React, { forwardRef } from 'react'
2
+ import type { HTMLAttributes, FunctionComponent } from 'react'
3
+
4
+ import { ImageGallerySelector } from '../..'
5
+
6
+ type ImageComponentType = FunctionComponent<{
7
+ url: string
8
+ alternateName?: string
9
+ loading?: 'eager' | 'lazy'
10
+ }>
11
+
12
+ export interface ImageElementData {
13
+ /**
14
+ * Image URL.
15
+ */
16
+ url: string
17
+ /**
18
+ * Alternative text description of the image.
19
+ */
20
+ alternateName: string
21
+ }
22
+
23
+ export interface ImageGalleryProps extends HTMLAttributes<HTMLDivElement> {
24
+ /**
25
+ * ID to find this component in testing tools (e.g.: cypress,
26
+ * testing-library, and jest).
27
+ */
28
+ testId?: string
29
+ /**
30
+ * List of images that should be rendered.
31
+ */
32
+ images: ImageElementData[]
33
+ /**
34
+ * Function that returns a React component that will be used to render images.
35
+ */
36
+ ImageComponent: ImageComponentType
37
+ /**
38
+ * The currently active thumbnail.
39
+ */
40
+ selectedImageIdx: number
41
+ /**
42
+ * Event handler for clicks on each thumbnail.
43
+ */
44
+ setSelectedImageIdx: (idx: number) => void
45
+ }
46
+
47
+ const ImageGallery = forwardRef<HTMLDivElement, ImageGalleryProps>(
48
+ function ImageGallery(
49
+ {
50
+ images,
51
+ children,
52
+ ImageComponent,
53
+ selectedImageIdx,
54
+ setSelectedImageIdx,
55
+ testId = 'fs-image-gallery',
56
+ ...otherProps
57
+ },
58
+ ref
59
+ ) {
60
+ const hasSelector = images.length > 1
61
+
62
+ return (
63
+ <section
64
+ ref={ref}
65
+ data-fs-image-gallery={
66
+ hasSelector ? 'with-selector' : 'without-selector'
67
+ }
68
+ data-testid={testId}
69
+ {...otherProps}
70
+ >
71
+ {children}
72
+ {hasSelector && (
73
+ <ImageGallerySelector
74
+ images={images}
75
+ onSelect={setSelectedImageIdx}
76
+ currentImageIdx={selectedImageIdx}
77
+ ImageComponent={ImageComponent}
78
+ />
79
+ )}
80
+ </section>
81
+ )
82
+ }
83
+ )
84
+
85
+ export default ImageGallery
@@ -0,0 +1,148 @@
1
+ import React, { useRef, useState, useCallback } from 'react'
2
+ import type { AriaAttributes } from 'react'
3
+ import { InView } from 'react-intersection-observer'
4
+ import { Button, Icon, IconButton } from '../..'
5
+
6
+ import type { ImageGalleryProps } from '.'
7
+
8
+ export interface ImageGallerySelectorProps
9
+ extends Pick<ImageGalleryProps, 'images' | 'ImageComponent'> {
10
+ /**
11
+ * ID to find this component in testing tools (e.g.: cypress,
12
+ * testing-library, and jest).
13
+ */
14
+ testId?: string
15
+ /**
16
+ * The currently active thumbnail.
17
+ */
18
+ currentImageIdx: number
19
+ /**
20
+ * For accessibility purposes, define a string that labels the current element.
21
+ */
22
+ 'aria-label'?: AriaAttributes['aria-label']
23
+ /**
24
+ * For accessibility purposes, define a string that labels the left navigation icon button.
25
+ */
26
+ navigationButtonLeftAriaLabel?: AriaAttributes['aria-label']
27
+ /**
28
+ * For accessibility purposes, define a string that labels the right navigation button icon.
29
+ */
30
+ navigationButtonRightAriaLabel?: AriaAttributes['aria-label']
31
+ /**
32
+ * Event handler for clicks on each thumbnail.
33
+ */
34
+ onSelect: (imageIdx: number) => void
35
+ }
36
+
37
+ const SCROLL_MARGIN_VALUE = 400
38
+
39
+ const moveScroll = (container: HTMLDivElement | null, value: number) => {
40
+ if (container) {
41
+ if (container.scrollHeight > container.clientHeight) {
42
+ // TODO: Temporary workaround for scroll-behavior with scrollTop – Safari 15.4) https://developer.apple.com/forums/thread/703294
43
+ container.style.overflow = 'auto'
44
+ window.requestAnimationFrame(() =>
45
+ container.scrollTo({ top: value, behavior: 'smooth' })
46
+ )
47
+ setTimeout(() => (container.style.overflow = 'hidden'), 2000)
48
+ } else {
49
+ container.scrollLeft += value
50
+ }
51
+ }
52
+ }
53
+
54
+ const hasScroll = (container: HTMLDivElement | null): boolean => {
55
+ if (container) {
56
+ return (
57
+ container.scrollHeight > container.clientHeight ||
58
+ container.scrollWidth > container.clientWidth
59
+ )
60
+ }
61
+
62
+ return false
63
+ }
64
+
65
+ function ImageGallerySelector({
66
+ images,
67
+ onSelect,
68
+ ImageComponent,
69
+ currentImageIdx,
70
+ testId = 'fs-image-gallery-selector',
71
+ 'aria-label': ariaLabel = 'Product Images',
72
+ navigationButtonLeftAriaLabel = 'Backward slide image selector',
73
+ navigationButtonRightAriaLabel = 'Forward slide image selector',
74
+ }: ImageGallerySelectorProps) {
75
+ const elementsRef = useRef<HTMLDivElement>(null)
76
+ const elementHasScroll = hasScroll(elementsRef.current)
77
+ const [firstImageInView, setFirstImageInView] = useState(true)
78
+ const [lastImageInView, setLastImageInView] = useState(true)
79
+
80
+ const inViewChange= useCallback((idx: number, inView: boolean) => {
81
+ idx === 0 && setFirstImageInView(inView)
82
+ idx === images.length - 1 && setLastImageInView(inView)
83
+ }, [images.length])
84
+
85
+ return (
86
+ <section
87
+ data-fs-image-gallery-selector
88
+ data-testid={testId}
89
+ aria-label={ariaLabel}
90
+ aria-roledescription="carousel"
91
+ >
92
+ {elementHasScroll && !firstImageInView && (
93
+ <div data-fs-image-gallery-selector-control>
94
+ <IconButton
95
+ data-fs-image-gallery-selector-control-button
96
+ aria-label={navigationButtonLeftAriaLabel}
97
+ icon={<Icon name="ArrowLeft" />}
98
+ size="small"
99
+ onClick={() =>
100
+ moveScroll(elementsRef.current, -SCROLL_MARGIN_VALUE)
101
+ }
102
+ />
103
+ </div>
104
+ )}
105
+ <div data-fs-image-gallery-selector-elements ref={elementsRef}>
106
+ {images.map((image, idx) => {
107
+ return (
108
+ <InView
109
+ key={idx}
110
+ onChange={(inView) => inViewChange(idx, inView)}>
111
+ <Button
112
+ key={idx}
113
+ aria-label={`${image.alternateName} - Image ${idx + 1} of ${
114
+ images.length
115
+ }`}
116
+ onClick={() => onSelect(idx)}
117
+ data-fs-image-gallery-selector-thumbnail={
118
+ idx === currentImageIdx ? 'selected' : 'true'
119
+ }
120
+ >
121
+ <ImageComponent
122
+ url={image.url ?? ''}
123
+ loading={idx === 0 ? 'eager' : 'lazy'}
124
+ alternateName={image.alternateName ?? ''}
125
+ />
126
+ </Button>
127
+ </InView>
128
+ )
129
+ })}
130
+ </div>
131
+ {elementHasScroll && !lastImageInView && (
132
+ <div data-fs-image-gallery-selector-control>
133
+ <IconButton
134
+ data-fs-image-gallery-selector-control-button
135
+ aria-label={navigationButtonRightAriaLabel}
136
+ icon={<Icon name="ArrowLeft" />}
137
+ size="small"
138
+ onClick={() =>
139
+ moveScroll(elementsRef.current, +SCROLL_MARGIN_VALUE)
140
+ }
141
+ />
142
+ </div>
143
+ )}
144
+ </section>
145
+ )
146
+ }
147
+
148
+ export default ImageGallerySelector
@@ -0,0 +1,14 @@
1
+ import React from 'react'
2
+ import type { PropsWithChildren } from 'react'
3
+
4
+ // TODO: Implements zoom feature to the selected image (Coming Soon)
5
+ export interface ImageZoomProps {
6
+ helpMessage?: string
7
+ zoomFactor?: number
8
+ }
9
+
10
+ const ImageZoom = ({ children }: PropsWithChildren<ImageZoomProps>) => {
11
+ return <>{children}</>
12
+ }
13
+
14
+ export default ImageZoom
@@ -0,0 +1,8 @@
1
+ export { default } from './ImageGallery'
2
+ export type { ImageGalleryProps, ImageElementData } from './ImageGallery'
3
+
4
+ export { default as ImageGallerySelector } from './ImageGallerySelector'
5
+ export type { ImageGallerySelectorProps } from './ImageGallerySelector'
6
+
7
+ export { default as ImageZoom } from './ImageZoom'
8
+ export type { ImageZoomProps } from './ImageZoom'