@envive-ai/react-widgets 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/SearchResults/SearchResults.cjs +82 -0
  2. package/dist/SearchResults/SearchResults.js +80 -0
  3. package/dist/SearchResults/SearchResultsWidget.cjs +34 -0
  4. package/dist/SearchResults/SearchResultsWidget.d.ts +6 -0
  5. package/dist/SearchResults/SearchResultsWidget.js +33 -0
  6. package/dist/SearchResults/index.cjs +2 -122
  7. package/dist/SearchResults/index.d.cts +2 -0
  8. package/dist/SearchResults/index.d.ts +2 -0
  9. package/dist/SearchResults/index.js +1 -119
  10. package/dist/SearchResults/withSearchResults.cjs +18 -0
  11. package/dist/SearchResults/withSearchResults.js +17 -0
  12. package/dist/SearchZeroState/SearchIcon.cjs +47 -0
  13. package/dist/SearchZeroState/SearchIcon.js +44 -0
  14. package/dist/SearchZeroState/SearchOverlay.cjs +42 -0
  15. package/dist/SearchZeroState/SearchOverlay.js +39 -0
  16. package/dist/SearchZeroState/SearchZeroState.cjs +169 -0
  17. package/dist/SearchZeroState/SearchZeroState.d.cts +7 -0
  18. package/dist/SearchZeroState/SearchZeroState.d.ts +7 -0
  19. package/dist/SearchZeroState/SearchZeroState.js +167 -0
  20. package/dist/SearchZeroState/SearchZeroStateWidget.cjs +23 -0
  21. package/dist/SearchZeroState/SearchZeroStateWidget.d.cts +15 -0
  22. package/dist/SearchZeroState/SearchZeroStateWidget.d.ts +15 -0
  23. package/dist/SearchZeroState/SearchZeroStateWidget.js +22 -0
  24. package/dist/SearchZeroState/components/RecommendedProducts.cjs +72 -0
  25. package/dist/SearchZeroState/components/RecommendedProducts.js +70 -0
  26. package/dist/SearchZeroState/index.cjs +4 -3070
  27. package/dist/SearchZeroState/index.d.cts +5 -0
  28. package/dist/SearchZeroState/index.d.ts +5 -0
  29. package/dist/SearchZeroState/index.js +2 -3065
  30. package/dist/SearchZeroState/overlay/overlayHostLocator.cjs +21 -0
  31. package/dist/SearchZeroState/overlay/overlayHostLocator.js +20 -0
  32. package/dist/SearchZeroState/types.d.cts +10 -0
  33. package/dist/SearchZeroState/types.d.ts +10 -0
  34. package/dist/SearchZeroState/zeroStateSearchVariants.cjs +21 -0
  35. package/dist/SearchZeroState/zeroStateSearchVariants.js +20 -0
  36. package/dist/SuggestionBar/SuggestionBar.cjs +74 -0
  37. package/dist/SuggestionBar/{index-DZU9kbWS.d.cts → SuggestionBar.d.cts} +5 -10
  38. package/dist/SuggestionBar/{index-DyXd4-b7.d.ts → SuggestionBar.d.ts} +5 -10
  39. package/dist/{SuggestionBar-BHAXhgcd.js → SuggestionBar/SuggestionBar.js} +6 -58
  40. package/dist/SuggestionBar/index.cjs +3 -3
  41. package/dist/SuggestionBar/index.d.cts +3 -0
  42. package/dist/SuggestionBar/index.d.ts +3 -0
  43. package/dist/SuggestionBar/index.js +2 -2
  44. package/dist/SuggestionBar/types.cjs +10 -0
  45. package/dist/SuggestionBar/types.d.cts +7 -0
  46. package/dist/SuggestionBar/types.d.ts +7 -0
  47. package/dist/SuggestionBar/types.js +9 -0
  48. package/dist/{SuggestionButtonContainer-Dm38gJiJ.cjs → SuggestionButtonContainer/SuggestionButtonContainer.cjs} +4 -102
  49. package/dist/SuggestionButtonContainer/SuggestionButtonContainer.d.cts +6 -0
  50. package/dist/SuggestionButtonContainer/SuggestionButtonContainer.d.ts +6 -0
  51. package/dist/{SuggestionButtonContainer-s2e9YGW_.js → SuggestionButtonContainer/SuggestionButtonContainer.js} +3 -96
  52. package/dist/SuggestionButtonContainer/index.cjs +1 -1
  53. package/dist/SuggestionButtonContainer/index.d.cts +3 -0
  54. package/dist/SuggestionButtonContainer/index.d.ts +3 -0
  55. package/dist/SuggestionButtonContainer/index.js +1 -1
  56. package/dist/SuggestionButtonContainer/{index-B_X537jw.d.cts → types.d.cts} +3 -6
  57. package/dist/SuggestionButtonContainer/{index-vwelzDzM.d.ts → types.d.ts} +3 -6
  58. package/dist/{chunk-DSlc6foC.cjs → _virtual/rolldown_runtime.cjs} +2 -12
  59. package/dist/hooks/dist/contexts/types.d.cts +52 -0
  60. package/dist/hooks/dist/types/test-types.d.cts +8 -0
  61. package/dist/{SuggestionBar-CK5aU2bb.cjs → node_modules/react-indiana-drag-scroll/dist/index.cjs} +6 -132
  62. package/dist/node_modules/uuid/dist/native.js +6 -0
  63. package/dist/node_modules/uuid/dist/rng.js +13 -0
  64. package/dist/node_modules/uuid/dist/stringify.js +9 -0
  65. package/dist/node_modules/uuid/dist/v4.js +27 -0
  66. package/dist/node_modules/uuid/dist-node/native.cjs +8 -0
  67. package/dist/node_modules/uuid/dist-node/rng.cjs +16 -0
  68. package/dist/node_modules/uuid/dist-node/stringify.cjs +10 -0
  69. package/dist/node_modules/uuid/dist-node/v4.cjs +27 -0
  70. package/dist/packages/hooks/dist/contexts/types.d.ts +52 -0
  71. package/dist/packages/hooks/dist/types/test-types.d.ts +8 -0
  72. package/dist/packages/icons/dist/AiSearchBold.cjs +38 -0
  73. package/dist/packages/icons/dist/AiSearchBold.js +38 -0
  74. package/dist/packages/icons/dist/AiSearchThin.cjs +35 -0
  75. package/dist/packages/icons/dist/AiSearchThin.js +35 -0
  76. package/dist/packages/icons/dist/IconCloseVariant.cjs +22 -0
  77. package/dist/packages/icons/dist/IconCloseVariant.js +22 -0
  78. package/dist/packages/icons/dist/Sparkles.cjs +43 -0
  79. package/dist/packages/icons/dist/Sparkles.js +43 -0
  80. package/dist/packages/icons/dist/_virtual/rolldown_runtime.cjs +29 -0
  81. package/dist/packages/icons/dist/_virtual/rolldown_runtime.js +27 -0
  82. package/dist/packages/icons/dist/node_modules/react/cjs/react-jsx-runtime.development.cjs +696 -0
  83. package/dist/packages/icons/dist/node_modules/react/cjs/react-jsx-runtime.development.js +696 -0
  84. package/dist/packages/icons/dist/node_modules/react/cjs/react-jsx-runtime.production.min.cjs +43 -0
  85. package/dist/packages/icons/dist/node_modules/react/cjs/react-jsx-runtime.production.min.js +43 -0
  86. package/dist/packages/icons/dist/node_modules/react/cjs/react.development.cjs +1528 -0
  87. package/dist/packages/icons/dist/node_modules/react/cjs/react.development.js +1528 -0
  88. package/dist/packages/icons/dist/node_modules/react/cjs/react.production.min.cjs +329 -0
  89. package/dist/packages/icons/dist/node_modules/react/cjs/react.production.min.js +329 -0
  90. package/dist/packages/icons/dist/node_modules/react/index.cjs +13 -0
  91. package/dist/packages/icons/dist/node_modules/react/index.js +13 -0
  92. package/dist/packages/icons/dist/node_modules/react/jsx-runtime.cjs +13 -0
  93. package/dist/packages/icons/dist/node_modules/react/jsx-runtime.js +13 -0
  94. package/dist/util/useHorizontalScrollAnimation.cjs +88 -0
  95. package/dist/util/useHorizontalScrollAnimation.js +87 -0
  96. package/dist/util/useReducedMotionWithOverride.cjs +15 -0
  97. package/dist/util/useReducedMotionWithOverride.js +14 -0
  98. package/package.json +5 -5
  99. package/src/SearchZeroState/SearchZeroState.tsx +1 -1
  100. package/src/SuggestionBar/SuggestionBar.tsx +2 -2
  101. package/dist/SearchResults/index-DCTxvwmv.d.cts +0 -6
  102. package/dist/SearchZeroState/index-DSFtalZR.d.ts +0 -27
  103. package/dist/SearchZeroState/index-bEcxYOSF.d.cts +0 -27
  104. /package/dist/SearchResults/{index-CYPV3XE0.d.ts → SearchResultsWidget.d.cts} +0 -0
