Created
May 11, 2018 00:48
-
-
Save MattSegal/b7e736981bf306517c3d94b39b96a025 to your computer and use it in GitHub Desktop.
Draftail atomic block state change
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component } from 'react'; | |
const { AtomicBlockUtils, EditorState, SelectionState, Modifier } = window.DraftJS | |
// The source gathers data for new entities that are being added in the Draftail editor | |
// It is invoked only when an new embed is inserted by the user | |
export class TextSource extends Component { | |
componentDidMount() { | |
const { editorState, entityType, onComplete } = this.props; | |
const content = editorState.getCurrentContent(); | |
const contentWithEntity = content.createEntity(entityType.type, 'MUTABLE', { | |
text: '', | |
}); | |
const entityKey = contentWithEntity.getLastCreatedEntityKey(); | |
const nextState = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' '); | |
onComplete(nextState); | |
} | |
render() { | |
return null; | |
} | |
} | |
// The block is used to render the entity in the editor | |
// It may receive props: | |
// * from the source component when first created | |
// * from the server side when reloaded from the database | |
export class TextBlock extends Component { | |
constructor(props) { | |
super(props) | |
const data = props.blockProps.entity.getData() | |
this.state = { | |
text: data.text, | |
} | |
} | |
handleTextChange = e => { | |
const { text } = this.state | |
this.setState({ | |
text: e.target.value | |
}) | |
} | |
saveText = e => { | |
// Update editor ContentState | |
const { block, blockProps } = this.props | |
const { editorState, onChange } = blockProps | |
onChange(updateBlockEntity(editorState, block, { | |
text: this.state.text, | |
})) | |
} | |
render() { | |
const data = this.props.blockProps.entity.getData() | |
const { text } = this.state | |
return ( | |
<div> | |
<p>Saved text is "{ data.text }"</p> | |
<input | |
name="title" | |
type="text" | |
onChange={this.handleTextChange} | |
value={text} | |
/> | |
<button onClick={this.saveText}>Submit</button> | |
</div> | |
) | |
} | |
} | |
// Update a block's data in the WYSIWYG editor, nicked from DraftUtils source code | |
const updateBlockEntity = (editorState, block, data) => { | |
const content = editorState.getCurrentContent(); | |
let nextContent = content.mergeEntityData(block.getEntityAt(0), data); | |
nextContent = Modifier.mergeBlockData( | |
nextContent, | |
new SelectionState({ | |
anchorKey: block.getKey(), | |
anchorOffset: 0, | |
focusKey: block.getKey(), | |
focusOffset: block.getLength(), | |
}), | |
{}, | |
); | |
return EditorState.push(editorState, nextContent, 'apply-entity'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This likely means you're loading React from your own build instead of from the version loaded with Wagtail – this could cause issues.
For
updateBlockEntity
, if I were you I'd copy the full source with the relevant comment:All of this code will be completely useless in the next version of Draft.js.
Also – in Wagtail 2.1 you'll be able to get this directly (wagtail/wagtail#4467) as
window.Draftail.DraftUtils.updateBlockEntity
.