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> <>
{this.editor && <button onClick={() => editor.focus().removeMarks()}>
<div> Clear formatting
<button onClick={() => this.editor.focus().removeMarks()}>
clear formatting
</button> </button>
<button <button
onClick={() => this.editor.focus().bold()} className={`${editor.isActive('bold') ? 'is-active' : ''}`}
className={`${this.editor.isActive('bold') ? 'is-active' : ''}`} onClick={() => editor.focus().bold()}
> >
bold Bold
</button> </button>
</div> </>
} )
<div ref={this.editorNode} /> }
</div>
export default () => {
const [value, setValue] = useState({
'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>
</>
) )
}
} }