2.Draftjs 学习笔记-Rich Styling

前提概要

draftjs的编辑器和input的区别就是,draft的值与状态是通过editorstate管理的,对比文档参考这里,editorstate的API 参考这里

正文

本章节主要是文本的简单样式控制,分别通过快捷键和按钮来实现

1. RichUtils and Key Commands(快捷键)

RichUtils has information about the core key commands available to web editors, such as Cmd+B (bold), Cmd+I (italic), and so on.

RichUtils 包含了快捷键映射的功能

继续修改components/MyEditor.js

import React from 'react';
import { Editor, EditorState, RichUtils } from 'draft-js';

class MyEditor extends React.Component {
     
  constructor(props) {
    super(props);
    this.state = { editorState: EditorState.createEmpty() };
    this.onChange = (editorState) => this.setState({ editorState });
    this.handleKeyCommand = this.handleKeyCommand.bind(this);
  }

  handleKeyCommand(command) {
    const newState = RichUtils.handleKeyCommand(this.state.editorState, command);
    if (newState) {
      this.onChange(newState);
      return 'handled';
    }
    return 'not-handled';
  }

  render() {
    const {editorState} = this.state;
    return (
      this.handleKeyCommand}
        onChange={
    this.onChange} />
    );
  }
}

MyEditor.propTypes = {
};

export default MyEditor;

可以在浏览器查看效果,输入一些文字,选中文字使用ctrl+b,和ctrl+i查看效果。
为何返回值是handled和not-handled?更多文档查看如下:
handleKeyCommand
The command argument supplied to handleKeyCommand is a string value, the name of the command to be executed. This is mapped from a DOM key event. See Advanced Topics - Key Binding for more on this, as well as details on why the function returns handled or not-handled.

2. Styling Controls in UI (通过按钮控制样式)

Here’s a super-basic example with a “Bold” button to toggle the BOLD style.
一个通过按钮来实现加粗的例子:
添加如下代码:

class MyEditor extends React.Component {
     
  // …

  _onBoldClick() {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
  }

  render() {
    return (
      <div>
        
        this.state.editorState}
          handleKeyCommand={
    this.handleKeyCommand}
          onChange={
    this.onChange}
        />
      div>
    );
  }
}

3.添加多种样式按钮操作
修改components/MyEditor.jsx

import React from 'react';
import { Editor, EditorState, RichUtils } from 'draft-js';
import Immutable from 'immutable';
import "draft-js/dist/Draft.css";
import styles from './Rich.less'

class MyEditor extends React.Component {
     
    constructor(props) {
        super(props);
        this.state = { editorState: EditorState.createEmpty() };

        this.focus = () => this.refs.editor.focus();
        this.onChange = (editorState) => this.setState({ editorState });
        this.handleKeyCommand = (command) => this._handleKeyCommand(command);
        this.onTab = (e) => this._onTab(e);
        this.toggleBlockType = (type) => this._toggleBlockType(type);
        this.toggleInlineStyle = (style) => this._toggleInlineStyle(style);
    }

    _handleKeyCommand(command) {
        const {editorState} = this.state;
        const newState = RichUtils.handleKeyCommand(editorState, command);
        if (newState) {
            this.onChange(newState);
            return true;
        }
        return false;
    }

    _onTab(e) {
        const maxDepth = 4;
        this.onChange(RichUtils.onTab(e, this.state.editorState, maxDepth));
    }

    _toggleBlockType(blockType) {
        this.onChange(
            RichUtils.toggleBlockType(
                this.state.editorState,
                blockType
            )
        );
    }

    _toggleInlineStyle(inlineStyle) {
        this.onChange(
            RichUtils.toggleInlineStyle(
                this.state.editorState,
                inlineStyle
            )
        );
    }

