User and channel mentions
This guide wires the mention events into a complete picker - the flow behind a
chat composer where typing @ suggests people and # suggests channels. If you
haven't met the mention API yet, read
Mentions first; here we move quickly and
assume the events and setMention are familiar.
The data behind a mention
Mentions are particularly useful if they point at something. Keep two lists around - one
for users, one for channels - each item carrying an id you can attach
to the finished mention:
const USERS = [
{ id: 'u1', name: 'John Doe' },
{ id: 'u2', name: 'Jane Smith' },
{ id: 'u3', name: 'Alice Johnson' },
{ id: 'u4', name: 'Bob Brown' },
];
const CHANNELS = [
{ id: 'c1', name: 'general' },
{ id: 'c2', name: 'engineering' },
{ id: 'c3', name: 'random' },
{ id: 'c4', name: 'announcements' },
];
Wiring the picker
Now let's register both indicators and the events callbacks:
<EnrichedTextInput
mentionIndicators={['@', '#']}
onStartMention={openPicker} // fired when '@' or '#' is typed
onChangeMention={updateQuery} // fired on every keystroke after an indicator
onEndMention={closePicker} // fired when the mention is left
// ...
/>
onStartMention hands you the indicator, so you know whether to show people or
channels. onChangeMention hands you the text typed so far - filter your list
with it. onEndMention fires when the cursor leaves the mention, so you dismiss
the list.
When the user taps a suggestion, finish the mention with setMention. Pass the
same indicator that started it, the display text, and
the item's data as attributes:
const pick = (item) => {
ref.current?.setMention(indicator, `${indicator}${item.name}`, {
id: item.id,
});
};
Now let's give each indicator its own look through
htmlStyle.mention:
const htmlStyle = {
mention: {
'@': { color: '#2b7a4b', backgroundColor: '#d8f3e3' },
'#': { color: '#2b5f9e', backgroundColor: '#d8e6f9' },
},
};
Try it out
Type @ to filter people or # to filter channels, keep typing to narrow the
list, then tap a suggestion.
A mention is only active while the editor is focused - if it blurs,
onEndMention fires and setMention becomes a no-op. On native, tapping a
suggestion never steals focus, so it just works. On web it does, so the rows
call preventDefault on mousedown to keep the editor focused. The example
wraps that in a small keepEditorFocused helper (see the Code tab).
The attributes you pass to setMention (here { id }) ride along in the HTML
and survive a round-trip through getHTML / setValue. Prefix custom keys with
data- if they need to outlive a sanitizer - see the note in
Mentions.