概要
本サイトで行っている、draft.js における以下の処理をまとめました。
テキストの貼り付け
画像の貼り付け(コピペまたはドロップ)
Facebook謹製のリッチテキストエディタフレームワーク。
テキストのペースト
デフォルトの状態で複数行のテキストを張り付けると、改行ごとにブロックが分かれてしまう。
これだと例えばcode-blockの中にペーストしたい時など、不便。
const handlePastedText = (
text: string,
html: string,
editorState: EditorState
) => {
try {
const newState = Modifier.replaceText(
editorState.getCurrentContent(),
editorState.getSelection(),
text.trim()
)
const newEditorState = EditorState.set(editorState, {
currentContent: newState,
})
setEditorState(newEditorState)
return 'handled'
} catch (error) {
return 'not-handled'
}
}
画像のペースト
画像のドラッグ&ドロップとコピペに対応する。張り付けられたら画像データをサーバーに送り、帰ってきたURLを元に画像ブロックで表示する。
const handleDroppedFiles = (
selection: SelectionState,
files: File[]
): DraftHandleValue => {
insertImageBlocks(urls)
return 'handled'
}
const handlePastedFiles = (files: File[]): DraftHandleValue => {
insertImageBlocks(urls)
return 'handled'
}
const insertImageBlocks = async (files: File[]) => {
const urls = await uploadImages(files)
let newEditorState: EditorState = null
for (const url of urls) {
newEditorState = newEditorState || editorState
const contentState = newEditorState.getCurrentContent()
const contentStateWithEntity = contentState.createEntity(
'IMAGE',
'IMMUTABLE',
{ src: url }
)
const entityKey = contentStateWithEntity.getLastCreatedEntityKey()
newEditorState = AtomicBlockUtils.insertAtomicBlock(
newEditorState,
entityKey,
' '
)
}
setEditorState(newEditorState)
}