@neuronection/assistant-ui 0.47.0 → 0.48.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.
@@ -1,303 +0,0 @@
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, Check, Pencil, Star, Trash2, Plus } 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({ profile }) {
27
- const letter = (profile.name.trim()[0] ?? "?").toUpperCase();
28
- return /* @__PURE__ */ jsx(
29
- "span",
30
- {
31
- "aria-hidden": true,
32
- className: "flex size-6 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold",
33
- style: profile.color ? { backgroundColor: `${profile.color}22`, color: profile.color } : {
34
- backgroundColor: "var(--as-secondary)",
35
- color: "var(--as-muted-fg)"
36
- },
37
- children: profile.color ? letter : /* @__PURE__ */ jsx(UserRound, { className: "size-3.5" })
38
- }
39
- );
40
- }
41
- var ProfileSwitcher = React.forwardRef(
42
- function ProfileSwitcher2({
43
- profiles,
44
- currentId,
45
- onSelect,
46
- onCreate,
47
- onRename,
48
- onDelete,
49
- onSetDefault,
50
- loading = false,
51
- error = null,
52
- align = "start",
53
- labels,
54
- icons,
55
- className
56
- }, ref) {
57
- const merged = { ...defaultLabels, ...labels };
58
- const TriggerIcon = icons?.trigger ?? UserRound;
59
- const CreateIcon = icons?.create ?? Plus;
60
- const RenameIcon = icons?.rename ?? Pencil;
61
- const SetDefaultIcon = icons?.setDefault ?? Star;
62
- const DeleteIcon = icons?.delete ?? Trash2;
63
- const EmptyIcon = icons?.empty ?? UserRound;
64
- const [open, setOpen] = React.useState(false);
65
- const [draftName, setDraftName] = React.useState("");
66
- const [renamingId, setRenamingId] = React.useState(null);
67
- const [renameDraft, setRenameDraft] = React.useState("");
68
- const renameInputRef = React.useRef(null);
69
- const current = profiles.find((profile) => profile.id === currentId) ?? profiles[0] ?? null;
70
- const close = React.useCallback(() => {
71
- setOpen(false);
72
- setRenamingId(null);
73
- setDraftName("");
74
- }, []);
75
- React.useEffect(() => {
76
- if (renamingId !== null) {
77
- renameInputRef.current?.focus();
78
- renameInputRef.current?.select();
79
- }
80
- }, [renamingId]);
81
- const startRename = (profile) => {
82
- setRenamingId(profile.id);
83
- setRenameDraft(profile.name);
84
- };
85
- const submitRename = async (profile) => {
86
- const name = renameDraft.trim();
87
- if (!name || name === profile.name) {
88
- setRenamingId(null);
89
- return;
90
- }
91
- await onRename(profile, name);
92
- setRenamingId(null);
93
- };
94
- const submitCreate = async (event) => {
95
- event.preventDefault();
96
- const name = draftName.trim();
97
- if (!name) return;
98
- await onCreate(name);
99
- setDraftName("");
100
- };
101
- return /* @__PURE__ */ jsx("div", { ref, "data-as": "profile-switcher", className: cn("inline-block", className), children: /* @__PURE__ */ jsxs(
102
- Popover,
103
- {
104
- open,
105
- onOpenChange: (next) => {
106
- setOpen(next);
107
- if (!next) {
108
- setRenamingId(null);
109
- setDraftName("");
110
- }
111
- },
112
- children: [
113
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
114
- Button,
115
- {
116
- type: "button",
117
- variant: "outline",
118
- size: "sm",
119
- "aria-haspopup": "dialog",
120
- "aria-label": merged.trigger,
121
- children: [
122
- /* @__PURE__ */ jsx(TriggerIcon, { "aria-hidden": true }),
123
- /* @__PURE__ */ jsx("span", { className: "max-w-32 truncate", children: current ? current.name : merged.empty })
124
- ]
125
- }
126
- ) }),
127
- /* @__PURE__ */ jsxs(
128
- PopoverContent,
129
- {
130
- align,
131
- role: "dialog",
132
- "aria-label": merged.panelTitle,
133
- className: "w-72 p-2",
134
- onEscapeKeyDown: (event) => {
135
- if (renamingId !== null) event.preventDefault();
136
- },
137
- children: [
138
- /* @__PURE__ */ jsx("div", { className: "px-2 pb-1 pt-1 text-xs font-medium text-[var(--as-muted-fg)]", children: merged.panelTitle }),
139
- loading ? /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-sm text-[var(--as-muted-fg)]", children: merged.loading }) : profiles.length === 0 ? /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 px-2 py-3 text-sm text-[var(--as-muted-fg)]", children: [
140
- /* @__PURE__ */ jsx(EmptyIcon, { "aria-hidden": true }),
141
- merged.empty
142
- ] }) : /* @__PURE__ */ jsx("ul", { className: "max-h-64 space-y-0.5 overflow-y-auto", children: profiles.map((profile) => {
143
- const isCurrent = current !== null && profile.id === current.id;
144
- return /* @__PURE__ */ jsx(
145
- "li",
146
- {
147
- className: "group flex items-center gap-1 rounded-[var(--as-radius-sm)] px-1 py-0.5 hover:bg-[var(--as-secondary)]",
148
- children: renamingId === profile.id ? /* @__PURE__ */ jsxs(
149
- "form",
150
- {
151
- className: "flex w-full items-center gap-1",
152
- onSubmit: (event) => {
153
- event.preventDefault();
154
- void submitRename(profile);
155
- },
156
- children: [
157
- /* @__PURE__ */ jsx(
158
- Input,
159
- {
160
- ref: renameInputRef,
161
- "aria-label": merged.rename(profile.name),
162
- placeholder: merged.renamePlaceholder,
163
- value: renameDraft,
164
- onChange: (event) => setRenameDraft(event.target.value),
165
- onKeyDown: (event) => {
166
- if (event.key === "Escape") {
167
- event.preventDefault();
168
- setRenamingId(null);
169
- }
170
- },
171
- className: "h-7 flex-1"
172
- }
173
- ),
174
- /* @__PURE__ */ jsx(
175
- Button,
176
- {
177
- type: "submit",
178
- size: "sm",
179
- disabled: !renameDraft.trim(),
180
- "aria-label": merged.renameSubmit,
181
- children: merged.renameSubmit
182
- }
183
- ),
184
- /* @__PURE__ */ jsx(
185
- Button,
186
- {
187
- type: "button",
188
- size: "sm",
189
- variant: "ghost",
190
- "aria-label": merged.cancel,
191
- onClick: () => setRenamingId(null),
192
- children: merged.cancel
193
- }
194
- )
195
- ]
196
- }
197
- ) : /* @__PURE__ */ jsxs(Fragment, { children: [
198
- /* @__PURE__ */ jsxs(
199
- "button",
200
- {
201
- type: "button",
202
- "aria-current": isCurrent || void 0,
203
- className: "flex min-w-0 flex-1 items-center gap-2 rounded-[var(--as-radius-sm)] px-1.5 py-1 text-left text-sm outline-none focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]",
204
- onClick: () => {
205
- onSelect(profile);
206
- close();
207
- },
208
- children: [
209
- /* @__PURE__ */ jsx(ProfileAvatar, { profile }),
210
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: profile.name }),
211
- isCurrent ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-0.5 text-[10px] text-[var(--as-muted-fg)]", children: [
212
- /* @__PURE__ */ jsx(Check, { "aria-hidden": true }),
213
- merged.currentBadge
214
- ] }) : null,
215
- profile.is_default ? /* @__PURE__ */ jsx("span", { className: "text-[10px] text-[var(--as-muted-fg)]", children: merged.defaultBadge }) : null
216
- ]
217
- }
218
- ),
219
- /* @__PURE__ */ jsx(
220
- Button,
221
- {
222
- type: "button",
223
- size: "sm",
224
- variant: "ghost",
225
- "aria-label": merged.rename(profile.name),
226
- onClick: () => startRename(profile),
227
- children: /* @__PURE__ */ jsx(RenameIcon, { "aria-hidden": true })
228
- }
229
- ),
230
- onSetDefault && !profile.is_default ? /* @__PURE__ */ jsx(
231
- Button,
232
- {
233
- type: "button",
234
- size: "sm",
235
- variant: "ghost",
236
- "aria-label": merged.setDefault(profile.name),
237
- onClick: () => void onSetDefault(profile),
238
- children: /* @__PURE__ */ jsx(SetDefaultIcon, { "aria-hidden": true })
239
- }
240
- ) : null,
241
- /* @__PURE__ */ jsx(
242
- Button,
243
- {
244
- type: "button",
245
- size: "sm",
246
- variant: "ghost",
247
- "aria-label": merged.delete(profile.name),
248
- onClick: () => void onDelete(profile),
249
- children: /* @__PURE__ */ jsx(DeleteIcon, { "aria-hidden": true })
250
- }
251
- )
252
- ] })
253
- },
254
- profile.id
255
- );
256
- }) }),
257
- error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "px-2 py-1 text-xs text-[var(--as-danger)]", children: error }) : null,
258
- /* @__PURE__ */ jsxs(
259
- "form",
260
- {
261
- className: "mt-2 flex items-center gap-1 border-t border-[var(--as-border)] pt-2",
262
- onSubmit: (event) => {
263
- void submitCreate(event);
264
- },
265
- children: [
266
- /* @__PURE__ */ jsx(
267
- Input,
268
- {
269
- "aria-label": merged.newProfile,
270
- placeholder: merged.newProfilePlaceholder,
271
- value: draftName,
272
- onChange: (event) => setDraftName(event.target.value),
273
- className: "h-7 flex-1"
274
- }
275
- ),
276
- /* @__PURE__ */ jsxs(
277
- Button,
278
- {
279
- type: "submit",
280
- size: "sm",
281
- disabled: !draftName.trim(),
282
- "aria-label": merged.create,
283
- children: [
284
- /* @__PURE__ */ jsx(CreateIcon, { "aria-hidden": true }),
285
- merged.create
286
- ]
287
- }
288
- )
289
- ]
290
- }
291
- )
292
- ]
293
- }
294
- )
295
- ]
296
- }
297
- ) });
298
- }
299
- );
300
-
301
- export { ProfileSwitcher };
302
- //# sourceMappingURL=chunk-C5OAZ2AW.js.map
303
- //# sourceMappingURL=chunk-C5OAZ2AW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/profile-switcher/ProfileSwitcher.tsx"],"names":["ProfileSwitcher"],"mappings":"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","file":"chunk-C5OAZ2AW.js","sourcesContent":["import * as React from 'react'\nimport {\n Check,\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({ profile }: { profile: ProfileItem }) {\n const letter = (profile.name.trim()[0] ?? '?').toUpperCase()\n return (\n <span\n aria-hidden\n className=\"flex size-6 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold\"\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 ? letter : <UserRound className=\"size-3.5\" />}\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 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 variant=\"outline\"\n size=\"sm\"\n aria-haspopup=\"dialog\"\n aria-label={merged.trigger}\n >\n <TriggerIcon aria-hidden />\n <span className=\"max-w-32 truncate\">{current ? current.name : merged.empty}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align={align}\n role=\"dialog\"\n aria-label={merged.panelTitle}\n className=\"w-72 p-2\"\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=\"px-2 pb-1 pt-1 text-xs font-medium text-[var(--as-muted-fg)]\">\n {merged.panelTitle}\n </div>\n {loading ? (\n <p className=\"px-2 py-3 text-sm text-[var(--as-muted-fg)]\">{merged.loading}</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 />\n {merged.empty}\n </p>\n ) : (\n <ul className=\"max-h-64 space-y-0.5 overflow-y-auto\">\n {profiles.map((profile) => {\n const isCurrent = current !== null && profile.id === current.id\n return (\n <li\n key={profile.id}\n className=\"group flex items-center gap-1 rounded-[var(--as-radius-sm)] px-1 py-0.5 hover:bg-[var(--as-secondary)]\"\n >\n {renamingId === profile.id ? (\n <form\n className=\"flex w-full items-center gap-1\"\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-7 flex-1\"\n />\n <Button\n type=\"submit\"\n size=\"sm\"\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 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 className=\"flex min-w-0 flex-1 items-center gap-2 rounded-[var(--as-radius-sm)] px-1.5 py-1 text-left text-sm outline-none focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n onClick={() => {\n onSelect(profile)\n close()\n }}\n >\n <ProfileAvatar profile={profile} />\n <span className=\"min-w-0 flex-1 truncate\">{profile.name}</span>\n {isCurrent ? (\n <span className=\"inline-flex items-center gap-0.5 text-[10px] text-[var(--as-muted-fg)]\">\n <Check aria-hidden />\n {merged.currentBadge}\n </span>\n ) : null}\n {profile.is_default ? (\n <span className=\"text-[10px] text-[var(--as-muted-fg)]\">\n {merged.defaultBadge}\n </span>\n ) : null}\n </button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n aria-label={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=\"sm\"\n variant=\"ghost\"\n aria-label={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=\"sm\"\n variant=\"ghost\"\n aria-label={merged.delete(profile.name)}\n onClick={() => void onDelete(profile)}\n >\n <DeleteIcon aria-hidden />\n </Button>\n </>\n )}\n </li>\n )\n })}\n </ul>\n )}\n {error ? (\n <p role=\"alert\" className=\"px-2 py-1 text-xs text-[var(--as-danger)]\">\n {error}\n </p>\n ) : null}\n <form\n className=\"mt-2 flex items-center gap-1 border-t border-[var(--as-border)] pt-2\"\n onSubmit={(event) => {\n void submitCreate(event)\n }}\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-7 flex-1\"\n />\n <Button\n type=\"submit\"\n size=\"sm\"\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 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat-message/ChatMessageEditor.tsx","../src/components/chat-message/MessageVariantSwitcher.tsx","../src/components/chat-message/ChatMessage.tsx"],"names":["ChatMessageEditor","React2","MessageVariantSwitcher","jsxs","jsx","React3","ChatMessage"],"mappings":"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","file":"chunk-EAJU4LFG.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\n\nexport interface ChatMessageEditorLabels {\n save: string\n cancel: string\n ariaLabel: string\n}\n\nexport interface ChatMessageEditorProps {\n value: string\n onValueChange: (value: string) => void\n /** Save & resend — branches the tree (family `edit` endpoint) and reruns the turn. */\n onSubmit: () => void\n onCancel: () => void\n submitDisabled?: boolean\n rows?: number\n labels?: Partial<ChatMessageEditorLabels>\n className?: string\n}\n\n/**\n * Inline user-prompt editor for the edit-and-resend flow (study pattern):\n * controlled textarea, Cmd/Ctrl+Enter saves, Escape cancels.\n */\nexport const ChatMessageEditor = React.forwardRef<HTMLDivElement, ChatMessageEditorProps>(\n function ChatMessageEditor(\n { value, onValueChange, onSubmit, onCancel, submitDisabled = false, rows = 3, labels, className },\n ref,\n ) {\n const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onCancel()\n return\n }\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n if (!submitDisabled) {\n onSubmit()\n }\n }\n }\n\n return (\n <div ref={ref} data-as=\"chat-message-editor\" className={cn('flex w-full flex-col gap-2', className)}>\n <textarea\n value={value}\n rows={rows}\n aria-label={labels?.ariaLabel ?? 'Edit message'}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"w-full resize-y rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n />\n <div className=\"flex items-center justify-end gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {labels?.cancel ?? 'Cancel'}\n </Button>\n <Button size=\"sm\" disabled={submitDisabled} onClick={onSubmit}>\n {labels?.save ?? 'Save & resend'}\n </Button>\n </div>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\n\nimport type { ChatMessageVariants } from '../chat-core/types'\nimport { cn } from '../../lib/utils'\n\nexport interface MessageVariantSwitcherLabels {\n group: string\n variantOf: (index: number, count: number) => string\n previous: string\n next: string\n}\n\nexport interface MessageVariantSwitcherProps {\n variants: ChatMessageVariants\n /** Flip the parent's active-child pointer to the sibling id (family `select` endpoint). */\n onSelect: (messageId: string) => void\n labels?: Partial<MessageVariantSwitcherLabels>\n className?: string\n}\n\n/**\n * The `‹ n/N ›` sibling-variant switcher under a branched message\n * (study's inline switcher, family branching contract).\n */\nexport const MessageVariantSwitcher = React.forwardRef<HTMLDivElement, MessageVariantSwitcherProps>(\n function MessageVariantSwitcher({ variants, onSelect, labels, className }, ref) {\n const { index, count, siblingIds } = variants\n const previousId = index > 1 ? siblingIds[index - 2] : undefined\n const nextId = index < count ? siblingIds[index] : undefined\n\n const select = (event: React.MouseEvent<HTMLButtonElement>, messageId: string | undefined) => {\n event.stopPropagation()\n if (messageId !== undefined) {\n onSelect(messageId)\n }\n }\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={labels?.group ?? 'Message variants'}\n data-as=\"message-variant-switcher\"\n className={cn('flex items-center gap-0.5 text-xs text-[var(--as-muted-fg)]', className)}\n >\n <button\n type=\"button\"\n disabled={previousId === undefined}\n aria-label={labels?.previous ?? 'Previous variant'}\n title={labels?.previous ?? 'Previous variant'}\n onClick={(event) => select(event, previousId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronLeft className=\"size-3.5\" aria-hidden />\n </button>\n <span className=\"tabular-nums\" title={labels?.variantOf?.(index, count) ?? `Variant ${index} of ${count}`}>\n {index}/{count}\n </span>\n <button\n type=\"button\"\n disabled={nextId === undefined}\n aria-label={labels?.next ?? 'Next variant'}\n title={labels?.next ?? 'Next variant'}\n onClick={(event) => select(event, nextId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronRight className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { Copy, Pencil, RotateCcw, TriangleAlert } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\nimport type { ChatError, ChatMessageVariants, ChatRole } from '../chat-core/types'\nimport { ChatMessageEditor, type ChatMessageEditorLabels } from './ChatMessageEditor'\nimport { MessageVariantSwitcher, type MessageVariantSwitcherLabels } from './MessageVariantSwitcher'\n\nexport interface ChatMessageAction {\n key: string\n label: string\n icon?: LucideIcon\n onClick: () => void\n danger?: boolean\n}\n\nexport interface ChatMessageActions {\n onCopy?: () => void\n onEdit?: () => void\n onRegenerate?: () => void\n onRetry?: () => void\n /** Extra icon actions (app-specific). */\n extras?: ChatMessageAction[]\n}\n\nexport interface ChatMessageLabels {\n copy: string\n edit: string\n regenerate: string\n retry: string\n interrupted: string\n error: string\n}\n\nexport interface ChatMessageProps {\n role: ChatRole\n /** Usually a `MarkdownSurface`; any node graph renders here. */\n content: React.ReactNode\n /** Thinking block slot (usually `ChatReasoning`). */\n reasoning?: React.ReactNode\n /** Tool cards / HITL cards below the content. */\n children?: React.ReactNode\n status?: 'streaming' | 'done' | 'error' | 'interrupted'\n error?: ChatError\n actions?: ChatMessageActions\n /** Edit-and-resend mode for user messages (renders `ChatMessageEditor`). */\n editing?: false | { value: string; onValueChange: (value: string) => void; onSubmit: () => void; onCancel: () => void; submitDisabled?: boolean }\n variants?: ChatMessageVariants\n onSelectVariant?: (messageId: string) => void\n /** Badge row (model, latency, tokens — app-defined). */\n meta?: React.ReactNode\n /** Deep-link chip row (career references, health citations). */\n chips?: React.ReactNode\n /** Attachment rail above the content. */\n attachments?: React.ReactNode\n labels?: Partial<ChatMessageLabels & ChatMessageEditorLabels & MessageVariantSwitcherLabels>\n compact?: boolean\n className?: string\n}\n\nconst actionButtonClass =\n 'rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]'\n\n/**\n * The family chat bubble: role-aligned, hover action row (copy / edit /\n * regenerate + app extras), variant switcher under branched messages,\n * reasoning and below-content slots, inline edit-and-resend, error +\n * interrupted states. Presentational — state lives app-side.\n */\nexport const ChatMessage = React.forwardRef<HTMLDivElement, ChatMessageProps>(\n function ChatMessage(\n {\n role,\n content,\n reasoning,\n children,\n status = 'done',\n error,\n actions,\n editing = false,\n variants,\n onSelectVariant,\n meta,\n chips,\n attachments,\n labels,\n compact = false,\n className,\n },\n ref,\n ) {\n const isUser = role === 'user'\n const isSystem = role === 'system'\n const showActions =\n actions !== undefined && (actions.onCopy !== undefined || actions.onEdit !== undefined || actions.onRegenerate !== undefined || (actions.extras?.length ?? 0) > 0)\n const editorLabels = { save: labels?.save, cancel: labels?.cancel, ariaLabel: labels?.ariaLabel }\n const switcherLabels = { group: labels?.group, variantOf: labels?.variantOf, previous: labels?.previous, next: labels?.next }\n\n if (isSystem) {\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n className={cn('flex justify-center', className)}\n >\n <div className=\"rounded-full border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-1 text-xs text-[var(--as-muted-fg)]\">\n {content}\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n data-status={status}\n className={cn('group/message flex w-full flex-col', isUser ? 'items-end' : 'items-start', className)}\n >\n {attachments ? <div className=\"mb-1.5 flex w-full flex-wrap justify-end gap-1.5\">{attachments}</div> : null}\n <div\n className={cn(\n 'relative flex max-w-[92%] flex-col gap-1.5 rounded-[var(--as-radius)] px-3 py-2 text-sm',\n compact && 'px-2.5 py-1.5',\n isUser\n ? 'rounded-br-[var(--as-radius-sm)] bg-[var(--as-primary)] text-[var(--as-primary-fg)]'\n : 'rounded-bl-[var(--as-radius-sm)] bg-[var(--as-muted)] text-[var(--as-fg)]',\n )}\n >\n {reasoning ? <div className=\"not-prose\">{reasoning}</div> : null}\n {editing ? (\n <ChatMessageEditor\n value={editing.value}\n onValueChange={editing.onValueChange}\n onSubmit={editing.onSubmit}\n onCancel={editing.onCancel}\n submitDisabled={editing.submitDisabled}\n labels={editorLabels}\n />\n ) : (\n <div className=\"min-w-0\">{content}</div>\n )}\n {status === 'interrupted' ? (\n <span className=\"self-start rounded-full bg-[var(--as-warning)]/15 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-[var(--as-warning)]\">\n {labels?.interrupted ?? 'Stopped'}\n </span>\n ) : null}\n {status === 'error' && error ? (\n <div\n role=\"alert\"\n className=\"flex flex-col gap-1 rounded-[var(--as-radius)] border border-[var(--as-danger)]/40 bg-[var(--as-danger)]/10 px-2.5 py-1.5 text-xs text-[var(--as-danger)]\"\n >\n <span className=\"font-mono font-semibold uppercase tracking-wide\">{error.code}</span>\n <span className=\"whitespace-pre-wrap break-words\">{error.message}</span>\n {error.retryable && actions?.onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"self-start\" onClick={actions.onRetry}>\n {labels?.retry ?? 'Retry'}\n </Button>\n ) : null}\n </div>\n ) : null}\n {chips ? <div className=\"flex flex-wrap gap-1.5\">{chips}</div> : null}\n {children ? <div className=\"flex flex-col gap-1.5\">{children}</div> : null}\n {showActions && !editing ? (\n <div\n className={cn(\n 'absolute top-1 flex items-center gap-0.5 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] p-0.5 opacity-0 shadow-[var(--as-shadow-1)] transition-opacity focus-within:opacity-100 group-hover/message:opacity-100',\n isUser ? '-left-9' : '-right-9',\n )}\n >\n {actions?.onCopy ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.copy ?? 'Copy'} title={labels?.copy ?? 'Copy'} onClick={actions.onCopy}>\n <Copy className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.onEdit ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.edit ?? 'Edit'} title={labels?.edit ?? 'Edit'} onClick={actions.onEdit}>\n <Pencil className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.onRegenerate ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.regenerate ?? 'Regenerate'} title={labels?.regenerate ?? 'Regenerate'} onClick={actions.onRegenerate}>\n <RotateCcw className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.extras?.map((extra) => (\n <button\n key={extra.key}\n type=\"button\"\n className={cn(actionButtonClass, extra.danger && 'hover:text-[var(--as-danger)]')}\n aria-label={extra.label}\n title={extra.label}\n onClick={extra.onClick}\n >\n {extra.icon ? <extra.icon className=\"size-3.5\" aria-hidden /> : <TriangleAlert className=\"size-3.5\" aria-hidden />}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n {meta ? <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 px-1 text-[10px] text-[var(--as-muted-fg)]\">{meta}</div> : null}\n {variants && variants.count > 1 && onSelectVariant ? (\n <MessageVariantSwitcher variants={variants} onSelect={onSelectVariant} labels={switcherLabels} className=\"mt-0.5 px-1\" />\n ) : null}\n </div>\n )\n },\n)\n"]}