EnrichedMarkdownTextInput supports mention flows — token-triggered inline entities (e.g. @user, #channel) rendered as styled links.
- User types an indicator (
@,#) or toolbar callsstartMention(indicator). onStartMentionfires → show suggestion list.onChangeMentionfires on each keystroke → filter suggestions by query.- User picks a suggestion → call
insertMention(displayText, url). onEndMentionfires → hide suggestions.
<EnrichedMarkdownTextInput
ref={ref}
mentionIndicators={['@', '#']}
markdownStyle={{
link: { color: '#2563EB', underline: true },
linkVariants: {
'^user:': { color: '#1264A3', backgroundColor: '#E8F5FB', underline: false },
'^channel:': { color: '#065F46', backgroundColor: '#D1FAE5', underline: false },
},
}}
onStartMention={({ indicator }) => setShowSuggestions(true)}
onChangeMention={({ indicator, text }) => setQuery(text)}
onEndMention={() => setShowSuggestions(false)}
onCaretRectChange={setCaretRect} // for positioning the popup
/>When the user selects a suggestion:
ref.current?.insertMention(`@${item.name}`, item.url);
// Markdown output: [@Alice](user://u_1)| Prop | Type | Default | Description |
|---|---|---|---|
mentionIndicators |
string[] |
[] |
Trigger strings that start a mention flow. |
| Event | Payload | When |
|---|---|---|
onStartMention |
{ indicator } |
Mention flow starts. |
onChangeMention |
{ indicator, text } |
Query text changes (each keystroke). |
onEndMention |
{ indicator } |
Mention flow ends (cancel, insert, or cursor moved away). |
| Method | Description |
|---|---|
startMention(indicator) |
Inserts the indicator at cursor and triggers the mention flow. Must be in mentionIndicators. |
insertMention(displayText, url) |
Replaces the active mention token with a styled link. Only works during an active flow. |
Mentions are links — style them per URL pattern via linkVariants in markdownStyle:
linkVariants: {
'^user:': { color: '#1264A3', backgroundColor: '#E8F5FB', underline: false },
'^channel:': { color: '#065F46', backgroundColor: '#D1FAE5', underline: false },
}Each key is a regex tested against the link URL. First match wins. Unspecified properties inherit from the base link style. Patterns are auto-sorted longest-first.
Use onCaretRectChange to get the caret's { x, y, width, height } relative to the input. Combine with the input's position (via onLayout) to place a floating popup:
<View
style={{
position: 'absolute',
left: inputLayout.x + caretRect.x,
top: inputLayout.y + caretRect.y + caretRect.height + 4,
}}
>
{/* suggestions */}
</View>For simpler layouts, just render the list adjacent to the input without caret tracking.
- Atomic deletion: Backspacing into a mention deletes it entirely (Slack-like).
- Debounce:
onChangeMentionfires every keystroke — debounce network requests. - Toolbar: Call
focus()beforestartMention()if the input isn't focused. - URL schemes: Use custom schemes (
user://,channel://) to distinguish mention types from regular links.