MentionTextArea
Rich textarea with mention triggers, async data sources, and customizable dropdown rendering for user mentions, hashtags, and more.
Quick Usage
Basic usage of `MentionTextArea` with a simple mention trigger. Remember to wrap your app in `ThemeProvider` (see the Theming page) so `color` and `variant` resolve correctly.
import React, { useState } from 'react';
import { MentionTextArea } from '@bytesui/react';
const users = [
{ id: '1', display: 'John Doe', subtitle: '@john' },
{ id: '2', display: 'Jane Smith', subtitle: '@jane' },
{ id: '3', display: 'Bob Johnson', subtitle: '@bob' },
];
export default function MentionExample() {
const [text, setText] = useState('');
const [mentions, setMentions] = useState([]);
return (
<MentionTextArea
value={text}
onChange={(value, mentionedItems) => {
setText(value);
setMentions(mentionedItems);
}}
triggers={[
{
trigger: '@',
data: users,
}
]}
rows={4}
placeholder="Type @ to mention someone..."
/>
);
}Interactive Demo
Test MentionTextArea with multiple triggers and async data loading.
Advanced Usage
Custom rendering, async data sources, and dropdown styling.
import React, { useState } from 'react';
import { MentionTextArea } from '@bytesui/react';
const fetchUsersAsync = async (query) => {
// Simulate API call
const allUsers = [
{ id: '1', display: 'Alice Johnson', subtitle: '@alice', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Alice' },
{ id: '2', display: 'Bob Smith', subtitle: '@bob', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Bob' },
];
return new Promise((resolve) => {
setTimeout(() => {
const filtered = allUsers.filter(u =>
u.display.toLowerCase().includes(query.toLowerCase())
);
resolve(filtered);
}, 500);
});
};
export default function AdvancedMentionExample() {
const [text, setText] = useState('');
const [mentions, setMentions] = useState([]);
return (
<MentionTextArea
value={text}
onChange={(value, items) => {
setText(value);
setMentions(items);
}}
triggers={[
{
trigger: '@',
data: fetchUsersAsync,
triggerClassName: 'mention-trigger',
}
]}
rows={6}
placeholder="Mention someone..."
placement="auto"
dropdownClassName="mention-dropdown"
dropdownStyle={{
maxHeight: '300px',
borderRadius: '8px',
}}
renderSuggestion={(item, isHighlighted) => (
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
{item.avatar && (
<img
src={item.avatar}
alt={item.display}
style={{ width: '28px', height: '28px', borderRadius: '50%' }}
/>
)}
<div>
<div style={{ fontWeight: 500 }}>{item.display}</div>
<div style={{ fontSize: '12px', color: '#888' }}>{item.subtitle}</div>
</div>
</div>
)}
renderLoading={() => <div>Loading users...</div>}
renderNotFound={() => <div>No users found</div>}
/>
);
}Color & Variant
`MentionTextArea` accepts `color` (one of the 8 semantic colors) and `variant` (`solid` | `outlined` | `soft` | `plain`). Defaults are `color="primary"` and `variant="outlined"`. When `disabled` is `true`, the neutral palette is used automatically.
import React, { useState } from 'react';
import { MentionTextArea } from '@bytesui/react';
const users = [{ id: '1', display: 'John Doe', subtitle: '@john' }];
export default function MentionColorVariantExample() {
const [text, setText] = useState('');
return (
<>
<MentionTextArea
value={text}
onChange={(value) => setText(value)}
triggers={[{ trigger: '@', data: users }]}
color="secondary"
variant="solid"
/>
<MentionTextArea
value={text}
onChange={(value) => setText(value)}
triggers={[{ trigger: '@', data: users }]}
color="success"
variant="soft"
/>
</>
);
}Slot Styling
Use the `style` prop with `Bui.*` slot keys to override the textarea, placeholder, and suggestion dropdown independently. `Bui.placeholder` controls placeholder color/typography and adapts automatically per `variant` unless overridden.
import React, { useState } from 'react';
import { MentionTextArea } from '@bytesui/react';
const users = [{ id: '1', display: 'John Doe', subtitle: '@john' }];
export default function MentionSlotStylingExample() {
const [text, setText] = useState('');
return (
<MentionTextArea
value={text}
onChange={(value) => setText(value)}
triggers={[{ trigger: '@', data: users }]}
color="tertiary"
style={{
'Bui.textarea': { borderRadius: '10px', fontSize: '14px' },
'Bui.textareaFocus': { borderColor: '#0ea5e9' },
'Bui.placeholder': { color: '#94a3b8', opacity: 0.6, fontStyle: 'italic' },
'Bui.dropdown': { borderRadius: '10px' },
'Bui.dropdownItem': { padding: '8px 12px' },
'Bui.dropdownItemHighlighted': { backgroundColor: '#e0f2fe' }
}}
/>
);
}MentionTextArea API
| Prop | Type | Default | Description |
|---|---|---|---|
triggers | MentionTrigger[] | required | Array of trigger configurations with character and data sources |
value | string | undefined | Controlled textarea value |
defaultValue | string | '' | Default value for uncontrolled mode |
onChange | (value: string, mentions: MentionItem[]) => void | undefined | Callback fired when text or mentions change |
rows | number | 4 | Number of visible rows in textarea |
id | string | undefined | Element ID passed through to the underlying textarea. |
name | string | undefined | Form control name passed through to the underlying textarea. |
disabled | boolean | false | Disables the textarea. Automatically resolves to the neutral color palette. |
readOnly | boolean | false | Makes the textarea read-only |
color | 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'error' | 'neutral' | 'info' | "primary" | Semantic color of the textarea, resolved from the active theme. |
variant | 'solid' | 'outlined' | 'soft' | 'plain' | "outlined" | Visual style variant of the textarea. |
style | MentionTextAreaSlotStyle | undefined | Slot-based style overrides keyed by `Bui.*` slot names. See the slots reference below. |
placement | 'auto' | 'top' | 'bottom' | 'auto' | Dropdown placement direction |
renderSuggestion | (item: MentionItem, isHighlighted: boolean) => ReactNode | undefined | Custom renderer for suggestion items |
renderLoading | () => ReactNode | undefined | Custom loading state renderer |
renderNotFound | () => ReactNode | undefined | Custom 'no results' renderer |
dropdownClassName | string | '' | Custom CSS class for dropdown wrapper |
dropdownStyle | CSSProperties | undefined | Inline styles for dropdown wrapper |
activeItemClassName | string | '' | Custom CSS class for highlighted item |
MentionTextArea Style Slots
| Slot | Description |
|---|---|
Bui.root | Container wrapper around the textarea and dropdown. |
Bui.textarea | Textarea element (default state). |
Bui.textareaFocus | Textarea while focused. |
Bui.textareaDisabled | Textarea while disabled. |
Bui.placeholder | Placeholder color/typography. Adapts automatically per `variant`. |
Bui.dropdown | Suggestion dropdown container. |
Bui.dropdownItem | Individual suggestion item (default state). |
Bui.dropdownItemHighlighted | Highlighted/keyboard-selected suggestion item. |
Bui.dropdownItemDisabled | Disabled suggestion item. |
Bui.dropdownLoading | Loading state text while async data resolves. |
Bui.dropdownNotFound | 'No results' state text. |