UNPKG

draft-js-single-line-plugin

Version:

Restrict a draft-js editor to a single line of input.

104 lines (88 loc) 3.32 kB
import { Map } from 'immutable'; import { ContentBlock, ContentState, EditorState, genKey } from 'draft-js'; import { NEWLINE_REGEX, replaceNewlines, condenseBlocks, stripEntityFromCharacterMetadata, characterListhasEntities } from './utils'; /** * Default options * @type {Object} */ var defaultOptions = { stripEntities: true /** * Single Line Plugin * @param {Object} options Per-instance options to override the defaults * @return {Object} Compatible draft-js-editor-plugin object */ };function singleLinePlugin() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; options = Object.assign({}, defaultOptions, options); return { /** * Return a compatible blockRenderMap * * NOTE: Needs to be explicitly applied, the plugin system doesn’t do * anything with this at the moment. * * @type {ImmutableMap} */ blockRenderMap: Map({ 'unstyled': { element: 'div' } }), /** * onChange * * Condense multiple blocks into a single block and (optionally) strip all * entities from the content of that block. * * @param {EditorState} editorState The current state of the editor * @return {EditorState} A new editor state */ onChange: function onChange(editorState) { var blocks = editorState.getCurrentContent().getBlocksAsArray(); // If we have more than one block, compress them if (blocks.length > 1) { editorState = condenseBlocks(editorState, blocks, options); } else { // We only have one content block var contentBlock = blocks[0]; var text = contentBlock.getText(); var characterList = contentBlock.getCharacterList(); var hasEntitiesToStrip = options.stripEntities && characterListhasEntities(characterList); if (NEWLINE_REGEX.test(text) || hasEntitiesToStrip) { // Replace the text stripped of its newlines. Note that we replace // one '\n' with one ' ' so we don't need to modify the characterList text = replaceNewlines(text); // Strip entities? if (options.stripEntities) { characterList = characterList.map(stripEntityFromCharacterMetadata); } // Create a new content block based on the old one contentBlock = new ContentBlock({ key: genKey(), text: text, type: 'unstyled', characterList: characterList, depth: 0 }); // Update the editor state with the compressed version // const selection = editorState.getSelection() var newContentState = ContentState.createFromBlockArray([contentBlock]); // Create the new state as an undoable action editorState = EditorState.push(editorState, newContentState, 'insert-characters'); } } return editorState; }, /** * Stop new lines being inserted by always handling the return * * @param {KeyboardEvent} e Synthetic keyboard event from draftjs * @return {String} Did we handle the return or not? (pro-trip: yes, we did) */ handleReturn: function handleReturn(e) { return 'handled'; } }; } export default singleLinePlugin;