Mentions
Mention component.
When To Use#
When you need to mention someone or something.
Usage upgrade after 4.24.4#
// works when >=4.24.4, recommended ✅
const options = [{ value: 'sample', label: 'sample' }];
return <Mentions options={options} />;
// works when <4.24.4, deprecated when >=4.24.4 🙅🏻♀️
<Mentions onChange={onChange}>
  <Mentions.Option value="sample">Sample</Mentions.Option>
</Mentions>;Examples
TypeScript
JavaScript
import React from 'react';
import { Mentions } from 'antd';
import type { MentionsOptionProps } from 'antd/es/mentions';
const onChange = (value: string) => {
  console.log('Change:', value);
};
const onSelect = (option: MentionsOptionProps) => {
  console.log('select', option);
};
const App: React.FC = () => (
  <Mentions
    style={{ width: '100%' }}
    onChange={onChange}
    onSelect={onSelect}
    defaultValue="@afc163"
    options={[
      {
        value: 'afc163',
        label: 'afc163',
      },
      {
        value: 'zombieJ',
        label: 'zombieJ',
      },
      {
        value: 'yesmeck',
        label: 'yesmeck',
      },
    ]}
  />
);
export default App;TypeScript
JavaScript
import React from 'react';
import { Button, Form, Mentions } from 'antd';
const { getMentions } = Mentions;
const App: React.FC = () => {
  const [form] = Form.useForm();
  const onReset = () => {
    form.resetFields();
  };
  const onFinish = async () => {
    try {
      const values = await form.validateFields();
      console.log('Submit:', values);
    } catch (errInfo) {
      console.log('Error:', errInfo);
    }
  };
  const checkMention = async (_: any, value: string) => {
    const mentions = getMentions(value);
    if (mentions.length < 2) {
      throw new Error('More than one must be selected!');
    }
  };
  return (
    <Form form={form} layout="horizontal" onFinish={onFinish}>
      <Form.Item
        name="coders"
        label="Top coders"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 16 }}
        rules={[{ validator: checkMention }]}
      >
        <Mentions
          rows={1}
          options={[
            {
              value: 'afc163',
              label: 'afc163',
            },
            {
              value: 'zombieJ',
              label: 'zombieJ',
            },
            {
              value: 'yesmeck',
              label: 'yesmeck',
            },
          ]}
        />
      </Form.Item>
      <Form.Item
        name="bio"
        label="Bio"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 16 }}
        rules={[{ required: true }]}
      >
        <Mentions
          rows={3}
          placeholder="You can use @ to ref user here"
          options={[
            {
              value: 'afc163',
              label: 'afc163',
            },
            {
              value: 'zombieJ',
              label: 'zombieJ',
            },
            {
              value: 'yesmeck',
              label: 'yesmeck',
            },
          ]}
        />
      </Form.Item>
      <Form.Item wrapperCol={{ span: 14, offset: 6 }}>
        <Button htmlType="submit" type="primary">
          Submit
        </Button>
           
        <Button htmlType="button" onClick={onReset}>
          Reset
        </Button>
      </Form.Item>
    </Form>
  );
};
export default App;TypeScript
JavaScript
import React from 'react';
import { Mentions } from 'antd';
const options = ['afc163', 'zombiej', 'yesmeck'].map(value => ({
  value,
  key: value,
  label: value,
}));
const App: React.FC = () => (
  <>
    <div style={{ marginBottom: 10 }}>
      <Mentions
        style={{ width: '100%' }}
        placeholder="this is disabled Mentions"
        disabled
        options={options}
      />
    </div>
    <Mentions
      style={{ width: '100%' }}
      placeholder="this is readOnly Mentions"
      readOnly
      options={options}
    />
  </>
);
export default App;TypeScript
JavaScript
import React from 'react';
import { Mentions } from 'antd';
const App: React.FC = () => (
  <Mentions
    autoSize
    style={{ width: '100%' }}
    options={[
      {
        value: 'afc163',
        label: 'afc163',
      },
      {
        value: 'zombieJ',
        label: 'zombieJ',
      },
      {
        value: 'yesmeck',
        label: 'yesmeck',
      },
    ]}
  />
);
export default App;TypeScript
JavaScript
import React, { useCallback, useRef, useState } from 'react';
import { Mentions } from 'antd';
import debounce from 'lodash/debounce';
const App: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [users, setUsers] = useState<{ login: string; avatar_url: string }[]>([]);
  const ref = useRef<string>();
  const loadGithubUsers = (key: string) => {
    if (!key) {
      setUsers([]);
      return;
    }
    fetch(`https://api.github.com/search/users?q=${key}`)
      .then(res => res.json())
      .then(({ items = [] }) => {
        if (ref.current !== key) return;
        setLoading(false);
        setUsers(items.slice(0, 10));
      });
  };
  const debounceLoadGithubUsers = useCallback(debounce(loadGithubUsers, 800), []);
  const onSearch = (search: string) => {
    console.log('Search:', search);
    ref.current = search;
    setLoading(!!search);
    setUsers([]);
    debounceLoadGithubUsers(search);
  };
  return (
    <Mentions
      style={{ width: '100%' }}
      loading={loading}
      onSearch={onSearch}
      options={users.map(({ login, avatar_url: avatar }) => ({
        key: login,
        value: login,
        className: 'antd-demo-dynamic-option',
        label: (
          <>
            <img src={avatar} alt={login} />
            <span>{login}</span>
          </>
        ),
      }))}
    />
  );
};
export default App;TypeScript
JavaScript
import React, { useState } from 'react';
import { Mentions } from 'antd';
const MOCK_DATA = {
  '@': ['afc163', 'zombiej', 'yesmeck'],
  '#': ['1.0', '2.0', '3.0'],
};
type PrefixType = keyof typeof MOCK_DATA;
const App: React.FC = () => {
  const [prefix, setPrefix] = useState<PrefixType>('@');
  const onSearch = (_: string, newPrefix: PrefixType) => {
    setPrefix(newPrefix);
  };
  return (
    <Mentions
      style={{ width: '100%' }}
      placeholder="input @ to mention people, # to mention tag"
      prefix={['@', '#']}
      onSearch={onSearch}
      options={(MOCK_DATA[prefix] || []).map(value => ({
        key: value,
        value,
        label: value,
      }))}
    />
  );
};
export default App;TypeScript
JavaScript
import React from 'react';
import { Mentions } from 'antd';
const App: React.FC = () => (
  <Mentions
    style={{ width: '100%' }}
    placement="top"
    options={[
      {
        value: 'afc163',
        label: 'afc163',
      },
      {
        value: 'zombieJ',
        label: 'zombieJ',
      },
      {
        value: 'yesmeck',
        label: 'yesmeck',
      },
    ]}
  />
);
export default App;TypeScript
JavaScript
import { Mentions, Space } from 'antd';
import type { OptionProps } from 'antd/es/mentions';
import React from 'react';
const { Option } = Mentions;
const onChange = (value: string) => {
  console.log('Change:', value);
};
const onSelect = (option: OptionProps) => {
  console.log('select', option);
};
const App: React.FC = () => {
  const options = (
    <>
      <Option value="afc163">afc163</Option>
      <Option value="zombieJ">zombieJ</Option>
      <Option value="yesmeck">yesmeck</Option>
    </>
  );
  return (
    <Space direction="vertical">
      <Mentions onChange={onChange} onSelect={onSelect} defaultValue="@afc163" status="error">
        {options}
      </Mentions>
      <Mentions onChange={onChange} onSelect={onSelect} defaultValue="@afc163" status="warning">
        {options}
      </Mentions>
    </Space>
  );
};
export default App;API#
Mention#
| Property | Description | Type | Default | Version | 
|---|---|---|---|---|
| autoFocus | Auto get focus when component mounted | boolean | false | |
| autoSize | Textarea height autosize feature, can be set to true | false or an object { minRows: 2, maxRows: 6 } | boolean | object | false | |
| defaultValue | Default value | string | - | |
| filterOption | Customize filter option logic | false | (input: string, option: OptionProps) => boolean | - | |
| getPopupContainer | Set the mount HTML node for suggestions | () => HTMLElement | - | |
| notFoundContent | Set mentions content when not match | ReactNode | Not Found | |
| placement | Set popup placement | top|bottom | bottom | |
| prefix | Set trigger prefix keyword | string | string[] | @ | |
| split | Set split string before and after selected mention | string |  | |
| status | Set validation status | 'error' | 'warning' | 'success' | 'validating' | - | 4.19.0 | 
| validateSearch | Customize trigger search logic | (text: string, props: MentionsProps) => void | - | |
| value | Set value of mentions | string | - | |
| onBlur | Trigger when mentions lose focus | () => void | - | |
| onChange | Trigger when value changed | (text: string) => void | - | |
| onFocus | Trigger when mentions get focus | () => void | - | |
| onResize | The callback function that is triggered when textarea resize | function({ width, height }) | - | |
| onSearch | Trigger when prefix hit | (text: string, prefix: string) => void | - | |
| onSelect | Trigger when user select the option | (option: OptionProps, prefix: string) => void | - | |
| options | Option Configuration | Options | [] | 4.24.4 | 
Mention methods#
| Name | Description | 
|---|---|
| blur() | Remove focus | 
| focus() | Get focus | 
Option#
| Property | Description | Type | Default | 
|---|---|---|---|
| value | The value of suggestion, the value will insert into input filed while selected | string | - | 
| label | Title of the option | React.ReactNode | - | 
| key | The key value of the option | string | - | 
| disabled | Optional | boolean | - | 
| className | className | string | - | 
| style | The style of the option | React.CSSProperties | - |