Skip to main content

Mention

Mention lets users type a trigger character to insert people, channels, or other tokens inline as they write.

On this page
Props
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/mention

Usage

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.

PropType
string
function
Placement
string
string
function

Last updated on 6/29/2026