@burdenoff/website-sdk 2026.924.9 → 2026.924.11
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/components/explore.js +119 -22
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +119 -22
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +56 -7
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +56 -7
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +119 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -22
- package/dist/index.mjs.map +1 -1
- package/dist/{use-progressive-reveal-Cmy8bA7L.d.mts → use-progressive-reveal-BBLRAnbU.d.mts} +6 -1
- package/dist/{use-progressive-reveal-DHPGGxZu.d.ts → use-progressive-reveal-myNKWb6S.d.ts} +6 -1
- package/package.json +1 -1
|
@@ -2059,6 +2059,45 @@ function buildFallbackCatalog(examplePrompts, welcome) {
|
|
|
2059
2059
|
conceptHighlights: []
|
|
2060
2060
|
};
|
|
2061
2061
|
}
|
|
2062
|
+
var BAKED_CATALOG_ELEMENT_ID = "boff-explore-catalog";
|
|
2063
|
+
function bakedCatalogLocale() {
|
|
2064
|
+
if (typeof navigator === "undefined") return "";
|
|
2065
|
+
return (navigator.language || "").toLowerCase().split("-")[0] ?? "";
|
|
2066
|
+
}
|
|
2067
|
+
function snapshotBakedElement() {
|
|
2068
|
+
if (typeof document === "undefined") return null;
|
|
2069
|
+
const el = document.getElementById(BAKED_CATALOG_ELEMENT_ID);
|
|
2070
|
+
if (!el || el.tagName !== "SCRIPT" || el.getAttribute("type") !== "application/json")
|
|
2071
|
+
return null;
|
|
2072
|
+
return {
|
|
2073
|
+
product: el.getAttribute("data-product") ?? "",
|
|
2074
|
+
locale: el.getAttribute("data-locale") ?? "",
|
|
2075
|
+
text: el.textContent ?? ""
|
|
2076
|
+
};
|
|
2077
|
+
}
|
|
2078
|
+
var BAKED_AT_LOAD = snapshotBakedElement();
|
|
2079
|
+
function isCatalogShape(value) {
|
|
2080
|
+
if (!value || typeof value !== "object") return false;
|
|
2081
|
+
const c = value;
|
|
2082
|
+
const listOrAbsent = (v) => v === void 0 || v === null || Array.isArray(v);
|
|
2083
|
+
const textOrAbsent = (v) => v === void 0 || v === null || typeof v === "string";
|
|
2084
|
+
return (c["enabled"] === void 0 || typeof c["enabled"] === "boolean") && listOrAbsent(c["products"]) && listOrAbsent(c["examplePrompts"]) && listOrAbsent(c["conceptHighlights"]) && textOrAbsent(c["welcomeTitle"]) && textOrAbsent(c["welcomeBody"]);
|
|
2085
|
+
}
|
|
2086
|
+
function readBakedCatalog(productSlug) {
|
|
2087
|
+
const baked = snapshotBakedElement() ?? BAKED_AT_LOAD;
|
|
2088
|
+
if (!baked) return null;
|
|
2089
|
+
if (baked.product !== (productSlug ?? "")) return null;
|
|
2090
|
+
if (baked.locale && baked.locale !== bakedCatalogLocale()) return null;
|
|
2091
|
+
try {
|
|
2092
|
+
const parsed = JSON.parse(baked.text);
|
|
2093
|
+
return isCatalogShape(parsed) ? parsed : null;
|
|
2094
|
+
} catch {
|
|
2095
|
+
return null;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
function serializeBakedCatalog(raw) {
|
|
2099
|
+
return JSON.stringify(raw).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
2100
|
+
}
|
|
2062
2101
|
function normalizeCatalog(raw, fallback) {
|
|
2063
2102
|
return {
|
|
2064
2103
|
enabled: raw.enabled !== false,
|
|
@@ -2308,9 +2347,17 @@ function useExploreChat(options = {}) {
|
|
|
2308
2347
|
),
|
|
2309
2348
|
[promptKey, welcomeKey]
|
|
2310
2349
|
);
|
|
2311
|
-
const [
|
|
2350
|
+
const [bakedRaw] = React.useState(
|
|
2351
|
+
() => readBakedCatalog(productSlug)
|
|
2352
|
+
);
|
|
2353
|
+
const [catalog, setCatalog] = React.useState(
|
|
2354
|
+
() => bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
2355
|
+
);
|
|
2356
|
+
const [serverCatalogRaw, setServerCatalogRaw] = React.useState(bakedRaw);
|
|
2312
2357
|
const [messages, setMessages] = React.useState([]);
|
|
2313
|
-
const [phase, setPhase] = React.useState(
|
|
2358
|
+
const [phase, setPhase] = React.useState(
|
|
2359
|
+
() => bakedRaw ? bakedRaw.enabled === false ? "disabled" : "ready" : "loading"
|
|
2360
|
+
);
|
|
2314
2361
|
const [error, setError] = React.useState(null);
|
|
2315
2362
|
const [remainingToday, setRemainingToday] = React.useState(null);
|
|
2316
2363
|
const [focusProduct, setFocusProductState] = React.useState(null);
|
|
@@ -2328,7 +2375,7 @@ function useExploreChat(options = {}) {
|
|
|
2328
2375
|
shareTokenRef.current = readShareToken();
|
|
2329
2376
|
}
|
|
2330
2377
|
const isSharedView = shareTokenRef.current !== null;
|
|
2331
|
-
const catalogRef = React.useRef(
|
|
2378
|
+
const catalogRef = React.useRef(catalog);
|
|
2332
2379
|
const turnCountRef = React.useRef(0);
|
|
2333
2380
|
const focusProductRef = React.useRef(null);
|
|
2334
2381
|
const lastSentTextRef = React.useRef(null);
|
|
@@ -2474,25 +2521,29 @@ function useExploreChat(options = {}) {
|
|
|
2474
2521
|
const raw = res.data?.exploreCatalog;
|
|
2475
2522
|
if (res.errors?.length || !raw) {
|
|
2476
2523
|
console.warn(
|
|
2477
|
-
"[WebSDK] exploreCatalog unavailable \u2014
|
|
2524
|
+
"[WebSDK] exploreCatalog unavailable \u2014 keeping the catalog the page started with",
|
|
2478
2525
|
res.errors?.[0]?.message
|
|
2479
2526
|
);
|
|
2480
2527
|
setPhase((prev) => prev === "loading" ? "ready" : prev);
|
|
2481
2528
|
return;
|
|
2482
2529
|
}
|
|
2483
|
-
const next = normalizeCatalog(
|
|
2530
|
+
const next = normalizeCatalog(
|
|
2531
|
+
raw,
|
|
2532
|
+
bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
2533
|
+
);
|
|
2484
2534
|
setCatalog(next);
|
|
2535
|
+
setServerCatalogRaw(raw);
|
|
2485
2536
|
catalogRef.current = next;
|
|
2486
2537
|
setPhase((prev) => {
|
|
2487
2538
|
if (!next.enabled) return "disabled";
|
|
2488
|
-
return prev === "loading" ? "ready" : prev;
|
|
2539
|
+
return prev === "loading" || prev === "disabled" ? "ready" : prev;
|
|
2489
2540
|
});
|
|
2490
2541
|
};
|
|
2491
2542
|
void load();
|
|
2492
2543
|
return () => {
|
|
2493
2544
|
cancelled = true;
|
|
2494
2545
|
};
|
|
2495
|
-
}, [client, productSlug, fallbackCatalog]);
|
|
2546
|
+
}, [client, productSlug, fallbackCatalog, bakedRaw]);
|
|
2496
2547
|
const startPolling = React.useCallback(
|
|
2497
2548
|
(conversationToken, messageId) => {
|
|
2498
2549
|
pollGenerationRef.current += 1;
|
|
@@ -2960,6 +3011,7 @@ function useExploreChat(options = {}) {
|
|
|
2960
3011
|
return {
|
|
2961
3012
|
phase,
|
|
2962
3013
|
catalog,
|
|
3014
|
+
serverCatalogRaw,
|
|
2963
3015
|
messages,
|
|
2964
3016
|
activity,
|
|
2965
3017
|
remainingToday,
|
|
@@ -3918,6 +3970,30 @@ var EXPLORE_CSS = `
|
|
|
3918
3970
|
}
|
|
3919
3971
|
.boff-explore-strip::-webkit-scrollbar { display: none; }
|
|
3920
3972
|
|
|
3973
|
+
/* The product chips run past the edge of their row (there are 38). A hard edge sliced the
|
|
3974
|
+
last visible chip mid-word ("Bi", "BigC") right beside "All 38"; a short fade says "there
|
|
3975
|
+
is more this way" instead. A mask carries only alpha, so the gradient's colour is a token
|
|
3976
|
+
that never shows. Mirrored for right-to-left locales, whose row runs the other way. */
|
|
3977
|
+
.boff-explore-chips-fade {
|
|
3978
|
+
/* Focus scrolling honours scroll-padding, so a tabbed-to chip is brought clear of the fade
|
|
3979
|
+
rather than left half-hidden under it. */
|
|
3980
|
+
scroll-padding-inline-end: 2rem;
|
|
3981
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3982
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3983
|
+
}
|
|
3984
|
+
/* A fade over a fixed edge would leave the LAST chip under it once the row is scrolled to
|
|
3985
|
+
the end \u2014 the visitor could never read it. A trailing spacer the width of the fade lets
|
|
3986
|
+
the final chip scroll clear of it. A pseudo-element rather than padding: trailing padding
|
|
3987
|
+
on a flex scroll container is not reliably part of its scrollable overflow. */
|
|
3988
|
+
.boff-explore-chips-fade::after {
|
|
3989
|
+
content: "";
|
|
3990
|
+
flex: 0 0 2rem;
|
|
3991
|
+
}
|
|
3992
|
+
[dir="rtl"] .boff-explore-chips-fade {
|
|
3993
|
+
-webkit-mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3994
|
+
mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3921
3997
|
@keyframes boff-explore-fade-in {
|
|
3922
3998
|
from { opacity: 0; transform: translateY(2px); }
|
|
3923
3999
|
to { opacity: 1; transform: none; }
|
|
@@ -3994,10 +4070,10 @@ var EXPLORE_CSS = `
|
|
|
3994
4070
|
Colour comes from the product's --primary token, so it is whatever that site's palette
|
|
3995
4071
|
already is, never a colour chosen here. */
|
|
3996
4072
|
.boff-explore-invite {
|
|
3997
|
-
border-color: hsl(var(--primary) / 0.
|
|
4073
|
+
border-color: hsl(var(--primary) / 0.6);
|
|
3998
4074
|
box-shadow:
|
|
3999
|
-
0 0 0 4px hsl(var(--primary) / 0.
|
|
4000
|
-
0 8px 24px -12px hsl(var(--primary) / 0.
|
|
4075
|
+
0 0 0 4px hsl(var(--primary) / 0.12),
|
|
4076
|
+
0 8px 24px -12px hsl(var(--primary) / 0.55);
|
|
4001
4077
|
animation: boff-explore-breathe 3.2s ease-in-out infinite;
|
|
4002
4078
|
}
|
|
4003
4079
|
/* Focus and typing both mean "I have found it", and the hint has done its job. */
|
|
@@ -4007,8 +4083,8 @@ var EXPLORE_CSS = `
|
|
|
4007
4083
|
box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10);
|
|
4008
4084
|
}
|
|
4009
4085
|
@keyframes boff-explore-breathe {
|
|
4010
|
-
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.
|
|
4011
|
-
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.
|
|
4086
|
+
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10), 0 8px 24px -12px hsl(var(--primary) / 0.50); }
|
|
4087
|
+
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.18), 0 8px 28px -12px hsl(var(--primary) / 0.65); }
|
|
4012
4088
|
}
|
|
4013
4089
|
|
|
4014
4090
|
/* Every one of the above is decoration. Reduced motion removes the movement and keeps the
|
|
@@ -5317,14 +5393,20 @@ function PromptCarousel({
|
|
|
5317
5393
|
"aria-label": `Ask: ${current}`,
|
|
5318
5394
|
"aria-live": paused ? "polite" : "off",
|
|
5319
5395
|
onClick: () => onPrompt(current),
|
|
5320
|
-
className: "
|
|
5396
|
+
className: "group flex min-w-0 flex-1 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 max-sm:min-h-[3.625rem] max-sm:rounded-2xl text-left text-sm text-card-foreground shadow-sm transition-colors hover:border-primary/50 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
5321
5397
|
children: [
|
|
5322
5398
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
5323
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5399
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5400
|
+
"span",
|
|
5401
|
+
{
|
|
5402
|
+
className: "boff-explore-fade min-w-0 max-sm:line-clamp-2 sm:truncate",
|
|
5403
|
+
children: current
|
|
5404
|
+
},
|
|
5405
|
+
current
|
|
5406
|
+
),
|
|
5324
5407
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
5325
5408
|
]
|
|
5326
|
-
}
|
|
5327
|
-
current
|
|
5409
|
+
}
|
|
5328
5410
|
),
|
|
5329
5411
|
count > 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5330
5412
|
"button",
|
|
@@ -5363,7 +5445,7 @@ function ProductStrip({
|
|
|
5363
5445
|
{
|
|
5364
5446
|
className: cn(
|
|
5365
5447
|
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
5366
|
-
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
5448
|
+
expanded ? "flex-wrap" : "boff-explore-chips-fade flex-nowrap overflow-x-auto"
|
|
5367
5449
|
),
|
|
5368
5450
|
children: [
|
|
5369
5451
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5501,11 +5583,11 @@ function ConceptStrip({
|
|
|
5501
5583
|
onScroll: measureRail,
|
|
5502
5584
|
"data-boff-explore": "concept-strip",
|
|
5503
5585
|
"aria-label": T.conceptStripLabel,
|
|
5504
|
-
className: "boff-explore-strip flex min-w-0 snap-x gap-3 overflow-x-auto pb-1",
|
|
5586
|
+
className: "boff-explore-strip flex min-w-0 snap-x gap-3 overflow-x-auto pb-1 sm:mx-10",
|
|
5505
5587
|
children: visible.map((highlight) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5506
5588
|
"li",
|
|
5507
5589
|
{
|
|
5508
|
-
className: "shrink-0 snap-start",
|
|
5590
|
+
className: "flex shrink-0 snap-start",
|
|
5509
5591
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5510
5592
|
"button",
|
|
5511
5593
|
{
|
|
@@ -5546,9 +5628,9 @@ function ConceptStrip({
|
|
|
5546
5628
|
}
|
|
5547
5629
|
)
|
|
5548
5630
|
] }),
|
|
5549
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col gap-0.5 p-2.5", children: [
|
|
5631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5 p-2.5", children: [
|
|
5550
5632
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-xs font-semibold leading-snug text-card-foreground", children: highlight.title }),
|
|
5551
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
5633
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-auto truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
5552
5634
|
] })
|
|
5553
5635
|
]
|
|
5554
5636
|
}
|
|
@@ -5765,6 +5847,7 @@ function ExplorePage({
|
|
|
5765
5847
|
const {
|
|
5766
5848
|
phase,
|
|
5767
5849
|
catalog,
|
|
5850
|
+
serverCatalogRaw,
|
|
5768
5851
|
messages,
|
|
5769
5852
|
activity,
|
|
5770
5853
|
remainingToday,
|
|
@@ -6196,6 +6279,10 @@ function ExplorePage({
|
|
|
6196
6279
|
const captchaOn = Boolean(
|
|
6197
6280
|
catalog.captchaRequired && catalog.recaptchaSiteKey
|
|
6198
6281
|
);
|
|
6282
|
+
const bakedCatalogJson = React.useMemo(
|
|
6283
|
+
() => serverCatalogRaw && serverCatalogRaw.enabled !== false ? serializeBakedCatalog(serverCatalogRaw) : null,
|
|
6284
|
+
[serverCatalogRaw]
|
|
6285
|
+
);
|
|
6199
6286
|
const rootStyle = {};
|
|
6200
6287
|
if (heightMode === "viewport") {
|
|
6201
6288
|
rootStyle["--boff-explore-offset"] = paneOffset === null ? normalizeOffset(viewportOffset) : `${paneOffset}px`;
|
|
@@ -6235,6 +6322,16 @@ function ExplorePage({
|
|
|
6235
6322
|
),
|
|
6236
6323
|
/* @__PURE__ */ jsxRuntime.jsx(ProseStyles, {}),
|
|
6237
6324
|
/* @__PURE__ */ jsxRuntime.jsx(ExploreStyles, {}),
|
|
6325
|
+
bakedCatalogJson ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6326
|
+
"script",
|
|
6327
|
+
{
|
|
6328
|
+
id: BAKED_CATALOG_ELEMENT_ID,
|
|
6329
|
+
type: "application/json",
|
|
6330
|
+
"data-product": productSlug ?? "",
|
|
6331
|
+
"data-locale": bakedCatalogLocale(),
|
|
6332
|
+
dangerouslySetInnerHTML: { __html: bakedCatalogJson }
|
|
6333
|
+
}
|
|
6334
|
+
) : null,
|
|
6238
6335
|
/* @__PURE__ */ jsxRuntime.jsx(ExploreAnswerStyles, {}),
|
|
6239
6336
|
!showWelcome ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-2.5", children: [
|
|
6240
6337
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6709,7 +6806,7 @@ function ExplorePage({
|
|
|
6709
6806
|
)
|
|
6710
6807
|
] }) : null,
|
|
6711
6808
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
6712
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: T.disclaimerShort }),
|
|
6809
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 sm:truncate", children: T.disclaimerShort }),
|
|
6713
6810
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6714
6811
|
"button",
|
|
6715
6812
|
{
|