@功能
會(huì)話是群組時(shí),輸入框提供@功能荆永,用戶是當(dāng)前群的群主時(shí),suggestionsList包含
@全體成員
;@組件使用Draft plugins提供的mention plugin
主要code:
import Editor from 'draft-js-plugins-editor';
import createMentionPlugin, {defaultSuggestionsFilter} from 'draft-js-mention-plugin';
import createLinkifyPlugin from 'draft-js-linkify-plugin';
import 'draft-js-mention-plugin/lib/plugin.css';
import 'draft-js-linkify-plugin/lib/plugin.css';
import MentionEntry from './Mention';
// 自定義mention彈出的位置
const positionSuggestions = ({decoratorRect, state, props}) => {
const editorWrapper = document.getElementsByClassName('chat-draft-editor')[0];
const wrapperRect = editorWrapper.getBoundingClientRect();
let left = decoratorRect.left - wrapperRect.left;
const newDecoratorRight = decoratorRect.left + 170;
if (newDecoratorRight >= wrapperRect.right) {
left = left - (newDecoratorRight - wrapperRect.right) - 10;
}
const bottom = wrapperRect.height + 25 - (decoratorRect.bottom - wrapperRect.top);
console.log('editor', decoratorRect);
let transform;
let transition;
if (state.isActive & props.suggestions.size > 0) {
transform = 'scale(1)';
transition = 'all 0.25s cubic-bezier(.3,1.2,.2,1)';
} else if (state.isActive) {
transform = 'scale(0)';
transition = 'all 0.35s cubic-bezier(.3,1,.2,1)';
}
return {
position: 'absolute',
left: `${left}px`,
bottom: `${bottom}px`,
minWidth: '170px',
maxHeight: '230px',
overflowY: 'scroll',
border: '1px solid #E6E6E6',
borderRadius: '6px',
transform,
transformOrigin: '1em 0%',
transition,
};
};
const defaultSuggestions = [];
export default class ChatDraftEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
suggestions: [],
};
this.mentionPlugin = createMentionPlugin({
defaultSuggestions,
entityMutability: 'IMMUTABLE',
positionSuggestions,
mentionPrefix: '@',
});
}
}
onSearchChange = ({value}) => {
const userList = this.props.userList;
const filterSuggestions = value === ''? userList : defaultSuggestionsFilter(value, userList);
this.setState({
suggestions: filterSuggestions,
});
};
render() {
const {MentionSuggestions} = this.mentionPlugin;
const plugins = [this.mentionPlugin];
return (
<div
className="chat-draft-editor"
onClick={()=> {
this.focus(0);
}}
>
<Editor
ref={(e) => {
this.editor = e;
}}
plugins={plugins}
decorators={draftDecorator}
editorState={this.state.editorState}
onChange={this.onChange.bind(this)}
onBlur={this.handleBlur.bind(this)}
blockRendererFn={this.blockRendererFn.bind(this)}
handleKeyCommand={this.handleKeyCommand.bind(this)}
keyBindingFn={this.keyBindingFn}
/>
<MentionSuggestions
onSearchChange={this.onSearchChange.bind(this)}
suggestions={this.state.suggestions}
entryComponent={MentionEntry}
// onOpen={this.handleMentionOpen.bind(this)}
// onClose={this.handleMentionClose.bind(this)}
/>
</div>
);
}
<MetionSuggestions />
是@列表組件柏锄,其屬性suggestions
為數(shù)組對(duì)象消请,格式可以自定義..如果格式自定義了的話,最好同時(shí)修改entryComponent
-
entryComponent
用來(lái)傳入自定義的mention列表中item的組件樣式森渐,意味著可以根據(jù)你的mention對(duì)象格式定制組件樣式:import React from 'react'; import Avatar from '../common/Avatar'; const MentionEntry = (props) => { const { mention, ...parentProps } = props; const isAll = mention.get('uid') == 'upcgroupatall' ? true: false; const avatarType = mention.get('gender') == '2'? 'women': 'men'; const suggestionEntry = isAll? ( <div className="mention-all">{mention.get('name')}</div> ): ( <div className="mention-entry"> <Avatar icon={mention.get('avatar')} shape="square" size="min" type={avatarType} /> <div className="mention-text">{mention.get('name')}</div> </div> ); return ( <div {...parentProps}> <div className="mention-suggestion" > {suggestionEntry} </div> </div> ); }; module.exports = MentionEntry;
-
onSearchChange
綁定@時(shí)的關(guān)鍵字filter方法:onSearchChange = ({value}) => { const userList = this.props.userList; const filterSuggestions = value === ''? userList : defaultSuggestionsFilter(value, userList); this.setState({ suggestions: filterSuggestions, }); };
這里原本按照官網(wǎng)demo寫(xiě)做入,會(huì)導(dǎo)致一個(gè)bug,即第一次觸發(fā)@同衣,value為''時(shí)竟块,filter方法并未返回整個(gè)list。因此添加判斷如上耐齐。
mention插件目前仍有些未解決的影響體驗(yàn)的問(wèn)題:會(huì)影響輸入框up/down arrow事件的正常處理浪秘;mention選擇時(shí),滾輪不會(huì)隨著up/down arrow滾動(dòng)