@agent-native/toolkit 0.6.0 → 0.8.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 +17 -1
- package/agent-native.eject.json +411 -0
- package/dist/chat-history/ChatHistoryList.d.ts +103 -0
- package/dist/chat-history/ChatHistoryList.d.ts.map +1 -0
- package/dist/chat-history/ChatHistoryList.js +109 -0
- package/dist/chat-history/ChatHistoryList.js.map +1 -0
- package/dist/chat-history/ChatHistoryList.spec.d.ts +2 -0
- package/dist/chat-history/ChatHistoryList.spec.d.ts.map +1 -0
- package/dist/chat-history/ChatHistoryList.spec.js +283 -0
- package/dist/chat-history/ChatHistoryList.spec.js.map +1 -0
- package/dist/chat-history/index.d.ts +2 -0
- package/dist/chat-history/index.d.ts.map +1 -0
- package/dist/chat-history/index.js +2 -0
- package/dist/chat-history/index.js.map +1 -0
- package/dist/chat-history.css +314 -0
- package/package.json +20 -1
- package/src/app-shell/header-actions.tsx +84 -0
- package/src/app-shell/index.ts +1 -0
- package/src/chat-history/ChatHistoryList.spec.tsx +453 -0
- package/src/chat-history/ChatHistoryList.tsx +469 -0
- package/src/chat-history/index.ts +7 -0
- package/src/chat-history.css +314 -0
- package/src/collab-ui/AgentPresenceChip.tsx +69 -0
- package/src/collab-ui/LiveCursorOverlay.tsx +241 -0
- package/src/collab-ui/PresenceBar.tsx +346 -0
- package/src/collab-ui/RecentEditHighlights.tsx +225 -0
- package/src/collab-ui/RemoteSelectionRings.tsx +227 -0
- package/src/collab-ui/agent-identity.ts +16 -0
- package/src/collab-ui/index.ts +39 -0
- package/src/collab-ui/lead-client.ts +32 -0
- package/src/collab-ui/types.spec.ts +18 -0
- package/src/collab-ui/types.ts +96 -0
- package/src/composer/AgentComposerFrame.tsx +59 -0
- package/src/composer/ComposerPlusMenu.tsx +983 -0
- package/src/composer/MentionPopover.tsx +412 -0
- package/src/composer/PastedTextChip.tsx +150 -0
- package/src/composer/PromptComposer.spec.ts +73 -0
- package/src/composer/PromptComposer.tsx +718 -0
- package/src/composer/RealtimeVoiceMode.spec.tsx +771 -0
- package/src/composer/RealtimeVoiceMode.tsx +856 -0
- package/src/composer/TiptapComposer.spec.ts +390 -0
- package/src/composer/TiptapComposer.tsx +2936 -0
- package/src/composer/VoiceButton.spec.ts +33 -0
- package/src/composer/VoiceButton.tsx +255 -0
- package/src/composer/asset-picker-url.spec.ts +56 -0
- package/src/composer/asset-picker-url.ts +80 -0
- package/src/composer/attachment-accept.spec.ts +22 -0
- package/src/composer/attachment-accept.ts +71 -0
- package/src/composer/draft-key.spec.ts +19 -0
- package/src/composer/draft-key.ts +7 -0
- package/src/composer/extensions/FileReference.tsx +55 -0
- package/src/composer/extensions/MentionReference.tsx +93 -0
- package/src/composer/extensions/SkillReference.tsx +56 -0
- package/src/composer/index.ts +79 -0
- package/src/composer/pasted-text.spec.ts +162 -0
- package/src/composer/pasted-text.ts +160 -0
- package/src/composer/prompt-attachments.spec.ts +80 -0
- package/src/composer/prompt-attachments.ts +93 -0
- package/src/composer/realtime-voice-audio-level.spec.ts +32 -0
- package/src/composer/realtime-voice-audio-level.ts +64 -0
- package/src/composer/realtime-voice-transcript.spec.ts +95 -0
- package/src/composer/realtime-voice-transcript.ts +134 -0
- package/src/composer/runtime-adapters.tsx +343 -0
- package/src/composer/types.ts +66 -0
- package/src/composer/use-file-search.ts +64 -0
- package/src/composer/use-mention-search.ts +90 -0
- package/src/composer/use-skills.ts +45 -0
- package/src/composer/useRealtimeVoiceMode.spec.ts +818 -0
- package/src/composer/useRealtimeVoiceMode.tsx +2117 -0
- package/src/composer/useVoiceDictation.spec.ts +45 -0
- package/src/composer/useVoiceDictation.ts +1191 -0
- package/src/context-ui/ContextMeter.tsx +101 -0
- package/src/context-ui/ContextSegmentRow.tsx +184 -0
- package/src/context-ui/ContextTreemap.tsx +125 -0
- package/src/context-ui/ContextXRayPanel.tsx +377 -0
- package/src/context-ui/format.ts +42 -0
- package/src/context-ui/index.ts +15 -0
- package/src/context-ui/types.ts +43 -0
- package/src/design-tweaks/index.ts +1 -0
- package/src/design-tweaks/visual-style-controls.tsx +1084 -0
- package/src/editor/BubbleToolbar.tsx +253 -0
- package/src/editor/CodeBlockNode.tsx +254 -0
- package/src/editor/DragHandle.spec.ts +588 -0
- package/src/editor/DragHandle.ts +1437 -0
- package/src/editor/ImageExtension.roundtrip.spec.ts +117 -0
- package/src/editor/ImageExtension.ts +306 -0
- package/src/editor/RegistryBlockContext.tsx +107 -0
- package/src/editor/RegistryBlockNode.spec.ts +279 -0
- package/src/editor/RegistryBlockNode.tsx +652 -0
- package/src/editor/RichMarkdownEditor.collab.spec.ts +79 -0
- package/src/editor/RichMarkdownEditor.roundtrip.spec.ts +226 -0
- package/src/editor/RichMarkdownEditor.tsx +81 -0
- package/src/editor/RunId.ts +61 -0
- package/src/editor/SharedRichEditor.tsx +321 -0
- package/src/editor/SlashCommandMenu.tsx +310 -0
- package/src/editor/disableHistory.spec.ts +85 -0
- package/src/editor/extensions.ts +402 -0
- package/src/editor/gfmDoc.spec.ts +230 -0
- package/src/editor/gfmDoc.ts +92 -0
- package/src/editor/index.ts +93 -0
- package/src/editor/registrySlashCommands.ts +131 -0
- package/src/editor/structuralReorderUndo.spec.ts +144 -0
- package/src/editor/surgical-apply.spec.ts +279 -0
- package/src/editor/surgical-apply.ts +192 -0
- package/src/editor/useCollabReconcile.concurrent.spec.ts +422 -0
- package/src/editor/useCollabReconcile.idempotent.spec.ts +324 -0
- package/src/editor/useCollabReconcile.ts +589 -0
- package/src/editor.css +510 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/use-mobile.tsx +21 -0
- package/src/hooks/use-toast.ts +188 -0
- package/src/index.ts +8 -0
- package/src/onboarding/index.ts +1 -0
- package/src/provider.tsx +47 -0
- package/src/sharing/VisibilityBadge.spec.ts +96 -0
- package/src/sharing/VisibilityBadge.tsx +37 -0
- package/src/sharing/index.ts +4 -0
- package/src/styles.css +21 -0
- package/src/ui/accordion.tsx +56 -0
- package/src/ui/alert-dialog.tsx +141 -0
- package/src/ui/alert.tsx +59 -0
- package/src/ui/aspect-ratio.tsx +5 -0
- package/src/ui/avatar.tsx +48 -0
- package/src/ui/badge.tsx +37 -0
- package/src/ui/breadcrumb.tsx +115 -0
- package/src/ui/button.tsx +78 -0
- package/src/ui/calendar.tsx +214 -0
- package/src/ui/card.tsx +86 -0
- package/src/ui/carousel.tsx +260 -0
- package/src/ui/chart.tsx +375 -0
- package/src/ui/checkbox.tsx +28 -0
- package/src/ui/collapsible.tsx +9 -0
- package/src/ui/command.spec.tsx +51 -0
- package/src/ui/command.tsx +174 -0
- package/src/ui/context-menu.tsx +202 -0
- package/src/ui/date-picker.tsx +64 -0
- package/src/ui/dialog.spec.tsx +43 -0
- package/src/ui/dialog.tsx +146 -0
- package/src/ui/drawer.tsx +126 -0
- package/src/ui/dropdown-menu.tsx +218 -0
- package/src/ui/form.tsx +177 -0
- package/src/ui/hover-card.tsx +27 -0
- package/src/ui/index.ts +52 -0
- package/src/ui/input-otp.tsx +69 -0
- package/src/ui/input.tsx +22 -0
- package/src/ui/label.tsx +24 -0
- package/src/ui/logo.tsx +36 -0
- package/src/ui/menubar.tsx +235 -0
- package/src/ui/navigation-menu.tsx +128 -0
- package/src/ui/pagination.tsx +121 -0
- package/src/ui/popover.tsx +44 -0
- package/src/ui/progress.tsx +26 -0
- package/src/ui/radio-group.tsx +42 -0
- package/src/ui/resizable.tsx +43 -0
- package/src/ui/scroll-area.tsx +46 -0
- package/src/ui/select.tsx +158 -0
- package/src/ui/separator.tsx +29 -0
- package/src/ui/sheet.tsx +160 -0
- package/src/ui/sidebar.tsx +777 -0
- package/src/ui/skeleton.tsx +18 -0
- package/src/ui/slider.tsx +26 -0
- package/src/ui/sonner.tsx +58 -0
- package/src/ui/spinner.tsx +17 -0
- package/src/ui/switch.tsx +27 -0
- package/src/ui/table.tsx +117 -0
- package/src/ui/tabs.tsx +53 -0
- package/src/ui/textarea.tsx +23 -0
- package/src/ui/toast.tsx +127 -0
- package/src/ui/toaster.tsx +33 -0
- package/src/ui/toggle-group.tsx +59 -0
- package/src/ui/toggle.tsx +43 -0
- package/src/ui/tooltip.tsx +53 -0
- package/src/ui/use-toast.ts +3 -0
- package/src/utils.ts +8 -0
package/README.md
CHANGED
|
@@ -25,6 +25,7 @@ and docs. Dispatch is a separate product rather than a Toolkit module.
|
|
|
25
25
|
|
|
26
26
|
```tsx
|
|
27
27
|
import { ToolkitProvider } from "@agent-native/toolkit/provider";
|
|
28
|
+
import { ChatHistoryList } from "@agent-native/toolkit/chat-history";
|
|
28
29
|
import { PresenceBar } from "@agent-native/toolkit/collab-ui";
|
|
29
30
|
import { ContextMeterView } from "@agent-native/toolkit/context-ui";
|
|
30
31
|
import { VisualTweakControl } from "@agent-native/toolkit/design-tweaks";
|
|
@@ -38,7 +39,22 @@ import { useSetHeaderActions } from "@agent-native/toolkit/app-shell";
|
|
|
38
39
|
|
|
39
40
|
Import `@agent-native/toolkit/styles.css` after Tailwind to include Toolkit's
|
|
40
41
|
source scanning. If an app renders `SharedRichEditor`, also import
|
|
41
|
-
`@agent-native/toolkit/editor.css`.
|
|
42
|
+
`@agent-native/toolkit/editor.css`. If an app renders `ChatHistoryList`, also
|
|
43
|
+
import `@agent-native/toolkit/chat-history.css`.
|
|
42
44
|
|
|
43
45
|
Inside template apps, prefer local adapters such as `@/components/ui/button` so
|
|
44
46
|
apps can replace their primitives without changing every callsite.
|
|
47
|
+
|
|
48
|
+
## Customize Or Take Ownership
|
|
49
|
+
|
|
50
|
+
Use public props, slots, callbacks, stable classes, and local adapters first.
|
|
51
|
+
If a product needs a deeper override, the published package includes readable
|
|
52
|
+
TypeScript under `node_modules/@agent-native/toolkit/src/`. Treat it as a
|
|
53
|
+
read-only reference: copy the smallest component or helper into app-owned
|
|
54
|
+
source, change the app import, and customize that copy. Do not edit
|
|
55
|
+
`node_modules` or deep-import private `src` files at runtime.
|
|
56
|
+
|
|
57
|
+
Keep Core runtime contracts intact when taking ownership of Toolkit UI. Actions,
|
|
58
|
+
application state, auth/access, persistence, agent execution, chat transport,
|
|
59
|
+
and page-to-sidebar thread handoff remain on their public Core APIs. Copied UI
|
|
60
|
+
is an app-owned snapshot and will not receive upstream fixes automatically.
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": 1,
|
|
3
|
+
"package": "@agent-native/toolkit",
|
|
4
|
+
"catalogs": ["toolkit-ui", "setup-readiness-ui"],
|
|
5
|
+
"units": [
|
|
6
|
+
{
|
|
7
|
+
"id": "toolkit/root",
|
|
8
|
+
"label": "Complete Toolkit source",
|
|
9
|
+
"catalog": "toolkit-ui",
|
|
10
|
+
"catalogItems": ["root"],
|
|
11
|
+
"entrypoints": ["."],
|
|
12
|
+
"strategy": "source-copy",
|
|
13
|
+
"sourceEntries": ["src/index.ts"],
|
|
14
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
15
|
+
"dependencies": [
|
|
16
|
+
"@assistant-ui/react",
|
|
17
|
+
"@radix-ui/react-accordion",
|
|
18
|
+
"@radix-ui/react-alert-dialog",
|
|
19
|
+
"@radix-ui/react-aspect-ratio",
|
|
20
|
+
"@radix-ui/react-avatar",
|
|
21
|
+
"@radix-ui/react-checkbox",
|
|
22
|
+
"@radix-ui/react-collapsible",
|
|
23
|
+
"@radix-ui/react-context-menu",
|
|
24
|
+
"@radix-ui/react-dialog",
|
|
25
|
+
"@radix-ui/react-dropdown-menu",
|
|
26
|
+
"@radix-ui/react-hover-card",
|
|
27
|
+
"@radix-ui/react-label",
|
|
28
|
+
"@radix-ui/react-menubar",
|
|
29
|
+
"@radix-ui/react-navigation-menu",
|
|
30
|
+
"@radix-ui/react-popover",
|
|
31
|
+
"@radix-ui/react-progress",
|
|
32
|
+
"@radix-ui/react-radio-group",
|
|
33
|
+
"@radix-ui/react-scroll-area",
|
|
34
|
+
"@radix-ui/react-select",
|
|
35
|
+
"@radix-ui/react-separator",
|
|
36
|
+
"@radix-ui/react-slider",
|
|
37
|
+
"@radix-ui/react-slot",
|
|
38
|
+
"@radix-ui/react-switch",
|
|
39
|
+
"@radix-ui/react-tabs",
|
|
40
|
+
"@radix-ui/react-toast",
|
|
41
|
+
"@radix-ui/react-toggle",
|
|
42
|
+
"@radix-ui/react-toggle-group",
|
|
43
|
+
"@radix-ui/react-tooltip",
|
|
44
|
+
"@tabler/icons-react",
|
|
45
|
+
"@tiptap/core",
|
|
46
|
+
"@tiptap/extension-code-block-lowlight",
|
|
47
|
+
"@tiptap/extension-collaboration",
|
|
48
|
+
"@tiptap/extension-collaboration-caret",
|
|
49
|
+
"@tiptap/extension-image",
|
|
50
|
+
"@tiptap/extension-link",
|
|
51
|
+
"@tiptap/extension-placeholder",
|
|
52
|
+
"@tiptap/extension-table",
|
|
53
|
+
"@tiptap/extension-table-cell",
|
|
54
|
+
"@tiptap/extension-table-header",
|
|
55
|
+
"@tiptap/extension-table-row",
|
|
56
|
+
"@tiptap/extension-task-item",
|
|
57
|
+
"@tiptap/extension-task-list",
|
|
58
|
+
"@tiptap/pm",
|
|
59
|
+
"@tiptap/react",
|
|
60
|
+
"@tiptap/starter-kit",
|
|
61
|
+
"@tiptap/y-tiptap",
|
|
62
|
+
"class-variance-authority",
|
|
63
|
+
"clsx",
|
|
64
|
+
"cmdk",
|
|
65
|
+
"date-fns",
|
|
66
|
+
"embla-carousel-react",
|
|
67
|
+
"highlight.js",
|
|
68
|
+
"input-otp",
|
|
69
|
+
"lowlight",
|
|
70
|
+
"next-themes",
|
|
71
|
+
"react",
|
|
72
|
+
"react-day-picker",
|
|
73
|
+
"react-dom",
|
|
74
|
+
"react-hook-form",
|
|
75
|
+
"react-resizable-panels",
|
|
76
|
+
"recharts",
|
|
77
|
+
"sonner",
|
|
78
|
+
"tailwind-merge",
|
|
79
|
+
"tiptap-markdown",
|
|
80
|
+
"vaul",
|
|
81
|
+
"y-protocols",
|
|
82
|
+
"yjs"
|
|
83
|
+
],
|
|
84
|
+
"protectedImports": ["@agent-native/core/client"],
|
|
85
|
+
"verification": ["pnpm typecheck"]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "toolkit/app-shell",
|
|
89
|
+
"label": "Application shell",
|
|
90
|
+
"catalog": "toolkit-ui",
|
|
91
|
+
"catalogItems": ["app-shell"],
|
|
92
|
+
"entrypoints": ["./app-shell", "./app-shell/*"],
|
|
93
|
+
"strategy": "source-copy",
|
|
94
|
+
"sourceEntries": ["src/app-shell"],
|
|
95
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
96
|
+
"dependencies": ["react"],
|
|
97
|
+
"verification": ["pnpm typecheck"]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "toolkit/collab-ui",
|
|
101
|
+
"label": "Collaboration UI",
|
|
102
|
+
"catalog": "toolkit-ui",
|
|
103
|
+
"catalogItems": ["collab-ui"],
|
|
104
|
+
"entrypoints": ["./collab-ui", "./collab-ui/*"],
|
|
105
|
+
"strategy": "source-copy",
|
|
106
|
+
"sourceEntries": ["src/collab-ui"],
|
|
107
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
108
|
+
"dependencies": [
|
|
109
|
+
"@radix-ui/react-tooltip",
|
|
110
|
+
"clsx",
|
|
111
|
+
"react",
|
|
112
|
+
"tailwind-merge",
|
|
113
|
+
"y-protocols"
|
|
114
|
+
],
|
|
115
|
+
"verification": ["pnpm typecheck"]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": "toolkit/chat-history",
|
|
119
|
+
"label": "Chat history",
|
|
120
|
+
"catalog": "toolkit-ui",
|
|
121
|
+
"catalogItems": ["chat-history"],
|
|
122
|
+
"entrypoints": ["./chat-history", "./chat-history/*"],
|
|
123
|
+
"strategy": "source-copy",
|
|
124
|
+
"sourceEntries": ["src/chat-history"],
|
|
125
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
126
|
+
"styles": [
|
|
127
|
+
{
|
|
128
|
+
"entrypoint": "./chat-history.css",
|
|
129
|
+
"source": "src/chat-history.css"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"dependencies": [
|
|
133
|
+
"@tabler/icons-react",
|
|
134
|
+
"clsx",
|
|
135
|
+
"react",
|
|
136
|
+
"tailwind-merge"
|
|
137
|
+
],
|
|
138
|
+
"verification": ["pnpm typecheck"]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "toolkit/composer",
|
|
142
|
+
"label": "Agent composer",
|
|
143
|
+
"catalog": "toolkit-ui",
|
|
144
|
+
"catalogItems": ["composer"],
|
|
145
|
+
"entrypoints": ["./composer", "./composer/*"],
|
|
146
|
+
"strategy": "source-copy",
|
|
147
|
+
"sourceEntries": ["src/composer"],
|
|
148
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
149
|
+
"dependencies": [
|
|
150
|
+
"@assistant-ui/react",
|
|
151
|
+
"@radix-ui/react-popover",
|
|
152
|
+
"@radix-ui/react-tooltip",
|
|
153
|
+
"@tabler/icons-react",
|
|
154
|
+
"@tiptap/core",
|
|
155
|
+
"@tiptap/extension-placeholder",
|
|
156
|
+
"@tiptap/pm",
|
|
157
|
+
"@tiptap/react",
|
|
158
|
+
"@tiptap/starter-kit",
|
|
159
|
+
"clsx",
|
|
160
|
+
"react",
|
|
161
|
+
"react-dom",
|
|
162
|
+
"tailwind-merge"
|
|
163
|
+
],
|
|
164
|
+
"protectedImports": [
|
|
165
|
+
"@agent-native/toolkit/ui/button",
|
|
166
|
+
"@agent-native/toolkit/ui/select",
|
|
167
|
+
"@agent-native/toolkit/ui/skeleton"
|
|
168
|
+
],
|
|
169
|
+
"verification": ["pnpm typecheck"]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"id": "toolkit/context-ui",
|
|
173
|
+
"label": "Context inspection UI",
|
|
174
|
+
"catalog": "toolkit-ui",
|
|
175
|
+
"catalogItems": ["context-ui"],
|
|
176
|
+
"entrypoints": ["./context-ui"],
|
|
177
|
+
"strategy": "source-copy",
|
|
178
|
+
"sourceEntries": ["src/context-ui"],
|
|
179
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
180
|
+
"dependencies": [
|
|
181
|
+
"@radix-ui/react-popover",
|
|
182
|
+
"@radix-ui/react-tooltip",
|
|
183
|
+
"@tabler/icons-react",
|
|
184
|
+
"clsx",
|
|
185
|
+
"react",
|
|
186
|
+
"recharts",
|
|
187
|
+
"tailwind-merge"
|
|
188
|
+
],
|
|
189
|
+
"verification": ["pnpm typecheck"]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"id": "toolkit/design-tweaks",
|
|
193
|
+
"label": "Design tweak controls",
|
|
194
|
+
"catalog": "toolkit-ui",
|
|
195
|
+
"catalogItems": ["design-tweaks"],
|
|
196
|
+
"entrypoints": ["./design-tweaks"],
|
|
197
|
+
"strategy": "source-copy",
|
|
198
|
+
"sourceEntries": ["src/design-tweaks"],
|
|
199
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
200
|
+
"dependencies": [
|
|
201
|
+
"@radix-ui/react-popover",
|
|
202
|
+
"@tabler/icons-react",
|
|
203
|
+
"clsx",
|
|
204
|
+
"react",
|
|
205
|
+
"tailwind-merge"
|
|
206
|
+
],
|
|
207
|
+
"verification": ["pnpm typecheck"]
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"id": "toolkit/editor",
|
|
211
|
+
"label": "Rich editor",
|
|
212
|
+
"catalog": "toolkit-ui",
|
|
213
|
+
"catalogItems": ["editor"],
|
|
214
|
+
"entrypoints": ["./editor", "./editor/*"],
|
|
215
|
+
"strategy": "source-copy",
|
|
216
|
+
"sourceEntries": ["src/editor"],
|
|
217
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
218
|
+
"styles": [
|
|
219
|
+
{
|
|
220
|
+
"entrypoint": "./editor.css",
|
|
221
|
+
"source": "src/editor.css"
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"dependencies": [
|
|
225
|
+
"@tabler/icons-react",
|
|
226
|
+
"@radix-ui/react-popover",
|
|
227
|
+
"@radix-ui/react-tooltip",
|
|
228
|
+
"@tiptap/core",
|
|
229
|
+
"@tiptap/extension-code-block-lowlight",
|
|
230
|
+
"@tiptap/extension-collaboration",
|
|
231
|
+
"@tiptap/extension-collaboration-caret",
|
|
232
|
+
"@tiptap/extension-image",
|
|
233
|
+
"@tiptap/extension-link",
|
|
234
|
+
"@tiptap/extension-placeholder",
|
|
235
|
+
"@tiptap/extension-table",
|
|
236
|
+
"@tiptap/extension-table-cell",
|
|
237
|
+
"@tiptap/extension-table-header",
|
|
238
|
+
"@tiptap/extension-table-row",
|
|
239
|
+
"@tiptap/extension-task-item",
|
|
240
|
+
"@tiptap/extension-task-list",
|
|
241
|
+
"@tiptap/pm",
|
|
242
|
+
"@tiptap/react",
|
|
243
|
+
"@tiptap/starter-kit",
|
|
244
|
+
"clsx",
|
|
245
|
+
"highlight.js",
|
|
246
|
+
"lowlight",
|
|
247
|
+
"react",
|
|
248
|
+
"tailwind-merge",
|
|
249
|
+
"tiptap-markdown",
|
|
250
|
+
"y-protocols",
|
|
251
|
+
"yjs"
|
|
252
|
+
],
|
|
253
|
+
"protectedImports": ["@agent-native/core/client"],
|
|
254
|
+
"verification": ["pnpm typecheck"]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"id": "toolkit/hooks",
|
|
258
|
+
"label": "Frontend hooks",
|
|
259
|
+
"catalog": "toolkit-ui",
|
|
260
|
+
"catalogItems": ["hooks"],
|
|
261
|
+
"entrypoints": ["./hooks", "./hooks/*"],
|
|
262
|
+
"strategy": "source-copy",
|
|
263
|
+
"sourceEntries": ["src/hooks"],
|
|
264
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
265
|
+
"dependencies": [
|
|
266
|
+
"@radix-ui/react-toast",
|
|
267
|
+
"@tabler/icons-react",
|
|
268
|
+
"class-variance-authority",
|
|
269
|
+
"clsx",
|
|
270
|
+
"react",
|
|
271
|
+
"tailwind-merge"
|
|
272
|
+
],
|
|
273
|
+
"verification": ["pnpm typecheck"]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"id": "toolkit/onboarding",
|
|
277
|
+
"label": "Onboarding UI",
|
|
278
|
+
"catalog": "setup-readiness-ui",
|
|
279
|
+
"catalogItems": ["onboarding"],
|
|
280
|
+
"entrypoints": ["./onboarding", "./onboarding/*"],
|
|
281
|
+
"strategy": "source-copy",
|
|
282
|
+
"sourceEntries": ["src/onboarding"],
|
|
283
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
284
|
+
"verification": ["pnpm typecheck"]
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"id": "toolkit/provider",
|
|
288
|
+
"label": "Toolkit provider",
|
|
289
|
+
"catalog": "toolkit-ui",
|
|
290
|
+
"catalogItems": ["provider"],
|
|
291
|
+
"entrypoints": ["./provider"],
|
|
292
|
+
"strategy": "source-copy",
|
|
293
|
+
"sourceEntries": ["src/provider.tsx"],
|
|
294
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
295
|
+
"dependencies": [
|
|
296
|
+
"@radix-ui/react-slot",
|
|
297
|
+
"class-variance-authority",
|
|
298
|
+
"clsx",
|
|
299
|
+
"react",
|
|
300
|
+
"tailwind-merge"
|
|
301
|
+
],
|
|
302
|
+
"verification": ["pnpm typecheck"]
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"id": "toolkit/sharing",
|
|
306
|
+
"label": "Sharing UI",
|
|
307
|
+
"catalog": "toolkit-ui",
|
|
308
|
+
"catalogItems": ["sharing"],
|
|
309
|
+
"entrypoints": ["./sharing", "./sharing/*"],
|
|
310
|
+
"strategy": "source-copy",
|
|
311
|
+
"sourceEntries": ["src/sharing"],
|
|
312
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
313
|
+
"dependencies": ["@tabler/icons-react"],
|
|
314
|
+
"verification": ["pnpm typecheck"]
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"id": "toolkit/ui",
|
|
318
|
+
"label": "UI primitives",
|
|
319
|
+
"catalog": "toolkit-ui",
|
|
320
|
+
"catalogItems": ["ui"],
|
|
321
|
+
"entrypoints": ["./ui", "./ui/*"],
|
|
322
|
+
"strategy": "source-copy",
|
|
323
|
+
"sourceEntries": ["src/ui"],
|
|
324
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
325
|
+
"dependencies": [
|
|
326
|
+
"@radix-ui/react-accordion",
|
|
327
|
+
"@radix-ui/react-alert-dialog",
|
|
328
|
+
"@radix-ui/react-aspect-ratio",
|
|
329
|
+
"@radix-ui/react-avatar",
|
|
330
|
+
"@radix-ui/react-checkbox",
|
|
331
|
+
"@radix-ui/react-collapsible",
|
|
332
|
+
"@radix-ui/react-context-menu",
|
|
333
|
+
"@radix-ui/react-dialog",
|
|
334
|
+
"@radix-ui/react-dropdown-menu",
|
|
335
|
+
"@radix-ui/react-hover-card",
|
|
336
|
+
"@radix-ui/react-label",
|
|
337
|
+
"@radix-ui/react-menubar",
|
|
338
|
+
"@radix-ui/react-navigation-menu",
|
|
339
|
+
"@radix-ui/react-popover",
|
|
340
|
+
"@radix-ui/react-progress",
|
|
341
|
+
"@radix-ui/react-radio-group",
|
|
342
|
+
"@radix-ui/react-scroll-area",
|
|
343
|
+
"@radix-ui/react-select",
|
|
344
|
+
"@radix-ui/react-separator",
|
|
345
|
+
"@radix-ui/react-slider",
|
|
346
|
+
"@radix-ui/react-slot",
|
|
347
|
+
"@radix-ui/react-switch",
|
|
348
|
+
"@radix-ui/react-tabs",
|
|
349
|
+
"@radix-ui/react-toast",
|
|
350
|
+
"@radix-ui/react-toggle",
|
|
351
|
+
"@radix-ui/react-toggle-group",
|
|
352
|
+
"@radix-ui/react-tooltip",
|
|
353
|
+
"@tabler/icons-react",
|
|
354
|
+
"class-variance-authority",
|
|
355
|
+
"clsx",
|
|
356
|
+
"cmdk",
|
|
357
|
+
"date-fns",
|
|
358
|
+
"embla-carousel-react",
|
|
359
|
+
"input-otp",
|
|
360
|
+
"next-themes",
|
|
361
|
+
"react",
|
|
362
|
+
"react-day-picker",
|
|
363
|
+
"react-hook-form",
|
|
364
|
+
"react-resizable-panels",
|
|
365
|
+
"recharts",
|
|
366
|
+
"sonner",
|
|
367
|
+
"tailwind-merge",
|
|
368
|
+
"vaul"
|
|
369
|
+
],
|
|
370
|
+
"verification": ["pnpm typecheck"]
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"id": "toolkit/utils",
|
|
374
|
+
"label": "Class name utilities",
|
|
375
|
+
"catalog": "toolkit-ui",
|
|
376
|
+
"catalogItems": ["utils"],
|
|
377
|
+
"entrypoints": ["./utils"],
|
|
378
|
+
"strategy": "source-copy",
|
|
379
|
+
"sourceEntries": ["src/utils.ts"],
|
|
380
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
381
|
+
"dependencies": ["clsx", "tailwind-merge"],
|
|
382
|
+
"verification": ["pnpm typecheck"]
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"id": "toolkit/styles",
|
|
386
|
+
"label": "Toolkit Tailwind source styles",
|
|
387
|
+
"catalog": "toolkit-ui",
|
|
388
|
+
"catalogItems": ["styles"],
|
|
389
|
+
"entrypoints": [],
|
|
390
|
+
"strategy": "source-copy",
|
|
391
|
+
"targetRoot": "app/components/agent-native/toolkit",
|
|
392
|
+
"styles": [
|
|
393
|
+
{
|
|
394
|
+
"entrypoint": "./styles.css",
|
|
395
|
+
"source": "src/styles.css"
|
|
396
|
+
}
|
|
397
|
+
],
|
|
398
|
+
"verification": ["pnpm typecheck"]
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"id": "toolkit/migration-metadata",
|
|
402
|
+
"label": "Toolkit migration metadata",
|
|
403
|
+
"catalog": "toolkit-ui",
|
|
404
|
+
"catalogItems": ["migration-manifest"],
|
|
405
|
+
"entrypoints": ["./migration-manifest.json"],
|
|
406
|
+
"strategy": "protected-seam",
|
|
407
|
+
"seam": "@agent-native/toolkit/migration-manifest.json",
|
|
408
|
+
"protectedImports": ["@agent-native/toolkit/migration-manifest.json"]
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/** A single row in a chat history list. Purely data — no fetching, no
|
|
3
|
+
* assistant-ui context. Formatting (relative time, "Active"/"Open" labels,
|
|
4
|
+
* status spinners) is the caller's responsibility; hand in the already
|
|
5
|
+
* rendered node via `timestamp`. */
|
|
6
|
+
export interface ChatHistoryItem {
|
|
7
|
+
id: string;
|
|
8
|
+
title: React.ReactNode;
|
|
9
|
+
/** Plain-text form of `title`, used to seed the inline rename input.
|
|
10
|
+
* Only needed when `onRename` is supplied. */
|
|
11
|
+
titleText?: string;
|
|
12
|
+
/** Secondary line — e.g. a message preview. */
|
|
13
|
+
subtitle?: React.ReactNode;
|
|
14
|
+
/** Tertiary line — e.g. a scope/folder label. */
|
|
15
|
+
detail?: React.ReactNode;
|
|
16
|
+
/** Pre-formatted trailing value: a relative time, "Active"/"Open", or a
|
|
17
|
+
* status node (spinner, unread dot). This component does not format
|
|
18
|
+
* dates or compute status itself. */
|
|
19
|
+
timestamp?: React.ReactNode;
|
|
20
|
+
pinned?: boolean;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ChatHistorySection {
|
|
24
|
+
id: string;
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
items: ChatHistoryItem[];
|
|
27
|
+
}
|
|
28
|
+
export interface ChatHistoryListLabels {
|
|
29
|
+
options: string | ((item: ChatHistoryItem) => string);
|
|
30
|
+
renameInput: string | ((item: ChatHistoryItem) => string);
|
|
31
|
+
rename: string;
|
|
32
|
+
pin: string;
|
|
33
|
+
unpin: string;
|
|
34
|
+
delete: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ChatHistoryListProps {
|
|
37
|
+
/** Flat item list. Ignored when `sections` is provided. */
|
|
38
|
+
items?: ChatHistoryItem[];
|
|
39
|
+
/** Grouped item list (e.g. "This deck" / "All chats", or pinned/recent). */
|
|
40
|
+
sections?: ChatHistorySection[];
|
|
41
|
+
/** Id of the currently active/selected item — highlighted in the list. */
|
|
42
|
+
activeId?: string | null;
|
|
43
|
+
onSelect: (id: string) => void;
|
|
44
|
+
/** Fired on double-click / explicit "open" gesture, distinct from select. */
|
|
45
|
+
onOpen?: (id: string) => void;
|
|
46
|
+
/** Presence enables the pin/unpin row action. */
|
|
47
|
+
onTogglePin?: (id: string) => void;
|
|
48
|
+
/** Presence enables the inline "Rename" row action. */
|
|
49
|
+
onRename?: (id: string, nextTitle: string) => void;
|
|
50
|
+
/** Optional character limit for the inline rename input. */
|
|
51
|
+
renameMaxLength?: number;
|
|
52
|
+
/** Presence enables the "Delete" row action. */
|
|
53
|
+
onDelete?: (id: string) => void;
|
|
54
|
+
/** Escape hatch: fully custom row action menu content, replacing the
|
|
55
|
+
* built-in rename/pin/delete items. Still gated by the trigger button,
|
|
56
|
+
* which shows whenever this or any of the on* callbacks above is set. */
|
|
57
|
+
renderRowActions?: (item: ChatHistoryItem) => React.ReactNode;
|
|
58
|
+
/** App-specific actions inserted after pin and before delete. Call
|
|
59
|
+
* `closeMenu` before starting the action. */
|
|
60
|
+
renderAdditionalRowActions?: (item: ChatHistoryItem, closeMenu: () => void) => React.ReactNode;
|
|
61
|
+
/** Controlled search input. Omit `onSearchChange` to hide the search box
|
|
62
|
+
* entirely and let the host render its own (results are always supplied
|
|
63
|
+
* by the caller via `items`/`sections` either way). */
|
|
64
|
+
searchValue?: string;
|
|
65
|
+
onSearchChange?: (value: string) => void;
|
|
66
|
+
searchPlaceholder?: string;
|
|
67
|
+
searchInputRef?: React.Ref<HTMLInputElement>;
|
|
68
|
+
/** True while results are being fetched — shows `loadingLabel` instead of
|
|
69
|
+
* the list. */
|
|
70
|
+
loading?: boolean;
|
|
71
|
+
loadingLabel?: React.ReactNode;
|
|
72
|
+
/** Shown instead of the list when set (takes priority over `loading`). */
|
|
73
|
+
error?: React.ReactNode;
|
|
74
|
+
emptyLabel?: React.ReactNode;
|
|
75
|
+
/** Shown instead of `emptyLabel` when `searchValue` is non-empty. */
|
|
76
|
+
emptySearchLabel?: React.ReactNode;
|
|
77
|
+
/** Optional localized labels for row actions and their accessible controls. */
|
|
78
|
+
labels?: Partial<ChatHistoryListLabels>;
|
|
79
|
+
/** Rendered after the list, inside the scroll container (e.g. a
|
|
80
|
+
* "Load older chats" button). */
|
|
81
|
+
footer?: React.ReactNode;
|
|
82
|
+
/** "popover" (default) matches core's compact HistoryPopover list.
|
|
83
|
+
* "rail" is a denser variant with a solid active background, closer to
|
|
84
|
+
* a sidebar run rail. */
|
|
85
|
+
variant?: "popover" | "rail";
|
|
86
|
+
className?: string;
|
|
87
|
+
listClassName?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Presentational chat history list shared by the Core `HistoryPopover`
|
|
91
|
+
* and Agent-Native Code's run rail
|
|
92
|
+
* (code-agents-ui). Styling is driven by stable `an-chat-history*` class
|
|
93
|
+
* names (see `@agent-native/toolkit/chat-history.css`) rather than Tailwind utilities
|
|
94
|
+
* so the same component renders correctly in a Tailwind host and in
|
|
95
|
+
* code-agents-ui's plain-CSS host.
|
|
96
|
+
*
|
|
97
|
+
* This component owns no data: search filtering, pin/rename persistence,
|
|
98
|
+
* and time formatting all stay with the caller. It only renders whatever
|
|
99
|
+
* `items`/`sections` it is given, plus the optional search box and
|
|
100
|
+
* loading/empty/error states.
|
|
101
|
+
*/
|
|
102
|
+
export declare function ChatHistoryList({ items, sections, activeId, onSelect, onOpen, onTogglePin, onRename, renameMaxLength, onDelete, renderRowActions, renderAdditionalRowActions, searchValue, onSearchChange, searchPlaceholder, searchInputRef, loading, loadingLabel, error, emptyLabel, emptySearchLabel, labels, footer, variant, className, listClassName, }: ChatHistoryListProps): React.JSX.Element;
|
|
103
|
+
//# sourceMappingURL=ChatHistoryList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatHistoryList.d.ts","sourceRoot":"","sources":["../../src/chat-history/ChatHistoryList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconDots, IconPencil, IconPinned, IconPinnedOff, IconSearch, IconTrash, } from "@tabler/icons-react";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { cn } from "../utils.js";
|
|
5
|
+
const DEFAULT_LABELS = {
|
|
6
|
+
options: "Chat options",
|
|
7
|
+
renameInput: "Rename chat",
|
|
8
|
+
rename: "Rename",
|
|
9
|
+
pin: "Pin to top",
|
|
10
|
+
unpin: "Unpin from top",
|
|
11
|
+
delete: "Delete",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Presentational chat history list shared by the Core `HistoryPopover`
|
|
15
|
+
* and Agent-Native Code's run rail
|
|
16
|
+
* (code-agents-ui). Styling is driven by stable `an-chat-history*` class
|
|
17
|
+
* names (see `@agent-native/toolkit/chat-history.css`) rather than Tailwind utilities
|
|
18
|
+
* so the same component renders correctly in a Tailwind host and in
|
|
19
|
+
* code-agents-ui's plain-CSS host.
|
|
20
|
+
*
|
|
21
|
+
* This component owns no data: search filtering, pin/rename persistence,
|
|
22
|
+
* and time formatting all stay with the caller. It only renders whatever
|
|
23
|
+
* `items`/`sections` it is given, plus the optional search box and
|
|
24
|
+
* loading/empty/error states.
|
|
25
|
+
*/
|
|
26
|
+
export function ChatHistoryList({ items, sections, activeId = null, onSelect, onOpen, onTogglePin, onRename, renameMaxLength, onDelete, renderRowActions, renderAdditionalRowActions, searchValue, onSearchChange, searchPlaceholder = "Search chats...", searchInputRef, loading = false, loadingLabel = "Searching...", error, emptyLabel = "No chats yet", emptySearchLabel = "No matching chats", labels, footer, variant = "popover", className, listClassName, }) {
|
|
27
|
+
const resolvedLabels = {
|
|
28
|
+
options: labels?.options ?? DEFAULT_LABELS.options,
|
|
29
|
+
renameInput: labels?.renameInput ?? DEFAULT_LABELS.renameInput,
|
|
30
|
+
rename: labels?.rename ?? DEFAULT_LABELS.rename,
|
|
31
|
+
pin: labels?.pin ?? DEFAULT_LABELS.pin,
|
|
32
|
+
unpin: labels?.unpin ?? DEFAULT_LABELS.unpin,
|
|
33
|
+
delete: labels?.delete ?? DEFAULT_LABELS.delete,
|
|
34
|
+
};
|
|
35
|
+
const resolvedSections = sections ?? (items ? [{ id: "default", items }] : []);
|
|
36
|
+
const totalCount = resolvedSections.reduce((sum, section) => sum + section.items.length, 0);
|
|
37
|
+
const hasSearchValue = Boolean(searchValue?.trim());
|
|
38
|
+
return (_jsxs("div", { className: cn("an-chat-history", variant === "rail" && "an-chat-history--rail", className), "data-agent-native": "chat-history-list", children: [onSearchChange && (_jsxs("div", { className: "an-chat-history__search", children: [_jsx(IconSearch, { size: 13, className: "an-chat-history__search-icon" }), _jsx("input", { ref: searchInputRef, type: "text", value: searchValue ?? "", onChange: (event) => onSearchChange(event.target.value), placeholder: searchPlaceholder, "aria-label": searchPlaceholder, className: "an-chat-history__search-input" })] })), _jsxs("div", { className: cn("an-chat-history__list", listClassName), children: [error ? (_jsx("div", { className: "an-chat-history__state an-chat-history__state--error", children: error })) : loading ? (_jsx("div", { className: "an-chat-history__state", children: loadingLabel })) : totalCount === 0 ? (_jsx("div", { className: "an-chat-history__state", children: hasSearchValue ? emptySearchLabel : emptyLabel })) : (resolvedSections.map((section) => section.items.length > 0 && (_jsxs("div", { className: "an-chat-history__section", children: [section.label && (_jsx("div", { className: "an-chat-history__section-label", children: section.label })), section.items.map((item) => (_jsx(ChatHistoryRow, { item: item, active: item.id === activeId, onSelect: onSelect, onOpen: onOpen, onTogglePin: onTogglePin, onRename: onRename, renameMaxLength: renameMaxLength, onDelete: onDelete, renderRowActions: renderRowActions, renderAdditionalRowActions: renderAdditionalRowActions, labels: resolvedLabels }, item.id)))] }, section.id)))), footer] })] }));
|
|
39
|
+
}
|
|
40
|
+
function ChatHistoryRow({ item, active, onSelect, onOpen, onTogglePin, onRename, renameMaxLength, onDelete, renderRowActions, renderAdditionalRowActions, labels, }) {
|
|
41
|
+
const [isRenaming, setIsRenaming] = useState(false);
|
|
42
|
+
const [draftTitle, setDraftTitle] = useState("");
|
|
43
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
44
|
+
const renameInputRef = useRef(null);
|
|
45
|
+
const menuRef = useRef(null);
|
|
46
|
+
const hasMenu = Boolean(onTogglePin ||
|
|
47
|
+
onRename ||
|
|
48
|
+
onDelete ||
|
|
49
|
+
renderRowActions ||
|
|
50
|
+
renderAdditionalRowActions);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!menuOpen)
|
|
53
|
+
return;
|
|
54
|
+
function handlePointerDown(event) {
|
|
55
|
+
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
56
|
+
setMenuOpen(false);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function handleKeyDown(event) {
|
|
60
|
+
if (event.key === "Escape")
|
|
61
|
+
setMenuOpen(false);
|
|
62
|
+
}
|
|
63
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
64
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
65
|
+
return () => {
|
|
66
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
67
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
68
|
+
};
|
|
69
|
+
}, [menuOpen]);
|
|
70
|
+
function startRename() {
|
|
71
|
+
setDraftTitle(item.titleText ?? "");
|
|
72
|
+
setIsRenaming(true);
|
|
73
|
+
setMenuOpen(false);
|
|
74
|
+
window.requestAnimationFrame(() => {
|
|
75
|
+
renameInputRef.current?.select();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function commitRename() {
|
|
79
|
+
const trimmed = draftTitle.trim();
|
|
80
|
+
setIsRenaming(false);
|
|
81
|
+
if (trimmed && trimmed !== item.titleText) {
|
|
82
|
+
onRename?.(item.id, trimmed);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function handleRenameKeyDown(event) {
|
|
86
|
+
if (event.key === "Enter") {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
commitRename();
|
|
89
|
+
}
|
|
90
|
+
else if (event.key === "Escape") {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
setIsRenaming(false);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const optionsLabel = typeof labels.options === "function"
|
|
96
|
+
? labels.options(item)
|
|
97
|
+
: labels.options;
|
|
98
|
+
const renameInputLabel = typeof labels.renameInput === "function"
|
|
99
|
+
? labels.renameInput(item)
|
|
100
|
+
: labels.renameInput;
|
|
101
|
+
return (_jsxs("div", { className: cn("an-chat-history-row", active && "an-chat-history-row--active", item.pinned && "an-chat-history-row--pinned", isRenaming && "an-chat-history-row--renaming", item.disabled && "an-chat-history-row--disabled"), children: [isRenaming ? (_jsx("div", { className: "an-chat-history-row__rename", children: _jsx("input", { ref: renameInputRef, className: "an-chat-history-row__rename-input", value: draftTitle, maxLength: renameMaxLength, onChange: (event) => setDraftTitle(event.target.value), onKeyDown: handleRenameKeyDown, onBlur: commitRename, autoFocus: true, "aria-label": renameInputLabel }) })) : (_jsxs("button", { type: "button", className: "an-chat-history-row__button", onClick: () => !item.disabled && onSelect(item.id), onDoubleClick: () => !item.disabled && onOpen?.(item.id), disabled: item.disabled, children: [_jsxs("div", { className: "an-chat-history-row__topline", children: [_jsx("span", { className: "an-chat-history-row__title", children: item.title }), item.timestamp != null && (_jsx("span", { className: "an-chat-history-row__timestamp", children: item.timestamp }))] }), item.subtitle != null && (_jsx("div", { className: "an-chat-history-row__subtitle", children: item.subtitle })), item.detail != null && (_jsx("div", { className: "an-chat-history-row__detail", children: item.detail }))] })), !isRenaming && hasMenu && (_jsxs("div", { className: "an-chat-history-row__menu", ref: menuRef, children: [_jsx("button", { type: "button", className: cn("an-chat-history-row__menu-trigger", item.pinned && "an-chat-history-row__menu-trigger--pinned"), "aria-label": optionsLabel, "aria-haspopup": "menu", "aria-expanded": menuOpen, onClick: () => setMenuOpen((open) => !open), children: item.pinned ? (_jsx(IconPinned, { size: 13, strokeWidth: 1.8 })) : (_jsx(IconDots, { size: 14, strokeWidth: 1.8 })) }), menuOpen && (_jsx("div", { className: "an-chat-history-row__menu-content", role: "menu", children: renderRowActions ? (renderRowActions(item)) : (_jsxs(_Fragment, { children: [onRename && (_jsxs("button", { type: "button", role: "menuitem", className: "an-chat-history-row__menu-item", onClick: startRename, children: [_jsx(IconPencil, { size: 13, strokeWidth: 1.8 }), _jsx("span", { children: labels.rename })] })), onTogglePin && (_jsxs("button", { type: "button", role: "menuitem", className: "an-chat-history-row__menu-item", onClick: () => {
|
|
102
|
+
setMenuOpen(false);
|
|
103
|
+
onTogglePin(item.id);
|
|
104
|
+
}, children: [item.pinned ? (_jsx(IconPinnedOff, { size: 13, strokeWidth: 1.8 })) : (_jsx(IconPinned, { size: 13, strokeWidth: 1.8 })), _jsx("span", { children: item.pinned ? labels.unpin : labels.pin })] })), renderAdditionalRowActions?.(item, () => setMenuOpen(false)), onDelete && (_jsxs("button", { type: "button", role: "menuitem", className: "an-chat-history-row__menu-item an-chat-history-row__menu-item--danger", onClick: () => {
|
|
105
|
+
setMenuOpen(false);
|
|
106
|
+
onDelete(item.id);
|
|
107
|
+
}, children: [_jsx(IconTrash, { size: 13, strokeWidth: 1.8 }), _jsx("span", { children: labels.delete })] }))] })) }))] }))] }));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=ChatHistoryList.js.map
|