@envive-ai/react-toolkit 0.1.5 → 0.1.7
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/Accordion/index.cjs +84 -0
- package/dist/Accordion/index.d.cts +13 -0
- package/dist/Accordion/index.d.ts +13 -0
- package/dist/Accordion/index.js +77 -0
- package/dist/AppliedFiltersScrollbar/index.cjs +49 -0
- package/dist/AppliedFiltersScrollbar/index.d.cts +22 -0
- package/dist/AppliedFiltersScrollbar/index.d.ts +22 -0
- package/dist/AppliedFiltersScrollbar/index.js +44 -0
- package/dist/ButtonBase/index.cjs +2 -1
- package/dist/ButtonBase/index.d.cts +3 -3
- package/dist/ButtonBase/index.d.ts +1 -1
- package/dist/ButtonBase/index.js +2 -1
- package/dist/{ButtonBase-CpmFsiUf.js → ButtonBase-BIAu5fIG.js} +1 -1
- package/dist/ButtonBase-BRfuPPzN.js +1 -0
- package/dist/ButtonBase-BleAVeo-.cjs +0 -0
- package/dist/{ButtonBase-Dlh3bpR3.cjs → ButtonBase-DcyxOe2v.cjs} +2 -2
- package/dist/DynamicFiltersScrollbar/index.cjs +37 -0
- package/dist/DynamicFiltersScrollbar/index.d.cts +28 -0
- package/dist/DynamicFiltersScrollbar/index.d.ts +28 -0
- package/dist/DynamicFiltersScrollbar/index.js +32 -0
- package/dist/FilterScrollbar/index.cjs +1 -1
- package/dist/FilterScrollbar/index.d.cts +4 -4
- package/dist/FilterScrollbar/index.d.ts +4 -4
- package/dist/FilterScrollbar/index.js +1 -1
- package/dist/Headline/index.cjs +1 -1
- package/dist/Headline/index.d.cts +2 -2
- package/dist/Headline/index.js +1 -1
- package/dist/ImageWithFallback/index.cjs +1 -1
- package/dist/ImageWithFallback/index.d.ts +2 -2
- package/dist/ImageWithFallback/index.js +1 -1
- package/dist/{ImageWithFallback-By6QdlCR.cjs → ImageWithFallback-1LqhQK1q.cjs} +2 -2
- package/dist/{ImageWithFallback-DtUrq_bk.js → ImageWithFallback-Ckwsmd8P.js} +1 -1
- package/dist/ProductCard/index.cjs +7 -8
- package/dist/ProductCard/index.d.cts +2 -108
- package/dist/ProductCard/index.d.ts +2 -108
- package/dist/ProductCard/index.js +4 -5
- package/dist/{ProductCard-CvTRvhm7.cjs → ProductCard-DZZKutY-.cjs} +64 -5
- package/dist/{ProductCard-aJbQz6Q7.js → ProductCard-SF8-lXlT.js} +46 -6
- package/dist/ProductGrid/index.cjs +5 -5
- package/dist/ProductGrid/index.d.cts +6 -6
- package/dist/ProductGrid/index.d.ts +6 -6
- package/dist/ProductGrid/index.js +5 -5
- package/dist/{ProductGrid-CSIH2_G9.cjs → ProductGrid-BSSmPr7K.cjs} +48 -46
- package/dist/{ProductGrid-NOCayW9O.js → ProductGrid-DTUhH219.js} +48 -46
- package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.cjs +1 -1
- package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.d.cts +1 -1
- package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.d.ts +1 -1
- package/dist/SearchAutocomplete/index.js +3 -0
- package/dist/{SearchAutocomplete-DCu9-Yfk.js → SearchAutocomplete-BPjlo6qq.js} +4 -4
- package/dist/{SearchAutocomplete-CQxxe5Op.cjs → SearchAutocomplete-BzaEXmRQ.cjs} +8 -8
- package/dist/SearchFilter/index.cjs +5 -5
- package/dist/SearchFilter/index.d.cts +1 -34
- package/dist/SearchFilter/index.d.ts +1 -34
- package/dist/SearchFilter/index.js +2 -2
- package/dist/{SearchFilterHeader-qkRVfAB5.cjs → SearchFilter-B15tybnV.cjs} +1 -1
- package/dist/{SearchFilterHeader-BDEcDc_4.js → SearchFilter-D427M2UE.js} +1 -1
- package/dist/SearchInput/index.cjs +3 -3
- package/dist/SearchInput/index.d.cts +4 -4
- package/dist/SearchInput/index.d.ts +5 -5
- package/dist/SearchInput/index.js +3 -3
- package/dist/{SearchInput-DxGvYGZO.js → SearchInput-C0wB4hSV.js} +6 -6
- package/dist/{SearchInput-Cdpwswyv.cjs → SearchInput-D6UW79wT.cjs} +10 -10
- package/dist/SearchInputForm/index.cjs +6 -5
- package/dist/SearchInputForm/index.d.cts +1 -31
- package/dist/SearchInputForm/index.d.ts +1 -31
- package/dist/SearchInputForm/index.js +6 -5
- package/dist/SearchResultsContent/index.cjs +64 -0
- package/dist/SearchResultsContent/index.d.cts +67 -0
- package/dist/SearchResultsContent/index.d.ts +67 -0
- package/dist/SearchResultsContent/index.js +60 -0
- package/dist/SearchResultsFilterSidebar/index.cjs +10 -6
- package/dist/SearchResultsFilterSidebar/index.d.cts +3 -44
- package/dist/SearchResultsFilterSidebar/index.d.ts +3 -44
- package/dist/SearchResultsFilterSidebar/index.js +7 -4
- package/dist/SearchResultsStates/index.cjs +15 -125
- package/dist/SearchResultsStates/index.d.cts +14 -7
- package/dist/SearchResultsStates/index.d.ts +14 -7
- package/dist/SearchResultsStates/index.js +12 -117
- package/dist/SearchResultsStates-CNp6YCqF.js +112 -0
- package/dist/SearchResultsStates-Du7HXBi8.cjs +135 -0
- package/dist/SparkleAnimation/index.cjs +1 -1
- package/dist/SparkleAnimation/index.d.cts +2 -2
- package/dist/SparkleAnimation/index.d.ts +2 -2
- package/dist/SparkleAnimation/index.js +1 -1
- package/dist/{SparkleAnimation-DfMCtvAQ.js → SparkleAnimation-B0u6JtO3.js} +2 -2
- package/dist/{SparkleAnimation-j-mAMEZZ.cjs → SparkleAnimation-D1QpGZIg.cjs} +4 -4
- package/dist/Spinner/index.cjs +1 -1
- package/dist/Spinner/index.d.cts +2 -2
- package/dist/Spinner/index.js +1 -1
- package/dist/SuggestionButton/index.cjs +3 -3
- package/dist/SuggestionButton/index.d.cts +3 -3
- package/dist/SuggestionButton/index.d.ts +3 -3
- package/dist/SuggestionButton/index.js +2 -2
- package/dist/Text/index.cjs +2 -10
- package/dist/Text/index.d.cts +2 -2
- package/dist/Text/index.d.ts +3 -3
- package/dist/Text/index.js +1 -9
- package/dist/Text-DkwDPbHy.js +10 -0
- package/dist/Text-Ji61nRRE.cjs +16 -0
- package/dist/TextInput/index.cjs +1 -1
- package/dist/TextInput/index.d.ts +1 -1
- package/dist/TextInput/index.js +1 -1
- package/dist/{TextInput-CObd_Wcw.cjs → TextInput-C6fF9cSB.cjs} +2 -2
- package/dist/{TextInput-ChPhL54o.js → TextInput-CRMqBW3X.js} +1 -1
- package/dist/index-14eDYe9f.d.ts +58 -0
- package/dist/{types-Dvgr3ZeV.d.cts → index-B3iEVxkL.d.cts} +108 -23
- package/dist/index-B8bifyF-.d.ts +36 -0
- package/dist/index-BFdFh46m.d.cts +58 -0
- package/dist/{types-B7hf-Lif.d.ts → index-ByucvlTy.d.ts} +108 -23
- package/dist/index-C2iKBk7w.d.cts +36 -0
- package/dist/index-DLbdcczl.d.ts +78 -0
- package/dist/index-DlvTcfAg.d.cts +78 -0
- package/dist/{searchFilterSidebarVariants-C_UTEIpZ.js → searchFilterSidebarVariants-CZT1frB-.js} +1 -1
- package/dist/{searchFilterSidebarVariants-DcQLi_TT.cjs → searchFilterSidebarVariants-xyhy0PmQ.cjs} +1 -1
- package/package.json +22 -5
- package/src/components/Accordion/Accordion.tsx +90 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AppliedFiltersScrollbar/AppliedFiltersScrollbar.tsx +70 -0
- package/src/components/AppliedFiltersScrollbar/index.ts +1 -0
- package/src/components/DynamicFiltersScrollbar/DynamicFiltersScrollbar.tsx +52 -0
- package/src/components/DynamicFiltersScrollbar/index.ts +1 -0
- package/src/components/ProductCard/ProductCard.tsx +34 -17
- package/src/components/ProductCard/types.ts +1 -1
- package/src/components/ProductGrid/ProductGrid.tsx +33 -33
- package/src/components/{SearchInputAutocomplete → SearchAutocomplete}/SearchAutocomplete.tsx +1 -1
- package/src/components/SearchInput/SearchInput.tsx +6 -6
- package/src/components/SearchInput/searchInputVariants.ts +5 -5
- package/src/components/SearchInputForm/SearchInputForm.tsx +6 -4
- package/src/components/SearchResultsContent/SearchResultsContent.tsx +87 -0
- package/src/components/SearchResultsContent/index.ts +2 -0
- package/src/components/SearchResultsContent/utils.ts +28 -0
- package/src/components/SearchResultsFilterSidebar/SearchResultsFilter.tsx +5 -6
- package/src/components/SearchResultsFilterSidebar/types.ts +14 -1
- package/src/components/SearchResultsStates/NoSearchResultsFound.tsx +2 -2
- package/src/components/SearchResultsStates/SearchResultsGrid.tsx +14 -12
- package/src/components/SearchResultsStates/SearchResultsLoadingGrid.tsx +4 -5
- package/dist/ProductCardSkeleton-B6YetUCT.js +0 -43
- package/dist/ProductCardSkeleton-BzBK36m-.cjs +0 -63
- package/dist/SearchInputAutocomplete/index.js +0 -3
- package/dist/types-5luH4G-3.d.cts +0 -5
- package/dist/types-BCAU5OQD.d.cts +0 -46
- package/dist/types-BIPqyTOJ.d.ts +0 -5
- package/dist/types-BwPquD10.d.ts +0 -46
- package/dist/types-CosVh8Hj.d.cts +0 -4
- package/dist/types-nR3jHgIO.d.ts +0 -4
- package/src/types/external.ts +0 -24
- /package/dist/{DynamicFiltersScrollbar-D8Lms7Ox.cjs → DynamicFiltersScrollbar-BTopFhyl.cjs} +0 -0
- /package/dist/{DynamicFiltersScrollbar-t_JASmYC.js → DynamicFiltersScrollbar-BmPTqym5.js} +0 -0
- /package/dist/{Headline-COAnonc2.js → Headline-XpaAeTSR.js} +0 -0
- /package/dist/{Headline-CdddUGwy.cjs → Headline-iP_MckEO.cjs} +0 -0
- /package/dist/{Spinner-D9kkaM9d.js → Spinner-BgGihEfJ.js} +0 -0
- /package/dist/{Spinner-DX35Epv3.cjs → Spinner-DzdIkS6t.cjs} +0 -0
- /package/dist/{colorsConfig-CKiMYHO_.js → colorsConfig-BQlaCfxi.js} +0 -0
- /package/dist/{colorsConfig-DulwYRIk.cjs → colorsConfig-DCvy_dV4.cjs} +0 -0
- /package/dist/{textVariantClasses-sT9E8Uty.d.ts → textVariantClasses-C8OCWZAw.d.ts} +0 -0
- /package/dist/{types-B19i3fxM.d.ts → types-Bm-qQyO3.d.ts} +0 -0
- /package/dist/{types-BQYpWDJ4.d.cts → types-C0UWKVvw.d.ts} +0 -0
- /package/dist/{types-C-Jrlw5Z.d.cts → types-CZHc-1wI.d.cts} +0 -0
- /package/dist/{types-DpfHwTzY.d.ts → types-D2xCS4y9.d.cts} +0 -0
- /package/src/components/{SearchInputAutocomplete → SearchAutocomplete}/index.ts +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/components/SearchFilter/types.d.ts
|
|
5
|
+
type SearchFilterItem$1 = {
|
|
6
|
+
id: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
value: string;
|
|
9
|
+
isSelected: boolean;
|
|
10
|
+
};
|
|
11
|
+
type SearchFilter$1 = {
|
|
12
|
+
id: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
items: SearchFilterItem$1[];
|
|
15
|
+
};
|
|
16
|
+
type SelectFilterItem = (filterItem: SearchFilterItem$1) => void;
|
|
17
|
+
interface SearchFilterItemProps {
|
|
18
|
+
filterItem: SearchFilterItem$1;
|
|
19
|
+
onSelectFilterItem: SelectFilterItem;
|
|
20
|
+
radioButtonFillColor: string;
|
|
21
|
+
radioButtonHoverColor: string;
|
|
22
|
+
radioButtonUncheckedBorderColor: string;
|
|
23
|
+
}
|
|
24
|
+
interface SearchFilterHeaderProps {
|
|
25
|
+
closeModal: () => void;
|
|
26
|
+
productCount: number;
|
|
27
|
+
headerClassName: string;
|
|
28
|
+
filterCloseIconVariant: 'dark' | 'light' | 'tertiary';
|
|
29
|
+
}
|
|
30
|
+
interface SearchFilterProps {
|
|
31
|
+
isOpen: boolean;
|
|
32
|
+
setIsOpen: (isOpen: boolean) => void;
|
|
33
|
+
filters: SearchFilter$1[];
|
|
34
|
+
productCount: number;
|
|
35
|
+
selectFilterItem: SelectFilterItem;
|
|
36
|
+
clearAllFilters: () => void;
|
|
37
|
+
applyFiltersUnchangedClasses: string;
|
|
38
|
+
applyFiltersChangedClasses: string;
|
|
39
|
+
filterButtonText: string;
|
|
40
|
+
radioButtonFillColor: string;
|
|
41
|
+
radioButtonHoverColor: string;
|
|
42
|
+
radioButtonUncheckedBorderColor: string;
|
|
43
|
+
filterCloseIconVariant: 'dark' | 'light' | 'tertiary';
|
|
44
|
+
headerContent: ReactNode;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/components/SearchFilter/SearchFilter.d.ts
|
|
48
|
+
declare const SearchFilter: ({
|
|
49
|
+
isOpen,
|
|
50
|
+
setIsOpen,
|
|
51
|
+
filters,
|
|
52
|
+
selectFilterItem,
|
|
53
|
+
clearAllFilters,
|
|
54
|
+
filterButtonText,
|
|
55
|
+
radioButtonFillColor,
|
|
56
|
+
radioButtonHoverColor,
|
|
57
|
+
radioButtonUncheckedBorderColor,
|
|
58
|
+
headerContent
|
|
59
|
+
}: SearchFilterProps) => react_jsx_runtime9.JSX.Element;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/components/SearchFilter/SearchFilterHeader.d.ts
|
|
62
|
+
declare const SearchFilterHeader: ({
|
|
63
|
+
closeModal,
|
|
64
|
+
productCount,
|
|
65
|
+
headerClassName,
|
|
66
|
+
filterCloseIconVariant
|
|
67
|
+
}: SearchFilterHeaderProps) => react_jsx_runtime9.JSX.Element;
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/components/SearchFilter/SearchFilterItem.d.ts
|
|
70
|
+
declare const SearchFilterItem: ({
|
|
71
|
+
filterItem,
|
|
72
|
+
onSelectFilterItem,
|
|
73
|
+
radioButtonFillColor,
|
|
74
|
+
radioButtonHoverColor,
|
|
75
|
+
radioButtonUncheckedBorderColor
|
|
76
|
+
}: SearchFilterItemProps) => react_jsx_runtime9.JSX.Element;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { SearchFilter, SearchFilterHeader, SearchFilterHeaderProps, SearchFilterItem, SearchFilterItemProps, SearchFilterProps, SelectFilterItem };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as react_jsx_runtime15 from "react/jsx-runtime";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/SearchFilter/types.d.ts
|
|
5
|
+
type SearchFilterItem$1 = {
|
|
6
|
+
id: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
value: string;
|
|
9
|
+
isSelected: boolean;
|
|
10
|
+
};
|
|
11
|
+
type SearchFilter$1 = {
|
|
12
|
+
id: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
items: SearchFilterItem$1[];
|
|
15
|
+
};
|
|
16
|
+
type SelectFilterItem = (filterItem: SearchFilterItem$1) => void;
|
|
17
|
+
interface SearchFilterItemProps {
|
|
18
|
+
filterItem: SearchFilterItem$1;
|
|
19
|
+
onSelectFilterItem: SelectFilterItem;
|
|
20
|
+
radioButtonFillColor: string;
|
|
21
|
+
radioButtonHoverColor: string;
|
|
22
|
+
radioButtonUncheckedBorderColor: string;
|
|
23
|
+
}
|
|
24
|
+
interface SearchFilterHeaderProps {
|
|
25
|
+
closeModal: () => void;
|
|
26
|
+
productCount: number;
|
|
27
|
+
headerClassName: string;
|
|
28
|
+
filterCloseIconVariant: 'dark' | 'light' | 'tertiary';
|
|
29
|
+
}
|
|
30
|
+
interface SearchFilterProps {
|
|
31
|
+
isOpen: boolean;
|
|
32
|
+
setIsOpen: (isOpen: boolean) => void;
|
|
33
|
+
filters: SearchFilter$1[];
|
|
34
|
+
productCount: number;
|
|
35
|
+
selectFilterItem: SelectFilterItem;
|
|
36
|
+
clearAllFilters: () => void;
|
|
37
|
+
applyFiltersUnchangedClasses: string;
|
|
38
|
+
applyFiltersChangedClasses: string;
|
|
39
|
+
filterButtonText: string;
|
|
40
|
+
radioButtonFillColor: string;
|
|
41
|
+
radioButtonHoverColor: string;
|
|
42
|
+
radioButtonUncheckedBorderColor: string;
|
|
43
|
+
filterCloseIconVariant: 'dark' | 'light' | 'tertiary';
|
|
44
|
+
headerContent: ReactNode;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/components/SearchFilter/SearchFilter.d.ts
|
|
48
|
+
declare const SearchFilter: ({
|
|
49
|
+
isOpen,
|
|
50
|
+
setIsOpen,
|
|
51
|
+
filters,
|
|
52
|
+
selectFilterItem,
|
|
53
|
+
clearAllFilters,
|
|
54
|
+
filterButtonText,
|
|
55
|
+
radioButtonFillColor,
|
|
56
|
+
radioButtonHoverColor,
|
|
57
|
+
radioButtonUncheckedBorderColor,
|
|
58
|
+
headerContent
|
|
59
|
+
}: SearchFilterProps) => react_jsx_runtime15.JSX.Element;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/components/SearchFilter/SearchFilterHeader.d.ts
|
|
62
|
+
declare const SearchFilterHeader: ({
|
|
63
|
+
closeModal,
|
|
64
|
+
productCount,
|
|
65
|
+
headerClassName,
|
|
66
|
+
filterCloseIconVariant
|
|
67
|
+
}: SearchFilterHeaderProps) => react_jsx_runtime15.JSX.Element;
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/components/SearchFilter/SearchFilterItem.d.ts
|
|
70
|
+
declare const SearchFilterItem: ({
|
|
71
|
+
filterItem,
|
|
72
|
+
onSelectFilterItem,
|
|
73
|
+
radioButtonFillColor,
|
|
74
|
+
radioButtonHoverColor,
|
|
75
|
+
radioButtonUncheckedBorderColor
|
|
76
|
+
}: SearchFilterItemProps) => react_jsx_runtime15.JSX.Element;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { SearchFilter, SearchFilterHeader, SearchFilterHeaderProps, SearchFilterItem, SearchFilterItemProps, SearchFilterProps, SelectFilterItem };
|
package/dist/{searchFilterSidebarVariants-DcQLi_TT.cjs → searchFilterSidebarVariants-xyhy0PmQ.cjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_colorsConfig = require('./colorsConfig-
|
|
1
|
+
const require_colorsConfig = require('./colorsConfig-DCvy_dV4.cjs');
|
|
2
2
|
|
|
3
3
|
//#region src/components/SearchResultsFilterSidebar/searchFilterSidebarVariants.ts
|
|
4
4
|
const searchFilterSidebarVariantClasses = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envive-ai/react-toolkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "React component library for Envive services.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"prepublish": "npm run build"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@envive-ai/react-hooks": "^0.1.1",
|
|
27
28
|
"@envive-ai/react-icons": "0.1.1",
|
|
28
29
|
"classnames": "^2.5.1",
|
|
29
30
|
"framer-motion": "^12.23.12",
|
|
@@ -39,10 +40,22 @@
|
|
|
39
40
|
"typescript": "~5.8.3"
|
|
40
41
|
},
|
|
41
42
|
"exports": {
|
|
43
|
+
"./Accordion": {
|
|
44
|
+
"import": "./dist/Accordion/index.js",
|
|
45
|
+
"require": "./dist/Accordion/index.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./AppliedFiltersScrollbar": {
|
|
48
|
+
"import": "./dist/AppliedFiltersScrollbar/index.js",
|
|
49
|
+
"require": "./dist/AppliedFiltersScrollbar/index.cjs"
|
|
50
|
+
},
|
|
42
51
|
"./ButtonBase": {
|
|
43
52
|
"import": "./dist/ButtonBase/index.js",
|
|
44
53
|
"require": "./dist/ButtonBase/index.cjs"
|
|
45
54
|
},
|
|
55
|
+
"./DynamicFiltersScrollbar": {
|
|
56
|
+
"import": "./dist/DynamicFiltersScrollbar/index.js",
|
|
57
|
+
"require": "./dist/DynamicFiltersScrollbar/index.cjs"
|
|
58
|
+
},
|
|
46
59
|
"./FilterScrollbar": {
|
|
47
60
|
"import": "./dist/FilterScrollbar/index.js",
|
|
48
61
|
"require": "./dist/FilterScrollbar/index.cjs"
|
|
@@ -63,6 +76,10 @@
|
|
|
63
76
|
"import": "./dist/ProductGrid/index.js",
|
|
64
77
|
"require": "./dist/ProductGrid/index.cjs"
|
|
65
78
|
},
|
|
79
|
+
"./SearchAutocomplete": {
|
|
80
|
+
"import": "./dist/SearchAutocomplete/index.js",
|
|
81
|
+
"require": "./dist/SearchAutocomplete/index.cjs"
|
|
82
|
+
},
|
|
66
83
|
"./SearchFilter": {
|
|
67
84
|
"import": "./dist/SearchFilter/index.js",
|
|
68
85
|
"require": "./dist/SearchFilter/index.cjs"
|
|
@@ -71,14 +88,14 @@
|
|
|
71
88
|
"import": "./dist/SearchInput/index.js",
|
|
72
89
|
"require": "./dist/SearchInput/index.cjs"
|
|
73
90
|
},
|
|
74
|
-
"./SearchInputAutocomplete": {
|
|
75
|
-
"import": "./dist/SearchInputAutocomplete/index.js",
|
|
76
|
-
"require": "./dist/SearchInputAutocomplete/index.cjs"
|
|
77
|
-
},
|
|
78
91
|
"./SearchInputForm": {
|
|
79
92
|
"import": "./dist/SearchInputForm/index.js",
|
|
80
93
|
"require": "./dist/SearchInputForm/index.cjs"
|
|
81
94
|
},
|
|
95
|
+
"./SearchResultsContent": {
|
|
96
|
+
"import": "./dist/SearchResultsContent/index.js",
|
|
97
|
+
"require": "./dist/SearchResultsContent/index.cjs"
|
|
98
|
+
},
|
|
82
99
|
"./SearchResultsFilterSidebar": {
|
|
83
100
|
"import": "./dist/SearchResultsFilterSidebar/index.js",
|
|
84
101
|
"require": "./dist/SearchResultsFilterSidebar/index.cjs"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { motion } from 'framer-motion';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { Text } from '@envive-ai/react-toolkit/Text';
|
|
5
|
+
import ChevronDown from '@envive-ai/react-icons/ChevronDown';
|
|
6
|
+
|
|
7
|
+
interface AccordionProps {
|
|
8
|
+
title: string;
|
|
9
|
+
content: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ANIMATION_DURATION = 0.3;
|
|
13
|
+
|
|
14
|
+
export const Accordion = ({ title, content }: AccordionProps) => {
|
|
15
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
16
|
+
|
|
17
|
+
const contentRef = useRef<HTMLDivElement>(null);
|
|
18
|
+
|
|
19
|
+
const titleWrapperClasses = classNames({
|
|
20
|
+
'spiffy-tw-border-b': true,
|
|
21
|
+
'spiffy-tw-border-[--spiffy-colors-border-light]': true,
|
|
22
|
+
'spiffy-tw-pb-2': true,
|
|
23
|
+
'spiffy-tw-flex': true,
|
|
24
|
+
'spiffy-tw-justify-between': true,
|
|
25
|
+
'spiffy-tw-items-center': true,
|
|
26
|
+
'spiffy-tw-w-full': true,
|
|
27
|
+
'spiffy-tw-group': true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const titleClasses = classNames({
|
|
31
|
+
'spiffy-tw-uppercase': true,
|
|
32
|
+
'spiffy-tw-text-[--spiffy-colors-text-primary]': true,
|
|
33
|
+
'!spiffy-tw-font-[400]': true,
|
|
34
|
+
'group-aria-expanded:!spiffy-tw-font-medium': true,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const contentClasses = classNames({
|
|
38
|
+
'spiffy-tw-overflow-hidden': true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<button
|
|
44
|
+
aria-expanded={isOpen}
|
|
45
|
+
type="button"
|
|
46
|
+
className={titleWrapperClasses}
|
|
47
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
48
|
+
>
|
|
49
|
+
<Text variant="body4" className={titleClasses}>
|
|
50
|
+
{title}
|
|
51
|
+
</Text>
|
|
52
|
+
<motion.div
|
|
53
|
+
variants={{
|
|
54
|
+
open: {
|
|
55
|
+
rotate: 180,
|
|
56
|
+
},
|
|
57
|
+
closed: {
|
|
58
|
+
rotate: 360,
|
|
59
|
+
},
|
|
60
|
+
}}
|
|
61
|
+
animate={isOpen ? 'open' : 'closed'}
|
|
62
|
+
transition={{ duration: ANIMATION_DURATION, ease: 'easeOut' }}
|
|
63
|
+
>
|
|
64
|
+
<ChevronDown />
|
|
65
|
+
</motion.div>
|
|
66
|
+
</button>
|
|
67
|
+
<motion.div
|
|
68
|
+
variants={{
|
|
69
|
+
open: {
|
|
70
|
+
height: 'auto',
|
|
71
|
+
marginTop: '24px',
|
|
72
|
+
marginBottom: '24px',
|
|
73
|
+
},
|
|
74
|
+
closed: {
|
|
75
|
+
height: '0px',
|
|
76
|
+
marginTop: '0px',
|
|
77
|
+
marginBottom: '0px',
|
|
78
|
+
},
|
|
79
|
+
}}
|
|
80
|
+
className={contentClasses}
|
|
81
|
+
initial={{ height: 0 }}
|
|
82
|
+
animate={isOpen ? 'open' : 'closed'}
|
|
83
|
+
transition={{ duration: ANIMATION_DURATION, ease: 'easeOut' }}
|
|
84
|
+
ref={contentRef}
|
|
85
|
+
>
|
|
86
|
+
{content}
|
|
87
|
+
</motion.div>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Accordion';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import ScrollContainer from 'react-indiana-drag-scroll';
|
|
3
|
+
import { SelectedFilterOption } from 'src/atoms/search/types';
|
|
4
|
+
import { Text } from '@envive-ai/react-toolkit/Text';
|
|
5
|
+
|
|
6
|
+
interface AppliedFiltersScrollbarProps {
|
|
7
|
+
selectedFilterOptions: SelectedFilterOption[];
|
|
8
|
+
filterBarClassNames: string;
|
|
9
|
+
filterDefaultClasses: string;
|
|
10
|
+
filterHoverClasses: string;
|
|
11
|
+
appliedFilterBackgroundClasses: string;
|
|
12
|
+
onRemoveFilter: (filter: SelectedFilterOption) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const AppliedFiltersScrollbar = ({
|
|
16
|
+
selectedFilterOptions,
|
|
17
|
+
filterBarClassNames,
|
|
18
|
+
filterDefaultClasses,
|
|
19
|
+
filterHoverClasses,
|
|
20
|
+
appliedFilterBackgroundClasses,
|
|
21
|
+
onRemoveFilter,
|
|
22
|
+
}: AppliedFiltersScrollbarProps) => {
|
|
23
|
+
if (selectedFilterOptions.length === 0) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Extract border and text classes from filterDefaultClasses, excluding background because everything is shared between filters except for the applied filters background
|
|
28
|
+
const filterDefaultWithoutBg = filterDefaultClasses
|
|
29
|
+
.replace(/spiffy-tw-bg-\[--spiffy-colors-[^\]]+\]/g, '')
|
|
30
|
+
.trim();
|
|
31
|
+
const buttonClasses = classNames(
|
|
32
|
+
' spiffy-tw-flex spiffy-tw-items-center spiffy-tw-rounded-full spiffy-tw-px-[8px] spiffy-tw-py-[4px] spiffy-tw-whitespace-nowrap',
|
|
33
|
+
filterHoverClasses,
|
|
34
|
+
filterDefaultWithoutBg,
|
|
35
|
+
appliedFilterBackgroundClasses,
|
|
36
|
+
);
|
|
37
|
+
const iconColor = 'currentColor'; // match with text color
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<ScrollContainer className={filterBarClassNames} hideScrollbars>
|
|
41
|
+
{selectedFilterOptions.map((filter) => {
|
|
42
|
+
return (
|
|
43
|
+
<button
|
|
44
|
+
key={filter.id}
|
|
45
|
+
className={buttonClasses}
|
|
46
|
+
type="button"
|
|
47
|
+
onClick={() => onRemoveFilter(filter)}
|
|
48
|
+
aria-label={`Remove filter: ${filter.displayName}`}
|
|
49
|
+
>
|
|
50
|
+
<div className="spiffy-tw-flex spiffy-tw-items-center spiffy-tw-gap-[8px]">
|
|
51
|
+
<Text variant="body3">{filter.displayName}</Text>
|
|
52
|
+
<svg
|
|
53
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
54
|
+
width="10"
|
|
55
|
+
height="10"
|
|
56
|
+
viewBox="0 0 10 10"
|
|
57
|
+
fill="none"
|
|
58
|
+
>
|
|
59
|
+
<path
|
|
60
|
+
d="M4.59766 4.29297L8.48535 0.405273L9.19238 1.1123L5.30469 5L9.19238 8.8877L8.48535 9.59473L4.59766 5.70703L0.707031 9.59766L0 8.89062L3.89062 5L0 1.10938L0.707031 0.402344L4.59766 4.29297Z"
|
|
61
|
+
fill={iconColor}
|
|
62
|
+
/>
|
|
63
|
+
</svg>
|
|
64
|
+
</div>
|
|
65
|
+
</button>
|
|
66
|
+
);
|
|
67
|
+
})}
|
|
68
|
+
</ScrollContainer>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AppliedFiltersScrollbar';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import ScrollContainer from 'react-indiana-drag-scroll';
|
|
3
|
+
import { Text } from '@envive-ai/react-toolkit/Text';
|
|
4
|
+
|
|
5
|
+
interface DynamicFiltersScrollbarProps {
|
|
6
|
+
availableDynamicFilters: { name: string; displayName: string }[];
|
|
7
|
+
filterBarClassNames: string;
|
|
8
|
+
filterDefaultClasses: string;
|
|
9
|
+
filterHoverClasses: string;
|
|
10
|
+
onToggleDynamicFilter: ({
|
|
11
|
+
filter,
|
|
12
|
+
dynamicFilterDisplayName,
|
|
13
|
+
}: {
|
|
14
|
+
filter: string;
|
|
15
|
+
dynamicFilterDisplayName: string;
|
|
16
|
+
}) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const DynamicFiltersScrollbar = ({
|
|
20
|
+
availableDynamicFilters,
|
|
21
|
+
filterBarClassNames,
|
|
22
|
+
filterDefaultClasses,
|
|
23
|
+
filterHoverClasses,
|
|
24
|
+
onToggleDynamicFilter,
|
|
25
|
+
}: DynamicFiltersScrollbarProps) => {
|
|
26
|
+
return (
|
|
27
|
+
<ScrollContainer className={filterBarClassNames} hideScrollbars>
|
|
28
|
+
{availableDynamicFilters.map(({ name, displayName }) => {
|
|
29
|
+
const buttonClasses = classNames(
|
|
30
|
+
'spiffy-tw-px-[12px] spiffy-tw-py-2 spiffy-tw-rounded-full spiffy-tw-border spiffy-tw-whitespace-nowrap ',
|
|
31
|
+
filterHoverClasses,
|
|
32
|
+
filterDefaultClasses,
|
|
33
|
+
);
|
|
34
|
+
return (
|
|
35
|
+
<button
|
|
36
|
+
key={name}
|
|
37
|
+
type="button"
|
|
38
|
+
className={buttonClasses}
|
|
39
|
+
onClick={() => {
|
|
40
|
+
onToggleDynamicFilter({
|
|
41
|
+
filter: name,
|
|
42
|
+
dynamicFilterDisplayName: displayName,
|
|
43
|
+
});
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<Text variant="body3">{displayName}</Text>
|
|
47
|
+
</button>
|
|
48
|
+
);
|
|
49
|
+
})}
|
|
50
|
+
</ScrollContainer>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DynamicFiltersScrollbar';
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
2
|
import { MdStar } from 'react-icons/md';
|
|
3
|
-
import { Text } from 'src/components/Text/Text';
|
|
4
3
|
import {
|
|
5
4
|
variantClassMap,
|
|
6
5
|
variantHoverClassMap,
|
|
7
6
|
productCardLayoutVariantClasses,
|
|
8
7
|
variantTitleColorMap,
|
|
9
8
|
} from './productCardVariants';
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
9
|
+
import { ChatElementDisplayLocation } from 'src/config/chatElementDisplayLocation';
|
|
10
|
+
import Logger from 'src/logging/logger';
|
|
11
|
+
import { TestProps } from 'src/test/types';
|
|
12
|
+
import { Headline } from '../Headline';
|
|
13
|
+
import { ImageWithFallback } from '../ImageWithFallback';
|
|
14
|
+
import { Spinner } from '../Spinner';
|
|
15
|
+
import {
|
|
13
16
|
ProductCardConfig,
|
|
17
|
+
ProductCardVariant,
|
|
14
18
|
ProductCardHoverVariant,
|
|
15
19
|
ProductCardLayoutVariant,
|
|
16
|
-
ProductCardVariant,
|
|
17
20
|
} from './types';
|
|
18
|
-
import
|
|
19
|
-
import type { ChatElementDisplayLocation } from 'src/config/chatElementDisplayLocation';
|
|
20
|
-
import Logger from 'src/logging/logger';
|
|
21
|
-
import { Spinner } from '../Spinner/Spinner';
|
|
21
|
+
import { Text } from 'src/components/Text/Text';
|
|
22
22
|
import { formatPrice } from 'src/util/formatPrice';
|
|
23
|
+
import { useImageResolver } from '@envive-ai/react-hooks/hooks';
|
|
23
24
|
|
|
24
25
|
const formatReviews = (stars: number) =>
|
|
25
26
|
String(
|
|
@@ -95,11 +96,26 @@ export const PriceSection = ({ originalPrice, salePrice, pricePrefix }: PriceSec
|
|
|
95
96
|
);
|
|
96
97
|
};
|
|
97
98
|
|
|
99
|
+
// export const formatPrice = (price?: number, currency: string = '$'): string => {
|
|
100
|
+
// if (price == null) {
|
|
101
|
+
// return '';
|
|
102
|
+
// }
|
|
103
|
+
|
|
104
|
+
// const options: Intl.NumberFormatOptions = {};
|
|
105
|
+
|
|
106
|
+
// if (!Number.isInteger(price)) {
|
|
107
|
+
// options.minimumFractionDigits = 2;
|
|
108
|
+
// options.maximumFractionDigits = 2;
|
|
109
|
+
// }
|
|
110
|
+
|
|
111
|
+
// return `${currency}${price.toLocaleString('en-US', options)}`;
|
|
112
|
+
// };
|
|
113
|
+
|
|
98
114
|
interface ProductCardProps extends TestProps {
|
|
99
115
|
productCardConfig?: ProductCardConfig;
|
|
100
116
|
merchantShortName: string;
|
|
101
117
|
title: string;
|
|
102
|
-
url
|
|
118
|
+
url: string;
|
|
103
119
|
searchResponseId?: string;
|
|
104
120
|
productResponseId?: string;
|
|
105
121
|
cardDisplayLocation: ChatElementDisplayLocation.IN_CHAT | ChatElementDisplayLocation.PRODUCT_GRID;
|
|
@@ -115,7 +131,7 @@ interface ProductCardProps extends TestProps {
|
|
|
115
131
|
aspectRatio?: '3:4' | 'square' | 'none';
|
|
116
132
|
clickPosition?: number | null;
|
|
117
133
|
growWithContainer?: boolean;
|
|
118
|
-
handleClick
|
|
134
|
+
handleClick?: (clickedUrl: string) => void;
|
|
119
135
|
}
|
|
120
136
|
|
|
121
137
|
export const ProductCard = ({
|
|
@@ -124,6 +140,8 @@ export const ProductCard = ({
|
|
|
124
140
|
imageUrl,
|
|
125
141
|
title,
|
|
126
142
|
url,
|
|
143
|
+
// searchResponseId,
|
|
144
|
+
// productResponseId,
|
|
127
145
|
originalPrice,
|
|
128
146
|
averageRating,
|
|
129
147
|
numberReviews,
|
|
@@ -132,13 +150,14 @@ export const ProductCard = ({
|
|
|
132
150
|
hoverVariant,
|
|
133
151
|
dataTestId,
|
|
134
152
|
layoutVariant = 'normal',
|
|
153
|
+
// cardDisplayLocation,
|
|
135
154
|
zoomOnHover = false,
|
|
136
155
|
aspectRatio = 'none',
|
|
156
|
+
// clickPosition = null,
|
|
137
157
|
growWithContainer = false,
|
|
138
158
|
handleClick,
|
|
139
159
|
}: ProductCardProps) => {
|
|
140
|
-
|
|
141
|
-
// const { productCardConfig } = orgUIConfig;
|
|
160
|
+
const { resolve } = useImageResolver();
|
|
142
161
|
|
|
143
162
|
const finalVariant = variant ?? productCardConfig?.variant ?? 'filled';
|
|
144
163
|
const finalHoverVariant = hoverVariant ?? productCardConfig?.hoverVariant ?? 'backgroundDark';
|
|
@@ -265,15 +284,13 @@ export const ProductCard = ({
|
|
|
265
284
|
|
|
266
285
|
return (
|
|
267
286
|
<div className={containerClassnames} data-testid={dataTestId}>
|
|
268
|
-
<a href={url} onClick={() => handleClick(url
|
|
287
|
+
<a href={url} onClick={() => handleClick(url)} target="_self" draggable={false}>
|
|
269
288
|
<div className={verticalContainerClassnames}>
|
|
270
289
|
<div className={imageClipContainerClassnames}>
|
|
271
290
|
<div className={imageContainerClassnames}>
|
|
272
291
|
{imageUrl && (
|
|
273
292
|
<ImageWithFallback
|
|
274
|
-
|
|
275
|
-
// src={resolve(imageUrl, layoutVariant === 'tall' ? 300 : 178)}
|
|
276
|
-
src={imageUrl}
|
|
293
|
+
src={resolve(imageUrl, layoutVariant === 'tall' ? 300 : 178)}
|
|
277
294
|
alt={title}
|
|
278
295
|
fallback={<Spinner className="spiffy-tw-w-6 spiffy-tw-h-6" />}
|
|
279
296
|
imageClassnames={imageClassnames}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ResponseCategory, SearchResponseProduct } from '@spiffy-ai/commerce-api-client';
|
|
2
2
|
import type { CamelCasedPropertiesDeep } from 'src/util/camelCasedPropertiesDeep';
|
|
3
3
|
|
|
4
4
|
export enum ProductCardSkeletonOverrides {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ProductCard } from '../ProductCard
|
|
1
|
+
import { ChatElementDisplayLocation } from 'src/config/chatElementDisplayLocation';
|
|
2
|
+
import { ProductGridVariant, ProductCardConfig, ProductCard } from '../ProductCard';
|
|
3
3
|
import { productGridVariantClasses } from './productGridVariants';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { SearchResponseProduct } from '@spiffy-ai/commerce-api-client';
|
|
6
|
+
import { CamelCasedPropertiesDeep } from 'src/util/camelCasedPropertiesDeep';
|
|
7
7
|
|
|
8
8
|
interface ProductGridProps {
|
|
9
9
|
productList: SearchResponseProduct[];
|
|
@@ -13,7 +13,6 @@ interface ProductGridProps {
|
|
|
13
13
|
merchantShortName: string;
|
|
14
14
|
searchResponseId: string;
|
|
15
15
|
cardsGrowWithContainer?: boolean;
|
|
16
|
-
handleClick: (clickedUrl: string) => void;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export const ProductGrid = ({
|
|
@@ -24,7 +23,6 @@ export const ProductGrid = ({
|
|
|
24
23
|
merchantShortName,
|
|
25
24
|
searchResponseId,
|
|
26
25
|
cardsGrowWithContainer = true,
|
|
27
|
-
handleClick,
|
|
28
26
|
}: ProductGridProps) => {
|
|
29
27
|
const {
|
|
30
28
|
productCardVariant,
|
|
@@ -41,33 +39,35 @@ export const ProductGrid = ({
|
|
|
41
39
|
|
|
42
40
|
return (
|
|
43
41
|
<div className={productGridClasses}>
|
|
44
|
-
{productList.map((product:
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
42
|
+
{productList.map((product: SearchResponseProduct, index: number) => {
|
|
43
|
+
const camelCasedProduct: CamelCasedPropertiesDeep<SearchResponseProduct> = product;
|
|
44
|
+
return (
|
|
45
|
+
<div key={camelCasedProduct.id} className={cardContainerClasses}>
|
|
46
|
+
<ProductCard
|
|
47
|
+
productCardConfig={productCardConfig}
|
|
48
|
+
merchantShortName={merchantShortName}
|
|
49
|
+
key={camelCasedProduct.id}
|
|
50
|
+
imageUrl={camelCasedProduct.imageUrl}
|
|
51
|
+
searchResponseId={searchResponseId}
|
|
52
|
+
productResponseId={camelCasedProduct.responseId}
|
|
53
|
+
title={camelCasedProduct.title}
|
|
54
|
+
url={camelCasedProduct.url}
|
|
55
|
+
originalPrice={camelCasedProduct.originalPrice}
|
|
56
|
+
salePrice={camelCasedProduct.salePrice}
|
|
57
|
+
averageRating={camelCasedProduct.averageRating}
|
|
58
|
+
numberReviews={camelCasedProduct.numberReviews}
|
|
59
|
+
cardDisplayLocation={ChatElementDisplayLocation.PRODUCT_GRID}
|
|
60
|
+
layoutVariant={productCardLayoutVariant}
|
|
61
|
+
variant={productCardVariant}
|
|
62
|
+
hoverVariant={productCardHoverVariant}
|
|
63
|
+
zoomOnHover={zoomOnHover}
|
|
64
|
+
aspectRatio={productCardImageAspectRatio}
|
|
65
|
+
clickPosition={index}
|
|
66
|
+
growWithContainer={cardsGrowWithContainer}
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
})}
|
|
71
71
|
</div>
|
|
72
72
|
);
|
|
73
73
|
};
|