diff --git a/apps/www/src/content/docs/ai-elements/prompt-input/demo.ts b/apps/www/src/content/docs/ai-elements/prompt-input/demo.ts
index 032646235..b0b86c8db 100644
--- a/apps/www/src/content/docs/ai-elements/prompt-input/demo.ts
+++ b/apps/www/src/content/docs/ai-elements/prompt-input/demo.ts
@@ -125,3 +125,327 @@ export const disabledDemo = {
`
};
+
+export const editorCapabilitiesDemo = {
+ type: 'code',
+ code: `function EditorCapabilities() {
+ const composer = React.useRef(null);
+
+ // Ungrouped items lead the menu; groups follow in the order they first
+ // appear. Icons, trailing badges, disabled rows and opaque \`data\` all work.
+ const ITEMS = [
+ {
+ id: 'page',
+ label: 'This page',
+ type: 'page',
+ icon: ,
+ data: { path: '/docs/ai-elements/prompt-input' }
+ },
+ {
+ id: 'button',
+ label: 'Button',
+ type: 'component',
+ group: 'Components',
+ icon: ,
+ data: { status: 'stable' }
+ },
+ {
+ id: 'data-table',
+ label: 'DataTable',
+ type: 'component',
+ group: 'Components',
+ icon: ,
+ data: { status: 'stable' }
+ },
+ {
+ id: 'prompt-input',
+ label: 'PromptInput',
+ type: 'component',
+ group: 'Components',
+ icon: ,
+ data: { status: 'beta' }
+ },
+ {
+ id: 'u1',
+ label: 'Maya Chen',
+ type: 'user',
+ group: 'Users',
+ icon:
+ },
+ {
+ id: 'u2',
+ label: 'Apsara Assistant',
+ type: 'user',
+ group: 'Users',
+ icon: ,
+ trailing: Agent
+ },
+ {
+ id: 'u3',
+ label: 'Dana Whitfield',
+ type: 'user',
+ group: 'Users',
+ icon: ,
+ disabled: true
+ }
+ ];
+
+ const MAX_LENGTH = 280;
+ const [draft, setDraft] = React.useState({ markup: '', text: '', mentions: [] });
+
+ // getValue() seeds the readout with the restored draft before any edit.
+ React.useEffect(() => {
+ const message = composer.current?.getValue();
+ if (message) setDraft(message);
+ }, []);
+
+ const mono = { fontFamily: 'monospace', wordBreak: 'break-all' };
+
+ // A fixed footprint: the readout below grows as you type, and the docs page
+ // centres this box, so letting it change height would nudge the whole page.
+ return (
+
+
+ setDraft({ markup, text: details.text, mentions: details.mentions })
+ }
+ onSubmit={(message, event) => event.currentTarget.reset()}
+ >
+
+ Promise.resolve(
+ refs.map(ref => ITEMS.find(item => item.id === ref.id)).filter(Boolean)
+ )
+ }
+ emptyMessage="Nothing matches"
+ />
+
+
+
+
+
+ {draft.text.length}/{MAX_LENGTH}
+
+
+
+
+
+
+ text
+ {draft.text || '—'}
+
+ markup (save this as the draft)
+ {draft.markup || '—'}
+
+ mentions
+ {draft.mentions.length === 0 ? (
+ —
+ ) : (
+ draft.mentions.map((mention, index) => (
+
+ {mention.type}:{mention.id} at [{mention.start}, {mention.end}]
+ {mention.data ? ' — data ' + JSON.stringify(mention.data) : ''}
+
+ ))
+ )}
+
+
+ );
+}`
+};
+
+export const mentionsDemo = {
+ type: 'code',
+ code: `function MentionsPromptInput() {
+ const ITEMS = [
+ { id: 'button', label: 'Button', type: 'component', group: 'Components' },
+ { id: 'data-table', label: 'DataTable', type: 'component', group: 'Components' },
+ {
+ id: 'prompt-input',
+ label: 'PromptInput',
+ type: 'component',
+ group: 'Components'
+ },
+ { id: 'u1', label: 'Maya Chen', type: 'user', group: 'Users' },
+ {
+ id: 'u2',
+ label: 'Apsara Assistant',
+ type: 'user',
+ group: 'Users',
+ trailing: Agent
+ },
+ { id: 'u3', label: 'Dana Whitfield', type: 'user', group: 'Users' }
+ ];
+
+ const [sent, setSent] = React.useState(null);
+
+ return (
+
+ {
+ setSent(message);
+ event.currentTarget.reset();
+ }}
+ >
+
+
+
+
+
+
+ {sent ? (
+
+ text: {sent.text}
+ markup: {sent.markup}
+
+ mentions: {sent.mentions.map(m => m.type + ':' + m.id).join(', ') || '—'}
+
+
+ ) : null}
+
+ );
+}`
+};
+
+export const mentionsAsyncDemo = {
+ type: 'code',
+ code: `function AsyncMentionsPromptInput() {
+ const DIRECTORY = [
+ { id: 'button', label: 'Button', type: 'component', group: 'Components' },
+ { id: 'data-table', label: 'DataTable', type: 'component', group: 'Components' },
+ {
+ id: 'prompt-input',
+ label: 'PromptInput',
+ type: 'component',
+ group: 'Components'
+ },
+ { id: 'u1', label: 'Maya Chen', type: 'user', group: 'Users' },
+ { id: 'u2', label: 'Ravi Iyer', type: 'user', group: 'Users' },
+ { id: 'u3', label: 'Nia Okafor', type: 'user', group: 'Users' }
+ ];
+
+ // Stands in for your API. The signal is aborted when a request is superseded.
+ const search = (query, { signal }) =>
+ new Promise((resolve, reject) => {
+ const timer = setTimeout(() => {
+ const q = query.toLowerCase();
+ resolve(DIRECTORY.filter(item => item.label.toLowerCase().includes(q)));
+ }, 600);
+ signal.addEventListener('abort', () => {
+ clearTimeout(timer);
+ reject(new DOMException('Aborted', 'AbortError'));
+ });
+ });
+
+ return (
+
+
event.currentTarget.reset()}
+ >
+
+ Promise.resolve(
+ refs
+ .map(ref => DIRECTORY.find(item => item.id === ref.id))
+ .filter(Boolean)
+ )
+ }
+ emptyMessage="Nothing by that name"
+ />
+
+
+
+
+
+
+ );
+}`
+};
+
+export const insertMentionDemo = {
+ type: 'code',
+ code: `function InsertMentionPromptInput() {
+ const composer = React.useRef(null);
+
+ // No here: typing @ does nothing, but chips added
+ // from code still render with their icon.
+ return (
+
+
event.currentTarget.reset()}
+ >
+
+
+
+
+
+
+
+
+ );
+}`
+};
diff --git a/apps/www/src/content/docs/ai-elements/prompt-input/index.mdx b/apps/www/src/content/docs/ai-elements/prompt-input/index.mdx
index ac6348a43..e91aebefe 100644
--- a/apps/www/src/content/docs/ai-elements/prompt-input/index.mdx
+++ b/apps/www/src/content/docs/ai-elements/prompt-input/index.mdx
@@ -1,11 +1,11 @@
---
title: PromptInput
-description: A composer for AI chat and standalone "Ask anything" boxes — auto-growing textarea, toolbar slots, and a status-aware submit button.
+description: A composer for AI chat and standalone "Ask anything" boxes — auto-growing input, inline @-mention chips, toolbar slots, and a status-aware submit button.
source: packages/raystack/components/prompt-input
tag: new
---
-import { preview, attachmentsDemo, statusDemo, controlledDemo, disabledDemo } from "./demo.ts";
+import { preview, attachmentsDemo, statusDemo, controlledDemo, disabledDemo, editorCapabilitiesDemo, mentionsDemo, mentionsAsyncDemo, insertMentionDemo } from "./demo.ts";
@@ -40,15 +40,21 @@ anything else.
### Root
The `