Search code examples
reactjsdraftjs

How to create custom key bindings in draft.js?


I press CTRL+B => I want selected text bolded.


Useful links:


Solution

  • We need to pass two props to our <Editor/>:
    keyBindingFn: maps CTRL + some key to some action sting
    handleKeyCommand: gets passed this action string and decides what to do with it.

    import React from 'react';
    
    import {
      Editor, EditorState,
      RichUtils, getDefaultKeyBinding
    } from 'draft-js';
    
    
    class Problem extends React.Component {
      constructor(props) {
        super(props);
        this.state = { editorState: EditorState.createEmpty() };
      }
    
      // this function maps keys we press to strings that represent some action (eg 'undo', or 'underline')
      // then the this.handleKeyCommand('underline') function gets called with this string.
      keyBindingFn = (event) => {
        // we press CTRL + K => return 'bbbold'
        // we use hasCommandModifier instead of checking for CTRL keyCode because different OSs have different command keys
        if (KeyBindingUtil.hasCommandModifier(event) && event.keyCode === 75) { return 'bbbold'; }
        // manages usual things, like:
        // Ctrl+Z => return 'undo'
        return getDefaultKeyBinding(event);
      }
    
      // command: string returned from this.keyBidingFn(event)
      // if this function returns 'handled' string, all ends here.
      // if it return 'not-handled', handling of :command will be delegated to Editor's default handling.
      handleKeyCommand = (command) => {
        let newState;
        if (command === 'bbbold') {
          newState = RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD');
        }
    
        if (newState) {
          this.setState({ editorState: newState });
          return 'handled';
        }
        return 'not-handled';
      }
    
      render = () =>
        <Editor
          editorState={this.state.editorState}
          onChange={(newState) => this.setState({ editorState: newState })}
          handleKeyCommand={this.handleKeyCommand}
          keyBindingFn={this.keyBindingFn}
        />
    }
    

    If you want something other than inline bold text (RichUtils.toggleInlineStyle), you can use RichUtils.toggleBlockType, RichUtils.toggleCode, etc.