@customerhero/react 2.1.1 → 2.2.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/dist/index.cjs +285 -57
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +281 -53
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -27,7 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
28
|
|
|
29
29
|
// src/components/chat-widget.tsx
|
|
30
|
-
var
|
|
30
|
+
var import_react11 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/context.tsx
|
|
33
33
|
var import_react = require("react");
|
|
@@ -118,6 +118,10 @@ function useChat() {
|
|
|
118
118
|
consumePendingPrefill: (0, import_react2.useCallback)(
|
|
119
119
|
() => client.consumePendingPrefill(),
|
|
120
120
|
[client]
|
|
121
|
+
),
|
|
122
|
+
dismissIncidentBanner: (0, import_react2.useCallback)(
|
|
123
|
+
() => client.dismissIncidentBanner(),
|
|
124
|
+
[client]
|
|
121
125
|
)
|
|
122
126
|
};
|
|
123
127
|
}
|
|
@@ -207,7 +211,7 @@ function ChatBubble() {
|
|
|
207
211
|
}
|
|
208
212
|
|
|
209
213
|
// src/components/chat-window.tsx
|
|
210
|
-
var
|
|
214
|
+
var import_react10 = require("react");
|
|
211
215
|
|
|
212
216
|
// src/components/chat-header.tsx
|
|
213
217
|
var import_react5 = require("react");
|
|
@@ -2226,8 +2230,231 @@ function Spinner2() {
|
|
|
2226
2230
|
] });
|
|
2227
2231
|
}
|
|
2228
2232
|
|
|
2229
|
-
// src/components/
|
|
2233
|
+
// src/components/incident-banner.tsx
|
|
2234
|
+
var import_react9 = require("react");
|
|
2230
2235
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2236
|
+
var PALETTE = {
|
|
2237
|
+
info: {
|
|
2238
|
+
bg: "#EFF6FF",
|
|
2239
|
+
fg: "#1E3A8A",
|
|
2240
|
+
fgMuted: "#3B5BA9",
|
|
2241
|
+
accent: "#2563EB",
|
|
2242
|
+
iconBg: "#DBEAFE",
|
|
2243
|
+
iconFg: "#2563EB"
|
|
2244
|
+
},
|
|
2245
|
+
warning: {
|
|
2246
|
+
bg: "#FFFBEB",
|
|
2247
|
+
fg: "#78350F",
|
|
2248
|
+
fgMuted: "#92541A",
|
|
2249
|
+
accent: "#B45309",
|
|
2250
|
+
iconBg: "#FEF3C7",
|
|
2251
|
+
iconFg: "#B45309"
|
|
2252
|
+
},
|
|
2253
|
+
outage: {
|
|
2254
|
+
bg: "#FEF2F2",
|
|
2255
|
+
fg: "#991B1B",
|
|
2256
|
+
fgMuted: "#B23A3A",
|
|
2257
|
+
accent: "#DC2626",
|
|
2258
|
+
iconBg: "#FEE2E2",
|
|
2259
|
+
iconFg: "#DC2626"
|
|
2260
|
+
}
|
|
2261
|
+
};
|
|
2262
|
+
function SeverityIcon({
|
|
2263
|
+
severity,
|
|
2264
|
+
color
|
|
2265
|
+
}) {
|
|
2266
|
+
const props = {
|
|
2267
|
+
width: 14,
|
|
2268
|
+
height: 14,
|
|
2269
|
+
viewBox: "0 0 24 24",
|
|
2270
|
+
fill: "none",
|
|
2271
|
+
stroke: color,
|
|
2272
|
+
strokeWidth: 2.25,
|
|
2273
|
+
strokeLinecap: "round",
|
|
2274
|
+
strokeLinejoin: "round",
|
|
2275
|
+
"aria-hidden": true
|
|
2276
|
+
};
|
|
2277
|
+
if (severity === "outage") {
|
|
2278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2281
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2282
|
+
] });
|
|
2283
|
+
}
|
|
2284
|
+
if (severity === "warning") {
|
|
2285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2286
|
+
/* @__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" }),
|
|
2287
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
2288
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
|
|
2289
|
+
] });
|
|
2290
|
+
}
|
|
2291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { ...props, children: [
|
|
2292
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2293
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
2294
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
2295
|
+
] });
|
|
2296
|
+
}
|
|
2297
|
+
function IncidentBanner() {
|
|
2298
|
+
const { incidentBanner, incidentBannerDismissed, dismissIncidentBanner, t } = useChat();
|
|
2299
|
+
const [linkHover, setLinkHover] = (0, import_react9.useState)(false);
|
|
2300
|
+
const [closeHover, setCloseHover] = (0, import_react9.useState)(false);
|
|
2301
|
+
if (!incidentBanner || incidentBannerDismissed) return null;
|
|
2302
|
+
const palette = PALETTE[incidentBanner.severity];
|
|
2303
|
+
const wrap = {
|
|
2304
|
+
background: palette.bg,
|
|
2305
|
+
color: palette.fg,
|
|
2306
|
+
padding: "12px 14px 12px 12px",
|
|
2307
|
+
display: "flex",
|
|
2308
|
+
gap: 10,
|
|
2309
|
+
alignItems: "flex-start",
|
|
2310
|
+
fontSize: 13,
|
|
2311
|
+
lineHeight: 1.45,
|
|
2312
|
+
boxShadow: "inset 0 -1px 0 rgba(0,0,0,0.04)"
|
|
2313
|
+
};
|
|
2314
|
+
const iconBadge = {
|
|
2315
|
+
width: 22,
|
|
2316
|
+
height: 22,
|
|
2317
|
+
borderRadius: "50%",
|
|
2318
|
+
background: palette.iconBg,
|
|
2319
|
+
display: "flex",
|
|
2320
|
+
alignItems: "center",
|
|
2321
|
+
justifyContent: "center",
|
|
2322
|
+
flexShrink: 0,
|
|
2323
|
+
marginTop: 1
|
|
2324
|
+
};
|
|
2325
|
+
const titleStyle = {
|
|
2326
|
+
margin: 0,
|
|
2327
|
+
fontSize: 13,
|
|
2328
|
+
fontWeight: 600,
|
|
2329
|
+
letterSpacing: "-0.005em"
|
|
2330
|
+
};
|
|
2331
|
+
const bodyStyle = {
|
|
2332
|
+
margin: "3px 0 0",
|
|
2333
|
+
fontSize: 12.5,
|
|
2334
|
+
color: palette.fgMuted
|
|
2335
|
+
};
|
|
2336
|
+
const footerRowStyle = {
|
|
2337
|
+
display: "flex",
|
|
2338
|
+
flexWrap: "wrap",
|
|
2339
|
+
alignItems: "center",
|
|
2340
|
+
gap: 10,
|
|
2341
|
+
marginTop: 8
|
|
2342
|
+
};
|
|
2343
|
+
const etaStyle = {
|
|
2344
|
+
display: "inline-block",
|
|
2345
|
+
padding: "2px 8px",
|
|
2346
|
+
borderRadius: 4,
|
|
2347
|
+
fontSize: 11,
|
|
2348
|
+
fontWeight: 500,
|
|
2349
|
+
color: palette.accent,
|
|
2350
|
+
background: palette.iconBg,
|
|
2351
|
+
lineHeight: 1.4
|
|
2352
|
+
};
|
|
2353
|
+
const linkStyle = {
|
|
2354
|
+
display: "inline-flex",
|
|
2355
|
+
alignItems: "center",
|
|
2356
|
+
gap: 4,
|
|
2357
|
+
color: palette.accent,
|
|
2358
|
+
textDecoration: linkHover ? "underline" : "none",
|
|
2359
|
+
textUnderlineOffset: 3,
|
|
2360
|
+
fontSize: 12.5,
|
|
2361
|
+
fontWeight: 600
|
|
2362
|
+
};
|
|
2363
|
+
const closeButtonStyle = {
|
|
2364
|
+
background: closeHover ? "rgba(0,0,0,0.06)" : "transparent",
|
|
2365
|
+
border: "none",
|
|
2366
|
+
color: palette.fgMuted,
|
|
2367
|
+
cursor: "pointer",
|
|
2368
|
+
padding: 4,
|
|
2369
|
+
borderRadius: 6,
|
|
2370
|
+
flexShrink: 0,
|
|
2371
|
+
lineHeight: 0,
|
|
2372
|
+
marginTop: -2,
|
|
2373
|
+
marginRight: -2,
|
|
2374
|
+
transition: "background-color 0.12s ease"
|
|
2375
|
+
};
|
|
2376
|
+
const role = incidentBanner.severity === "outage" ? "alert" : "status";
|
|
2377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { role, style: wrap, children: [
|
|
2378
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: iconBadge, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2379
|
+
SeverityIcon,
|
|
2380
|
+
{
|
|
2381
|
+
severity: incidentBanner.severity,
|
|
2382
|
+
color: palette.iconFg
|
|
2383
|
+
}
|
|
2384
|
+
) }),
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { style: titleStyle, children: incidentBanner.title }),
|
|
2387
|
+
incidentBanner.body ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { style: bodyStyle, children: incidentBanner.body }) : null,
|
|
2388
|
+
incidentBanner.eta || incidentBanner.link ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: footerRowStyle, children: [
|
|
2389
|
+
incidentBanner.eta ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: etaStyle, children: incidentBanner.eta }) : null,
|
|
2390
|
+
incidentBanner.link ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2391
|
+
"a",
|
|
2392
|
+
{
|
|
2393
|
+
href: incidentBanner.link.url,
|
|
2394
|
+
target: "_blank",
|
|
2395
|
+
rel: "noopener noreferrer",
|
|
2396
|
+
style: linkStyle,
|
|
2397
|
+
onMouseEnter: () => setLinkHover(true),
|
|
2398
|
+
onMouseLeave: () => setLinkHover(false),
|
|
2399
|
+
children: [
|
|
2400
|
+
incidentBanner.link.label ?? t("incident_default_link_label"),
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2402
|
+
"svg",
|
|
2403
|
+
{
|
|
2404
|
+
width: "12",
|
|
2405
|
+
height: "12",
|
|
2406
|
+
viewBox: "0 0 24 24",
|
|
2407
|
+
fill: "none",
|
|
2408
|
+
stroke: "currentColor",
|
|
2409
|
+
strokeWidth: "2.5",
|
|
2410
|
+
strokeLinecap: "round",
|
|
2411
|
+
strokeLinejoin: "round",
|
|
2412
|
+
"aria-hidden": "true",
|
|
2413
|
+
children: [
|
|
2414
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
2415
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "12 5 19 12 12 19" })
|
|
2416
|
+
]
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
]
|
|
2420
|
+
}
|
|
2421
|
+
) : null
|
|
2422
|
+
] }) : null
|
|
2423
|
+
] }),
|
|
2424
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2425
|
+
"button",
|
|
2426
|
+
{
|
|
2427
|
+
type: "button",
|
|
2428
|
+
onClick: dismissIncidentBanner,
|
|
2429
|
+
"aria-label": t("incident_dismiss"),
|
|
2430
|
+
style: closeButtonStyle,
|
|
2431
|
+
onMouseEnter: () => setCloseHover(true),
|
|
2432
|
+
onMouseLeave: () => setCloseHover(false),
|
|
2433
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2434
|
+
"svg",
|
|
2435
|
+
{
|
|
2436
|
+
width: "14",
|
|
2437
|
+
height: "14",
|
|
2438
|
+
viewBox: "0 0 24 24",
|
|
2439
|
+
fill: "none",
|
|
2440
|
+
stroke: "currentColor",
|
|
2441
|
+
strokeWidth: "2",
|
|
2442
|
+
strokeLinecap: "round",
|
|
2443
|
+
strokeLinejoin: "round",
|
|
2444
|
+
"aria-hidden": "true",
|
|
2445
|
+
children: [
|
|
2446
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2447
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2448
|
+
]
|
|
2449
|
+
}
|
|
2450
|
+
)
|
|
2451
|
+
}
|
|
2452
|
+
)
|
|
2453
|
+
] });
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
// src/components/chat-window.tsx
|
|
2457
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2231
2458
|
function ConfigError({ message, title }) {
|
|
2232
2459
|
const errorStyle = {
|
|
2233
2460
|
flex: 1,
|
|
@@ -2239,8 +2466,8 @@ function ConfigError({ message, title }) {
|
|
|
2239
2466
|
textAlign: "center",
|
|
2240
2467
|
gap: 8
|
|
2241
2468
|
};
|
|
2242
|
-
return /* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: errorStyle, children: [
|
|
2470
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2244
2471
|
"svg",
|
|
2245
2472
|
{
|
|
2246
2473
|
width: "32",
|
|
@@ -2252,14 +2479,14 @@ function ConfigError({ message, title }) {
|
|
|
2252
2479
|
strokeLinecap: "round",
|
|
2253
2480
|
strokeLinejoin: "round",
|
|
2254
2481
|
children: [
|
|
2255
|
-
/* @__PURE__ */ (0,
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2482
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2258
2485
|
]
|
|
2259
2486
|
}
|
|
2260
2487
|
),
|
|
2261
|
-
/* @__PURE__ */ (0,
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2488
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 14, fontWeight: 500, color: "#333", margin: 0 }, children: title }),
|
|
2489
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 12, color: "#999", margin: 0 }, children: message })
|
|
2263
2490
|
] });
|
|
2264
2491
|
}
|
|
2265
2492
|
function fieldKey(field) {
|
|
@@ -2286,9 +2513,9 @@ function validateField(field, value) {
|
|
|
2286
2513
|
}
|
|
2287
2514
|
function PreChatFormView() {
|
|
2288
2515
|
const { preChatForm, submitPreChatForm, cancelPreChatForm, config, t } = useChat();
|
|
2289
|
-
const [values, setValues] = (0,
|
|
2290
|
-
const [errors, setErrors] = (0,
|
|
2291
|
-
const [submitting, setSubmitting] = (0,
|
|
2516
|
+
const [values, setValues] = (0, import_react10.useState)({});
|
|
2517
|
+
const [errors, setErrors] = (0, import_react10.useState)({});
|
|
2518
|
+
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
2292
2519
|
if (!preChatForm) return null;
|
|
2293
2520
|
function setValue(key, value) {
|
|
2294
2521
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
@@ -2384,15 +2611,15 @@ function PreChatFormView() {
|
|
|
2384
2611
|
fontSize: 14,
|
|
2385
2612
|
cursor: "pointer"
|
|
2386
2613
|
};
|
|
2387
|
-
return /* @__PURE__ */ (0,
|
|
2614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2388
2615
|
"form",
|
|
2389
2616
|
{
|
|
2390
2617
|
style: containerStyle,
|
|
2391
2618
|
onSubmit: handleSubmit,
|
|
2392
2619
|
"data-customerhero-prechat-form": true,
|
|
2393
2620
|
children: [
|
|
2394
|
-
preChatForm.title && /* @__PURE__ */ (0,
|
|
2395
|
-
preChatForm.description && /* @__PURE__ */ (0,
|
|
2621
|
+
preChatForm.title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { style: { fontSize: 16, fontWeight: 600, margin: 0 }, children: preChatForm.title }),
|
|
2622
|
+
preChatForm.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { fontSize: 13, margin: 0, opacity: 0.8 }, children: preChatForm.description }),
|
|
2396
2623
|
preChatForm.fields.map((field) => {
|
|
2397
2624
|
const k = fieldKey(field);
|
|
2398
2625
|
const v = values[k];
|
|
@@ -2400,12 +2627,12 @@ function PreChatFormView() {
|
|
|
2400
2627
|
const required = "required" in field ? !!field.required : false;
|
|
2401
2628
|
const label = fieldLabel(field);
|
|
2402
2629
|
if (field.kind === "textarea") {
|
|
2403
|
-
return /* @__PURE__ */ (0,
|
|
2404
|
-
/* @__PURE__ */ (0,
|
|
2630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2405
2632
|
label,
|
|
2406
2633
|
required && " *"
|
|
2407
2634
|
] }),
|
|
2408
|
-
/* @__PURE__ */ (0,
|
|
2635
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2409
2636
|
"textarea",
|
|
2410
2637
|
{
|
|
2411
2638
|
style: { ...inputStyle, minHeight: 80, resize: "vertical" },
|
|
@@ -2414,32 +2641,32 @@ function PreChatFormView() {
|
|
|
2414
2641
|
onChange: (e) => setValue(k, e.target.value)
|
|
2415
2642
|
}
|
|
2416
2643
|
),
|
|
2417
|
-
err && /* @__PURE__ */ (0,
|
|
2644
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2418
2645
|
] }, k);
|
|
2419
2646
|
}
|
|
2420
2647
|
if (field.kind === "select") {
|
|
2421
|
-
return /* @__PURE__ */ (0,
|
|
2422
|
-
/* @__PURE__ */ (0,
|
|
2648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2423
2650
|
label,
|
|
2424
2651
|
required && " *"
|
|
2425
2652
|
] }),
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2653
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2427
2654
|
"select",
|
|
2428
2655
|
{
|
|
2429
2656
|
style: inputStyle,
|
|
2430
2657
|
value: v ?? "",
|
|
2431
2658
|
onChange: (e) => setValue(k, e.target.value),
|
|
2432
2659
|
children: [
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2434
|
-
field.options.map((opt) => /* @__PURE__ */ (0,
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "\u2014" }),
|
|
2661
|
+
field.options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
|
|
2435
2662
|
]
|
|
2436
2663
|
}
|
|
2437
2664
|
),
|
|
2438
|
-
err && /* @__PURE__ */ (0,
|
|
2665
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2439
2666
|
] }, k);
|
|
2440
2667
|
}
|
|
2441
2668
|
if (field.kind === "consent") {
|
|
2442
|
-
return /* @__PURE__ */ (0,
|
|
2669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2443
2670
|
"label",
|
|
2444
2671
|
{
|
|
2445
2672
|
style: {
|
|
@@ -2449,7 +2676,7 @@ function PreChatFormView() {
|
|
|
2449
2676
|
gap: 8
|
|
2450
2677
|
},
|
|
2451
2678
|
children: [
|
|
2452
|
-
/* @__PURE__ */ (0,
|
|
2679
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2453
2680
|
"input",
|
|
2454
2681
|
{
|
|
2455
2682
|
type: "checkbox",
|
|
@@ -2458,11 +2685,11 @@ function PreChatFormView() {
|
|
|
2458
2685
|
style: { marginTop: 3 }
|
|
2459
2686
|
}
|
|
2460
2687
|
),
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { style: { fontSize: 13, fontWeight: 400 }, children: [
|
|
2462
2689
|
field.label,
|
|
2463
|
-
field.url && /* @__PURE__ */ (0,
|
|
2690
|
+
field.url && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2464
2691
|
" ",
|
|
2465
|
-
/* @__PURE__ */ (0,
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2466
2693
|
"a",
|
|
2467
2694
|
{
|
|
2468
2695
|
href: field.url,
|
|
@@ -2474,7 +2701,7 @@ function PreChatFormView() {
|
|
|
2474
2701
|
)
|
|
2475
2702
|
] })
|
|
2476
2703
|
] }),
|
|
2477
|
-
err && /* @__PURE__ */ (0,
|
|
2704
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2478
2705
|
]
|
|
2479
2706
|
},
|
|
2480
2707
|
k
|
|
@@ -2482,12 +2709,12 @@ function PreChatFormView() {
|
|
|
2482
2709
|
}
|
|
2483
2710
|
const inputType = field.kind === "email" ? "email" : field.kind === "phone" ? "tel" : "text";
|
|
2484
2711
|
const maxLength = field.kind === "text" ? field.maxLength : void 0;
|
|
2485
|
-
return /* @__PURE__ */ (0,
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
2712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { style: labelStyle, children: [
|
|
2713
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2487
2714
|
label,
|
|
2488
2715
|
required && " *"
|
|
2489
2716
|
] }),
|
|
2490
|
-
/* @__PURE__ */ (0,
|
|
2717
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2491
2718
|
"input",
|
|
2492
2719
|
{
|
|
2493
2720
|
type: inputType,
|
|
@@ -2497,11 +2724,11 @@ function PreChatFormView() {
|
|
|
2497
2724
|
onChange: (e) => setValue(k, e.target.value)
|
|
2498
2725
|
}
|
|
2499
2726
|
),
|
|
2500
|
-
err && /* @__PURE__ */ (0,
|
|
2727
|
+
err && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: errorStyle, children: err })
|
|
2501
2728
|
] }, k);
|
|
2502
2729
|
}),
|
|
2503
|
-
/* @__PURE__ */ (0,
|
|
2504
|
-
/* @__PURE__ */ (0,
|
|
2730
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: buttonRowStyle, children: [
|
|
2731
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2505
2732
|
"button",
|
|
2506
2733
|
{
|
|
2507
2734
|
type: "button",
|
|
@@ -2511,7 +2738,7 @@ function PreChatFormView() {
|
|
|
2511
2738
|
children: t("action_cancel")
|
|
2512
2739
|
}
|
|
2513
2740
|
),
|
|
2514
|
-
/* @__PURE__ */ (0,
|
|
2741
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", style: submitStyle, disabled: submitting, children: preChatForm.submitLabel })
|
|
2515
2742
|
] })
|
|
2516
2743
|
]
|
|
2517
2744
|
}
|
|
@@ -2520,9 +2747,9 @@ function PreChatFormView() {
|
|
|
2520
2747
|
function ChatWindow() {
|
|
2521
2748
|
const { isOpen, config, configError, t, isRtl, preChatFormVisible } = useChat();
|
|
2522
2749
|
const reduced = useReducedMotion();
|
|
2523
|
-
const [visible, setVisible] = (0,
|
|
2524
|
-
const [shouldRender, setShouldRender] = (0,
|
|
2525
|
-
(0,
|
|
2750
|
+
const [visible, setVisible] = (0, import_react10.useState)(false);
|
|
2751
|
+
const [shouldRender, setShouldRender] = (0, import_react10.useState)(false);
|
|
2752
|
+
(0, import_react10.useEffect)(() => {
|
|
2526
2753
|
if (isOpen) {
|
|
2527
2754
|
setShouldRender(true);
|
|
2528
2755
|
requestAnimationFrame(() => {
|
|
@@ -2571,17 +2798,18 @@ function ChatWindow() {
|
|
|
2571
2798
|
textDecoration: "underline",
|
|
2572
2799
|
textUnderlineOffset: 2
|
|
2573
2800
|
};
|
|
2574
|
-
return /* @__PURE__ */ (0,
|
|
2575
|
-
/* @__PURE__ */ (0,
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style, dir: isRtl ? "rtl" : "ltr", children: [
|
|
2802
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatHeader, {}),
|
|
2803
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IncidentBanner, {}),
|
|
2804
|
+
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: [
|
|
2805
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatMessages, {}),
|
|
2806
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatSuggestions, {}),
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatInput, {})
|
|
2580
2808
|
] }),
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: poweredStyle, children: [
|
|
2582
2810
|
t("powered_by"),
|
|
2583
2811
|
" ",
|
|
2584
|
-
/* @__PURE__ */ (0,
|
|
2812
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2585
2813
|
"a",
|
|
2586
2814
|
{
|
|
2587
2815
|
href: "https://customerhero.app",
|
|
@@ -2596,12 +2824,12 @@ function ChatWindow() {
|
|
|
2596
2824
|
}
|
|
2597
2825
|
|
|
2598
2826
|
// src/components/chat-widget.tsx
|
|
2599
|
-
var
|
|
2827
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2600
2828
|
function ChatWidgetInner({ identity }) {
|
|
2601
2829
|
const client = useCustomerHeroClient();
|
|
2602
2830
|
const { configLoaded, configError } = useChat();
|
|
2603
|
-
const prevIdentityRef = (0,
|
|
2604
|
-
(0,
|
|
2831
|
+
const prevIdentityRef = (0, import_react11.useRef)(void 0);
|
|
2832
|
+
(0, import_react11.useEffect)(() => {
|
|
2605
2833
|
const key = identity ? JSON.stringify(identity) : void 0;
|
|
2606
2834
|
if (key !== prevIdentityRef.current) {
|
|
2607
2835
|
prevIdentityRef.current = key;
|
|
@@ -2611,13 +2839,13 @@ function ChatWidgetInner({ identity }) {
|
|
|
2611
2839
|
}
|
|
2612
2840
|
}, [identity, client]);
|
|
2613
2841
|
if (!configLoaded || configError) return null;
|
|
2614
|
-
return /* @__PURE__ */ (0,
|
|
2615
|
-
/* @__PURE__ */ (0,
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2842
|
+
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, {})
|
|
2617
2845
|
] });
|
|
2618
2846
|
}
|
|
2619
2847
|
function ChatWidget({ identity, ...config }) {
|
|
2620
|
-
return /* @__PURE__ */ (0,
|
|
2848
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CustomerHeroProvider, { ...config, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatWidgetInner, { identity }) });
|
|
2621
2849
|
}
|
|
2622
2850
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2623
2851
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -97,6 +97,10 @@ function useChat() {
|
|
|
97
97
|
consumePendingPrefill: useCallback(
|
|
98
98
|
() => client.consumePendingPrefill(),
|
|
99
99
|
[client]
|
|
100
|
+
),
|
|
101
|
+
dismissIncidentBanner: useCallback(
|
|
102
|
+
() => client.dismissIncidentBanner(),
|
|
103
|
+
[client]
|
|
100
104
|
)
|
|
101
105
|
};
|
|
102
106
|
}
|
|
@@ -186,7 +190,7 @@ function ChatBubble() {
|
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
// src/components/chat-window.tsx
|
|
189
|
-
import { useEffect as useEffect7, useState as
|
|
193
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
190
194
|
|
|
191
195
|
// src/components/chat-header.tsx
|
|
192
196
|
import { useState as useState3, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
@@ -2214,8 +2218,231 @@ function Spinner2() {
|
|
|
2214
2218
|
] });
|
|
2215
2219
|
}
|
|
2216
2220
|
|
|
2221
|
+
// src/components/incident-banner.tsx
|
|
2222
|
+
import { useState as useState7 } from "react";
|
|
2223
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2224
|
+
var PALETTE = {
|
|
2225
|
+
info: {
|
|
2226
|
+
bg: "#EFF6FF",
|
|
2227
|
+
fg: "#1E3A8A",
|
|
2228
|
+
fgMuted: "#3B5BA9",
|
|
2229
|
+
accent: "#2563EB",
|
|
2230
|
+
iconBg: "#DBEAFE",
|
|
2231
|
+
iconFg: "#2563EB"
|
|
2232
|
+
},
|
|
2233
|
+
warning: {
|
|
2234
|
+
bg: "#FFFBEB",
|
|
2235
|
+
fg: "#78350F",
|
|
2236
|
+
fgMuted: "#92541A",
|
|
2237
|
+
accent: "#B45309",
|
|
2238
|
+
iconBg: "#FEF3C7",
|
|
2239
|
+
iconFg: "#B45309"
|
|
2240
|
+
},
|
|
2241
|
+
outage: {
|
|
2242
|
+
bg: "#FEF2F2",
|
|
2243
|
+
fg: "#991B1B",
|
|
2244
|
+
fgMuted: "#B23A3A",
|
|
2245
|
+
accent: "#DC2626",
|
|
2246
|
+
iconBg: "#FEE2E2",
|
|
2247
|
+
iconFg: "#DC2626"
|
|
2248
|
+
}
|
|
2249
|
+
};
|
|
2250
|
+
function SeverityIcon({
|
|
2251
|
+
severity,
|
|
2252
|
+
color
|
|
2253
|
+
}) {
|
|
2254
|
+
const props = {
|
|
2255
|
+
width: 14,
|
|
2256
|
+
height: 14,
|
|
2257
|
+
viewBox: "0 0 24 24",
|
|
2258
|
+
fill: "none",
|
|
2259
|
+
stroke: color,
|
|
2260
|
+
strokeWidth: 2.25,
|
|
2261
|
+
strokeLinecap: "round",
|
|
2262
|
+
strokeLinejoin: "round",
|
|
2263
|
+
"aria-hidden": true
|
|
2264
|
+
};
|
|
2265
|
+
if (severity === "outage") {
|
|
2266
|
+
return /* @__PURE__ */ jsxs6("svg", { ...props, children: [
|
|
2267
|
+
/* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2268
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2269
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2270
|
+
] });
|
|
2271
|
+
}
|
|
2272
|
+
if (severity === "warning") {
|
|
2273
|
+
return /* @__PURE__ */ jsxs6("svg", { ...props, children: [
|
|
2274
|
+
/* @__PURE__ */ jsx9("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" }),
|
|
2275
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
2276
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
|
|
2277
|
+
] });
|
|
2278
|
+
}
|
|
2279
|
+
return /* @__PURE__ */ jsxs6("svg", { ...props, children: [
|
|
2280
|
+
/* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2281
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
2282
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
2283
|
+
] });
|
|
2284
|
+
}
|
|
2285
|
+
function IncidentBanner() {
|
|
2286
|
+
const { incidentBanner, incidentBannerDismissed, dismissIncidentBanner, t } = useChat();
|
|
2287
|
+
const [linkHover, setLinkHover] = useState7(false);
|
|
2288
|
+
const [closeHover, setCloseHover] = useState7(false);
|
|
2289
|
+
if (!incidentBanner || incidentBannerDismissed) return null;
|
|
2290
|
+
const palette = PALETTE[incidentBanner.severity];
|
|
2291
|
+
const wrap = {
|
|
2292
|
+
background: palette.bg,
|
|
2293
|
+
color: palette.fg,
|
|
2294
|
+
padding: "12px 14px 12px 12px",
|
|
2295
|
+
display: "flex",
|
|
2296
|
+
gap: 10,
|
|
2297
|
+
alignItems: "flex-start",
|
|
2298
|
+
fontSize: 13,
|
|
2299
|
+
lineHeight: 1.45,
|
|
2300
|
+
boxShadow: "inset 0 -1px 0 rgba(0,0,0,0.04)"
|
|
2301
|
+
};
|
|
2302
|
+
const iconBadge = {
|
|
2303
|
+
width: 22,
|
|
2304
|
+
height: 22,
|
|
2305
|
+
borderRadius: "50%",
|
|
2306
|
+
background: palette.iconBg,
|
|
2307
|
+
display: "flex",
|
|
2308
|
+
alignItems: "center",
|
|
2309
|
+
justifyContent: "center",
|
|
2310
|
+
flexShrink: 0,
|
|
2311
|
+
marginTop: 1
|
|
2312
|
+
};
|
|
2313
|
+
const titleStyle = {
|
|
2314
|
+
margin: 0,
|
|
2315
|
+
fontSize: 13,
|
|
2316
|
+
fontWeight: 600,
|
|
2317
|
+
letterSpacing: "-0.005em"
|
|
2318
|
+
};
|
|
2319
|
+
const bodyStyle = {
|
|
2320
|
+
margin: "3px 0 0",
|
|
2321
|
+
fontSize: 12.5,
|
|
2322
|
+
color: palette.fgMuted
|
|
2323
|
+
};
|
|
2324
|
+
const footerRowStyle = {
|
|
2325
|
+
display: "flex",
|
|
2326
|
+
flexWrap: "wrap",
|
|
2327
|
+
alignItems: "center",
|
|
2328
|
+
gap: 10,
|
|
2329
|
+
marginTop: 8
|
|
2330
|
+
};
|
|
2331
|
+
const etaStyle = {
|
|
2332
|
+
display: "inline-block",
|
|
2333
|
+
padding: "2px 8px",
|
|
2334
|
+
borderRadius: 4,
|
|
2335
|
+
fontSize: 11,
|
|
2336
|
+
fontWeight: 500,
|
|
2337
|
+
color: palette.accent,
|
|
2338
|
+
background: palette.iconBg,
|
|
2339
|
+
lineHeight: 1.4
|
|
2340
|
+
};
|
|
2341
|
+
const linkStyle = {
|
|
2342
|
+
display: "inline-flex",
|
|
2343
|
+
alignItems: "center",
|
|
2344
|
+
gap: 4,
|
|
2345
|
+
color: palette.accent,
|
|
2346
|
+
textDecoration: linkHover ? "underline" : "none",
|
|
2347
|
+
textUnderlineOffset: 3,
|
|
2348
|
+
fontSize: 12.5,
|
|
2349
|
+
fontWeight: 600
|
|
2350
|
+
};
|
|
2351
|
+
const closeButtonStyle = {
|
|
2352
|
+
background: closeHover ? "rgba(0,0,0,0.06)" : "transparent",
|
|
2353
|
+
border: "none",
|
|
2354
|
+
color: palette.fgMuted,
|
|
2355
|
+
cursor: "pointer",
|
|
2356
|
+
padding: 4,
|
|
2357
|
+
borderRadius: 6,
|
|
2358
|
+
flexShrink: 0,
|
|
2359
|
+
lineHeight: 0,
|
|
2360
|
+
marginTop: -2,
|
|
2361
|
+
marginRight: -2,
|
|
2362
|
+
transition: "background-color 0.12s ease"
|
|
2363
|
+
};
|
|
2364
|
+
const role = incidentBanner.severity === "outage" ? "alert" : "status";
|
|
2365
|
+
return /* @__PURE__ */ jsxs6("div", { role, style: wrap, children: [
|
|
2366
|
+
/* @__PURE__ */ jsx9("div", { style: iconBadge, children: /* @__PURE__ */ jsx9(
|
|
2367
|
+
SeverityIcon,
|
|
2368
|
+
{
|
|
2369
|
+
severity: incidentBanner.severity,
|
|
2370
|
+
color: palette.iconFg
|
|
2371
|
+
}
|
|
2372
|
+
) }),
|
|
2373
|
+
/* @__PURE__ */ jsxs6("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
2374
|
+
/* @__PURE__ */ jsx9("p", { style: titleStyle, children: incidentBanner.title }),
|
|
2375
|
+
incidentBanner.body ? /* @__PURE__ */ jsx9("p", { style: bodyStyle, children: incidentBanner.body }) : null,
|
|
2376
|
+
incidentBanner.eta || incidentBanner.link ? /* @__PURE__ */ jsxs6("div", { style: footerRowStyle, children: [
|
|
2377
|
+
incidentBanner.eta ? /* @__PURE__ */ jsx9("span", { style: etaStyle, children: incidentBanner.eta }) : null,
|
|
2378
|
+
incidentBanner.link ? /* @__PURE__ */ jsxs6(
|
|
2379
|
+
"a",
|
|
2380
|
+
{
|
|
2381
|
+
href: incidentBanner.link.url,
|
|
2382
|
+
target: "_blank",
|
|
2383
|
+
rel: "noopener noreferrer",
|
|
2384
|
+
style: linkStyle,
|
|
2385
|
+
onMouseEnter: () => setLinkHover(true),
|
|
2386
|
+
onMouseLeave: () => setLinkHover(false),
|
|
2387
|
+
children: [
|
|
2388
|
+
incidentBanner.link.label ?? t("incident_default_link_label"),
|
|
2389
|
+
/* @__PURE__ */ jsxs6(
|
|
2390
|
+
"svg",
|
|
2391
|
+
{
|
|
2392
|
+
width: "12",
|
|
2393
|
+
height: "12",
|
|
2394
|
+
viewBox: "0 0 24 24",
|
|
2395
|
+
fill: "none",
|
|
2396
|
+
stroke: "currentColor",
|
|
2397
|
+
strokeWidth: "2.5",
|
|
2398
|
+
strokeLinecap: "round",
|
|
2399
|
+
strokeLinejoin: "round",
|
|
2400
|
+
"aria-hidden": "true",
|
|
2401
|
+
children: [
|
|
2402
|
+
/* @__PURE__ */ jsx9("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
2403
|
+
/* @__PURE__ */ jsx9("polyline", { points: "12 5 19 12 12 19" })
|
|
2404
|
+
]
|
|
2405
|
+
}
|
|
2406
|
+
)
|
|
2407
|
+
]
|
|
2408
|
+
}
|
|
2409
|
+
) : null
|
|
2410
|
+
] }) : null
|
|
2411
|
+
] }),
|
|
2412
|
+
/* @__PURE__ */ jsx9(
|
|
2413
|
+
"button",
|
|
2414
|
+
{
|
|
2415
|
+
type: "button",
|
|
2416
|
+
onClick: dismissIncidentBanner,
|
|
2417
|
+
"aria-label": t("incident_dismiss"),
|
|
2418
|
+
style: closeButtonStyle,
|
|
2419
|
+
onMouseEnter: () => setCloseHover(true),
|
|
2420
|
+
onMouseLeave: () => setCloseHover(false),
|
|
2421
|
+
children: /* @__PURE__ */ jsxs6(
|
|
2422
|
+
"svg",
|
|
2423
|
+
{
|
|
2424
|
+
width: "14",
|
|
2425
|
+
height: "14",
|
|
2426
|
+
viewBox: "0 0 24 24",
|
|
2427
|
+
fill: "none",
|
|
2428
|
+
stroke: "currentColor",
|
|
2429
|
+
strokeWidth: "2",
|
|
2430
|
+
strokeLinecap: "round",
|
|
2431
|
+
strokeLinejoin: "round",
|
|
2432
|
+
"aria-hidden": "true",
|
|
2433
|
+
children: [
|
|
2434
|
+
/* @__PURE__ */ jsx9("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2435
|
+
/* @__PURE__ */ jsx9("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2436
|
+
]
|
|
2437
|
+
}
|
|
2438
|
+
)
|
|
2439
|
+
}
|
|
2440
|
+
)
|
|
2441
|
+
] });
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2217
2444
|
// src/components/chat-window.tsx
|
|
2218
|
-
import { Fragment as Fragment5, jsx as
|
|
2445
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2219
2446
|
function ConfigError({ message, title }) {
|
|
2220
2447
|
const errorStyle = {
|
|
2221
2448
|
flex: 1,
|
|
@@ -2227,8 +2454,8 @@ function ConfigError({ message, title }) {
|
|
|
2227
2454
|
textAlign: "center",
|
|
2228
2455
|
gap: 8
|
|
2229
2456
|
};
|
|
2230
|
-
return /* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */
|
|
2457
|
+
return /* @__PURE__ */ jsxs7("div", { style: errorStyle, children: [
|
|
2458
|
+
/* @__PURE__ */ jsxs7(
|
|
2232
2459
|
"svg",
|
|
2233
2460
|
{
|
|
2234
2461
|
width: "32",
|
|
@@ -2240,14 +2467,14 @@ function ConfigError({ message, title }) {
|
|
|
2240
2467
|
strokeLinecap: "round",
|
|
2241
2468
|
strokeLinejoin: "round",
|
|
2242
2469
|
children: [
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
/* @__PURE__ */
|
|
2470
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2471
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2472
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2246
2473
|
]
|
|
2247
2474
|
}
|
|
2248
2475
|
),
|
|
2249
|
-
/* @__PURE__ */
|
|
2250
|
-
/* @__PURE__ */
|
|
2476
|
+
/* @__PURE__ */ jsx10("p", { style: { fontSize: 14, fontWeight: 500, color: "#333", margin: 0 }, children: title }),
|
|
2477
|
+
/* @__PURE__ */ jsx10("p", { style: { fontSize: 12, color: "#999", margin: 0 }, children: message })
|
|
2251
2478
|
] });
|
|
2252
2479
|
}
|
|
2253
2480
|
function fieldKey(field) {
|
|
@@ -2274,9 +2501,9 @@ function validateField(field, value) {
|
|
|
2274
2501
|
}
|
|
2275
2502
|
function PreChatFormView() {
|
|
2276
2503
|
const { preChatForm, submitPreChatForm, cancelPreChatForm, config, t } = useChat();
|
|
2277
|
-
const [values, setValues] =
|
|
2278
|
-
const [errors, setErrors] =
|
|
2279
|
-
const [submitting, setSubmitting] =
|
|
2504
|
+
const [values, setValues] = useState8({});
|
|
2505
|
+
const [errors, setErrors] = useState8({});
|
|
2506
|
+
const [submitting, setSubmitting] = useState8(false);
|
|
2280
2507
|
if (!preChatForm) return null;
|
|
2281
2508
|
function setValue(key, value) {
|
|
2282
2509
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
@@ -2372,15 +2599,15 @@ function PreChatFormView() {
|
|
|
2372
2599
|
fontSize: 14,
|
|
2373
2600
|
cursor: "pointer"
|
|
2374
2601
|
};
|
|
2375
|
-
return /* @__PURE__ */
|
|
2602
|
+
return /* @__PURE__ */ jsxs7(
|
|
2376
2603
|
"form",
|
|
2377
2604
|
{
|
|
2378
2605
|
style: containerStyle,
|
|
2379
2606
|
onSubmit: handleSubmit,
|
|
2380
2607
|
"data-customerhero-prechat-form": true,
|
|
2381
2608
|
children: [
|
|
2382
|
-
preChatForm.title && /* @__PURE__ */
|
|
2383
|
-
preChatForm.description && /* @__PURE__ */
|
|
2609
|
+
preChatForm.title && /* @__PURE__ */ jsx10("h3", { style: { fontSize: 16, fontWeight: 600, margin: 0 }, children: preChatForm.title }),
|
|
2610
|
+
preChatForm.description && /* @__PURE__ */ jsx10("p", { style: { fontSize: 13, margin: 0, opacity: 0.8 }, children: preChatForm.description }),
|
|
2384
2611
|
preChatForm.fields.map((field) => {
|
|
2385
2612
|
const k = fieldKey(field);
|
|
2386
2613
|
const v = values[k];
|
|
@@ -2388,12 +2615,12 @@ function PreChatFormView() {
|
|
|
2388
2615
|
const required = "required" in field ? !!field.required : false;
|
|
2389
2616
|
const label = fieldLabel(field);
|
|
2390
2617
|
if (field.kind === "textarea") {
|
|
2391
|
-
return /* @__PURE__ */
|
|
2392
|
-
/* @__PURE__ */
|
|
2618
|
+
return /* @__PURE__ */ jsxs7("label", { style: labelStyle, children: [
|
|
2619
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2393
2620
|
label,
|
|
2394
2621
|
required && " *"
|
|
2395
2622
|
] }),
|
|
2396
|
-
/* @__PURE__ */
|
|
2623
|
+
/* @__PURE__ */ jsx10(
|
|
2397
2624
|
"textarea",
|
|
2398
2625
|
{
|
|
2399
2626
|
style: { ...inputStyle, minHeight: 80, resize: "vertical" },
|
|
@@ -2402,32 +2629,32 @@ function PreChatFormView() {
|
|
|
2402
2629
|
onChange: (e) => setValue(k, e.target.value)
|
|
2403
2630
|
}
|
|
2404
2631
|
),
|
|
2405
|
-
err && /* @__PURE__ */
|
|
2632
|
+
err && /* @__PURE__ */ jsx10("span", { style: errorStyle, children: err })
|
|
2406
2633
|
] }, k);
|
|
2407
2634
|
}
|
|
2408
2635
|
if (field.kind === "select") {
|
|
2409
|
-
return /* @__PURE__ */
|
|
2410
|
-
/* @__PURE__ */
|
|
2636
|
+
return /* @__PURE__ */ jsxs7("label", { style: labelStyle, children: [
|
|
2637
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2411
2638
|
label,
|
|
2412
2639
|
required && " *"
|
|
2413
2640
|
] }),
|
|
2414
|
-
/* @__PURE__ */
|
|
2641
|
+
/* @__PURE__ */ jsxs7(
|
|
2415
2642
|
"select",
|
|
2416
2643
|
{
|
|
2417
2644
|
style: inputStyle,
|
|
2418
2645
|
value: v ?? "",
|
|
2419
2646
|
onChange: (e) => setValue(k, e.target.value),
|
|
2420
2647
|
children: [
|
|
2421
|
-
/* @__PURE__ */
|
|
2422
|
-
field.options.map((opt) => /* @__PURE__ */
|
|
2648
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "\u2014" }),
|
|
2649
|
+
field.options.map((opt) => /* @__PURE__ */ jsx10("option", { value: opt.value, children: opt.label }, opt.value))
|
|
2423
2650
|
]
|
|
2424
2651
|
}
|
|
2425
2652
|
),
|
|
2426
|
-
err && /* @__PURE__ */
|
|
2653
|
+
err && /* @__PURE__ */ jsx10("span", { style: errorStyle, children: err })
|
|
2427
2654
|
] }, k);
|
|
2428
2655
|
}
|
|
2429
2656
|
if (field.kind === "consent") {
|
|
2430
|
-
return /* @__PURE__ */
|
|
2657
|
+
return /* @__PURE__ */ jsxs7(
|
|
2431
2658
|
"label",
|
|
2432
2659
|
{
|
|
2433
2660
|
style: {
|
|
@@ -2437,7 +2664,7 @@ function PreChatFormView() {
|
|
|
2437
2664
|
gap: 8
|
|
2438
2665
|
},
|
|
2439
2666
|
children: [
|
|
2440
|
-
/* @__PURE__ */
|
|
2667
|
+
/* @__PURE__ */ jsx10(
|
|
2441
2668
|
"input",
|
|
2442
2669
|
{
|
|
2443
2670
|
type: "checkbox",
|
|
@@ -2446,11 +2673,11 @@ function PreChatFormView() {
|
|
|
2446
2673
|
style: { marginTop: 3 }
|
|
2447
2674
|
}
|
|
2448
2675
|
),
|
|
2449
|
-
/* @__PURE__ */
|
|
2676
|
+
/* @__PURE__ */ jsxs7("span", { style: { fontSize: 13, fontWeight: 400 }, children: [
|
|
2450
2677
|
field.label,
|
|
2451
|
-
field.url && /* @__PURE__ */
|
|
2678
|
+
field.url && /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
2452
2679
|
" ",
|
|
2453
|
-
/* @__PURE__ */
|
|
2680
|
+
/* @__PURE__ */ jsx10(
|
|
2454
2681
|
"a",
|
|
2455
2682
|
{
|
|
2456
2683
|
href: field.url,
|
|
@@ -2462,7 +2689,7 @@ function PreChatFormView() {
|
|
|
2462
2689
|
)
|
|
2463
2690
|
] })
|
|
2464
2691
|
] }),
|
|
2465
|
-
err && /* @__PURE__ */
|
|
2692
|
+
err && /* @__PURE__ */ jsx10("span", { style: errorStyle, children: err })
|
|
2466
2693
|
]
|
|
2467
2694
|
},
|
|
2468
2695
|
k
|
|
@@ -2470,12 +2697,12 @@ function PreChatFormView() {
|
|
|
2470
2697
|
}
|
|
2471
2698
|
const inputType = field.kind === "email" ? "email" : field.kind === "phone" ? "tel" : "text";
|
|
2472
2699
|
const maxLength = field.kind === "text" ? field.maxLength : void 0;
|
|
2473
|
-
return /* @__PURE__ */
|
|
2474
|
-
/* @__PURE__ */
|
|
2700
|
+
return /* @__PURE__ */ jsxs7("label", { style: labelStyle, children: [
|
|
2701
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2475
2702
|
label,
|
|
2476
2703
|
required && " *"
|
|
2477
2704
|
] }),
|
|
2478
|
-
/* @__PURE__ */
|
|
2705
|
+
/* @__PURE__ */ jsx10(
|
|
2479
2706
|
"input",
|
|
2480
2707
|
{
|
|
2481
2708
|
type: inputType,
|
|
@@ -2485,11 +2712,11 @@ function PreChatFormView() {
|
|
|
2485
2712
|
onChange: (e) => setValue(k, e.target.value)
|
|
2486
2713
|
}
|
|
2487
2714
|
),
|
|
2488
|
-
err && /* @__PURE__ */
|
|
2715
|
+
err && /* @__PURE__ */ jsx10("span", { style: errorStyle, children: err })
|
|
2489
2716
|
] }, k);
|
|
2490
2717
|
}),
|
|
2491
|
-
/* @__PURE__ */
|
|
2492
|
-
/* @__PURE__ */
|
|
2718
|
+
/* @__PURE__ */ jsxs7("div", { style: buttonRowStyle, children: [
|
|
2719
|
+
/* @__PURE__ */ jsx10(
|
|
2493
2720
|
"button",
|
|
2494
2721
|
{
|
|
2495
2722
|
type: "button",
|
|
@@ -2499,7 +2726,7 @@ function PreChatFormView() {
|
|
|
2499
2726
|
children: t("action_cancel")
|
|
2500
2727
|
}
|
|
2501
2728
|
),
|
|
2502
|
-
/* @__PURE__ */
|
|
2729
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", style: submitStyle, disabled: submitting, children: preChatForm.submitLabel })
|
|
2503
2730
|
] })
|
|
2504
2731
|
]
|
|
2505
2732
|
}
|
|
@@ -2508,8 +2735,8 @@ function PreChatFormView() {
|
|
|
2508
2735
|
function ChatWindow() {
|
|
2509
2736
|
const { isOpen, config, configError, t, isRtl, preChatFormVisible } = useChat();
|
|
2510
2737
|
const reduced = useReducedMotion();
|
|
2511
|
-
const [visible, setVisible] =
|
|
2512
|
-
const [shouldRender, setShouldRender] =
|
|
2738
|
+
const [visible, setVisible] = useState8(false);
|
|
2739
|
+
const [shouldRender, setShouldRender] = useState8(false);
|
|
2513
2740
|
useEffect7(() => {
|
|
2514
2741
|
if (isOpen) {
|
|
2515
2742
|
setShouldRender(true);
|
|
@@ -2559,17 +2786,18 @@ function ChatWindow() {
|
|
|
2559
2786
|
textDecoration: "underline",
|
|
2560
2787
|
textUnderlineOffset: 2
|
|
2561
2788
|
};
|
|
2562
|
-
return /* @__PURE__ */
|
|
2563
|
-
/* @__PURE__ */
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
/* @__PURE__ */
|
|
2567
|
-
/* @__PURE__ */
|
|
2789
|
+
return /* @__PURE__ */ jsxs7("div", { style, dir: isRtl ? "rtl" : "ltr", children: [
|
|
2790
|
+
/* @__PURE__ */ jsx10(ChatHeader, {}),
|
|
2791
|
+
/* @__PURE__ */ jsx10(IncidentBanner, {}),
|
|
2792
|
+
configError ? /* @__PURE__ */ jsx10(ConfigError, { title: t("unable_to_load"), message: configError }) : preChatFormVisible ? /* @__PURE__ */ jsx10(PreChatFormView, {}) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
2793
|
+
/* @__PURE__ */ jsx10(ChatMessages, {}),
|
|
2794
|
+
/* @__PURE__ */ jsx10(ChatSuggestions, {}),
|
|
2795
|
+
/* @__PURE__ */ jsx10(ChatInput, {})
|
|
2568
2796
|
] }),
|
|
2569
|
-
/* @__PURE__ */
|
|
2797
|
+
/* @__PURE__ */ jsxs7("div", { style: poweredStyle, children: [
|
|
2570
2798
|
t("powered_by"),
|
|
2571
2799
|
" ",
|
|
2572
|
-
/* @__PURE__ */
|
|
2800
|
+
/* @__PURE__ */ jsx10(
|
|
2573
2801
|
"a",
|
|
2574
2802
|
{
|
|
2575
2803
|
href: "https://customerhero.app",
|
|
@@ -2584,7 +2812,7 @@ function ChatWindow() {
|
|
|
2584
2812
|
}
|
|
2585
2813
|
|
|
2586
2814
|
// src/components/chat-widget.tsx
|
|
2587
|
-
import { Fragment as Fragment6, jsx as
|
|
2815
|
+
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2588
2816
|
function ChatWidgetInner({ identity }) {
|
|
2589
2817
|
const client = useCustomerHeroClient();
|
|
2590
2818
|
const { configLoaded, configError } = useChat();
|
|
@@ -2599,13 +2827,13 @@ function ChatWidgetInner({ identity }) {
|
|
|
2599
2827
|
}
|
|
2600
2828
|
}, [identity, client]);
|
|
2601
2829
|
if (!configLoaded || configError) return null;
|
|
2602
|
-
return /* @__PURE__ */
|
|
2603
|
-
/* @__PURE__ */
|
|
2604
|
-
/* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
2831
|
+
/* @__PURE__ */ jsx11(ChatBubble, {}),
|
|
2832
|
+
/* @__PURE__ */ jsx11(ChatWindow, {})
|
|
2605
2833
|
] });
|
|
2606
2834
|
}
|
|
2607
2835
|
function ChatWidget({ identity, ...config }) {
|
|
2608
|
-
return /* @__PURE__ */
|
|
2836
|
+
return /* @__PURE__ */ jsx11(CustomerHeroProvider, { ...config, children: /* @__PURE__ */ jsx11(ChatWidgetInner, { identity }) });
|
|
2609
2837
|
}
|
|
2610
2838
|
export {
|
|
2611
2839
|
ActionConfirmationCard,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@customerhero/react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "React components for embedding the CustomerHero chat widget.",
|
|
6
6
|
"keywords": [
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"react": ">=18"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@customerhero/js": "^2.
|
|
61
|
+
"@customerhero/js": "^2.2.0",
|
|
62
62
|
"@testing-library/react": "^16.1.0",
|
|
63
63
|
"@types/react": "^19.0.0",
|
|
64
64
|
"@types/react-dom": "^19.0.0",
|