@neuronection/assistant-ui 0.47.0 → 0.49.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/CHANGELOG.md +26 -0
- package/dist/chat-message.d.ts +6 -0
- package/dist/chat-message.js +1 -1
- package/dist/chat-transcript.js +1 -1
- package/dist/{chunk-GNHADPX6.js → chunk-67FLOT4X.js} +3 -3
- package/dist/{chunk-GNHADPX6.js.map → chunk-67FLOT4X.js.map} +1 -1
- package/dist/{chunk-4XV2FGBS.js → chunk-BCKOBT7T.js} +21 -17
- package/dist/chunk-BCKOBT7T.js.map +1 -0
- package/dist/{chunk-EAJU4LFG.js → chunk-C5JZCCU7.js} +6 -3
- package/dist/chunk-C5JZCCU7.js.map +1 -0
- package/dist/{chunk-AIFKK377.js → chunk-CYK3ZLAB.js} +14 -10
- package/dist/chunk-CYK3ZLAB.js.map +1 -0
- package/dist/{chunk-OEBCS7EF.js → chunk-PTTJJEYJ.js} +3 -3
- package/dist/{chunk-OEBCS7EF.js.map → chunk-PTTJJEYJ.js.map} +1 -1
- package/dist/chunk-Q6LSPNCL.js +3 -0
- package/dist/chunk-Q6LSPNCL.js.map +1 -0
- package/dist/{chunk-HA7ZIB7V.js → chunk-RXFQZMSF.js} +3 -3
- package/dist/{chunk-HA7ZIB7V.js.map → chunk-RXFQZMSF.js.map} +1 -1
- package/dist/{chunk-UAZYDEXA.js → chunk-URLF67WR.js} +2 -2
- package/dist/{chunk-UAZYDEXA.js.map → chunk-URLF67WR.js.map} +1 -1
- package/dist/chunk-WY5TO6R4.js +415 -0
- package/dist/chunk-WY5TO6R4.js.map +1 -0
- package/dist/{chunk-MTFHU6QY.js → chunk-XOODPYJ3.js} +3 -3
- package/dist/{chunk-MTFHU6QY.js.map → chunk-XOODPYJ3.js.map} +1 -1
- package/dist/combobox.js +1 -1
- package/dist/countries.d.ts +19 -5
- package/dist/countries.js +212 -53
- package/dist/countries.js.map +1 -1
- package/dist/index.d.ts +20 -5
- package/dist/index.js +11 -11
- package/dist/languages.d.ts +28 -0
- package/dist/languages.js +75 -0
- package/dist/languages.js.map +1 -0
- package/dist/model-picker.js +1 -1
- package/dist/model-registry.js +1 -1
- package/dist/profile-switcher.js +1 -1
- package/dist/provider-form.d.ts +7 -0
- package/dist/provider-form.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/task-assignment-picker.js +1 -1
- package/dist/user-menu.d.ts +7 -5
- package/dist/user-menu.js +1 -1
- package/package.json +5 -1
- package/dist/chunk-4XV2FGBS.js.map +0 -1
- package/dist/chunk-AIFKK377.js.map +0 -1
- package/dist/chunk-C5OAZ2AW.js +0 -303
- package/dist/chunk-C5OAZ2AW.js.map +0 -1
- package/dist/chunk-EAJU4LFG.js.map +0 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { Input } from './chunk-GQDW6BBO.js';
|
|
2
|
+
import { Popover, PopoverTrigger, PopoverContent } from './chunk-VX3EQRSM.js';
|
|
3
|
+
import { Button } from './chunk-4WBBF5LH.js';
|
|
4
|
+
import { cn } from './chunk-RVVXVTH3.js';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { UserRound, ChevronDown, Pencil, Star, Trash2, Plus, Check } from 'lucide-react';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
var defaultLabels = {
|
|
10
|
+
trigger: "Switch profile",
|
|
11
|
+
panelTitle: "Profiles",
|
|
12
|
+
currentBadge: "Current",
|
|
13
|
+
defaultBadge: "Default",
|
|
14
|
+
newProfile: "New profile",
|
|
15
|
+
newProfilePlaceholder: "Profile name",
|
|
16
|
+
create: "Create",
|
|
17
|
+
rename: (name) => `Rename ${name}`,
|
|
18
|
+
renamePlaceholder: "Profile name",
|
|
19
|
+
renameSubmit: "Save",
|
|
20
|
+
setDefault: (name) => `Make ${name} the default profile`,
|
|
21
|
+
delete: (name) => `Delete ${name}`,
|
|
22
|
+
cancel: "Cancel",
|
|
23
|
+
loading: "Loading profiles\u2026",
|
|
24
|
+
empty: "No profiles yet"
|
|
25
|
+
};
|
|
26
|
+
function ProfileAvatar({
|
|
27
|
+
profile,
|
|
28
|
+
size = "sm"
|
|
29
|
+
}) {
|
|
30
|
+
const letter = (profile.name.trim()[0] ?? "?").toUpperCase();
|
|
31
|
+
return /* @__PURE__ */ jsx(
|
|
32
|
+
"span",
|
|
33
|
+
{
|
|
34
|
+
"aria-hidden": true,
|
|
35
|
+
className: cn(
|
|
36
|
+
"flex shrink-0 items-center justify-center rounded-full font-semibold ring-1 ring-[var(--as-border)]",
|
|
37
|
+
size === "md" ? "size-8 text-xs" : "size-6 text-[10px]"
|
|
38
|
+
),
|
|
39
|
+
style: profile.color ? { backgroundColor: `${profile.color}22`, color: profile.color } : {
|
|
40
|
+
backgroundColor: "var(--as-secondary)",
|
|
41
|
+
color: "var(--as-muted-fg)"
|
|
42
|
+
},
|
|
43
|
+
children: profile.color ? letter : /* @__PURE__ */ jsx(UserRound, { className: size === "md" ? "size-4" : "size-3.5" })
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function ProfileRowBadges({
|
|
48
|
+
isCurrent,
|
|
49
|
+
isDefault,
|
|
50
|
+
currentBadge,
|
|
51
|
+
defaultBadge
|
|
52
|
+
}) {
|
|
53
|
+
if (!isCurrent && !isDefault) return null;
|
|
54
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
55
|
+
isCurrent ? /* @__PURE__ */ jsxs(
|
|
56
|
+
"span",
|
|
57
|
+
{
|
|
58
|
+
className: "inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-medium",
|
|
59
|
+
style: {
|
|
60
|
+
backgroundColor: "color-mix(in srgb, var(--as-accent) 12%, transparent)",
|
|
61
|
+
color: "var(--as-accent)"
|
|
62
|
+
},
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "size-3" }),
|
|
65
|
+
currentBadge
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
) : null,
|
|
69
|
+
isDefault ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-[var(--as-secondary)] px-1.5 py-0.5 text-[10px] font-medium text-[var(--as-muted-fg)]", children: defaultBadge }) : null
|
|
70
|
+
] });
|
|
71
|
+
}
|
|
72
|
+
var ProfileSwitcher = React.forwardRef(
|
|
73
|
+
function ProfileSwitcher2({
|
|
74
|
+
profiles,
|
|
75
|
+
currentId,
|
|
76
|
+
onSelect,
|
|
77
|
+
onCreate,
|
|
78
|
+
onRename,
|
|
79
|
+
onDelete,
|
|
80
|
+
onSetDefault,
|
|
81
|
+
loading = false,
|
|
82
|
+
error = null,
|
|
83
|
+
align = "start",
|
|
84
|
+
labels,
|
|
85
|
+
icons,
|
|
86
|
+
className
|
|
87
|
+
}, ref) {
|
|
88
|
+
const merged = { ...defaultLabels, ...labels };
|
|
89
|
+
const TriggerIcon = icons?.trigger ?? UserRound;
|
|
90
|
+
const CreateIcon = icons?.create ?? Plus;
|
|
91
|
+
const RenameIcon = icons?.rename ?? Pencil;
|
|
92
|
+
const SetDefaultIcon = icons?.setDefault ?? Star;
|
|
93
|
+
const DeleteIcon = icons?.delete ?? Trash2;
|
|
94
|
+
const EmptyIcon = icons?.empty ?? UserRound;
|
|
95
|
+
const [open, setOpen] = React.useState(false);
|
|
96
|
+
const [draftName, setDraftName] = React.useState("");
|
|
97
|
+
const [renamingId, setRenamingId] = React.useState(null);
|
|
98
|
+
const [renameDraft, setRenameDraft] = React.useState("");
|
|
99
|
+
const renameInputRef = React.useRef(null);
|
|
100
|
+
const current = profiles.find((profile) => profile.id === currentId) ?? profiles[0] ?? null;
|
|
101
|
+
const close = React.useCallback(() => {
|
|
102
|
+
setOpen(false);
|
|
103
|
+
setRenamingId(null);
|
|
104
|
+
setDraftName("");
|
|
105
|
+
}, []);
|
|
106
|
+
React.useEffect(() => {
|
|
107
|
+
if (renamingId !== null) {
|
|
108
|
+
renameInputRef.current?.focus();
|
|
109
|
+
renameInputRef.current?.select();
|
|
110
|
+
}
|
|
111
|
+
}, [renamingId]);
|
|
112
|
+
const startRename = (profile) => {
|
|
113
|
+
setRenamingId(profile.id);
|
|
114
|
+
setRenameDraft(profile.name);
|
|
115
|
+
};
|
|
116
|
+
const submitRename = async (profile) => {
|
|
117
|
+
const name = renameDraft.trim();
|
|
118
|
+
if (!name || name === profile.name) {
|
|
119
|
+
setRenamingId(null);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
await onRename(profile, name);
|
|
123
|
+
setRenamingId(null);
|
|
124
|
+
};
|
|
125
|
+
const submitCreate = async (event) => {
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
const name = draftName.trim();
|
|
128
|
+
if (!name) return;
|
|
129
|
+
await onCreate(name);
|
|
130
|
+
setDraftName("");
|
|
131
|
+
};
|
|
132
|
+
const onListKeyDown = (event) => {
|
|
133
|
+
const rows = Array.from(
|
|
134
|
+
event.currentTarget.querySelectorAll("[data-profile-row]")
|
|
135
|
+
);
|
|
136
|
+
if (rows.length === 0) return;
|
|
137
|
+
const index = rows.indexOf(document.activeElement);
|
|
138
|
+
let next = -1;
|
|
139
|
+
if (event.key === "ArrowDown") next = index < 0 ? 0 : Math.min(index + 1, rows.length - 1);
|
|
140
|
+
else if (event.key === "ArrowUp")
|
|
141
|
+
next = index < 0 ? rows.length - 1 : Math.max(index - 1, 0);
|
|
142
|
+
else if (event.key === "Home") next = 0;
|
|
143
|
+
else if (event.key === "End") next = rows.length - 1;
|
|
144
|
+
if (next >= 0) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
rows[next]?.focus();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
return /* @__PURE__ */ jsx("div", { ref, "data-as": "profile-switcher", className: cn("inline-block", className), children: /* @__PURE__ */ jsxs(
|
|
150
|
+
Popover,
|
|
151
|
+
{
|
|
152
|
+
open,
|
|
153
|
+
onOpenChange: (next) => {
|
|
154
|
+
setOpen(next);
|
|
155
|
+
if (!next) {
|
|
156
|
+
setRenamingId(null);
|
|
157
|
+
setDraftName("");
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
children: [
|
|
161
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
162
|
+
"button",
|
|
163
|
+
{
|
|
164
|
+
type: "button",
|
|
165
|
+
"aria-haspopup": "dialog",
|
|
166
|
+
"aria-label": merged.trigger,
|
|
167
|
+
"data-testid": "profile-trigger",
|
|
168
|
+
className: "flex cursor-pointer items-center gap-2 rounded-full p-0.5 pr-2 transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]",
|
|
169
|
+
children: [
|
|
170
|
+
current ? /* @__PURE__ */ jsx(ProfileAvatar, { profile: current, size: "md" }) : /* @__PURE__ */ jsx(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
"aria-hidden": true,
|
|
174
|
+
className: "flex size-8 shrink-0 items-center justify-center rounded-full ring-1 ring-[var(--as-border)]",
|
|
175
|
+
children: /* @__PURE__ */ jsx(TriggerIcon, { className: "size-4 text-[var(--as-muted-fg)]" })
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-32 truncate text-sm font-medium", children: current ? current.name : merged.empty }),
|
|
179
|
+
/* @__PURE__ */ jsx(
|
|
180
|
+
ChevronDown,
|
|
181
|
+
{
|
|
182
|
+
"aria-hidden": true,
|
|
183
|
+
className: "size-3.5 text-[var(--as-muted-fg)] transition-transform duration-150 [[data-state=open]>&]:rotate-180"
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
) }),
|
|
189
|
+
/* @__PURE__ */ jsxs(
|
|
190
|
+
PopoverContent,
|
|
191
|
+
{
|
|
192
|
+
align,
|
|
193
|
+
role: "dialog",
|
|
194
|
+
"aria-label": merged.panelTitle,
|
|
195
|
+
className: "w-80 p-1.5 shadow-[var(--as-shadow-pop)] backdrop-blur-xl",
|
|
196
|
+
onEscapeKeyDown: (event) => {
|
|
197
|
+
if (renamingId !== null) event.preventDefault();
|
|
198
|
+
},
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-2 pb-1 pt-1", children: [
|
|
201
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wide text-[var(--as-muted-fg)]", children: merged.panelTitle }),
|
|
202
|
+
profiles.length > 0 ? /* @__PURE__ */ jsx("span", { className: "text-[11px] tabular-nums text-[var(--as-muted-fg)]", children: profiles.length }) : null
|
|
203
|
+
] }),
|
|
204
|
+
loading ? /* @__PURE__ */ jsx(
|
|
205
|
+
"p",
|
|
206
|
+
{
|
|
207
|
+
className: "as-anim-fade px-2 py-3 text-sm text-[var(--as-muted-fg)]",
|
|
208
|
+
role: "status",
|
|
209
|
+
children: merged.loading
|
|
210
|
+
}
|
|
211
|
+
) : profiles.length === 0 ? /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 px-2 py-3 text-sm text-[var(--as-muted-fg)]", children: [
|
|
212
|
+
/* @__PURE__ */ jsx(EmptyIcon, { "aria-hidden": true, className: "size-4" }),
|
|
213
|
+
merged.empty
|
|
214
|
+
] }) : /* @__PURE__ */ jsx(
|
|
215
|
+
"ul",
|
|
216
|
+
{
|
|
217
|
+
className: "max-h-72 space-y-0.5 overflow-y-auto",
|
|
218
|
+
onKeyDown: onListKeyDown,
|
|
219
|
+
children: profiles.map((profile) => {
|
|
220
|
+
const isCurrent = current !== null && profile.id === current.id;
|
|
221
|
+
return /* @__PURE__ */ jsx(
|
|
222
|
+
"li",
|
|
223
|
+
{
|
|
224
|
+
className: "flex items-center gap-1 rounded-[var(--as-radius-sm)] px-0.5 py-0.5 hover:bg-[var(--as-secondary)]",
|
|
225
|
+
children: renamingId === profile.id ? /* @__PURE__ */ jsxs(
|
|
226
|
+
"form",
|
|
227
|
+
{
|
|
228
|
+
className: "flex w-full items-center gap-1 py-0.5",
|
|
229
|
+
onSubmit: (event) => {
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
void submitRename(profile);
|
|
232
|
+
},
|
|
233
|
+
children: [
|
|
234
|
+
/* @__PURE__ */ jsx(
|
|
235
|
+
Input,
|
|
236
|
+
{
|
|
237
|
+
ref: renameInputRef,
|
|
238
|
+
"aria-label": merged.rename(profile.name),
|
|
239
|
+
placeholder: merged.renamePlaceholder,
|
|
240
|
+
value: renameDraft,
|
|
241
|
+
onChange: (event) => setRenameDraft(event.target.value),
|
|
242
|
+
onKeyDown: (event) => {
|
|
243
|
+
if (event.key === "Escape") {
|
|
244
|
+
event.preventDefault();
|
|
245
|
+
setRenamingId(null);
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
className: "h-8 flex-1"
|
|
249
|
+
}
|
|
250
|
+
),
|
|
251
|
+
/* @__PURE__ */ jsx(
|
|
252
|
+
Button,
|
|
253
|
+
{
|
|
254
|
+
type: "submit",
|
|
255
|
+
size: "sm",
|
|
256
|
+
className: "h-8",
|
|
257
|
+
disabled: !renameDraft.trim(),
|
|
258
|
+
"aria-label": merged.renameSubmit,
|
|
259
|
+
children: merged.renameSubmit
|
|
260
|
+
}
|
|
261
|
+
),
|
|
262
|
+
/* @__PURE__ */ jsx(
|
|
263
|
+
Button,
|
|
264
|
+
{
|
|
265
|
+
type: "button",
|
|
266
|
+
size: "sm",
|
|
267
|
+
variant: "ghost",
|
|
268
|
+
className: "h-8",
|
|
269
|
+
"aria-label": merged.cancel,
|
|
270
|
+
onClick: () => setRenamingId(null),
|
|
271
|
+
children: merged.cancel
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
]
|
|
275
|
+
}
|
|
276
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
277
|
+
/* @__PURE__ */ jsxs(
|
|
278
|
+
"button",
|
|
279
|
+
{
|
|
280
|
+
type: "button",
|
|
281
|
+
"aria-current": isCurrent || void 0,
|
|
282
|
+
"data-profile-row": true,
|
|
283
|
+
"data-testid": `profile-option-${profile.id}`,
|
|
284
|
+
className: "flex min-w-0 flex-1 cursor-pointer items-center gap-2.5 rounded-[var(--as-radius-sm)] px-1.5 py-1.5 text-left text-sm outline-none transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] aria-current:bg-[color-mix(in_srgb,var(--as-accent)_8%,transparent)]",
|
|
285
|
+
onClick: () => {
|
|
286
|
+
onSelect(profile);
|
|
287
|
+
close();
|
|
288
|
+
},
|
|
289
|
+
children: [
|
|
290
|
+
/* @__PURE__ */ jsx(ProfileAvatar, { profile, size: "md" }),
|
|
291
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: profile.name }),
|
|
292
|
+
/* @__PURE__ */ jsx(
|
|
293
|
+
ProfileRowBadges,
|
|
294
|
+
{
|
|
295
|
+
isCurrent,
|
|
296
|
+
isDefault: Boolean(profile.is_default),
|
|
297
|
+
currentBadge: merged.currentBadge,
|
|
298
|
+
defaultBadge: merged.defaultBadge
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
),
|
|
304
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-0.5 pr-0.5", children: [
|
|
305
|
+
/* @__PURE__ */ jsx(
|
|
306
|
+
Button,
|
|
307
|
+
{
|
|
308
|
+
type: "button",
|
|
309
|
+
size: "icon",
|
|
310
|
+
variant: "ghost",
|
|
311
|
+
className: "size-7 rounded-[var(--as-radius-sm)]",
|
|
312
|
+
"aria-label": merged.rename(profile.name),
|
|
313
|
+
title: merged.rename(profile.name),
|
|
314
|
+
onClick: () => startRename(profile),
|
|
315
|
+
children: /* @__PURE__ */ jsx(RenameIcon, { "aria-hidden": true })
|
|
316
|
+
}
|
|
317
|
+
),
|
|
318
|
+
onSetDefault && !profile.is_default ? /* @__PURE__ */ jsx(
|
|
319
|
+
Button,
|
|
320
|
+
{
|
|
321
|
+
type: "button",
|
|
322
|
+
size: "icon",
|
|
323
|
+
variant: "ghost",
|
|
324
|
+
className: "size-7 rounded-[var(--as-radius-sm)]",
|
|
325
|
+
"aria-label": merged.setDefault(profile.name),
|
|
326
|
+
title: merged.setDefault(profile.name),
|
|
327
|
+
onClick: () => void onSetDefault(profile),
|
|
328
|
+
children: /* @__PURE__ */ jsx(SetDefaultIcon, { "aria-hidden": true })
|
|
329
|
+
}
|
|
330
|
+
) : null,
|
|
331
|
+
/* @__PURE__ */ jsx(
|
|
332
|
+
Button,
|
|
333
|
+
{
|
|
334
|
+
type: "button",
|
|
335
|
+
size: "icon",
|
|
336
|
+
variant: "ghost",
|
|
337
|
+
className: "size-7 rounded-[var(--as-radius-sm)] hover:text-[var(--as-danger)]",
|
|
338
|
+
"aria-label": merged.delete(profile.name),
|
|
339
|
+
title: merged.delete(profile.name),
|
|
340
|
+
onClick: () => void onDelete(profile),
|
|
341
|
+
children: /* @__PURE__ */ jsx(DeleteIcon, { "aria-hidden": true })
|
|
342
|
+
}
|
|
343
|
+
)
|
|
344
|
+
] })
|
|
345
|
+
] })
|
|
346
|
+
},
|
|
347
|
+
profile.id
|
|
348
|
+
);
|
|
349
|
+
})
|
|
350
|
+
}
|
|
351
|
+
),
|
|
352
|
+
error ? /* @__PURE__ */ jsx(
|
|
353
|
+
"p",
|
|
354
|
+
{
|
|
355
|
+
role: "alert",
|
|
356
|
+
className: "mx-1 mt-1 rounded-[var(--as-radius-sm)] bg-[color-mix(in_srgb,var(--as-danger)_10%,transparent)] px-2 py-1 text-xs text-[var(--as-danger)]",
|
|
357
|
+
children: error
|
|
358
|
+
}
|
|
359
|
+
) : null,
|
|
360
|
+
/* @__PURE__ */ jsxs(
|
|
361
|
+
"form",
|
|
362
|
+
{
|
|
363
|
+
className: "mt-1 flex items-center gap-1.5 border-t border-[var(--as-border)] p-1.5 pt-2",
|
|
364
|
+
onSubmit: (event) => {
|
|
365
|
+
void submitCreate(event);
|
|
366
|
+
},
|
|
367
|
+
children: [
|
|
368
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
369
|
+
/* @__PURE__ */ jsx(
|
|
370
|
+
CreateIcon,
|
|
371
|
+
{
|
|
372
|
+
"aria-hidden": true,
|
|
373
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-[var(--as-muted-fg)]"
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
/* @__PURE__ */ jsx(
|
|
377
|
+
Input,
|
|
378
|
+
{
|
|
379
|
+
"aria-label": merged.newProfile,
|
|
380
|
+
placeholder: merged.newProfilePlaceholder,
|
|
381
|
+
value: draftName,
|
|
382
|
+
onChange: (event) => setDraftName(event.target.value),
|
|
383
|
+
className: "h-8 pl-8"
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
] }),
|
|
387
|
+
/* @__PURE__ */ jsxs(
|
|
388
|
+
Button,
|
|
389
|
+
{
|
|
390
|
+
type: "submit",
|
|
391
|
+
size: "sm",
|
|
392
|
+
className: "h-8 gap-1 px-2.5",
|
|
393
|
+
disabled: !draftName.trim(),
|
|
394
|
+
"aria-label": merged.create,
|
|
395
|
+
children: [
|
|
396
|
+
/* @__PURE__ */ jsx(CreateIcon, { "aria-hidden": true }),
|
|
397
|
+
merged.create
|
|
398
|
+
]
|
|
399
|
+
}
|
|
400
|
+
)
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
)
|
|
404
|
+
]
|
|
405
|
+
}
|
|
406
|
+
)
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
) });
|
|
410
|
+
}
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
export { ProfileSwitcher };
|
|
414
|
+
//# sourceMappingURL=chunk-WY5TO6R4.js.map
|
|
415
|
+
//# sourceMappingURL=chunk-WY5TO6R4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/profile-switcher/ProfileSwitcher.tsx"],"names":["ProfileSwitcher"],"mappings":"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","file":"chunk-WY5TO6R4.js","sourcesContent":["import * as React from 'react'\nimport {\n Check,\n ChevronDown,\n Pencil,\n Plus,\n Star,\n Trash2,\n UserRound,\n type LucideIcon,\n} from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\nimport { Input } from '../input/Input'\nimport { Popover, PopoverContent, PopoverTrigger } from '../popover/Popover'\n\nexport interface ProfileItem {\n id: string\n name: string\n is_default?: boolean\n color?: string | null\n}\n\nexport interface ProfileSwitcherLabels {\n trigger: string\n panelTitle: string\n currentBadge: string\n defaultBadge: string\n newProfile: string\n newProfilePlaceholder: string\n create: string\n rename: (name: string) => string\n renamePlaceholder: string\n renameSubmit: string\n setDefault: (name: string) => string\n delete: (name: string) => string\n cancel: string\n loading: string\n empty: string\n}\n\nexport interface ProfileSwitcherIcons {\n trigger?: LucideIcon\n create?: LucideIcon\n rename?: LucideIcon\n setDefault?: LucideIcon\n delete?: LucideIcon\n empty?: LucideIcon\n}\n\nexport interface ProfileSwitcherProps {\n profiles: ProfileItem[]\n currentId: string | null\n onSelect: (profile: ProfileItem) => void\n onCreate: (name: string) => void | Promise<unknown>\n onRename: (profile: ProfileItem, name: string) => void | Promise<unknown>\n onDelete: (profile: ProfileItem) => void | Promise<unknown>\n /** When given, rows expose a \"make Default\" action (identity-auth §12). */\n onSetDefault?: (profile: ProfileItem) => void | Promise<unknown>\n loading?: boolean\n error?: string | null\n align?: 'start' | 'end'\n labels?: Partial<ProfileSwitcherLabels>\n icons?: ProfileSwitcherIcons\n className?: string\n}\n\nconst defaultLabels: ProfileSwitcherLabels = {\n trigger: 'Switch profile',\n panelTitle: 'Profiles',\n currentBadge: 'Current',\n defaultBadge: 'Default',\n newProfile: 'New profile',\n newProfilePlaceholder: 'Profile name',\n create: 'Create',\n rename: (name) => `Rename ${name}`,\n renamePlaceholder: 'Profile name',\n renameSubmit: 'Save',\n setDefault: (name) => `Make ${name} the default profile`,\n delete: (name) => `Delete ${name}`,\n cancel: 'Cancel',\n loading: 'Loading profiles…',\n empty: 'No profiles yet',\n}\n\nfunction ProfileAvatar({\n profile,\n size = 'sm',\n}: {\n profile: ProfileItem\n size?: 'sm' | 'md'\n}) {\n const letter = (profile.name.trim()[0] ?? '?').toUpperCase()\n return (\n <span\n aria-hidden\n className={cn(\n 'flex shrink-0 items-center justify-center rounded-full font-semibold ring-1 ring-[var(--as-border)]',\n size === 'md' ? 'size-8 text-xs' : 'size-6 text-[10px]',\n )}\n style={\n profile.color\n ? { backgroundColor: `${profile.color}22`, color: profile.color }\n : {\n backgroundColor: 'var(--as-secondary)',\n color: 'var(--as-muted-fg)',\n }\n }\n >\n {profile.color ? (\n letter\n ) : (\n <UserRound className={size === 'md' ? 'size-4' : 'size-3.5'} />\n )}\n </span>\n )\n}\n\n/** Status pills on a row: accent \"Current\" when active, muted \"Default\". */\nfunction ProfileRowBadges({\n isCurrent,\n isDefault,\n currentBadge,\n defaultBadge,\n}: {\n isCurrent: boolean\n isDefault: boolean\n currentBadge: string\n defaultBadge: string\n}) {\n if (!isCurrent && !isDefault) return null\n return (\n <span className=\"flex shrink-0 items-center gap-1\">\n {isCurrent ? (\n <span\n className=\"inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-medium\"\n style={{\n backgroundColor: 'color-mix(in srgb, var(--as-accent) 12%, transparent)',\n color: 'var(--as-accent)',\n }}\n >\n <Check aria-hidden className=\"size-3\" />\n {currentBadge}\n </span>\n ) : null}\n {isDefault ? (\n <span className=\"inline-flex items-center rounded-full bg-[var(--as-secondary)] px-1.5 py-0.5 text-[10px] font-medium text-[var(--as-muted-fg)]\">\n {defaultBadge}\n </span>\n ) : null}\n </span>\n )\n}\n\nexport const ProfileSwitcher = React.forwardRef<HTMLDivElement, ProfileSwitcherProps>(\n function ProfileSwitcher(\n {\n profiles,\n currentId,\n onSelect,\n onCreate,\n onRename,\n onDelete,\n onSetDefault,\n loading = false,\n error = null,\n align = 'start',\n labels,\n icons,\n className,\n },\n ref,\n ) {\n const merged = { ...defaultLabels, ...labels }\n const TriggerIcon = icons?.trigger ?? UserRound\n const CreateIcon = icons?.create ?? Plus\n const RenameIcon = icons?.rename ?? Pencil\n const SetDefaultIcon = icons?.setDefault ?? Star\n const DeleteIcon = icons?.delete ?? Trash2\n const EmptyIcon = icons?.empty ?? UserRound\n\n const [open, setOpen] = React.useState(false)\n const [draftName, setDraftName] = React.useState('')\n const [renamingId, setRenamingId] = React.useState<string | null>(null)\n const [renameDraft, setRenameDraft] = React.useState('')\n const renameInputRef = React.useRef<HTMLInputElement>(null)\n\n const current = profiles.find((profile) => profile.id === currentId) ?? profiles[0] ?? null\n\n const close = React.useCallback(() => {\n setOpen(false)\n setRenamingId(null)\n setDraftName('')\n }, [])\n\n React.useEffect(() => {\n if (renamingId !== null) {\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n }\n }, [renamingId])\n\n const startRename = (profile: ProfileItem) => {\n setRenamingId(profile.id)\n setRenameDraft(profile.name)\n }\n\n const submitRename = async (profile: ProfileItem) => {\n const name = renameDraft.trim()\n if (!name || name === profile.name) {\n setRenamingId(null)\n return\n }\n await onRename(profile, name)\n setRenamingId(null)\n }\n\n const submitCreate = async (event: React.FormEvent) => {\n event.preventDefault()\n const name = draftName.trim()\n if (!name) return\n await onCreate(name)\n setDraftName('')\n }\n\n // Roving arrows: ↓/↑ (and Home/End) walk the profile rows without\n // leaving the panel; Tab keeps the DOM order (select → actions).\n const onListKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n const rows = Array.from(\n event.currentTarget.querySelectorAll<HTMLButtonElement>('[data-profile-row]'),\n )\n if (rows.length === 0) return\n const index = rows.indexOf(document.activeElement as HTMLButtonElement)\n let next = -1\n if (event.key === 'ArrowDown') next = index < 0 ? 0 : Math.min(index + 1, rows.length - 1)\n else if (event.key === 'ArrowUp')\n next = index < 0 ? rows.length - 1 : Math.max(index - 1, 0)\n else if (event.key === 'Home') next = 0\n else if (event.key === 'End') next = rows.length - 1\n if (next >= 0) {\n event.preventDefault()\n rows[next]?.focus()\n }\n }\n\n return (\n <div ref={ref} data-as=\"profile-switcher\" className={cn('inline-block', className)}>\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n if (!next) {\n setRenamingId(null)\n setDraftName('')\n }\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-label={merged.trigger}\n data-testid=\"profile-trigger\"\n className=\"flex cursor-pointer items-center gap-2 rounded-full p-0.5 pr-2 transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n {current ? (\n <ProfileAvatar profile={current} size=\"md\" />\n ) : (\n <span\n aria-hidden\n className=\"flex size-8 shrink-0 items-center justify-center rounded-full ring-1 ring-[var(--as-border)]\"\n >\n <TriggerIcon className=\"size-4 text-[var(--as-muted-fg)]\" />\n </span>\n )}\n <span className=\"max-w-32 truncate text-sm font-medium\">\n {current ? current.name : merged.empty}\n </span>\n <ChevronDown\n aria-hidden\n className=\"size-3.5 text-[var(--as-muted-fg)] transition-transform duration-150 [[data-state=open]>&]:rotate-180\"\n />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align={align}\n role=\"dialog\"\n aria-label={merged.panelTitle}\n className=\"w-80 p-1.5 shadow-[var(--as-shadow-pop)] backdrop-blur-xl\"\n onEscapeKeyDown={(event) => {\n // Escape cancels an inline rename first, closes the panel\n // only on the second press.\n if (renamingId !== null) event.preventDefault()\n }}\n >\n <div className=\"flex items-center justify-between px-2 pb-1 pt-1\">\n <span className=\"text-[11px] font-semibold uppercase tracking-wide text-[var(--as-muted-fg)]\">\n {merged.panelTitle}\n </span>\n {profiles.length > 0 ? (\n <span className=\"text-[11px] tabular-nums text-[var(--as-muted-fg)]\">\n {profiles.length}\n </span>\n ) : null}\n </div>\n {loading ? (\n <p\n className=\"as-anim-fade px-2 py-3 text-sm text-[var(--as-muted-fg)]\"\n role=\"status\"\n >\n {merged.loading}\n </p>\n ) : profiles.length === 0 ? (\n <p className=\"flex items-center gap-2 px-2 py-3 text-sm text-[var(--as-muted-fg)]\">\n <EmptyIcon aria-hidden className=\"size-4\" />\n {merged.empty}\n </p>\n ) : (\n <ul\n className=\"max-h-72 space-y-0.5 overflow-y-auto\"\n onKeyDown={onListKeyDown}\n >\n {profiles.map((profile) => {\n const isCurrent = current !== null && profile.id === current.id\n return (\n <li\n key={profile.id}\n className=\"flex items-center gap-1 rounded-[var(--as-radius-sm)] px-0.5 py-0.5 hover:bg-[var(--as-secondary)]\"\n >\n {renamingId === profile.id ? (\n <form\n className=\"flex w-full items-center gap-1 py-0.5\"\n onSubmit={(event) => {\n event.preventDefault()\n void submitRename(profile)\n }}\n >\n <Input\n ref={renameInputRef}\n aria-label={merged.rename(profile.name)}\n placeholder={merged.renamePlaceholder}\n value={renameDraft}\n onChange={(event) => setRenameDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n setRenamingId(null)\n }\n }}\n className=\"h-8 flex-1\"\n />\n <Button\n type=\"submit\"\n size=\"sm\"\n className=\"h-8\"\n disabled={!renameDraft.trim()}\n aria-label={merged.renameSubmit}\n >\n {merged.renameSubmit}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-8\"\n aria-label={merged.cancel}\n onClick={() => setRenamingId(null)}\n >\n {merged.cancel}\n </Button>\n </form>\n ) : (\n <>\n <button\n type=\"button\"\n aria-current={isCurrent || undefined}\n data-profile-row\n data-testid={`profile-option-${profile.id}`}\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2.5 rounded-[var(--as-radius-sm)] px-1.5 py-1.5 text-left text-sm outline-none transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] aria-current:bg-[color-mix(in_srgb,var(--as-accent)_8%,transparent)]\"\n onClick={() => {\n onSelect(profile)\n close()\n }}\n >\n <ProfileAvatar profile={profile} size=\"md\" />\n <span className=\"min-w-0 flex-1 truncate font-medium\">\n {profile.name}\n </span>\n <ProfileRowBadges\n isCurrent={isCurrent}\n isDefault={Boolean(profile.is_default)}\n currentBadge={merged.currentBadge}\n defaultBadge={merged.defaultBadge}\n />\n </button>\n <span className=\"flex shrink-0 items-center gap-0.5 pr-0.5\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-7 rounded-[var(--as-radius-sm)]\"\n aria-label={merged.rename(profile.name)}\n title={merged.rename(profile.name)}\n onClick={() => startRename(profile)}\n >\n <RenameIcon aria-hidden />\n </Button>\n {onSetDefault && !profile.is_default ? (\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-7 rounded-[var(--as-radius-sm)]\"\n aria-label={merged.setDefault(profile.name)}\n title={merged.setDefault(profile.name)}\n onClick={() => void onSetDefault(profile)}\n >\n <SetDefaultIcon aria-hidden />\n </Button>\n ) : null}\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-7 rounded-[var(--as-radius-sm)] hover:text-[var(--as-danger)]\"\n aria-label={merged.delete(profile.name)}\n title={merged.delete(profile.name)}\n onClick={() => void onDelete(profile)}\n >\n <DeleteIcon aria-hidden />\n </Button>\n </span>\n </>\n )}\n </li>\n )\n })}\n </ul>\n )}\n {error ? (\n <p\n role=\"alert\"\n className=\"mx-1 mt-1 rounded-[var(--as-radius-sm)] bg-[color-mix(in_srgb,var(--as-danger)_10%,transparent)] px-2 py-1 text-xs text-[var(--as-danger)]\"\n >\n {error}\n </p>\n ) : null}\n <form\n className=\"mt-1 flex items-center gap-1.5 border-t border-[var(--as-border)] p-1.5 pt-2\"\n onSubmit={(event) => {\n void submitCreate(event)\n }}\n >\n <div className=\"relative min-w-0 flex-1\">\n <CreateIcon\n aria-hidden\n className=\"pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-[var(--as-muted-fg)]\"\n />\n <Input\n aria-label={merged.newProfile}\n placeholder={merged.newProfilePlaceholder}\n value={draftName}\n onChange={(event) => setDraftName(event.target.value)}\n className=\"h-8 pl-8\"\n />\n </div>\n <Button\n type=\"submit\"\n size=\"sm\"\n className=\"h-8 gap-1 px-2.5\"\n disabled={!draftName.trim()}\n aria-label={merged.create}\n >\n <CreateIcon aria-hidden />\n {merged.create}\n </Button>\n </form>\n </PopoverContent>\n </Popover>\n </div>\n )\n },\n)\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkdownSurface } from './chunk-HQ3X5SVR.js';
|
|
2
|
-
import { ChatMessage } from './chunk-
|
|
2
|
+
import { ChatMessage } from './chunk-C5JZCCU7.js';
|
|
3
3
|
import { cn } from './chunk-RVVXVTH3.js';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { ArrowDown } from 'lucide-react';
|
|
@@ -169,5 +169,5 @@ var ChatTranscript = React.forwardRef(
|
|
|
169
169
|
);
|
|
170
170
|
|
|
171
171
|
export { ChatTranscript };
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
173
|
-
//# sourceMappingURL=chunk-
|
|
172
|
+
//# sourceMappingURL=chunk-XOODPYJ3.js.map
|
|
173
|
+
//# sourceMappingURL=chunk-XOODPYJ3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/chat-transcript/ChatTranscript.tsx"],"names":["ChatTranscript"],"mappings":"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","file":"chunk-MTFHU6QY.js","sourcesContent":["import * as React from 'react'\nimport { ArrowDown } from 'lucide-react'\nimport { useVirtualizer } from '@tanstack/react-virtual'\n\nimport { cn } from '../../lib/utils'\nimport { ChatMessage } from '../chat-message/ChatMessage'\nimport { MarkdownSurface } from '../chat-markdown/MarkdownSurface'\nimport type { ChatMessageView } from '../chat-core/types'\n\nexport interface ChatTranscriptLabels {\n log: string\n scrollToBottom: string\n empty: string\n replied: string\n}\n\nexport interface ChatTranscriptProps {\n items: ChatMessageView[]\n /** Override the default `ChatMessage` + `MarkdownSurface` rendering. */\n renderItem?: (message: ChatMessageView, index: number) => React.ReactNode\n /** Streaming tail — the live turn bubble (or any node). */\n live?: React.ReactNode\n emptyState?: React.ReactNode\n /** Stick to bottom while the user hasn't scrolled away. Default true. */\n autoScroll?: boolean\n /** Distance from the bottom that still counts as \"at the bottom\". Default 120 px. */\n scrollThresholdPx?: number\n /** Virtualize long transcripts (dynamic row measurement). Default false. */\n virtualized?: boolean\n labels?: Partial<ChatTranscriptLabels>\n className?: string\n}\n\nfunction defaultRenderItem(message: ChatMessageView) {\n return (\n <ChatMessage\n role={message.role}\n status={message.status}\n content={<MarkdownSurface value={message.content} streaming={message.status === 'streaming'} />}\n variants={message.variants}\n />\n )\n}\n\n/**\n * The conversation list: `role=\"log\"` with polite turn-completion\n * announcements, stick-to-bottom auto-scroll with a jump-to-latest pill,\n * optional virtualization for thousand-message threads.\n */\nexport const ChatTranscript = React.forwardRef<HTMLDivElement, ChatTranscriptProps>(\n function ChatTranscript(\n {\n items,\n renderItem = defaultRenderItem,\n live,\n emptyState,\n autoScroll = true,\n scrollThresholdPx = 120,\n virtualized = false,\n labels,\n className,\n },\n ref,\n ) {\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const atBottomRef = React.useRef(true)\n const lastScrollTopRef = React.useRef(0)\n const lastTouchYRef = React.useRef<number | null>(null)\n const [showJump, setShowJump] = React.useState(false)\n const [announcement, setAnnouncement] = React.useState('')\n const previousCountRef = React.useRef(-1)\n\n const onScroll = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight\n const goingUp = element.scrollTop < lastScrollTopRef.current\n lastScrollTopRef.current = element.scrollTop\n const atBottom = distance <= scrollThresholdPx && !(goingUp && distance > 0)\n atBottomRef.current = atBottom\n setShowJump(element.scrollHeight > element.clientHeight && !atBottom)\n }\n\n /**\n * Fast streams re-pin the bottom on every render (rAF), which erases\n * a partial upward scroll before it can cross `scrollThresholdPx` —\n * so user scroll-up INTENT cancels stickiness synchronously here\n * (wheel up, touch drag up, scroll-up keys), and any upward scroll\n * event with distance left also breaks it. Scrolling back to the\n * bottom (or the jump pill) re-arms the follow.\n */\n const cancelStick = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n atBottomRef.current = false\n setShowJump(element.scrollHeight > element.clientHeight)\n }\n\n const onWheel = (event: React.WheelEvent<HTMLDivElement>) => {\n if (event.deltaY < 0) {\n cancelStick()\n }\n }\n\n const onTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {\n lastTouchYRef.current = event.touches[0]?.clientY ?? null\n }\n\n const onTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {\n const y = event.touches[0]?.clientY\n if (y === undefined) {\n return\n }\n if (lastTouchYRef.current !== null && y > lastTouchYRef.current) {\n cancelStick()\n }\n lastTouchYRef.current = y\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n event.key === 'ArrowUp' ||\n event.key === 'PageUp' ||\n event.key === 'Home' ||\n (event.key === ' ' && event.shiftKey)\n ) {\n cancelStick()\n }\n }\n\n React.useEffect(() => {\n const element = scrollRef.current\n if (element === null || !autoScroll || !atBottomRef.current) {\n return\n }\n const frame = requestAnimationFrame(() => {\n element.scrollTop = element.scrollHeight\n })\n return () => cancelAnimationFrame(frame)\n })\n\n React.useEffect(() => {\n if (previousCountRef.current === -1) {\n previousCountRef.current = items.length\n return\n }\n if (items.length > previousCountRef.current) {\n const added = items[items.length - 1]\n previousCountRef.current = items.length\n if (added && added.role !== 'user') {\n setAnnouncement(labels?.replied ?? 'Assistant replied')\n }\n return\n }\n previousCountRef.current = items.length\n }, [items, labels])\n\n const scrollToBottom = () => {\n const element = scrollRef.current\n if (element !== null) {\n element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' })\n }\n }\n\n const rowCount = items.length + (live !== undefined ? 1 : 0)\n const virtualizer = useVirtualizer({\n count: virtualized ? rowCount : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 120,\n overscan: 8,\n initialRect: { width: 480, height: 600 },\n })\n\n return (\n <div ref={ref} data-as=\"chat-transcript\" className={cn('relative min-h-0 flex-1', className)}>\n <div\n ref={scrollRef}\n onScroll={onScroll}\n onWheel={onWheel}\n onTouchStart={onTouchStart}\n onTouchMove={onTouchMove}\n onKeyDown={onKeyDown}\n role=\"log\"\n aria-label={labels?.log ?? 'Conversation'}\n aria-busy={live !== undefined}\n className=\"h-full overflow-y-auto overscroll-contain px-1 py-2\"\n >\n {items.length === 0 && live === undefined ? (\n <div className=\"flex h-full min-h-40 items-center justify-center p-4 text-sm text-[var(--as-muted-fg)]\">\n {emptyState ?? (labels?.empty ?? 'Start the conversation')}\n </div>\n ) : virtualized ? (\n <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>\n {virtualizer.getVirtualItems().map((row) => {\n const isLive = row.index >= items.length\n const node = isLive ? live : renderItem(items[row.index]!, row.index)\n return (\n <div\n key={row.key}\n data-index={row.index}\n ref={virtualizer.measureElement}\n style={{ position: 'absolute', top: 0, left: 0, width: '100%', transform: `translateY(${row.start}px)` }}\n className=\"px-2 py-1.5\"\n >\n {node}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 px-2\">\n {items.map((message, index) => (\n <div key={message.id}>{renderItem(message, index)}</div>\n ))}\n {live !== undefined ? <div data-as=\"chat-transcript-live\">{live}</div> : null}\n </div>\n )}\n </div>\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {showJump ? (\n <button\n type=\"button\"\n onClick={scrollToBottom}\n aria-label={labels?.scrollToBottom ?? 'Scroll to latest'}\n title={labels?.scrollToBottom ?? 'Scroll to latest'}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ArrowDown className=\"size-4\" aria-hidden />\n </button>\n ) : null}\n </div>\n )\n },\n)\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-transcript/ChatTranscript.tsx"],"names":["ChatTranscript"],"mappings":"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","file":"chunk-XOODPYJ3.js","sourcesContent":["import * as React from 'react'\nimport { ArrowDown } from 'lucide-react'\nimport { useVirtualizer } from '@tanstack/react-virtual'\n\nimport { cn } from '../../lib/utils'\nimport { ChatMessage } from '../chat-message/ChatMessage'\nimport { MarkdownSurface } from '../chat-markdown/MarkdownSurface'\nimport type { ChatMessageView } from '../chat-core/types'\n\nexport interface ChatTranscriptLabels {\n log: string\n scrollToBottom: string\n empty: string\n replied: string\n}\n\nexport interface ChatTranscriptProps {\n items: ChatMessageView[]\n /** Override the default `ChatMessage` + `MarkdownSurface` rendering. */\n renderItem?: (message: ChatMessageView, index: number) => React.ReactNode\n /** Streaming tail — the live turn bubble (or any node). */\n live?: React.ReactNode\n emptyState?: React.ReactNode\n /** Stick to bottom while the user hasn't scrolled away. Default true. */\n autoScroll?: boolean\n /** Distance from the bottom that still counts as \"at the bottom\". Default 120 px. */\n scrollThresholdPx?: number\n /** Virtualize long transcripts (dynamic row measurement). Default false. */\n virtualized?: boolean\n labels?: Partial<ChatTranscriptLabels>\n className?: string\n}\n\nfunction defaultRenderItem(message: ChatMessageView) {\n return (\n <ChatMessage\n role={message.role}\n status={message.status}\n content={<MarkdownSurface value={message.content} streaming={message.status === 'streaming'} />}\n variants={message.variants}\n />\n )\n}\n\n/**\n * The conversation list: `role=\"log\"` with polite turn-completion\n * announcements, stick-to-bottom auto-scroll with a jump-to-latest pill,\n * optional virtualization for thousand-message threads.\n */\nexport const ChatTranscript = React.forwardRef<HTMLDivElement, ChatTranscriptProps>(\n function ChatTranscript(\n {\n items,\n renderItem = defaultRenderItem,\n live,\n emptyState,\n autoScroll = true,\n scrollThresholdPx = 120,\n virtualized = false,\n labels,\n className,\n },\n ref,\n ) {\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const atBottomRef = React.useRef(true)\n const lastScrollTopRef = React.useRef(0)\n const lastTouchYRef = React.useRef<number | null>(null)\n const [showJump, setShowJump] = React.useState(false)\n const [announcement, setAnnouncement] = React.useState('')\n const previousCountRef = React.useRef(-1)\n\n const onScroll = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight\n const goingUp = element.scrollTop < lastScrollTopRef.current\n lastScrollTopRef.current = element.scrollTop\n const atBottom = distance <= scrollThresholdPx && !(goingUp && distance > 0)\n atBottomRef.current = atBottom\n setShowJump(element.scrollHeight > element.clientHeight && !atBottom)\n }\n\n /**\n * Fast streams re-pin the bottom on every render (rAF), which erases\n * a partial upward scroll before it can cross `scrollThresholdPx` —\n * so user scroll-up INTENT cancels stickiness synchronously here\n * (wheel up, touch drag up, scroll-up keys), and any upward scroll\n * event with distance left also breaks it. Scrolling back to the\n * bottom (or the jump pill) re-arms the follow.\n */\n const cancelStick = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n atBottomRef.current = false\n setShowJump(element.scrollHeight > element.clientHeight)\n }\n\n const onWheel = (event: React.WheelEvent<HTMLDivElement>) => {\n if (event.deltaY < 0) {\n cancelStick()\n }\n }\n\n const onTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {\n lastTouchYRef.current = event.touches[0]?.clientY ?? null\n }\n\n const onTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {\n const y = event.touches[0]?.clientY\n if (y === undefined) {\n return\n }\n if (lastTouchYRef.current !== null && y > lastTouchYRef.current) {\n cancelStick()\n }\n lastTouchYRef.current = y\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n event.key === 'ArrowUp' ||\n event.key === 'PageUp' ||\n event.key === 'Home' ||\n (event.key === ' ' && event.shiftKey)\n ) {\n cancelStick()\n }\n }\n\n React.useEffect(() => {\n const element = scrollRef.current\n if (element === null || !autoScroll || !atBottomRef.current) {\n return\n }\n const frame = requestAnimationFrame(() => {\n element.scrollTop = element.scrollHeight\n })\n return () => cancelAnimationFrame(frame)\n })\n\n React.useEffect(() => {\n if (previousCountRef.current === -1) {\n previousCountRef.current = items.length\n return\n }\n if (items.length > previousCountRef.current) {\n const added = items[items.length - 1]\n previousCountRef.current = items.length\n if (added && added.role !== 'user') {\n setAnnouncement(labels?.replied ?? 'Assistant replied')\n }\n return\n }\n previousCountRef.current = items.length\n }, [items, labels])\n\n const scrollToBottom = () => {\n const element = scrollRef.current\n if (element !== null) {\n element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' })\n }\n }\n\n const rowCount = items.length + (live !== undefined ? 1 : 0)\n const virtualizer = useVirtualizer({\n count: virtualized ? rowCount : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 120,\n overscan: 8,\n initialRect: { width: 480, height: 600 },\n })\n\n return (\n <div ref={ref} data-as=\"chat-transcript\" className={cn('relative min-h-0 flex-1', className)}>\n <div\n ref={scrollRef}\n onScroll={onScroll}\n onWheel={onWheel}\n onTouchStart={onTouchStart}\n onTouchMove={onTouchMove}\n onKeyDown={onKeyDown}\n role=\"log\"\n aria-label={labels?.log ?? 'Conversation'}\n aria-busy={live !== undefined}\n className=\"h-full overflow-y-auto overscroll-contain px-1 py-2\"\n >\n {items.length === 0 && live === undefined ? (\n <div className=\"flex h-full min-h-40 items-center justify-center p-4 text-sm text-[var(--as-muted-fg)]\">\n {emptyState ?? (labels?.empty ?? 'Start the conversation')}\n </div>\n ) : virtualized ? (\n <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>\n {virtualizer.getVirtualItems().map((row) => {\n const isLive = row.index >= items.length\n const node = isLive ? live : renderItem(items[row.index]!, row.index)\n return (\n <div\n key={row.key}\n data-index={row.index}\n ref={virtualizer.measureElement}\n style={{ position: 'absolute', top: 0, left: 0, width: '100%', transform: `translateY(${row.start}px)` }}\n className=\"px-2 py-1.5\"\n >\n {node}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 px-2\">\n {items.map((message, index) => (\n <div key={message.id}>{renderItem(message, index)}</div>\n ))}\n {live !== undefined ? <div data-as=\"chat-transcript-live\">{live}</div> : null}\n </div>\n )}\n </div>\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {showJump ? (\n <button\n type=\"button\"\n onClick={scrollToBottom}\n aria-label={labels?.scrollToBottom ?? 'Scroll to latest'}\n title={labels?.scrollToBottom ?? 'Scroll to latest'}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ArrowDown className=\"size-4\" aria-hidden />\n </button>\n ) : null}\n </div>\n )\n },\n)\n"]}
|
package/dist/combobox.js
CHANGED
package/dist/countries.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared country catalog
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Shared country catalog: the officially assigned ISO 3166-1 alpha-2
|
|
3
|
+
* list (249 entries) with CLDR English names and
|
|
4
|
+
* code-derived flag emoji, for any country picker (provider data
|
|
5
|
+
* residency, billing, locale pickers). Data-only export (library
|
|
6
|
+
* ADR-006; family ADR-0024) — apps render labels via
|
|
7
|
+
* `countryDisplayName` or their own i18n. Consumed via the
|
|
5
8
|
* `@neuronection/assistant-ui/countries` subpath.
|
|
9
|
+
*
|
|
10
|
+
* No legacy: `GB` is the United Kingdom code (never `UK`); no alias
|
|
11
|
+
* maps, no normalization shims (ADR-0024 policy: zero users, zero
|
|
12
|
+
* compat). `pickCountries` preserves caller order.
|
|
6
13
|
*/
|
|
7
14
|
interface CountryOption {
|
|
8
15
|
code: string;
|
|
@@ -10,6 +17,13 @@ interface CountryOption {
|
|
|
10
17
|
flag: string;
|
|
11
18
|
}
|
|
12
19
|
declare const COUNTRIES: CountryOption[];
|
|
13
|
-
declare
|
|
20
|
+
declare function findCountry(code?: string): CountryOption | undefined;
|
|
21
|
+
declare function pickCountries(codes: string[]): CountryOption[];
|
|
22
|
+
declare function getCountryFlag(code?: string): string;
|
|
23
|
+
/** Localized country name via Intl.DisplayNames; falls back to the
|
|
24
|
+
* catalog English name, then the raw code. Never throws. (`ZZ` is
|
|
25
|
+
* CLDR's "unknown region" sentinel — treated as unknown so callers
|
|
26
|
+
* get the raw-code fallback, matching `getCountryFlag`.) */
|
|
27
|
+
declare function countryDisplayName(code: string, locale?: string): string;
|
|
14
28
|
|
|
15
|
-
export { COUNTRIES, type CountryOption, getCountryFlag };
|
|
29
|
+
export { COUNTRIES, type CountryOption, countryDisplayName, findCountry, getCountryFlag, pickCountries };
|