HomeBytesheetsUI TemplatesUI ToolsRoad MapsStack DiscussionByte Camp
BytesUIv0.5.3
⌘K

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

PropTypeDefaultDescription
triggersMentionTrigger[]requiredArray of trigger configurations with character and data sources
valuestringundefinedControlled textarea value
defaultValuestring''Default value for uncontrolled mode
onChange(value: string, mentions: MentionItem[]) => voidundefinedCallback fired when text or mentions change
rowsnumber4Number of visible rows in textarea
idstringundefinedElement ID passed through to the underlying textarea.
namestringundefinedForm control name passed through to the underlying textarea.
disabledbooleanfalseDisables the textarea. Automatically resolves to the neutral color palette.
readOnlybooleanfalseMakes 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.
styleMentionTextAreaSlotStyleundefinedSlot-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) => ReactNodeundefinedCustom renderer for suggestion items
renderLoading() => ReactNodeundefinedCustom loading state renderer
renderNotFound() => ReactNodeundefinedCustom 'no results' renderer
dropdownClassNamestring''Custom CSS class for dropdown wrapper
dropdownStyleCSSPropertiesundefinedInline styles for dropdown wrapper
activeItemClassNamestring''Custom CSS class for highlighted item

MentionTextArea Style Slots

SlotDescription
Bui.rootContainer wrapper around the textarea and dropdown.
Bui.textareaTextarea element (default state).
Bui.textareaFocusTextarea while focused.
Bui.textareaDisabledTextarea while disabled.
Bui.placeholderPlaceholder color/typography. Adapts automatically per `variant`.
Bui.dropdownSuggestion dropdown container.
Bui.dropdownItemIndividual suggestion item (default state).
Bui.dropdownItemHighlightedHighlighted/keyboard-selected suggestion item.
Bui.dropdownItemDisabledDisabled suggestion item.
Bui.dropdownLoadingLoading state text while async data resolves.
Bui.dropdownNotFound'No results' state text.