@assistant-ui/mcp-docs-server 0.1.29 → 0.1.30
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/.docs/organized/code-examples/waterfall.md +15 -7
- package/.docs/organized/code-examples/with-a2a.md +8 -20
- package/.docs/organized/code-examples/with-ag-ui.md +9 -6
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +8 -8
- package/.docs/organized/code-examples/with-artifacts.md +10 -8
- package/.docs/organized/code-examples/with-assistant-transport.md +9 -10
- package/.docs/organized/code-examples/with-chain-of-thought.md +7 -7
- package/.docs/organized/code-examples/with-cloud-standalone.md +13 -10
- package/.docs/organized/code-examples/with-cloud.md +8 -9
- package/.docs/organized/code-examples/with-custom-thread-list.md +8 -8
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +15 -10
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +11 -11
- package/.docs/organized/code-examples/with-expo.md +20 -16
- package/.docs/organized/code-examples/with-external-store.md +7 -7
- package/.docs/organized/code-examples/with-ffmpeg.md +15 -10
- package/.docs/organized/code-examples/with-generative-ui.md +7 -7
- package/.docs/organized/code-examples/with-google-adk.md +6 -6
- package/.docs/organized/code-examples/with-heat-graph.md +5 -5
- package/.docs/organized/code-examples/with-interactables.md +8 -23
- package/.docs/organized/code-examples/with-langchain.md +437 -0
- package/.docs/organized/code-examples/with-langgraph.md +15 -15
- package/.docs/organized/code-examples/with-livekit.md +15 -10
- package/.docs/organized/code-examples/with-opencode.md +8 -10
- package/.docs/organized/code-examples/with-parent-id-grouping.md +8 -8
- package/.docs/organized/code-examples/with-react-hook-form.md +219 -147
- package/.docs/organized/code-examples/with-react-ink.md +2 -2
- package/.docs/organized/code-examples/with-react-router.md +10 -10
- package/.docs/organized/code-examples/with-store.md +8 -5
- package/.docs/organized/code-examples/with-tanstack.md +8 -8
- package/.docs/organized/code-examples/with-tap-runtime.md +9 -5
- package/.docs/raw/docs/(docs)/guides/mentions.mdx +248 -109
- package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +112 -92
- package/.docs/raw/docs/(docs)/rtl.mdx +79 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +149 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +2 -0
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +4 -0
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +1 -1
- package/.docs/raw/docs/primitives/composer.mdx +94 -62
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +57 -0
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +47 -1
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +1 -1
- package/.docs/raw/docs/runtimes/langchain/comparison.mdx +60 -0
- package/.docs/raw/docs/runtimes/langchain/index.mdx +210 -0
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +155 -63
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -4
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +199 -0
- package/.docs/raw/docs/ui/directive-text.mdx +113 -0
- package/.docs/raw/docs/ui/reasoning.mdx +13 -9
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/package.json +3 -3
- package/src/utils/logger.ts +1 -1
- package/.docs/raw/docs/ui/mention.mdx +0 -168
|
@@ -368,6 +368,7 @@ export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
|
|
|
368
368
|
<div className="flex items-center gap-2">
|
|
369
369
|
<span className="text-muted-foreground text-sm">Controls:</span>
|
|
370
370
|
<button
|
|
371
|
+
type="button"
|
|
371
372
|
onClick={() => {
|
|
372
373
|
updateCurrentThreadMessages((prev) => [
|
|
373
374
|
...prev,
|
|
@@ -383,6 +384,7 @@ export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
|
|
|
383
384
|
Add User Message
|
|
384
385
|
</button>
|
|
385
386
|
<button
|
|
387
|
+
type="button"
|
|
386
388
|
onClick={() => {
|
|
387
389
|
updateCurrentThreadMessages((prev) => [
|
|
388
390
|
...prev,
|
|
@@ -400,12 +402,14 @@ export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
|
|
|
400
402
|
Add Assistant Message
|
|
401
403
|
</button>
|
|
402
404
|
<button
|
|
405
|
+
type="button"
|
|
403
406
|
onClick={() => setIsRunning(!isRunning)}
|
|
404
407
|
className="rounded-md bg-accent px-3 py-1 font-medium text-accent-foreground text-sm hover:bg-accent/80"
|
|
405
408
|
>
|
|
406
409
|
{isRunning ? "Stop" : "Start"} Running
|
|
407
410
|
</button>
|
|
408
411
|
<button
|
|
412
|
+
type="button"
|
|
409
413
|
onClick={() => updateCurrentThreadMessages(() => [])}
|
|
410
414
|
className="rounded-md bg-destructive px-3 py-1 font-medium text-sm text-white hover:bg-destructive/90"
|
|
411
415
|
>
|
|
@@ -598,21 +602,21 @@ export default nextConfig;
|
|
|
598
602
|
"class-variance-authority": "^0.7.1",
|
|
599
603
|
"clsx": "^2.1.1",
|
|
600
604
|
"lucide-react": "^1.8.0",
|
|
601
|
-
"next": "^16.2.
|
|
605
|
+
"next": "^16.2.4",
|
|
602
606
|
"react": "^19.2.5",
|
|
603
607
|
"react-dom": "^19.2.5",
|
|
604
608
|
"tailwind-merge": "^3.5.0"
|
|
605
609
|
},
|
|
606
610
|
"devDependencies": {
|
|
607
611
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
608
|
-
"@tailwindcss/postcss": "^4.2.
|
|
612
|
+
"@tailwindcss/postcss": "^4.2.4",
|
|
609
613
|
"@types/node": "^25.6.0",
|
|
610
614
|
"@types/react": "^19.2.14",
|
|
611
615
|
"@types/react-dom": "^19.2.3",
|
|
612
|
-
"postcss": "^8.5.
|
|
613
|
-
"tailwindcss": "^4.2.
|
|
616
|
+
"postcss": "^8.5.10",
|
|
617
|
+
"tailwindcss": "^4.2.4",
|
|
614
618
|
"tw-animate-css": "^1.4.0",
|
|
615
|
-
"typescript": "^6.0.
|
|
619
|
+
"typescript": "^6.0.3"
|
|
616
620
|
}
|
|
617
621
|
}
|
|
618
622
|
|
|
@@ -17,30 +17,32 @@ User types "@" → Trigger detected → Adapter provides categories/items
|
|
|
17
17
|
|
|
18
18
|
The mention system has three layers:
|
|
19
19
|
|
|
20
|
-
1. **Trigger detection** —
|
|
20
|
+
1. **Trigger detection** — the composer input watches for a trigger character (`@` by default) and extracts the query
|
|
21
21
|
2. **Adapter** — provides the categories and items to display in the popover (e.g. registered tools)
|
|
22
22
|
3. **Formatter** — serializes a selected item into directive text (`:type[label]{name=id}`) and parses it back for rendering
|
|
23
23
|
|
|
24
|
+
Under the hood, mentions are one kind of [trigger popover](/docs/guides/slash-commands#trigger-popover-architecture). A mention declares its behavior with a `<TriggerPopover.Directive>` sub-primitive, which writes the formatter-serialized directive into the composer on selection.
|
|
25
|
+
|
|
24
26
|
## Quick Start
|
|
25
27
|
|
|
26
|
-
The fastest path is the pre-built [Mention UI
|
|
28
|
+
The fastest path is the pre-built [Mention UI components](/docs/ui/composer-trigger-popover), which wire everything together with two shadcn components — the popover picker and the message-side chip renderer:
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
|
-
npx shadcn@latest add "https://r.assistant-ui.com/composer-
|
|
31
|
+
npx shadcn@latest add "https://r.assistant-ui.com/composer-trigger-popover" "https://r.assistant-ui.com/directive-text"
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
See the [
|
|
34
|
+
See the [Composer Trigger Popover](/docs/ui/composer-trigger-popover) and [Directive Text](/docs/ui/directive-text) guides for setup steps.
|
|
33
35
|
|
|
34
36
|
The rest of this guide covers the underlying concepts and customization points.
|
|
35
37
|
|
|
36
|
-
##
|
|
38
|
+
## Trigger Adapter
|
|
37
39
|
|
|
38
|
-
A `
|
|
40
|
+
A `Unstable_TriggerAdapter` provides the data for the popover. All methods are **synchronous** — use external state management (React Query, SWR, local state) for async data, then expose loaded results through the adapter.
|
|
39
41
|
|
|
40
42
|
```ts
|
|
41
|
-
import type {
|
|
43
|
+
import type { Unstable_TriggerAdapter } from "@assistant-ui/core";
|
|
42
44
|
|
|
43
|
-
const myAdapter:
|
|
45
|
+
const myAdapter: Unstable_TriggerAdapter = {
|
|
44
46
|
categories() {
|
|
45
47
|
return [
|
|
46
48
|
{ id: "tools", label: "Tools" },
|
|
@@ -80,40 +82,142 @@ const myAdapter: Unstable_MentionAdapter = {
|
|
|
80
82
|
};
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
Pass the adapter to `
|
|
85
|
+
Pass the adapter to `TriggerPopover` and declare a `Directive` sub-primitive to bind the insertion behavior:
|
|
84
86
|
|
|
85
87
|
```tsx
|
|
86
|
-
|
|
88
|
+
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
89
|
+
import { unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
|
|
90
|
+
|
|
91
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
87
92
|
<ComposerPrimitive.Root>
|
|
88
93
|
<ComposerPrimitive.Input placeholder="Type @ to mention..." />
|
|
94
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
95
|
+
char="@"
|
|
96
|
+
adapter={myAdapter}
|
|
97
|
+
>
|
|
98
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive
|
|
99
|
+
formatter={unstable_defaultDirectiveFormatter}
|
|
100
|
+
/>
|
|
101
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
102
|
+
{(categories) =>
|
|
103
|
+
categories.map((cat) => (
|
|
104
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
|
|
105
|
+
key={cat.id}
|
|
106
|
+
categoryId={cat.id}
|
|
107
|
+
>
|
|
108
|
+
{cat.label}
|
|
109
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
110
|
+
))
|
|
111
|
+
}
|
|
112
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
113
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
114
|
+
{(items) =>
|
|
115
|
+
items.map((item) => (
|
|
116
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem
|
|
117
|
+
key={item.id}
|
|
118
|
+
item={item}
|
|
119
|
+
>
|
|
120
|
+
{item.label}
|
|
121
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
122
|
+
))
|
|
123
|
+
}
|
|
124
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
125
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
89
126
|
</ComposerPrimitive.Root>
|
|
90
|
-
</ComposerPrimitive.
|
|
127
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
91
128
|
```
|
|
92
129
|
|
|
93
|
-
|
|
130
|
+
Exactly one behavior sub-primitive (`Directive` or `Action`) is allowed per `TriggerPopover`. The parent reads the registered behavior and wires the selection machinery.
|
|
94
131
|
|
|
95
|
-
|
|
132
|
+
### Built-in Mention Adapter
|
|
133
|
+
|
|
134
|
+
`unstable_useMentionAdapter` covers the common cases: mention registered tools, add your own items, mix tools with custom items, or show multi-category drill-down.
|
|
135
|
+
|
|
136
|
+
**Tools from model context (default):**
|
|
96
137
|
|
|
97
138
|
```tsx
|
|
98
|
-
import {
|
|
139
|
+
import { unstable_useMentionAdapter } from "@assistant-ui/react";
|
|
140
|
+
|
|
141
|
+
const mention = unstable_useMentionAdapter();
|
|
142
|
+
// → { adapter, directive } — spread into <ComposerTriggerPopover {...mention} />
|
|
143
|
+
// Default: single "Tools" category reading from useAssistantTool registrations
|
|
144
|
+
```
|
|
99
145
|
|
|
100
|
-
|
|
101
|
-
// Format tool names for display (default: raw name)
|
|
102
|
-
formatLabel: (name) =>
|
|
103
|
-
name.replaceAll("_", " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
146
|
+
**Custom items only (no tools):**
|
|
104
147
|
|
|
105
|
-
|
|
106
|
-
|
|
148
|
+
```tsx
|
|
149
|
+
const mention = unstable_useMentionAdapter({
|
|
150
|
+
items: [
|
|
151
|
+
{ id: "alice", type: "user", label: "Alice", icon: "User" },
|
|
152
|
+
{ id: "bob", type: "user", label: "Bob", icon: "User" },
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
```
|
|
107
156
|
|
|
108
|
-
|
|
109
|
-
// tools: [{ id: "search", type: "tool", label: "Search" }],
|
|
157
|
+
**Mix custom items with model-context tools (flat):**
|
|
110
158
|
|
|
111
|
-
|
|
112
|
-
|
|
159
|
+
```tsx
|
|
160
|
+
const mention = unstable_useMentionAdapter({
|
|
161
|
+
items: [{ id: "kb", type: "doc", label: "Knowledge Base", icon: "Book" }],
|
|
162
|
+
includeModelContextTools: true,
|
|
113
163
|
});
|
|
114
164
|
```
|
|
115
165
|
|
|
116
|
-
|
|
166
|
+
**Multi-category drill-down:**
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
const mention = unstable_useMentionAdapter({
|
|
170
|
+
categories: [
|
|
171
|
+
{
|
|
172
|
+
id: "users",
|
|
173
|
+
label: "Users",
|
|
174
|
+
items: [
|
|
175
|
+
{ id: "alice", type: "user", label: "Alice", icon: "User" },
|
|
176
|
+
{ id: "bob", type: "user", label: "Bob", icon: "User" },
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: "files",
|
|
181
|
+
label: "Files",
|
|
182
|
+
items: [
|
|
183
|
+
{ id: "readme", type: "file", label: "README.md", icon: "FileText" },
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
// Tools auto-appended as their own category (default id "tools", label "Tools")
|
|
188
|
+
includeModelContextTools: true,
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Tool formatting and category override:**
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
const mention = unstable_useMentionAdapter({
|
|
196
|
+
categories: [{ id: "users", label: "Users", items: [...] }],
|
|
197
|
+
includeModelContextTools: {
|
|
198
|
+
category: { id: "integrations", label: "Integrations" },
|
|
199
|
+
formatLabel: (name) =>
|
|
200
|
+
name.replaceAll("_", " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
201
|
+
icon: "Wrench",
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Options summary:**
|
|
207
|
+
|
|
208
|
+
| Option | Type | Behavior |
|
|
209
|
+
| --- | --- | --- |
|
|
210
|
+
| `items` | `Unstable_Mention[]` | Flat list (ignored when `categories` is set) |
|
|
211
|
+
| `categories` | `{id, label, items}[]` | Drill-down groups |
|
|
212
|
+
| `includeModelContextTools` | `boolean \| object` | Default: `true` iff neither `items` nor `categories` |
|
|
213
|
+
| `formatter` | `Unstable_DirectiveFormatter` | Override directive serialization (default: `unstable_defaultDirectiveFormatter`) |
|
|
214
|
+
| `onInserted` | `(item) => void` | Fires after the directive is inserted into the composer |
|
|
215
|
+
| `iconMap` | `Record<string, IconComponent>` | Maps `metadata.icon` / category `id` strings to React components |
|
|
216
|
+
| `fallbackIcon` | `IconComponent` | Fallback when no entry in `iconMap` matches |
|
|
217
|
+
|
|
218
|
+
`icon` on each mention is a shortcut for `metadata.icon` that the picker UI resolves via `iconMap`. Dedup between custom items and model-context tools is by `id` — explicit items win.
|
|
219
|
+
|
|
220
|
+
The hook returns `{ adapter, directive, iconMap?, fallbackIcon? }` — spread into `<ComposerTriggerPopover {...mention} />` for one-line wiring. Callers consuming the raw primitives instead destructure: `mention.adapter`, `mention.directive.formatter`, etc.
|
|
117
221
|
|
|
118
222
|
## Directive Format
|
|
119
223
|
|
|
@@ -175,13 +279,17 @@ const slashFormatter: Unstable_DirectiveFormatter = {
|
|
|
175
279
|
};
|
|
176
280
|
```
|
|
177
281
|
|
|
178
|
-
Pass it to
|
|
282
|
+
Pass it to the trigger's `Directive` sub-primitive and the message renderer:
|
|
179
283
|
|
|
180
284
|
```tsx
|
|
181
285
|
// Composer
|
|
182
|
-
<ComposerPrimitive.
|
|
286
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
287
|
+
char="@"
|
|
288
|
+
adapter={adapter}
|
|
289
|
+
>
|
|
290
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={slashFormatter} />
|
|
183
291
|
...
|
|
184
|
-
</ComposerPrimitive.
|
|
292
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
185
293
|
|
|
186
294
|
// User messages
|
|
187
295
|
const SlashDirectiveText = createDirectiveText(slashFormatter);
|
|
@@ -206,22 +314,29 @@ With **Lexical**, selected mentions appear as styled inline chips that behave as
|
|
|
206
314
|
```tsx
|
|
207
315
|
import { LexicalComposerInput } from "@assistant-ui/react-lexical";
|
|
208
316
|
|
|
209
|
-
<ComposerPrimitive.
|
|
317
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
210
318
|
<ComposerPrimitive.Root>
|
|
211
319
|
<LexicalComposerInput placeholder="Type @ to mention..." />
|
|
212
320
|
<ComposerPrimitive.Send />
|
|
321
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
322
|
+
char="@"
|
|
323
|
+
adapter={adapter}
|
|
324
|
+
>
|
|
325
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={formatter} />
|
|
326
|
+
...
|
|
327
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
213
328
|
</ComposerPrimitive.Root>
|
|
214
|
-
</ComposerPrimitive.
|
|
329
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
215
330
|
```
|
|
216
331
|
|
|
217
|
-
`LexicalComposerInput`
|
|
332
|
+
`LexicalComposerInput` automatically discovers every `Directive` trigger registered under `TriggerPopoverRoot` and renders their selections as inline chips.
|
|
218
333
|
|
|
219
334
|
## Rendering Mentions in Messages
|
|
220
335
|
|
|
221
336
|
Use `DirectiveText` as the `Text` component for user messages so directives render as inline chips instead of raw syntax:
|
|
222
337
|
|
|
223
338
|
```tsx
|
|
224
|
-
import { DirectiveText } from "@/components/assistant-ui/
|
|
339
|
+
import { DirectiveText } from "@/components/assistant-ui/directive-text";
|
|
225
340
|
|
|
226
341
|
<MessagePrimitive.Parts
|
|
227
342
|
components={{
|
|
@@ -235,7 +350,7 @@ For assistant messages, keep using your markdown renderer (e.g. `MarkdownText`)
|
|
|
235
350
|
For a custom formatter, use `createDirectiveText`:
|
|
236
351
|
|
|
237
352
|
```tsx
|
|
238
|
-
import { createDirectiveText } from "@/components/assistant-ui/
|
|
353
|
+
import { createDirectiveText } from "@/components/assistant-ui/directive-text";
|
|
239
354
|
|
|
240
355
|
const MyDirectiveText = createDirectiveText(myFormatter);
|
|
241
356
|
```
|
|
@@ -273,134 +388,158 @@ You can use the extracted mentions to:
|
|
|
273
388
|
|
|
274
389
|
## Reading Mention State
|
|
275
390
|
|
|
276
|
-
Use `
|
|
391
|
+
Use `unstable_useTriggerPopoverScopeContext` inside the `TriggerPopover` to programmatically access the popover state for that trigger:
|
|
277
392
|
|
|
278
393
|
```tsx
|
|
279
|
-
import {
|
|
280
|
-
|
|
281
|
-
function
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
//
|
|
394
|
+
import { unstable_useTriggerPopoverScopeContext } from "@assistant-ui/react";
|
|
395
|
+
|
|
396
|
+
function MyPopoverContent() {
|
|
397
|
+
const scope = unstable_useTriggerPopoverScopeContext();
|
|
398
|
+
|
|
399
|
+
// scope.open — whether the popover is visible
|
|
400
|
+
// scope.query — current search text after the trigger
|
|
401
|
+
// scope.categories — filtered category list
|
|
402
|
+
// scope.items — filtered item list
|
|
403
|
+
// scope.highlightedIndex — keyboard-navigated index
|
|
404
|
+
// scope.isSearchMode — true when global search is active
|
|
405
|
+
// scope.selectItem(item) — programmatically select an item
|
|
406
|
+
// scope.close() — close the popover
|
|
407
|
+
|
|
408
|
+
return null;
|
|
292
409
|
}
|
|
293
410
|
```
|
|
294
411
|
|
|
295
|
-
This hook must be used
|
|
412
|
+
This hook must be used inside a `ComposerPrimitive.Unstable_TriggerPopover`.
|
|
413
|
+
|
|
414
|
+
To iterate every registered trigger (e.g. from a custom input implementation), use `unstable_useTriggerPopoverTriggers` inside `TriggerPopoverRoot`.
|
|
296
415
|
|
|
297
416
|
## Building a Custom Popover
|
|
298
417
|
|
|
299
|
-
Use the
|
|
418
|
+
Use the trigger popover primitives to build a fully custom popover:
|
|
300
419
|
|
|
301
420
|
```tsx
|
|
302
|
-
<ComposerPrimitive.
|
|
421
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
303
422
|
<ComposerPrimitive.Root>
|
|
304
423
|
<ComposerPrimitive.Input />
|
|
305
424
|
|
|
306
|
-
<ComposerPrimitive.
|
|
307
|
-
|
|
425
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
426
|
+
char="@"
|
|
427
|
+
adapter={adapter}
|
|
428
|
+
className="popover"
|
|
429
|
+
>
|
|
430
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={formatter} />
|
|
431
|
+
|
|
432
|
+
<ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
308
433
|
← Back
|
|
309
|
-
</ComposerPrimitive.
|
|
434
|
+
</ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
310
435
|
|
|
311
|
-
<ComposerPrimitive.
|
|
436
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
312
437
|
{(categories) =>
|
|
313
438
|
categories.map((cat) => (
|
|
314
|
-
<ComposerPrimitive.
|
|
439
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
|
|
315
440
|
key={cat.id}
|
|
316
441
|
categoryId={cat.id}
|
|
317
442
|
>
|
|
318
443
|
{cat.label}
|
|
319
|
-
</ComposerPrimitive.
|
|
444
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
320
445
|
))
|
|
321
446
|
}
|
|
322
|
-
</ComposerPrimitive.
|
|
447
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
323
448
|
|
|
324
|
-
<ComposerPrimitive.
|
|
449
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
325
450
|
{(items) =>
|
|
326
451
|
items.map((item) => (
|
|
327
|
-
<ComposerPrimitive.
|
|
452
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem
|
|
328
453
|
key={item.id}
|
|
329
454
|
item={item}
|
|
330
455
|
>
|
|
331
456
|
{item.label}
|
|
332
|
-
</ComposerPrimitive.
|
|
457
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
333
458
|
))
|
|
334
459
|
}
|
|
335
|
-
</ComposerPrimitive.
|
|
336
|
-
</ComposerPrimitive.
|
|
460
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
461
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
337
462
|
|
|
338
463
|
<ComposerPrimitive.Send />
|
|
339
464
|
</ComposerPrimitive.Root>
|
|
340
|
-
</ComposerPrimitive.
|
|
465
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
341
466
|
```
|
|
342
467
|
|
|
343
468
|
### Primitives Reference
|
|
344
469
|
|
|
345
470
|
| Primitive | Description |
|
|
346
471
|
| --- | --- |
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
472
|
+
| `Unstable_TriggerPopoverRoot` | Root provider — groups one or more triggers, manages plugin registry |
|
|
473
|
+
| `Unstable_TriggerPopover` | Declares a trigger (id, char, adapter) and renders the popover container |
|
|
474
|
+
| `Unstable_TriggerPopover.Directive` | Behavior sub-primitive — inserts a formatted directive into the composer on selection |
|
|
475
|
+
| `Unstable_TriggerPopover.Action` | Behavior sub-primitive — runs a callback on selection; inserts a chip by default |
|
|
476
|
+
| `Unstable_TriggerPopoverCategories` | Render-function for the top-level category list |
|
|
477
|
+
| `Unstable_TriggerPopoverCategoryItem` | Button that drills into a category (`role="option"`, auto `data-highlighted`) |
|
|
478
|
+
| `Unstable_TriggerPopoverItems` | Render-function for items within the active category or search results |
|
|
479
|
+
| `Unstable_TriggerPopoverItem` | Button that selects an item (`role="option"`, auto `data-highlighted`) |
|
|
480
|
+
| `Unstable_TriggerPopoverBack` | Button that navigates back from items to categories |
|
|
354
481
|
|
|
355
482
|
See the [Composer API reference](/docs/api-reference/primitives/composer) for full prop details.
|
|
356
483
|
|
|
357
484
|
## Combining with Slash Commands
|
|
358
485
|
|
|
359
|
-
Mentions and [slash commands](/docs/guides/slash-commands)
|
|
486
|
+
Mentions and [slash commands](/docs/guides/slash-commands) coexist on the same composer — they're both just triggers on the shared `TriggerPopoverRoot`:
|
|
360
487
|
|
|
361
488
|
```tsx
|
|
362
|
-
<ComposerPrimitive.
|
|
363
|
-
<ComposerPrimitive.
|
|
364
|
-
<ComposerPrimitive.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
489
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
490
|
+
<ComposerPrimitive.Root>
|
|
491
|
+
<ComposerPrimitive.Input placeholder="Type @ to mention, / for commands..." />
|
|
492
|
+
<ComposerPrimitive.Send />
|
|
493
|
+
|
|
494
|
+
{/* Mention popover (shows on @) */}
|
|
495
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
496
|
+
char="@"
|
|
497
|
+
adapter={mention.adapter}
|
|
498
|
+
>
|
|
499
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive {...mention.directive} />
|
|
500
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
501
|
+
{(categories) => categories.map((cat) => (
|
|
502
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem key={cat.id} categoryId={cat.id}>
|
|
503
|
+
{cat.label}
|
|
504
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
505
|
+
))}
|
|
506
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
507
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
508
|
+
{(items) => items.map((item) => (
|
|
509
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item}>
|
|
510
|
+
{item.label}
|
|
511
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
512
|
+
))}
|
|
513
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
514
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
515
|
+
|
|
516
|
+
{/* Slash command popover (shows on /) */}
|
|
517
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
518
|
+
char="/"
|
|
519
|
+
adapter={slashAdapter}
|
|
520
|
+
>
|
|
521
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Action
|
|
522
|
+
formatter={unstable_defaultDirectiveFormatter}
|
|
523
|
+
onExecute={(item) => commandHandlers[item.id]?.()}
|
|
524
|
+
/>
|
|
525
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
526
|
+
{(items) => items.map((item, index) => (
|
|
527
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
|
|
528
|
+
{item.label}
|
|
529
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
530
|
+
))}
|
|
531
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
532
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
533
|
+
</ComposerPrimitive.Root>
|
|
534
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
399
535
|
```
|
|
400
536
|
|
|
537
|
+
Each `TriggerPopover` declares its own scope — its popover UI reads state only from that declaration, so `@` and `/` never collide.
|
|
538
|
+
|
|
401
539
|
## Related
|
|
402
540
|
|
|
403
|
-
- [
|
|
541
|
+
- [ComposerTriggerPopover UI Component](/docs/ui/composer-trigger-popover) — pre-built shadcn component
|
|
542
|
+
- [DirectiveText UI Component](/docs/ui/directive-text) — renders mention chips in user messages
|
|
404
543
|
- [Slash Commands Guide](/docs/guides/slash-commands) — `/` command system built on the same architecture
|
|
405
544
|
- [Tools Guide](/docs/guides/tools) — register tools that appear in the mention picker
|
|
406
545
|
- [Composer Primitives](/docs/primitives/composer) — underlying composer primitives
|