@convai/web-widget 0.1.3 → 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -11
- package/chunks/lightbox-Dxfdw3VU.js +683 -0
- package/index.d.ts +26 -0
- package/index.js +4 -0
- package/package.json +53 -2
- package/react.d.ts +23 -0
- package/react.js +3551 -0
- package/runtime.js +12023 -12685
- package/types.d.ts +62 -0
- package/ui/react/components/ConvaiWidget.d.ts +86 -0
- package/ui/react/components/index.d.ts +1 -0
- package/ui/react/components/rtc-widget/components/AudioSettingsPanel.d.ts +9 -0
- package/ui/react/components/rtc-widget/components/AudioVisualizer.d.ts +35 -0
- package/ui/react/components/rtc-widget/components/ConviMessage.d.ts +13 -0
- package/ui/react/components/rtc-widget/components/FloatingVideo.d.ts +8 -0
- package/ui/react/components/rtc-widget/components/MarkdownRenderer.d.ts +31 -0
- package/ui/react/components/rtc-widget/components/MessageBubble.d.ts +9 -0
- package/ui/react/components/rtc-widget/components/MessageList.d.ts +14 -0
- package/ui/react/components/rtc-widget/components/SiteCard.d.ts +15 -0
- package/ui/react/components/rtc-widget/components/UserMessage.d.ts +9 -0
- package/ui/react/components/rtc-widget/components/conviComponents/ConviButton.d.ts +6 -0
- package/ui/react/components/rtc-widget/components/conviComponents/ConviFooter.d.ts +24 -0
- package/ui/react/components/rtc-widget/components/conviComponents/ConviHeader.d.ts +16 -0
- package/ui/react/components/rtc-widget/components/conviComponents/SettingsTray.d.ts +12 -0
- package/ui/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts +14 -0
- package/ui/react/components/rtc-widget/components/conviComponents/index.d.ts +5 -0
- package/ui/react/components/rtc-widget/components/index.d.ts +8 -0
- package/ui/react/components/rtc-widget/index.d.ts +5 -0
- package/ui/react/components/rtc-widget/styles/framerConfig.d.ts +115 -0
- package/ui/react/components/rtc-widget/styles/icons.d.ts +27 -0
- package/ui/react/components/rtc-widget/styles/index.d.ts +5 -0
- package/ui/react/components/rtc-widget/styles/styledComponents.d.ts +53 -0
- package/ui/react/components/rtc-widget/styles/theme.d.ts +187 -0
- package/ui/react/components/rtc-widget/types/index.d.ts +59 -0
- package/ui/react/hooks/useCharacterInfo.d.ts +18 -0
- package/ui/react/hooks/useLocalCameraTrack.d.ts +21 -0
- package/ui/react/icons.d.ts +37 -0
- package/ui/shared/lightbox.d.ts +15 -0
- package/ui/shared/linkStyles.d.ts +64 -0
- package/ui/shared/logger.d.ts +30 -0
- package/ui/vanilla/ConvaiWidget.d.ts +46 -0
- package/ui/vanilla/WidgetEventSubscriptions.d.ts +14 -0
- package/ui/vanilla/icons.d.ts +34 -0
- package/ui/vanilla/styles.d.ts +168 -0
- package/ui/vanilla/types.d.ts +170 -0
- package/v1.js +2 -2
- package/vanilla.d.ts +21 -0
- package/vanilla.js +2512 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
const PREVIEW_TIMEOUT_MS = 12e3;
|
|
2
|
+
const MAX_CARDS_PER_MESSAGE = 6;
|
|
3
|
+
const SVG_OPEN = '<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24" width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">';
|
|
4
|
+
const GLYPH_PATHS = {
|
|
5
|
+
document: '<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/>',
|
|
6
|
+
email: '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/>',
|
|
7
|
+
phone: '<path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.4 1.8.7 2.7a2 2 0 0 1-.5 2.1L8.1 9.7a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.6 2.7.7a2 2 0 0 1 1.8 2z"/>',
|
|
8
|
+
sms: '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
|
|
9
|
+
ftp: '<path d="M4 17V7l8 5 8-5v10"/><path d="M4 7h16"/>',
|
|
10
|
+
zoom: '<circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3M11 8v6M8 11h6"/>',
|
|
11
|
+
close: '<path d="M18 6 6 18M6 6l12 12"/>',
|
|
12
|
+
external: '<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><path d="M15 3h6v6M10 14 21 3"/>'
|
|
13
|
+
};
|
|
14
|
+
function glyph(name) {
|
|
15
|
+
return `${SVG_OPEN}${GLYPH_PATHS[name]}</svg>`;
|
|
16
|
+
}
|
|
17
|
+
const UNITLESS = /* @__PURE__ */ new Set([
|
|
18
|
+
"opacity",
|
|
19
|
+
"zIndex",
|
|
20
|
+
"flex",
|
|
21
|
+
"flexGrow",
|
|
22
|
+
"flexShrink",
|
|
23
|
+
"lineHeight",
|
|
24
|
+
"fontWeight",
|
|
25
|
+
"order",
|
|
26
|
+
"WebkitLineClamp"
|
|
27
|
+
]);
|
|
28
|
+
function toCssText(style) {
|
|
29
|
+
return Object.entries(style).map(([k, v]) => {
|
|
30
|
+
const prop = k.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
31
|
+
const val = typeof v === "number" && !UNITLESS.has(k) ? `${v}px` : String(v);
|
|
32
|
+
return `${prop}: ${val};`;
|
|
33
|
+
}).join(" ");
|
|
34
|
+
}
|
|
35
|
+
const RADIUS = 8;
|
|
36
|
+
const ACCENT = "#10b981";
|
|
37
|
+
const chrome = (pct) => `color-mix(in srgb, currentColor ${pct}%, transparent)`;
|
|
38
|
+
const presentationStyles = {
|
|
39
|
+
link: {
|
|
40
|
+
color: ACCENT,
|
|
41
|
+
textDecoration: "underline",
|
|
42
|
+
wordBreak: "break-all",
|
|
43
|
+
borderRadius: 2
|
|
44
|
+
},
|
|
45
|
+
/** Applied on focus-visible by the renderer; kept here so both agree. */
|
|
46
|
+
linkFocus: { outline: `2px solid ${chrome(60)}`, outlineOffset: 2 },
|
|
47
|
+
blocked: { opacity: 0.75, textDecoration: "underline dotted", cursor: "help" },
|
|
48
|
+
card: {
|
|
49
|
+
display: "block",
|
|
50
|
+
position: "relative",
|
|
51
|
+
marginTop: 6,
|
|
52
|
+
maxWidth: 320,
|
|
53
|
+
aspectRatio: "16 / 10",
|
|
54
|
+
borderRadius: RADIUS,
|
|
55
|
+
overflow: "hidden",
|
|
56
|
+
background: chrome(6),
|
|
57
|
+
boxShadow: `inset 0 0 0 1px ${chrome(10)}`
|
|
58
|
+
},
|
|
59
|
+
cardButton: { cursor: "zoom-in" },
|
|
60
|
+
zoom: {
|
|
61
|
+
position: "absolute",
|
|
62
|
+
right: 6,
|
|
63
|
+
bottom: 6,
|
|
64
|
+
width: 24,
|
|
65
|
+
height: 24,
|
|
66
|
+
display: "flex",
|
|
67
|
+
alignItems: "center",
|
|
68
|
+
justifyContent: "center",
|
|
69
|
+
borderRadius: 6,
|
|
70
|
+
background: "rgba(0,0,0,.55)",
|
|
71
|
+
color: "#fff",
|
|
72
|
+
fontSize: 14,
|
|
73
|
+
pointerEvents: "none"
|
|
74
|
+
},
|
|
75
|
+
media: {
|
|
76
|
+
display: "block",
|
|
77
|
+
width: "100%",
|
|
78
|
+
height: "100%",
|
|
79
|
+
objectFit: "cover",
|
|
80
|
+
borderRadius: RADIUS,
|
|
81
|
+
transition: "opacity .18s ease"
|
|
82
|
+
},
|
|
83
|
+
videoMedia: { objectFit: "contain" },
|
|
84
|
+
skeleton: {
|
|
85
|
+
position: "absolute",
|
|
86
|
+
inset: 0,
|
|
87
|
+
borderRadius: RADIUS,
|
|
88
|
+
background: chrome(8),
|
|
89
|
+
backgroundImage: `linear-gradient(90deg, transparent, ${chrome(12)}, transparent)`,
|
|
90
|
+
backgroundSize: "200% 100%",
|
|
91
|
+
animation: "convai-preview-shimmer 1.4s ease-in-out infinite"
|
|
92
|
+
},
|
|
93
|
+
caption: {
|
|
94
|
+
display: "block",
|
|
95
|
+
marginTop: 4,
|
|
96
|
+
fontSize: 11,
|
|
97
|
+
opacity: 0.7,
|
|
98
|
+
whiteSpace: "nowrap",
|
|
99
|
+
overflow: "hidden",
|
|
100
|
+
textOverflow: "ellipsis"
|
|
101
|
+
},
|
|
102
|
+
unavailable: {
|
|
103
|
+
display: "block",
|
|
104
|
+
marginTop: 6,
|
|
105
|
+
fontSize: 11,
|
|
106
|
+
opacity: 0.55,
|
|
107
|
+
fontStyle: "italic",
|
|
108
|
+
whiteSpace: "nowrap",
|
|
109
|
+
overflow: "hidden",
|
|
110
|
+
textOverflow: "ellipsis"
|
|
111
|
+
},
|
|
112
|
+
fileCard: {
|
|
113
|
+
display: "flex",
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
gap: 10,
|
|
116
|
+
marginTop: 6,
|
|
117
|
+
maxWidth: 320,
|
|
118
|
+
padding: "8px 10px",
|
|
119
|
+
borderRadius: RADIUS,
|
|
120
|
+
background: chrome(6),
|
|
121
|
+
boxShadow: `inset 0 0 0 1px ${chrome(10)}`,
|
|
122
|
+
color: "inherit",
|
|
123
|
+
textDecoration: "none"
|
|
124
|
+
},
|
|
125
|
+
fileIcon: {
|
|
126
|
+
position: "relative",
|
|
127
|
+
flex: "0 0 auto",
|
|
128
|
+
width: 36,
|
|
129
|
+
height: 44,
|
|
130
|
+
display: "flex",
|
|
131
|
+
alignItems: "flex-end",
|
|
132
|
+
justifyContent: "center",
|
|
133
|
+
paddingBottom: 4,
|
|
134
|
+
boxSizing: "border-box",
|
|
135
|
+
borderRadius: 4,
|
|
136
|
+
background: chrome(10),
|
|
137
|
+
color: ACCENT,
|
|
138
|
+
fontSize: 9,
|
|
139
|
+
fontWeight: 700,
|
|
140
|
+
letterSpacing: ".04em"
|
|
141
|
+
},
|
|
142
|
+
fileBody: { minWidth: 0, display: "flex", flexDirection: "column", gap: 2 },
|
|
143
|
+
fileName: {
|
|
144
|
+
fontSize: 13,
|
|
145
|
+
fontWeight: 600,
|
|
146
|
+
whiteSpace: "nowrap",
|
|
147
|
+
overflow: "hidden",
|
|
148
|
+
textOverflow: "ellipsis"
|
|
149
|
+
},
|
|
150
|
+
fileMeta: {
|
|
151
|
+
fontSize: 11,
|
|
152
|
+
opacity: 0.7,
|
|
153
|
+
whiteSpace: "nowrap",
|
|
154
|
+
overflow: "hidden",
|
|
155
|
+
textOverflow: "ellipsis"
|
|
156
|
+
},
|
|
157
|
+
contact: {
|
|
158
|
+
display: "inline-flex",
|
|
159
|
+
alignItems: "center",
|
|
160
|
+
gap: 4,
|
|
161
|
+
padding: "1px 8px 1px 6px",
|
|
162
|
+
borderRadius: 999,
|
|
163
|
+
background: chrome(8),
|
|
164
|
+
color: ACCENT,
|
|
165
|
+
textDecoration: "none",
|
|
166
|
+
fontSize: "0.95em",
|
|
167
|
+
lineHeight: 1.6,
|
|
168
|
+
verticalAlign: "baseline",
|
|
169
|
+
maxWidth: "100%"
|
|
170
|
+
},
|
|
171
|
+
contactGlyph: { display: "inline-flex", fontSize: 13, opacity: 0.9 },
|
|
172
|
+
badge: {
|
|
173
|
+
display: "inline-block",
|
|
174
|
+
marginLeft: 4,
|
|
175
|
+
padding: "0 4px",
|
|
176
|
+
borderRadius: 3,
|
|
177
|
+
fontSize: 9,
|
|
178
|
+
fontWeight: 700,
|
|
179
|
+
letterSpacing: ".04em",
|
|
180
|
+
verticalAlign: "middle",
|
|
181
|
+
background: chrome(10),
|
|
182
|
+
opacity: 0.8
|
|
183
|
+
},
|
|
184
|
+
lightboxBackdrop: {
|
|
185
|
+
position: "fixed",
|
|
186
|
+
inset: 0,
|
|
187
|
+
zIndex: 2147483e3,
|
|
188
|
+
display: "flex",
|
|
189
|
+
alignItems: "center",
|
|
190
|
+
justifyContent: "center",
|
|
191
|
+
background: "rgba(0,0,0,.82)",
|
|
192
|
+
padding: 24,
|
|
193
|
+
boxSizing: "border-box",
|
|
194
|
+
animation: "convai-lightbox-in .16s ease-out"
|
|
195
|
+
},
|
|
196
|
+
lightbox: {
|
|
197
|
+
position: "relative",
|
|
198
|
+
display: "flex",
|
|
199
|
+
flexDirection: "column",
|
|
200
|
+
alignItems: "center",
|
|
201
|
+
gap: 10,
|
|
202
|
+
maxWidth: "90vw",
|
|
203
|
+
maxHeight: "90vh",
|
|
204
|
+
color: "#fff"
|
|
205
|
+
},
|
|
206
|
+
lightboxImage: {
|
|
207
|
+
display: "block",
|
|
208
|
+
maxWidth: "90vw",
|
|
209
|
+
maxHeight: "calc(90vh - 72px)",
|
|
210
|
+
objectFit: "contain",
|
|
211
|
+
borderRadius: RADIUS,
|
|
212
|
+
background: "#000"
|
|
213
|
+
},
|
|
214
|
+
lightboxCaption: {
|
|
215
|
+
fontSize: 12,
|
|
216
|
+
opacity: 0.8,
|
|
217
|
+
maxWidth: "90vw",
|
|
218
|
+
whiteSpace: "nowrap",
|
|
219
|
+
overflow: "hidden",
|
|
220
|
+
textOverflow: "ellipsis"
|
|
221
|
+
},
|
|
222
|
+
lightboxControls: {
|
|
223
|
+
position: "absolute",
|
|
224
|
+
top: -4,
|
|
225
|
+
right: -4,
|
|
226
|
+
transform: "translateY(-100%)",
|
|
227
|
+
display: "flex",
|
|
228
|
+
gap: 6
|
|
229
|
+
},
|
|
230
|
+
lightboxButton: {
|
|
231
|
+
display: "inline-flex",
|
|
232
|
+
alignItems: "center",
|
|
233
|
+
gap: 6,
|
|
234
|
+
padding: "6px 10px",
|
|
235
|
+
borderRadius: 999,
|
|
236
|
+
border: "1px solid rgba(255,255,255,.25)",
|
|
237
|
+
background: "rgba(0,0,0,.5)",
|
|
238
|
+
color: "#fff",
|
|
239
|
+
fontSize: 12,
|
|
240
|
+
cursor: "pointer",
|
|
241
|
+
textDecoration: "none"
|
|
242
|
+
},
|
|
243
|
+
lightboxFallback: {
|
|
244
|
+
padding: "32px 40px",
|
|
245
|
+
fontSize: 13,
|
|
246
|
+
opacity: 0.8,
|
|
247
|
+
border: "1px dashed rgba(255,255,255,.3)",
|
|
248
|
+
borderRadius: RADIUS
|
|
249
|
+
},
|
|
250
|
+
// Site card: Open Graph metadata under a plain web link. Same chrome as the
|
|
251
|
+
// file card so the three card kinds read as one family.
|
|
252
|
+
siteCard: {
|
|
253
|
+
display: "block",
|
|
254
|
+
marginTop: 6,
|
|
255
|
+
maxWidth: 320,
|
|
256
|
+
padding: "8px 10px",
|
|
257
|
+
borderRadius: RADIUS,
|
|
258
|
+
background: chrome(6),
|
|
259
|
+
boxShadow: `inset 0 0 0 1px ${chrome(10)}`,
|
|
260
|
+
color: "inherit",
|
|
261
|
+
textDecoration: "none"
|
|
262
|
+
},
|
|
263
|
+
siteHeader: { display: "flex", alignItems: "center", gap: 6, minWidth: 0 },
|
|
264
|
+
siteFavicon: {
|
|
265
|
+
width: 16,
|
|
266
|
+
height: 16,
|
|
267
|
+
flex: "0 0 auto",
|
|
268
|
+
borderRadius: 3,
|
|
269
|
+
objectFit: "contain"
|
|
270
|
+
},
|
|
271
|
+
siteName: {
|
|
272
|
+
fontSize: 12,
|
|
273
|
+
fontWeight: 700,
|
|
274
|
+
whiteSpace: "nowrap",
|
|
275
|
+
overflow: "hidden",
|
|
276
|
+
textOverflow: "ellipsis"
|
|
277
|
+
},
|
|
278
|
+
siteTitle: {
|
|
279
|
+
display: "block",
|
|
280
|
+
marginTop: 2,
|
|
281
|
+
fontSize: 13,
|
|
282
|
+
fontWeight: 600,
|
|
283
|
+
color: ACCENT,
|
|
284
|
+
whiteSpace: "nowrap",
|
|
285
|
+
overflow: "hidden",
|
|
286
|
+
textOverflow: "ellipsis"
|
|
287
|
+
},
|
|
288
|
+
siteDescription: {
|
|
289
|
+
display: "-webkit-box",
|
|
290
|
+
WebkitBoxOrient: "vertical",
|
|
291
|
+
WebkitLineClamp: 2,
|
|
292
|
+
overflow: "hidden",
|
|
293
|
+
marginTop: 2,
|
|
294
|
+
fontSize: 12,
|
|
295
|
+
opacity: 0.75,
|
|
296
|
+
lineHeight: 1.35
|
|
297
|
+
},
|
|
298
|
+
siteImage: {
|
|
299
|
+
display: "block",
|
|
300
|
+
width: "100%",
|
|
301
|
+
aspectRatio: "16 / 9",
|
|
302
|
+
objectFit: "cover",
|
|
303
|
+
marginTop: 8,
|
|
304
|
+
borderRadius: 6
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
const aeroTheme = {
|
|
308
|
+
colors: {
|
|
309
|
+
convai: {
|
|
310
|
+
light: "#1EB453",
|
|
311
|
+
dark: "#084c3a"
|
|
312
|
+
},
|
|
313
|
+
neutral: {
|
|
314
|
+
100: "#f5f5f5",
|
|
315
|
+
200: "#e5e5e5",
|
|
316
|
+
300: "#d4d4d4",
|
|
317
|
+
400: "#a3a3a3",
|
|
318
|
+
700: "#404040"
|
|
319
|
+
},
|
|
320
|
+
glass: {
|
|
321
|
+
medium: "rgba(255, 255, 255, 0.15)",
|
|
322
|
+
backdrop: "rgba(255, 255, 255, 0.8)"
|
|
323
|
+
},
|
|
324
|
+
error: {
|
|
325
|
+
500: "#ef4444"
|
|
326
|
+
},
|
|
327
|
+
text: {
|
|
328
|
+
primary: "#1f2937",
|
|
329
|
+
secondary: "#6b7280"
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
typography: {
|
|
333
|
+
fontFamily: {
|
|
334
|
+
primary: '"Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
335
|
+
body: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
336
|
+
},
|
|
337
|
+
fontSize: {
|
|
338
|
+
sm: "14px",
|
|
339
|
+
base: "16px"
|
|
340
|
+
},
|
|
341
|
+
fontWeight: {
|
|
342
|
+
semibold: 600
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
spacing: {
|
|
346
|
+
xs: "4px"
|
|
347
|
+
},
|
|
348
|
+
borderRadius: {
|
|
349
|
+
md: "8px",
|
|
350
|
+
lg: "12px",
|
|
351
|
+
xl: "16px",
|
|
352
|
+
full: "9999px"
|
|
353
|
+
},
|
|
354
|
+
shadows: {
|
|
355
|
+
xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
|
|
356
|
+
glass: "0 8px 32px rgba(0, 0, 0, 0.1)"
|
|
357
|
+
},
|
|
358
|
+
glass: {
|
|
359
|
+
backdrop: "blur(20px)",
|
|
360
|
+
border: "1px solid rgba(255, 255, 255, 0.2)"
|
|
361
|
+
},
|
|
362
|
+
transitions: {
|
|
363
|
+
fast: "0.15s ease-in-out"
|
|
364
|
+
},
|
|
365
|
+
zIndex: {
|
|
366
|
+
modal: 1040
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
const getGlobalStyles = () => `
|
|
370
|
+
@keyframes convai-pulse {
|
|
371
|
+
0%, 100% {
|
|
372
|
+
opacity: 1;
|
|
373
|
+
}
|
|
374
|
+
50% {
|
|
375
|
+
opacity: 0.5;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
@keyframes convai-spin {
|
|
380
|
+
from {
|
|
381
|
+
transform: rotate(0deg);
|
|
382
|
+
}
|
|
383
|
+
to {
|
|
384
|
+
transform: rotate(360deg);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
@keyframes convai-bounce {
|
|
389
|
+
0%, 100% {
|
|
390
|
+
transform: translateY(0);
|
|
391
|
+
}
|
|
392
|
+
50% {
|
|
393
|
+
transform: translateY(-10px);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
@keyframes convai-slide-up {
|
|
398
|
+
from {
|
|
399
|
+
transform: translateY(20px);
|
|
400
|
+
opacity: 0;
|
|
401
|
+
}
|
|
402
|
+
to {
|
|
403
|
+
transform: translateY(0);
|
|
404
|
+
opacity: 1;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
@keyframes convai-slide-down {
|
|
409
|
+
from {
|
|
410
|
+
transform: translateY(-20px);
|
|
411
|
+
opacity: 0;
|
|
412
|
+
}
|
|
413
|
+
to {
|
|
414
|
+
transform: translateY(0);
|
|
415
|
+
opacity: 1;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@keyframes convai-fade-in {
|
|
420
|
+
from {
|
|
421
|
+
opacity: 0;
|
|
422
|
+
}
|
|
423
|
+
to {
|
|
424
|
+
opacity: 1;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
@keyframes convai-scale-in {
|
|
429
|
+
from {
|
|
430
|
+
transform: scale(0.8);
|
|
431
|
+
opacity: 0;
|
|
432
|
+
}
|
|
433
|
+
to {
|
|
434
|
+
transform: scale(1);
|
|
435
|
+
opacity: 1;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.convai-widget * {
|
|
440
|
+
box-sizing: border-box;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.convai-widget {
|
|
444
|
+
font-family: var(--convai-font, ${aeroTheme.typography.fontFamily.primary});
|
|
445
|
+
color: var(--convai-panel-fg, ${aeroTheme.colors.text.primary});
|
|
446
|
+
-webkit-font-smoothing: antialiased;
|
|
447
|
+
-moz-osx-font-smoothing: grayscale;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.convai-widget button {
|
|
451
|
+
font-family: inherit;
|
|
452
|
+
cursor: pointer;
|
|
453
|
+
border: none;
|
|
454
|
+
outline: none;
|
|
455
|
+
background: none;
|
|
456
|
+
padding: 0;
|
|
457
|
+
margin: 0;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.convai-widget input {
|
|
461
|
+
font-family: inherit;
|
|
462
|
+
border: none;
|
|
463
|
+
outline: none;
|
|
464
|
+
background: none;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.convai-widget::-webkit-scrollbar {
|
|
468
|
+
width: 6px;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.convai-widget::-webkit-scrollbar-track {
|
|
472
|
+
background: rgba(0, 0, 0, 0.05);
|
|
473
|
+
border-radius: 3px;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.convai-widget::-webkit-scrollbar-thumb {
|
|
477
|
+
background: rgba(0, 0, 0, 0.2);
|
|
478
|
+
border-radius: 3px;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.convai-widget::-webkit-scrollbar-thumb:hover {
|
|
482
|
+
background: rgba(0, 0, 0, 0.3);
|
|
483
|
+
}
|
|
484
|
+
`;
|
|
485
|
+
const WIDGET_STYLES_ID = "convai-widget-styles";
|
|
486
|
+
const WIDGET_KEYFRAMES_ID = "convai-widget-keyframes";
|
|
487
|
+
const styledTargets = /* @__PURE__ */ new WeakSet();
|
|
488
|
+
const keyframedTargets = /* @__PURE__ */ new WeakSet();
|
|
489
|
+
const styleHost = (target) => target instanceof ShadowRoot ? target : target.head;
|
|
490
|
+
const hasStyleNode = (target, id) => styleHost(target).querySelector(`#${id}`) !== null;
|
|
491
|
+
const WIDGET_KEYFRAMES = `
|
|
492
|
+
@keyframes popIn {
|
|
493
|
+
from { opacity: 0; transform: scale(0.95) translateY(-10px); }
|
|
494
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* Link-preview skeleton: one sweep across the placeholder while the media
|
|
498
|
+
* decodes. Lives here rather than in getGlobalStyles() because that string is
|
|
499
|
+
* pinned byte-for-byte by the inline-style parity fixture, and this is an
|
|
500
|
+
* addition no existing element uses. */
|
|
501
|
+
@keyframes convai-preview-shimmer {
|
|
502
|
+
from { background-position: 200% 0; }
|
|
503
|
+
to { background-position: -200% 0; }
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/* Image lightbox entrance. Additive, like the shimmer above. */
|
|
507
|
+
@keyframes convai-lightbox-in {
|
|
508
|
+
from { opacity: 0; transform: scale(.98); }
|
|
509
|
+
to { opacity: 1; transform: scale(1); }
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* Connecting overlay: logo spin + label pulse. Values match the React
|
|
513
|
+
* widget's framer-motion transitions (ConvaiWidget.tsx:681-737) exactly --
|
|
514
|
+
* a full turn every 2s linear, and opacity 0.5 -> 1 -> 0.5 every 2s
|
|
515
|
+
* ease-in-out. React does not honour prefers-reduced-motion; vanilla does,
|
|
516
|
+
* via the media query below, since a full-turn infinite spin plus a
|
|
517
|
+
* pulsing label is exactly what that setting exists for. */
|
|
518
|
+
@keyframes convaiConnectingSpin {
|
|
519
|
+
from { transform: rotate(0deg); }
|
|
520
|
+
to { transform: rotate(360deg); }
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
@keyframes convaiConnectingPulse {
|
|
524
|
+
0%, 100% { opacity: 0.5; }
|
|
525
|
+
50% { opacity: 1; }
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* Voice mode's avatar: two counter-rotating liquid-gradient layers behind
|
|
529
|
+
* the character image. Matches the React overlay's framer-motion values
|
|
530
|
+
* (VoiceModeOverlay.tsx) — 20s clockwise for the conic layer, 15s
|
|
531
|
+
* anticlockwise for the radial one, both linear and infinite — and the
|
|
532
|
+
* gentle scale breathing it applies while the character is speaking. */
|
|
533
|
+
@keyframes convaiVoiceSpin {
|
|
534
|
+
from { transform: rotate(0deg); }
|
|
535
|
+
to { transform: rotate(360deg); }
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
@keyframes convaiVoiceSpinReverse {
|
|
539
|
+
from { transform: rotate(360deg); }
|
|
540
|
+
to { transform: rotate(0deg); }
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
@keyframes convaiVoiceBreathe {
|
|
544
|
+
0%, 100% { transform: scale(1); }
|
|
545
|
+
50% { transform: scale(1.05); }
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
@media (prefers-reduced-motion: reduce) {
|
|
549
|
+
.convai-connecting-spin {
|
|
550
|
+
animation: none !important;
|
|
551
|
+
}
|
|
552
|
+
.convai-connecting-pulse {
|
|
553
|
+
animation: none !important;
|
|
554
|
+
}
|
|
555
|
+
.convai-voice-gradient,
|
|
556
|
+
.convai-voice-avatar {
|
|
557
|
+
animation: none !important;
|
|
558
|
+
}
|
|
559
|
+
[data-convai-skeleton] {
|
|
560
|
+
animation: none !important;
|
|
561
|
+
}
|
|
562
|
+
[part~="lightbox-backdrop"] {
|
|
563
|
+
animation: none !important;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
`;
|
|
567
|
+
const injectGlobalStyles = (target = document) => {
|
|
568
|
+
if (styledTargets.has(target)) return;
|
|
569
|
+
if (hasStyleNode(target, WIDGET_STYLES_ID)) {
|
|
570
|
+
styledTargets.add(target);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
const styleElement = document.createElement("style");
|
|
574
|
+
styleElement.id = WIDGET_STYLES_ID;
|
|
575
|
+
styleElement.textContent = getGlobalStyles();
|
|
576
|
+
styleHost(target).appendChild(styleElement);
|
|
577
|
+
styledTargets.add(target);
|
|
578
|
+
};
|
|
579
|
+
const injectKeyframes = (target = document) => {
|
|
580
|
+
if (keyframedTargets.has(target)) return;
|
|
581
|
+
if (hasStyleNode(target, WIDGET_KEYFRAMES_ID)) {
|
|
582
|
+
keyframedTargets.add(target);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
const style = document.createElement("style");
|
|
586
|
+
style.id = WIDGET_KEYFRAMES_ID;
|
|
587
|
+
style.textContent = WIDGET_KEYFRAMES;
|
|
588
|
+
styleHost(target).appendChild(style);
|
|
589
|
+
keyframedTargets.add(target);
|
|
590
|
+
};
|
|
591
|
+
let current = null;
|
|
592
|
+
const el = (tag, part, style) => {
|
|
593
|
+
const node = document.createElement(tag);
|
|
594
|
+
node.setAttribute("part", part);
|
|
595
|
+
node.style.cssText = toCssText(style);
|
|
596
|
+
return node;
|
|
597
|
+
};
|
|
598
|
+
function openLightbox(opts) {
|
|
599
|
+
var _a;
|
|
600
|
+
current == null ? void 0 : current.close();
|
|
601
|
+
injectKeyframes(opts.root);
|
|
602
|
+
const mount = opts.root instanceof ShadowRoot ? opts.root : opts.root.body;
|
|
603
|
+
const backdrop = el("div", "lightbox-backdrop", presentationStyles.lightboxBackdrop);
|
|
604
|
+
backdrop.setAttribute("role", "dialog");
|
|
605
|
+
backdrop.setAttribute("aria-modal", "true");
|
|
606
|
+
backdrop.setAttribute("aria-label", opts.alt || "Image preview");
|
|
607
|
+
const box = el("div", "lightbox", presentationStyles.lightbox);
|
|
608
|
+
const img = el("img", "lightbox-image", presentationStyles.lightboxImage);
|
|
609
|
+
img.src = opts.src;
|
|
610
|
+
img.alt = opts.alt;
|
|
611
|
+
const caption = el("span", "lightbox-caption", presentationStyles.lightboxCaption);
|
|
612
|
+
caption.textContent = opts.caption;
|
|
613
|
+
const controls = el("div", "lightbox-controls", presentationStyles.lightboxControls);
|
|
614
|
+
const open = el("a", "lightbox-open", presentationStyles.lightboxButton);
|
|
615
|
+
open.href = opts.href;
|
|
616
|
+
open.target = "_blank";
|
|
617
|
+
open.rel = "noopener noreferrer";
|
|
618
|
+
open.innerHTML = `${glyph("external")}<span>Open original</span>`;
|
|
619
|
+
const close = el("button", "lightbox-close", presentationStyles.lightboxButton);
|
|
620
|
+
close.type = "button";
|
|
621
|
+
close.setAttribute("aria-label", "Close image preview");
|
|
622
|
+
close.innerHTML = glyph("close");
|
|
623
|
+
controls.append(open, close);
|
|
624
|
+
img.addEventListener("error", () => {
|
|
625
|
+
const fallback = el("div", "lightbox-fallback", presentationStyles.lightboxFallback);
|
|
626
|
+
fallback.textContent = "Image could not be loaded";
|
|
627
|
+
img.replaceWith(fallback);
|
|
628
|
+
});
|
|
629
|
+
const previousOverflow = document.body.style.overflow;
|
|
630
|
+
const restoreFocus = (_a = opts.returnFocusTo) != null ? _a : document.activeElement;
|
|
631
|
+
const activeElement = () => opts.root instanceof ShadowRoot ? opts.root.activeElement : document.activeElement;
|
|
632
|
+
const onKey = (e) => {
|
|
633
|
+
if (e.key === "Escape") {
|
|
634
|
+
e.preventDefault();
|
|
635
|
+
handle.close();
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
if (e.key === "Tab") {
|
|
639
|
+
const active = activeElement();
|
|
640
|
+
if (e.shiftKey && active === open) {
|
|
641
|
+
e.preventDefault();
|
|
642
|
+
close.focus();
|
|
643
|
+
} else if (!e.shiftKey && active === close) {
|
|
644
|
+
e.preventDefault();
|
|
645
|
+
open.focus();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
const handle = {
|
|
650
|
+
close() {
|
|
651
|
+
var _a2;
|
|
652
|
+
if (current !== handle) return;
|
|
653
|
+
current = null;
|
|
654
|
+
document.removeEventListener("keydown", onKey, true);
|
|
655
|
+
backdrop.remove();
|
|
656
|
+
document.body.style.overflow = previousOverflow;
|
|
657
|
+
(_a2 = restoreFocus == null ? void 0 : restoreFocus.focus) == null ? void 0 : _a2.call(restoreFocus);
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
backdrop.addEventListener("click", (e) => {
|
|
661
|
+
if (e.target === backdrop) handle.close();
|
|
662
|
+
});
|
|
663
|
+
close.addEventListener("click", () => handle.close());
|
|
664
|
+
document.addEventListener("keydown", onKey, true);
|
|
665
|
+
box.append(controls, img, caption);
|
|
666
|
+
backdrop.appendChild(box);
|
|
667
|
+
mount.appendChild(backdrop);
|
|
668
|
+
document.body.style.overflow = "hidden";
|
|
669
|
+
current = handle;
|
|
670
|
+
close.focus();
|
|
671
|
+
return handle;
|
|
672
|
+
}
|
|
673
|
+
export {
|
|
674
|
+
MAX_CARDS_PER_MESSAGE as M,
|
|
675
|
+
PREVIEW_TIMEOUT_MS as P,
|
|
676
|
+
injectGlobalStyles as a,
|
|
677
|
+
aeroTheme as b,
|
|
678
|
+
glyph as g,
|
|
679
|
+
injectKeyframes as i,
|
|
680
|
+
openLightbox as o,
|
|
681
|
+
presentationStyles as p,
|
|
682
|
+
toCssText as t
|
|
683
|
+
};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@convai/web-widget` for bundlers.
|
|
3
|
+
*
|
|
4
|
+
* The package's other two artifacts are for a script tag: `v1.js` registers
|
|
5
|
+
* `<convai-widget>` on the page, and `runtime.js` is the chunk it fetches. Both
|
|
6
|
+
* bundle `@convai/web-sdk`, because a copy/paste embed's whole value is that
|
|
7
|
+
* the host page installs nothing.
|
|
8
|
+
*
|
|
9
|
+
* This entry is the opposite trade. It treats the SDK as **external**, so an
|
|
10
|
+
* application that already depends on it links one copy rather than two, and
|
|
11
|
+
* has no side effects, so a bundler can drop whatever is unused. Nothing here
|
|
12
|
+
* touches `document` or registers an element at import time.
|
|
13
|
+
*
|
|
14
|
+
* Importing it does not define `<convai-widget>`. That is deliberate: a
|
|
15
|
+
* bundler consumer composes the pieces, and a custom element registered as a
|
|
16
|
+
* side effect of an import is exactly the kind of thing tree-shaking cannot
|
|
17
|
+
* reason about.
|
|
18
|
+
*/
|
|
19
|
+
export type { ErrorCode, ErrorDetail, MessageDetail, Placement, Preload, WidgetConfig, } from './types';
|
|
20
|
+
/**
|
|
21
|
+
* The version this build came from, for a consumer reporting a bug.
|
|
22
|
+
*
|
|
23
|
+
* Injected from package.json at build time by Vite's `define`, so it cannot
|
|
24
|
+
* drift from the published version the way a hand-written constant would.
|
|
25
|
+
*/
|
|
26
|
+
export declare const VERSION: string;
|
package/index.js
ADDED