    render() {
        const {editorState} = this.state;

        // If the user changes block type before entering any text, we can
        // either style the placeholder or hide it. Let's just hide it now.
        let className = styles['RichEditor-editor'];
        var contentState = editorState.getCurrentContent();
        if (!contentState.hasText()) {
            if (contentState.getBlockMap().first().getType() !== 'unstyled') {
                className += ' ' + styles['RichEditor-hidePlaceholder'];
            }
        }

        return (
            
"RichEditor-root"]}> this.toggleBlockType} /> this.toggleInlineStyle} />
this.focus}> this.handleKeyCommand} onChange={ this.onChange} onTab={ this.onTab} placeholder="Tell a story..." onFocus={()=>{console.log('focus')}} ref='editor' spellCheck={ true} />
); } } const styleMap = { CODE: { backgroundColor: 'rgba(0, 0, 0, 0.05)', fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', fontSize: 16, padding: 2, }, }; function getBlockStyle(block) { switch (block.getType()) { case 'blockquote': return styles['RichEditor-blockquote']; default: return null; } } class StyleButton extends React.Component { constructor() { super(); this.onToggle = (e) => { e.preventDefault(); this.props.onToggle(this.props.style); }; } render() { let className = styles['RichEditor-styleButton']; if (this.props.active) { className += ' ' + styles['RichEditor-activeButton']; } return ( this.onToggle}> { this.props.label} ); } } const BLOCK_TYPES = [ { label: 'H1', style: 'header-one' }, { label: 'H2', style: 'header-two' }, { label: 'H3', style: 'header-three' }, { label: 'H4', style: 'header-four' }, { label: 'H5', style: 'header-five' }, { label: 'H6', style: 'header-six' }, { label: 'Blockquote', style: 'blockquote' }, { label: 'UL', style: 'unordered-list-item' }, { label: 'OL', style: 'ordered-list-item' }, { label: 'Code Block', style: 'code-block' }, ]; const BlockStyleControls = (props) => { const {editorState} = props; const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() .getBlockForKey(selection.getStartKey()) .getType(); return (
"RichEditor-controls"]}> {BLOCK_TYPES.map((type) => type.label} active={ type.style === blockType} label={ type.label} onToggle={props.onToggle} style={ type.style} /> )}
); }; var INLINE_STYLES = [ { label: 'Bold', style: 'BOLD' }, { label: 'Italic', style: 'ITALIC' }, { label: 'Underline', style: 'UNDERLINE' }, { label: 'Monospace', style: 'CODE' }, ]; const InlineStyleControls = (props) => { var currentStyle = props.editorState.getCurrentInlineStyle(); return (
"RichEditor-controls"]}> {INLINE_STYLES.map(type => type.label} active={currentStyle.has(type.style)} label={ type.label} onToggle={props.onToggle} style={ type.style} /> )}
); }; MyEditor.propTypes = { }; export default MyEditor;

样式文件 component/Rich.less

.RichEditor-root {
  background: #fff;
  border: 1px solid #ddd;
  font-family: 'Georgia', serif;
  font-size: 14px;
  padding: 15px;
}

.RichEditor-editor {
  border-top: 1px solid #ddd;
  cursor: text;
  font-size: 16px;
  margin-top: 10px;
}

.RichEditor-editor .public-DraftEditorPlaceholder-root,
.RichEditor-editor .public-DraftEditor-content {
  margin: 0 -15px -15px;
  padding: 15px;
}

.RichEditor-editor .public-DraftEditor-content {
  min-height: 100px;
}

.RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
  display: none;
}

.RichEditor-editor .RichEditor-blockquote {
  border-left: 5px solid #eee;
  color: #666;
  font-family: 'Hoefler Text', 'Georgia', serif;
  font-style: italic;
  margin: 16px 0;
  padding: 10px 20px;
}

.RichEditor-editor .public-DraftStyleDefault-pre {
  background-color: rgba(0, 0, 0, 0.05);
  font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
  font-size: 16px;
  padding: 20px;
}

.RichEditor-controls {
  font-family: 'Helvetica', sans-serif;
  font-size: 14px;
  margin-bottom: 5px;
  user-select: none;
}

.RichEditor-styleButton {
  color: #999;
  cursor: pointer;
  margin-right: 16px;
  padding: 2px 0;
  display: inline-block;
}

.RichEditor-activeButton {
  color: #5890ff;
}

你可能感兴趣的:(draftjs,编辑器,富文本,react,draftjs)