@burdenoff/website-sdk 2026.828.7 → 2026.829.2
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 +567 -200
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +569 -202
- 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 +139 -69
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +139 -69
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +567 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +567 -200
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-DhvZhH8f.d.mts → use-explore-chat-8eL7WdLc.d.mts} +16 -2
- package/dist/{use-explore-chat-DhvZhH8f.d.ts → use-explore-chat-8eL7WdLc.d.ts} +16 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4929,6 +4929,7 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
4929
4929
|
description
|
|
4930
4930
|
product
|
|
4931
4931
|
imageUrl
|
|
4932
|
+
index
|
|
4932
4933
|
}
|
|
4933
4934
|
ctas {
|
|
4934
4935
|
kind
|
|
@@ -4936,6 +4937,8 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
4936
4937
|
url
|
|
4937
4938
|
product
|
|
4938
4939
|
}
|
|
4940
|
+
followUps
|
|
4941
|
+
answered
|
|
4939
4942
|
errorCode
|
|
4940
4943
|
createdAt
|
|
4941
4944
|
completedAt
|
|
@@ -5001,6 +5004,16 @@ var SEND_EXPLORE_MESSAGE_MUTATION = (
|
|
|
5001
5004
|
}
|
|
5002
5005
|
`
|
|
5003
5006
|
);
|
|
5007
|
+
var RECORD_EXPLORE_CLICK_MUTATION = (
|
|
5008
|
+
/* GraphQL */
|
|
5009
|
+
`
|
|
5010
|
+
mutation RecordExploreClick($input: RecordExploreClickInput!) {
|
|
5011
|
+
recordExploreClick(input: $input) {
|
|
5012
|
+
recorded
|
|
5013
|
+
}
|
|
5014
|
+
}
|
|
5015
|
+
`
|
|
5016
|
+
);
|
|
5004
5017
|
|
|
5005
5018
|
// src/data/products.ts
|
|
5006
5019
|
var ECOSYSTEM_PRODUCTS = [
|
|
@@ -5933,6 +5946,20 @@ function useExploreChat(options = {}) {
|
|
|
5933
5946
|
return null;
|
|
5934
5947
|
}, [messages]);
|
|
5935
5948
|
const canSend = (phase === "ready" || phase === "error") && catalog.enabled && turnCount < catalog.limits.maxTurnsPerConversation;
|
|
5949
|
+
const recordClick = useCallback(
|
|
5950
|
+
(messageId, kind, url) => {
|
|
5951
|
+
const token = conversationTokenRef.current;
|
|
5952
|
+
if (!token) return;
|
|
5953
|
+
try {
|
|
5954
|
+
void client.mutate(RECORD_EXPLORE_CLICK_MUTATION, {
|
|
5955
|
+
input: { conversationToken: token, messageId, kind, url }
|
|
5956
|
+
}).catch(() => {
|
|
5957
|
+
});
|
|
5958
|
+
} catch {
|
|
5959
|
+
}
|
|
5960
|
+
},
|
|
5961
|
+
[client]
|
|
5962
|
+
);
|
|
5936
5963
|
return {
|
|
5937
5964
|
phase,
|
|
5938
5965
|
catalog,
|
|
@@ -5950,7 +5977,8 @@ function useExploreChat(options = {}) {
|
|
|
5950
5977
|
history: archive,
|
|
5951
5978
|
openConversation,
|
|
5952
5979
|
deleteConversation,
|
|
5953
|
-
clearHistory
|
|
5980
|
+
clearHistory,
|
|
5981
|
+
recordClick
|
|
5954
5982
|
};
|
|
5955
5983
|
}
|
|
5956
5984
|
var optimisticCounter = 0;
|
|
@@ -5963,21 +5991,37 @@ function getRecognitionCtor() {
|
|
|
5963
5991
|
const w = window;
|
|
5964
5992
|
return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;
|
|
5965
5993
|
}
|
|
5994
|
+
function isTouchDevice() {
|
|
5995
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
5996
|
+
try {
|
|
5997
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
5998
|
+
} catch {
|
|
5999
|
+
return false;
|
|
6000
|
+
}
|
|
6001
|
+
}
|
|
5966
6002
|
var MIC_DENIED_MESSAGE = "Microphone access was blocked. Allow it in your browser's site settings to dictate.";
|
|
6003
|
+
var MIC_UNAVAILABLE_MESSAGE = "Dictation isn't available in this browser. You can type instead.";
|
|
6004
|
+
var RELEASE_SETTLE_MS = 250;
|
|
6005
|
+
var RETRY_DELAY_MS = 350;
|
|
6006
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6007
|
+
setTimeout(resolve, ms);
|
|
6008
|
+
});
|
|
5967
6009
|
async function ensureMicrophoneAccess() {
|
|
5968
6010
|
const media = typeof navigator === "undefined" ? void 0 : navigator.mediaDevices;
|
|
5969
|
-
if (!media?.getUserMedia)
|
|
6011
|
+
if (!media?.getUserMedia)
|
|
6012
|
+
return { ok: true, confirmed: false, primed: false };
|
|
5970
6013
|
try {
|
|
5971
6014
|
const status = await navigator.permissions?.query({
|
|
5972
6015
|
name: "microphone"
|
|
5973
6016
|
});
|
|
5974
|
-
if (status?.state === "granted")
|
|
6017
|
+
if (status?.state === "granted")
|
|
6018
|
+
return { ok: true, confirmed: true, primed: false };
|
|
5975
6019
|
} catch {
|
|
5976
6020
|
}
|
|
5977
6021
|
try {
|
|
5978
6022
|
const stream = await media.getUserMedia({ audio: true });
|
|
5979
6023
|
for (const track of stream.getTracks()) track.stop();
|
|
5980
|
-
return { ok: true, confirmed: true };
|
|
6024
|
+
return { ok: true, confirmed: true, primed: true };
|
|
5981
6025
|
} catch (error) {
|
|
5982
6026
|
const name = typeof error === "object" && error !== null && "name" in error ? String(error.name) : "";
|
|
5983
6027
|
if (name === "NotAllowedError" || name === "SecurityError") {
|
|
@@ -6021,19 +6065,17 @@ function useSpeechInput({
|
|
|
6021
6065
|
const recognitionRef = useRef(null);
|
|
6022
6066
|
const startTokenRef = useRef(0);
|
|
6023
6067
|
const micConfirmedRef = useRef(false);
|
|
6024
|
-
const
|
|
6025
|
-
const
|
|
6026
|
-
(Ctor, token) => {
|
|
6027
|
-
beginRecognitionRef.current?.(Ctor, token);
|
|
6028
|
-
},
|
|
6029
|
-
[]
|
|
6030
|
-
);
|
|
6068
|
+
const wantsListeningRef = useRef(false);
|
|
6069
|
+
const retriedRef = useRef(false);
|
|
6031
6070
|
const finalRef = useRef(onFinalTranscript);
|
|
6032
6071
|
const errorRef = useRef(onError);
|
|
6033
6072
|
finalRef.current = onFinalTranscript;
|
|
6034
6073
|
errorRef.current = onError;
|
|
6074
|
+
const langRef = useRef(lang);
|
|
6075
|
+
langRef.current = lang;
|
|
6035
6076
|
const stop = useCallback(() => {
|
|
6036
6077
|
startTokenRef.current += 1;
|
|
6078
|
+
wantsListeningRef.current = false;
|
|
6037
6079
|
setListening(false);
|
|
6038
6080
|
setInterim("");
|
|
6039
6081
|
const recognition = recognitionRef.current;
|
|
@@ -6042,83 +6084,111 @@ function useSpeechInput({
|
|
|
6042
6084
|
recognition.stop();
|
|
6043
6085
|
} catch {
|
|
6044
6086
|
}
|
|
6045
|
-
setListening(false);
|
|
6046
|
-
setInterim("");
|
|
6047
6087
|
}, []);
|
|
6048
|
-
const
|
|
6088
|
+
const openSession = useCallback((token) => {
|
|
6049
6089
|
const Ctor = getRecognitionCtor();
|
|
6050
|
-
if (!Ctor) return;
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6090
|
+
if (!Ctor || token !== startTokenRef.current) return;
|
|
6091
|
+
const recognition = new Ctor();
|
|
6092
|
+
recognition.lang = langRef.current ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
6093
|
+
recognition.continuous = !isTouchDevice();
|
|
6094
|
+
recognition.interimResults = true;
|
|
6095
|
+
recognition.maxAlternatives = 1;
|
|
6096
|
+
recognition.onstart = () => {
|
|
6097
|
+
if (token !== startTokenRef.current) return;
|
|
6098
|
+
setError(null);
|
|
6099
|
+
setListening(true);
|
|
6100
|
+
};
|
|
6101
|
+
recognition.onresult = (event) => {
|
|
6102
|
+
if (token !== startTokenRef.current) return;
|
|
6103
|
+
let settled = "";
|
|
6104
|
+
let pending = "";
|
|
6105
|
+
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
6106
|
+
const result = event.results[i];
|
|
6107
|
+
if (!result) continue;
|
|
6108
|
+
const text = result[0]?.transcript ?? "";
|
|
6109
|
+
if (result.isFinal) settled += text;
|
|
6110
|
+
else pending += text;
|
|
6111
|
+
}
|
|
6112
|
+
setInterim(pending);
|
|
6113
|
+
if (settled.trim() !== "") finalRef.current(settled);
|
|
6114
|
+
};
|
|
6115
|
+
recognition.onerror = (event) => {
|
|
6116
|
+
if (token !== startTokenRef.current) return;
|
|
6117
|
+
if ((event.error === "not-allowed" || event.error === "service-not-allowed") && micConfirmedRef.current && !retriedRef.current) {
|
|
6118
|
+
retriedRef.current = true;
|
|
6119
|
+
void sleep(RETRY_DELAY_MS).then(() => {
|
|
6120
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
6121
|
+
return;
|
|
6122
|
+
openSessionRef.current?.(token);
|
|
6123
|
+
});
|
|
6124
|
+
return;
|
|
6125
|
+
}
|
|
6126
|
+
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? MIC_UNAVAILABLE_MESSAGE : describeError(event.error);
|
|
6127
|
+
wantsListeningRef.current = false;
|
|
6128
|
+
setListening(false);
|
|
6129
|
+
setInterim("");
|
|
6130
|
+
if (message !== "") {
|
|
6131
|
+
setError(message);
|
|
6132
|
+
errorRef.current?.(message);
|
|
6133
|
+
}
|
|
6134
|
+
};
|
|
6135
|
+
recognition.onend = () => {
|
|
6136
|
+
if (token !== startTokenRef.current) return;
|
|
6137
|
+
setInterim("");
|
|
6138
|
+
if (wantsListeningRef.current && isTouchDevice()) {
|
|
6139
|
+
void sleep(120).then(() => {
|
|
6140
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
6141
|
+
return;
|
|
6142
|
+
openSessionRef.current?.(token);
|
|
6143
|
+
});
|
|
6144
|
+
return;
|
|
6145
|
+
}
|
|
6146
|
+
setListening(false);
|
|
6147
|
+
};
|
|
6148
|
+
recognitionRef.current = recognition;
|
|
6149
|
+
try {
|
|
6150
|
+
recognition.start();
|
|
6151
|
+
} catch {
|
|
6152
|
+
wantsListeningRef.current = false;
|
|
6153
|
+
setListening(false);
|
|
6154
|
+
}
|
|
6155
|
+
}, []);
|
|
6156
|
+
const openSessionRef = useRef(null);
|
|
6157
|
+
openSessionRef.current = openSession;
|
|
6158
|
+
const start = useCallback(() => {
|
|
6159
|
+
if (!getRecognitionCtor()) return;
|
|
6054
6160
|
startTokenRef.current += 1;
|
|
6055
6161
|
const token = startTokenRef.current;
|
|
6056
|
-
|
|
6162
|
+
wantsListeningRef.current = true;
|
|
6163
|
+
retriedRef.current = false;
|
|
6164
|
+
micConfirmedRef.current = false;
|
|
6165
|
+
setError(null);
|
|
6166
|
+
setListening(true);
|
|
6167
|
+
void ensureMicrophoneAccess().then(async (access) => {
|
|
6057
6168
|
if (token !== startTokenRef.current) return;
|
|
6058
|
-
micConfirmedRef.current = access.ok && access.confirmed;
|
|
6059
6169
|
if (!access.ok) {
|
|
6170
|
+
wantsListeningRef.current = false;
|
|
6060
6171
|
setListening(false);
|
|
6061
6172
|
setError(access.message);
|
|
6062
6173
|
errorRef.current?.(access.message);
|
|
6063
6174
|
return;
|
|
6064
6175
|
}
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
const beginRecognitionImpl = useCallback(
|
|
6069
|
-
(Ctor, token) => {
|
|
6070
|
-
const recognition = new Ctor();
|
|
6071
|
-
recognition.lang = lang ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
6072
|
-
recognition.continuous = true;
|
|
6073
|
-
recognition.interimResults = true;
|
|
6074
|
-
recognition.maxAlternatives = 1;
|
|
6075
|
-
recognition.onstart = () => {
|
|
6176
|
+
micConfirmedRef.current = access.confirmed;
|
|
6177
|
+
if (access.primed) {
|
|
6178
|
+
await sleep(RELEASE_SETTLE_MS);
|
|
6076
6179
|
if (token !== startTokenRef.current) return;
|
|
6077
|
-
setError(null);
|
|
6078
|
-
setListening(true);
|
|
6079
|
-
};
|
|
6080
|
-
recognition.onresult = (event) => {
|
|
6081
|
-
let settled = "";
|
|
6082
|
-
let pending = "";
|
|
6083
|
-
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
6084
|
-
const result = event.results[i];
|
|
6085
|
-
if (!result) continue;
|
|
6086
|
-
const text = result[0]?.transcript ?? "";
|
|
6087
|
-
if (result.isFinal) settled += text;
|
|
6088
|
-
else pending += text;
|
|
6089
|
-
}
|
|
6090
|
-
setInterim(pending);
|
|
6091
|
-
if (settled.trim() !== "") finalRef.current(settled);
|
|
6092
|
-
};
|
|
6093
|
-
recognition.onerror = (event) => {
|
|
6094
|
-
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? "Dictation isn't available in this browser. You can type instead." : describeError(event.error);
|
|
6095
|
-
setListening(false);
|
|
6096
|
-
setInterim("");
|
|
6097
|
-
if (message !== "") {
|
|
6098
|
-
setError(message);
|
|
6099
|
-
errorRef.current?.(message);
|
|
6100
|
-
}
|
|
6101
|
-
};
|
|
6102
|
-
recognition.onend = () => {
|
|
6103
|
-
setListening(false);
|
|
6104
|
-
setInterim("");
|
|
6105
|
-
};
|
|
6106
|
-
recognitionRef.current = recognition;
|
|
6107
|
-
try {
|
|
6108
|
-
recognition.start();
|
|
6109
|
-
} catch {
|
|
6110
|
-
setListening(false);
|
|
6111
6180
|
}
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
);
|
|
6115
|
-
beginRecognitionRef.current = beginRecognitionImpl;
|
|
6181
|
+
openSessionRef.current?.(token);
|
|
6182
|
+
});
|
|
6183
|
+
}, []);
|
|
6116
6184
|
const toggle = useCallback(() => {
|
|
6117
6185
|
if (listening) stop();
|
|
6118
6186
|
else start();
|
|
6119
6187
|
}, [listening, start, stop]);
|
|
6120
6188
|
useEffect(
|
|
6121
6189
|
() => () => {
|
|
6190
|
+
startTokenRef.current += 1;
|
|
6191
|
+
wantsListeningRef.current = false;
|
|
6122
6192
|
const recognition = recognitionRef.current;
|
|
6123
6193
|
if (!recognition) return;
|
|
6124
6194
|
recognition.onresult = null;
|
|
@@ -6177,6 +6247,50 @@ var EXPLORE_CSS = `
|
|
|
6177
6247
|
border-radius: 9999px;
|
|
6178
6248
|
background-clip: content-box;
|
|
6179
6249
|
}
|
|
6250
|
+
|
|
6251
|
+
/* The product strip scrolls inside itself; a visible scrollbar would read as a broken
|
|
6252
|
+
layout rather than an affordance, and reserving its gutter shifts the chips. */
|
|
6253
|
+
.boff-explore-strip {
|
|
6254
|
+
scrollbar-width: none;
|
|
6255
|
+
-ms-overflow-style: none;
|
|
6256
|
+
}
|
|
6257
|
+
.boff-explore-strip::-webkit-scrollbar { display: none; }
|
|
6258
|
+
|
|
6259
|
+
@keyframes boff-explore-fade-in {
|
|
6260
|
+
from { opacity: 0; transform: translateY(2px); }
|
|
6261
|
+
to { opacity: 1; transform: none; }
|
|
6262
|
+
}
|
|
6263
|
+
.boff-explore-fade { animation: boff-explore-fade-in 220ms ease-out; }
|
|
6264
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6265
|
+
.boff-explore-fade { animation: none; }
|
|
6266
|
+
}
|
|
6267
|
+
|
|
6268
|
+
/* Nothing inside an answer may widen the page. Model output carries long URLs, code and
|
|
6269
|
+
tables \u2014 each of those overflows a phone by default, and one overflowing child makes the
|
|
6270
|
+
WHOLE document horizontally scrollable, not just the bubble. */
|
|
6271
|
+
.boff-explore-body,
|
|
6272
|
+
.boff-explore-body p,
|
|
6273
|
+
.boff-explore-body li,
|
|
6274
|
+
.boff-explore-body a,
|
|
6275
|
+
.boff-explore-body h1,
|
|
6276
|
+
.boff-explore-body h2,
|
|
6277
|
+
.boff-explore-body h3 {
|
|
6278
|
+
overflow-wrap: anywhere;
|
|
6279
|
+
word-break: break-word;
|
|
6280
|
+
}
|
|
6281
|
+
.boff-explore-body pre {
|
|
6282
|
+
overflow-x: auto;
|
|
6283
|
+
max-width: 100%;
|
|
6284
|
+
}
|
|
6285
|
+
.boff-explore-body table {
|
|
6286
|
+
display: block;
|
|
6287
|
+
overflow-x: auto;
|
|
6288
|
+
max-width: 100%;
|
|
6289
|
+
}
|
|
6290
|
+
.boff-explore-body img {
|
|
6291
|
+
max-width: 100%;
|
|
6292
|
+
height: auto;
|
|
6293
|
+
}
|
|
6180
6294
|
`;
|
|
6181
6295
|
function ExploreStyles() {
|
|
6182
6296
|
return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: EXPLORE_CSS } });
|
|
@@ -6198,7 +6312,6 @@ var CAPABILITIES = [
|
|
|
6198
6312
|
body: "Get the sources and next steps \u2014 pricing, docs, a demo \u2014 without hunting."
|
|
6199
6313
|
}
|
|
6200
6314
|
];
|
|
6201
|
-
var PRODUCT_CHIP_PREVIEW = 12;
|
|
6202
6315
|
var CTA_VARIANTS = {
|
|
6203
6316
|
CONTACT: "default",
|
|
6204
6317
|
WAITLIST: "default",
|
|
@@ -6237,7 +6350,10 @@ function logoUrlOf(url) {
|
|
|
6237
6350
|
return null;
|
|
6238
6351
|
}
|
|
6239
6352
|
}
|
|
6240
|
-
function ReferenceCard({
|
|
6353
|
+
function ReferenceCard({
|
|
6354
|
+
reference,
|
|
6355
|
+
onFollow
|
|
6356
|
+
}) {
|
|
6241
6357
|
const [imageFailed, setImageFailed] = useState(false);
|
|
6242
6358
|
const [logoFailed, setLogoFailed] = useState(false);
|
|
6243
6359
|
const host = hostnameOf(reference.url);
|
|
@@ -6259,9 +6375,11 @@ function ReferenceCard({ reference }) {
|
|
|
6259
6375
|
"a",
|
|
6260
6376
|
{
|
|
6261
6377
|
"data-boff-explore": "reference",
|
|
6378
|
+
"data-index": reference.index ?? void 0,
|
|
6262
6379
|
href: reference.url,
|
|
6263
6380
|
target: "_blank",
|
|
6264
6381
|
rel: "noopener noreferrer",
|
|
6382
|
+
onClick: () => onFollow?.(reference.url),
|
|
6265
6383
|
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",
|
|
6266
6384
|
children: [
|
|
6267
6385
|
/* @__PURE__ */ jsx("div", { className: "relative h-11 w-11 shrink-0 overflow-hidden rounded-lg bg-muted sm:hidden", children: logoImg }),
|
|
@@ -6285,7 +6403,10 @@ function ReferenceCard({ reference }) {
|
|
|
6285
6403
|
}
|
|
6286
6404
|
) }) : letterPlate }),
|
|
6287
6405
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 sm:gap-1.5 sm:p-3", children: [
|
|
6288
|
-
/* @__PURE__ */
|
|
6406
|
+
/* @__PURE__ */ jsxs("p", { className: "line-clamp-2 text-sm font-semibold leading-snug text-card-foreground", children: [
|
|
6407
|
+
reference.index ? /* @__PURE__ */ 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,
|
|
6408
|
+
reference.title || host || reference.url
|
|
6409
|
+
] }),
|
|
6289
6410
|
reference.description ? /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-xs leading-relaxed text-muted-foreground max-sm:hidden", children: reference.description }) : null,
|
|
6290
6411
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:mt-auto sm:pt-2", children: [
|
|
6291
6412
|
reference.product ? /* @__PURE__ */ 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,
|
|
@@ -6301,7 +6422,8 @@ function ReferenceCard({ reference }) {
|
|
|
6301
6422
|
}
|
|
6302
6423
|
function CtaButton({
|
|
6303
6424
|
cta,
|
|
6304
|
-
onNavigate
|
|
6425
|
+
onNavigate,
|
|
6426
|
+
onFollow
|
|
6305
6427
|
}) {
|
|
6306
6428
|
const variant = CTA_VARIANTS[cta.kind] ?? "outline";
|
|
6307
6429
|
const internal = isInternalPath(cta.url);
|
|
@@ -6314,7 +6436,10 @@ function CtaButton({
|
|
|
6314
6436
|
type: "button",
|
|
6315
6437
|
size: "sm",
|
|
6316
6438
|
variant,
|
|
6317
|
-
onClick: () =>
|
|
6439
|
+
onClick: () => {
|
|
6440
|
+
onFollow?.(cta.url);
|
|
6441
|
+
onNavigate(cta.url);
|
|
6442
|
+
},
|
|
6318
6443
|
children: cta.label
|
|
6319
6444
|
}
|
|
6320
6445
|
);
|
|
@@ -6325,6 +6450,7 @@ function CtaButton({
|
|
|
6325
6450
|
"data-boff-explore": "cta",
|
|
6326
6451
|
"data-kind": cta.kind,
|
|
6327
6452
|
href: cta.url,
|
|
6453
|
+
onClick: () => onFollow?.(cta.url),
|
|
6328
6454
|
...internal ? {} : { target: "_blank", rel: "noopener noreferrer" },
|
|
6329
6455
|
children: [
|
|
6330
6456
|
cta.label,
|
|
@@ -6376,7 +6502,9 @@ function AssistantBubble({
|
|
|
6376
6502
|
message,
|
|
6377
6503
|
activity,
|
|
6378
6504
|
onNavigate,
|
|
6379
|
-
anchorRef
|
|
6505
|
+
anchorRef,
|
|
6506
|
+
onFollow,
|
|
6507
|
+
onFollowUp
|
|
6380
6508
|
}) {
|
|
6381
6509
|
const streaming = message.status === "PENDING" || message.status === "RUNNING";
|
|
6382
6510
|
const body = message.content || message.partialContent || "";
|
|
@@ -6398,24 +6526,77 @@ function AssistantBubble({
|
|
|
6398
6526
|
}
|
|
6399
6527
|
),
|
|
6400
6528
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [
|
|
6529
|
+
message.status === "COMPLETED" && message.answered === false ? /* @__PURE__ */ jsxs(
|
|
6530
|
+
"div",
|
|
6531
|
+
{
|
|
6532
|
+
"data-boff-explore": "no-answer",
|
|
6533
|
+
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",
|
|
6534
|
+
children: [
|
|
6535
|
+
/* @__PURE__ */ jsx(TriangleAlert, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-amber-600 dark:text-amber-400" }),
|
|
6536
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
6537
|
+
"I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
|
|
6538
|
+
" ",
|
|
6539
|
+
/* @__PURE__ */ jsx(
|
|
6540
|
+
"a",
|
|
6541
|
+
{
|
|
6542
|
+
href: "/contact",
|
|
6543
|
+
className: "underline underline-offset-2 hover:text-primary",
|
|
6544
|
+
onClick: (event) => {
|
|
6545
|
+
if (!onNavigate) return;
|
|
6546
|
+
event.preventDefault();
|
|
6547
|
+
onNavigate("/contact");
|
|
6548
|
+
},
|
|
6549
|
+
children: "ask a human"
|
|
6550
|
+
}
|
|
6551
|
+
),
|
|
6552
|
+
"."
|
|
6553
|
+
] })
|
|
6554
|
+
]
|
|
6555
|
+
}
|
|
6556
|
+
) : null,
|
|
6401
6557
|
body ? /* @__PURE__ */ jsxs("div", { className: "rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm", children: [
|
|
6402
|
-
/* @__PURE__ */ jsx("div", { className: "boff-prose boff-prose-sm text-card-foreground", children: /* @__PURE__ */ jsx(Markdown, { children: body }) }),
|
|
6558
|
+
/* @__PURE__ */ jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsx(Markdown, { children: body }) }),
|
|
6403
6559
|
streaming ? /* @__PURE__ */ jsx("span", { className: "boff-explore-caret", "aria-hidden": "true" }) : null
|
|
6404
6560
|
] }) : null,
|
|
6405
6561
|
streaming ? /* @__PURE__ */ jsx(ThinkingIndicator, { activity }) : null,
|
|
6406
6562
|
failed && !body ? /* @__PURE__ */ 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,
|
|
6407
6563
|
message.references.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
6408
6564
|
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Sources" }),
|
|
6409
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: message.references.map((reference) => /* @__PURE__ */ jsx(
|
|
6565
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: message.references.map((reference) => /* @__PURE__ */ jsx(
|
|
6566
|
+
ReferenceCard,
|
|
6567
|
+
{
|
|
6568
|
+
reference,
|
|
6569
|
+
onFollow: (url) => onFollow?.("REFERENCE", url)
|
|
6570
|
+
},
|
|
6571
|
+
reference.url
|
|
6572
|
+
)) })
|
|
6410
6573
|
] }) : null,
|
|
6411
6574
|
message.ctas.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 pt-0.5", children: message.ctas.map((cta) => /* @__PURE__ */ jsx(
|
|
6412
6575
|
CtaButton,
|
|
6413
6576
|
{
|
|
6414
6577
|
cta,
|
|
6415
|
-
onNavigate
|
|
6578
|
+
onNavigate,
|
|
6579
|
+
onFollow: (url) => onFollow?.("CTA", url)
|
|
6416
6580
|
},
|
|
6417
6581
|
`${cta.kind}-${cta.url}`
|
|
6418
|
-
)) }) : null
|
|
6582
|
+
)) }) : null,
|
|
6583
|
+
message.status === "COMPLETED" && (message.followUps?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 pt-0.5", children: [
|
|
6584
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground", children: "Next you could ask" }),
|
|
6585
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: (message.followUps ?? []).map((question) => /* @__PURE__ */ jsxs(
|
|
6586
|
+
"button",
|
|
6587
|
+
{
|
|
6588
|
+
"data-boff-explore": "follow-up",
|
|
6589
|
+
type: "button",
|
|
6590
|
+
onClick: () => onFollowUp?.(question),
|
|
6591
|
+
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",
|
|
6592
|
+
children: [
|
|
6593
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: question }),
|
|
6594
|
+
/* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6595
|
+
]
|
|
6596
|
+
},
|
|
6597
|
+
question
|
|
6598
|
+
)) })
|
|
6599
|
+
] }) : null
|
|
6419
6600
|
] })
|
|
6420
6601
|
]
|
|
6421
6602
|
}
|
|
@@ -6461,6 +6642,256 @@ function ErrorBanner({
|
|
|
6461
6642
|
}
|
|
6462
6643
|
);
|
|
6463
6644
|
}
|
|
6645
|
+
function PromptCarousel({
|
|
6646
|
+
prompts,
|
|
6647
|
+
onPrompt,
|
|
6648
|
+
disabled
|
|
6649
|
+
}) {
|
|
6650
|
+
const [index, setIndex] = useState(0);
|
|
6651
|
+
const [paused, setPaused] = useState(false);
|
|
6652
|
+
const count = prompts.length;
|
|
6653
|
+
const current = prompts[index % count] ?? prompts[0] ?? "";
|
|
6654
|
+
const go = useCallback(
|
|
6655
|
+
(delta) => {
|
|
6656
|
+
setIndex((i) => (i + delta + count) % count);
|
|
6657
|
+
},
|
|
6658
|
+
[count]
|
|
6659
|
+
);
|
|
6660
|
+
useEffect(() => {
|
|
6661
|
+
if (paused || disabled || count < 2) return;
|
|
6662
|
+
if (typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
6663
|
+
return;
|
|
6664
|
+
}
|
|
6665
|
+
const timer = setInterval(() => setIndex((i) => (i + 1) % count), 4500);
|
|
6666
|
+
return () => clearInterval(timer);
|
|
6667
|
+
}, [paused, disabled, count]);
|
|
6668
|
+
if (count === 0) return null;
|
|
6669
|
+
return /* @__PURE__ */ jsxs(
|
|
6670
|
+
"div",
|
|
6671
|
+
{
|
|
6672
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
6673
|
+
role: "group",
|
|
6674
|
+
"aria-roledescription": "carousel",
|
|
6675
|
+
"aria-label": "Example questions",
|
|
6676
|
+
onMouseEnter: () => setPaused(true),
|
|
6677
|
+
onMouseLeave: () => setPaused(false),
|
|
6678
|
+
onFocusCapture: () => setPaused(true),
|
|
6679
|
+
onBlurCapture: () => setPaused(false),
|
|
6680
|
+
children: [
|
|
6681
|
+
count > 1 ? /* @__PURE__ */ jsx(
|
|
6682
|
+
"button",
|
|
6683
|
+
{
|
|
6684
|
+
type: "button",
|
|
6685
|
+
"aria-label": "Previous suggestion",
|
|
6686
|
+
onClick: () => go(-1),
|
|
6687
|
+
className: "hidden h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex",
|
|
6688
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
6689
|
+
}
|
|
6690
|
+
) : null,
|
|
6691
|
+
/* @__PURE__ */ jsxs(
|
|
6692
|
+
"button",
|
|
6693
|
+
{
|
|
6694
|
+
"data-boff-explore": "chip",
|
|
6695
|
+
"data-chip-kind": "prompt",
|
|
6696
|
+
type: "button",
|
|
6697
|
+
disabled,
|
|
6698
|
+
"aria-label": `Ask: ${current}`,
|
|
6699
|
+
"aria-live": paused ? "polite" : "off",
|
|
6700
|
+
onClick: () => onPrompt(current),
|
|
6701
|
+
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",
|
|
6702
|
+
children: [
|
|
6703
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
6704
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: current }),
|
|
6705
|
+
/* @__PURE__ */ jsx(ArrowUp, { className: "ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6706
|
+
]
|
|
6707
|
+
},
|
|
6708
|
+
current
|
|
6709
|
+
),
|
|
6710
|
+
count > 1 ? /* @__PURE__ */ jsx(
|
|
6711
|
+
"button",
|
|
6712
|
+
{
|
|
6713
|
+
type: "button",
|
|
6714
|
+
"aria-label": "Next suggestion",
|
|
6715
|
+
onClick: () => go(1),
|
|
6716
|
+
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6717
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
6718
|
+
}
|
|
6719
|
+
) : null
|
|
6720
|
+
]
|
|
6721
|
+
}
|
|
6722
|
+
);
|
|
6723
|
+
}
|
|
6724
|
+
function ProductStrip({
|
|
6725
|
+
products,
|
|
6726
|
+
focusProduct,
|
|
6727
|
+
onFocus
|
|
6728
|
+
}) {
|
|
6729
|
+
const [expanded, setExpanded] = useState(false);
|
|
6730
|
+
const chipClass = (active) => cn(
|
|
6731
|
+
"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",
|
|
6732
|
+
active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6733
|
+
);
|
|
6734
|
+
return /* @__PURE__ */ jsxs(
|
|
6735
|
+
"div",
|
|
6736
|
+
{
|
|
6737
|
+
className: "flex min-w-0 items-center gap-2",
|
|
6738
|
+
role: "group",
|
|
6739
|
+
"aria-label": "Focus the assistant on one product",
|
|
6740
|
+
children: [
|
|
6741
|
+
/* @__PURE__ */ jsxs(
|
|
6742
|
+
"div",
|
|
6743
|
+
{
|
|
6744
|
+
className: cn(
|
|
6745
|
+
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
6746
|
+
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
6747
|
+
),
|
|
6748
|
+
children: [
|
|
6749
|
+
/* @__PURE__ */ jsx(
|
|
6750
|
+
"button",
|
|
6751
|
+
{
|
|
6752
|
+
"data-boff-explore": "chip",
|
|
6753
|
+
"data-chip-kind": "product",
|
|
6754
|
+
"data-product": "all",
|
|
6755
|
+
type: "button",
|
|
6756
|
+
"aria-pressed": focusProduct === null,
|
|
6757
|
+
onClick: () => onFocus(null),
|
|
6758
|
+
className: chipClass(focusProduct === null),
|
|
6759
|
+
children: "All products"
|
|
6760
|
+
}
|
|
6761
|
+
),
|
|
6762
|
+
products.map((product) => /* @__PURE__ */ jsx(
|
|
6763
|
+
"button",
|
|
6764
|
+
{
|
|
6765
|
+
"data-boff-explore": "chip",
|
|
6766
|
+
"data-chip-kind": "product",
|
|
6767
|
+
"data-product": product.slug,
|
|
6768
|
+
type: "button",
|
|
6769
|
+
"aria-pressed": focusProduct === product.slug,
|
|
6770
|
+
title: product.tagline ?? product.name,
|
|
6771
|
+
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6772
|
+
className: chipClass(focusProduct === product.slug),
|
|
6773
|
+
children: product.name
|
|
6774
|
+
},
|
|
6775
|
+
product.slug
|
|
6776
|
+
))
|
|
6777
|
+
]
|
|
6778
|
+
}
|
|
6779
|
+
),
|
|
6780
|
+
products.length > 0 ? /* @__PURE__ */ jsx(
|
|
6781
|
+
"button",
|
|
6782
|
+
{
|
|
6783
|
+
type: "button",
|
|
6784
|
+
"data-boff-explore": "products-toggle",
|
|
6785
|
+
"aria-expanded": expanded,
|
|
6786
|
+
onClick: () => setExpanded((v) => !v),
|
|
6787
|
+
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",
|
|
6788
|
+
children: expanded ? "Show less" : `All ${products.length}`
|
|
6789
|
+
}
|
|
6790
|
+
) : null
|
|
6791
|
+
]
|
|
6792
|
+
}
|
|
6793
|
+
);
|
|
6794
|
+
}
|
|
6795
|
+
function DisclaimerDialog({
|
|
6796
|
+
open,
|
|
6797
|
+
onClose,
|
|
6798
|
+
captchaOn
|
|
6799
|
+
}) {
|
|
6800
|
+
const panelRef = useRef(null);
|
|
6801
|
+
const closeRef = useRef(null);
|
|
6802
|
+
const titleId = "boff-explore-disclaimer-title";
|
|
6803
|
+
useEffect(() => {
|
|
6804
|
+
if (!open) return;
|
|
6805
|
+
const opener = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
6806
|
+
const focusable = () => Array.from(
|
|
6807
|
+
panelRef.current?.querySelectorAll(
|
|
6808
|
+
'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])'
|
|
6809
|
+
) ?? []
|
|
6810
|
+
);
|
|
6811
|
+
const onKey = (event) => {
|
|
6812
|
+
if (event.key === "Escape") {
|
|
6813
|
+
onClose();
|
|
6814
|
+
return;
|
|
6815
|
+
}
|
|
6816
|
+
if (event.key !== "Tab") return;
|
|
6817
|
+
const items = focusable();
|
|
6818
|
+
if (items.length === 0) return;
|
|
6819
|
+
const first = items[0];
|
|
6820
|
+
const last = items[items.length - 1];
|
|
6821
|
+
const active = document.activeElement;
|
|
6822
|
+
if (event.shiftKey && (active === first || !panelRef.current?.contains(active))) {
|
|
6823
|
+
event.preventDefault();
|
|
6824
|
+
last?.focus();
|
|
6825
|
+
} else if (!event.shiftKey && active === last) {
|
|
6826
|
+
event.preventDefault();
|
|
6827
|
+
first?.focus();
|
|
6828
|
+
}
|
|
6829
|
+
};
|
|
6830
|
+
document.addEventListener("keydown", onKey);
|
|
6831
|
+
closeRef.current?.focus();
|
|
6832
|
+
return () => {
|
|
6833
|
+
document.removeEventListener("keydown", onKey);
|
|
6834
|
+
opener?.focus();
|
|
6835
|
+
};
|
|
6836
|
+
}, [open, onClose]);
|
|
6837
|
+
if (!open) return null;
|
|
6838
|
+
return /* @__PURE__ */ jsx(
|
|
6839
|
+
"div",
|
|
6840
|
+
{
|
|
6841
|
+
"data-boff-explore": "disclaimer-dialog",
|
|
6842
|
+
role: "dialog",
|
|
6843
|
+
"aria-modal": "true",
|
|
6844
|
+
"aria-labelledby": titleId,
|
|
6845
|
+
className: "fixed inset-0 z-50 flex items-end justify-center bg-foreground/40 p-4 backdrop-blur-sm sm:items-center",
|
|
6846
|
+
onClick: onClose,
|
|
6847
|
+
children: /* @__PURE__ */ jsxs(
|
|
6848
|
+
"div",
|
|
6849
|
+
{
|
|
6850
|
+
ref: panelRef,
|
|
6851
|
+
className: "w-full max-w-md rounded-2xl border border-border bg-card p-5 shadow-xl",
|
|
6852
|
+
onClick: (event) => event.stopPropagation(),
|
|
6853
|
+
children: [
|
|
6854
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
6855
|
+
/* @__PURE__ */ jsx(
|
|
6856
|
+
"span",
|
|
6857
|
+
{
|
|
6858
|
+
"aria-hidden": "true",
|
|
6859
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary",
|
|
6860
|
+
children: /* @__PURE__ */ jsx(TriangleAlert, { className: "h-4 w-4" })
|
|
6861
|
+
}
|
|
6862
|
+
),
|
|
6863
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
6864
|
+
/* @__PURE__ */ jsx(
|
|
6865
|
+
"p",
|
|
6866
|
+
{
|
|
6867
|
+
id: titleId,
|
|
6868
|
+
className: "text-sm font-semibold text-card-foreground",
|
|
6869
|
+
children: "How this assistant works"
|
|
6870
|
+
}
|
|
6871
|
+
),
|
|
6872
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-2 text-xs leading-relaxed text-muted-foreground", children: [
|
|
6873
|
+
/* @__PURE__ */ jsx("p", { children: "Answers are generated from our public documentation and can be imperfect \u2014 check anything important against the linked sources." }),
|
|
6874
|
+
/* @__PURE__ */ 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." }),
|
|
6875
|
+
captchaOn ? /* @__PURE__ */ jsx("p", { children: "Protected by reCAPTCHA \u2014 the Google Privacy Policy and Terms of Service apply." }) : null
|
|
6876
|
+
] })
|
|
6877
|
+
] })
|
|
6878
|
+
] }),
|
|
6879
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-end", children: /* @__PURE__ */ jsx(
|
|
6880
|
+
Button,
|
|
6881
|
+
{
|
|
6882
|
+
ref: closeRef,
|
|
6883
|
+
size: "sm",
|
|
6884
|
+
variant: "secondary",
|
|
6885
|
+
onClick: onClose,
|
|
6886
|
+
children: "Got it"
|
|
6887
|
+
}
|
|
6888
|
+
) })
|
|
6889
|
+
]
|
|
6890
|
+
}
|
|
6891
|
+
)
|
|
6892
|
+
}
|
|
6893
|
+
);
|
|
6894
|
+
}
|
|
6464
6895
|
function WelcomeState({
|
|
6465
6896
|
title,
|
|
6466
6897
|
body,
|
|
@@ -6471,21 +6902,19 @@ function WelcomeState({
|
|
|
6471
6902
|
onFocus,
|
|
6472
6903
|
disabled
|
|
6473
6904
|
}) {
|
|
6474
|
-
|
|
6475
|
-
const visibleProducts = showAllProducts ? products : products.slice(0, PRODUCT_CHIP_PREVIEW);
|
|
6476
|
-
return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-3xl px-4 py-10 sm:py-14", children: [
|
|
6905
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-3xl px-4 py-8 sm:py-12", children: [
|
|
6477
6906
|
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
6478
6907
|
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1 text-xs font-medium text-muted-foreground", children: [
|
|
6479
6908
|
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" }),
|
|
6480
6909
|
"AI answers, grounded in our documentation"
|
|
6481
6910
|
] }),
|
|
6482
|
-
/* @__PURE__ */ jsx("h1", { className: "mt-
|
|
6483
|
-
/* @__PURE__ */ jsx("p", { className: "mx-auto mt-
|
|
6911
|
+
/* @__PURE__ */ jsx("h1", { className: "mt-4 text-balance break-words text-2xl font-bold tracking-tight sm:text-4xl", children: title }),
|
|
6912
|
+
/* @__PURE__ */ jsx("p", { className: "mx-auto mt-2.5 max-w-2xl text-pretty text-sm leading-relaxed text-muted-foreground sm:text-lg", children: body })
|
|
6484
6913
|
] }),
|
|
6485
|
-
/* @__PURE__ */ jsx("ul", { className: "mt-
|
|
6914
|
+
/* @__PURE__ */ jsx("ul", { className: "mt-7 grid gap-2.5 sm:grid-cols-3", children: CAPABILITIES.map(({ icon: Icon, title: capTitle, body: capBody }) => /* @__PURE__ */ jsxs(
|
|
6486
6915
|
"li",
|
|
6487
6916
|
{
|
|
6488
|
-
className: "rounded-xl border border-border bg-card p-
|
|
6917
|
+
className: "rounded-xl border border-border/70 bg-card/60 p-3.5 text-left transition-colors hover:border-border",
|
|
6489
6918
|
children: [
|
|
6490
6919
|
/* @__PURE__ */ jsx("span", { className: "mb-2.5 flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" }) }),
|
|
6491
6920
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-card-foreground", children: capTitle }),
|
|
@@ -6494,72 +6923,27 @@ function WelcomeState({
|
|
|
6494
6923
|
},
|
|
6495
6924
|
capTitle
|
|
6496
6925
|
)) }),
|
|
6497
|
-
prompts.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-
|
|
6498
|
-
/* @__PURE__ */ jsx("p", { className: "mb-2
|
|
6499
|
-
/* @__PURE__ */ jsx(
|
|
6500
|
-
|
|
6926
|
+
prompts.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-8", children: [
|
|
6927
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Try asking" }),
|
|
6928
|
+
/* @__PURE__ */ jsx(
|
|
6929
|
+
PromptCarousel,
|
|
6501
6930
|
{
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
className: "group inline-flex max-w-full items-center gap-1.5 rounded-full border border-border bg-card px-3.5 py-1.5 text-left text-sm text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6508
|
-
children: [
|
|
6509
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: prompt }),
|
|
6510
|
-
/* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6511
|
-
]
|
|
6512
|
-
},
|
|
6513
|
-
prompt
|
|
6514
|
-
)) })
|
|
6931
|
+
prompts,
|
|
6932
|
+
onPrompt,
|
|
6933
|
+
disabled
|
|
6934
|
+
}
|
|
6935
|
+
)
|
|
6515
6936
|
] }) : null,
|
|
6516
|
-
products.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-
|
|
6517
|
-
/* @__PURE__ */ jsx("p", { className: "mb-2
|
|
6518
|
-
/* @__PURE__ */
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
"aria-pressed": focusProduct === null,
|
|
6527
|
-
onClick: () => onFocus(null),
|
|
6528
|
-
className: cn(
|
|
6529
|
-
"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",
|
|
6530
|
-
focusProduct === null ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6531
|
-
),
|
|
6532
|
-
children: "All products"
|
|
6533
|
-
}
|
|
6534
|
-
),
|
|
6535
|
-
visibleProducts.map((product) => /* @__PURE__ */ jsx(
|
|
6536
|
-
"button",
|
|
6537
|
-
{
|
|
6538
|
-
"data-boff-explore": "chip",
|
|
6539
|
-
"data-chip-kind": "product",
|
|
6540
|
-
"data-product": product.slug,
|
|
6541
|
-
type: "button",
|
|
6542
|
-
"aria-pressed": focusProduct === product.slug,
|
|
6543
|
-
title: product.tagline ?? product.name,
|
|
6544
|
-
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6545
|
-
className: cn(
|
|
6546
|
-
"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",
|
|
6547
|
-
focusProduct === product.slug ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6548
|
-
),
|
|
6549
|
-
children: product.name
|
|
6550
|
-
},
|
|
6551
|
-
product.slug
|
|
6552
|
-
)),
|
|
6553
|
-
products.length > PRODUCT_CHIP_PREVIEW ? /* @__PURE__ */ jsx(
|
|
6554
|
-
"button",
|
|
6555
|
-
{
|
|
6556
|
-
type: "button",
|
|
6557
|
-
onClick: () => setShowAllProducts((v) => !v),
|
|
6558
|
-
className: "rounded-full px-3 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",
|
|
6559
|
-
children: showAllProducts ? "Show fewer" : `Show all ${products.length}`
|
|
6560
|
-
}
|
|
6561
|
-
) : null
|
|
6562
|
-
] })
|
|
6937
|
+
products.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-6", children: [
|
|
6938
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Focus on a product" }),
|
|
6939
|
+
/* @__PURE__ */ jsx(
|
|
6940
|
+
ProductStrip,
|
|
6941
|
+
{
|
|
6942
|
+
products,
|
|
6943
|
+
focusProduct,
|
|
6944
|
+
onFocus
|
|
6945
|
+
}
|
|
6946
|
+
)
|
|
6563
6947
|
] }) : null
|
|
6564
6948
|
] });
|
|
6565
6949
|
}
|
|
@@ -6596,7 +6980,8 @@ function ExplorePage({
|
|
|
6596
6980
|
history,
|
|
6597
6981
|
openConversation,
|
|
6598
6982
|
deleteConversation,
|
|
6599
|
-
clearHistory
|
|
6983
|
+
clearHistory,
|
|
6984
|
+
recordClick
|
|
6600
6985
|
} = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
|
|
6601
6986
|
const [draft, setDraft] = useState("");
|
|
6602
6987
|
const textareaRef = useRef(null);
|
|
@@ -6615,6 +7000,7 @@ function ExplorePage({
|
|
|
6615
7000
|
}
|
|
6616
7001
|
});
|
|
6617
7002
|
speechStopRef.current = speech.stop;
|
|
7003
|
+
const [disclaimerOpen, setDisclaimerOpen] = useState(false);
|
|
6618
7004
|
const scrollRef = useRef(null);
|
|
6619
7005
|
const latestAssistantRef = useRef(null);
|
|
6620
7006
|
const alignedForRef = useRef(null);
|
|
@@ -6707,7 +7093,7 @@ function ExplorePage({
|
|
|
6707
7093
|
"data-boff-explore": "page",
|
|
6708
7094
|
"data-phase": phase,
|
|
6709
7095
|
className: cn(
|
|
6710
|
-
"flex w-full flex-col bg-background text-foreground",
|
|
7096
|
+
"flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground",
|
|
6711
7097
|
heightMode === "auto" && "min-h-[70vh]",
|
|
6712
7098
|
className
|
|
6713
7099
|
),
|
|
@@ -6849,7 +7235,7 @@ function ExplorePage({
|
|
|
6849
7235
|
role: "log",
|
|
6850
7236
|
"aria-live": "polite",
|
|
6851
7237
|
"aria-label": "Explore conversation",
|
|
6852
|
-
className: "boff-explore-scroll min-h-0 flex-1 overflow-y-auto",
|
|
7238
|
+
className: "boff-explore-scroll min-h-0 min-w-0 flex-1 overflow-y-auto overflow-x-hidden",
|
|
6853
7239
|
children: showWelcome ? /* @__PURE__ */ jsx(
|
|
6854
7240
|
WelcomeState,
|
|
6855
7241
|
{
|
|
@@ -6862,21 +7248,31 @@ function ExplorePage({
|
|
|
6862
7248
|
onFocus: setFocusProduct,
|
|
6863
7249
|
disabled: !canSend || busy
|
|
6864
7250
|
}
|
|
6865
|
-
) : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
7251
|
+
) : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
6866
7252
|
(message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { message }, message.id) : /* @__PURE__ */ jsx(
|
|
6867
7253
|
AssistantBubble,
|
|
6868
7254
|
{
|
|
6869
7255
|
message,
|
|
6870
7256
|
activity,
|
|
6871
7257
|
onNavigate,
|
|
6872
|
-
anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0
|
|
7258
|
+
anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0,
|
|
7259
|
+
onFollow: (kind, url) => recordClick(message.id, kind, url),
|
|
7260
|
+
onFollowUp: sendPrompt
|
|
6873
7261
|
},
|
|
6874
7262
|
message.id
|
|
6875
7263
|
)
|
|
6876
7264
|
) })
|
|
6877
7265
|
}
|
|
6878
7266
|
),
|
|
6879
|
-
/* @__PURE__ */ jsx(
|
|
7267
|
+
/* @__PURE__ */ jsx(
|
|
7268
|
+
DisclaimerDialog,
|
|
7269
|
+
{
|
|
7270
|
+
open: disclaimerOpen,
|
|
7271
|
+
onClose: () => setDisclaimerOpen(false),
|
|
7272
|
+
captchaOn
|
|
7273
|
+
}
|
|
7274
|
+
),
|
|
7275
|
+
/* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md", children: /* @__PURE__ */ jsxs(
|
|
6880
7276
|
"form",
|
|
6881
7277
|
{
|
|
6882
7278
|
"data-boff-explore": "composer",
|
|
@@ -6891,7 +7287,7 @@ function ExplorePage({
|
|
|
6891
7287
|
"div",
|
|
6892
7288
|
{
|
|
6893
7289
|
className: cn(
|
|
6894
|
-
"flex items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-
|
|
7290
|
+
"flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all",
|
|
6895
7291
|
overLimit ? "border-destructive/60" : "border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring"
|
|
6896
7292
|
),
|
|
6897
7293
|
children: [
|
|
@@ -6912,7 +7308,7 @@ function ExplorePage({
|
|
|
6912
7308
|
},
|
|
6913
7309
|
"aria-label": "Ask a question",
|
|
6914
7310
|
placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? `Ask about ${focusedProductName}\u2026` : "Ask anything about our products\u2026",
|
|
6915
|
-
className: "max-h-[200px] min-h-[44px] flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm"
|
|
7311
|
+
className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm"
|
|
6916
7312
|
}
|
|
6917
7313
|
),
|
|
6918
7314
|
speech.supported ? /* @__PURE__ */ jsx(
|
|
@@ -7003,48 +7399,19 @@ function ExplorePage({
|
|
|
7003
7399
|
}
|
|
7004
7400
|
)
|
|
7005
7401
|
] }),
|
|
7006
|
-
/* @__PURE__ */ jsxs(
|
|
7007
|
-
"
|
|
7008
|
-
|
|
7009
|
-
"
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
"
|
|
7013
|
-
|
|
7014
|
-
"
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
/* @__PURE__ */ jsx(
|
|
7020
|
-
"a",
|
|
7021
|
-
{
|
|
7022
|
-
href: "https://policies.google.com/privacy",
|
|
7023
|
-
target: "_blank",
|
|
7024
|
-
rel: "noopener noreferrer",
|
|
7025
|
-
className: "underline underline-offset-2 hover:text-foreground",
|
|
7026
|
-
children: "Privacy Policy"
|
|
7027
|
-
}
|
|
7028
|
-
),
|
|
7029
|
-
" ",
|
|
7030
|
-
"and",
|
|
7031
|
-
" ",
|
|
7032
|
-
/* @__PURE__ */ jsx(
|
|
7033
|
-
"a",
|
|
7034
|
-
{
|
|
7035
|
-
href: "https://policies.google.com/terms",
|
|
7036
|
-
target: "_blank",
|
|
7037
|
-
rel: "noopener noreferrer",
|
|
7038
|
-
className: "underline underline-offset-2 hover:text-foreground",
|
|
7039
|
-
children: "Terms of Service"
|
|
7040
|
-
}
|
|
7041
|
-
),
|
|
7042
|
-
" ",
|
|
7043
|
-
"apply."
|
|
7044
|
-
] }) : null
|
|
7045
|
-
]
|
|
7046
|
-
}
|
|
7047
|
-
)
|
|
7402
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
7403
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: "Grounded in our docs \u2014 check anything important." }),
|
|
7404
|
+
/* @__PURE__ */ jsx(
|
|
7405
|
+
"button",
|
|
7406
|
+
{
|
|
7407
|
+
type: "button",
|
|
7408
|
+
"data-boff-explore": "disclaimer",
|
|
7409
|
+
onClick: () => setDisclaimerOpen(true),
|
|
7410
|
+
className: "shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
7411
|
+
children: "Disclaimer"
|
|
7412
|
+
}
|
|
7413
|
+
)
|
|
7414
|
+
] })
|
|
7048
7415
|
]
|
|
7049
7416
|
}
|
|
7050
7417
|
) })
|