Mention Input

A textarea with @-mention autocomplete. The trigger only fires at a word boundary, so an email address does not open the menu halfway through every address anyone types.

src/components/ui/mention-input.tsx

About

From the component's own source, where it was written.

A textarea with @-mention autocomplete.

The trigger only fires at a word boundary — after a space or at the start of the text. Without that, an email address opens the menu halfway through every address anyone types.

The query ends at whitespace, so the menu closes on its own once someone types past a name rather than staying open with no matches.

Positioning is deliberately anchored to the field, not to the caret. Caret coordinates in a textarea require rendering a mirror element and measuring it, which is a lot of machinery and breaks on wrap; a menu under the field is understood immediately.

Install

npx astralyx-ui add mention-input

Usage

import { MentionInput } from '@/components/ui/mention-input'

<MentionInput options={people} value={body} onValueChange={setBody} />

Composer

Change the props and the source below follows.

Props
tsx
<MentionInput
  options={people}
  trigger="@"
  value={body}
  onValueChange={setBody}
/>

Examples

Comment box

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

MentionInput

Extends Omit<ComponentProps<'textarea'>, 'value' | 'defaultValue' | 'onChange'>.

PropTypeDefaultDescription
optionsMentionable[]required{ id, label, description?, avatar? }.
valuestring——
defaultValuestring''—
onValueChange(value: string) => void——
onMention(option: Mentionable) => void—Fires on insert, for collecting the mentioned ids alongside the text.
triggerstring'@'Any prefix — # for issues, / for commands.
listLabelstring'People'Accessible name for the suggestion list.

Types

Mentionable

A textarea with

FieldTypeDescription
idstring—
labelstring—
description?string—
avatar?ReactNode—

Behaviour

TopicDetailDescription
positioninganchored to the fieldNot to the caret: caret coordinates in a textarea need a measured mirror element and break on wrap, and a menu under the field is understood immediately.