@@ -0,0 +1,39 @@
1
+ import { getOverlayPortalTarget } from "./overlay/overlayHostLocator.js";
2
+ import React from "react";
3
+ import classNames from "classnames";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { motion } from "framer-motion";
6
+ import { createPortal } from "react-dom";
7
+
8
+ //#region src/SearchZeroState/SearchOverlay.tsx
9
+ const SearchOverlay = React.forwardRef(({ children, className, dataTestId, role, ariaModal, ariaLabelledby, id, usingPortal }, ref) => {
10
+ const overlayClasses = classNames("spiffy-search-overlay", "spiffy-tw-fixed", "spiffy-tw-top-[0]", "spiffy-tw-left-[0]", "spiffy-tw-h-[100vh]", "spiffy-tw-w-full", "spiffy-h-[calc(100%-1rem)]", "spiffy-tw-px-[24px] spiffy-tw-pt-[16px] sm:spiffy-tw-px-[41px] sm:spiffy-tw-pt-[40px]", "spiffy-tw-z-[2147483647]", "spiffy-tw-overflow-y-auto", "spiffy-tw-overflow-x-hidden", className);
11
+ const overlayContentClasses = classNames("spiffy-search-overlay-content", "spiffy-tw-flex spiffy-tw-flex-col", "spiffy-tw-min-h-full", className);
12
+ const node = /* @__PURE__ */ jsx(motion.div, {
13
+ ref,
14
+ className: overlayClasses,
15
+ initial: { opacity: 0 },
16
+ animate: { opacity: 1 },
17
+ exit: { opacity: 0 },
18
+ transition: { duration: .2 },
19
+ children: /* @__PURE__ */ jsx("div", {
20
+ className: overlayContentClasses,
21
+ "data-testid": dataTestId,
22
+ role,
23
+ "aria-modal": ariaModal,
24
+ "aria-labelledby": ariaLabelledby,
25
+ id,
26
+ children
27
+ })
28
+ });
29
+ if (!usingPortal) return node;
30
+ try {
31
+ return createPortal(node, getOverlayPortalTarget());
32
+ } catch (err) {
33
+ return node;
34
+ }
35
+ });
36
+ SearchOverlay.displayName = "SearchOverlay";
37
+
38
+ //#endregion
39
+ export { SearchOverlay };
@@ -0,0 +1,169 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_SuggestionBar = require('../SuggestionBar/SuggestionBar.cjs');
3
+ require('../SuggestionBar/index.cjs');
4
+ const require_Sparkles = require('../packages/icons/dist/Sparkles.cjs');
5
+ const require_IconCloseVariant = require('../packages/icons/dist/IconCloseVariant.cjs');
6
+ const require_SearchOverlay = require('./SearchOverlay.cjs');
7
+ const require_zeroStateSearchVariants = require('./zeroStateSearchVariants.cjs');
8
+ const require_SearchIcon = require('./SearchIcon.cjs');
9
+ const require_RecommendedProducts = require('./components/RecommendedProducts.cjs');
10
+ let react = require("react");
11
+ react = require_rolldown_runtime.__toESM(react);
12
+ let __envive_ai_react_hooks_hooks_Search = require("@envive-ai/react-hooks/hooks/Search");
13
+ let react_jsx_runtime = require("react/jsx-runtime");
14
+ let __envive_ai_react_hooks_application_models = require("@envive-ai/react-hooks/application/models");
15
+ let framer_motion = require("framer-motion");
16
+ let __envive_ai_react_hooks_hooks_AmplitudeOperations = require("@envive-ai/react-hooks/hooks/AmplitudeOperations");
17
+ let __envive_ai_react_hooks_types = require("@envive-ai/react-hooks/types");
18
+ let __envive_ai_react_hooks_contexts_amplitudeContext = require("@envive-ai/react-hooks/contexts/amplitudeContext");
19
+ let __envive_ai_react_toolkit_SearchInputForm = require("@envive-ai/react-toolkit/SearchInputForm");
20
+ let __envive_ai_react_toolkit_SearchInput = require("@envive-ai/react-toolkit/SearchInput");
21
+ let __envive_ai_react_toolkit_Typography = require("@envive-ai/react-toolkit/Typography");
22
+
23
+ //#region src/SearchZeroState/SearchZeroState.tsx
24
+ const SEARCH_ENTRYPOINT_INPUT_TESTID = "spiffy-search-entrypoint-input";
25
+ const SearchZeroState = ({ widgetConfig, initialIsOpen, entryPointRef }) => {
26
+ console.log("SearchZeroState: widgetConfig", widgetConfig);
27
+ const { searchZeroStateVariant, searchInputVariant, searchIconVariant, searchIconSize = 24, searchBoxPlaceholder, layout, compactLabel, initialSuggestions = [], animationSpeed = "standard", suggestionButtonConfig, includeSubtitle, usingPortal = false } = widgetConfig;
28
+ const { variant: suggestionButtonVariant, hoverVariant: suggestionButtonHoverVariant, borderRadius: suggestionButtonBorderRadius } = suggestionButtonConfig;
29
+ const [isOpen, setIsOpen] = (0, react.useState)(!!initialIsOpen);
30
+ const searchInputRef = (0, react.useRef)(null);
31
+ const searchInput = (0, __envive_ai_react_hooks_hooks_Search.useSearch)({ allowRedirect: true });
32
+ const { track } = (0, __envive_ai_react_hooks_hooks_AmplitudeOperations.useAmplitudeTracking)();
33
+ const { recommendedProductsHeading, searchOverlayHeading, productCardConfig, merchantShortName, recommendedProducts, searchText, autocompleteResults, focusedIndex, focusedOptionId, shouldShowAutocomplete, onSearchInputChange, onSearchInputFocus, onSearchInputBlur, onKeyDown, onAutocompleteSelect, onSubmitSearch, resetSearch } = searchInput;
34
+ const { overlayBackgroundClasses, sparklesIconColor } = require_zeroStateSearchVariants.searchZeroStateVariantClasses[searchZeroStateVariant && require_zeroStateSearchVariants.searchZeroStateVariantClasses[searchZeroStateVariant] ? searchZeroStateVariant : "backgroundTertiary"];
35
+ const { searchInputIconColor } = __envive_ai_react_toolkit_SearchInput.searchInputVariantClasses[searchInputVariant];
36
+ const handleOpen = () => setIsOpen(true);
37
+ const handleClose = () => setIsOpen(false);
38
+ (0, react.useEffect)(() => {
39
+ if (isOpen) track(__envive_ai_react_hooks_contexts_amplitudeContext.SpiffyMetricsEventName.SearchComponentVisible, { eventProps: { search_component: __envive_ai_react_hooks_application_models.SpiffyWidgets.SearchZeroState } });
40
+ }, [isOpen, track]);
41
+ (0, react.useEffect)(() => {
42
+ if (isOpen) {
43
+ resetSearch();
44
+ searchInputRef.current?.focus();
45
+ }
46
+ }, [isOpen, resetSearch]);
47
+ const submitSearchString = (0, react.useCallback)((query) => {
48
+ onSearchInputChange(query);
49
+ if (onSubmitSearch && query.trim()) {
50
+ onSubmitSearch();
51
+ setIsOpen(false);
52
+ }
53
+ }, [onSubmitSearch, onSearchInputChange]);
54
+ const searchChange = (value) => {
55
+ onSearchInputChange(value);
56
+ };
57
+ if (!isOpen) {
58
+ if (layout === "icon") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SearchIcon.SearchIcon, {
59
+ entryPointRef,
60
+ size: searchIconSize,
61
+ variant: searchIconVariant,
62
+ label: compactLabel,
63
+ onClick: handleOpen,
64
+ color: searchInputIconColor
65
+ });
66
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_SearchInput.SearchInput, {
67
+ value: "",
68
+ onChange: () => {},
69
+ placeholder: searchBoxPlaceholder,
70
+ suggestions: [],
71
+ onFocus: handleOpen,
72
+ searchInputVariant,
73
+ dataTestId: SEARCH_ENTRYPOINT_INPUT_TESTID
74
+ });
75
+ }
76
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, { children: isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_SearchOverlay.SearchOverlay, {
77
+ role: "dialog",
78
+ ariaModal: true,
79
+ ariaLabelledby: "global-search-title",
80
+ className: overlayBackgroundClasses,
81
+ usingPortal,
82
+ children: [
83
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
84
+ className: "spiffy-tw-relative spiffy-tw-mb-4",
85
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
86
+ className: "spiffy-tw-flex spiffy-tw-items-center",
87
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_Typography.Typography, {
88
+ id: "global-search-title",
89
+ variant: "t3",
90
+ children: searchOverlayHeading
91
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Sparkles.Sparkles_default, {
92
+ className: "spiffy-tw-ml-2 spiffy-tw-h-[36px] spiffy-tw-w-[24px] sm:spiffy-tw-h-[45px] sm:spiffy-tw-w-[36px]",
93
+ color: sparklesIconColor,
94
+ stroke: "2px"
95
+ })]
96
+ }), includeSubtitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_Typography.Typography, {
97
+ variant: "body2",
98
+ children: "Go ahead, get as specific as you like..."
99
+ })]
100
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
101
+ onClick: handleClose,
102
+ className: "spiffy-tw-absolute spiffy-tw-right-4 spiffy-tw-top-4 sm:spiffy-tw-right-8 sm:spiffy-tw-top-8",
103
+ "aria-label": "Close search",
104
+ type: "button",
105
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_IconCloseVariant.IconCloseVariant_default, {
106
+ className: "spiffy-tw-h-[20px] spiffy-tw-w-[20px] sm:spiffy-tw-h-[28px] sm:spiffy-tw-w-[28px]",
107
+ strokeWidth: "2px"
108
+ })
109
+ })] }),
110
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_SearchInputForm.SearchInputForm, {
111
+ searchInputRef,
112
+ searchInputVariant,
113
+ searchText,
114
+ autocompleteResults,
115
+ searchBoxPlaceholder,
116
+ focusedOptionId,
117
+ shouldShowAutocomplete,
118
+ focusedIndex,
119
+ onKeyDown,
120
+ onAutocompleteSelect,
121
+ onSearchInputChange: searchChange,
122
+ onSearchSubmit: () => submitSearchString,
123
+ onSearchInputFocus,
124
+ onSearchInputBlur
125
+ }),
126
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.AnimatePresence, { children: [initialSuggestions && initialSuggestions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
127
+ className: "spiffy-tw-w-full spiffy-tw-justify-center spiffy-tw-overflow-hidden",
128
+ initial: { opacity: 0 },
129
+ animate: { opacity: 1 },
130
+ exit: { opacity: 0 },
131
+ transition: { duration: .2 },
132
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
133
+ className: "spiffy-tw-mt-6",
134
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SuggestionBar.SuggestionBar, {
135
+ id: "global-search-suggestions",
136
+ locationForMetrics: __envive_ai_react_hooks_types.SuggestionBarLocationForMetrics.SUGGESTION_BAR_TOP,
137
+ buttonTexts: initialSuggestions,
138
+ buttonBorderRadius: suggestionButtonBorderRadius,
139
+ buttonVariation: suggestionButtonVariant ?? "primary",
140
+ hoverButtonVariation: suggestionButtonHoverVariant ?? "primary",
141
+ animationSpeed,
142
+ handleReply: (message) => {
143
+ if (message.type === __envive_ai_react_hooks_application_models.MessageType.QueryTyped && message.metadata?.content) {
144
+ track(__envive_ai_react_hooks_contexts_amplitudeContext.SpiffyMetricsEventName.SearchZeroStateSuggestionClicked, { eventProps: {
145
+ queryText: message.metadata.content,
146
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
147
+ } });
148
+ submitSearchString(message.metadata.content);
149
+ }
150
+ },
151
+ twoRowsOnMobile: true
152
+ })
153
+ })
154
+ }), recommendedProducts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
155
+ className: "spiffy-tw-mt-[40px]",
156
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_RecommendedProducts.RecommendedProducts, {
157
+ retrievedProducts: recommendedProducts,
158
+ merchantShortName,
159
+ productCardConfig,
160
+ productGridVariant: "standard",
161
+ heading: recommendedProductsHeading
162
+ })
163
+ })] })
164
+ ]
165
+ }) });
166
+ };
167
+
168
+ //#endregion
169
+ exports.SearchZeroState = SearchZeroState;
@@ -0,0 +1,7 @@
1
+ import { SearchZeroStateProps } from "./types.cjs";
2
+ import React from "react";
3
+
4
+ //#region src/SearchZeroState/SearchZeroState.d.ts
5
+ declare const SearchZeroState: React.FC<SearchZeroStateProps>;
6
+ //#endregion
7
+ export { SearchZeroState };
@@ -0,0 +1,7 @@
1
+ import { SearchZeroStateProps } from "./types.js";
2
+ import React from "react";
3
+
4
+ //#region src/SearchZeroState/SearchZeroState.d.ts
5
+ declare const SearchZeroState: React.FC<SearchZeroStateProps>;
6
+ //#endregion
7
+ export { SearchZeroState };
@@ -0,0 +1,167 @@
1
+ import { SuggestionBar } from "../SuggestionBar/SuggestionBar.js";
2
+ import "../SuggestionBar/index.js";
3
+ import { Sparkles_default } from "../packages/icons/dist/Sparkles.js";
4
+ import { IconCloseVariant_default } from "../packages/icons/dist/IconCloseVariant.js";
5
+ import { SearchOverlay } from "./SearchOverlay.js";
6
+ import { searchZeroStateVariantClasses } from "./zeroStateSearchVariants.js";
7
+ import { SearchIcon } from "./SearchIcon.js";
8
+ import { RecommendedProducts } from "./components/RecommendedProducts.js";
9
+ import React, { useCallback, useEffect, useRef, useState } from "react";
10
+ import { useSearch } from "@envive-ai/react-hooks/hooks/Search";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ import { MessageType, SpiffyWidgets } from "@envive-ai/react-hooks/application/models";
13
+ import { AnimatePresence, motion } from "framer-motion";
14
+ import { useAmplitudeTracking } from "@envive-ai/react-hooks/hooks/AmplitudeOperations";
15
+ import { SuggestionBarLocationForMetrics } from "@envive-ai/react-hooks/types";
16
+ import { SpiffyMetricsEventName } from "@envive-ai/react-hooks/contexts/amplitudeContext";
17
+ import { SearchInputForm } from "@envive-ai/react-toolkit/SearchInputForm";
18
+ import { SearchInput, searchInputVariantClasses } from "@envive-ai/react-toolkit/SearchInput";
19
+ import { Typography } from "@envive-ai/react-toolkit/Typography";
20
+
21
+ //#region src/SearchZeroState/SearchZeroState.tsx
22
+ const SEARCH_ENTRYPOINT_INPUT_TESTID = "spiffy-search-entrypoint-input";
23
+ const SearchZeroState = ({ widgetConfig, initialIsOpen, entryPointRef }) => {
24
+ console.log("SearchZeroState: widgetConfig", widgetConfig);
25
+ const { searchZeroStateVariant, searchInputVariant, searchIconVariant, searchIconSize = 24, searchBoxPlaceholder, layout, compactLabel, initialSuggestions = [], animationSpeed = "standard", suggestionButtonConfig, includeSubtitle, usingPortal = false } = widgetConfig;
26
+ const { variant: suggestionButtonVariant, hoverVariant: suggestionButtonHoverVariant, borderRadius: suggestionButtonBorderRadius } = suggestionButtonConfig;
27
+ const [isOpen, setIsOpen] = useState(!!initialIsOpen);
28
+ const searchInputRef = useRef(null);
29
+ const searchInput = useSearch({ allowRedirect: true });
30
+ const { track } = useAmplitudeTracking();
31
+ const { recommendedProductsHeading, searchOverlayHeading, productCardConfig, merchantShortName, recommendedProducts, searchText, autocompleteResults, focusedIndex, focusedOptionId, shouldShowAutocomplete, onSearchInputChange, onSearchInputFocus, onSearchInputBlur, onKeyDown, onAutocompleteSelect, onSubmitSearch, resetSearch } = searchInput;
32
+ const { overlayBackgroundClasses, sparklesIconColor } = searchZeroStateVariantClasses[searchZeroStateVariant && searchZeroStateVariantClasses[searchZeroStateVariant] ? searchZeroStateVariant : "backgroundTertiary"];
33
+ const { searchInputIconColor } = searchInputVariantClasses[searchInputVariant];
34
+ const handleOpen = () => setIsOpen(true);
35
+ const handleClose = () => setIsOpen(false);
36
+ useEffect(() => {
37
+ if (isOpen) track(SpiffyMetricsEventName.SearchComponentVisible, { eventProps: { search_component: SpiffyWidgets.SearchZeroState } });
38
+ }, [isOpen, track]);
39
+ useEffect(() => {
40
+ if (isOpen) {
41
+ resetSearch();
42
+ searchInputRef.current?.focus();
43
+ }
44
+ }, [isOpen, resetSearch]);
45
+ const submitSearchString = useCallback((query) => {
46
+ onSearchInputChange(query);
47
+ if (onSubmitSearch && query.trim()) {
48
+ onSubmitSearch();
49
+ setIsOpen(false);
50
+ }
51
+ }, [onSubmitSearch, onSearchInputChange]);
52
+ const searchChange = (value) => {
53
+ onSearchInputChange(value);
54
+ };
55
+ if (!isOpen) {
56
+ if (layout === "icon") return /* @__PURE__ */ jsx(SearchIcon, {
57
+ entryPointRef,
58
+ size: searchIconSize,
59
+ variant: searchIconVariant,
60
+ label: compactLabel,
61
+ onClick: handleOpen,
62
+ color: searchInputIconColor
63
+ });
64
+ return /* @__PURE__ */ jsx(SearchInput, {
65
+ value: "",
66
+ onChange: () => {},
67
+ placeholder: searchBoxPlaceholder,
68
+ suggestions: [],
69
+ onFocus: handleOpen,
70
+ searchInputVariant,
71
+ dataTestId: SEARCH_ENTRYPOINT_INPUT_TESTID
72
+ });
73
+ }
74
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxs(SearchOverlay, {
75
+ role: "dialog",
76
+ ariaModal: true,
77
+ ariaLabelledby: "global-search-title",
78
+ className: overlayBackgroundClasses,
79
+ usingPortal,
80
+ children: [
81
+ /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
82
+ className: "spiffy-tw-relative spiffy-tw-mb-4",
83
+ children: [/* @__PURE__ */ jsxs("div", {
84
+ className: "spiffy-tw-flex spiffy-tw-items-center",
85
+ children: [/* @__PURE__ */ jsx(Typography, {
86
+ id: "global-search-title",
87
+ variant: "t3",
88
+ children: searchOverlayHeading
89
+ }), /* @__PURE__ */ jsx(Sparkles_default, {
90
+ className: "spiffy-tw-ml-2 spiffy-tw-h-[36px] spiffy-tw-w-[24px] sm:spiffy-tw-h-[45px] sm:spiffy-tw-w-[36px]",
91
+ color: sparklesIconColor,
92
+ stroke: "2px"
93
+ })]
94
+ }), includeSubtitle && /* @__PURE__ */ jsx(Typography, {
95
+ variant: "body2",
96
+ children: "Go ahead, get as specific as you like..."
97
+ })]
98
+ }), /* @__PURE__ */ jsx("button", {
99
+ onClick: handleClose,
100
+ className: "spiffy-tw-absolute spiffy-tw-right-4 spiffy-tw-top-4 sm:spiffy-tw-right-8 sm:spiffy-tw-top-8",
101
+ "aria-label": "Close search",
102
+ type: "button",
103
+ children: /* @__PURE__ */ jsx(IconCloseVariant_default, {
104
+ className: "spiffy-tw-h-[20px] spiffy-tw-w-[20px] sm:spiffy-tw-h-[28px] sm:spiffy-tw-w-[28px]",
105
+ strokeWidth: "2px"
106
+ })
107
+ })] }),
108
+ /* @__PURE__ */ jsx(SearchInputForm, {
109
+ searchInputRef,
110
+ searchInputVariant,
111
+ searchText,
112
+ autocompleteResults,
113
+ searchBoxPlaceholder,
114
+ focusedOptionId,
115
+ shouldShowAutocomplete,
116
+ focusedIndex,
117
+ onKeyDown,
118
+ onAutocompleteSelect,
119
+ onSearchInputChange: searchChange,
120
+ onSearchSubmit: () => submitSearchString,
121
+ onSearchInputFocus,
122
+ onSearchInputBlur
123
+ }),
124
+ /* @__PURE__ */ jsxs(AnimatePresence, { children: [initialSuggestions && initialSuggestions.length > 0 && /* @__PURE__ */ jsx(motion.div, {
125
+ className: "spiffy-tw-w-full spiffy-tw-justify-center spiffy-tw-overflow-hidden",
126
+ initial: { opacity: 0 },
127
+ animate: { opacity: 1 },
128
+ exit: { opacity: 0 },
129
+ transition: { duration: .2 },
130
+ children: /* @__PURE__ */ jsx("div", {
131
+ className: "spiffy-tw-mt-6",
132
+ children: /* @__PURE__ */ jsx(SuggestionBar, {
133
+ id: "global-search-suggestions",
134
+ locationForMetrics: SuggestionBarLocationForMetrics.SUGGESTION_BAR_TOP,
135
+ buttonTexts: initialSuggestions,
136
+ buttonBorderRadius: suggestionButtonBorderRadius,
137
+ buttonVariation: suggestionButtonVariant ?? "primary",
138
+ hoverButtonVariation: suggestionButtonHoverVariant ?? "primary",
139
+ animationSpeed,
140
+ handleReply: (message) => {
141
+ if (message.type === MessageType.QueryTyped && message.metadata?.content) {
142
+ track(SpiffyMetricsEventName.SearchZeroStateSuggestionClicked, { eventProps: {
143
+ queryText: message.metadata.content,
144
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
145
+ } });
146
+ submitSearchString(message.metadata.content);
147
+ }
148
+ },
149
+ twoRowsOnMobile: true
150
+ })
151
+ })
152
+ }), recommendedProducts.length > 0 && /* @__PURE__ */ jsx("div", {
153
+ className: "spiffy-tw-mt-[40px]",
154
+ children: /* @__PURE__ */ jsx(RecommendedProducts, {
155
+ retrievedProducts: recommendedProducts,
156
+ merchantShortName,
157
+ productCardConfig,
158
+ productGridVariant: "standard",
159
+ heading: recommendedProductsHeading
160
+ })
161
+ })] })
162
+ ]
163
+ }) });
164
+ };
165
+
166
+ //#endregion
167
+ export { SearchZeroState };
@@ -0,0 +1,23 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_SearchZeroState = require('./SearchZeroState.cjs');
3
+ let react = require("react");
4
+ let __envive_ai_react_hooks_hooks_NewOrgConfig = require("@envive-ai/react-hooks/hooks/NewOrgConfig");
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+
7
+ //#region src/SearchZeroState/SearchZeroStateWidget.tsx
8
+ const SearchZeroStateWidget = ({ initialIsOpen, widgetConfigId = "searchEntryPointIcon", entryPointRef }) => {
9
+ const newConfig = (0, __envive_ai_react_hooks_hooks_NewOrgConfig.useNewOrgConfig)();
10
+ const widgetConfig = (0, react.useMemo)(() => {
11
+ if (newConfig && newConfig.frontendConfig?.widgetConfigs) return { ...(newConfig.frontendConfig?.widgetConfigs).find((widget) => widget.key === widgetConfigId).config };
12
+ return null;
13
+ }, [newConfig, widgetConfigId]);
14
+ if (!widgetConfig) return null;
15
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SearchZeroState.SearchZeroState, {
16
+ widgetConfig,
17
+ initialIsOpen,
18
+ entryPointRef
19
+ });
20
+ };
21
+
22
+ //#endregion
23
+ exports.SearchZeroStateWidget = SearchZeroStateWidget;
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
+
3
+ //#region src/SearchZeroState/SearchZeroStateWidget.d.ts
4
+ type SearchZeroStateWidgetProps = {
5
+ initialIsOpen: boolean;
6
+ widgetConfigId?: string;
7
+ entryPointRef: React.Ref<HTMLButtonElement>;
8
+ };
9
+ declare const SearchZeroStateWidget: ({
10
+ initialIsOpen,
11
+ widgetConfigId,
12
+ entryPointRef
13
+ }: SearchZeroStateWidgetProps) => react_jsx_runtime1.JSX.Element;
14
+ //#endregion
15
+ export { SearchZeroStateWidget };
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
+
3
+ //#region src/SearchZeroState/SearchZeroStateWidget.d.ts
4
+ type SearchZeroStateWidgetProps = {
5
+ initialIsOpen: boolean;
6
+ widgetConfigId?: string;
7
+ entryPointRef: React.Ref<HTMLButtonElement>;
8
+ };
9
+ declare const SearchZeroStateWidget: ({
10
+ initialIsOpen,
11
+ widgetConfigId,
12
+ entryPointRef
13
+ }: SearchZeroStateWidgetProps) => react_jsx_runtime1.JSX.Element;
14
+ //#endregion
15
+ export { SearchZeroStateWidget };
@@ -0,0 +1,22 @@
1
+ import { SearchZeroState } from "./SearchZeroState.js";
2
+ import { useMemo } from "react";
3
+ import { useNewOrgConfig } from "@envive-ai/react-hooks/hooks/NewOrgConfig";
4
+ import { jsx } from "react/jsx-runtime";
5
+
6
+ //#region src/SearchZeroState/SearchZeroStateWidget.tsx
7
+ const SearchZeroStateWidget = ({ initialIsOpen, widgetConfigId = "searchEntryPointIcon", entryPointRef }) => {
8
+ const newConfig = useNewOrgConfig();
9
+ const widgetConfig = useMemo(() => {
10
+ if (newConfig && newConfig.frontendConfig?.widgetConfigs) return { ...(newConfig.frontendConfig?.widgetConfigs).find((widget) => widget.key === widgetConfigId).config };
11
+ return null;
12
+ }, [newConfig, widgetConfigId]);
13
+ if (!widgetConfig) return null;
14
+ return /* @__PURE__ */ jsx(SearchZeroState, {
15
+ widgetConfig,
16
+ initialIsOpen,
17
+ entryPointRef
18
+ });
19
+ };
20
+
21
+ //#endregion
22
+ export { SearchZeroStateWidget };
@@ -0,0 +1,72 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ let classnames = require("classnames");
3
+ classnames = require_rolldown_runtime.__toESM(classnames);
4
+ let react_jsx_runtime = require("react/jsx-runtime");
5
+ let __envive_ai_react_hooks_application_models = require("@envive-ai/react-hooks/application/models");
6
+ let framer_motion = require("framer-motion");
7
+ let __envive_ai_react_hooks_hooks_AmplitudeOperations = require("@envive-ai/react-hooks/hooks/AmplitudeOperations");
8
+ let __envive_ai_react_hooks_contexts_amplitudeContext = require("@envive-ai/react-hooks/contexts/amplitudeContext");
9
+ let __envive_ai_react_toolkit_Typography = require("@envive-ai/react-toolkit/Typography");
10
+ let __envive_ai_react_toolkit_ProductGrid = require("@envive-ai/react-toolkit/ProductGrid");
11
+
12
+ //#region src/SearchZeroState/components/RecommendedProducts.tsx
13
+ const RecommendedProducts = ({ retrievedProducts, merchantShortName, productCardConfig = {
14
+ variant: "minimal",
15
+ hoverVariant: "none",
16
+ layoutVariant: "square"
17
+ }, productGridVariant = "square", heading }) => {
18
+ const { track } = (0, __envive_ai_react_hooks_hooks_AmplitudeOperations.useAmplitudeTracking)();
19
+ const containerClasses = (0, classnames.default)("spiffy-tw-justify-center", "spiffy-tw-overflow-hidden", "spiffy-tw-bg-white", "spiffy-tw-relative", "spiffy-tw-px-[24px]", "spiffy-tw-py-[16px]", "sm:spiffy-tw-px-[41px]", "sm:spiffy-tw-py-[40px]");
20
+ const titleContainerClasses = (0, classnames.default)("spiffy-tw-w-full", "spiffy-tw-border-b", "spiffy-tw-border-solid", "spiffy-tw-border-b-[--spiffy-colors-text-accent]", "spiffy-tw-pb-[8px]", "spiffy-tw-mb-[16px]");
21
+ const productGridClasses = (0, classnames.default)("spiffy-tw-grid", "spiffy-tw-justify-items-stretch", "spiffy-tw-grid-cols-2", "md:spiffy-tw-grid-cols-3", "lg:spiffy-tw-grid-cols-4", "spiffy-tw-gap-x-[4px]", "spiffy-tw-gap-y-[24px]", "spiffy-tw-h-full", "spiffy-tw-w-full", "spiffy-tw-items-stretch");
22
+ if (retrievedProducts == null || retrievedProducts.length === 0) return null;
23
+ const handleProductClick = (product, index) => {
24
+ track(__envive_ai_react_hooks_contexts_amplitudeContext.SpiffyMetricsEventName.ProductCardClicked, {
25
+ eventProps: {
26
+ url: product.url,
27
+ search_response_id: void 0,
28
+ product_response_id: product.response_id,
29
+ trigger_location: __envive_ai_react_hooks_application_models.ChatElementDisplayLocation.SEARCH_ZERO_STATE_SUGGESTED_PRODUCTS,
30
+ click_position: index != null ? index + 1 : null,
31
+ title: product.title,
32
+ original_price: product.original_price,
33
+ sale_price: product.sale_price,
34
+ average_rating: product.average_rating,
35
+ number_reviews: product.number_reviews
36
+ },
37
+ alsoSendToGoogleAnalytics: true
38
+ });
39
+ };
40
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.div, {
41
+ className: containerClasses,
42
+ initial: { opacity: 0 },
43
+ animate: { opacity: 1 },
44
+ exit: { opacity: 0 },
45
+ transition: { duration: .2 },
46
+ style: {
47
+ left: "50%",
48
+ right: "50%",
49
+ marginLeft: "-50vw",
50
+ marginRight: "-50vw",
51
+ width: "100vw"
52
+ },
53
+ children: [heading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
54
+ className: titleContainerClasses,
55
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_Typography.Typography, {
56
+ variant: "h1",
57
+ className: "spiffy-tw-text-[--spiffy-colors-text-accent]",
58
+ children: heading
59
+ })
60
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__envive_ai_react_toolkit_ProductGrid.ProductGrid, {
61
+ productList: retrievedProducts,
62
+ productGridVariant,
63
+ productGridClasses,
64
+ productCardConfig,
65
+ merchantShortName,
66
+ onProductClick: handleProductClick
67
+ })]
68
+ });
69
+ };
70
+
71
+ //#endregion
72
+ exports.RecommendedProducts = RecommendedProducts;
@@ -0,0 +1,70 @@
1
+ import classNames from "classnames";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { ChatElementDisplayLocation } from "@envive-ai/react-hooks/application/models";
4
+ import { motion } from "framer-motion";
5
+ import { useAmplitudeTracking } from "@envive-ai/react-hooks/hooks/AmplitudeOperations";
6
+ import { SpiffyMetricsEventName } from "@envive-ai/react-hooks/contexts/amplitudeContext";
7
+ import { Typography } from "@envive-ai/react-toolkit/Typography";
8
+ import { ProductGrid } from "@envive-ai/react-toolkit/ProductGrid";
9
+
10
+ //#region src/SearchZeroState/components/RecommendedProducts.tsx
11
+ const RecommendedProducts = ({ retrievedProducts, merchantShortName, productCardConfig = {
12
+ variant: "minimal",
13
+ hoverVariant: "none",
14
+ layoutVariant: "square"
15
+ }, productGridVariant = "square", heading }) => {
16
+ const { track } = useAmplitudeTracking();
17
+ const containerClasses = classNames("spiffy-tw-justify-center", "spiffy-tw-overflow-hidden", "spiffy-tw-bg-white", "spiffy-tw-relative", "spiffy-tw-px-[24px]", "spiffy-tw-py-[16px]", "sm:spiffy-tw-px-[41px]", "sm:spiffy-tw-py-[40px]");
18
+ const titleContainerClasses = classNames("spiffy-tw-w-full", "spiffy-tw-border-b", "spiffy-tw-border-solid", "spiffy-tw-border-b-[--spiffy-colors-text-accent]", "spiffy-tw-pb-[8px]", "spiffy-tw-mb-[16px]");
19
+ const productGridClasses = classNames("spiffy-tw-grid", "spiffy-tw-justify-items-stretch", "spiffy-tw-grid-cols-2", "md:spiffy-tw-grid-cols-3", "lg:spiffy-tw-grid-cols-4", "spiffy-tw-gap-x-[4px]", "spiffy-tw-gap-y-[24px]", "spiffy-tw-h-full", "spiffy-tw-w-full", "spiffy-tw-items-stretch");
20
+ if (retrievedProducts == null || retrievedProducts.length === 0) return null;
21
+ const handleProductClick = (product, index) => {
22
+ track(SpiffyMetricsEventName.ProductCardClicked, {
23
+ eventProps: {
24
+ url: product.url,
25
+ search_response_id: void 0,
26
+ product_response_id: product.response_id,
27
+ trigger_location: ChatElementDisplayLocation.SEARCH_ZERO_STATE_SUGGESTED_PRODUCTS,
28
+ click_position: index != null ? index + 1 : null,
29
+ title: product.title,
30
+ original_price: product.original_price,
31
+ sale_price: product.sale_price,
32
+ average_rating: product.average_rating,
33
+ number_reviews: product.number_reviews
34
+ },
35
+ alsoSendToGoogleAnalytics: true
36
+ });
37
+ };
38
+ return /* @__PURE__ */ jsxs(motion.div, {
39
+ className: containerClasses,
40
+ initial: { opacity: 0 },
41
+ animate: { opacity: 1 },
42
+ exit: { opacity: 0 },
43
+ transition: { duration: .2 },
44
+ style: {
45
+ left: "50%",
46
+ right: "50%",
47
+ marginLeft: "-50vw",
48
+ marginRight: "-50vw",
49
+ width: "100vw"
50
+ },
51
+ children: [heading && /* @__PURE__ */ jsx("div", {
52
+ className: titleContainerClasses,
53
+ children: /* @__PURE__ */ jsx(Typography, {
54
+ variant: "h1",
55
+ className: "spiffy-tw-text-[--spiffy-colors-text-accent]",
56
+ children: heading
57
+ })
58
+ }), /* @__PURE__ */ jsx(ProductGrid, {
59
+ productList: retrievedProducts,
60
+ productGridVariant,
61
+ productGridClasses,
62
+ productCardConfig,
63
+ merchantShortName,
64
+ onProductClick: handleProductClick
65
+ })]
66
+ });
67
+ };
68
+
69
+ //#endregion
70
+ export { RecommendedProducts };