@customerhero/react 2.2.0 → 2.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.
- package/README.md +19 -0
- package/dist/chunk-BB2DI7WR.js +2932 -0
- package/dist/index.cjs +254 -142
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +20 -2820
- package/dist/preview.cjs +2976 -0
- package/dist/preview.d.cts +32 -0
- package/dist/preview.d.ts +32 -0
- package/dist/preview.js +53 -0
- package/package.json +12 -2
package/dist/index.cjs
CHANGED
|
@@ -18,16 +18,16 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
23
|
ActionConfirmationCard: () => ActionConfirmationCard,
|
|
24
24
|
ChatWidget: () => ChatWidget,
|
|
25
25
|
useChat: () => useChat
|
|
26
26
|
});
|
|
27
|
-
module.exports = __toCommonJS(
|
|
27
|
+
module.exports = __toCommonJS(src_exports);
|
|
28
28
|
|
|
29
29
|
// src/components/chat-widget.tsx
|
|
30
|
-
var
|
|
30
|
+
var import_react12 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/context.tsx
|
|
33
33
|
var import_react = require("react");
|
|
@@ -36,6 +36,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
36
36
|
var CustomerHeroContext = (0, import_react.createContext)(null);
|
|
37
37
|
function CustomerHeroProvider({
|
|
38
38
|
children,
|
|
39
|
+
disableAutoFetch,
|
|
39
40
|
...config
|
|
40
41
|
}) {
|
|
41
42
|
const clientRef = (0, import_react.useRef)(null);
|
|
@@ -43,8 +44,9 @@ function CustomerHeroProvider({
|
|
|
43
44
|
clientRef.current = new import_js.CustomerHeroChat(config);
|
|
44
45
|
}
|
|
45
46
|
(0, import_react.useEffect)(() => {
|
|
47
|
+
if (disableAutoFetch) return;
|
|
46
48
|
clientRef.current?.fetchConfig();
|
|
47
|
-
}, []);
|
|
49
|
+
}, [disableAutoFetch]);
|
|
48
50
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CustomerHeroContext.Provider, { value: clientRef.current, children });
|
|
49
51
|
}
|
|
50
52
|
function useCustomerHeroClient() {
|
|
@@ -127,7 +129,7 @@ function useChat() {
|
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
// src/components/chat-bubble.tsx
|
|
130
|
-
var
|
|
132
|
+
var import_react5 = require("react");
|
|
131
133
|
|
|
132
134
|
// src/use-reduced-motion.ts
|
|
133
135
|
var import_react3 = require("react");
|
|
@@ -145,41 +147,110 @@ function useReducedMotion() {
|
|
|
145
147
|
return reduced;
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
// src/use-effective-theme.ts
|
|
151
|
+
var import_js2 = require("@customerhero/js");
|
|
152
|
+
|
|
153
|
+
// src/use-prefers-dark.ts
|
|
154
|
+
var import_react4 = require("react");
|
|
155
|
+
function usePrefersDark() {
|
|
156
|
+
const [prefersDark, setPrefersDark] = (0, import_react4.useState)(false);
|
|
157
|
+
(0, import_react4.useEffect)(() => {
|
|
158
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
162
|
+
const update = () => setPrefersDark(mq.matches);
|
|
163
|
+
update();
|
|
164
|
+
if (typeof mq.addEventListener === "function") {
|
|
165
|
+
mq.addEventListener("change", update);
|
|
166
|
+
return () => mq.removeEventListener("change", update);
|
|
167
|
+
}
|
|
168
|
+
mq.addListener(update);
|
|
169
|
+
return () => mq.removeListener(update);
|
|
170
|
+
}, []);
|
|
171
|
+
return prefersDark;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/use-effective-theme.ts
|
|
175
|
+
function useEffectiveTheme() {
|
|
176
|
+
const { config } = useChat();
|
|
177
|
+
const prefersDark = usePrefersDark();
|
|
178
|
+
const scheme = (0, import_js2.resolveScheme)(config.colorScheme, prefersDark);
|
|
179
|
+
const colors = (0, import_js2.effectiveColors)(config, scheme);
|
|
180
|
+
const isDark = scheme === "dark";
|
|
181
|
+
return {
|
|
182
|
+
scheme,
|
|
183
|
+
primary: colors.primary,
|
|
184
|
+
background: colors.background,
|
|
185
|
+
text: colors.text,
|
|
186
|
+
bubbleBackground: isDark ? "rgba(255,255,255,0.08)" : "#f0f0f0",
|
|
187
|
+
divider: isDark ? "rgba(255,255,255,0.12)" : "#e0e0e0",
|
|
188
|
+
size: (0, import_js2.sizePreset)(config.size),
|
|
189
|
+
radius: (0, import_js2.panelRadius)(config.cornerStyle)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
148
193
|
// src/components/chat-bubble.tsx
|
|
149
194
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
150
|
-
function ChatBubble() {
|
|
195
|
+
function ChatBubble({ embedded } = {}) {
|
|
151
196
|
const { toggle, config, t, isRtl } = useChat();
|
|
152
197
|
const reduced = useReducedMotion();
|
|
153
|
-
const
|
|
154
|
-
(0,
|
|
198
|
+
const theme = useEffectiveTheme();
|
|
199
|
+
const [mounted, setMounted] = (0, import_react5.useState)(false);
|
|
200
|
+
(0, import_react5.useEffect)(() => {
|
|
155
201
|
const id = requestAnimationFrame(() => setMounted(true));
|
|
156
202
|
return () => cancelAnimationFrame(id);
|
|
157
203
|
}, []);
|
|
158
204
|
const visible = mounted;
|
|
159
205
|
const effectivePosition = isRtl ? config.position === "bottom-right" ? "bottom-left" : "bottom-right" : config.position;
|
|
206
|
+
const colors = theme;
|
|
207
|
+
const preset = theme.size;
|
|
208
|
+
const hasLabel = !!config.launcher.label;
|
|
209
|
+
const width = hasLabel ? "auto" : preset.bubble;
|
|
210
|
+
const height = preset.bubble;
|
|
211
|
+
const borderRadius = hasLabel ? preset.bubble / 2 : "50%";
|
|
160
212
|
const style = {
|
|
161
|
-
position: "fixed",
|
|
162
|
-
bottom:
|
|
163
|
-
[effectivePosition === "bottom-left" ? "left" : "right"]:
|
|
164
|
-
width
|
|
165
|
-
height
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
213
|
+
position: embedded ? "absolute" : "fixed",
|
|
214
|
+
bottom: config.offset.bottom,
|
|
215
|
+
[effectivePosition === "bottom-left" ? "left" : "right"]: config.offset.side,
|
|
216
|
+
width,
|
|
217
|
+
height,
|
|
218
|
+
minWidth: preset.bubble,
|
|
219
|
+
paddingInline: hasLabel ? Math.round(preset.bubble * 0.35) : 0,
|
|
220
|
+
borderRadius,
|
|
221
|
+
background: colors.primary,
|
|
222
|
+
color: "#FFFFFF",
|
|
169
223
|
display: "flex",
|
|
170
224
|
alignItems: "center",
|
|
171
225
|
justifyContent: "center",
|
|
226
|
+
gap: hasLabel ? 8 : 0,
|
|
172
227
|
cursor: "pointer",
|
|
173
|
-
boxShadow: "0 4px 20px rgba(0,0,0,0.15)",
|
|
174
|
-
zIndex:
|
|
228
|
+
boxShadow: theme.scheme === "dark" ? "0 6px 20px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06)" : "0 4px 20px rgba(0,0,0,0.15)",
|
|
229
|
+
zIndex: config.zIndex,
|
|
175
230
|
border: "none",
|
|
176
|
-
|
|
231
|
+
fontSize: preset.fontSize,
|
|
232
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
233
|
+
fontWeight: 500,
|
|
177
234
|
opacity: visible ? 1 : 0,
|
|
178
235
|
transform: visible ? "scale(1)" : "scale(0.6)",
|
|
179
236
|
transition: reduced ? "none" : "opacity 0.25s ease, transform 0.25s ease",
|
|
180
237
|
pointerEvents: visible ? "auto" : "none"
|
|
181
238
|
};
|
|
182
|
-
|
|
239
|
+
const iconSize = Math.round(preset.bubble * 0.43);
|
|
240
|
+
const dotSize = Math.max(10, Math.round(preset.bubble * 0.22));
|
|
241
|
+
const dotOffset = Math.round(preset.bubble * 0.08);
|
|
242
|
+
const dotStyle = {
|
|
243
|
+
position: "absolute",
|
|
244
|
+
top: dotOffset,
|
|
245
|
+
[effectivePosition === "bottom-left" ? "left" : "right"]: dotOffset,
|
|
246
|
+
width: dotSize,
|
|
247
|
+
height: dotSize,
|
|
248
|
+
borderRadius: "50%",
|
|
249
|
+
background: "#22c55e",
|
|
250
|
+
border: "2px solid rgba(255,255,255,0.9)",
|
|
251
|
+
pointerEvents: "none"
|
|
252
|
+
};
|
|
253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
183
254
|
"button",
|
|
184
255
|
{
|
|
185
256
|
onClick: toggle,
|
|
@@ -187,41 +258,55 @@ function ChatBubble() {
|
|
|
187
258
|
dir: isRtl ? "rtl" : "ltr",
|
|
188
259
|
"aria-label": t("open_chat"),
|
|
189
260
|
onMouseEnter: (e) => {
|
|
190
|
-
if (!reduced) e.currentTarget.style.transform = "scale(1.
|
|
261
|
+
if (!reduced) e.currentTarget.style.transform = "scale(1.06)";
|
|
191
262
|
},
|
|
192
263
|
onMouseLeave: (e) => {
|
|
193
264
|
if (!reduced) e.currentTarget.style.transform = "scale(1)";
|
|
194
265
|
},
|
|
195
|
-
children:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
266
|
+
children: [
|
|
267
|
+
config.launcher.iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
268
|
+
"img",
|
|
269
|
+
{
|
|
270
|
+
src: config.launcher.iconUrl,
|
|
271
|
+
alt: "",
|
|
272
|
+
width: iconSize,
|
|
273
|
+
height: iconSize,
|
|
274
|
+
style: { display: "block" }
|
|
275
|
+
}
|
|
276
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
277
|
+
"svg",
|
|
278
|
+
{
|
|
279
|
+
width: iconSize,
|
|
280
|
+
height: iconSize,
|
|
281
|
+
viewBox: "0 0 24 24",
|
|
282
|
+
fill: "none",
|
|
283
|
+
stroke: "currentColor",
|
|
284
|
+
strokeWidth: "2",
|
|
285
|
+
strokeLinecap: "round",
|
|
286
|
+
strokeLinejoin: "round",
|
|
287
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
288
|
+
}
|
|
289
|
+
),
|
|
290
|
+
hasLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: config.launcher.label }),
|
|
291
|
+
config.launcher.showOnlineDot && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: dotStyle, "aria-hidden": true })
|
|
292
|
+
]
|
|
209
293
|
}
|
|
210
294
|
);
|
|
211
295
|
}
|
|
212
296
|
|
|
213
297
|
// src/components/chat-window.tsx
|
|
214
|
-
var
|
|
298
|
+
var import_react11 = require("react");
|
|
215
299
|
|
|
216
300
|
// src/components/chat-header.tsx
|
|
217
|
-
var
|
|
301
|
+
var import_react6 = require("react");
|
|
218
302
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
219
303
|
function ChatHeader() {
|
|
220
304
|
const { config, close, reset, t } = useChat();
|
|
221
305
|
const reduced = useReducedMotion();
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
(0,
|
|
306
|
+
const theme = useEffectiveTheme();
|
|
307
|
+
const [menuOpen, setMenuOpen] = (0, import_react6.useState)(false);
|
|
308
|
+
const menuRef = (0, import_react6.useRef)(null);
|
|
309
|
+
(0, import_react6.useEffect)(() => {
|
|
225
310
|
if (!menuOpen) return;
|
|
226
311
|
const handleClick = (e) => {
|
|
227
312
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
@@ -232,7 +317,7 @@ function ChatHeader() {
|
|
|
232
317
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
233
318
|
}, [menuOpen]);
|
|
234
319
|
const headerStyle = {
|
|
235
|
-
background:
|
|
320
|
+
background: theme.primary,
|
|
236
321
|
padding: 16,
|
|
237
322
|
display: "flex",
|
|
238
323
|
alignItems: "center",
|
|
@@ -267,14 +352,16 @@ function ChatHeader() {
|
|
|
267
352
|
opacity: 0.7,
|
|
268
353
|
padding: 4
|
|
269
354
|
};
|
|
355
|
+
const isDark = theme.scheme === "dark";
|
|
270
356
|
const menuStyle = {
|
|
271
357
|
position: "absolute",
|
|
272
358
|
top: "100%",
|
|
273
359
|
right: 0,
|
|
274
360
|
marginTop: 4,
|
|
275
|
-
background:
|
|
361
|
+
background: theme.background,
|
|
362
|
+
border: `1px solid ${theme.divider}`,
|
|
276
363
|
borderRadius: 8,
|
|
277
|
-
boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
|
|
364
|
+
boxShadow: isDark ? "0 4px 16px rgba(0,0,0,0.5)" : "0 4px 16px rgba(0,0,0,0.15)",
|
|
278
365
|
minWidth: 180,
|
|
279
366
|
overflow: "hidden",
|
|
280
367
|
zIndex: 10,
|
|
@@ -291,7 +378,7 @@ function ChatHeader() {
|
|
|
291
378
|
background: "none",
|
|
292
379
|
cursor: "pointer",
|
|
293
380
|
fontSize: 13,
|
|
294
|
-
color:
|
|
381
|
+
color: theme.text,
|
|
295
382
|
textAlign: "left",
|
|
296
383
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
|
|
297
384
|
};
|
|
@@ -368,7 +455,7 @@ function ChatHeader() {
|
|
|
368
455
|
reset();
|
|
369
456
|
},
|
|
370
457
|
onMouseEnter: (e) => {
|
|
371
|
-
e.currentTarget.style.background =
|
|
458
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
372
459
|
},
|
|
373
460
|
onMouseLeave: (e) => {
|
|
374
461
|
e.currentTarget.style.background = "none";
|
|
@@ -430,7 +517,7 @@ function ChatHeader() {
|
|
|
430
517
|
}
|
|
431
518
|
|
|
432
519
|
// src/components/chat-messages.tsx
|
|
433
|
-
var
|
|
520
|
+
var import_react8 = require("react");
|
|
434
521
|
|
|
435
522
|
// src/markdown/render.tsx
|
|
436
523
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -797,7 +884,7 @@ function renderMarkdown(source, opts = {}) {
|
|
|
797
884
|
}
|
|
798
885
|
|
|
799
886
|
// src/components/action-confirmation-card.tsx
|
|
800
|
-
var
|
|
887
|
+
var import_react7 = require("react");
|
|
801
888
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
802
889
|
function ActionConfirmationCard({
|
|
803
890
|
block,
|
|
@@ -806,10 +893,10 @@ function ActionConfirmationCard({
|
|
|
806
893
|
onApprove,
|
|
807
894
|
onCancel
|
|
808
895
|
}) {
|
|
809
|
-
const [chosen, setChosen] = (0,
|
|
810
|
-
const [showSpinner, setShowSpinner] = (0,
|
|
811
|
-
const [error, setError] = (0,
|
|
812
|
-
const [showSummary, setShowSummary] = (0,
|
|
896
|
+
const [chosen, setChosen] = (0, import_react7.useState)(null);
|
|
897
|
+
const [showSpinner, setShowSpinner] = (0, import_react7.useState)(false);
|
|
898
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
899
|
+
const [showSummary, setShowSummary] = (0, import_react7.useState)(false);
|
|
813
900
|
const handle = async (choice) => {
|
|
814
901
|
if (chosen) return;
|
|
815
902
|
setChosen(choice);
|
|
@@ -1037,7 +1124,7 @@ function MessageRatingButtons({
|
|
|
1037
1124
|
t,
|
|
1038
1125
|
reduced
|
|
1039
1126
|
}) {
|
|
1040
|
-
const [rated, setRated] = (0,
|
|
1127
|
+
const [rated, setRated] = (0, import_react8.useState)(null);
|
|
1041
1128
|
const handleRate = (rating) => {
|
|
1042
1129
|
setRated(rating);
|
|
1043
1130
|
onRate(messageId, rating);
|
|
@@ -1118,8 +1205,8 @@ function AnimatedMessage({
|
|
|
1118
1205
|
animate,
|
|
1119
1206
|
reduced
|
|
1120
1207
|
}) {
|
|
1121
|
-
const [visible, setVisible] = (0,
|
|
1122
|
-
(0,
|
|
1208
|
+
const [visible, setVisible] = (0, import_react8.useState)(!animate);
|
|
1209
|
+
(0, import_react8.useEffect)(() => {
|
|
1123
1210
|
if (!animate || reduced) {
|
|
1124
1211
|
setVisible(true);
|
|
1125
1212
|
return;
|
|
@@ -1264,7 +1351,7 @@ function Message({
|
|
|
1264
1351
|
color: "white",
|
|
1265
1352
|
borderBottomRightRadius: 4
|
|
1266
1353
|
} : {
|
|
1267
|
-
background:
|
|
1354
|
+
background: config.bubbleBackground,
|
|
1268
1355
|
color: config.textColor,
|
|
1269
1356
|
borderBottomLeftRadius: 4
|
|
1270
1357
|
}
|
|
@@ -1360,7 +1447,6 @@ function ChatMessages() {
|
|
|
1360
1447
|
messages,
|
|
1361
1448
|
isLoading,
|
|
1362
1449
|
error,
|
|
1363
|
-
config,
|
|
1364
1450
|
conversationId,
|
|
1365
1451
|
rateMessage,
|
|
1366
1452
|
sendMessage,
|
|
@@ -1368,13 +1454,19 @@ function ChatMessages() {
|
|
|
1368
1454
|
cancelAction,
|
|
1369
1455
|
t
|
|
1370
1456
|
} = useChat();
|
|
1457
|
+
const theme = useEffectiveTheme();
|
|
1458
|
+
const themedConfig = {
|
|
1459
|
+
primaryColor: theme.primary,
|
|
1460
|
+
textColor: theme.text,
|
|
1461
|
+
bubbleBackground: theme.bubbleBackground
|
|
1462
|
+
};
|
|
1371
1463
|
const reduced = useReducedMotion();
|
|
1372
|
-
const containerRef = (0,
|
|
1373
|
-
const messagesEndRef = (0,
|
|
1374
|
-
const isFirstRender = (0,
|
|
1375
|
-
const prevMessageCount = (0,
|
|
1376
|
-
const stickRef = (0,
|
|
1377
|
-
const suppressScrollRef = (0,
|
|
1464
|
+
const containerRef = (0, import_react8.useRef)(null);
|
|
1465
|
+
const messagesEndRef = (0, import_react8.useRef)(null);
|
|
1466
|
+
const isFirstRender = (0, import_react8.useRef)(true);
|
|
1467
|
+
const prevMessageCount = (0, import_react8.useRef)(0);
|
|
1468
|
+
const stickRef = (0, import_react8.useRef)(true);
|
|
1469
|
+
const suppressScrollRef = (0, import_react8.useRef)(false);
|
|
1378
1470
|
const autoScrollTo = (top) => {
|
|
1379
1471
|
const el = containerRef.current;
|
|
1380
1472
|
if (!el) return;
|
|
@@ -1391,7 +1483,7 @@ function ChatMessages() {
|
|
|
1391
1483
|
const distFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
1392
1484
|
stickRef.current = distFromBottom < 60;
|
|
1393
1485
|
};
|
|
1394
|
-
(0,
|
|
1486
|
+
(0, import_react8.useEffect)(() => {
|
|
1395
1487
|
const el = containerRef.current;
|
|
1396
1488
|
if (!el) return;
|
|
1397
1489
|
const lastMsg2 = messages[messages.length - 1];
|
|
@@ -1416,7 +1508,7 @@ function ChatMessages() {
|
|
|
1416
1508
|
isFirstRender.current = false;
|
|
1417
1509
|
}, [messages, isLoading, reduced]);
|
|
1418
1510
|
const newStartIndex = isFirstRender.current ? messages.length : prevMessageCount.current;
|
|
1419
|
-
(0,
|
|
1511
|
+
(0, import_react8.useEffect)(() => {
|
|
1420
1512
|
prevMessageCount.current = messages.length;
|
|
1421
1513
|
}, [messages.length]);
|
|
1422
1514
|
let lastBotIndex = -1;
|
|
@@ -1441,7 +1533,7 @@ function ChatMessages() {
|
|
|
1441
1533
|
Message,
|
|
1442
1534
|
{
|
|
1443
1535
|
message: msg,
|
|
1444
|
-
config,
|
|
1536
|
+
config: themedConfig,
|
|
1445
1537
|
onRate: rateMessage,
|
|
1446
1538
|
onSend: sendMessage,
|
|
1447
1539
|
onApproveAction: approveAction,
|
|
@@ -1480,10 +1572,13 @@ var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
|
1480
1572
|
function ChatSuggestions() {
|
|
1481
1573
|
const { messages, isLoading, config, sendMessage } = useChat();
|
|
1482
1574
|
const reduced = useReducedMotion();
|
|
1575
|
+
const theme = useEffectiveTheme();
|
|
1483
1576
|
const hasUserMessage = messages.some((m) => m.role === "user");
|
|
1484
1577
|
if (config.suggestedMessages.length === 0 || hasUserMessage || isLoading) {
|
|
1485
1578
|
return null;
|
|
1486
1579
|
}
|
|
1580
|
+
const isDark = theme.scheme === "dark";
|
|
1581
|
+
const idleBorder = isDark ? "rgba(255,255,255,0.18)" : "#e0e0e0";
|
|
1487
1582
|
const containerStyle = {
|
|
1488
1583
|
padding: "8px 16px",
|
|
1489
1584
|
display: "flex",
|
|
@@ -1493,11 +1588,11 @@ function ChatSuggestions() {
|
|
|
1493
1588
|
};
|
|
1494
1589
|
const chipStyle = {
|
|
1495
1590
|
background: "none",
|
|
1496
|
-
border:
|
|
1591
|
+
border: `1px solid ${idleBorder}`,
|
|
1497
1592
|
borderRadius: 20,
|
|
1498
1593
|
padding: "7px 14px",
|
|
1499
1594
|
fontSize: 13,
|
|
1500
|
-
color:
|
|
1595
|
+
color: theme.text,
|
|
1501
1596
|
cursor: "pointer",
|
|
1502
1597
|
textAlign: "left",
|
|
1503
1598
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
@@ -1509,11 +1604,11 @@ function ChatSuggestions() {
|
|
|
1509
1604
|
style: chipStyle,
|
|
1510
1605
|
onClick: () => sendMessage(text),
|
|
1511
1606
|
onMouseEnter: (e) => {
|
|
1512
|
-
e.currentTarget.style.borderColor =
|
|
1513
|
-
e.currentTarget.style.background = `${
|
|
1607
|
+
e.currentTarget.style.borderColor = theme.primary;
|
|
1608
|
+
e.currentTarget.style.background = `${theme.primary}14`;
|
|
1514
1609
|
},
|
|
1515
1610
|
onMouseLeave: (e) => {
|
|
1516
|
-
e.currentTarget.style.borderColor =
|
|
1611
|
+
e.currentTarget.style.borderColor = idleBorder;
|
|
1517
1612
|
e.currentTarget.style.background = "none";
|
|
1518
1613
|
},
|
|
1519
1614
|
children: text
|
|
@@ -1523,8 +1618,8 @@ function ChatSuggestions() {
|
|
|
1523
1618
|
}
|
|
1524
1619
|
|
|
1525
1620
|
// src/components/chat-input.tsx
|
|
1526
|
-
var
|
|
1527
|
-
var
|
|
1621
|
+
var import_react9 = require("react");
|
|
1622
|
+
var import_js3 = require("@customerhero/js");
|
|
1528
1623
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1529
1624
|
var MAX_ATTACHMENTS = 3;
|
|
1530
1625
|
var ALLOWED_MIME_TYPES = [
|
|
@@ -1542,47 +1637,50 @@ function ChatInput() {
|
|
|
1542
1637
|
sendMessage,
|
|
1543
1638
|
uploadAttachment,
|
|
1544
1639
|
isLoading,
|
|
1640
|
+
readOnly,
|
|
1545
1641
|
config,
|
|
1546
1642
|
t,
|
|
1547
1643
|
consumePendingPrefill,
|
|
1548
1644
|
pendingPrefill
|
|
1549
1645
|
} = useChat();
|
|
1646
|
+
const theme = useEffectiveTheme();
|
|
1647
|
+
const isDark = theme.scheme === "dark";
|
|
1550
1648
|
const reduced = useReducedMotion();
|
|
1551
|
-
const [value, setValue] = (0,
|
|
1552
|
-
const [attachments, setAttachments] = (0,
|
|
1553
|
-
const [captureSupported, setCaptureSupported] = (0,
|
|
1554
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
1555
|
-
const [dragActive, setDragActive] = (0,
|
|
1556
|
-
const [transientError, setTransientError] = (0,
|
|
1557
|
-
const fileInputRef = (0,
|
|
1558
|
-
const textInputRef = (0,
|
|
1559
|
-
const menuRef = (0,
|
|
1560
|
-
const menuButtonRef = (0,
|
|
1561
|
-
const dragCounterRef = (0,
|
|
1562
|
-
(0,
|
|
1563
|
-
setCaptureSupported((0,
|
|
1649
|
+
const [value, setValue] = (0, import_react9.useState)("");
|
|
1650
|
+
const [attachments, setAttachments] = (0, import_react9.useState)([]);
|
|
1651
|
+
const [captureSupported, setCaptureSupported] = (0, import_react9.useState)(false);
|
|
1652
|
+
const [menuOpen, setMenuOpen] = (0, import_react9.useState)(false);
|
|
1653
|
+
const [dragActive, setDragActive] = (0, import_react9.useState)(false);
|
|
1654
|
+
const [transientError, setTransientError] = (0, import_react9.useState)(null);
|
|
1655
|
+
const fileInputRef = (0, import_react9.useRef)(null);
|
|
1656
|
+
const textInputRef = (0, import_react9.useRef)(null);
|
|
1657
|
+
const menuRef = (0, import_react9.useRef)(null);
|
|
1658
|
+
const menuButtonRef = (0, import_react9.useRef)(null);
|
|
1659
|
+
const dragCounterRef = (0, import_react9.useRef)(0);
|
|
1660
|
+
(0, import_react9.useEffect)(() => {
|
|
1661
|
+
setCaptureSupported((0, import_js3.canCaptureScreenshot)());
|
|
1564
1662
|
}, []);
|
|
1565
|
-
(0,
|
|
1663
|
+
(0, import_react9.useEffect)(() => {
|
|
1566
1664
|
const id = requestAnimationFrame(() => textInputRef.current?.focus());
|
|
1567
1665
|
return () => cancelAnimationFrame(id);
|
|
1568
1666
|
}, []);
|
|
1569
|
-
(0,
|
|
1667
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
1570
1668
|
const el = textInputRef.current;
|
|
1571
1669
|
if (!el) return;
|
|
1572
1670
|
el.style.height = "auto";
|
|
1573
1671
|
el.style.height = `${el.scrollHeight}px`;
|
|
1574
1672
|
}, [value]);
|
|
1575
|
-
(0,
|
|
1673
|
+
(0, import_react9.useEffect)(() => {
|
|
1576
1674
|
if (pendingPrefill === null) return;
|
|
1577
1675
|
const text = consumePendingPrefill();
|
|
1578
1676
|
if (text !== null) setValue(text);
|
|
1579
1677
|
}, [pendingPrefill, consumePendingPrefill]);
|
|
1580
|
-
(0,
|
|
1678
|
+
(0, import_react9.useEffect)(() => {
|
|
1581
1679
|
return () => {
|
|
1582
1680
|
for (const a of attachments) URL.revokeObjectURL(a.previewUrl);
|
|
1583
1681
|
};
|
|
1584
1682
|
}, []);
|
|
1585
|
-
(0,
|
|
1683
|
+
(0, import_react9.useEffect)(() => {
|
|
1586
1684
|
if (!menuOpen) return;
|
|
1587
1685
|
const onClick = (e) => {
|
|
1588
1686
|
const target = e.target;
|
|
@@ -1601,7 +1699,7 @@ function ChatInput() {
|
|
|
1601
1699
|
document.removeEventListener("keydown", onKey);
|
|
1602
1700
|
};
|
|
1603
1701
|
}, [menuOpen]);
|
|
1604
|
-
(0,
|
|
1702
|
+
(0, import_react9.useEffect)(() => {
|
|
1605
1703
|
if (!transientError) return;
|
|
1606
1704
|
const id = window.setTimeout(() => setTransientError(null), 4e3);
|
|
1607
1705
|
return () => window.clearTimeout(id);
|
|
@@ -1657,10 +1755,10 @@ function ChatInput() {
|
|
|
1657
1755
|
const handleCapture = async () => {
|
|
1658
1756
|
setMenuOpen(false);
|
|
1659
1757
|
try {
|
|
1660
|
-
const blob = await (0,
|
|
1758
|
+
const blob = await (0, import_js3.captureScreenshot)();
|
|
1661
1759
|
await startUpload(blob);
|
|
1662
1760
|
} catch (e) {
|
|
1663
|
-
if (e instanceof
|
|
1761
|
+
if (e instanceof import_js3.ScreenshotCancelled) return;
|
|
1664
1762
|
}
|
|
1665
1763
|
};
|
|
1666
1764
|
const handlePickFile = () => {
|
|
@@ -1742,7 +1840,7 @@ function ChatInput() {
|
|
|
1742
1840
|
const containerStyle = {
|
|
1743
1841
|
position: "relative",
|
|
1744
1842
|
padding: "12px 16px",
|
|
1745
|
-
borderTop:
|
|
1843
|
+
borderTop: `1px solid ${theme.divider}`,
|
|
1746
1844
|
display: "flex",
|
|
1747
1845
|
flexDirection: "column",
|
|
1748
1846
|
gap: 8
|
|
@@ -1757,14 +1855,14 @@ function ChatInput() {
|
|
|
1757
1855
|
const TEXTAREA_MAX_HEIGHT = 140;
|
|
1758
1856
|
const inputStyle = {
|
|
1759
1857
|
flex: 1,
|
|
1760
|
-
border:
|
|
1858
|
+
border: `1px solid ${theme.divider}`,
|
|
1761
1859
|
borderRadius: 18,
|
|
1762
1860
|
padding: "10px 16px",
|
|
1763
1861
|
fontSize: 14,
|
|
1764
1862
|
lineHeight: 1.4,
|
|
1765
1863
|
outline: "none",
|
|
1766
|
-
background: "#fafafa",
|
|
1767
|
-
color:
|
|
1864
|
+
background: isDark ? "rgba(255,255,255,0.06)" : "#fafafa",
|
|
1865
|
+
color: theme.text,
|
|
1768
1866
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
1769
1867
|
resize: "none",
|
|
1770
1868
|
overflowY: "auto",
|
|
@@ -1775,7 +1873,7 @@ function ChatInput() {
|
|
|
1775
1873
|
width: 36,
|
|
1776
1874
|
height: 36,
|
|
1777
1875
|
borderRadius: "50%",
|
|
1778
|
-
background:
|
|
1876
|
+
background: theme.primary,
|
|
1779
1877
|
border: "none",
|
|
1780
1878
|
color: "white",
|
|
1781
1879
|
cursor: isLoading ? "not-allowed" : "pointer",
|
|
@@ -1805,10 +1903,10 @@ function ChatInput() {
|
|
|
1805
1903
|
position: "absolute",
|
|
1806
1904
|
bottom: "calc(100% + 4px)",
|
|
1807
1905
|
left: 0,
|
|
1808
|
-
background:
|
|
1809
|
-
border:
|
|
1906
|
+
background: theme.background,
|
|
1907
|
+
border: `1px solid ${theme.divider}`,
|
|
1810
1908
|
borderRadius: 8,
|
|
1811
|
-
boxShadow: "0 4px 16px rgba(0,0,0,0.12)",
|
|
1909
|
+
boxShadow: isDark ? "0 4px 16px rgba(0,0,0,0.5)" : "0 4px 16px rgba(0,0,0,0.12)",
|
|
1812
1910
|
padding: 4,
|
|
1813
1911
|
minWidth: 180,
|
|
1814
1912
|
zIndex: 10,
|
|
@@ -1825,7 +1923,7 @@ function ChatInput() {
|
|
|
1825
1923
|
borderRadius: 4,
|
|
1826
1924
|
cursor: "pointer",
|
|
1827
1925
|
fontSize: 14,
|
|
1828
|
-
color:
|
|
1926
|
+
color: theme.text,
|
|
1829
1927
|
textAlign: "left",
|
|
1830
1928
|
whiteSpace: "nowrap",
|
|
1831
1929
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
|
|
@@ -1833,13 +1931,13 @@ function ChatInput() {
|
|
|
1833
1931
|
const dropOverlayStyle = {
|
|
1834
1932
|
position: "absolute",
|
|
1835
1933
|
inset: 0,
|
|
1836
|
-
background: "rgba(255,255,255,0.92)",
|
|
1837
|
-
border: `2px dashed ${
|
|
1934
|
+
background: isDark ? "rgba(15,23,42,0.92)" : "rgba(255,255,255,0.92)",
|
|
1935
|
+
border: `2px dashed ${theme.primary}`,
|
|
1838
1936
|
borderRadius: 4,
|
|
1839
1937
|
display: "flex",
|
|
1840
1938
|
alignItems: "center",
|
|
1841
1939
|
justifyContent: "center",
|
|
1842
|
-
color:
|
|
1940
|
+
color: theme.primary,
|
|
1843
1941
|
fontSize: 14,
|
|
1844
1942
|
fontWeight: 500,
|
|
1845
1943
|
pointerEvents: "none",
|
|
@@ -1854,7 +1952,7 @@ function ChatInput() {
|
|
|
1854
1952
|
padding: "4px 10px",
|
|
1855
1953
|
fontSize: 12
|
|
1856
1954
|
};
|
|
1857
|
-
const attachDisabled = attachments.length >= MAX_ATTACHMENTS || isLoading;
|
|
1955
|
+
const attachDisabled = attachments.length >= MAX_ATTACHMENTS || isLoading || readOnly;
|
|
1858
1956
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1859
1957
|
"div",
|
|
1860
1958
|
{
|
|
@@ -1883,7 +1981,7 @@ function ChatInput() {
|
|
|
1883
1981
|
}
|
|
1884
1982
|
),
|
|
1885
1983
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle, children: [
|
|
1886
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { position: "relative" }, children: [
|
|
1984
|
+
config.allowAttachments !== false && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { position: "relative" }, children: [
|
|
1887
1985
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1888
1986
|
"button",
|
|
1889
1987
|
{
|
|
@@ -1908,7 +2006,7 @@ function ChatInput() {
|
|
|
1908
2006
|
onClick: handlePickFile,
|
|
1909
2007
|
style: menuItemStyle,
|
|
1910
2008
|
onMouseEnter: (e) => {
|
|
1911
|
-
e.currentTarget.style.background =
|
|
2009
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
1912
2010
|
},
|
|
1913
2011
|
onMouseLeave: (e) => {
|
|
1914
2012
|
e.currentTarget.style.background = "transparent";
|
|
@@ -1927,7 +2025,7 @@ function ChatInput() {
|
|
|
1927
2025
|
onClick: handleCapture,
|
|
1928
2026
|
style: menuItemStyle,
|
|
1929
2027
|
onMouseEnter: (e) => {
|
|
1930
|
-
e.currentTarget.style.background =
|
|
2028
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
1931
2029
|
},
|
|
1932
2030
|
onMouseLeave: (e) => {
|
|
1933
2031
|
e.currentTarget.style.background = "transparent";
|
|
@@ -1964,14 +2062,14 @@ function ChatInput() {
|
|
|
1964
2062
|
onPaste: handlePaste,
|
|
1965
2063
|
placeholder: config.placeholderText,
|
|
1966
2064
|
style: inputStyle,
|
|
1967
|
-
disabled: isLoading
|
|
2065
|
+
disabled: isLoading || readOnly
|
|
1968
2066
|
}
|
|
1969
2067
|
),
|
|
1970
2068
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1971
2069
|
"button",
|
|
1972
2070
|
{
|
|
1973
2071
|
onClick: handleSend,
|
|
1974
|
-
disabled: isLoading || !value.trim(),
|
|
2072
|
+
disabled: isLoading || readOnly || !value.trim(),
|
|
1975
2073
|
style: sendButtonStyle,
|
|
1976
2074
|
"aria-label": t("send_message"),
|
|
1977
2075
|
onMouseEnter: (e) => {
|
|
@@ -2231,7 +2329,7 @@ function Spinner2() {
|
|
|
2231
2329
|
}
|
|
2232
2330
|
|
|
2233
2331
|
// src/components/incident-banner.tsx
|
|
2234
|
-
var
|
|
2332
|
+
var import_react10 = require("react");
|
|
2235
2333
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2236
2334
|
var PALETTE = {
|
|
2237
2335
|
info: {
|
|
@@ -2296,8 +2394,8 @@ function SeverityIcon({
|
|
|
2296
2394
|
}
|
|
2297
2395
|
function IncidentBanner() {
|
|
2298
2396
|
const { incidentBanner, incidentBannerDismissed, dismissIncidentBanner, t } = useChat();
|
|
2299
|
-
const [linkHover, setLinkHover] = (0,
|
|
2300
|
-
const [closeHover, setCloseHover] = (0,
|
|
2397
|
+
const [linkHover, setLinkHover] = (0, import_react10.useState)(false);
|
|
2398
|
+
const [closeHover, setCloseHover] = (0, import_react10.useState)(false);
|
|
2301
2399
|
if (!incidentBanner || incidentBannerDismissed) return null;
|
|
2302
2400
|
const palette = PALETTE[incidentBanner.severity];
|
|
2303
2401
|
const wrap = {
|
|
@@ -2513,9 +2611,9 @@ function validateField(field, value) {
|
|
|
2513
2611
|
}
|
|
2514
2612
|
function PreChatFormView() {
|
|
2515
2613
|
const { preChatForm, submitPreChatForm, cancelPreChatForm, config, t } = useChat();
|
|
2516
|
-
const [values, setValues] = (0,
|
|
2517
|
-
const [errors, setErrors] = (0,
|
|
2518
|
-
const [submitting, setSubmitting] = (0,
|
|
2614
|
+
const [values, setValues] = (0, import_react11.useState)({});
|
|
2615
|
+
const [errors, setErrors] = (0, import_react11.useState)({});
|
|
2616
|
+
const [submitting, setSubmitting] = (0, import_react11.useState)(false);
|
|
2519
2617
|
if (!preChatForm) return null;
|
|
2520
2618
|
function setValue(key, value) {
|
|
2521
2619
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
@@ -2744,12 +2842,13 @@ function PreChatFormView() {
|
|
|
2744
2842
|
}
|
|
2745
2843
|
);
|
|
2746
2844
|
}
|
|
2747
|
-
function ChatWindow() {
|
|
2845
|
+
function ChatWindow({ embedded } = {}) {
|
|
2748
2846
|
const { isOpen, config, configError, t, isRtl, preChatFormVisible } = useChat();
|
|
2749
2847
|
const reduced = useReducedMotion();
|
|
2750
|
-
const
|
|
2751
|
-
const [
|
|
2752
|
-
(0,
|
|
2848
|
+
const theme = useEffectiveTheme();
|
|
2849
|
+
const [visible, setVisible] = (0, import_react11.useState)(false);
|
|
2850
|
+
const [shouldRender, setShouldRender] = (0, import_react11.useState)(false);
|
|
2851
|
+
(0, import_react11.useEffect)(() => {
|
|
2753
2852
|
if (isOpen) {
|
|
2754
2853
|
setShouldRender(true);
|
|
2755
2854
|
requestAnimationFrame(() => {
|
|
@@ -2767,34 +2866,44 @@ function ChatWindow() {
|
|
|
2767
2866
|
}, [isOpen, reduced]);
|
|
2768
2867
|
if (!shouldRender) return null;
|
|
2769
2868
|
const effectivePosition = isRtl ? config.position === "bottom-right" ? "bottom-left" : "bottom-right" : config.position;
|
|
2869
|
+
const colors = theme;
|
|
2870
|
+
const preset = theme.size;
|
|
2871
|
+
const radius = theme.radius;
|
|
2872
|
+
const panelBottom = config.offset.bottom + preset.bubble + 14;
|
|
2770
2873
|
const style = {
|
|
2771
|
-
position: "fixed",
|
|
2772
|
-
bottom:
|
|
2773
|
-
[effectivePosition === "bottom-left" ? "left" : "right"]:
|
|
2774
|
-
width:
|
|
2775
|
-
maxWidth: "calc(100vw - 40px)",
|
|
2776
|
-
height:
|
|
2777
|
-
maxHeight:
|
|
2778
|
-
borderRadius:
|
|
2874
|
+
position: embedded ? "absolute" : "fixed",
|
|
2875
|
+
bottom: panelBottom,
|
|
2876
|
+
[effectivePosition === "bottom-left" ? "left" : "right"]: config.offset.side,
|
|
2877
|
+
width: preset.width,
|
|
2878
|
+
maxWidth: embedded ? "calc(100% - 16px)" : "calc(100vw - 40px)",
|
|
2879
|
+
height: preset.height,
|
|
2880
|
+
maxHeight: embedded ? `calc(100% - ${panelBottom + 16}px)` : `calc(100vh - ${panelBottom + 30}px)`,
|
|
2881
|
+
borderRadius: radius,
|
|
2779
2882
|
overflow: "hidden",
|
|
2780
2883
|
display: "flex",
|
|
2781
2884
|
flexDirection: "column",
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2885
|
+
// In dark mode the default 0.15 opacity black shadow is invisible
|
|
2886
|
+
// against a dark page; switch to a stronger shadow plus a subtle 1px
|
|
2887
|
+
// light outline so the panel still reads as a separated surface.
|
|
2888
|
+
boxShadow: theme.scheme === "dark" ? "0 12px 40px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06)" : "0 8px 40px rgba(0,0,0,0.15)",
|
|
2889
|
+
zIndex: config.zIndex,
|
|
2890
|
+
background: colors.background,
|
|
2891
|
+
color: colors.text,
|
|
2892
|
+
fontSize: preset.fontSize,
|
|
2785
2893
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
2786
2894
|
opacity: visible ? 1 : 0,
|
|
2787
2895
|
transform: visible ? "translateY(0) scale(1)" : "translateY(16px) scale(0.97)",
|
|
2788
2896
|
transition: reduced ? "none" : "opacity 0.25s ease, transform 0.25s ease"
|
|
2789
2897
|
};
|
|
2898
|
+
const isDark = theme.scheme === "dark";
|
|
2790
2899
|
const poweredStyle = {
|
|
2791
2900
|
textAlign: "center",
|
|
2792
2901
|
padding: 6,
|
|
2793
2902
|
fontSize: 10,
|
|
2794
|
-
color: "#aaa"
|
|
2903
|
+
color: isDark ? "rgba(255,255,255,0.45)" : "#aaa"
|
|
2795
2904
|
};
|
|
2796
2905
|
const linkStyle = {
|
|
2797
|
-
color: "#888",
|
|
2906
|
+
color: isDark ? "rgba(255,255,255,0.6)" : "#888",
|
|
2798
2907
|
textDecoration: "underline",
|
|
2799
2908
|
textUnderlineOffset: 2
|
|
2800
2909
|
};
|
|
@@ -2825,11 +2934,14 @@ function ChatWindow() {
|
|
|
2825
2934
|
|
|
2826
2935
|
// src/components/chat-widget.tsx
|
|
2827
2936
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2828
|
-
function ChatWidgetInner({
|
|
2937
|
+
function ChatWidgetInner({
|
|
2938
|
+
identity,
|
|
2939
|
+
embedded
|
|
2940
|
+
}) {
|
|
2829
2941
|
const client = useCustomerHeroClient();
|
|
2830
2942
|
const { configLoaded, configError } = useChat();
|
|
2831
|
-
const prevIdentityRef = (0,
|
|
2832
|
-
(0,
|
|
2943
|
+
const prevIdentityRef = (0, import_react12.useRef)(void 0);
|
|
2944
|
+
(0, import_react12.useEffect)(() => {
|
|
2833
2945
|
const key = identity ? JSON.stringify(identity) : void 0;
|
|
2834
2946
|
if (key !== prevIdentityRef.current) {
|
|
2835
2947
|
prevIdentityRef.current = key;
|
|
@@ -2840,12 +2952,12 @@ function ChatWidgetInner({ identity }) {
|
|
|
2840
2952
|
}, [identity, client]);
|
|
2841
2953
|
if (!configLoaded || configError) return null;
|
|
2842
2954
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2843
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatBubble, {}),
|
|
2844
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWindow, {})
|
|
2955
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatBubble, { embedded }),
|
|
2956
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWindow, { embedded })
|
|
2845
2957
|
] });
|
|
2846
2958
|
}
|
|
2847
|
-
function ChatWidget({ identity, ...config }) {
|
|
2848
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CustomerHeroProvider, { ...config, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWidgetInner, { identity }) });
|
|
2959
|
+
function ChatWidget({ identity, embedded, ...config }) {
|
|
2960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CustomerHeroProvider, { ...config, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWidgetInner, { identity, embedded }) });
|
|
2849
2961
|
}
|
|
2850
2962
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2851
2963
|
0 && (module.exports = {
|