@envive-ai/react-toolkit 0.1.5 → 0.1.6
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/ButtonBase/index.cjs +2 -1
- package/dist/ButtonBase/index.d.cts +2 -2
- package/dist/ButtonBase/index.d.ts +3 -3
- 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/FilterScrollbar/index.cjs +1 -1
- package/dist/FilterScrollbar/index.d.cts +3 -3
- 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.d.ts +2 -2
- package/dist/Headline/index.js +1 -1
- package/dist/ImageWithFallback/index.cjs +1 -1
- package/dist/ImageWithFallback/index.d.cts +2 -2
- 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 +3 -3
- package/dist/SearchInput/index.d.ts +3 -3
- 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/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 +23 -24
- package/dist/SearchResultsStates/index.d.cts +13 -6
- package/dist/SearchResultsStates/index.d.ts +14 -7
- package/dist/SearchResultsStates/index.js +19 -21
- 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-BdOjC8l-.js} +2 -2
- package/dist/{SparkleAnimation-j-mAMEZZ.cjs → SparkleAnimation-BhyeL26m.cjs} +4 -4
- package/dist/Spinner/index.cjs +1 -1
- package/dist/Spinner/index.d.cts +2 -2
- package/dist/Spinner/index.d.ts +2 -2
- package/dist/Spinner/index.js +1 -1
- package/dist/SuggestionButton/index.cjs +3 -3
- package/dist/SuggestionButton/index.d.cts +2 -2
- 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 +3 -3
- package/dist/Text/index.d.ts +3 -3
- package/dist/Text/index.js +1 -9
- package/dist/Text-CV9pv8ds.js +10 -0
- package/dist/Text-DDT3sqY1.cjs +16 -0
- package/dist/TextInput/index.cjs +1 -1
- package/dist/TextInput/index.d.cts +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-B0oln9VD.d.ts +58 -0
- package/dist/index-B125udRj.d.cts +78 -0
- package/dist/index-BHNzU-Pc.d.ts +36 -0
- package/dist/index-BNCrvswP.d.cts +36 -0
- package/dist/index-CQlBDGTL.d.cts +58 -0
- package/dist/{types-B7hf-Lif.d.ts → index-CcnuEYQN.d.ts} +110 -3
- package/dist/index-DMXTg_9L.d.ts +78 -0
- package/dist/{types-Dvgr3ZeV.d.cts → index-wYn2mEDm.d.cts} +110 -3
- package/dist/{searchFilterSidebarVariants-C_UTEIpZ.js → searchFilterSidebarVariants-BWQyiKwS.js} +1 -1
- package/dist/{searchFilterSidebarVariants-DcQLi_TT.cjs → searchFilterSidebarVariants-D08jyA7U.cjs} +1 -1
- package/package.json +10 -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/DynamicFiltersScrollbar/DynamicFiltersScrollbar.tsx +52 -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/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-DwnnFNBf.d.cts → textVariantClasses-C8OCWZAw.d.ts} +0 -0
- /package/dist/{textVariantClasses-sT9E8Uty.d.ts → textVariantClasses-Cdg-UUHi.d.cts} +0 -0
- /package/dist/{types-B19i3fxM.d.ts → types-Bm-qQyO3.d.ts} +0 -0
- /package/dist/{types-DpfHwTzY.d.ts → types-BruEHw-X.d.ts} +0 -0
- /package/src/components/{SearchInputAutocomplete → SearchAutocomplete}/index.ts +0 -0
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
import { TestProps } from "./types-BQYpWDJ4.cjs";
|
|
2
|
+
import * as react_jsx_runtime17 from "react/jsx-runtime";
|
|
3
|
+
import { FC } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/config/chatElementDisplayLocation.d.ts
|
|
6
|
+
declare enum ChatElementDisplayLocation {
|
|
7
|
+
IN_CHAT = "in_chat",
|
|
8
|
+
CHAT_PREVIEW = "chat_preview",
|
|
9
|
+
FLOATING_BUTTON = "floating_button",
|
|
10
|
+
HELP_ME_CHOOSE = "help_me_choose",
|
|
11
|
+
PLP_IMAGE_BANNER = "plp_image_banner",
|
|
12
|
+
TOP_REVIEWS_SNIPPET = "top_reviews_snippet",
|
|
13
|
+
BOTTOM_REVIEWS_SNIPPET = "bottom_reviews_snippet",
|
|
14
|
+
BLOCK_BACK_BUTTON = "block_back_button",
|
|
15
|
+
SWITCH_TO_AGENT = "switch_to_agent",
|
|
16
|
+
CONVERSATIONAL_SEARCH = "conversational_search",
|
|
17
|
+
GLOBAL_SEARCH_ENTRYPOINT = "global_search_entrypoint",
|
|
18
|
+
SEARCH_NAV_ENTRYPOINT = "search_nav_entrypoint",
|
|
19
|
+
SEARCH_PROMPT = "search_prompt",
|
|
20
|
+
SEARCH_PROMPT_BUTTON = "search_prompt_button",
|
|
21
|
+
PRODUCT_GRID = "product_grid",
|
|
22
|
+
UNSPECIFIED = "unspecified",
|
|
23
|
+
FILTER_MODAL = "filter_modal",
|
|
24
|
+
PROMPT_CARD = "prompt_card",
|
|
25
|
+
WINDOW_API_CALL = "window_api_call",
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
1
28
|
//#region src/types/external.d.ts
|
|
2
29
|
declare enum ResponseCategory {
|
|
3
30
|
Product = "product",
|
|
@@ -12,7 +39,7 @@ interface SearchResponseProduct {
|
|
|
12
39
|
brand?: string;
|
|
13
40
|
category?: string;
|
|
14
41
|
availability?: string;
|
|
15
|
-
url
|
|
42
|
+
url: string;
|
|
16
43
|
responseId?: string;
|
|
17
44
|
originalPrice?: number;
|
|
18
45
|
salePrice?: number;
|
|
@@ -254,7 +281,7 @@ interface SearchResponseProductAttributes {
|
|
|
254
281
|
category: ResponseCategory.Product;
|
|
255
282
|
attributes: CamelCasedPropertiesDeep<SearchResponseProduct>;
|
|
256
283
|
}
|
|
257
|
-
interface ProductCardSkeletonProps {
|
|
284
|
+
interface ProductCardSkeletonProps$1 {
|
|
258
285
|
layoutVariant: ProductCardLayoutVariant;
|
|
259
286
|
aspectRatio: ProductCardImageAspectRatio;
|
|
260
287
|
growWithContainer?: boolean;
|
|
@@ -269,4 +296,84 @@ interface ProductGridProps {
|
|
|
269
296
|
cardsGrowWithContainer?: boolean;
|
|
270
297
|
}
|
|
271
298
|
//#endregion
|
|
272
|
-
|
|
299
|
+
//#region src/components/ProductCard/ProductCard.d.ts
|
|
300
|
+
interface RatingSummaryProps {
|
|
301
|
+
stars: number;
|
|
302
|
+
reviewCount: number;
|
|
303
|
+
className?: string;
|
|
304
|
+
}
|
|
305
|
+
declare const RatingSummary: ({
|
|
306
|
+
stars,
|
|
307
|
+
reviewCount,
|
|
308
|
+
className
|
|
309
|
+
}: RatingSummaryProps) => react_jsx_runtime17.JSX.Element;
|
|
310
|
+
interface PriceSectionProps {
|
|
311
|
+
originalPrice?: string;
|
|
312
|
+
salePrice?: string;
|
|
313
|
+
pricePrefix?: string;
|
|
314
|
+
}
|
|
315
|
+
declare const PriceSection: ({
|
|
316
|
+
originalPrice,
|
|
317
|
+
salePrice,
|
|
318
|
+
pricePrefix
|
|
319
|
+
}: PriceSectionProps) => react_jsx_runtime17.JSX.Element;
|
|
320
|
+
interface ProductCardProps extends TestProps {
|
|
321
|
+
productCardConfig?: ProductCardConfig;
|
|
322
|
+
merchantShortName: string;
|
|
323
|
+
title: string;
|
|
324
|
+
url: string;
|
|
325
|
+
searchResponseId?: string;
|
|
326
|
+
productResponseId?: string;
|
|
327
|
+
cardDisplayLocation: ChatElementDisplayLocation.IN_CHAT | ChatElementDisplayLocation.PRODUCT_GRID;
|
|
328
|
+
imageUrl?: string;
|
|
329
|
+
originalPrice?: number;
|
|
330
|
+
averageRating?: number;
|
|
331
|
+
numberReviews?: number;
|
|
332
|
+
salePrice?: number;
|
|
333
|
+
variant?: ProductCardVariant;
|
|
334
|
+
hoverVariant?: ProductCardHoverVariant;
|
|
335
|
+
layoutVariant?: ProductCardLayoutVariant;
|
|
336
|
+
zoomOnHover?: boolean;
|
|
337
|
+
aspectRatio?: '3:4' | 'square' | 'none';
|
|
338
|
+
clickPosition?: number | null;
|
|
339
|
+
growWithContainer?: boolean;
|
|
340
|
+
handleClick?: (clickedUrl: string) => void;
|
|
341
|
+
}
|
|
342
|
+
declare const ProductCard: ({
|
|
343
|
+
productCardConfig,
|
|
344
|
+
merchantShortName,
|
|
345
|
+
imageUrl,
|
|
346
|
+
title,
|
|
347
|
+
url,
|
|
348
|
+
originalPrice,
|
|
349
|
+
averageRating,
|
|
350
|
+
numberReviews,
|
|
351
|
+
salePrice,
|
|
352
|
+
variant,
|
|
353
|
+
hoverVariant,
|
|
354
|
+
dataTestId,
|
|
355
|
+
layoutVariant,
|
|
356
|
+
zoomOnHover,
|
|
357
|
+
aspectRatio,
|
|
358
|
+
growWithContainer,
|
|
359
|
+
handleClick
|
|
360
|
+
}: ProductCardProps) => react_jsx_runtime17.JSX.Element;
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/components/ProductCard/ProductCardSkeleton.d.ts
|
|
363
|
+
interface ProductCardSkeletonProps {
|
|
364
|
+
layoutVariant: ProductCardLayoutVariant;
|
|
365
|
+
aspectRatio?: '3:4' | 'square' | 'none';
|
|
366
|
+
growWithContainer?: boolean;
|
|
367
|
+
}
|
|
368
|
+
declare const ProductCardSkeleton: FC<ProductCardSkeletonProps>;
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/components/ProductCard/productCardVariants.d.ts
|
|
371
|
+
/**
|
|
372
|
+
* Shared variant mapping configurations for ProductCard components
|
|
373
|
+
*/
|
|
374
|
+
declare const variantClassMap: Map<ProductCardVariant, string[]>;
|
|
375
|
+
declare const variantHoverClassMap: Map<ProductCardHoverVariant, string[]>;
|
|
376
|
+
declare const variantTitleColorMap: Map<ProductCardVariant, string>;
|
|
377
|
+
declare const productCardLayoutVariantClasses: Record<ProductCardLayoutVariant, Record<string, string[]>>;
|
|
378
|
+
//#endregion
|
|
379
|
+
export { AnimatedProductCardOverrides, PriceSection, ProductCard, ProductCardConfig, ProductCardHoverVariant, ProductCardImageAspectRatio, ProductCardLayoutVariant, ProductCardSkeleton, ProductCardSkeletonOverrides, ProductCardSkeletonProps$1 as ProductCardSkeletonProps, ProductCardVariant, ProductGridProps, ProductGridVariant, RatingSummary, SearchResponseProductAttributes, productCardLayoutVariantClasses, variantClassMap, variantHoverClassMap, variantTitleColorMap };
|
package/dist/{searchFilterSidebarVariants-DcQLi_TT.cjs → searchFilterSidebarVariants-D08jyA7U.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.6",
|
|
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,6 +40,10 @@
|
|
|
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
|
+
},
|
|
42
47
|
"./ButtonBase": {
|
|
43
48
|
"import": "./dist/ButtonBase/index.js",
|
|
44
49
|
"require": "./dist/ButtonBase/index.cjs"
|
|
@@ -63,6 +68,10 @@
|
|
|
63
68
|
"import": "./dist/ProductGrid/index.js",
|
|
64
69
|
"require": "./dist/ProductGrid/index.cjs"
|
|
65
70
|
},
|
|
71
|
+
"./SearchAutocomplete": {
|
|
72
|
+
"import": "./dist/SearchAutocomplete/index.js",
|
|
73
|
+
"require": "./dist/SearchAutocomplete/index.cjs"
|
|
74
|
+
},
|
|
66
75
|
"./SearchFilter": {
|
|
67
76
|
"import": "./dist/SearchFilter/index.js",
|
|
68
77
|
"require": "./dist/SearchFilter/index.cjs"
|
|
@@ -71,10 +80,6 @@
|
|
|
71
80
|
"import": "./dist/SearchInput/index.js",
|
|
72
81
|
"require": "./dist/SearchInput/index.cjs"
|
|
73
82
|
},
|
|
74
|
-
"./SearchInputAutocomplete": {
|
|
75
|
-
"import": "./dist/SearchInputAutocomplete/index.js",
|
|
76
|
-
"require": "./dist/SearchInputAutocomplete/index.cjs"
|
|
77
|
-
},
|
|
78
83
|
"./SearchInputForm": {
|
|
79
84
|
"import": "./dist/SearchInputForm/index.js",
|
|
80
85
|
"require": "./dist/SearchInputForm/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,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
|
+
};
|
|
@@ -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
|
};
|
package/src/components/{SearchInputAutocomplete → SearchAutocomplete}/SearchAutocomplete.tsx
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { motion } from 'framer-motion';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import OutlinedStar from '@envive-ai/react-icons/
|
|
4
|
+
import OutlinedStar from '@envive-ai/react-icons/OutlinedStar';
|
|
5
5
|
|
|
6
6
|
interface GlobalSearchAutocompleteProps {
|
|
7
7
|
id: string;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useRef, useImperativeHandle } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import MagnifyingGlassStarVariant from '@envive-ai/react-icons/
|
|
4
|
-
import
|
|
5
|
-
import { TextInput } from '
|
|
3
|
+
import MagnifyingGlassStarVariant from '@envive-ai/react-icons/MagnifyingGlassStarVariant';
|
|
4
|
+
import { SearchInputVariant } from '../SearchInputForm';
|
|
5
|
+
import { TextInput } from '../TextInput';
|
|
6
6
|
import { searchInputVariantClasses } from './searchInputVariants';
|
|
7
|
-
import
|
|
7
|
+
import { IconClose } from '@envive-ai/react-icons/src/index.js';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
interface SearchInputProps {
|
|
10
10
|
searchInputVariant?: SearchInputVariant;
|
|
11
11
|
value: string;
|
|
12
12
|
placeholder?: string;
|
|
@@ -126,7 +126,7 @@ export const SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(
|
|
|
126
126
|
aria-label="Clear search input"
|
|
127
127
|
type="button"
|
|
128
128
|
>
|
|
129
|
-
<
|
|
129
|
+
<IconClose className={closeButtonIconClassName} />
|
|
130
130
|
</button>
|
|
131
131
|
)}
|
|
132
132
|
</div>
|