Part of the Ant Design ecosystem.
💬 React mentions textarea with searchable suggestions and keyboard navigation.
English | ç®€ä½“ä¸æ–‡
- Textarea mentions with prefix based search and selection.
- Keyboard navigation for suggestion menus.
- Data-driven
optionsAPI andOptionchildren API. - Multiple prefixes, custom filtering, custom validation, and split token support.
- Built on
@rc-component/input,@rc-component/menu, and@rc-component/trigger.
npm install @rc-component/mentionsThe package is published as
@rc-component/mentions. Legacyrc-mentionsreferences should migrate to the scoped package name.
import Mentions from '@rc-component/mentions';
const options = [
{ value: 'light', label: 'Light' },
{ value: 'bamboo', label: 'Bamboo' },
{ value: 'cat', label: 'Cat' },
];
export default () => (
<Mentions options={options} placeholder="Use @ to mention someone" />
);import Mentions from '@rc-component/mentions';
const { Option } = Mentions;
export default () => (
<Mentions prefix={['@', '#']}>
<Option value="design">Design</Option>
<Option value="docs">Docs</Option>
</Mentions>
);Import the styles from assets/index.less or the compiled CSS generated by npm run compile.
Run the local dumi site:
npm install
npm startThen open http://localhost:8000.
| Property | Type | Default | Description |
|---|---|---|---|
| allowClear | boolean | AllowClearConfig |
false |
Show a clear button for the textarea value. |
| autoFocus | boolean |
false |
Focus the textarea when mounted. |
| autoSize | boolean | { minRows?: number; maxRows?: number } |
- | Auto resize textarea height. |
| children | ReactNode |
- | Mentions.Option children. |
| className | string |
- | Class name for the root element. |
| classNames | MentionsProps['classNames'] |
- | Semantic class names for slots. |
| defaultValue | string |
- | Initial value. |
| direction | 'ltr' | 'rtl' |
ltr |
Popup direction. |
| filterOption | false | (input: string, option: OptionProps) => boolean |
- | Customize option filtering. |
| getPopupContainer | () => HTMLElement |
- | Container for the suggestion popup. |
| id | string |
- | Textarea id. |
| notFoundContent | ReactNode |
Not Found |
Content shown when no option matches. |
| options | DataDrivenOptionProps[] |
- | Data-driven options. |
| placement | 'top' | 'bottom' |
bottom |
Suggestion popup placement. |
| popupClassName | string |
- | Class name for the popup. |
| prefix | string | string[] |
@ |
Trigger prefix or prefixes. |
| prefixCls | string |
rc-mentions |
Class name prefix. |
| rows | number |
1 |
Textarea row count. |
| silent | boolean |
false |
Ignore Enter behavior during transition phases. |
| split | string |
' ' |
String inserted after a selected mention. |
| style | React.CSSProperties |
- | Inline styles for the root element. |
| styles | MentionsProps['styles'] |
- | Semantic styles for slots. |
| transitionName | string |
- | Popup transition name. |
| validateSearch | (text: string, split: MentionsProps['split']) => boolean |
- | Customize trigger search logic. |
| value | string |
- | Controlled value. |
| onBlur | React.FocusEventHandler<HTMLTextAreaElement> |
- | Triggered when textarea loses focus. |
| onChange | (text: string) => void |
- | Triggered when value changes. |
| onFocus | React.FocusEventHandler<HTMLTextAreaElement> |
- | Triggered when textarea receives focus. |
| onKeyDown | React.KeyboardEventHandler<HTMLTextAreaElement> |
- | Triggered on key down. |
| onKeyUp | React.KeyboardEventHandler<HTMLTextAreaElement> |
- | Triggered on key up. |
| onPopupScroll | (event: React.UIEvent<HTMLDivElement>) => void |
- | Triggered when the popup scrolls. |
| onPressEnter | React.KeyboardEventHandler<HTMLTextAreaElement> |
- | Triggered when Enter is pressed. |
| onResize | (size: { width: number; height: number }) => void |
- | Triggered when textarea size changes. |
| onSearch | (text: string, prefix: string) => void |
- | Triggered when a prefix starts a search. |
| onSelect | (option: OptionProps, prefix: string) => void |
- | Triggered when an option is selected. |
| popupRender | (menu: React.ReactElement) => ReactNode |
- | Customize the dropdown menu rendering |
| Property | Type | Default | Description |
|---|---|---|---|
| children | ReactNode |
- | Option label. |
| className | string |
- | Class name for the option. |
| disabled | boolean |
false |
Disable the option. |
| key | string |
- | React key and option key. |
| style | React.CSSProperties |
- | Inline option style. |
| value | string |
- | Mention value inserted into the textarea. |
import Mentions, { type MentionsRef } from '@rc-component/mentions';
const ref = React.useRef<MentionsRef>(null);
ref.current?.focus();
ref.current?.blur();| Property | Type | Description |
|---|---|---|
| focus | () => void |
Focus the textarea. |
| blur | () => void |
Blur the textarea. |
| textarea | HTMLTextAreaElement | null |
Deprecated textarea reference. |
| nativeElement | HTMLElement |
Root native element. |
npm install
npm start
npm test
npm run tsc
npm run compile
npm run buildThe dumi site runs at http://localhost:8000 by default.
npm run prepublishOnlyThe release flow is handled by @rc-component/np through the rc-np command after the package build.
@rc-component/mentions is released under the MIT license.
allowClear accepts a boolean or an AllowClearConfig object from @rc-component/util:
interface AllowClearConfig {
clearIcon?: React.ReactNode;
disabled?: boolean;
tabIndex?: number;
label?: string;
}All fields are optional. disabled: true behaves like allowClear={false}: the clear button and space reserved solely for it are removed; the input remains editable. Existing suffixes and other content are preserved. This changes the previous hidden-button spacing behavior where applicable.
tabIndex affects only the clear button; -1 removes it from Tab navigation while retaining mouse activation. label supplies its accessible name through aria-label. Defaults, clear values, callbacks, and component state restrictions are unchanged.
When no other affix keeps the wrapper mounted, dynamically disabling clearing can recreate the input DOM node and lose focus or selection, just like switching to allowClear={false}. The value is preserved. With an existing suffix, the wrapper, focus, and selection remain stable.