Vesture

Inputs

MentionsInput

A contentEditable text input that opens a filtered autocomplete dropdown on "@" (or any trigger character) for tagging users/entities, inserting them as distinct non-editable chips.

MentionsInput

Preview

Type @ to mention a teammate.

Usage

tsx
import { MentionsInput } from "@vesture/react";
import type { MentionOption } from "@vesture/react";

const teamMembers: MentionOption[] = [
  { id: "1", label: "Ada Lovelace" },
  { id: "2", label: "Grace Hopper" },
];

function Example() {
  const [comment, setComment] = useState("");
  return (
    <MentionsInput
      value={comment}
      onChange={setComment}
      options={teamMembers}
      placeholder="Leave a comment, @mention a teammate…"
    />
  );
}

Behavior

  • Typing the trigger character opens a dropdown anchored at the text cursor, filtered as you keep typing; ArrowUp/Down moves the highlight, Enter selects, Escape closes.
  • options accepts either a static array or an async (query) => Promise<MentionOption[]> function for server-side search — the same dual-mode pattern as Combobox.
  • Selecting an option inserts a non-editable mention chip at the cursor and resumes normal typing immediately after it.
  • onMentionsChange fires with the current set of entities actually present in the text, recomputed on every edit — deleting a chip drops it from the callback's result, not just inserting a new one adds to it.

Props

PropTypeDefaultDescription
value / defaultValue / onChangestringControlled / uncontrolled sanitized HTML content (plain text plus mention chip spans).
optionsMentionOption[] | ((query: string) => Promise<MentionOption[]>)Required. Static list or async search, keyed by the text typed after the trigger.
triggerstring"@"Character that opens the mention dropdown.
onMentionsChange(mentions: MentionOption[]) => voidFires with the entities currently mentioned in the text, deduplicated by id.
placeholderstringShown when the editor is empty.
invalid / disabledbooleanSame contract as Input.