Mentions

A textarea that opens a suggestion list after a trigger character, for @ mentions and anything else keyed the same way.

Usage

When to use a mention field, how the trigger and the options fit together, and how to read the text back when you submit.

When to use

Use Mentions when the reader is writing and needs to name a person or a label inside the text: a comment box, a task description or a chat composer.
Reach for something else when:
  • The whole field is the query. Use an Autocomplete: one value, one line, no text around it.
  • The reader picks rather than writes. Use a Select, which keeps the chosen items as values instead of characters in a string.
  • Nothing is referenced. Use Input.TextArea.

The trigger character

prefix is the character that opens the list, "@" by default. On Input the same name means a node shown before the text, so the two are easy to mix up.
  • split (a space by default) ends a mention, and is inserted after each one you pick. With "" the next word runs into the mention.
  • validateSearch decides whether the text after the trigger is still a search. The default stops at split, so the list closes on a space. Replace it when names contain spaces, and keep it fast: it runs on every keystroke.
  • Pass an array to prefix for several triggers, and use onSearch: its second argument is the prefix that was typed, so you can swap options for each one.
Keep to the conventional characters. Readers expect people after @ and topics after #.

Where the options come from

Pass options. Mentions.Option children are deprecated, and the kit does not re-export them.
  • A static list filters itself. The default filterOption matches each option's value, not its label. If your values are ids and the names live in the label, pass your own filter.
  • Set filterOption={false} for server results. The default filter runs again over the results you fetched, which is the usual cause of a search that shows nothing. Fetch in onSearch, keep the results in state and pass them as options.
  • loading replaces the list with a spinner. It also turns on silent, so Enter cannot pick an option that is about to be replaced.
  • Set notFoundContent for the empty state. The default is the full Empty illustration, which is large for a small popup. A single line of text reads better.

The field itself

  • Clamp autoSize in a composer. autoSize alone grows the field with no limit. Pass { minRows, maxRows } so a long comment scrolls instead of pushing the send button off the screen.
  • rows sets the starting height and defaults to 1, which looks like a single-line input. Raise it where the reader is expected to write a paragraph.
  • size, variant and status work as on Input and Select. Match what the rest of the form uses.
  • allowClear empties the whole field. It suits a search-like field. In a comment box, one misclick loses a paragraph.
  • Style the list with classNames.popup. The list renders in a portal, outside the field, so a descendant selector cannot reach it. On Mentions, classNames.textarea and classNames.popup are plain strings, unlike Select's classNames.popup.root. popupClassName also works and is merged with it.
  • Set getPopupContainer inside a scrolling panel. The list is themed wherever it renders. Point it at a parent only when it has to scroll or clip with the field.
  • placement is bottom or top, and the list flips on its own when it runs out of room. Set top when the field sits at the bottom of a sheet.

Turning the text back into ids

The value is a plain string. Nothing marks where a mention starts or ends, so map it back to records when you submit.
  • Mentions.getMentions(value, { prefix, split }) returns { prefix, value } for each mention. Pass it the same prefix and split as the field. It is a parser, not a component, so import it from antd.
  • It matches on text, so two people called “alex” come back as one. Record the id in onSelect when that matters, and use the parsed string for mentions typed by hand.
  • Do not render the submitted text as markup. A mention is characters the reader typed, and an attacker can type them too.