@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.
Files changed (160) hide show
  1. package/dist/Accordion/index.cjs +84 -0
  2. package/dist/Accordion/index.d.cts +13 -0
  3. package/dist/Accordion/index.d.ts +13 -0
  4. package/dist/Accordion/index.js +77 -0
  5. package/dist/AppliedFiltersScrollbar/index.cjs +49 -0
  6. package/dist/AppliedFiltersScrollbar/index.d.cts +22 -0
  7. package/dist/AppliedFiltersScrollbar/index.d.ts +22 -0
  8. package/dist/AppliedFiltersScrollbar/index.js +44 -0
  9. package/dist/ButtonBase/index.cjs +2 -1
  10. package/dist/ButtonBase/index.d.cts +3 -3
  11. package/dist/ButtonBase/index.d.ts +1 -1
  12. package/dist/ButtonBase/index.js +2 -1
  13. package/dist/{ButtonBase-CpmFsiUf.js → ButtonBase-BIAu5fIG.js} +1 -1
  14. package/dist/ButtonBase-BRfuPPzN.js +1 -0
  15. package/dist/ButtonBase-BleAVeo-.cjs +0 -0
  16. package/dist/{ButtonBase-Dlh3bpR3.cjs → ButtonBase-DcyxOe2v.cjs} +2 -2
  17. package/dist/DynamicFiltersScrollbar/index.cjs +37 -0
  18. package/dist/DynamicFiltersScrollbar/index.d.cts +28 -0
  19. package/dist/DynamicFiltersScrollbar/index.d.ts +28 -0
  20. package/dist/DynamicFiltersScrollbar/index.js +32 -0
  21. package/dist/FilterScrollbar/index.cjs +1 -1
  22. package/dist/FilterScrollbar/index.d.cts +4 -4
  23. package/dist/FilterScrollbar/index.d.ts +4 -4
  24. package/dist/FilterScrollbar/index.js +1 -1
  25. package/dist/Headline/index.cjs +1 -1
  26. package/dist/Headline/index.d.cts +2 -2
  27. package/dist/Headline/index.js +1 -1
  28. package/dist/ImageWithFallback/index.cjs +1 -1
  29. package/dist/ImageWithFallback/index.d.ts +2 -2
  30. package/dist/ImageWithFallback/index.js +1 -1
  31. package/dist/{ImageWithFallback-By6QdlCR.cjs → ImageWithFallback-1LqhQK1q.cjs} +2 -2
  32. package/dist/{ImageWithFallback-DtUrq_bk.js → ImageWithFallback-Ckwsmd8P.js} +1 -1
  33. package/dist/ProductCard/index.cjs +7 -8
  34. package/dist/ProductCard/index.d.cts +2 -108
  35. package/dist/ProductCard/index.d.ts +2 -108
  36. package/dist/ProductCard/index.js +4 -5
  37. package/dist/{ProductCard-CvTRvhm7.cjs → ProductCard-DZZKutY-.cjs} +64 -5
  38. package/dist/{ProductCard-aJbQz6Q7.js → ProductCard-SF8-lXlT.js} +46 -6
  39. package/dist/ProductGrid/index.cjs +5 -5
  40. package/dist/ProductGrid/index.d.cts +6 -6
  41. package/dist/ProductGrid/index.d.ts +6 -6
  42. package/dist/ProductGrid/index.js +5 -5
  43. package/dist/{ProductGrid-CSIH2_G9.cjs → ProductGrid-BSSmPr7K.cjs} +48 -46
  44. package/dist/{ProductGrid-NOCayW9O.js → ProductGrid-DTUhH219.js} +48 -46
  45. package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.cjs +1 -1
  46. package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.d.cts +1 -1
  47. package/dist/{SearchInputAutocomplete → SearchAutocomplete}/index.d.ts +1 -1
  48. package/dist/SearchAutocomplete/index.js +3 -0
  49. package/dist/{SearchAutocomplete-DCu9-Yfk.js → SearchAutocomplete-BPjlo6qq.js} +4 -4
  50. package/dist/{SearchAutocomplete-CQxxe5Op.cjs → SearchAutocomplete-BzaEXmRQ.cjs} +8 -8
  51. package/dist/SearchFilter/index.cjs +5 -5
  52. package/dist/SearchFilter/index.d.cts +1 -34
  53. package/dist/SearchFilter/index.d.ts +1 -34
  54. package/dist/SearchFilter/index.js +2 -2
  55. package/dist/{SearchFilterHeader-qkRVfAB5.cjs → SearchFilter-B15tybnV.cjs} +1 -1
  56. package/dist/{SearchFilterHeader-BDEcDc_4.js → SearchFilter-D427M2UE.js} +1 -1
  57. package/dist/SearchInput/index.cjs +3 -3
  58. package/dist/SearchInput/index.d.cts +4 -4
  59. package/dist/SearchInput/index.d.ts +5 -5
  60. package/dist/SearchInput/index.js +3 -3
  61. package/dist/{SearchInput-DxGvYGZO.js → SearchInput-C0wB4hSV.js} +6 -6
  62. package/dist/{SearchInput-Cdpwswyv.cjs → SearchInput-D6UW79wT.cjs} +10 -10
  63. package/dist/SearchInputForm/index.cjs +6 -5
  64. package/dist/SearchInputForm/index.d.cts +1 -31
  65. package/dist/SearchInputForm/index.d.ts +1 -31
  66. package/dist/SearchInputForm/index.js +6 -5
  67. package/dist/SearchResultsContent/index.cjs +64 -0
  68. package/dist/SearchResultsContent/index.d.cts +67 -0
  69. package/dist/SearchResultsContent/index.d.ts +67 -0
  70. package/dist/SearchResultsContent/index.js +60 -0
  71. package/dist/SearchResultsFilterSidebar/index.cjs +10 -6
  72. package/dist/SearchResultsFilterSidebar/index.d.cts +3 -44
  73. package/dist/SearchResultsFilterSidebar/index.d.ts +3 -44
  74. package/dist/SearchResultsFilterSidebar/index.js +7 -4
  75. package/dist/SearchResultsStates/index.cjs +15 -125
  76. package/dist/SearchResultsStates/index.d.cts +14 -7
  77. package/dist/SearchResultsStates/index.d.ts +14 -7
  78. package/dist/SearchResultsStates/index.js +12 -117
  79. package/dist/SearchResultsStates-CNp6YCqF.js +112 -0
  80. package/dist/SearchResultsStates-Du7HXBi8.cjs +135 -0
  81. package/dist/SparkleAnimation/index.cjs +1 -1
  82. package/dist/SparkleAnimation/index.d.cts +2 -2
  83. package/dist/SparkleAnimation/index.d.ts +2 -2
  84. package/dist/SparkleAnimation/index.js +1 -1
  85. package/dist/{SparkleAnimation-DfMCtvAQ.js → SparkleAnimation-B0u6JtO3.js} +2 -2
  86. package/dist/{SparkleAnimation-j-mAMEZZ.cjs → SparkleAnimation-D1QpGZIg.cjs} +4 -4
  87. package/dist/Spinner/index.cjs +1 -1
  88. package/dist/Spinner/index.d.cts +2 -2
  89. package/dist/Spinner/index.js +1 -1
  90. package/dist/SuggestionButton/index.cjs +3 -3
  91. package/dist/SuggestionButton/index.d.cts +3 -3
  92. package/dist/SuggestionButton/index.d.ts +3 -3
  93. package/dist/SuggestionButton/index.js +2 -2
  94. package/dist/Text/index.cjs +2 -10
  95. package/dist/Text/index.d.cts +2 -2
  96. package/dist/Text/index.d.ts +3 -3
  97. package/dist/Text/index.js +1 -9
  98. package/dist/Text-DkwDPbHy.js +10 -0
  99. package/dist/Text-Ji61nRRE.cjs +16 -0
  100. package/dist/TextInput/index.cjs +1 -1
  101. package/dist/TextInput/index.d.ts +1 -1
  102. package/dist/TextInput/index.js +1 -1
  103. package/dist/{TextInput-CObd_Wcw.cjs → TextInput-C6fF9cSB.cjs} +2 -2
  104. package/dist/{TextInput-ChPhL54o.js → TextInput-CRMqBW3X.js} +1 -1
  105. package/dist/index-14eDYe9f.d.ts +58 -0
  106. package/dist/{types-Dvgr3ZeV.d.cts → index-B3iEVxkL.d.cts} +108 -23
  107. package/dist/index-B8bifyF-.d.ts +36 -0
  108. package/dist/index-BFdFh46m.d.cts +58 -0
  109. package/dist/{types-B7hf-Lif.d.ts → index-ByucvlTy.d.ts} +108 -23
  110. package/dist/index-C2iKBk7w.d.cts +36 -0
  111. package/dist/index-DLbdcczl.d.ts +78 -0
  112. package/dist/index-DlvTcfAg.d.cts +78 -0
  113. package/dist/{searchFilterSidebarVariants-C_UTEIpZ.js → searchFilterSidebarVariants-CZT1frB-.js} +1 -1
  114. package/dist/{searchFilterSidebarVariants-DcQLi_TT.cjs → searchFilterSidebarVariants-xyhy0PmQ.cjs} +1 -1
  115. package/package.json +22 -5
  116. package/src/components/Accordion/Accordion.tsx +90 -0
  117. package/src/components/Accordion/index.ts +1 -0
  118. package/src/components/AppliedFiltersScrollbar/AppliedFiltersScrollbar.tsx +70 -0
  119. package/src/components/AppliedFiltersScrollbar/index.ts +1 -0
  120. package/src/components/DynamicFiltersScrollbar/DynamicFiltersScrollbar.tsx +52 -0
  121. package/src/components/DynamicFiltersScrollbar/index.ts +1 -0
  122. package/src/components/ProductCard/ProductCard.tsx +34 -17
  123. package/src/components/ProductCard/types.ts +1 -1
  124. package/src/components/ProductGrid/ProductGrid.tsx +33 -33
  125. package/src/components/{SearchInputAutocomplete → SearchAutocomplete}/SearchAutocomplete.tsx +1 -1
  126. package/src/components/SearchInput/SearchInput.tsx +6 -6
  127. package/src/components/SearchInput/searchInputVariants.ts +5 -5
  128. package/src/components/SearchInputForm/SearchInputForm.tsx +6 -4
  129. package/src/components/SearchResultsContent/SearchResultsContent.tsx +87 -0
  130. package/src/components/SearchResultsContent/index.ts +2 -0
  131. package/src/components/SearchResultsContent/utils.ts +28 -0
  132. package/src/components/SearchResultsFilterSidebar/SearchResultsFilter.tsx +5 -6
  133. package/src/components/SearchResultsFilterSidebar/types.ts +14 -1
  134. package/src/components/SearchResultsStates/NoSearchResultsFound.tsx +2 -2
  135. package/src/components/SearchResultsStates/SearchResultsGrid.tsx +14 -12
  136. package/src/components/SearchResultsStates/SearchResultsLoadingGrid.tsx +4 -5
  137. package/dist/ProductCardSkeleton-B6YetUCT.js +0 -43
  138. package/dist/ProductCardSkeleton-BzBK36m-.cjs +0 -63
  139. package/dist/SearchInputAutocomplete/index.js +0 -3
  140. package/dist/types-5luH4G-3.d.cts +0 -5
  141. package/dist/types-BCAU5OQD.d.cts +0 -46
  142. package/dist/types-BIPqyTOJ.d.ts +0 -5
  143. package/dist/types-BwPquD10.d.ts +0 -46
  144. package/dist/types-CosVh8Hj.d.cts +0 -4
  145. package/dist/types-nR3jHgIO.d.ts +0 -4
  146. package/src/types/external.ts +0 -24
  147. /package/dist/{DynamicFiltersScrollbar-D8Lms7Ox.cjs → DynamicFiltersScrollbar-BTopFhyl.cjs} +0 -0
  148. /package/dist/{DynamicFiltersScrollbar-t_JASmYC.js → DynamicFiltersScrollbar-BmPTqym5.js} +0 -0
  149. /package/dist/{Headline-COAnonc2.js → Headline-XpaAeTSR.js} +0 -0
  150. /package/dist/{Headline-CdddUGwy.cjs → Headline-iP_MckEO.cjs} +0 -0
  151. /package/dist/{Spinner-D9kkaM9d.js → Spinner-BgGihEfJ.js} +0 -0
  152. /package/dist/{Spinner-DX35Epv3.cjs → Spinner-DzdIkS6t.cjs} +0 -0
  153. /package/dist/{colorsConfig-CKiMYHO_.js → colorsConfig-BQlaCfxi.js} +0 -0
  154. /package/dist/{colorsConfig-DulwYRIk.cjs → colorsConfig-DCvy_dV4.cjs} +0 -0
  155. /package/dist/{textVariantClasses-sT9E8Uty.d.ts → textVariantClasses-C8OCWZAw.d.ts} +0 -0
  156. /package/dist/{types-B19i3fxM.d.ts → types-Bm-qQyO3.d.ts} +0 -0
  157. /package/dist/{types-BQYpWDJ4.d.cts → types-C0UWKVvw.d.ts} +0 -0
  158. /package/dist/{types-C-Jrlw5Z.d.cts → types-CZHc-1wI.d.cts} +0 -0
  159. /package/dist/{types-DpfHwTzY.d.ts → types-D2xCS4y9.d.cts} +0 -0
  160. /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 };
