ant-design/components/mention/index.tsx

129 lines
3.1 KiB
TypeScript
Raw Normal View History

2016-09-21 11:54:53 +08:00
import React from 'react';
import RcMention, { Nav, toString, toEditorState, getMentions } from 'rc-editor-mention';
import classNames from 'classnames';
import shallowequal from 'shallowequal';
2016-11-14 13:20:00 +08:00
import Icon from '../icon';
2016-07-04 10:31:27 +08:00
export interface MentionProps {
prefixCls: string;
suggestionStyle?: React.CSSProperties;
2016-07-04 10:31:27 +08:00
suggestions?: Array<any>;
onSearchChange?: Function;
onChange?: Function;
notFoundContent?: any;
loading?: Boolean;
style?: React.CSSProperties;
defaultValue?: any;
value?: any;
2016-07-18 17:58:55 +08:00
className?: string;
2016-07-04 10:31:27 +08:00
multiLines?: Boolean;
prefix?: string;
placeholder?: string;
getSuggestionContainer?: (triggerNode: Element) => HTMLElement;
onFocus?: Function;
onBlur?: Function;
readOnly?: boolean;
disabled?: boolean;
2016-07-04 10:31:27 +08:00
}
export interface MentionState {
suggestions?: Array<any>;
focus?: Boolean;
}
export default class Mention extends React.Component<MentionProps, MentionState> {
static getMentions = getMentions;
2016-07-04 10:31:27 +08:00
static defaultProps = {
prefixCls: 'ant-mention',
notFoundContent: '无匹配结果,轻敲空格完成输入',
loading: false,
multiLines: false,
};
static Nav = Nav;
static toString = toString;
static toContentState = toEditorState;
static toEditorState = text => {
console.warn('Mention.toEditorState is deprecated. Use toContentState instead.');
return toEditorState(text);
}
2016-07-04 10:31:27 +08:00
constructor(props) {
super(props);
this.state = {
suggestions: props.suggestions,
focus: false,
};
}
componentWillReceiveProps({ suggestions }) {
if (!shallowequal(suggestions, this.props.suggestions)) {
this.setState({
suggestions,
});
}
2016-07-04 10:31:27 +08:00
}
onSearchChange = (value, prefix) => {
2016-07-04 10:31:27 +08:00
if (this.props.onSearchChange) {
return this.props.onSearchChange(value, prefix);
2016-07-04 10:31:27 +08:00
}
return this.defaultSearchChange(value);
}
2016-11-14 12:21:58 +08:00
onChange = (editorState) => {
2016-07-04 10:31:27 +08:00
if (this.props.onChange) {
2016-07-19 12:31:03 +08:00
this.props.onChange(editorState);
2016-07-04 10:31:27 +08:00
}
}
2016-07-18 17:58:55 +08:00
2016-07-04 10:31:27 +08:00
defaultSearchChange(value: String): void {
const searchValue = value.toLowerCase();
2016-10-24 12:04:26 +08:00
const filteredSuggestions = (this.props.suggestions || []).filter(
suggestion => suggestion.toLowerCase().indexOf(searchValue) !== -1,
2016-07-04 10:31:27 +08:00
);
this.setState({
suggestions: filteredSuggestions,
});
}
onFocus = (ev) => {
this.setState({
focus: true,
});
if (this.props.onFocus) {
this.props.onFocus(ev);
}
}
onBlur = (ev) => {
this.setState({
focus: false,
});
if (this.props.onBlur) {
this.props.onBlur(ev);
}
}
2016-07-04 10:31:27 +08:00
render() {
2016-11-14 12:21:58 +08:00
const { className = '', prefixCls, loading } = this.props;
2016-07-04 10:31:27 +08:00
const { suggestions, focus } = this.state;
const cls = classNames(className, {
2016-11-14 12:21:58 +08:00
[`${prefixCls}-active`]: focus,
2016-07-04 10:31:27 +08:00
});
2016-11-14 12:21:58 +08:00
const notFoundContent = loading
? <Icon type="loading" />
: this.props.notFoundContent;
2016-07-18 17:58:55 +08:00
2016-11-14 12:21:58 +08:00
return (
<RcMention
2016-07-04 10:31:27 +08:00
{...this.props}
className={cls}
2016-11-14 12:21:58 +08:00
onSearchChange={this.onSearchChange}
onChange={this.onChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
2016-07-18 17:58:55 +08:00
suggestions={suggestions}
2016-07-04 10:31:27 +08:00
notFoundContent={notFoundContent}
2016-11-14 12:21:58 +08:00
/>
);
2016-07-04 10:31:27 +08:00
}
}