When inserting an atomic block, it is necessary to be able to set block data in the same step. Same as setting an entity at that very moment.
One reason is: inserting an atomic block and adding block data are two steps at the moment. If you press undo it is quite weird that the first undo operation just removes the block data (user cannot see any change) and then with a second undo operation the atomic block is removed.
I'm curious about a related issue here and was wondering if anyone would mind providing a bit more context.
I've been storing custom block data in entities attached to a space character I insert as the first character to the block. I haven't yet run across a mention of using getData or setData at the block level for storing custom block data. @delijah it looks like that's what you're trying to do.
Can anyone a bit more familiar with draft.js comment on whether there are reasons to use an Entity vs block data? If we should use block data (seems cleaner to me...), then I'd second delijah's request here.
insertAtomicBlock: function(
editorState: EditorState,
entityKey: string,
character: string
): EditorState
should be
insertAtomicBlock: function(
editorState: EditorState,
entityKey: string,
blockData: Map<any, any>,
character: string
): EditorState
Agreeing with @VanishingDante
@tbohlen
I'm new to draftjs
I have the same question with you, what are blockData and entity really for
draft-js's docs are too simple to get the needed informations
I only use contentData here
const blockRenderFn = contentBlock => {
const type = contentBlock.getType()
if (type === 'atomic') {
const editable = contentBlock.getData().get('editable')
return {
component: AtomicBlockComponent,
editable
}
}
}
I wrote this insertAtomicBlockWithData function to get the missing option
import {
BlockMapBuilder,
CharacterMetadata,
ContentBlock,
Modifier,
EditorState,
genKey
} from 'draft-js'
import { List, Repeat } from 'immutable'
const insertAtomicBlockWithData = (editorState, entityKey, blockData, character) => {
const contentState = editorState.getCurrentContent()
const selectionState = editorState.getSelection()
const afterRemovalContentState = Modifier.removeRange(
contentState,
selectionState,
'backwarad'
)
const targetSelectionState = afterRemovalContentState.getSelectionAfter()
const afterSplitContentState = Modifier.splitBlock(afterRemovalContentState, targetSelectionState)
const insertionTarget = afterSplitContentState.getSelectionAfter()
const asAtomicBlock = Modifier.setBlockType(
afterSplitContentState,
insertionTarget,
'atomic'
)
const charData = CharacterMetadata.create({ entity: entityKey })
const fragmentArray = [
new ContentBlock({
key: genKey(),
type: 'atomic',
text: character,
characterList: List(Repeat(charData, character.length)),
data: blockData
}),
new ContentBlock({
key: genKey(),
type: 'unstyled',
text: '',
characterList: List()
})
]
const fragment = BlockMapBuilder.createFromArray(fragmentArray)
const withAtomicBlock = Modifier.replaceWithFragment(
asAtomicBlock,
insertionTarget, fragment
)
const newContentState = withAtomicBlock.merge({
selectionBefore: selectionState,
selectionAfter: withAtomicBlock.getSelectionAfter().set('hasFocus', true)
})
return EditorState.push(editorState, newContentState, 'insert-fragment')
}
export default insertAtomicBlockWithData
Can someone please explain what an atomic block is and give an example for appropriate use-cases for it?
Sadly closing because of inactivity.
Most helpful comment
I wrote this insertAtomicBlockWithData function to get the missing option