@@ -1,4 +1,4 @@
1
- import { ColorNames, colorVar } from "./colorsConfig-CKiMYHO_.js";
1
+ import { ColorNames, colorVar } from "./colorsConfig-BQlaCfxi.js";
2
2
 
3
3
  //#region src/components/SearchResultsFilterSidebar/searchFilterSidebarVariants.ts
4
4
  const searchFilterSidebarVariantClasses = {
@@ -1,4 +1,4 @@
1
- const require_colorsConfig = require('./colorsConfig-DulwYRIk.cjs');
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.5",
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 { Headline } from '../Headline/Headline';
11
- import { ImageWithFallback } from 'src/components/ImageWithFallback/ImageWithFallback';
12
- import type {
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 type { TestProps } from 'src/test/types';
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?: string;
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: (clickedUrl: string) => void;
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
- // const orgUIConfig = useAtomValue(orgUIConfigAtom);
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 || '')} target="_self" draggable={false}>
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
- // TODO: Fix once
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 type { ResponseCategory, SearchResponseProduct } from 'src/types/external';
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 type { ProductCardConfig, ProductGridVariant } from '../ProductCard/types';
2
- import { ProductCard } from '../ProductCard/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 { ChatElementDisplayLocation } from 'src/config/chatElementDisplayLocation';
6
- import { SearchResponseProduct } from 'src/types/external';
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: (typeof productList)[0], index: number) => (
45
- <div key={product.id} className={cardContainerClasses}>
46
- <ProductCard
47
- productCardConfig={productCardConfig}
48
- merchantShortName={merchantShortName}
49
- key={product.id}
50
- imageUrl={product.imageUrl}
51
- searchResponseId={searchResponseId}
52
- productResponseId={product.responseId}
53
- title={product.title}
54
- url={product.url}
55
- originalPrice={product.originalPrice}
56
- salePrice={product.salePrice}
57
- averageRating={product.averageRating}
58
- numberReviews={product.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
- handleClick={handleClick}
68
- />
69
- </div>
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
  };