Refactor React demo

This commit is contained in:
Sven Adlung
2020-04-28 22:41:08 +02:00
parent e6c6ec263f
commit 9e1d8f1943
2 changed files with 95 additions and 36 deletions

View File

@@ -0,0 +1,30 @@
import React, { useState, useRef, useEffect, createContext, useContext } from 'react'
import { Editor as Tiptap } from '@tiptap/core'
export const EditorContext = createContext({})
export const useEditor = () => useContext(EditorContext)
export const Editor = ({ value, onChange, children, ...props }) => {
const [editor, setEditor] = useState(null)
const editorRef = useRef(null)
useEffect(() => {
const e = new Tiptap({
element: editorRef.current,
content: value,
...props,
}).on('transaction', () => {
onChange(e.json())
})
setEditor(e)
}, [])
return (
<EditorContext.Provider value={editor}>
{editorRef.current && children}
<div ref={editorRef} />
</EditorContext.Provider>
)
}

View File

@@ -1,40 +1,69 @@
import React, { Component } from 'react' import React, { useState } from 'react'
import { Editor } from '@tiptap/core' import { useEditor, Editor } from './components/Editor'
import extensions from '@tiptap/starter-kit' import extensions from '@tiptap/starter-kit'
export default class extends Component { // Menu bar example component
constructor() { // useEditor only works for child components of <Editor />
super() const MenuBar = () => {
this.editorNode = React.createRef() const editor = useEditor()
}
componentDidMount() {
this.editor = new Editor({
element: this.editorNode.current,
content: '<p>rendered in <strong>react</strong>!</p>',
extensions: extensions(),
})
this.forceUpdate()
}
render() { return (
return ( <>
<div> <button onClick={() => editor.focus().removeMarks()}>
{this.editor && Clear formatting
<div> </button>
<button onClick={() => this.editor.focus().removeMarks()}> <button
clear formatting className={`${editor.isActive('bold') ? 'is-active' : ''}`}
</button> onClick={() => editor.focus().bold()}
<button >
onClick={() => this.editor.focus().bold()} Bold
className={`${this.editor.isActive('bold') ? 'is-active' : ''}`} </button>
> </>
bold )
</button> }
</div>
} export default () => {
<div ref={this.editorNode} /> const [value, setValue] = useState({
</div> 'type': 'document',
) 'content': [
} {
'type': 'paragraph',
'content': [
{
'type': 'text',
'text': 'rendered in '
},
{
'type': 'text',
'marks': [
{
'type': 'bold'
}
],
'text': 'react'
},
{
'type': 'text',
'text': '!'
}
]
}
]
})
return (
<>
<p>
<button onClick={() => alert(JSON.stringify(value))}>Alert state</button>
</p>
<hr style={{ margin: '0.85rem 0'}} />
<Editor
value={value}
onChange={setValue}
extensions={extensions()}
>
<MenuBar />
</Editor>
</>
)
} }