On this page
const people = /* ... */;
<Mention className="w-[320px]">
<TextField>
<Label>Comment</Label>
<TextArea />
</TextField>
<Popover>
<MenuContent items={people} renderEmptyState={() => "No people found."}>
{(person) => (
<MenuItem id={person.id} textValue={person.id}>
<Avatar size="sm">
<AvatarFallback>{person.name.charAt(0)}</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<span className="text-sm">{person.name}</span>
<span className="text-xs text-fg-muted">@{person.id}</span>
</div>
</MenuItem>
)}
</MenuContent>
</Popover>
</Mention>Installation
npx shadcn@latest add @dotui/mentionUsage
Mention wires an @-mention experience onto your existing primitives: compose an input — a bare TextArea (or Input) — plus a Popover + Menu for the suggestions, and Mention injects the wiring (value, caret-anchored popover, filtering, keyboard navigation, insertion) through context. Typing the trigger character (@ by default) opens the list at the caret and filters as you type; selecting an item inserts it inline.
import { TextArea } from '@/components/ui/input'
import { MenuContent, MenuItem } from '@/components/ui/menu'
import { Mention } from '@/components/ui/mention'
import { Popover } from '@/components/ui/popover'<Mention>
<TextArea aria-label="Comment" />
<Popover>
<MenuContent items={people}>
{(person) => <MenuItem id={person.id}>{person.name}</MenuItem>}
</MenuContent>
</Popover>
</Mention>The input is optional to wrap: drop in a bare TextArea/Input with an aria-label, or wrap it in a TextField when you want a visible Label (and its description/validation). Either way the suggestions stay keyboard-accessible.
<Mention>
<TextField>
<Label>Comment</Label>
<TextArea />
</TextField>
<Popover>{/* ...suggestions */}</Popover>
</Mention>The trigger prop changes the character that opens the list, and getItemText maps a selected item's key to the text inserted after the trigger.
<Mention trigger="#" getItemText={(key) => String(key)}>
{/* ... */}
</Mention>Examples
Basic
Highlighted
With avatars
Single-line input
Custom trigger
Controlled
Value: Hey
API Reference
Mention is the only component; the input and suggestion list are composed from the TextArea / Input (optionally wrapped in a TextField), Popover, and Menu primitives.
Mention
A mention input lets users type a trigger character (like `@`) to open an inline list of suggestions and insert one as a token in the text. `Mention` wires the behaviour onto composed primitives — a `TextField` + `TextArea` for the input, a `Popover` + `Menu`/`MenuItem` for the suggestions — by injecting their props through context, so no bespoke sub-components are needed.
| Prop | Type | Default | |
|---|---|---|---|
string | "@" | ||
function | String(key) | ||
Placement | "bottom start" | ||
string | — | ||
string | — | ||
function | — | ||
Last updated on 6/29/2026