@burdenoff/website-sdk 2026.829.1 → 2026.829.3
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 +281 -66
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +282 -67
- 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 +50 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +50 -1
- 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 +281 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +282 -67
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-DhvZhH8f.d.mts → use-explore-chat-B-E7jN1H.d.mts} +21 -2
- package/dist/{use-explore-chat-DhvZhH8f.d.ts → use-explore-chat-B-E7jN1H.d.ts} +21 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -18,7 +18,7 @@ export { ProblemSolved, ProblemsSolvedSection, ProblemsSolvedSectionProps } from
|
|
|
18
18
|
export { DetectedPlatform, ElectronDownloadLink, ElectronDownloadLinkProps, detectElectronPlatform } from './components/electron-download.mjs';
|
|
19
19
|
export { ExplorePage, ExplorePageProps } from './components/explore.mjs';
|
|
20
20
|
export { ExploreCta, ExploreCtaProps } from './components/explore-cta.mjs';
|
|
21
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, e as EXPLORE_CATALOG_QUERY, f as EXPLORE_MESSAGE_QUERY, g as ExploreCatalog, h as ExploreCatalogQueryData, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, i as ExploreConversation, j as ExploreCtaKind, k as ExploreCtaLink, l as ExploreErrorCode, m as ExploreLimits, n as ExploreMessage, o as ExploreMessageQueryData, p as ExploreMessageRole, q as ExploreMessageStatus, r as ExploreProduct, s as ExploreReference, F as FALLBACK_EXPLORE_LIMITS, S as SEND_EXPLORE_MESSAGE_MUTATION, t as SendExploreMessageInput, v as SendExploreMessageMutationData, w as SendExploreMessageResult, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from './use-explore-chat-
|
|
21
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, e as EXPLORE_CATALOG_QUERY, f as EXPLORE_MESSAGE_QUERY, g as ExploreCatalog, h as ExploreCatalogQueryData, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, i as ExploreConversation, j as ExploreCtaKind, k as ExploreCtaLink, l as ExploreErrorCode, m as ExploreLimits, n as ExploreMessage, o as ExploreMessageQueryData, p as ExploreMessageRole, q as ExploreMessageStatus, r as ExploreProduct, s as ExploreReference, F as FALLBACK_EXPLORE_LIMITS, S as SEND_EXPLORE_MESSAGE_MUTATION, t as SendExploreMessageInput, v as SendExploreMessageMutationData, w as SendExploreMessageResult, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from './use-explore-chat-B-E7jN1H.mjs';
|
|
22
22
|
export { RybbitAnalytics, RybbitAnalyticsProps } from './analytics/index.mjs';
|
|
23
23
|
export { PageHead, PageHeadProps } from './seo/index.mjs';
|
|
24
24
|
export { ProductData, ProductProvider, ProductProviderProps, useProduct, useProductConfig } from './product/index.mjs';
|
|
@@ -62,7 +62,7 @@ declare function CareersSubmissionForm({ productName, recaptchaSiteKey, postings
|
|
|
62
62
|
|
|
63
63
|
declare const buttonVariants: (props?: ({
|
|
64
64
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
65
|
-
size?: "
|
|
65
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
66
66
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
67
67
|
interface ButtonProps extends react.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
68
68
|
asChild?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export { ProblemSolved, ProblemsSolvedSection, ProblemsSolvedSectionProps } from
|
|
|
18
18
|
export { DetectedPlatform, ElectronDownloadLink, ElectronDownloadLinkProps, detectElectronPlatform } from './components/electron-download.js';
|
|
19
19
|
export { ExplorePage, ExplorePageProps } from './components/explore.js';
|
|
20
20
|
export { ExploreCta, ExploreCtaProps } from './components/explore-cta.js';
|
|
21
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, e as EXPLORE_CATALOG_QUERY, f as EXPLORE_MESSAGE_QUERY, g as ExploreCatalog, h as ExploreCatalogQueryData, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, i as ExploreConversation, j as ExploreCtaKind, k as ExploreCtaLink, l as ExploreErrorCode, m as ExploreLimits, n as ExploreMessage, o as ExploreMessageQueryData, p as ExploreMessageRole, q as ExploreMessageStatus, r as ExploreProduct, s as ExploreReference, F as FALLBACK_EXPLORE_LIMITS, S as SEND_EXPLORE_MESSAGE_MUTATION, t as SendExploreMessageInput, v as SendExploreMessageMutationData, w as SendExploreMessageResult, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from './use-explore-chat-
|
|
21
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, e as EXPLORE_CATALOG_QUERY, f as EXPLORE_MESSAGE_QUERY, g as ExploreCatalog, h as ExploreCatalogQueryData, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, i as ExploreConversation, j as ExploreCtaKind, k as ExploreCtaLink, l as ExploreErrorCode, m as ExploreLimits, n as ExploreMessage, o as ExploreMessageQueryData, p as ExploreMessageRole, q as ExploreMessageStatus, r as ExploreProduct, s as ExploreReference, F as FALLBACK_EXPLORE_LIMITS, S as SEND_EXPLORE_MESSAGE_MUTATION, t as SendExploreMessageInput, v as SendExploreMessageMutationData, w as SendExploreMessageResult, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from './use-explore-chat-B-E7jN1H.js';
|
|
22
22
|
export { RybbitAnalytics, RybbitAnalyticsProps } from './analytics/index.js';
|
|
23
23
|
export { PageHead, PageHeadProps } from './seo/index.js';
|
|
24
24
|
export { ProductData, ProductProvider, ProductProviderProps, useProduct, useProductConfig } from './product/index.js';
|
|
@@ -62,7 +62,7 @@ declare function CareersSubmissionForm({ productName, recaptchaSiteKey, postings
|
|
|
62
62
|
|
|
63
63
|
declare const buttonVariants: (props?: ({
|
|
64
64
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
65
|
-
size?: "
|
|
65
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
66
66
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
67
67
|
interface ButtonProps extends react.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
68
68
|
asChild?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -4959,6 +4959,7 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
4959
4959
|
description
|
|
4960
4960
|
product
|
|
4961
4961
|
imageUrl
|
|
4962
|
+
index
|
|
4962
4963
|
}
|
|
4963
4964
|
ctas {
|
|
4964
4965
|
kind
|
|
@@ -4966,6 +4967,8 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
4966
4967
|
url
|
|
4967
4968
|
product
|
|
4968
4969
|
}
|
|
4970
|
+
followUps
|
|
4971
|
+
answered
|
|
4969
4972
|
errorCode
|
|
4970
4973
|
createdAt
|
|
4971
4974
|
completedAt
|
|
@@ -5031,6 +5034,26 @@ var SEND_EXPLORE_MESSAGE_MUTATION = (
|
|
|
5031
5034
|
}
|
|
5032
5035
|
`
|
|
5033
5036
|
);
|
|
5037
|
+
var RECORD_EXPLORE_CLICK_MUTATION = (
|
|
5038
|
+
/* GraphQL */
|
|
5039
|
+
`
|
|
5040
|
+
mutation RecordExploreClick($input: RecordExploreClickInput!) {
|
|
5041
|
+
recordExploreClick(input: $input) {
|
|
5042
|
+
recorded
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
`
|
|
5046
|
+
);
|
|
5047
|
+
var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
|
|
5048
|
+
/* GraphQL */
|
|
5049
|
+
`
|
|
5050
|
+
mutation CreateExploreShareLink($conversationToken: String!) {
|
|
5051
|
+
createExploreShareLink(conversationToken: $conversationToken) {
|
|
5052
|
+
shareToken
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
5055
|
+
`
|
|
5056
|
+
);
|
|
5034
5057
|
|
|
5035
5058
|
// src/data/products.ts
|
|
5036
5059
|
var ECOSYSTEM_PRODUCTS = [
|
|
@@ -5963,6 +5986,30 @@ function useExploreChat(options = {}) {
|
|
|
5963
5986
|
return null;
|
|
5964
5987
|
}, [messages]);
|
|
5965
5988
|
const canSend = (phase === "ready" || phase === "error") && catalog.enabled && turnCount < catalog.limits.maxTurnsPerConversation;
|
|
5989
|
+
const createShareLink = React.useCallback(async () => {
|
|
5990
|
+
const token = conversationTokenRef.current;
|
|
5991
|
+
if (!token) return null;
|
|
5992
|
+
try {
|
|
5993
|
+
const result = await client.mutate(CREATE_EXPLORE_SHARE_LINK_MUTATION, { conversationToken: token });
|
|
5994
|
+
return result?.data?.createExploreShareLink?.shareToken ?? null;
|
|
5995
|
+
} catch {
|
|
5996
|
+
return null;
|
|
5997
|
+
}
|
|
5998
|
+
}, [client]);
|
|
5999
|
+
const recordClick = React.useCallback(
|
|
6000
|
+
(messageId, kind, url) => {
|
|
6001
|
+
const token = conversationTokenRef.current;
|
|
6002
|
+
if (!token) return;
|
|
6003
|
+
try {
|
|
6004
|
+
void client.mutate(RECORD_EXPLORE_CLICK_MUTATION, {
|
|
6005
|
+
input: { conversationToken: token, messageId, kind, url }
|
|
6006
|
+
}).catch(() => {
|
|
6007
|
+
});
|
|
6008
|
+
} catch {
|
|
6009
|
+
}
|
|
6010
|
+
},
|
|
6011
|
+
[client]
|
|
6012
|
+
);
|
|
5966
6013
|
return {
|
|
5967
6014
|
phase,
|
|
5968
6015
|
catalog,
|
|
@@ -5980,7 +6027,9 @@ function useExploreChat(options = {}) {
|
|
|
5980
6027
|
history: archive,
|
|
5981
6028
|
openConversation,
|
|
5982
6029
|
deleteConversation,
|
|
5983
|
-
clearHistory
|
|
6030
|
+
clearHistory,
|
|
6031
|
+
recordClick,
|
|
6032
|
+
createShareLink
|
|
5984
6033
|
};
|
|
5985
6034
|
}
|
|
5986
6035
|
var optimisticCounter = 0;
|
|
@@ -6352,7 +6401,10 @@ function logoUrlOf(url) {
|
|
|
6352
6401
|
return null;
|
|
6353
6402
|
}
|
|
6354
6403
|
}
|
|
6355
|
-
function ReferenceCard({
|
|
6404
|
+
function ReferenceCard({
|
|
6405
|
+
reference,
|
|
6406
|
+
onFollow
|
|
6407
|
+
}) {
|
|
6356
6408
|
const [imageFailed, setImageFailed] = React.useState(false);
|
|
6357
6409
|
const [logoFailed, setLogoFailed] = React.useState(false);
|
|
6358
6410
|
const host = hostnameOf(reference.url);
|
|
@@ -6374,9 +6426,11 @@ function ReferenceCard({ reference }) {
|
|
|
6374
6426
|
"a",
|
|
6375
6427
|
{
|
|
6376
6428
|
"data-boff-explore": "reference",
|
|
6429
|
+
"data-index": reference.index ?? void 0,
|
|
6377
6430
|
href: reference.url,
|
|
6378
6431
|
target: "_blank",
|
|
6379
6432
|
rel: "noopener noreferrer",
|
|
6433
|
+
onClick: () => onFollow?.(reference.url),
|
|
6380
6434
|
className: "group flex flex-row items-center gap-3 overflow-hidden rounded-xl border border-border bg-card p-2 transition-colors hover:border-primary/40 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:flex-col sm:items-stretch sm:gap-0 sm:p-0",
|
|
6381
6435
|
children: [
|
|
6382
6436
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-11 w-11 shrink-0 overflow-hidden rounded-lg bg-muted sm:hidden", children: logoImg }),
|
|
@@ -6400,7 +6454,10 @@ function ReferenceCard({ reference }) {
|
|
|
6400
6454
|
}
|
|
6401
6455
|
) }) : letterPlate }),
|
|
6402
6456
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 sm:gap-1.5 sm:p-3", children: [
|
|
6403
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6457
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "line-clamp-2 text-sm font-semibold leading-snug text-card-foreground", children: [
|
|
6458
|
+
reference.index ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1.5 inline-flex h-4 min-w-4 items-center justify-center rounded bg-primary/10 px-1 text-[10px] font-bold text-primary", children: reference.index }) : null,
|
|
6459
|
+
reference.title || host || reference.url
|
|
6460
|
+
] }),
|
|
6404
6461
|
reference.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-2 text-xs leading-relaxed text-muted-foreground max-sm:hidden", children: reference.description }) : null,
|
|
6405
6462
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:mt-auto sm:pt-2", children: [
|
|
6406
6463
|
reference.product ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground max-sm:hidden", children: reference.product }) : null,
|
|
@@ -6416,7 +6473,8 @@ function ReferenceCard({ reference }) {
|
|
|
6416
6473
|
}
|
|
6417
6474
|
function CtaButton({
|
|
6418
6475
|
cta,
|
|
6419
|
-
onNavigate
|
|
6476
|
+
onNavigate,
|
|
6477
|
+
onFollow
|
|
6420
6478
|
}) {
|
|
6421
6479
|
const variant = CTA_VARIANTS[cta.kind] ?? "outline";
|
|
6422
6480
|
const internal = isInternalPath(cta.url);
|
|
@@ -6429,7 +6487,10 @@ function CtaButton({
|
|
|
6429
6487
|
type: "button",
|
|
6430
6488
|
size: "sm",
|
|
6431
6489
|
variant,
|
|
6432
|
-
onClick: () =>
|
|
6490
|
+
onClick: () => {
|
|
6491
|
+
onFollow?.(cta.url);
|
|
6492
|
+
onNavigate(cta.url);
|
|
6493
|
+
},
|
|
6433
6494
|
children: cta.label
|
|
6434
6495
|
}
|
|
6435
6496
|
);
|
|
@@ -6440,6 +6501,7 @@ function CtaButton({
|
|
|
6440
6501
|
"data-boff-explore": "cta",
|
|
6441
6502
|
"data-kind": cta.kind,
|
|
6442
6503
|
href: cta.url,
|
|
6504
|
+
onClick: () => onFollow?.(cta.url),
|
|
6443
6505
|
...internal ? {} : { target: "_blank", rel: "noopener noreferrer" },
|
|
6444
6506
|
children: [
|
|
6445
6507
|
cta.label,
|
|
@@ -6491,7 +6553,9 @@ function AssistantBubble({
|
|
|
6491
6553
|
message,
|
|
6492
6554
|
activity,
|
|
6493
6555
|
onNavigate,
|
|
6494
|
-
anchorRef
|
|
6556
|
+
anchorRef,
|
|
6557
|
+
onFollow,
|
|
6558
|
+
onFollowUp
|
|
6495
6559
|
}) {
|
|
6496
6560
|
const streaming = message.status === "PENDING" || message.status === "RUNNING";
|
|
6497
6561
|
const body = message.content || message.partialContent || "";
|
|
@@ -6513,6 +6577,34 @@ function AssistantBubble({
|
|
|
6513
6577
|
}
|
|
6514
6578
|
),
|
|
6515
6579
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [
|
|
6580
|
+
message.status === "COMPLETED" && message.answered === false ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6581
|
+
"div",
|
|
6582
|
+
{
|
|
6583
|
+
"data-boff-explore": "no-answer",
|
|
6584
|
+
className: "flex items-start gap-2 rounded-xl border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-foreground",
|
|
6585
|
+
children: [
|
|
6586
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.TriangleAlert, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-amber-600 dark:text-amber-400" }),
|
|
6587
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6588
|
+
"I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
|
|
6589
|
+
" ",
|
|
6590
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6591
|
+
"a",
|
|
6592
|
+
{
|
|
6593
|
+
href: "/contact",
|
|
6594
|
+
className: "underline underline-offset-2 hover:text-primary",
|
|
6595
|
+
onClick: (event) => {
|
|
6596
|
+
if (!onNavigate) return;
|
|
6597
|
+
event.preventDefault();
|
|
6598
|
+
onNavigate("/contact");
|
|
6599
|
+
},
|
|
6600
|
+
children: "ask a human"
|
|
6601
|
+
}
|
|
6602
|
+
),
|
|
6603
|
+
"."
|
|
6604
|
+
] })
|
|
6605
|
+
]
|
|
6606
|
+
}
|
|
6607
|
+
) : null,
|
|
6516
6608
|
body ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm", children: [
|
|
6517
6609
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: body }) }),
|
|
6518
6610
|
streaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "boff-explore-caret", "aria-hidden": "true" }) : null
|
|
@@ -6521,16 +6613,41 @@ function AssistantBubble({
|
|
|
6521
6613
|
failed && !body ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-2xl rounded-tl-md border border-border bg-muted px-4 py-3 text-sm text-muted-foreground", children: "That answer didn't come through. Try asking again." }) : null,
|
|
6522
6614
|
message.references.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
6523
6615
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Sources" }),
|
|
6524
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: message.references.map((reference) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6616
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: message.references.map((reference) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6617
|
+
ReferenceCard,
|
|
6618
|
+
{
|
|
6619
|
+
reference,
|
|
6620
|
+
onFollow: (url) => onFollow?.("REFERENCE", url)
|
|
6621
|
+
},
|
|
6622
|
+
reference.url
|
|
6623
|
+
)) })
|
|
6525
6624
|
] }) : null,
|
|
6526
6625
|
message.ctas.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 pt-0.5", children: message.ctas.map((cta) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6527
6626
|
CtaButton,
|
|
6528
6627
|
{
|
|
6529
6628
|
cta,
|
|
6530
|
-
onNavigate
|
|
6629
|
+
onNavigate,
|
|
6630
|
+
onFollow: (url) => onFollow?.("CTA", url)
|
|
6531
6631
|
},
|
|
6532
6632
|
`${cta.kind}-${cta.url}`
|
|
6533
|
-
)) }) : null
|
|
6633
|
+
)) }) : null,
|
|
6634
|
+
message.status === "COMPLETED" && (message.followUps?.length ?? 0) > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5 pt-0.5", children: [
|
|
6635
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground", children: "Next you could ask" }),
|
|
6636
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5", children: (message.followUps ?? []).map((question) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6637
|
+
"button",
|
|
6638
|
+
{
|
|
6639
|
+
"data-boff-explore": "follow-up",
|
|
6640
|
+
type: "button",
|
|
6641
|
+
onClick: () => onFollowUp?.(question),
|
|
6642
|
+
className: "group inline-flex max-w-full items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1 text-left text-xs text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6643
|
+
children: [
|
|
6644
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: question }),
|
|
6645
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6646
|
+
]
|
|
6647
|
+
},
|
|
6648
|
+
question
|
|
6649
|
+
)) })
|
|
6650
|
+
] }) : null
|
|
6534
6651
|
] })
|
|
6535
6652
|
]
|
|
6536
6653
|
}
|
|
@@ -6604,6 +6721,9 @@ function PromptCarousel({
|
|
|
6604
6721
|
"div",
|
|
6605
6722
|
{
|
|
6606
6723
|
className: "flex min-w-0 items-center gap-1.5",
|
|
6724
|
+
role: "group",
|
|
6725
|
+
"aria-roledescription": "carousel",
|
|
6726
|
+
"aria-label": "Example questions",
|
|
6607
6727
|
onMouseEnter: () => setPaused(true),
|
|
6608
6728
|
onMouseLeave: () => setPaused(false),
|
|
6609
6729
|
onFocusCapture: () => setPaused(true),
|
|
@@ -6626,6 +6746,8 @@ function PromptCarousel({
|
|
|
6626
6746
|
"data-chip-kind": "prompt",
|
|
6627
6747
|
type: "button",
|
|
6628
6748
|
disabled,
|
|
6749
|
+
"aria-label": `Ask: ${current}`,
|
|
6750
|
+
"aria-live": paused ? "polite" : "off",
|
|
6629
6751
|
onClick: () => onPrompt(current),
|
|
6630
6752
|
className: "boff-explore-fade group flex min-w-0 flex-1 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 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",
|
|
6631
6753
|
children: [
|
|
@@ -6660,72 +6782,108 @@ function ProductStrip({
|
|
|
6660
6782
|
"shrink-0 rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6661
6783
|
active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6662
6784
|
);
|
|
6663
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6785
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6786
|
+
"div",
|
|
6787
|
+
{
|
|
6788
|
+
className: "flex min-w-0 items-center gap-2",
|
|
6789
|
+
role: "group",
|
|
6790
|
+
"aria-label": "Focus the assistant on one product",
|
|
6791
|
+
children: [
|
|
6792
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6793
|
+
"div",
|
|
6794
|
+
{
|
|
6795
|
+
className: cn(
|
|
6796
|
+
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
6797
|
+
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
6798
|
+
),
|
|
6799
|
+
children: [
|
|
6800
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6801
|
+
"button",
|
|
6802
|
+
{
|
|
6803
|
+
"data-boff-explore": "chip",
|
|
6804
|
+
"data-chip-kind": "product",
|
|
6805
|
+
"data-product": "all",
|
|
6806
|
+
type: "button",
|
|
6807
|
+
"aria-pressed": focusProduct === null,
|
|
6808
|
+
onClick: () => onFocus(null),
|
|
6809
|
+
className: chipClass(focusProduct === null),
|
|
6810
|
+
children: "All products"
|
|
6811
|
+
}
|
|
6812
|
+
),
|
|
6813
|
+
products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6814
|
+
"button",
|
|
6815
|
+
{
|
|
6816
|
+
"data-boff-explore": "chip",
|
|
6817
|
+
"data-chip-kind": "product",
|
|
6818
|
+
"data-product": product.slug,
|
|
6819
|
+
type: "button",
|
|
6820
|
+
"aria-pressed": focusProduct === product.slug,
|
|
6821
|
+
title: product.tagline ?? product.name,
|
|
6822
|
+
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6823
|
+
className: chipClass(focusProduct === product.slug),
|
|
6824
|
+
children: product.name
|
|
6825
|
+
},
|
|
6826
|
+
product.slug
|
|
6827
|
+
))
|
|
6828
|
+
]
|
|
6829
|
+
}
|
|
6670
6830
|
),
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6686
|
-
"button",
|
|
6687
|
-
{
|
|
6688
|
-
"data-boff-explore": "chip",
|
|
6689
|
-
"data-chip-kind": "product",
|
|
6690
|
-
"data-product": product.slug,
|
|
6691
|
-
type: "button",
|
|
6692
|
-
"aria-pressed": focusProduct === product.slug,
|
|
6693
|
-
title: product.tagline ?? product.name,
|
|
6694
|
-
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6695
|
-
className: chipClass(focusProduct === product.slug),
|
|
6696
|
-
children: product.name
|
|
6697
|
-
},
|
|
6698
|
-
product.slug
|
|
6699
|
-
))
|
|
6700
|
-
]
|
|
6701
|
-
}
|
|
6702
|
-
),
|
|
6703
|
-
products.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6704
|
-
"button",
|
|
6705
|
-
{
|
|
6706
|
-
type: "button",
|
|
6707
|
-
"data-boff-explore": "products-toggle",
|
|
6708
|
-
onClick: () => setExpanded((v) => !v),
|
|
6709
|
-
className: "shrink-0 whitespace-nowrap rounded-full px-2 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6710
|
-
children: expanded ? "Show less" : `All ${products.length}`
|
|
6711
|
-
}
|
|
6712
|
-
) : null
|
|
6713
|
-
] });
|
|
6831
|
+
products.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6832
|
+
"button",
|
|
6833
|
+
{
|
|
6834
|
+
type: "button",
|
|
6835
|
+
"data-boff-explore": "products-toggle",
|
|
6836
|
+
"aria-expanded": expanded,
|
|
6837
|
+
onClick: () => setExpanded((v) => !v),
|
|
6838
|
+
className: "shrink-0 whitespace-nowrap rounded-full px-2 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6839
|
+
children: expanded ? "Show less" : `All ${products.length}`
|
|
6840
|
+
}
|
|
6841
|
+
) : null
|
|
6842
|
+
]
|
|
6843
|
+
}
|
|
6844
|
+
);
|
|
6714
6845
|
}
|
|
6715
6846
|
function DisclaimerDialog({
|
|
6716
6847
|
open,
|
|
6717
6848
|
onClose,
|
|
6718
6849
|
captchaOn
|
|
6719
6850
|
}) {
|
|
6851
|
+
const panelRef = React.useRef(null);
|
|
6720
6852
|
const closeRef = React.useRef(null);
|
|
6853
|
+
const titleId = "boff-explore-disclaimer-title";
|
|
6721
6854
|
React.useEffect(() => {
|
|
6722
6855
|
if (!open) return;
|
|
6856
|
+
const opener = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
6857
|
+
const focusable = () => Array.from(
|
|
6858
|
+
panelRef.current?.querySelectorAll(
|
|
6859
|
+
'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])'
|
|
6860
|
+
) ?? []
|
|
6861
|
+
);
|
|
6723
6862
|
const onKey = (event) => {
|
|
6724
|
-
if (event.key === "Escape")
|
|
6863
|
+
if (event.key === "Escape") {
|
|
6864
|
+
onClose();
|
|
6865
|
+
return;
|
|
6866
|
+
}
|
|
6867
|
+
if (event.key !== "Tab") return;
|
|
6868
|
+
const items = focusable();
|
|
6869
|
+
if (items.length === 0) return;
|
|
6870
|
+
const first = items[0];
|
|
6871
|
+
const last = items[items.length - 1];
|
|
6872
|
+
const active = document.activeElement;
|
|
6873
|
+
if (event.shiftKey && (active === first || !panelRef.current?.contains(active))) {
|
|
6874
|
+
event.preventDefault();
|
|
6875
|
+
last?.focus();
|
|
6876
|
+
} else if (!event.shiftKey && active === last) {
|
|
6877
|
+
event.preventDefault();
|
|
6878
|
+
first?.focus();
|
|
6879
|
+
}
|
|
6725
6880
|
};
|
|
6726
6881
|
document.addEventListener("keydown", onKey);
|
|
6727
6882
|
closeRef.current?.focus();
|
|
6728
|
-
return () =>
|
|
6883
|
+
return () => {
|
|
6884
|
+
document.removeEventListener("keydown", onKey);
|
|
6885
|
+
opener?.focus();
|
|
6886
|
+
};
|
|
6729
6887
|
}, [open, onClose]);
|
|
6730
6888
|
if (!open) return null;
|
|
6731
6889
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6734,19 +6892,34 @@ function DisclaimerDialog({
|
|
|
6734
6892
|
"data-boff-explore": "disclaimer-dialog",
|
|
6735
6893
|
role: "dialog",
|
|
6736
6894
|
"aria-modal": "true",
|
|
6737
|
-
"aria-
|
|
6895
|
+
"aria-labelledby": titleId,
|
|
6738
6896
|
className: "fixed inset-0 z-50 flex items-end justify-center bg-foreground/40 p-4 backdrop-blur-sm sm:items-center",
|
|
6739
6897
|
onClick: onClose,
|
|
6740
6898
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6741
6899
|
"div",
|
|
6742
6900
|
{
|
|
6901
|
+
ref: panelRef,
|
|
6743
6902
|
className: "w-full max-w-md rounded-2xl border border-border bg-card p-5 shadow-xl",
|
|
6744
6903
|
onClick: (event) => event.stopPropagation(),
|
|
6745
6904
|
children: [
|
|
6746
6905
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
6747
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6906
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6907
|
+
"span",
|
|
6908
|
+
{
|
|
6909
|
+
"aria-hidden": "true",
|
|
6910
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary",
|
|
6911
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TriangleAlert, { className: "h-4 w-4" })
|
|
6912
|
+
}
|
|
6913
|
+
),
|
|
6748
6914
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
6749
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6915
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6916
|
+
"p",
|
|
6917
|
+
{
|
|
6918
|
+
id: titleId,
|
|
6919
|
+
className: "text-sm font-semibold text-card-foreground",
|
|
6920
|
+
children: "How this assistant works"
|
|
6921
|
+
}
|
|
6922
|
+
),
|
|
6750
6923
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 space-y-2 text-xs leading-relaxed text-muted-foreground", children: [
|
|
6751
6924
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Answers are generated from our public documentation and can be imperfect \u2014 check anything important against the linked sources." }),
|
|
6752
6925
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Conversations are saved in this browser so you can come back to them, and are also stored on our servers to help us improve these answers. Please don't share personal or confidential information." }),
|
|
@@ -6858,7 +7031,9 @@ function ExplorePage({
|
|
|
6858
7031
|
history,
|
|
6859
7032
|
openConversation,
|
|
6860
7033
|
deleteConversation,
|
|
6861
|
-
clearHistory
|
|
7034
|
+
clearHistory,
|
|
7035
|
+
recordClick,
|
|
7036
|
+
createShareLink
|
|
6862
7037
|
} = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
|
|
6863
7038
|
const [draft, setDraft] = React.useState("");
|
|
6864
7039
|
const textareaRef = React.useRef(null);
|
|
@@ -6878,6 +7053,7 @@ function ExplorePage({
|
|
|
6878
7053
|
});
|
|
6879
7054
|
speechStopRef.current = speech.stop;
|
|
6880
7055
|
const [disclaimerOpen, setDisclaimerOpen] = React.useState(false);
|
|
7056
|
+
const [shareLabel, setShareLabel] = React.useState("Share");
|
|
6881
7057
|
const scrollRef = React.useRef(null);
|
|
6882
7058
|
const latestAssistantRef = React.useRef(null);
|
|
6883
7059
|
const alignedForRef = React.useRef(null);
|
|
@@ -6932,6 +7108,25 @@ function ExplorePage({
|
|
|
6932
7108
|
if (!el) return;
|
|
6933
7109
|
el.scrollTop = el.scrollHeight;
|
|
6934
7110
|
}, [activity, latestAssistantId, messages]);
|
|
7111
|
+
const handleShare = React.useCallback(async () => {
|
|
7112
|
+
setShareLabel("Copying\u2026");
|
|
7113
|
+
const token = await createShareLink();
|
|
7114
|
+
if (!token) {
|
|
7115
|
+
setShareLabel("Unavailable");
|
|
7116
|
+
setTimeout(() => setShareLabel("Share"), 2500);
|
|
7117
|
+
return;
|
|
7118
|
+
}
|
|
7119
|
+
const base = (pageUrl ?? window.location.href).split("?")[0];
|
|
7120
|
+
const url = `${base}?c=${encodeURIComponent(token)}`;
|
|
7121
|
+
try {
|
|
7122
|
+
await navigator.clipboard.writeText(url);
|
|
7123
|
+
setShareLabel("Copied");
|
|
7124
|
+
} catch {
|
|
7125
|
+
window.prompt("Copy this link", url);
|
|
7126
|
+
setShareLabel("Share");
|
|
7127
|
+
}
|
|
7128
|
+
setTimeout(() => setShareLabel("Share"), 2500);
|
|
7129
|
+
}, [createShareLink, pageUrl]);
|
|
6935
7130
|
const submitDraft = React.useCallback(() => {
|
|
6936
7131
|
const text = draft.trim();
|
|
6937
7132
|
if (!text || overLimit || busy || !canSend) return;
|
|
@@ -7014,6 +7209,24 @@ function ExplorePage({
|
|
|
7014
7209
|
]
|
|
7015
7210
|
}
|
|
7016
7211
|
),
|
|
7212
|
+
messages.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7213
|
+
Button,
|
|
7214
|
+
{
|
|
7215
|
+
"data-boff-explore": "share",
|
|
7216
|
+
type: "button",
|
|
7217
|
+
size: "sm",
|
|
7218
|
+
variant: "ghost",
|
|
7219
|
+
className: "shrink-0 text-muted-foreground",
|
|
7220
|
+
title: "Copy a read-only link to this conversation",
|
|
7221
|
+
onClick: () => {
|
|
7222
|
+
void handleShare();
|
|
7223
|
+
},
|
|
7224
|
+
children: [
|
|
7225
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3.5 w-3.5" }),
|
|
7226
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: shareLabel })
|
|
7227
|
+
]
|
|
7228
|
+
}
|
|
7229
|
+
) : null,
|
|
7017
7230
|
history.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7018
7231
|
Button,
|
|
7019
7232
|
{
|
|
@@ -7132,7 +7345,9 @@ function ExplorePage({
|
|
|
7132
7345
|
message,
|
|
7133
7346
|
activity,
|
|
7134
7347
|
onNavigate,
|
|
7135
|
-
anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0
|
|
7348
|
+
anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0,
|
|
7349
|
+
onFollow: (kind, url) => recordClick(message.id, kind, url),
|
|
7350
|
+
onFollowUp: sendPrompt
|
|
7136
7351
|
},
|
|
7137
7352
|
message.id
|
|
7138
7353
|
)
|