mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 17:44:35 +08:00
chore: Remove LocaleProvider & Mention in export (#19935)
* chore: Clean up * clean up test case * clean up
This commit is contained in:
parent
ee7a55380d
commit
5fc62314af
@ -31,7 +31,6 @@ Array [
|
|||||||
"InputNumber",
|
"InputNumber",
|
||||||
"Layout",
|
"Layout",
|
||||||
"List",
|
"List",
|
||||||
"LocaleProvider",
|
|
||||||
"message",
|
"message",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Mentions",
|
"Mentions",
|
||||||
@ -63,7 +62,6 @@ Array [
|
|||||||
"Timeline",
|
"Timeline",
|
||||||
"Tooltip",
|
"Tooltip",
|
||||||
"Typography",
|
"Typography",
|
||||||
"Mention",
|
|
||||||
"Upload",
|
"Upload",
|
||||||
"version",
|
"version",
|
||||||
]
|
]
|
||||||
|
@ -7758,180 +7758,6 @@ exports[`ConfigProvider components List prefixCls 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Mention configProvider 1`] = `
|
|
||||||
<div
|
|
||||||
class="config-mention-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="config-mention-editor oneline"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="config-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="config-mention-editor-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ConfigProvider components Mention normal 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ConfigProvider components Mention prefixCls 1`] = `
|
|
||||||
<div
|
|
||||||
class="prefix-Mention-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="prefix-Mention-editor oneline"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="prefix-Mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="prefix-Mention-editor-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ConfigProvider components Menu configProvider 1`] = `
|
exports[`ConfigProvider components Menu configProvider 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-light config-menu-root config-menu-inline"
|
class="config-menu config-menu-light config-menu-root config-menu-inline"
|
||||||
|
@ -27,7 +27,6 @@ import Input from '../../input';
|
|||||||
import InputNumber from '../../input-number';
|
import InputNumber from '../../input-number';
|
||||||
import Layout from '../../layout';
|
import Layout from '../../layout';
|
||||||
import List from '../../list';
|
import List from '../../list';
|
||||||
import Mention from '../../mention';
|
|
||||||
import Menu from '../../menu';
|
import Menu from '../../menu';
|
||||||
import Modal from '../../modal';
|
import Modal from '../../modal';
|
||||||
import Pagination from '../../pagination';
|
import Pagination from '../../pagination';
|
||||||
@ -341,9 +340,6 @@ describe('ConfigProvider', () => {
|
|||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
// Mention
|
|
||||||
testPair('Mention', props => <Mention {...props} />);
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
testPair('Menu', props => (
|
testPair('Menu', props => (
|
||||||
<Menu {...props} defaultOpenKeys={['bamboo']} mode="inline">
|
<Menu {...props} defaultOpenKeys={['bamboo']} mode="inline">
|
||||||
|
@ -74,8 +74,6 @@ export { default as Layout } from './layout';
|
|||||||
|
|
||||||
export { default as List } from './list';
|
export { default as List } from './list';
|
||||||
|
|
||||||
export { default as LocaleProvider } from './locale-provider';
|
|
||||||
|
|
||||||
export { default as message } from './message';
|
export { default as message } from './message';
|
||||||
|
|
||||||
export { default as Menu } from './menu';
|
export { default as Menu } from './menu';
|
||||||
@ -138,8 +136,6 @@ export { default as Tooltip } from './tooltip';
|
|||||||
|
|
||||||
export { default as Typography } from './typography';
|
export { default as Typography } from './typography';
|
||||||
|
|
||||||
export { default as Mention } from './mention';
|
|
||||||
|
|
||||||
export { default as Upload } from './upload';
|
export { default as Upload } from './upload';
|
||||||
|
|
||||||
export { default as version } from './version';
|
export { default as version } from './version';
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
import demoTest from '../../../tests/shared/demoTest';
|
|
||||||
|
|
||||||
demoTest('locale-provider');
|
|
@ -3,10 +3,8 @@ import React from 'react';
|
|||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import MockDate from 'mockdate';
|
import MockDate from 'mockdate';
|
||||||
import { resetWarned } from '../../_util/warning';
|
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
|
||||||
Pagination,
|
Pagination,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
TimePicker,
|
TimePicker,
|
||||||
@ -17,6 +15,7 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
Transfer,
|
Transfer,
|
||||||
} from '../..';
|
} from '../..';
|
||||||
|
import LocaleProvider from '..';
|
||||||
import arEG from '../ar_EG';
|
import arEG from '../ar_EG';
|
||||||
import bgBG from '../bg_BG';
|
import bgBG from '../bg_BG';
|
||||||
import caES from '../ca_ES';
|
import caES from '../ca_ES';
|
||||||
@ -247,20 +246,4 @@ describe('Locale Provider', () => {
|
|||||||
wrapper.setState({ locale: null });
|
wrapper.setState({ locale: null });
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('warning if use LocaleProvider', () => {
|
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
||||||
resetWarned();
|
|
||||||
|
|
||||||
mount(
|
|
||||||
<LocaleProvider locale={{}}>
|
|
||||||
<div />
|
|
||||||
</LocaleProvider>,
|
|
||||||
);
|
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
|
||||||
'Warning: [antd: LocaleProvider] `LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead: http://u.ant.design/locale',
|
|
||||||
);
|
|
||||||
|
|
||||||
errorSpy.mockRestore();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
---
|
|
||||||
order: 2
|
|
||||||
title:
|
|
||||||
zh-CN: 所有组件
|
|
||||||
en-US: All components
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Components which need localization support are listed here, you can toggle the language in the demo.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import {
|
|
||||||
LocaleProvider,
|
|
||||||
Pagination,
|
|
||||||
DatePicker,
|
|
||||||
TimePicker,
|
|
||||||
Calendar,
|
|
||||||
Popconfirm,
|
|
||||||
Table,
|
|
||||||
Modal,
|
|
||||||
Button,
|
|
||||||
Select,
|
|
||||||
Transfer,
|
|
||||||
Radio,
|
|
||||||
} from 'antd';
|
|
||||||
import zhCN from 'antd/es/locale-provider/zh_CN';
|
|
||||||
import moment from 'moment';
|
|
||||||
import 'moment/locale/zh-cn';
|
|
||||||
|
|
||||||
moment.locale('en');
|
|
||||||
|
|
||||||
const { Option } = Select;
|
|
||||||
const { RangePicker } = DatePicker;
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: 'Name',
|
|
||||||
dataIndex: 'name',
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
text: 'filter1',
|
|
||||||
value: 'filter1',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Age',
|
|
||||||
dataIndex: 'age',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
class Page extends React.Component {
|
|
||||||
state = {
|
|
||||||
visible: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
showModal = () => {
|
|
||||||
this.setState({ visible: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
hideModal = () => {
|
|
||||||
this.setState({ visible: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const info = () => {
|
|
||||||
Modal.info({
|
|
||||||
title: 'some info',
|
|
||||||
content: 'some info',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const confirm = () => {
|
|
||||||
Modal.confirm({
|
|
||||||
title: 'some info',
|
|
||||||
content: 'some info',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="locale-components">
|
|
||||||
<div className="example">
|
|
||||||
<Pagination defaultCurrent={1} total={50} showSizeChanger />
|
|
||||||
</div>
|
|
||||||
<div className="example">
|
|
||||||
<Select showSearch style={{ width: 200 }}>
|
|
||||||
<Option value="jack">jack</Option>
|
|
||||||
<Option value="lucy">lucy</Option>
|
|
||||||
</Select>
|
|
||||||
<DatePicker />
|
|
||||||
<TimePicker />
|
|
||||||
<RangePicker style={{ width: 200 }} />
|
|
||||||
</div>
|
|
||||||
<div className="example">
|
|
||||||
<Button type="primary" onClick={this.showModal}>
|
|
||||||
Show Modal
|
|
||||||
</Button>
|
|
||||||
<Button onClick={info}>Show info</Button>
|
|
||||||
<Button onClick={confirm}>Show confirm</Button>
|
|
||||||
<Popconfirm title="Question?">
|
|
||||||
<a href="#">Click to confirm</a>
|
|
||||||
</Popconfirm>
|
|
||||||
</div>
|
|
||||||
<div className="example">
|
|
||||||
<Transfer dataSource={[]} showSearch targetKeys={[]} render={item => item.title} />
|
|
||||||
</div>
|
|
||||||
<div style={{ width: 319, border: '1px solid #d9d9d9', borderRadius: 4 }}>
|
|
||||||
<Calendar fullscreen={false} value={moment()} />
|
|
||||||
</div>
|
|
||||||
<div className="example">
|
|
||||||
<Table dataSource={[]} columns={columns} />
|
|
||||||
</div>
|
|
||||||
<Modal title="Locale Modal" visible={this.state.visible} onCancel={this.hideModal}>
|
|
||||||
<p>Locale Modal</p>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class App extends React.Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
locale: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
changeLocale = e => {
|
|
||||||
const localeValue = e.target.value;
|
|
||||||
this.setState({ locale: localeValue });
|
|
||||||
if (!localeValue) {
|
|
||||||
moment.locale('en');
|
|
||||||
} else {
|
|
||||||
moment.locale('zh-cn');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { locale } = this.state;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className="change-locale">
|
|
||||||
<span style={{ marginRight: 16 }}>Change locale of components: </span>
|
|
||||||
<Radio.Group defaultValue={undefined} onChange={this.changeLocale}>
|
|
||||||
<Radio.Button key="en" value={undefined}>
|
|
||||||
English
|
|
||||||
</Radio.Button>
|
|
||||||
<Radio.Button key="cn" value={zhCN}>
|
|
||||||
中文
|
|
||||||
</Radio.Button>
|
|
||||||
</Radio.Group>
|
|
||||||
</div>
|
|
||||||
<LocaleProvider locale={locale}>
|
|
||||||
<Page
|
|
||||||
key={locale ? locale.locale : 'en' /* Have to refresh for production environment */}
|
|
||||||
/>
|
|
||||||
</LocaleProvider>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, mountNode);
|
|
||||||
```
|
|
||||||
|
|
||||||
```css
|
|
||||||
.locale-components {
|
|
||||||
border-top: 1px solid #d9d9d9;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example {
|
|
||||||
margin: 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example > * {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.change-locale {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
order: 1
|
|
||||||
title:
|
|
||||||
zh-CN: 国际化
|
|
||||||
en-US: Localization
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
用 `LocaleProvider` 包裹你的应用,并引用对应的语言包。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Wrap your app with `LocaleProvider`, and apply the corresponding language package.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Pagination, LocaleProvider } from 'antd';
|
|
||||||
import zhCN from 'antd/es/locale-provider/zh_CN';
|
|
||||||
|
|
||||||
const App = () => (
|
|
||||||
<div>
|
|
||||||
<Pagination defaultCurrent={1} total={50} showSizeChanger />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<LocaleProvider locale={zhCN}>
|
|
||||||
<App />
|
|
||||||
</LocaleProvider>,
|
|
||||||
mountNode,
|
|
||||||
);
|
|
||||||
```
|
|
@ -1,56 +0,0 @@
|
|||||||
---
|
|
||||||
category: Components
|
|
||||||
type: Deprecated
|
|
||||||
cols: 1
|
|
||||||
title: LocaleProvider (Deprecated)
|
|
||||||
---
|
|
||||||
|
|
||||||
`LocaleProvider` component. Deprecated, please use [ConfigProvider](/components/config-provider) instead.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
`LocaleProvider` makes use of [context](https://facebook.github.io/react/docs/context.html), a feature of React, to accomplish global effectiveness by wrapping the app only once.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { LocaleProvider } from 'antd';
|
|
||||||
import fr_FR from 'antd/es/locale-provider/fr_FR';
|
|
||||||
import moment from 'moment';
|
|
||||||
import 'moment/locale/fr';
|
|
||||||
|
|
||||||
moment.locale('fr');
|
|
||||||
...
|
|
||||||
|
|
||||||
return <LocaleProvider locale={fr_FR}><App /></LocaleProvider>;
|
|
||||||
```
|
|
||||||
|
|
||||||
We provide some locales like English, Chinese, Russian, German, French etc. All locale packages can be found in [here](https://github.com/ant-design/ant-design/blob/master/components/locale-provider/).
|
|
||||||
|
|
||||||
Note: if you need to use antd's UMD dist file, please use `antd/dist/antd-with-locales.js` and corresponding moment locale:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
const { LocaleProvider, locales } = window.antd;
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
return <LocaleProvider locale={locales.fr_FR}><App /></LocaleProvider>;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add a new language
|
|
||||||
|
|
||||||
If you can't find your language, you are welcome to create a locale package based on [en_US](https://github.com/ant-design/ant-design/blob/master/components/locale-provider/en_US.tsx) and send us a pull request.
|
|
||||||
|
|
||||||
### Other localization needs
|
|
||||||
|
|
||||||
This component aims to provide localization of the built-in text. If you want to support other documents, we recommend using [react-intl](https://github.com/yahoo/react-intl), refer to [Intl demo 1](http://github.com/ant-design/intl-example) and [Intl demo 2](http://yiminghe.me/learning-react/examples/react-intl.html?locale=en-US).
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
| Property | Description | Type | Default | Version |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| locale | language package setting, you can find the packages in [antd/es/locale-provider](http://unpkg.com/antd/es/locale-provider/) | object | - | |
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
#### Locale problem is still existed even LocaleProvider is used?
|
|
||||||
|
|
||||||
Please make sure you set moment locale by `moment.locale('zh-cn')`, or you don't have two moment of different version.
|
|
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
category: Components
|
|
||||||
subtitle: 国际化(废弃)
|
|
||||||
cols: 1
|
|
||||||
type: 废弃
|
|
||||||
title: LocaleProvider
|
|
||||||
---
|
|
||||||
|
|
||||||
国际化组件。已废弃,请使用 [ConfigProvider](/components/config-provider) 代替。
|
|
||||||
|
|
||||||
## 使用
|
|
||||||
|
|
||||||
LocaleProvider 使用 React 的 [context](https://facebook.github.io/react/docs/context.html) 特性,只需在应用外围包裹一次即可全局生效。
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { LocaleProvider } from 'antd';
|
|
||||||
import zh_CN from 'antd/es/locale-provider/zh_CN';
|
|
||||||
import moment from 'moment';
|
|
||||||
import 'moment/locale/zh-cn';
|
|
||||||
|
|
||||||
moment.locale('zh-cn');
|
|
||||||
...
|
|
||||||
|
|
||||||
return <LocaleProvider locale={zh_CN}><App /></LocaleProvider>;
|
|
||||||
```
|
|
||||||
|
|
||||||
我们提供了英语,中文,俄语,法语,德语等多种语言支持,所有语言包可以在 [这里](https://github.com/ant-design/ant-design/blob/master/components/locale-provider/) 找到。
|
|
||||||
|
|
||||||
注意:如果你需要使用 UMD 版的 dist 文件,应该引入 `antd/dist/antd-with-locales.js`,同时引入 moment 对应的 locale,然后按以下方式使用:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
const { LocaleProvider, locales } = window.antd;
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
return <LocaleProvider locale={locales.en_US}><App /></LocaleProvider>;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 增加语言包
|
|
||||||
|
|
||||||
如果你找不到你需要的语言包,欢迎你在 [英文语言包](https://github.com/ant-design/ant-design/blob/master/components/locale-provider/en_US.tsx) 的基础上创建一个新的语言包,并给我们 Pull Request。
|
|
||||||
|
|
||||||
### 其他国际化需求
|
|
||||||
|
|
||||||
本模块仅用于组件的内建文案,若有业务文案的国际化需求,建议使用 [react-intl](https://github.com/yahoo/react-intl),可参考示例:[Intl demo 1](http://github.com/ant-design/intl-example) 和 [Intl demo 2](http://yiminghe.me/learning-react/examples/react-intl.html?locale=en-US)。
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| locale | 语言包配置,语言包可到 [antd/es/locale-provider](http://unpkg.com/antd/es/locale-provider/) 目录下寻找 | object | - | |
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
#### 为什么我使用了 LocaleProvider 还有问题?
|
|
||||||
|
|
||||||
请检查是否设置了 `moment.locale('zh-cn')`,或者是否有两个版本的 moment 共存。
|
|
@ -1,796 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/async.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/avatar.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/basic.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-text="true"
|
|
||||||
>
|
|
||||||
@afc163
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/controllder-simple.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-text="true"
|
|
||||||
>
|
|
||||||
@afc163
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/controlled.md correctly 1`] = `
|
|
||||||
<form
|
|
||||||
class="ant-form ant-form-horizontal"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-row ant-form-item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-col ant-col-6 ant-form-item-label"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class=""
|
|
||||||
for="mention"
|
|
||||||
title="Top coders"
|
|
||||||
>
|
|
||||||
Top coders
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="ant-col ant-col-16 ant-form-item-control"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-form-item-control-input"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-text="true"
|
|
||||||
>
|
|
||||||
@afc163
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="ant-row ant-form-item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-col ant-col-14 ant-col-offset-6 ant-form-item-control"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-form-item-control-input"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="ant-btn ant-btn-primary"
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
Submit
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="ant-btn"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
Reset
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/custom-tag.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-inner"
|
|
||||||
id="placeholder-123"
|
|
||||||
style="white-space:pre-wrap"
|
|
||||||
>
|
|
||||||
@someone
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/multilines.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper multilines"
|
|
||||||
style="width:100%;height:100px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor"
|
|
||||||
style="width:100%;height:100px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%;height:100px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/multiple-trigger.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-inner"
|
|
||||||
id="placeholder-123"
|
|
||||||
style="white-space:pre-wrap"
|
|
||||||
>
|
|
||||||
input @ to mention people, # to mention tag
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/placement.md correctly 1`] = `
|
|
||||||
<div
|
|
||||||
class="ant-mention-placement-top ant-mention-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="notranslate public-DraftEditor-content"
|
|
||||||
contenteditable="true"
|
|
||||||
role="textbox"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/popupContainer.md correctly 1`] = `
|
|
||||||
<button
|
|
||||||
class="ant-btn ant-btn-primary"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
Click Me
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`renders ./components/mention/demo/readonly.md correctly 1`] = `
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
style="margin-bottom:10px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper disabled"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor readonly oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-inner"
|
|
||||||
id="placeholder-123"
|
|
||||||
style="white-space:pre-wrap"
|
|
||||||
>
|
|
||||||
this is disabled Mention
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="public-DraftEditor-content"
|
|
||||||
contenteditable="false"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
style="width:0;opacity:0;border:0;position:absolute;left:0;top:0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="ant-mention-wrapper readonly"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor readonly oneline"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-mention-toolbar"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="ant-mention-editor-wrapper"
|
|
||||||
style="width:100%"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-root"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftEditorPlaceholder-inner"
|
|
||||||
id="placeholder-123"
|
|
||||||
style="white-space:pre-wrap"
|
|
||||||
>
|
|
||||||
this is readOnly Mention
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="DraftEditor-editorContainer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-describedby="placeholder-123"
|
|
||||||
class="public-DraftEditor-content"
|
|
||||||
contenteditable="false"
|
|
||||||
spellcheck="false"
|
|
||||||
style="outline:none;user-select:text;-webkit-user-select:text;white-space:pre-wrap;word-wrap:break-word"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
data-contents="true"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
data-block="true"
|
|
||||||
data-editor="123"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
data-offset-key="123-0-0"
|
|
||||||
>
|
|
||||||
<br
|
|
||||||
data-text="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
style="width:0;opacity:0;border:0;position:absolute;left:0;top:0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,5 +0,0 @@
|
|||||||
import demoTest from '../../../tests/shared/demoTest';
|
|
||||||
|
|
||||||
jest.mock('draft-js/lib/generateRandomKey', () => () => '123');
|
|
||||||
|
|
||||||
demoTest('mention', { skip: process.env.LIB_DIR === 'dist' });
|
|
@ -1,123 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import Mention from '..';
|
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
|
||||||
|
|
||||||
const { toContentState } = Mention;
|
|
||||||
|
|
||||||
describe('Mention', () => {
|
|
||||||
mountTest(Mention);
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
jest.useFakeTimers();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
jest.useRealTimers();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should has focus function', () => {
|
|
||||||
const handleFocus = jest.fn();
|
|
||||||
const wrapper = mount(
|
|
||||||
<Mention
|
|
||||||
defaultValue={toContentState('@afc163')}
|
|
||||||
onFocus={handleFocus}
|
|
||||||
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
wrapper.instance().focus();
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(handleFocus).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('basic suggestion', () => {
|
|
||||||
const handleSearch = jest.fn();
|
|
||||||
const wrapper = mount(
|
|
||||||
<Mention suggestions={['afc163', 'raohai']} onSearchChange={handleSearch} />,
|
|
||||||
);
|
|
||||||
wrapper.find('DraftEditorContents').simulate('focus');
|
|
||||||
const ed = wrapper.find('.public-DraftEditor-content');
|
|
||||||
ed.simulate('beforeInput', { data: '@a' });
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(handleSearch).toHaveBeenCalledWith('a', '@');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('change suggestions', () => {
|
|
||||||
const container = mount(<div id="container" />);
|
|
||||||
const wrapper = mount(
|
|
||||||
<Mention
|
|
||||||
suggestions={['afc163', 'raohai']}
|
|
||||||
getSuggestionContainer={() => container.getDOMNode()}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
wrapper.find('DraftEditorContents').simulate('focus');
|
|
||||||
const ed = wrapper.find('.public-DraftEditor-content');
|
|
||||||
ed.simulate('beforeInput', { data: '@' });
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(container.getDOMNode().querySelectorAll('.ant-mention-dropdown-item').length).toBe(2);
|
|
||||||
expect(container.getDOMNode().querySelectorAll('.ant-mention-dropdown-item')[0].innerHTML).toBe(
|
|
||||||
'afc163',
|
|
||||||
);
|
|
||||||
wrapper.setProps({ suggestions: ['yesmeck', 'yiminghe', 'lucy'] });
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(container.getDOMNode().querySelectorAll('.ant-mention-dropdown-item').length).toBe(3);
|
|
||||||
expect(container.getDOMNode().querySelectorAll('.ant-mention-dropdown-item')[0].innerHTML).toBe(
|
|
||||||
'yesmeck',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('select item', () => {
|
|
||||||
const onChange = jest.fn();
|
|
||||||
const onSelect = jest.fn();
|
|
||||||
const wrapper = mount(
|
|
||||||
<Mention suggestions={['afc163', 'raohai']} onChange={onChange} onSelect={onSelect} />,
|
|
||||||
);
|
|
||||||
wrapper.find('DraftEditorContents').simulate('focus');
|
|
||||||
const ed = wrapper.find('.public-DraftEditor-content');
|
|
||||||
ed.simulate('beforeInput', { data: '@' });
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(onChange).toHaveBeenCalled();
|
|
||||||
expect(onSelect).not.toHaveBeenCalled();
|
|
||||||
wrapper
|
|
||||||
.find('.ant-mention-dropdown-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('mouseDown');
|
|
||||||
wrapper
|
|
||||||
.find('.ant-mention-dropdown-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('mouseUp');
|
|
||||||
wrapper
|
|
||||||
.find('.ant-mention-dropdown-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
jest.runAllTimers();
|
|
||||||
expect(onSelect).toHaveBeenCalled();
|
|
||||||
expect(wrapper.find('.public-DraftStyleDefault-block').text()).toBe('@afc163 ');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('defaultSuggestion filter', () => {
|
|
||||||
const wrapper = mount(<Mention defaultSuggestions={['light', 'bamboo']} />);
|
|
||||||
|
|
||||||
wrapper.find('DraftEditorContents').simulate('focus');
|
|
||||||
const ed = wrapper.find('.public-DraftEditor-content');
|
|
||||||
ed.simulate('beforeInput', { data: '@b' });
|
|
||||||
jest.runAllTimers();
|
|
||||||
|
|
||||||
const items = wrapper.find('div.ant-mention-dropdown-item');
|
|
||||||
expect(items.length).toBe(1);
|
|
||||||
expect(items.at(0).props().children).toBe('bamboo');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check filteredSuggestions', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<Mention defaultSuggestions={[<Mention.Nav key="light" value="light" />]} />,
|
|
||||||
);
|
|
||||||
wrapper.find('DraftEditorContents').simulate('focus');
|
|
||||||
const ed = wrapper.find('.public-DraftEditor-content');
|
|
||||||
ed.simulate('beforeInput', { data: '@l' });
|
|
||||||
jest.runAllTimers();
|
|
||||||
const items = wrapper.find('div.ant-mention-dropdown-item');
|
|
||||||
expect(items.length).toBe(1);
|
|
||||||
expect(items.at(0).props().value).toBe('light');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,59 +0,0 @@
|
|||||||
---
|
|
||||||
order: 1
|
|
||||||
title:
|
|
||||||
zh-CN: 异步加载
|
|
||||||
en-US: Asynchronous loading
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
匹配内容列表为异步返回时。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
async
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
|
|
||||||
|
|
||||||
class AsyncMention extends React.Component {
|
|
||||||
state = {
|
|
||||||
suggestions: [],
|
|
||||||
loading: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchSuggestions = (value, callback) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
callback(users.filter(item => item.indexOf(value) !== -1));
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearchChange = value => {
|
|
||||||
this.fetchSuggestions(value, suggestions => {
|
|
||||||
this.setState({
|
|
||||||
suggestions,
|
|
||||||
loading: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.setState({
|
|
||||||
loading: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { suggestions, loading } = this.state;
|
|
||||||
return (
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
loading={loading}
|
|
||||||
suggestions={suggestions}
|
|
||||||
onSearchChange={this.onSearchChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<AsyncMention />, mountNode);
|
|
||||||
```
|
|
@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
order: 3
|
|
||||||
title:
|
|
||||||
zh-CN: 头像
|
|
||||||
en-US: Icon Image
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
自定义建议(含头像)
|
|
||||||
|
|
||||||
注意,自定义建议时,onSearchChange 必须不能为空。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Customize suggestions.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention, Avatar } from 'antd';
|
|
||||||
|
|
||||||
const { Nav } = Mention;
|
|
||||||
|
|
||||||
const webFrameworks = [
|
|
||||||
{
|
|
||||||
name: 'React',
|
|
||||||
type: 'JavaScript',
|
|
||||||
icon: 'https://zos.alipayobjects.com/rmsportal/LFIeMPzdLcLnEUe.svg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Angular',
|
|
||||||
type: 'JavaScript',
|
|
||||||
icon: 'https://zos.alipayobjects.com/rmsportal/PJTbxSvzYWjDZnJ.png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Dva',
|
|
||||||
type: 'Javascript',
|
|
||||||
icon: 'https://zos.alipayobjects.com/rmsportal/EYPwSeEJKxDtVxI.png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Flask',
|
|
||||||
type: 'Python',
|
|
||||||
icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
class CustomNavMention extends React.Component {
|
|
||||||
state = {
|
|
||||||
suggestions: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearchChange = value => {
|
|
||||||
const searchValue = value.toLowerCase();
|
|
||||||
const filtered = webFrameworks.filter(
|
|
||||||
item => item.name.toLowerCase().indexOf(searchValue) !== -1,
|
|
||||||
);
|
|
||||||
const suggestions = filtered.map(suggestion => (
|
|
||||||
<Nav
|
|
||||||
value={suggestion.name}
|
|
||||||
data={suggestion}
|
|
||||||
disabled={suggestion.disabled}
|
|
||||||
key="mention-avatar"
|
|
||||||
>
|
|
||||||
<Avatar
|
|
||||||
src={suggestion.icon}
|
|
||||||
size="small"
|
|
||||||
style={{
|
|
||||||
width: 14,
|
|
||||||
height: 14,
|
|
||||||
marginRight: 8,
|
|
||||||
top: -1,
|
|
||||||
position: 'relative',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{suggestion.name} - {suggestion.type}
|
|
||||||
</Nav>
|
|
||||||
));
|
|
||||||
this.setState({ suggestions });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { suggestions } = this.state;
|
|
||||||
return (
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
suggestions={suggestions}
|
|
||||||
onSearchChange={this.onSearchChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<CustomNavMention />, mountNode);
|
|
||||||
```
|
|
@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
order: 0
|
|
||||||
title:
|
|
||||||
zh-CN: 基本使用
|
|
||||||
en-US: Basic
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
基本使用
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Basic usage.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toString, toContentState } = Mention;
|
|
||||||
|
|
||||||
function onChange(contentState) {
|
|
||||||
console.log(toString(contentState));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelect(suggestion) {
|
|
||||||
console.log('onSelect', suggestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
defaultValue={toContentState('@afc163')}
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
onSelect={onSelect}
|
|
||||||
/>,
|
|
||||||
mountNode,
|
|
||||||
);
|
|
||||||
```
|
|
@ -1,49 +0,0 @@
|
|||||||
---
|
|
||||||
order: 3
|
|
||||||
title:
|
|
||||||
zh-CN: 受控模式
|
|
||||||
en-US: Controlled
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
受控模式.
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Controlled mode.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toContentState } = Mention;
|
|
||||||
|
|
||||||
class App extends React.Component {
|
|
||||||
state = {
|
|
||||||
value: toContentState('@afc163'),
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.mention.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChange = editorState => {
|
|
||||||
this.setState({
|
|
||||||
value: editorState,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Mention
|
|
||||||
ref={ele => (this.mention = ele)}
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
value={this.state.value}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, mountNode);
|
|
||||||
```
|
|
@ -1,75 +0,0 @@
|
|||||||
---
|
|
||||||
order: 4
|
|
||||||
title:
|
|
||||||
zh-CN: 配合 Form 使用
|
|
||||||
en-US: With Form
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
受控模式,例如配合 Form 使用。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Controlled mode, for example, to work with `Form`.
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
import { Mention, Form, Button } from 'antd';
|
|
||||||
|
|
||||||
const { toContentState, getMentions } = Mention;
|
|
||||||
const FormItem = Form.Item;
|
|
||||||
|
|
||||||
const App = () => {
|
|
||||||
const [form] = Form.useForm();
|
|
||||||
|
|
||||||
const checkMention = (rule, value, callback) => {
|
|
||||||
const mentions = getMentions(form.getFieldValue('mention'));
|
|
||||||
if (mentions.length < 2) {
|
|
||||||
callback(new Error('More than one must be selected!'));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReset = () => {
|
|
||||||
form.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFinish = values => {
|
|
||||||
console.log('Submit:', values);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form
|
|
||||||
form={form}
|
|
||||||
layout="horizontal"
|
|
||||||
initialValues={{ mention: toContentState('@afc163') }}
|
|
||||||
onFinish={onFinish}
|
|
||||||
>
|
|
||||||
<FormItem
|
|
||||||
name="mention"
|
|
||||||
id="control-mention"
|
|
||||||
label="Top coders"
|
|
||||||
labelCol={{ span: 6 }}
|
|
||||||
wrapperCol={{ span: 16 }}
|
|
||||||
rules={[{ validator: checkMention }]}
|
|
||||||
>
|
|
||||||
<Mention
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem wrapperCol={{ span: 14, offset: 6 }}>
|
|
||||||
<Button htmlType="submit" type="primary">
|
|
||||||
Submit
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button htmlType="button" onClick={onReset}>
|
|
||||||
Reset
|
|
||||||
</Button>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, mountNode);
|
|
||||||
```
|
|
@ -1,70 +0,0 @@
|
|||||||
---
|
|
||||||
order: 2
|
|
||||||
title:
|
|
||||||
zh-CN: 自定义建议
|
|
||||||
en-US: Customize Suggestion
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
自定义建议
|
|
||||||
|
|
||||||
注意,自定义建议时,onSearchChange 必须不能为空。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Customize suggestions.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { Nav } = Mention;
|
|
||||||
|
|
||||||
const webFrameworks = [
|
|
||||||
{ name: 'React', type: 'JavaScript' },
|
|
||||||
{ name: 'Angular', type: 'JavaScript' },
|
|
||||||
{ name: 'Laravel', type: 'PHP', disabled: true },
|
|
||||||
{ name: 'Flask', type: 'Python' },
|
|
||||||
{ name: 'Django', type: 'Python' },
|
|
||||||
];
|
|
||||||
|
|
||||||
function onSelect(suggestion, data) {
|
|
||||||
console.log('onSelect', suggestion, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomNavMention extends React.Component {
|
|
||||||
state = {
|
|
||||||
suggestions: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearchChange = value => {
|
|
||||||
const searchValue = value.toLowerCase();
|
|
||||||
const filtered = webFrameworks.filter(
|
|
||||||
item => item.name.toLowerCase().indexOf(searchValue) !== -1,
|
|
||||||
);
|
|
||||||
const suggestions = filtered.map(suggestion => (
|
|
||||||
<Nav value={suggestion.name} data={suggestion} key={suggestion.name}>
|
|
||||||
<span>
|
|
||||||
{suggestion.name} - {suggestion.type}
|
|
||||||
</span>
|
|
||||||
</Nav>
|
|
||||||
));
|
|
||||||
this.setState({ suggestions });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { suggestions } = this.state;
|
|
||||||
return (
|
|
||||||
<Mention
|
|
||||||
placeholder="@someone"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
suggestions={suggestions}
|
|
||||||
onSearchChange={this.onSearchChange}
|
|
||||||
onSelect={onSelect}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<CustomNavMention />, mountNode);
|
|
||||||
```
|
|
@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
order: 5
|
|
||||||
title:
|
|
||||||
zh-CN: 多行
|
|
||||||
en-US: Multi-lines Mode
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
多行模式,多行模式必须指定高度。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Multi lines mode.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toString } = Mention;
|
|
||||||
|
|
||||||
function onChange(editorState) {
|
|
||||||
console.log(toString(editorState));
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%', height: 100 }}
|
|
||||||
onChange={onChange}
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']}
|
|
||||||
multiLines
|
|
||||||
/>,
|
|
||||||
mountNode,
|
|
||||||
);
|
|
||||||
```
|
|
@ -1,64 +0,0 @@
|
|||||||
---
|
|
||||||
order: 8
|
|
||||||
title:
|
|
||||||
zh-CN: 自定义触发字符
|
|
||||||
en-US: Customize Trigger Token
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
通过 `prefix` 属性自定义触发字符。默认为 `@`, 可以定义为数组。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Customize Trigger Token by `prefix` props. Default to `@`, `Array<string>` also supported.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toString } = Mention;
|
|
||||||
|
|
||||||
function onChange(editorState) {
|
|
||||||
console.log(toString(editorState));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelect(suggestion) {
|
|
||||||
console.log('onSelect', suggestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
|
|
||||||
const tags = ['1.0', '2.0', '3.0'];
|
|
||||||
|
|
||||||
class App extends React.Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
suggestions: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearchChange = (value, trigger) => {
|
|
||||||
console.log('onSearchChange', value, trigger);
|
|
||||||
const dataSource = trigger === '@' ? users : tags;
|
|
||||||
this.setState({
|
|
||||||
suggestions: dataSource.filter(item => item.indexOf(value) !== -1),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
placeholder="input @ to mention people, # to mention tag"
|
|
||||||
prefix={['@', '#']}
|
|
||||||
onSearchChange={this.onSearchChange}
|
|
||||||
suggestions={this.state.suggestions}
|
|
||||||
onSelect={onSelect}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, mountNode);
|
|
||||||
```
|
|
@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
order: 0
|
|
||||||
title:
|
|
||||||
zh-CN: 向上展开
|
|
||||||
en-US: Placement
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
向上展开建议。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Change the suggestions placement.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toString } = Mention;
|
|
||||||
|
|
||||||
function onChange(contentState) {
|
|
||||||
console.log(toString(contentState));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelect(suggestion) {
|
|
||||||
console.log('onSelect', suggestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
onSelect={onSelect}
|
|
||||||
placement="top"
|
|
||||||
/>,
|
|
||||||
mountNode,
|
|
||||||
);
|
|
||||||
```
|
|
@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
order: 6
|
|
||||||
title:
|
|
||||||
zh-CN: 建议渲染父节点
|
|
||||||
en-US: SuggestionContainer
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
指定提示渲染的父节点。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
To set the container of the suggestion.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention, Popover, Button } from 'antd';
|
|
||||||
|
|
||||||
const { toString, toContentState } = Mention;
|
|
||||||
|
|
||||||
function onChange(editorState) {
|
|
||||||
console.log(toString(editorState));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelect(suggestion) {
|
|
||||||
console.log('onSelect', suggestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverContainer extends React.Component {
|
|
||||||
getSuggestionContainer = () => this.popover.getPopupDomNode();
|
|
||||||
|
|
||||||
visibleChange = visible => {
|
|
||||||
if (visible && this.mention) {
|
|
||||||
this.mention.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const mention = (
|
|
||||||
<Mention
|
|
||||||
ref={ele => (this.mention = ele)}
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
defaultValue={toContentState('@afc163')}
|
|
||||||
defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
|
|
||||||
onSelect={onSelect}
|
|
||||||
getSuggestionContainer={this.getSuggestionContainer}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
trigger="click"
|
|
||||||
content={mention}
|
|
||||||
title="Title"
|
|
||||||
ref={popover => (this.popover = popover)}
|
|
||||||
onVisibleChange={this.visibleChange}
|
|
||||||
>
|
|
||||||
<Button type="primary">Click Me</Button>
|
|
||||||
</Popover>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<PopoverContainer />, mountNode);
|
|
||||||
```
|
|
@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
order: 7
|
|
||||||
title:
|
|
||||||
zh-CN: 无效或只读
|
|
||||||
en-US: disabled or readOnly
|
|
||||||
---
|
|
||||||
|
|
||||||
## zh-CN
|
|
||||||
|
|
||||||
通过 `disabled` 属性设置是否生效。通过 `readOnly` 属性设置是否只读。
|
|
||||||
|
|
||||||
## en-US
|
|
||||||
|
|
||||||
Configurate `disabled` and `readOnly`.
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { Mention } from 'antd';
|
|
||||||
|
|
||||||
const { toString } = Mention;
|
|
||||||
|
|
||||||
function onChange(editorState) {
|
|
||||||
console.log(toString(editorState));
|
|
||||||
}
|
|
||||||
|
|
||||||
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div style={{ marginBottom: 10 }}>
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
placeholder="this is disabled Mention"
|
|
||||||
suggestions={users}
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Mention
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
onChange={onChange}
|
|
||||||
placeholder="this is readOnly Mention"
|
|
||||||
suggestions={users}
|
|
||||||
readOnly
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, mountNode);
|
|
||||||
```
|
|
@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
category: Components
|
|
||||||
type: Deprecated
|
|
||||||
title: Mention (Deprecated)
|
|
||||||
---
|
|
||||||
|
|
||||||
Mention component. Deprecated, please use [Mentions](/components/mentions) instead.
|
|
||||||
|
|
||||||
## Why deprecated?
|
|
||||||
|
|
||||||
<div class="ant-alert ant-alert-error ant-alert-no-icon">
|
|
||||||
Mention use
|
|
||||||
<a href="https://www.npmjs.com/package/draft-js" target="_blank" rel="noopener noreferrer">Draft.js</a>
|
|
||||||
to measure tips position, which use nearly 11.6% package size. We hope to reduce bundle size by using lightweight solution to handle this.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<Mention
|
|
||||||
onChange={onChange}
|
|
||||||
suggestions={['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mention API
|
|
||||||
|
|
||||||
| API | Description | Type | Version |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| getMentions | get mentioned people in current contentState | Function(ContentState: contentState): string\[] | |
|
|
||||||
| toContentState | convert string to ContentState | Function(value: string): ContentState | |
|
|
||||||
| toString | convert ContentState to string | Function(contentState: ContentState): string | |
|
|
||||||
|
|
||||||
### Mention
|
|
||||||
|
|
||||||
| Property | Description | Type | Default | Version |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| autoFocus | get focus when component mounted | boolean | false | |
|
|
||||||
| defaultValue | default value | ContentState, you can use `Mention.toContentState` to convert text to `ContentState` | null | |
|
|
||||||
| defaultSuggestions | default suggestion content | Array<string\|Mention.Nav> | \[] | 3.12.0 |
|
|
||||||
| disabled | Tell if the input is disabled. | boolean | false | |
|
|
||||||
| getSuggestionContainer | rendered to the root of the menu. Default rendered to the body dom. If gets any problem of the menu while scrolling. Try to make the root the dom scrolled, and make it position relative. | function | () => document.body | |
|
|
||||||
| loading | loading mode | boolean | false | |
|
|
||||||
| multiLines | multilines mode | boolean | false | |
|
|
||||||
| notFoundContent | suggestion when suggestions empty | string | 'No matches found' | |
|
|
||||||
| placeholder | placeholder of input | string | null | |
|
|
||||||
| placement | The position of the suggestion relative to the target, which can be one of `top` and `bottom` | string | 'bottom'. | |
|
|
||||||
| prefix | character which will trigger Mention to show mention list | string or Array<string> | '@' | |
|
|
||||||
| readOnly | Tell if the input is readonly. | boolean | false | |
|
|
||||||
| suggestions | suggestion content | Array<string\|Mention.Nav> | \[] | |
|
|
||||||
| suggestionStyle | style of suggestion container | object | {} | |
|
|
||||||
| value | core state of mention | ContentState | null | |
|
|
||||||
| onBlur | Callback function called when mention component blur | function(e) | null | |
|
|
||||||
| onChange | Callback function called when content of input changes | function(contentState: ContentState) | null | |
|
|
||||||
| onFocus | Callback function called when mention component get focus | function | null | |
|
|
||||||
| onSearchChange | Callback function called when search content changes | function(value:string, trigger: string) | \[] | |
|
|
||||||
| onSelect | Callback function called when select from suggestions | function(suggestion: string, data?: any) | null | |
|
|
||||||
|
|
||||||
### Mention methods
|
|
||||||
|
|
||||||
| Name | Description | Version |
|
|
||||||
| ------- | ------------ | ------- |
|
|
||||||
| blur() | remove focus | |
|
|
||||||
| focus() | get focus | |
|
|
||||||
|
|
||||||
### Nav
|
|
||||||
|
|
||||||
| Property | Description | Type | Default | Version |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| children | suggestion content | object | {} | |
|
|
||||||
| value | value of suggestion, the value will insert into input filed while selected | string | "" | |
|
|
@ -1,172 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import RcMention, { Nav, toString, toEditorState, getMentions } from 'rc-editor-mention';
|
|
||||||
import { polyfill } from 'react-lifecycles-compat';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { Loading } from '@ant-design/icons';
|
|
||||||
|
|
||||||
import warning from '../_util/warning';
|
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
|
||||||
|
|
||||||
export type MentionPlacement = 'top' | 'bottom';
|
|
||||||
|
|
||||||
type SuggestionItme = React.ReactElement<{ value?: string }> | string;
|
|
||||||
|
|
||||||
export interface MentionProps {
|
|
||||||
prefixCls?: string;
|
|
||||||
suggestionStyle?: React.CSSProperties;
|
|
||||||
defaultSuggestions?: Array<SuggestionItme>;
|
|
||||||
suggestions?: Array<React.ReactElement<any>>;
|
|
||||||
onSearchChange?: (value: string, trigger: string) => any;
|
|
||||||
onChange?: (contentState: any) => void;
|
|
||||||
notFoundContent?: any;
|
|
||||||
loading?: boolean;
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
defaultValue?: any;
|
|
||||||
value?: any;
|
|
||||||
className?: string;
|
|
||||||
multiLines?: boolean;
|
|
||||||
prefix?: string | string[];
|
|
||||||
placeholder?: string;
|
|
||||||
getSuggestionContainer?: (triggerNode: Element) => HTMLElement;
|
|
||||||
onFocus?: React.FocusEventHandler<HTMLElement>;
|
|
||||||
onBlur?: React.FocusEventHandler<HTMLElement>;
|
|
||||||
onSelect?: (suggestion: string, data?: any) => void;
|
|
||||||
readOnly?: boolean;
|
|
||||||
disabled?: boolean;
|
|
||||||
placement?: MentionPlacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MentionState {
|
|
||||||
filteredSuggestions?: Array<any>;
|
|
||||||
focus?: Boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Mention extends React.Component<MentionProps, MentionState> {
|
|
||||||
static getMentions = getMentions;
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
notFoundContent: 'No matches found',
|
|
||||||
loading: false,
|
|
||||||
multiLines: false,
|
|
||||||
placement: 'bottom' as MentionPlacement,
|
|
||||||
};
|
|
||||||
|
|
||||||
static Nav = Nav;
|
|
||||||
|
|
||||||
static toString = toString;
|
|
||||||
|
|
||||||
static toContentState = toEditorState;
|
|
||||||
|
|
||||||
private mentionEle: any;
|
|
||||||
|
|
||||||
constructor(props: MentionProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
filteredSuggestions: props.defaultSuggestions,
|
|
||||||
focus: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
warning(
|
|
||||||
false,
|
|
||||||
'Mention',
|
|
||||||
'Mention component is deprecated. Please use Mentions component instead.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
mentionRef = (ele: any) => {
|
|
||||||
this.mentionEle = ele;
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearchChange = (value: string, prefix: string) => {
|
|
||||||
if (this.props.onSearchChange) {
|
|
||||||
return this.props.onSearchChange(value, prefix);
|
|
||||||
}
|
|
||||||
return this.defaultSearchChange(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
onChange = (editorState: any) => {
|
|
||||||
if (this.props.onChange) {
|
|
||||||
this.props.onChange(editorState);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onFocus = (ev: React.FocusEvent<HTMLElement>) => {
|
|
||||||
this.setState({
|
|
||||||
focus: true,
|
|
||||||
});
|
|
||||||
if (this.props.onFocus) {
|
|
||||||
this.props.onFocus(ev);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onBlur = (ev: React.FocusEvent<HTMLElement>) => {
|
|
||||||
this.setState({
|
|
||||||
focus: false,
|
|
||||||
});
|
|
||||||
if (this.props.onBlur) {
|
|
||||||
this.props.onBlur(ev);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
focus = () => {
|
|
||||||
this.mentionEle._editor.focusEditor();
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultSearchChange(value: string): void {
|
|
||||||
const searchValue = value.toLowerCase();
|
|
||||||
const filteredSuggestions = (this.props.defaultSuggestions || []).filter(suggestion => {
|
|
||||||
if (typeof suggestion === 'string') {
|
|
||||||
return suggestion.toLowerCase().indexOf(searchValue) !== -1;
|
|
||||||
}
|
|
||||||
if (suggestion.type && suggestion.type === Nav) {
|
|
||||||
return suggestion.props.value
|
|
||||||
? suggestion.props.value.toLowerCase().indexOf(searchValue) !== -1
|
|
||||||
: true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
this.setState({
|
|
||||||
filteredSuggestions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderMention = ({ getPrefixCls }: ConfigConsumerProps) => {
|
|
||||||
const {
|
|
||||||
prefixCls: customizePrefixCls,
|
|
||||||
className = '',
|
|
||||||
loading,
|
|
||||||
placement,
|
|
||||||
suggestions,
|
|
||||||
} = this.props;
|
|
||||||
const { filteredSuggestions, focus } = this.state;
|
|
||||||
const prefixCls = getPrefixCls('mention', customizePrefixCls);
|
|
||||||
const cls = classNames(className, {
|
|
||||||
[`${prefixCls}-active`]: focus,
|
|
||||||
[`${prefixCls}-placement-top`]: placement === 'top',
|
|
||||||
});
|
|
||||||
const notFoundContent = loading ? <Loading /> : this.props.notFoundContent;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RcMention
|
|
||||||
{...this.props}
|
|
||||||
prefixCls={prefixCls}
|
|
||||||
className={cls}
|
|
||||||
ref={this.mentionRef}
|
|
||||||
onSearchChange={this.onSearchChange}
|
|
||||||
onChange={this.onChange}
|
|
||||||
onFocus={this.onFocus}
|
|
||||||
onBlur={this.onBlur}
|
|
||||||
suggestions={suggestions || filteredSuggestions}
|
|
||||||
notFoundContent={notFoundContent}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <ConfigConsumer>{this.renderMention}</ConfigConsumer>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
polyfill(Mention);
|
|
||||||
|
|
||||||
export default Mention;
|
|
@ -1,72 +0,0 @@
|
|||||||
---
|
|
||||||
category: Components
|
|
||||||
type: 废弃
|
|
||||||
subtitle: 提及(废弃)
|
|
||||||
title: Mention
|
|
||||||
---
|
|
||||||
|
|
||||||
提及组件。已废弃,请使用 [Mentions](/components/mentions) 代替。
|
|
||||||
|
|
||||||
## 为何废弃?
|
|
||||||
|
|
||||||
<div class="ant-alert ant-alert-error ant-alert-no-icon">
|
|
||||||
Mention 组件使用了
|
|
||||||
<a href="https://www.npmjs.com/package/draft-js" target="_blank" rel="noopener noreferrer">Draft.js</a>
|
|
||||||
进行提示定位,占用了约 11.6% 的包大小。因而我们决定使用更轻量级的解决方案以便于在未来降低整个包的大小。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<Mention
|
|
||||||
onChange={onChange}
|
|
||||||
suggestions={['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mention API
|
|
||||||
|
|
||||||
| API | 说明 | 类型 | 版本 |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| getMentions | 获取当前 contentState 中提到的人的列表 | Function(contentState: ContentState): string\[] | |
|
|
||||||
| toContentState | 把字符串转成 ContentState | Function(value: string): ContentState | |
|
|
||||||
| toString | 把 ContentState 转成字符串 | Function(contentState: ContentState): string | |
|
|
||||||
|
|
||||||
### Mention
|
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| autoFocus | 自动获取焦点 | boolean | false | |
|
|
||||||
| defaultValue | 默认值 | ContentState, 可以用 `Mention.toContentState(text)` 把文字转换成 ContentState | null | |
|
|
||||||
| defaultSuggestions | 默认建议内容 | Array<string\|Mention.Nav> | \[] | 3.12.0 |
|
|
||||||
| disabled | 是否禁用状态. | boolean | false | |
|
|
||||||
| getSuggestionContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位 | function() | () => document.body | |
|
|
||||||
| loading | 加载中 | boolean | false | |
|
|
||||||
| multiLines | 多行模式 | boolean | false | |
|
|
||||||
| notFoundContent | 未找到时的内容 | string | '无匹配结果,轻敲空格完成输入' | |
|
|
||||||
| placeholder | 输入框默认文字 | string | null | |
|
|
||||||
| placement | 建议框位置,可选 `top` `bottom` | string | 'bottom' | |
|
|
||||||
| prefix | 触发弹出下拉框的字符 | string or Array<string> | '@' | |
|
|
||||||
| readOnly | 是否只读. | boolean | false | |
|
|
||||||
| suggestions | 建议内容 | Array<string\|Mention.Nav> | \[] | |
|
|
||||||
| suggestionStyle | 弹出下拉框样式 | object | {} | |
|
|
||||||
| value | 值 | ContentState | null | |
|
|
||||||
| onBlur | 失去焦点时回调 | function(e) | null | |
|
|
||||||
| onChange | 输入框内容变化时回调 | function(contentState: ContentState) | null | |
|
|
||||||
| onFocus | 获得焦点时回调 | function(e) | null | |
|
|
||||||
| onSearchChange | 输入框中 @ 变化时回调 | function(value:string, trigger: string) | \[] | |
|
|
||||||
| onSelect | 下拉框选择建议时回调 | function(suggestion: string, data?: any) | null | |
|
|
||||||
|
|
||||||
### Mention 方法
|
|
||||||
|
|
||||||
| 名称 | 描述 | 版本 |
|
|
||||||
| ------- | -------- | ---- |
|
|
||||||
| blur() | 移除焦点 | |
|
|
||||||
| focus() | 获取焦点 | |
|
|
||||||
|
|
||||||
### Nav
|
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
|
||||||
| -------- | ---------------------------------------- | ------ | ------ | ---- |
|
|
||||||
| children | 建议内容 | object | {} | |
|
|
||||||
| value | 建议值,选择建议时,用此值插入到输入框中 | string | "" | |
|
|
@ -1,133 +0,0 @@
|
|||||||
@import '../../style/themes/index';
|
|
||||||
@import '../../style/mixins/index';
|
|
||||||
@import '../../input/style/mixin';
|
|
||||||
|
|
||||||
@mention-prefix-cls: ~'@{ant-prefix}-mention';
|
|
||||||
|
|
||||||
.@{mention-prefix-cls}-wrapper {
|
|
||||||
.reset-component;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
.@{mention-prefix-cls}-editor {
|
|
||||||
.input;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
height: auto; // To override height in .input mixin
|
|
||||||
min-height: @input-height-base;
|
|
||||||
padding: 0;
|
|
||||||
line-height: @line-height-base;
|
|
||||||
&-wrapper {
|
|
||||||
height: auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.@{mention-prefix-cls}-active:not(.disabled) .@{mention-prefix-cls}-editor {
|
|
||||||
.active;
|
|
||||||
}
|
|
||||||
&.disabled .@{mention-prefix-cls}-editor {
|
|
||||||
.disabled();
|
|
||||||
}
|
|
||||||
.public-DraftEditorPlaceholder-root {
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
.public-DraftEditorPlaceholder-inner {
|
|
||||||
height: auto;
|
|
||||||
padding: 5px @control-padding-horizontal - 1px;
|
|
||||||
color: @input-placeholder-color;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
outline: none;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.DraftEditor-editorContainer .public-DraftEditor-content {
|
|
||||||
height: auto;
|
|
||||||
padding: 5px @control-padding-horizontal - 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{mention-prefix-cls}-dropdown {
|
|
||||||
.reset-component;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: -9999px;
|
|
||||||
left: -9999px;
|
|
||||||
z-index: @zindex-dropdown;
|
|
||||||
min-width: 120px;
|
|
||||||
max-height: 250px;
|
|
||||||
margin-top: 1.5em;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
background-color: @component-background;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: @box-shadow-base;
|
|
||||||
|
|
||||||
&-placement-top {
|
|
||||||
margin-top: -0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-notfound&-item {
|
|
||||||
color: @disabled-color;
|
|
||||||
|
|
||||||
.@{iconfont-css-prefix}-loading {
|
|
||||||
display: block;
|
|
||||||
color: @primary-color;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&-item {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
padding: 5px @control-padding-horizontal;
|
|
||||||
overflow: hidden;
|
|
||||||
color: @text-color;
|
|
||||||
font-weight: normal;
|
|
||||||
line-height: 22px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: @item-hover-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.focus,
|
|
||||||
&-active {
|
|
||||||
background-color: @item-active-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-disabled {
|
|
||||||
color: @disabled-color;
|
|
||||||
cursor: not-allowed;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: @disabled-color;
|
|
||||||
background-color: @component-background;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-selected {
|
|
||||||
&,
|
|
||||||
&:hover {
|
|
||||||
color: @text-color;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: @background-color-base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-divider {
|
|
||||||
height: 1px;
|
|
||||||
margin: 1px 0;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 0;
|
|
||||||
background-color: @border-color-split;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
import './index.less';
|
|
@ -6,8 +6,6 @@ title: Mentions
|
|||||||
|
|
||||||
Mention component.
|
Mention component.
|
||||||
|
|
||||||
> Mention component is deprecated. Please click [here](/components/mention) to view old document.
|
|
||||||
|
|
||||||
## When To Use
|
## When To Use
|
||||||
|
|
||||||
When need to mention someone or something.
|
When need to mention someone or something.
|
||||||
|
@ -7,8 +7,6 @@ title: Mentions
|
|||||||
|
|
||||||
提及组件。
|
提及组件。
|
||||||
|
|
||||||
> 原 Mention 组件已废弃,原文档请点击[这里](/components/mention)。
|
|
||||||
|
|
||||||
## 何时使用
|
## 何时使用
|
||||||
|
|
||||||
用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
|
用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
|
||||||
|
@ -114,7 +114,6 @@
|
|||||||
"rc-dialog": "~7.5.2",
|
"rc-dialog": "~7.5.2",
|
||||||
"rc-drawer": "~3.0.0",
|
"rc-drawer": "~3.0.0",
|
||||||
"rc-dropdown": "~3.0.0-alpha.0",
|
"rc-dropdown": "~3.0.0-alpha.0",
|
||||||
"rc-editor-mention": "^1.1.13",
|
|
||||||
"rc-field-form": "^0.0.0-alpha.17",
|
"rc-field-form": "^0.0.0-alpha.17",
|
||||||
"rc-input-number": "~4.5.0",
|
"rc-input-number": "~4.5.0",
|
||||||
"rc-mentions": "~0.4.0",
|
"rc-mentions": "~0.4.0",
|
||||||
|
@ -31,7 +31,6 @@ Array [
|
|||||||
"InputNumber",
|
"InputNumber",
|
||||||
"Layout",
|
"Layout",
|
||||||
"List",
|
"List",
|
||||||
"LocaleProvider",
|
|
||||||
"message",
|
"message",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Mentions",
|
"Mentions",
|
||||||
@ -63,7 +62,6 @@ Array [
|
|||||||
"Timeline",
|
"Timeline",
|
||||||
"Tooltip",
|
"Tooltip",
|
||||||
"Typography",
|
"Typography",
|
||||||
"Mention",
|
|
||||||
"Upload",
|
"Upload",
|
||||||
"version",
|
"version",
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user