@customerhero/react 2.1.1 → 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 +523 -183
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +20 -2592
- 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() {
|
|
@@ -118,12 +120,16 @@ function useChat() {
|
|
|
118
120
|
consumePendingPrefill: (0, import_react2.useCallback)(
|
|
119
121
|
() => client.consumePendingPrefill(),
|
|
120
122
|
[client]
|
|
123
|
+
),
|
|
124
|
+
dismissIncidentBanner: (0, import_react2.useCallback)(
|
|
125
|
+
() => client.dismissIncidentBanner(),
|
|
126
|
+
[client]
|
|
121
127
|
)
|
|
122
128
|
};
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
// src/components/chat-bubble.tsx
|
|
126
|
-
var
|
|
132
|
+
var import_react5 = require("react");
|
|
127
133
|
|
|
128
134
|
// src/use-reduced-motion.ts
|
|
129
135
|
var import_react3 = require("react");
|
|
@@ -141,41 +147,110 @@ function useReducedMotion() {
|
|
|
141
147
|
return reduced;
|
|
142
148
|
}
|
|
143
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
|
+
|
|
144
193
|
// src/components/chat-bubble.tsx
|
|
145
194
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
146
|
-
function ChatBubble() {
|
|
195
|
+
function ChatBubble({ embedded } = {}) {
|
|
147
196
|
const { toggle, config, t, isRtl } = useChat();
|
|
148
197
|
const reduced = useReducedMotion();
|
|
149
|
-
const
|
|
150
|
-
(0,
|
|
198
|
+
const theme = useEffectiveTheme();
|
|
199
|
+
const [mounted, setMounted] = (0, import_react5.useState)(false);
|
|
200
|
+
(0, import_react5.useEffect)(() => {
|
|
151
201
|
const id = requestAnimationFrame(() => setMounted(true));
|
|
152
202
|
return () => cancelAnimationFrame(id);
|
|
153
203
|
}, []);
|
|
154
204
|
const visible = mounted;
|
|
155
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%";
|
|
156
212
|
const style = {
|
|
157
|
-
position: "fixed",
|
|
158
|
-
bottom:
|
|
159
|
-
[effectivePosition === "bottom-left" ? "left" : "right"]:
|
|
160
|
-
width
|
|
161
|
-
height
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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",
|
|
165
223
|
display: "flex",
|
|
166
224
|
alignItems: "center",
|
|
167
225
|
justifyContent: "center",
|
|
226
|
+
gap: hasLabel ? 8 : 0,
|
|
168
227
|
cursor: "pointer",
|
|
169
|
-
boxShadow: "0 4px 20px rgba(0,0,0,0.15)",
|
|
170
|
-
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,
|
|
171
230
|
border: "none",
|
|
172
|
-
|
|
231
|
+
fontSize: preset.fontSize,
|
|
232
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
233
|
+
fontWeight: 500,
|
|
173
234
|
opacity: visible ? 1 : 0,
|
|
174
235
|
transform: visible ? "scale(1)" : "scale(0.6)",
|
|
175
236
|
transition: reduced ? "none" : "opacity 0.25s ease, transform 0.25s ease",
|
|
176
237
|
pointerEvents: visible ? "auto" : "none"
|
|
177
238
|
};
|
|
178
|
-
|
|
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)(
|
|
179
254
|
"button",
|
|
180
255
|
{
|
|
181
256
|
onClick: toggle,
|
|
@@ -183,41 +258,55 @@ function ChatBubble() {
|
|
|
183
258
|
dir: isRtl ? "rtl" : "ltr",
|
|
184
259
|
"aria-label": t("open_chat"),
|
|
185
260
|
onMouseEnter: (e) => {
|
|
186
|
-
if (!reduced) e.currentTarget.style.transform = "scale(1.
|
|
261
|
+
if (!reduced) e.currentTarget.style.transform = "scale(1.06)";
|
|
187
262
|
},
|
|
188
263
|
onMouseLeave: (e) => {
|
|
189
264
|
if (!reduced) e.currentTarget.style.transform = "scale(1)";
|
|
190
265
|
},
|
|
191
|
-
children:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
+
]
|
|
205
293
|
}
|
|
206
294
|
);
|
|
207
295
|
}
|
|
208
296
|
|
|
209
297
|
// src/components/chat-window.tsx
|
|
210
|
-
var
|
|
298
|
+
var import_react11 = require("react");
|
|
211
299
|
|
|
212
300
|
// src/components/chat-header.tsx
|
|
213
|
-
var
|
|
301
|
+
var import_react6 = require("react");
|
|
214
302
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
215
303
|
function ChatHeader() {
|
|
216
304
|
const { config, close, reset, t } = useChat();
|
|
217
305
|
const reduced = useReducedMotion();
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
(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)(() => {
|
|
221
310
|
if (!menuOpen) return;
|
|
222
311
|
const handleClick = (e) => {
|
|
223
312
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
@@ -228,7 +317,7 @@ function ChatHeader() {
|
|
|
228
317
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
229
318
|
}, [menuOpen]);
|
|
230
319
|
const headerStyle = {
|
|
231
|
-
background:
|
|
320
|
+
background: theme.primary,
|
|
232
321
|
padding: 16,
|
|
233
322
|
display: "flex",
|
|
234
323
|
alignItems: "center",
|
|
@@ -263,14 +352,16 @@ function ChatHeader() {
|
|
|
263
352
|
opacity: 0.7,
|
|
264
353
|
padding: 4
|
|
265
354
|
};
|
|
355
|
+
const isDark = theme.scheme === "dark";
|
|
266
356
|
const menuStyle = {
|
|
267
357
|
position: "absolute",
|
|
268
358
|
top: "100%",
|
|
269
359
|
right: 0,
|
|
270
360
|
marginTop: 4,
|
|
271
|
-
background:
|
|
361
|
+
background: theme.background,
|
|
362
|
+
border: `1px solid ${theme.divider}`,
|
|
272
363
|
borderRadius: 8,
|
|
273
|
-
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)",
|
|
274
365
|
minWidth: 180,
|
|
275
366
|
overflow: "hidden",
|
|
276
367
|
zIndex: 10,
|
|
@@ -287,7 +378,7 @@ function ChatHeader() {
|
|
|
287
378
|
background: "none",
|
|
288
379
|
cursor: "pointer",
|
|
289
380
|
fontSize: 13,
|
|
290
|
-
color:
|
|
381
|
+
color: theme.text,
|
|
291
382
|
textAlign: "left",
|
|
292
383
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
|
|
293
384
|
};
|
|
@@ -364,7 +455,7 @@ function ChatHeader() {
|
|
|
364
455
|
reset();
|
|
365
456
|
},
|
|
366
457
|
onMouseEnter: (e) => {
|
|
367
|
-
e.currentTarget.style.background =
|
|
458
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
368
459
|
},
|
|
369
460
|
onMouseLeave: (e) => {
|
|
370
461
|
e.currentTarget.style.background = "none";
|
|
@@ -426,7 +517,7 @@ function ChatHeader() {
|
|
|
426
517
|
}
|
|
427
518
|
|
|
428
519
|
// src/components/chat-messages.tsx
|
|
429
|
-
var
|
|
520
|
+
var import_react8 = require("react");
|
|
430
521
|
|
|
431
522
|
// src/markdown/render.tsx
|
|
432
523
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -793,7 +884,7 @@ function renderMarkdown(source, opts = {}) {
|
|
|
793
884
|
}
|
|
794
885
|
|
|
795
886
|
// src/components/action-confirmation-card.tsx
|
|
796
|
-
var
|
|
887
|
+
var import_react7 = require("react");
|
|
797
888
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
798
889
|
function ActionConfirmationCard({
|
|
799
890
|
block,
|
|
@@ -802,10 +893,10 @@ function ActionConfirmationCard({
|
|
|
802
893
|
onApprove,
|
|
803
894
|
onCancel
|
|
804
895
|
}) {
|
|
805
|
-
const [chosen, setChosen] = (0,
|
|
806
|
-
const [showSpinner, setShowSpinner] = (0,
|
|
807
|
-
const [error, setError] = (0,
|
|
808
|
-
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);
|
|
809
900
|
const handle = async (choice) => {
|
|
810
901
|
if (chosen) return;
|
|
811
902
|
setChosen(choice);
|
|
@@ -1033,7 +1124,7 @@ function MessageRatingButtons({
|
|
|
1033
1124
|
t,
|
|
1034
1125
|
reduced
|
|
1035
1126
|
}) {
|
|
1036
|
-
const [rated, setRated] = (0,
|
|
1127
|
+
const [rated, setRated] = (0, import_react8.useState)(null);
|
|
1037
1128
|
const handleRate = (rating) => {
|
|
1038
1129
|
setRated(rating);
|
|
1039
1130
|
onRate(messageId, rating);
|
|
@@ -1114,8 +1205,8 @@ function AnimatedMessage({
|
|
|
1114
1205
|
animate,
|
|
1115
1206
|
reduced
|
|
1116
1207
|
}) {
|
|
1117
|
-
const [visible, setVisible] = (0,
|
|
1118
|
-
(0,
|
|
1208
|
+
const [visible, setVisible] = (0, import_react8.useState)(!animate);
|
|
1209
|
+
(0, import_react8.useEffect)(() => {
|
|
1119
1210
|
if (!animate || reduced) {
|
|
1120
1211
|
setVisible(true);
|
|
1121
1212
|
return;
|
|
@@ -1260,7 +1351,7 @@ function Message({
|
|
|
1260
1351
|
color: "white",
|
|
1261
1352
|
borderBottomRightRadius: 4
|
|
1262
1353
|
} : {
|
|
1263
|
-
background:
|
|
1354
|
+
background: config.bubbleBackground,
|
|
1264
1355
|
color: config.textColor,
|
|
1265
1356
|
borderBottomLeftRadius: 4
|
|
1266
1357
|
}
|
|
@@ -1356,7 +1447,6 @@ function ChatMessages() {
|
|
|
1356
1447
|
messages,
|
|
1357
1448
|
isLoading,
|
|
1358
1449
|
error,
|
|
1359
|
-
config,
|
|
1360
1450
|
conversationId,
|
|
1361
1451
|
rateMessage,
|
|
1362
1452
|
sendMessage,
|
|
@@ -1364,13 +1454,19 @@ function ChatMessages() {
|
|
|
1364
1454
|
cancelAction,
|
|
1365
1455
|
t
|
|
1366
1456
|
} = useChat();
|
|
1457
|
+
const theme = useEffectiveTheme();
|
|
1458
|
+
const themedConfig = {
|
|
1459
|
+
primaryColor: theme.primary,
|
|
1460
|
+
textColor: theme.text,
|
|
1461
|
+
bubbleBackground: theme.bubbleBackground
|
|
1462
|
+
};
|
|
1367
1463
|
const reduced = useReducedMotion();
|
|
1368
|
-
const containerRef = (0,
|
|
1369
|
-
const messagesEndRef = (0,
|
|
1370
|
-
const isFirstRender = (0,
|
|
1371
|
-
const prevMessageCount = (0,
|
|
1372
|
-
const stickRef = (0,
|
|
1373
|
-
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);
|
|
1374
1470
|
const autoScrollTo = (top) => {
|
|
1375
1471
|
const el = containerRef.current;
|
|
1376
1472
|
if (!el) return;
|
|
@@ -1387,7 +1483,7 @@ function ChatMessages() {
|
|
|
1387
1483
|
const distFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
1388
1484
|
stickRef.current = distFromBottom < 60;
|
|
1389
1485
|
};
|
|
1390
|
-
(0,
|
|
1486
|
+
(0, import_react8.useEffect)(() => {
|
|
1391
1487
|
const el = containerRef.current;
|
|
1392
1488
|
if (!el) return;
|
|
1393
1489
|
const lastMsg2 = messages[messages.length - 1];
|
|
@@ -1412,7 +1508,7 @@ function ChatMessages() {
|
|
|
1412
1508
|
isFirstRender.current = false;
|
|
1413
1509
|
}, [messages, isLoading, reduced]);
|
|
1414
1510
|
const newStartIndex = isFirstRender.current ? messages.length : prevMessageCount.current;
|
|
1415
|
-
(0,
|
|
1511
|
+
(0, import_react8.useEffect)(() => {
|
|
1416
1512
|
prevMessageCount.current = messages.length;
|
|
1417
1513
|
}, [messages.length]);
|
|
1418
1514
|
let lastBotIndex = -1;
|
|
@@ -1437,7 +1533,7 @@ function ChatMessages() {
|
|
|
1437
1533
|
Message,
|
|
1438
1534
|
{
|
|
1439
1535
|
message: msg,
|
|
1440
|
-
config,
|
|
1536
|
+
config: themedConfig,
|
|
1441
1537
|
onRate: rateMessage,
|
|
1442
1538
|
onSend: sendMessage,
|
|
1443
1539
|
onApproveAction: approveAction,
|
|
@@ -1476,10 +1572,13 @@ var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
|
1476
1572
|
function ChatSuggestions() {
|
|
1477
1573
|
const { messages, isLoading, config, sendMessage } = useChat();
|
|
1478
1574
|
const reduced = useReducedMotion();
|
|
1575
|
+
const theme = useEffectiveTheme();
|
|
1479
1576
|
const hasUserMessage = messages.some((m) => m.role === "user");
|
|
1480
1577
|
if (config.suggestedMessages.length === 0 || hasUserMessage || isLoading) {
|
|
1481
1578
|
return null;
|
|
1482
1579
|
}
|
|
1580
|
+
const isDark = theme.scheme === "dark";
|
|
1581
|
+
const idleBorder = isDark ? "rgba(255,255,255,0.18)" : "#e0e0e0";
|
|
1483
1582
|
const containerStyle = {
|
|
1484
1583
|
padding: "8px 16px",
|
|
1485
1584
|
display: "flex",
|
|
@@ -1489,11 +1588,11 @@ function ChatSuggestions() {
|
|
|
1489
1588
|
};
|
|
1490
1589
|
const chipStyle = {
|
|
1491
1590
|
background: "none",
|
|
1492
|
-
border:
|
|
1591
|
+
border: `1px solid ${idleBorder}`,
|
|
1493
1592
|
borderRadius: 20,
|
|
1494
1593
|
padding: "7px 14px",
|
|
1495
1594
|
fontSize: 13,
|
|
1496
|
-
color:
|
|
1595
|
+
color: theme.text,
|
|
1497
1596
|
cursor: "pointer",
|
|
1498
1597
|
textAlign: "left",
|
|
1499
1598
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
@@ -1505,11 +1604,11 @@ function ChatSuggestions() {
|
|
|
1505
1604
|
style: chipStyle,
|
|
1506
1605
|
onClick: () => sendMessage(text),
|
|
1507
1606
|
onMouseEnter: (e) => {
|
|
1508
|
-
e.currentTarget.style.borderColor =
|
|
1509
|
-
e.currentTarget.style.background = `${
|
|
1607
|
+
e.currentTarget.style.borderColor = theme.primary;
|
|
1608
|
+
e.currentTarget.style.background = `${theme.primary}14`;
|
|
1510
1609
|
},
|
|
1511
1610
|
onMouseLeave: (e) => {
|
|
1512
|
-
e.currentTarget.style.borderColor =
|
|
1611
|
+
e.currentTarget.style.borderColor = idleBorder;
|
|
1513
1612
|
e.currentTarget.style.background = "none";
|
|
1514
1613
|
},
|
|
1515
1614
|
children: text
|
|
@@ -1519,8 +1618,8 @@ function ChatSuggestions() {
|
|
|
1519
1618
|
}
|
|
1520
1619
|
|
|
1521
1620
|
// src/components/chat-input.tsx
|
|
1522
|
-
var
|
|
1523
|
-
var
|
|
1621
|
+
var import_react9 = require("react");
|
|
1622
|
+
var import_js3 = require("@customerhero/js");
|
|
1524
1623
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1525
1624
|
var MAX_ATTACHMENTS = 3;
|
|
1526
1625
|
var ALLOWED_MIME_TYPES = [
|
|
@@ -1538,47 +1637,50 @@ function ChatInput() {
|
|
|
1538
1637
|
sendMessage,
|
|
1539
1638
|
uploadAttachment,
|
|
1540
1639
|
isLoading,
|
|
1640
|
+
readOnly,
|
|
1541
1641
|
config,
|
|
1542
1642
|
t,
|
|
1543
1643
|
consumePendingPrefill,
|
|
1544
1644
|
pendingPrefill
|
|
1545
1645
|
} = useChat();
|
|
1646
|
+
const theme = useEffectiveTheme();
|
|
1647
|
+
const isDark = theme.scheme === "dark";
|
|
1546
1648
|
const reduced = useReducedMotion();
|
|
1547
|
-
const [value, setValue] = (0,
|
|
1548
|
-
const [attachments, setAttachments] = (0,
|
|
1549
|
-
const [captureSupported, setCaptureSupported] = (0,
|
|
1550
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
1551
|
-
const [dragActive, setDragActive] = (0,
|
|
1552
|
-
const [transientError, setTransientError] = (0,
|
|
1553
|
-
const fileInputRef = (0,
|
|
1554
|
-
const textInputRef = (0,
|
|
1555
|
-
const menuRef = (0,
|
|
1556
|
-
const menuButtonRef = (0,
|
|
1557
|
-
const dragCounterRef = (0,
|
|
1558
|
-
(0,
|
|
1559
|
-
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)());
|
|
1560
1662
|
}, []);
|
|
1561
|
-
(0,
|
|
1663
|
+
(0, import_react9.useEffect)(() => {
|
|
1562
1664
|
const id = requestAnimationFrame(() => textInputRef.current?.focus());
|
|
1563
1665
|
return () => cancelAnimationFrame(id);
|
|
1564
1666
|
}, []);
|
|
1565
|
-
(0,
|
|
1667
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
1566
1668
|
const el = textInputRef.current;
|
|
1567
1669
|
if (!el) return;
|
|
1568
1670
|
el.style.height = "auto";
|
|
1569
1671
|
el.style.height = `${el.scrollHeight}px`;
|
|
1570
1672
|
}, [value]);
|
|
1571
|
-
(0,
|
|
1673
|
+
(0, import_react9.useEffect)(() => {
|
|
1572
1674
|
if (pendingPrefill === null) return;
|
|
1573
1675
|
const text = consumePendingPrefill();
|
|
1574
1676
|
if (text !== null) setValue(text);
|
|
1575
1677
|
}, [pendingPrefill, consumePendingPrefill]);
|
|
1576
|
-
(0,
|
|
1678
|
+
(0, import_react9.useEffect)(() => {
|
|
1577
1679
|
return () => {
|
|
1578
1680
|
for (const a of attachments) URL.revokeObjectURL(a.previewUrl);
|
|
1579
1681
|
};
|
|
1580
1682
|
}, []);
|
|
1581
|
-
(0,
|
|
1683
|
+
(0, import_react9.useEffect)(() => {
|
|
1582
1684
|
if (!menuOpen) return;
|
|
1583
1685
|
const onClick = (e) => {
|
|
1584
1686
|
const target = e.target;
|
|
@@ -1597,7 +1699,7 @@ function ChatInput() {
|
|
|
1597
1699
|
document.removeEventListener("keydown", onKey);
|
|
1598
1700
|
};
|
|
1599
1701
|
}, [menuOpen]);
|
|
1600
|
-
(0,
|
|
1702
|
+
(0, import_react9.useEffect)(() => {
|
|
1601
1703
|
if (!transientError) return;
|
|
1602
1704
|
const id = window.setTimeout(() => setTransientError(null), 4e3);
|
|
1603
1705
|
return () => window.clearTimeout(id);
|
|
@@ -1653,10 +1755,10 @@ function ChatInput() {
|
|
|
1653
1755
|
const handleCapture = async () => {
|
|
1654
1756
|
setMenuOpen(false);
|
|
1655
1757
|
try {
|
|
1656
|
-
const blob = await (0,
|
|
1758
|
+
const blob = await (0, import_js3.captureScreenshot)();
|
|
1657
1759
|
await startUpload(blob);
|
|
1658
1760
|
} catch (e) {
|
|
1659
|
-
if (e instanceof
|
|
1761
|
+
if (e instanceof import_js3.ScreenshotCancelled) return;
|
|
1660
1762
|
}
|
|
1661
1763
|
};
|
|
1662
1764
|
const handlePickFile = () => {
|
|
@@ -1738,7 +1840,7 @@ function ChatInput() {
|
|
|
1738
1840
|
const containerStyle = {
|
|
1739
1841
|
position: "relative",
|
|
1740
1842
|
padding: "12px 16px",
|
|
1741
|
-
borderTop:
|
|
1843
|
+
borderTop: `1px solid ${theme.divider}`,
|
|
1742
1844
|
display: "flex",
|
|
1743
1845
|
flexDirection: "column",
|
|
1744
1846
|
gap: 8
|
|
@@ -1753,14 +1855,14 @@ function ChatInput() {
|
|
|
1753
1855
|
const TEXTAREA_MAX_HEIGHT = 140;
|
|
1754
1856
|
const inputStyle = {
|
|
1755
1857
|
flex: 1,
|
|
1756
|
-
border:
|
|
1858
|
+
border: `1px solid ${theme.divider}`,
|
|
1757
1859
|
borderRadius: 18,
|
|
1758
1860
|
padding: "10px 16px",
|
|
1759
1861
|
fontSize: 14,
|
|
1760
1862
|
lineHeight: 1.4,
|
|
1761
1863
|
outline: "none",
|
|
1762
|
-
background: "#fafafa",
|
|
1763
|
-
color:
|
|
1864
|
+
background: isDark ? "rgba(255,255,255,0.06)" : "#fafafa",
|
|
1865
|
+
color: theme.text,
|
|
1764
1866
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
1765
1867
|
resize: "none",
|
|
1766
1868
|
overflowY: "auto",
|
|
@@ -1771,7 +1873,7 @@ function ChatInput() {
|
|
|
1771
1873
|
width: 36,
|
|
1772
1874
|
height: 36,
|
|
1773
1875
|
borderRadius: "50%",
|
|
1774
|
-
background:
|
|
1876
|
+
background: theme.primary,
|
|
1775
1877
|
border: "none",
|
|
1776
1878
|
color: "white",
|
|
1777
1879
|
cursor: isLoading ? "not-allowed" : "pointer",
|
|
@@ -1801,10 +1903,10 @@ function ChatInput() {
|
|
|
1801
1903
|
position: "absolute",
|
|
1802
1904
|
bottom: "calc(100% + 4px)",
|
|
1803
1905
|
left: 0,
|
|
1804
|
-
background:
|
|
1805
|
-
border:
|
|
1906
|
+
background: theme.background,
|
|
1907
|
+
border: `1px solid ${theme.divider}`,
|
|
1806
1908
|
borderRadius: 8,
|
|
1807
|
-
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)",
|
|
1808
1910
|
padding: 4,
|
|
1809
1911
|
minWidth: 180,
|
|
1810
1912
|
zIndex: 10,
|
|
@@ -1821,7 +1923,7 @@ function ChatInput() {
|
|
|
1821
1923
|
borderRadius: 4,
|
|
1822
1924
|
cursor: "pointer",
|
|
1823
1925
|
fontSize: 14,
|
|
1824
|
-
color:
|
|
1926
|
+
color: theme.text,
|
|
1825
1927
|
textAlign: "left",
|
|
1826
1928
|
whiteSpace: "nowrap",
|
|
1827
1929
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
|
|
@@ -1829,13 +1931,13 @@ function ChatInput() {
|
|
|
1829
1931
|
const dropOverlayStyle = {
|
|
1830
1932
|
position: "absolute",
|
|
1831
1933
|
inset: 0,
|
|
1832
|
-
background: "rgba(255,255,255,0.92)",
|
|
1833
|
-
border: `2px dashed ${
|
|
1934
|
+
background: isDark ? "rgba(15,23,42,0.92)" : "rgba(255,255,255,0.92)",
|
|
1935
|
+
border: `2px dashed ${theme.primary}`,
|
|
1834
1936
|
borderRadius: 4,
|
|
1835
1937
|
display: "flex",
|
|
1836
1938
|
alignItems: "center",
|
|
1837
1939
|
justifyContent: "center",
|
|
1838
|
-
color:
|
|
1940
|
+
color: theme.primary,
|
|
1839
1941
|
fontSize: 14,
|
|
1840
1942
|
fontWeight: 500,
|
|
1841
1943
|
pointerEvents: "none",
|
|
@@ -1850,7 +1952,7 @@ function ChatInput() {
|
|
|
1850
1952
|
padding: "4px 10px",
|
|
1851
1953
|
fontSize: 12
|
|
1852
1954
|
};
|
|
1853
|
-
const attachDisabled = attachments.length >= MAX_ATTACHMENTS || isLoading;
|
|
1955
|
+
const attachDisabled = attachments.length >= MAX_ATTACHMENTS || isLoading || readOnly;
|
|
1854
1956
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1855
1957
|
"div",
|
|
1856
1958
|
{
|
|
@@ -1879,7 +1981,7 @@ function ChatInput() {
|
|
|
1879
1981
|
}
|
|
1880
1982
|
),
|
|
1881
1983
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle, children: [
|
|
1882
|
-
/* @__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: [
|
|
1883
1985
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1884
1986
|
"button",
|
|
1885
1987
|
{
|
|
@@ -1904,7 +2006,7 @@ function ChatInput() {
|
|
|
1904
2006
|
onClick: handlePickFile,
|
|
1905
2007
|
style: menuItemStyle,
|
|
1906
2008
|
onMouseEnter: (e) => {
|
|
1907
|
-
e.currentTarget.style.background =
|
|
2009
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
1908
2010
|
},
|
|
1909
2011
|
onMouseLeave: (e) => {
|
|
1910
2012
|
e.currentTarget.style.background = "transparent";
|
|
@@ -1923,7 +2025,7 @@ function ChatInput() {
|
|
|
1923
2025
|
onClick: handleCapture,
|
|
1924
2026
|
style: menuItemStyle,
|
|
1925
2027
|
onMouseEnter: (e) => {
|
|
1926
|
-
e.currentTarget.style.background =
|
|
2028
|
+
e.currentTarget.style.background = theme.bubbleBackground;
|
|
1927
2029
|
},
|
|
1928
2030
|
onMouseLeave: (e) => {
|
|
1929
2031
|
e.currentTarget.style.background = "transparent";
|
|
@@ -1960,14 +2062,14 @@ function ChatInput() {
|
|
|
1960
2062
|
onPaste: handlePaste,
|
|
1961
2063
|
placeholder: config.placeholderText,
|
|
1962
2064
|
style: inputStyle,
|
|
1963
|
-
disabled: isLoading
|
|
2065
|
+
disabled: isLoading || readOnly
|
|
1964
2066
|
}
|
|
1965
2067
|
),
|
|
1966
2068
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1967
2069
|
"button",
|
|
1968
2070
|
{
|
|
1969
2071
|
onClick: handleSend,
|
|
1970
|
-
disabled: isLoading || !value.trim(),
|
|
2072
|
+
disabled: isLoading || readOnly || !value.trim(),
|
|
1971
2073
|
style: sendButtonStyle,
|
|
1972
2074
|
"aria-label": t("send_message"),
|
|
1973
2075
|
onMouseEnter: (e) => {
|
|
@@ -2226,8 +2328,231 @@ function Spinner2() {
|
|
|
2226
2328
|
] });
|
|
2227
2329
|
}
|
|
2228
2330
|
|
|
2229
|
-
// src/components/
|
|
2331
|
+
// src/components/incident-banner.tsx
|
|
2332
|
+
var import_react10 = require("react");
|
|
2230
2333
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2334
|
+
var PALETTE = {
|
|
2335
|
+
info: {
|
|
2336
|
+
bg: "#EFF6FF",
|
|
2337
|
+
fg: "#1E3A8A",
|
|
2338
|
+
fgMuted: "#3B5BA9",
|
|
2339
|
+
accent: "#2563EB",
|
|
2340
|
+
iconBg: "#DBEAFE",
|
|
2341
|
+
iconFg: "#2563EB"
|
|
2342
|
+
},
|
|
2343
|
+
warning: {
|
|
2344
|
+
bg: "#FFFBEB",
|
|
2345
|
+
fg: "#78350F",
|
|
2346
|
+
fgMuted: "#92541A",
|
|
2347
|
+
accent: "#B45309",
|
|
2348
|
+
iconBg: "#FEF3C7",
|
|
2349
|
+
iconFg: "#B45309"
|
|
2350
|
+
},
|
|
2351
|
+
outage: {
|
|
2352
|
+
bg: "#FEF2F2",
|
|
2353
|
+
fg: "#991B1B",
|
|
2354
|
+
fgMuted: "#B23A3A",
|
|
2355
|
+
accent: "#DC2626",
|
|
2356
|
+
iconBg: "#FEE2E2",
|
|
2357
|
+
iconFg: "#DC2626"
|
|
2358
|
+
}
|
|
2359
|
+
};
|
|
2360
|
+
function SeverityIcon({
|
|
2361
|
+
severity,
|
|
2362
|
+
color
|
|
2363
|
+
}) {
|
|
2364
|
+
const props = {
|
|
2365
|
+
width: 14,
|
|
2366
|
+
height: 14,
|
|
2367
|
+
viewBox: "0 0 24 24",
|
|
2368
|
+
fill: "none",
|
|
2369
|
+
stroke: color,
|
|
2370
|
+
strokeWidth: 2.25,
|
|
2371
|
+
strokeLinecap: "round",
|
|
2372
|
+
strokeLinejoin: "round",
|
|
2373
|
+
"aria-hidden": true
|
|
2374
|
+
};
|
|
2375
|
+
if (severity === "outage") {
|
|
2376
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2377
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2378
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2379
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2380
|
+
] });
|
|
2381
|
+
}
|
|
2382
|
+
if (severity === "warning") {
|
|
2383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2384
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
|
|
2387
|
+
] });
|
|
2388
|
+
}
|
|
2389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2391
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
2392
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
2393
|
+
] });
|
|
2394
|
+
}
|
|
2395
|
+
function IncidentBanner() {
|
|
2396
|
+
const { incidentBanner, incidentBannerDismissed, dismissIncidentBanner, t } = useChat();
|
|
2397
|
+
const [linkHover, setLinkHover] = (0, import_react10.useState)(false);
|
|
2398
|
+
const [closeHover, setCloseHover] = (0, import_react10.useState)(false);
|
|
2399
|
+
if (!incidentBanner || incidentBannerDismissed) return null;
|
|
2400
|
+
const palette = PALETTE[incidentBanner.severity];
|
|
2401
|
+
const wrap = {
|
|
2402
|
+
background: palette.bg,
|
|
2403
|
+
color: palette.fg,
|
|
2404
|
+
padding: "12px 14px 12px 12px",
|
|
2405
|
+
display: "flex",
|
|
2406
|
+
gap: 10,
|
|
2407
|
+
alignItems: "flex-start",
|
|
2408
|
+
fontSize: 13,
|
|
2409
|
+
lineHeight: 1.45,
|
|
2410
|
+
boxShadow: "inset 0 -1px 0 rgba(0,0,0,0.04)"
|
|
2411
|
+
};
|
|
2412
|
+
const iconBadge = {
|
|
2413
|
+
width: 22,
|
|
2414
|
+
height: 22,
|
|
2415
|
+
borderRadius: "50%",
|
|
2416
|
+
background: palette.iconBg,
|
|
2417
|
+
display: "flex",
|
|
2418
|
+
alignItems: "center",
|
|
2419
|
+
justifyContent: "center",
|
|
2420
|
+
flexShrink: 0,
|
|
2421
|
+
marginTop: 1
|
|
2422
|
+
};
|
|
2423
|
+
const titleStyle = {
|
|
2424
|
+
margin: 0,
|
|
2425
|
+
fontSize: 13,
|
|
2426
|
+
fontWeight: 600,
|
|
2427
|
+
letterSpacing: "-0.005em"
|
|
2428
|
+
};
|
|
2429
|
+
const bodyStyle = {
|
|
2430
|
+
margin: "3px 0 0",
|
|
2431
|
+
fontSize: 12.5,
|
|
2432
|
+
color: palette.fgMuted
|
|
2433
|
+
};
|
|
2434
|
+
const footerRowStyle = {
|
|
2435
|
+
display: "flex",
|
|
2436
|
+
flexWrap: "wrap",
|
|
2437
|
+
alignItems: "center",
|
|
2438
|
+
gap: 10,
|
|
2439
|
+
marginTop: 8
|
|
2440
|
+
};
|
|
2441
|
+
const etaStyle = {
|
|
2442
|
+
display: "inline-block",
|
|
2443
|
+
padding: "2px 8px",
|
|
2444
|
+
borderRadius: 4,
|
|
2445
|
+
fontSize: 11,
|
|
2446
|
+
fontWeight: 500,
|
|
2447
|
+
color: palette.accent,
|
|
2448
|
+
background: palette.iconBg,
|
|
2449
|
+
lineHeight: 1.4
|
|
2450
|
+
};
|
|
2451
|
+
const linkStyle = {
|
|
2452
|
+
display: "inline-flex",
|
|
2453
|
+
alignItems: "center",
|
|
2454
|
+
gap: 4,
|
|
2455
|
+
color: palette.accent,
|
|
2456
|
+
textDecoration: linkHover ? "underline" : "none",
|
|
2457
|
+
textUnderlineOffset: 3,
|
|
2458
|
+
fontSize: 12.5,
|
|
2459
|
+
fontWeight: 600
|
|
2460
|
+
};
|
|
2461
|
+
const closeButtonStyle = {
|
|
2462
|
+
background: closeHover ? "rgba(0,0,0,0.06)" : "transparent",
|
|
2463
|
+
border: "none",
|
|
2464
|
+
color: palette.fgMuted,
|
|
2465
|
+
cursor: "pointer",
|
|
2466
|
+
padding: 4,
|
|
2467
|
+
borderRadius: 6,
|
|
2468
|
+
flexShrink: 0,
|
|
2469
|
+
lineHeight: 0,
|
|
2470
|
+
marginTop: -2,
|
|
2471
|
+
marginRight: -2,
|
|
2472
|
+
transition: "background-color 0.12s ease"
|
|
2473
|
+
};
|
|
2474
|
+
const role = incidentBanner.severity === "outage" ? "alert" : "status";
|
|
2475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { role, style: wrap, children: [
|
|
2476
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: iconBadge, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2477
|
+
SeverityIcon,
|
|
2478
|
+
{
|
|
2479
|
+
severity: incidentBanner.severity,
|
|
2480
|
+
color: palette.iconFg
|
|
2481
|
+
}
|
|
2482
|
+
) }),
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { style: titleStyle, children: incidentBanner.title }),
|
|
2485
|
+
incidentBanner.body ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { style: bodyStyle, children: incidentBanner.body }) : null,
|
|
2486
|
+
incidentBanner.eta || incidentBanner.link ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: footerRowStyle, children: [
|
|
2487
|
+
incidentBanner.eta ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: etaStyle, children: incidentBanner.eta }) : null,
|
|
2488
|
+
incidentBanner.link ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2489
|
+
"a",
|
|
2490
|
+
{
|
|
2491
|
+
href: incidentBanner.link.url,
|
|
2492
|
+
target: "_blank",
|
|
2493
|
+
rel: "noopener noreferrer",
|
|
2494
|
+
style: linkStyle,
|
|
2495
|
+
onMouseEnter: () => setLinkHover(true),
|
|
2496
|
+
onMouseLeave: () => setLinkHover(false),
|
|
2497
|
+
children: [
|
|
2498
|
+
incidentBanner.link.label ?? t("incident_default_link_label"),
|
|
2499
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2500
|
+
"svg",
|
|
2501
|
+
{
|
|
2502
|
+
width: "12",
|
|
2503
|
+
height: "12",
|
|
2504
|
+
viewBox: "0 0 24 24",
|
|
2505
|
+
fill: "none",
|
|
2506
|
+
stroke: "currentColor",
|
|
2507
|
+
strokeWidth: "2.5",
|
|
2508
|
+
strokeLinecap: "round",
|
|
2509
|
+
strokeLinejoin: "round",
|
|
2510
|
+
"aria-hidden": "true",
|
|
2511
|
+
children: [
|
|
2512
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
2513
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "12 5 19 12 12 19" })
|
|
2514
|
+
]
|
|
2515
|
+
}
|
|
2516
|
+
)
|
|
2517
|
+
]
|
|
2518
|
+
}
|
|
2519
|
+
) : null
|
|
2520
|
+
] }) : null
|
|
2521
|
+
] }),
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2523
|
+
"button",
|
|
2524
|
+
{
|
|
2525
|
+
type: "button",
|
|
2526
|
+
onClick: dismissIncidentBanner,
|
|
2527
|
+
"aria-label": t("incident_dismiss"),
|
|
2528
|
+
style: closeButtonStyle,
|
|
2529
|
+
onMouseEnter: () => setCloseHover(true),
|
|
2530
|
+
onMouseLeave: () => setCloseHover(false),
|
|
2531
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2532
|
+
"svg",
|
|
2533
|
+
{
|
|
2534
|
+
width: "14",
|
|
2535
|
+
height: "14",
|
|
2536
|
+
viewBox: "0 0 24 24",
|
|
2537
|
+
fill: "none",
|
|
2538
|
+
stroke: "currentColor",
|
|
2539
|
+
strokeWidth: "2",
|
|
2540
|
+
strokeLinecap: "round",
|
|
2541
|
+
strokeLinejoin: "round",
|
|
2542
|
+
"aria-hidden": "true",
|
|
2543
|
+
children: [
|
|
2544
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2545
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2546
|
+
]
|
|
2547
|
+
}
|
|
2548
|
+
)
|
|
2549
|
+
}
|
|
2550
|
+
)
|
|
2551
|
+
] });
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
// src/components/chat-window.tsx
|
|
2555
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2231
2556
|
function ConfigError({ message, title }) {
|
|
2232
2557
|
const errorStyle = {
|
|
2233
2558
|
flex: 1,
|
|
@@ -2239,8 +2564,8 @@ function ConfigError({ message, title }) {
|
|
|
2239
2564
|
textAlign: "center",
|
|
2240
2565
|
gap: 8
|
|
2241
2566
|
};
|
|
2242
|
-
return /* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: errorStyle, children: [
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2244
2569
|
"svg",
|
|
2245
2570
|
{
|
|
2246
2571
|
width: "32",
|
|
@@ -2252,14 +2577,14 @@ function ConfigError({ message, title }) {
|
|
|
2252
2577
|
strokeLinecap: "round",
|
|
2253
2578
|
strokeLinejoin: "round",
|
|
2254
2579
|
children: [
|
|
2255
|
-
/* @__PURE__ */ (0,
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2580
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2258
2583
|
]
|
|
2259
2584
|
}
|
|
2260
2585
|
),
|
|
2261
|
-
/* @__PURE__ */ (0,
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2586
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 14, fontWeight: 500, color: "#333", margin: 0 }, children: title }),
|
|
2587
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 12, color: "#999", margin: 0 }, children: message })
|
|
2263
2588
|
] });
|
|
2264
2589
|
}
|
|
2265
2590
|
function fieldKey(field) {
|
|
@@ -2286,9 +2611,9 @@ function validateField(field, value) {
|
|
|
2286
2611
|
}
|
|
2287
2612
|
function PreChatFormView() {
|
|
2288
2613
|
const { preChatForm, submitPreChatForm, cancelPreChatForm, config, t } = useChat();
|
|
2289
|
-
const [values, setValues] = (0,
|
|
2290
|
-
const [errors, setErrors] = (0,
|
|
2291
|
-
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);
|
|
2292
2617
|
if (!preChatForm) return null;
|
|
2293
2618
|
function setValue(key, value) {
|
|
2294
2619
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
@@ -2384,15 +2709,15 @@ function PreChatFormView() {
|
|
|
2384
2709
|
fontSize: 14,
|
|
2385
2710
|
cursor: "pointer"
|
|
2386
2711
|
};
|
|
2387
|
-
return /* @__PURE__ */ (0,
|
|
2712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2388
2713
|
"form",
|
|
2389
2714
|
{
|
|
2390
2715
|
style: containerStyle,
|
|
2391
2716
|
onSubmit: handleSubmit,
|
|
2392
2717
|
"data-customerhero-prechat-form": true,
|
|
2393
2718
|
children: [
|
|
2394
|
-
preChatForm.title && /* @__PURE__ */ (0,
|
|
2395
|
-
preChatForm.description && /* @__PURE__ */ (0,
|
|
2719
|
+
preChatForm.title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { style: { fontSize: 16, fontWeight: 600, margin: 0 }, children: preChatForm.title }),
|
|
2720
|
+
preChatForm.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 13, margin: 0, opacity: 0.8 }, children: preChatForm.description }),
|
|
2396
2721
|
preChatForm.fields.map((field) => {
|
|
2397
2722
|
const k = fieldKey(field);
|
|
2398
2723
|
const v = values[k];
|
|
@@ -2400,12 +2725,12 @@ function PreChatFormView() {
|
|
|
2400
2725
|
const required = "required" in field ? !!field.required : false;
|
|
2401
2726
|
const label = fieldLabel(field);
|
|
2402
2727
|
if (field.kind === "textarea") {
|
|
2403
|
-
return /* @__PURE__ */ (0,
|
|
2404
|
-
/* @__PURE__ */ (0,
|
|
2728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2729
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2405
2730
|
label,
|
|
2406
2731
|
required && " *"
|
|
2407
2732
|
] }),
|
|
2408
|
-
/* @__PURE__ */ (0,
|
|
2733
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2409
2734
|
"textarea",
|
|
2410
2735
|
{
|
|
2411
2736
|
style: { ...inputStyle, minHeight: 80, resize: "vertical" },
|
|
@@ -2414,32 +2739,32 @@ function PreChatFormView() {
|
|
|
2414
2739
|
onChange: (e) => setValue(k, e.target.value)
|
|
2415
2740
|
}
|
|
2416
2741
|
),
|
|
2417
|
-
err && /* @__PURE__ */ (0,
|
|
2742
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2418
2743
|
] }, k);
|
|
2419
2744
|
}
|
|
2420
2745
|
if (field.kind === "select") {
|
|
2421
|
-
return /* @__PURE__ */ (0,
|
|
2422
|
-
/* @__PURE__ */ (0,
|
|
2746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2423
2748
|
label,
|
|
2424
2749
|
required && " *"
|
|
2425
2750
|
] }),
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2751
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2427
2752
|
"select",
|
|
2428
2753
|
{
|
|
2429
2754
|
style: inputStyle,
|
|
2430
2755
|
value: v ?? "",
|
|
2431
2756
|
onChange: (e) => setValue(k, e.target.value),
|
|
2432
2757
|
children: [
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2434
|
-
field.options.map((opt) => /* @__PURE__ */ (0,
|
|
2758
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "\u2014" }),
|
|
2759
|
+
field.options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
|
|
2435
2760
|
]
|
|
2436
2761
|
}
|
|
2437
2762
|
),
|
|
2438
|
-
err && /* @__PURE__ */ (0,
|
|
2763
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2439
2764
|
] }, k);
|
|
2440
2765
|
}
|
|
2441
2766
|
if (field.kind === "consent") {
|
|
2442
|
-
return /* @__PURE__ */ (0,
|
|
2767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2443
2768
|
"label",
|
|
2444
2769
|
{
|
|
2445
2770
|
style: {
|
|
@@ -2449,7 +2774,7 @@ function PreChatFormView() {
|
|
|
2449
2774
|
gap: 8
|
|
2450
2775
|
},
|
|
2451
2776
|
children: [
|
|
2452
|
-
/* @__PURE__ */ (0,
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2453
2778
|
"input",
|
|
2454
2779
|
{
|
|
2455
2780
|
type: "checkbox",
|
|
@@ -2458,11 +2783,11 @@ function PreChatFormView() {
|
|
|
2458
2783
|
style: { marginTop: 3 }
|
|
2459
2784
|
}
|
|
2460
2785
|
),
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2786
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { style: { fontSize: 13, fontWeight: 400 }, children: [
|
|
2462
2787
|
field.label,
|
|
2463
|
-
field.url && /* @__PURE__ */ (0,
|
|
2788
|
+
field.url && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2464
2789
|
" ",
|
|
2465
|
-
/* @__PURE__ */ (0,
|
|
2790
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2466
2791
|
"a",
|
|
2467
2792
|
{
|
|
2468
2793
|
href: field.url,
|
|
@@ -2474,7 +2799,7 @@ function PreChatFormView() {
|
|
|
2474
2799
|
)
|
|
2475
2800
|
] })
|
|
2476
2801
|
] }),
|
|
2477
|
-
err && /* @__PURE__ */ (0,
|
|
2802
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2478
2803
|
]
|
|
2479
2804
|
},
|
|
2480
2805
|
k
|
|
@@ -2482,12 +2807,12 @@ function PreChatFormView() {
|
|
|
2482
2807
|
}
|
|
2483
2808
|
const inputType = field.kind === "email" ? "email" : field.kind === "phone" ? "tel" : "text";
|
|
2484
2809
|
const maxLength = field.kind === "text" ? field.maxLength : void 0;
|
|
2485
|
-
return /* @__PURE__ */ (0,
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
2810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2811
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2487
2812
|
label,
|
|
2488
2813
|
required && " *"
|
|
2489
2814
|
] }),
|
|
2490
|
-
/* @__PURE__ */ (0,
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2491
2816
|
"input",
|
|
2492
2817
|
{
|
|
2493
2818
|
type: inputType,
|
|
@@ -2497,11 +2822,11 @@ function PreChatFormView() {
|
|
|
2497
2822
|
onChange: (e) => setValue(k, e.target.value)
|
|
2498
2823
|
}
|
|
2499
2824
|
),
|
|
2500
|
-
err && /* @__PURE__ */ (0,
|
|
2825
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2501
2826
|
] }, k);
|
|
2502
2827
|
}),
|
|
2503
|
-
/* @__PURE__ */ (0,
|
|
2504
|
-
/* @__PURE__ */ (0,
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: buttonRowStyle, children: [
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2505
2830
|
"button",
|
|
2506
2831
|
{
|
|
2507
2832
|
type: "button",
|
|
@@ -2511,18 +2836,19 @@ function PreChatFormView() {
|
|
|
2511
2836
|
children: t("action_cancel")
|
|
2512
2837
|
}
|
|
2513
2838
|
),
|
|
2514
|
-
/* @__PURE__ */ (0,
|
|
2839
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", style: submitStyle, disabled: submitting, children: preChatForm.submitLabel })
|
|
2515
2840
|
] })
|
|
2516
2841
|
]
|
|
2517
2842
|
}
|
|
2518
2843
|
);
|
|
2519
2844
|
}
|
|
2520
|
-
function ChatWindow() {
|
|
2845
|
+
function ChatWindow({ embedded } = {}) {
|
|
2521
2846
|
const { isOpen, config, configError, t, isRtl, preChatFormVisible } = useChat();
|
|
2522
2847
|
const reduced = useReducedMotion();
|
|
2523
|
-
const
|
|
2524
|
-
const [
|
|
2525
|
-
(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)(() => {
|
|
2526
2852
|
if (isOpen) {
|
|
2527
2853
|
setShouldRender(true);
|
|
2528
2854
|
requestAnimationFrame(() => {
|
|
@@ -2540,48 +2866,59 @@ function ChatWindow() {
|
|
|
2540
2866
|
}, [isOpen, reduced]);
|
|
2541
2867
|
if (!shouldRender) return null;
|
|
2542
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;
|
|
2543
2873
|
const style = {
|
|
2544
|
-
position: "fixed",
|
|
2545
|
-
bottom:
|
|
2546
|
-
[effectivePosition === "bottom-left" ? "left" : "right"]:
|
|
2547
|
-
width:
|
|
2548
|
-
maxWidth: "calc(100vw - 40px)",
|
|
2549
|
-
height:
|
|
2550
|
-
maxHeight:
|
|
2551
|
-
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,
|
|
2552
2882
|
overflow: "hidden",
|
|
2553
2883
|
display: "flex",
|
|
2554
2884
|
flexDirection: "column",
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
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,
|
|
2558
2893
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
2559
2894
|
opacity: visible ? 1 : 0,
|
|
2560
2895
|
transform: visible ? "translateY(0) scale(1)" : "translateY(16px) scale(0.97)",
|
|
2561
2896
|
transition: reduced ? "none" : "opacity 0.25s ease, transform 0.25s ease"
|
|
2562
2897
|
};
|
|
2898
|
+
const isDark = theme.scheme === "dark";
|
|
2563
2899
|
const poweredStyle = {
|
|
2564
2900
|
textAlign: "center",
|
|
2565
2901
|
padding: 6,
|
|
2566
2902
|
fontSize: 10,
|
|
2567
|
-
color: "#aaa"
|
|
2903
|
+
color: isDark ? "rgba(255,255,255,0.45)" : "#aaa"
|
|
2568
2904
|
};
|
|
2569
2905
|
const linkStyle = {
|
|
2570
|
-
color: "#888",
|
|
2906
|
+
color: isDark ? "rgba(255,255,255,0.6)" : "#888",
|
|
2571
2907
|
textDecoration: "underline",
|
|
2572
2908
|
textUnderlineOffset: 2
|
|
2573
2909
|
};
|
|
2574
|
-
return /* @__PURE__ */ (0,
|
|
2575
|
-
/* @__PURE__ */ (0,
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2910
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style, dir: isRtl ? "rtl" : "ltr", children: [
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatHeader, {}),
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IncidentBanner, {}),
|
|
2913
|
+
configError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ConfigError, { title: t("unable_to_load"), message: configError }) : preChatFormVisible ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PreChatFormView, {}) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2914
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatMessages, {}),
|
|
2915
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatSuggestions, {}),
|
|
2916
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatInput, {})
|
|
2580
2917
|
] }),
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2918
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: poweredStyle, children: [
|
|
2582
2919
|
t("powered_by"),
|
|
2583
2920
|
" ",
|
|
2584
|
-
/* @__PURE__ */ (0,
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2585
2922
|
"a",
|
|
2586
2923
|
{
|
|
2587
2924
|
href: "https://customerhero.app",
|
|
@@ -2596,12 +2933,15 @@ function ChatWindow() {
|
|
|
2596
2933
|
}
|
|
2597
2934
|
|
|
2598
2935
|
// src/components/chat-widget.tsx
|
|
2599
|
-
var
|
|
2600
|
-
function ChatWidgetInner({
|
|
2936
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2937
|
+
function ChatWidgetInner({
|
|
2938
|
+
identity,
|
|
2939
|
+
embedded
|
|
2940
|
+
}) {
|
|
2601
2941
|
const client = useCustomerHeroClient();
|
|
2602
2942
|
const { configLoaded, configError } = useChat();
|
|
2603
|
-
const prevIdentityRef = (0,
|
|
2604
|
-
(0,
|
|
2943
|
+
const prevIdentityRef = (0, import_react12.useRef)(void 0);
|
|
2944
|
+
(0, import_react12.useEffect)(() => {
|
|
2605
2945
|
const key = identity ? JSON.stringify(identity) : void 0;
|
|
2606
2946
|
if (key !== prevIdentityRef.current) {
|
|
2607
2947
|
prevIdentityRef.current = key;
|
|
@@ -2611,13 +2951,13 @@ function ChatWidgetInner({ identity }) {
|
|
|
2611
2951
|
}
|
|
2612
2952
|
}, [identity, client]);
|
|
2613
2953
|
if (!configLoaded || configError) return null;
|
|
2614
|
-
return /* @__PURE__ */ (0,
|
|
2615
|
-
/* @__PURE__ */ (0,
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2955
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatBubble, { embedded }),
|
|
2956
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWindow, { embedded })
|
|
2617
2957
|
] });
|
|
2618
2958
|
}
|
|
2619
|
-
function ChatWidget({ identity, ...config }) {
|
|
2620
|
-
return /* @__PURE__ */ (0,
|
|
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 }) });
|
|
2621
2961
|
}
|
|
2622
2962
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2623
2963
|
0 && (module.exports = {
|