@faststore/components 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/dist/atoms/Button/Button.js +1 -1
- package/dist/atoms/Button/Button.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/organisms/ImageGallery/ImageGallery.d.ts +42 -0
- package/dist/organisms/ImageGallery/ImageGallery.js +10 -0
- package/dist/organisms/ImageGallery/ImageGallery.js.map +1 -0
- package/dist/organisms/ImageGallery/ImageGallerySelector.d.ts +31 -0
- package/dist/organisms/ImageGallery/ImageGallerySelector.js +46 -0
- package/dist/organisms/ImageGallery/ImageGallerySelector.js.map +1 -0
- package/dist/organisms/ImageGallery/ImageZoom.d.ts +7 -0
- package/dist/organisms/ImageGallery/ImageZoom.js +6 -0
- package/dist/organisms/ImageGallery/ImageZoom.js.map +1 -0
- package/dist/organisms/ImageGallery/index.d.ts +6 -0
- package/dist/organisms/ImageGallery/index.js +4 -0
- package/dist/organisms/ImageGallery/index.js.map +1 -0
- package/package.json +2 -2
- package/src/atoms/Button/Button.tsx +1 -1
- package/src/index.ts +12 -0
- package/src/organisms/ImageGallery/ImageGallery.tsx +85 -0
- package/src/organisms/ImageGallery/ImageGallerySelector.tsx +148 -0
- package/src/organisms/ImageGallery/ImageZoom.tsx +14 -0
- package/src/organisms/ImageGallery/index.ts +8 -0
|
@@ -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;
|
|
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":"AAAA,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE5D,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAiChD,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAE/B,MAAM,UAAU,GAAG,CAAC,SAAgC,EAAE,KAAa,EAAE,EAAE;IACrE,IAAI,SAAS,EAAE;QACb,IAAI,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,YAAY,EAAE;YACnD,gIAAgI;YAChI,SAAS,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAA;YACjC,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAChC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CACvD,CAAA;YACD,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;SAC9D;aAAM;YACL,SAAS,CAAC,UAAU,IAAI,KAAK,CAAA;SAC9B;KACF;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,SAAgC,EAAW,EAAE;IAC9D,IAAI,SAAS,EAAE;QACb,OAAO,CACL,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,YAAY;YAC/C,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,WAAW,CAC9C,CAAA;KACF;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,SAAS,oBAAoB,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,cAAc,EACd,eAAe,EACf,MAAM,GAAG,2BAA2B,EACpC,YAAY,EAAE,SAAS,GAAG,gBAAgB,EAC1C,6BAA6B,GAAG,+BAA+B,EAC/D,8BAA8B,GAAG,8BAA8B,GACrC;IAC1B,MAAM,WAAW,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IAChD,MAAM,gBAAgB,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACvD,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9D,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAE5D,MAAM,YAAY,GAAE,WAAW,CAAC,CAAC,GAAW,EAAE,MAAe,EAAE,EAAE;QAC/D,GAAG,KAAK,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAA;QACxC,GAAG,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACzD,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAEnB,OAAO,CACL,wFAEe,MAAM,gBACP,SAAS,0BACA,UAAU;QAE9B,gBAAgB,IAAI,CAAC,gBAAgB,IAAI,CACxC;YACE,oBAAC,UAAU,yEAEG,6BAA6B,EACzC,IAAI,EAAE,oBAAC,IAAI,IAAC,IAAI,EAAC,WAAW,GAAG,EAC/B,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE,CACZ,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,mBAAmB,CAAC,GAEvD,CACE,CACP;QACD,8EAA6C,GAAG,EAAE,WAAW,IAC1D,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACzB,OAAO,CACL,oBAAC,MAAM,IACL,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC;gBAC/C,oBAAC,MAAM,IACL,GAAG,EAAE,GAAG,gBACI,GAAG,KAAK,CAAC,aAAa,YAAY,GAAG,GAAG,CAAC,OACnD,MAAM,CAAC,MACT,EAAE,EACF,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,8CAE1B,GAAG,KAAK,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;oBAG/C,oBAAC,cAAc,IACb,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,EAAE,EACpB,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EACrC,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,EAAE,GACxC,CACK,CACF,CACV,CAAA;QACH,CAAC,CAAC,CACE;QACL,gBAAgB,IAAI,CAAC,eAAe,IAAI,CACvC;YACE,oBAAC,UAAU,yEAEG,8BAA8B,EAC1C,IAAI,EAAE,oBAAC,IAAI,IAAC,IAAI,EAAC,WAAW,GAAG,EAC/B,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE,CACZ,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,mBAAmB,CAAC,GAEvD,CACE,CACP,CACO,CACX,CAAA;AACH,CAAC;AAED,eAAe,oBAAoB,CAAA"}
|
|
@@ -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 @@
|
|
|
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.
|
|
3
|
+
"version": "2.0.103-alpha.0",
|
|
4
4
|
"module": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
6
6
|
"author": "Emerson Laurentino @emersonlaurentino",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"node": "16.18.0",
|
|
31
31
|
"yarn": "1.19.1"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "cac804588d1f91794f39bf7b7ce8e18234a7286a"
|
|
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'
|