diff --git a/docs/babel.config.js b/docs/babel.config.js
index 30a18002..7e7cba28 100644
--- a/docs/babel.config.js
+++ b/docs/babel.config.js
@@ -5,5 +5,6 @@ module.exports = {
],
plugins: [
'@babel/plugin-proposal-optional-chaining',
+ '@babel/plugin-proposal-class-properties',
],
}
diff --git a/docs/gridsome.server.js b/docs/gridsome.server.js
index 737872a2..83bb46dc 100644
--- a/docs/gridsome.server.js
+++ b/docs/gridsome.server.js
@@ -57,6 +57,7 @@ module.exports = function (api) {
api.chainWebpack(config => {
config.resolve.extensions
.add('.ts')
+ .add('.tsx')
.add('.jsx')
config.module
diff --git a/docs/package.json b/docs/package.json
index 86e049b4..1cca1e83 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -35,7 +35,9 @@
"yjs": "^13.5.1"
},
"devDependencies": {
+ "@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-optional-chaining": "^7.13.0",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/preset-env": "^7.13.5",
"@babel/preset-react": "^7.12.13",
"html-loader": "^1.3.2",
diff --git a/docs/src/demos/Examples/Default/React/index-nope.jsx b/docs/src/demos/Examples/Default/React/index-nope.jsx
new file mode 100644
index 00000000..d654737d
--- /dev/null
+++ b/docs/src/demos/Examples/Default/React/index-nope.jsx
@@ -0,0 +1,143 @@
+import * as React from 'react'
+import ReactDOM from 'react-dom'
+import { EditorState } from 'prosemirror-state'
+import { EditorView } from 'prosemirror-view'
+import { Node, Schema } from 'prosemirror-model'
+// import applyDevTools from 'prosemirror-dev-tools'
+// import styled from 'styled-components'
+
+// Here we have the (too simple) React component which
+// we'll be rendering content into.
+//
+class Underlined extends React.Component {
+ constructor(props) {
+ super(props)
+ this.hole = React.createRef()
+ }
+ // We'll put the content into what we render using
+ // this function, which appends a given node to
+ // a ref HTMLElement, if present.
+ //
+ append(node) {
+ if (this.hole) {
+ this.hole.current.appendChild(node)
+ }
+ }
+
+ render() {
+ // Just really wanted to prove I could get React AND
+ // styled-component abilities at the same time.
+ //
+ // const UnderlinedText = styled.p`
+ // text-decoration: underline;
+ // `
+
+ // The styled components version is basically just a wrapper to do SCSS styling.
+ // Questionable if it's even needed for such simple styling and because you can't clearly see the
+ // DOM structure from the code (hence making `& > ${Component}` selectors quite unintuitive)
+ // return
+ return
{ this.createEditorView(ref) }} />
+ }
+}
diff --git a/docs/src/demos/Examples/Default/React/index-ori.jsx b/docs/src/demos/Examples/Default/React/index-ori.jsx
new file mode 100644
index 00000000..e3893834
--- /dev/null
+++ b/docs/src/demos/Examples/Default/React/index-ori.jsx
@@ -0,0 +1,167 @@
+import React, { useState } from 'react'
+import { defaultExtensions } from '@tiptap/starter-kit'
+import { useEditor, Editor } from '@tiptap/react'
+import './styles.scss'
+
+// useEditor only works for child components of
+const MenuBar = () => {
+ const editor = useEditor()
+
+ return (
+ <>
+
editor.chain().focus().toggleBold().run()}
+ className={`${editor.isActive('bold') ? 'is-active' : ''}`}
+ >
+ bold
+
+
editor.chain().focus().toggleItalic().run()}
+ className={`${editor.isActive('italic') ? 'active' : ''}`}
+ >
+ italic
+
+
editor.chain().focus().toggleStrike().run()}
+ className={`${editor.isActive('strike') ? 'active' : ''}`}
+ >
+ strike
+
+
editor.chain().focus().toggleCode().run()}
+ className={`${editor.isActive('code') ? 'active' : ''}`}
+ >
+ code
+
+
editor.chain().focus().unsetAllMarks().run()}>
+ clear marks
+
+
editor.chain().focus().clearNodes().run()}>
+ clear nodes
+
+
editor.chain().focus().setParagraph().run()}
+ className={`${editor.isActive('paragraph') ? 'active' : ''}`}
+ >
+ paragraph
+
+
editor.chain().focus().toggleHeading({ level: 1 }).run()}
+ className={`${editor.isActive('heading', { level: 1 }) ? 'active' : ''}`}
+ >
+ h1
+
+
editor.chain().focus().toggleHeading({ level: 2 }).run()}
+ className={`${editor.isActive('heading', { level: 2 }) ? 'active' : ''}`}
+ >
+ h2
+
+
editor.chain().focus().toggleHeading({ level: 3 }).run()}
+ className={`${editor.isActive('heading', { level: 3 }) ? 'active' : ''}`}
+ >
+ h3
+
+
editor.chain().focus().toggleHeading({ level: 4 }).run()}
+ className={`${editor.isActive('heading', { level: 4 }) ? 'active' : ''}`}
+ >
+ h4
+
+
editor.chain().focus().toggleHeading({ level: 5 }).run()}
+ className={`${editor.isActive('heading', { level: 5 }) ? 'active' : ''}`}
+ >
+ h5
+
+
editor.chain().focus().toggleHeading({ level: 6 }).run()}
+ className={`${editor.isActive('heading', { level: 6 }) ? 'active' : ''}`}
+ >
+ h6
+
+
editor.chain().focus().toggleBulletList().run()}
+ className={`${editor.isActive('bulletList') ? 'active' : ''}`}
+ >
+ bullet list
+
+
editor.chain().focus().toggleOrderedList().run()}
+ className={`${editor.isActive('orderedList') ? 'active' : ''}`}
+ >
+ ordered list
+
+
editor.chain().focus().toggleCodeBlock().run()}
+ className={`${editor.isActive('codeBlock') ? 'active' : ''}`}
+ >
+ code block
+
+
editor.chain().focus().toggleBlockquote().run()}
+ className={`${editor.isActive('blockquote') ? 'active' : ''}`}
+ >
+ blockquote
+
+
editor.chain().focus().setHorizontalRule().run()}>
+ horizontal rule
+
+
editor.chain().focus().setHardBreak().run()}>
+ hard break
+
+
editor.chain().focus().undo().run()}>
+ undo
+
+
editor.chain().focus().redo().run()}>
+ redo
+
+ >
+ )
+}
+
+export default () => {
+ const [value, setValue] = useState(`
+
+ Hi there,
+
+
+ this is a basic basic example of tiptap . Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:
+
+
+
+ That’s a bullet list with one …
+
+
+ … or two list items.
+
+
+
+ Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:
+
+
body {
+ display: none;
+}
+
+ I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.
+
+
+ Wow, that’s amazing. Good work, boy! 👏
+
+ — Mom
+
+`)
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
diff --git a/docs/src/demos/Examples/Default/React/index.jsx b/docs/src/demos/Examples/Default/React/index.jsx
index e3893834..8274e29f 100644
--- a/docs/src/demos/Examples/Default/React/index.jsx
+++ b/docs/src/demos/Examples/Default/React/index.jsx
@@ -1,167 +1,84 @@
-import React, { useState } from 'react'
+import React, { useState, useEffect } from 'react'
import { defaultExtensions } from '@tiptap/starter-kit'
-import { useEditor, Editor } from '@tiptap/react'
+import Paragraph from '@tiptap/extension-paragraph'
+import { Editor, EditorContent, ReactNodeViewRenderer } from '@tiptap/react'
import './styles.scss'
+import { render, unmountComponentAtNode } from 'react-dom'
-// useEditor only works for child components of
-const MenuBar = () => {
- const editor = useEditor()
+const useEditor = (options = {}) => {
+ const [editor, setEditor] = useState(null)
- return (
- <>
-
editor.chain().focus().toggleBold().run()}
- className={`${editor.isActive('bold') ? 'is-active' : ''}`}
- >
- bold
-
-
editor.chain().focus().toggleItalic().run()}
- className={`${editor.isActive('italic') ? 'active' : ''}`}
- >
- italic
-
-
editor.chain().focus().toggleStrike().run()}
- className={`${editor.isActive('strike') ? 'active' : ''}`}
- >
- strike
-
-
editor.chain().focus().toggleCode().run()}
- className={`${editor.isActive('code') ? 'active' : ''}`}
- >
- code
-
-
editor.chain().focus().unsetAllMarks().run()}>
- clear marks
-
-
editor.chain().focus().clearNodes().run()}>
- clear nodes
-
-
editor.chain().focus().setParagraph().run()}
- className={`${editor.isActive('paragraph') ? 'active' : ''}`}
- >
- paragraph
-
-
editor.chain().focus().toggleHeading({ level: 1 }).run()}
- className={`${editor.isActive('heading', { level: 1 }) ? 'active' : ''}`}
- >
- h1
-
-
editor.chain().focus().toggleHeading({ level: 2 }).run()}
- className={`${editor.isActive('heading', { level: 2 }) ? 'active' : ''}`}
- >
- h2
-
-
editor.chain().focus().toggleHeading({ level: 3 }).run()}
- className={`${editor.isActive('heading', { level: 3 }) ? 'active' : ''}`}
- >
- h3
-
-
editor.chain().focus().toggleHeading({ level: 4 }).run()}
- className={`${editor.isActive('heading', { level: 4 }) ? 'active' : ''}`}
- >
- h4
-
-
editor.chain().focus().toggleHeading({ level: 5 }).run()}
- className={`${editor.isActive('heading', { level: 5 }) ? 'active' : ''}`}
- >
- h5
-
-
editor.chain().focus().toggleHeading({ level: 6 }).run()}
- className={`${editor.isActive('heading', { level: 6 }) ? 'active' : ''}`}
- >
- h6
-
-
editor.chain().focus().toggleBulletList().run()}
- className={`${editor.isActive('bulletList') ? 'active' : ''}`}
- >
- bullet list
-
-
editor.chain().focus().toggleOrderedList().run()}
- className={`${editor.isActive('orderedList') ? 'active' : ''}`}
- >
- ordered list
-
-
editor.chain().focus().toggleCodeBlock().run()}
- className={`${editor.isActive('codeBlock') ? 'active' : ''}`}
- >
- code block
-
-
editor.chain().focus().toggleBlockquote().run()}
- className={`${editor.isActive('blockquote') ? 'active' : ''}`}
- >
- blockquote
-
-
editor.chain().focus().setHorizontalRule().run()}>
- horizontal rule
-
-
editor.chain().focus().setHardBreak().run()}>
- hard break
-
-
editor.chain().focus().undo().run()}>
- undo
-
-
editor.chain().focus().redo().run()}>
- redo
-
- >
- )
+ useEffect(() => {
+ const instance = new Editor(options)
+ setEditor(instance)
+
+ return () => {
+ instance.destroy()
+ }
+ }, [])
+
+ return editor
+}
+
+
+
+function reactNodeView(Component) {
+ const renderComponent = (props, dom) => render(
, dom)
+
+ return (node, view, getPos, decorations) => {
+ let dom = document.createElement("div")
+ renderComponent({ node, view, decorations, getPos }, dom)
+
+ console.log(dom)
+ return {
+ dom,
+ contentDOM: dom.querySelector('[data-node-view-content]'),
+ update(node, decorations) {
+ renderComponent({ node, view, decorations, getPos }, dom)
+ return true
+ },
+ destroy() {
+ unmountComponentAtNode(dom)
+ },
+ }
+ }
}
export default () => {
- const [value, setValue] = useState(`
-
- Hi there,
-
-
- this is a basic basic example of tiptap . Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:
-
-
-
- That’s a bullet list with one …
-
-
- … or two list items.
-
-
-
- Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:
-
-
body {
- display: none;
-}
-
- I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.
-
-
- Wow, that’s amazing. Good work, boy! 👏
-
- — Mom
-
-`)
+ const editor = useEditor({
+ content: '
hello react
',
+ extensions: [
+ ...defaultExtensions(),
+ Paragraph.extend({
+ addNodeView() {
+ return reactNodeView(() => {
+ // useEffect(() => {
+ // console.log('effect')
+ // }, []);
+
+ return (
+
+
+
+ )
+ })
+ return ReactNodeViewRenderer(() => {
+ // useEffect(() => {
+ // console.log('effect')
+ // }, []);
+
+ return (
+
+
+
+ )
+ })
+ },
+ }),
+ ]
+ })
return (
- <>
-
-
-
- >
+
)
}
diff --git a/packages/react/package.json b/packages/react/package.json
index 707be903..bebb8446 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -23,9 +23,13 @@
],
"peerDependencies": {
"@tiptap/core": "^2.0.0-beta.1",
- "react": "^17.0.1"
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1"
},
"dependencies": {
"prosemirror-view": "^1.17.8"
+ },
+ "devDependencies": {
+ "@types/react-dom": "^17.0.1"
}
}
diff --git a/packages/react/src/Editor.ts b/packages/react/src/Editor.ts
new file mode 100644
index 00000000..e4c174f5
--- /dev/null
+++ b/packages/react/src/Editor.ts
@@ -0,0 +1,5 @@
+import { Editor as CoreEditor } from '@tiptap/core'
+
+export class Editor extends CoreEditor {
+ public contentComponent: any | null = null
+}
diff --git a/packages/react/src/EditorContent.jsx b/packages/react/src/EditorContent.jsx
new file mode 100644
index 00000000..e7395037
--- /dev/null
+++ b/packages/react/src/EditorContent.jsx
@@ -0,0 +1,71 @@
+import React, { useState, useRef, useEffect } from 'react'
+import ReactDOM from 'react-dom'
+import { Editor } from './Editor'
+
+// export const EditorContent = ({ editor }) => {
+// const editorContentRef = useRef(null)
+
+// useEffect(() => {
+// if (editor && editor.options.element) {
+// console.log('set editorContent element')
+
+// const element = editorContentRef.current
+
+// element.appendChild(editor.options.element.firstChild)
+
+// editor.setOptions({
+// element,
+// })
+
+// console.log({instance: this})
+
+// // TODO: why setTimeout?
+// setTimeout(() => {
+// editor.createNodeViews()
+// }, 0)
+// }
+// })
+
+// return (
+//
+// )
+// }
+
+export class EditorContent extends React.Component {
+ constructor(props) {
+ super(props)
+ this.editorContentRef = React.createRef()
+ this.editorPortalRef = React.createRef()
+
+ this.state = {
+ editor: this.props.editor
+ }
+ }
+
+ componentDidUpdate() {
+ const { editor } = this.props
+
+ if (editor && editor.options.element) {
+ const element = this.editorContentRef.current
+
+ element.appendChild(editor.options.element.firstChild)
+
+ editor.setOptions({
+ element,
+ })
+
+ editor.contentComponent = this
+
+ // TODO: why setTimeout?
+ setTimeout(() => {
+ editor.createNodeViews()
+ }, 0)
+ }
+ }
+
+ render() {
+ return (
+
+ )
+ }
+}
diff --git a/packages/react/src/ReactNodeViewRenderer.ts b/packages/react/src/ReactNodeViewRenderer.ts
index 7fb1a1a8..c4af67b4 100644
--- a/packages/react/src/ReactNodeViewRenderer.ts
+++ b/packages/react/src/ReactNodeViewRenderer.ts
@@ -1 +1,209 @@
-export default class ReactNodeViewRenderer {}
+// @ts-nocheck
+import { Node, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core'
+import { Decoration, NodeView } from 'prosemirror-view'
+import { NodeSelection } from 'prosemirror-state'
+import { Node as ProseMirrorNode } from 'prosemirror-model'
+import React from 'react'
+import ReactDOM from 'react-dom'
+import { Editor } from './Editor'
+import { ReactRenderer } from './ReactRenderer'
+import test from './test'
+
+interface ReactNodeViewRendererOptions {
+ stopEvent: ((event: Event) => boolean) | null,
+ update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
+}
+
+class ReactNodeView implements NodeView {
+
+ renderer!: ReactRenderer
+
+ editor: Editor
+
+ extension!: Node
+
+ node!: ProseMirrorNode
+
+ decorations!: Decoration[]
+
+ getPos!: any
+
+ isDragging = false
+
+ options: ReactNodeViewRendererOptions = {
+ stopEvent: null,
+ update: null,
+ }
+
+ constructor(component: any, props: NodeViewRendererProps, options?: Partial
) {
+ this.options = { ...this.options, ...options }
+ this.editor = props.editor as Editor
+ this.extension = props.extension
+ this.node = props.node
+ this.getPos = props.getPos
+ this.mount(component)
+ }
+
+ mount(component: any) {
+ const props = {}
+
+ if (!component.displayName) {
+ component.displayName = this.extension.config.name
+ }
+
+ this.renderer = new ReactRenderer(component, {
+ editor: this.editor,
+ props,
+ })
+ }
+
+ get dom() {
+ // if (!this.renderer.element) {
+ // return null
+ // }
+
+ // if (!this.renderer.element.hasAttribute('data-node-view-wrapper')) {
+ // throw Error('Please use the NodeViewWrapper component for your node view.')
+ // }
+
+ return this.renderer.element
+ }
+
+ get contentDOM() {
+ // console.log(this.dom)
+ // return null
+ // if (!this.renderer.element) {
+ // return null
+ // }
+
+ const hasContent = !this.node.type.isAtom
+
+ if (!hasContent) {
+ return null
+ }
+
+ const contentElement = this.dom.querySelector('[data-node-view-content]')
+
+ return contentElement || this.dom
+ }
+
+ stopEvent(event: Event) {
+ if (typeof this.options.stopEvent === 'function') {
+ return this.options.stopEvent(event)
+ }
+
+ const target = (event.target as HTMLElement)
+ const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)
+
+ // ignore all events from child nodes
+ if (!isInElement) {
+ return false
+ }
+
+ const { isEditable } = this.editor
+ const { isDragging } = this
+ const isDraggable = !!this.node.type.spec.draggable
+ const isSelectable = NodeSelection.isSelectable(this.node)
+ const isCopyEvent = event.type === 'copy'
+ const isPasteEvent = event.type === 'paste'
+ const isCutEvent = event.type === 'cut'
+ const isClickEvent = event.type === 'mousedown'
+ const isDragEvent = event.type.startsWith('drag') || event.type === 'drop'
+
+ // ProseMirror tries to drag selectable nodes
+ // even if `draggable` is set to `false`
+ // this fix prevents that
+ if (!isDraggable && isSelectable && isDragEvent) {
+ event.preventDefault()
+ }
+
+ if (isDraggable && isDragEvent && !isDragging) {
+ event.preventDefault()
+ return false
+ }
+
+ // we have to store that dragging started
+ if (isDraggable && isEditable && !isDragging && isClickEvent) {
+ const dragHandle = target.closest('[data-drag-handle]')
+ const isValidDragHandle = dragHandle
+ && (this.dom === dragHandle || (this.dom.contains(dragHandle)))
+
+ if (isValidDragHandle) {
+ this.isDragging = true
+ document.addEventListener('dragend', () => {
+ this.isDragging = false
+ }, { once: true })
+ }
+ }
+
+ // these events are handled by prosemirror
+ if (
+ isDragging
+ || isCopyEvent
+ || isPasteEvent
+ || isCutEvent
+ || (isClickEvent && isSelectable)
+ ) {
+ return false
+ }
+
+ return true
+ }
+
+ ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
+ if (mutation.type === 'selection') {
+ if (this.node.isLeaf) {
+ return true
+ }
+
+ return false
+ }
+
+ if (!this.contentDOM) {
+ return true
+ }
+
+ const contentDOMHasChanged = !this.contentDOM.contains(mutation.target)
+ || this.contentDOM === mutation.target
+
+ return contentDOMHasChanged
+ }
+
+ destroy() {
+ this.renderer.destroy()
+ }
+
+ update(node: ProseMirrorNode, decorations: Decoration[]) {
+ if (typeof this.options.update === 'function') {
+ return this.options.update(node, decorations)
+ }
+
+ if (node.type !== this.node.type) {
+ return false
+ }
+
+ if (node === this.node && this.decorations === decorations) {
+ return true
+ }
+
+ this.node = node
+ this.decorations = decorations
+ // this.renderer.updateProps({ node, decorations })
+ this.renderer.render()
+
+ return true
+ }
+}
+
+export function ReactNodeViewRenderer(component: any, options?: Partial): NodeViewRenderer {
+ return (props: NodeViewRendererProps) => {
+ // try to get the parent component
+ // this is important for vue devtools to show the component hierarchy correctly
+ // maybe it’s `undefined` because isn’t rendered yet
+ if (!(props.editor as Editor).contentComponent) {
+ return {}
+ }
+
+ return new ReactNodeView(component, props, options) as NodeView
+ }
+}
diff --git a/packages/react/src/ReactRenderer.ts b/packages/react/src/ReactRenderer.ts
index d2672c60..6f7ece45 100644
--- a/packages/react/src/ReactRenderer.ts
+++ b/packages/react/src/ReactRenderer.ts
@@ -1 +1,58 @@
-export default class ReactRenderer {}
+// @ts-nocheck
+
+import React from 'react'
+import { render, unmountComponentAtNode } from 'react-dom'
+
+import { Editor } from './Editor'
+
+export interface VueRendererOptions {
+ as?: string;
+ editor: Editor;
+ props?: { [key: string]: any };
+}
+
+export class ReactRenderer {
+ id: string
+
+ editor: Editor
+
+ component: any
+
+ teleportElement: Element
+
+ element: Element
+
+ props: { [key: string]: any }
+
+ constructor(component: any, { props = {}, editor }: VueRendererOptions) {
+ this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString()
+ this.component = component
+ this.editor = editor
+ this.props = props
+
+ this.teleportElement = document.createElement('div')
+ // this.teleportElement.setAttribute('data-bla', '')
+ // render(React.createElement(component), this.teleportElement)
+ // render(React.createElement(component), this.teleportElement)
+ this.render()
+ // this.element = this.teleportElement.firstElementChild as Element
+ this.element = this.teleportElement
+ }
+
+ render() {
+ render(React.createElement(this.component), this.teleportElement)
+ }
+
+ updateProps(props: { [key: string]: any } = {}) {
+ // TODO
+ }
+
+ destroy() {
+ // TODO
+ // console.log('DESTROY', { bla: this.teleportElement })
+ // console.log(document.querySelector('[data-bla]'))
+ unmountComponentAtNode(this.teleportElement)
+ // unmountComponentAtNode(document.querySelector('[data-bla]'))
+ }
+
+}
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index 2fdac48e..27fc78c4 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -1,7 +1,9 @@
// @ts-nocheck
export * from '@tiptap/core'
-export { default as ReactRenderer } from './ReactRenderer'
-export { default as ReactNodeViewRenderer } from './ReactNodeViewRenderer'
-export {
- Editor, EditorContext, useEditor,
-} from './components/Editor'
+export { Editor } from './Editor'
+// export {
+// Editor, EditorContext, useEditor,
+// } from './components/Editor'
+export * from './ReactRenderer'
+export * from './ReactNodeViewRenderer'
+export * from './EditorContent'
diff --git a/packages/react/src/test.jsx b/packages/react/src/test.jsx
new file mode 100644
index 00000000..0c78dc43
--- /dev/null
+++ b/packages/react/src/test.jsx
@@ -0,0 +1,7 @@
+import React from 'react'
+
+export default () => {
+ return (
+
+ )
+}
diff --git a/yarn.lock b/yarn.lock
index b5900c7e..bf010110 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1952,9 +1952,9 @@
universal-user-agent "^6.0.0"
"@octokit/openapi-types@^5.3.0":
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.0.tgz#29e3faa119da90082dc653ea74c8bb345d197bf7"
- integrity sha512-5q2qBz4iZ0xS/DEJ0ROusFbN4cVlbJE9GvOByen+mv7artuGXfVhONqcuRd7jYN2glTmCnzcZw+X6LrjRVqs0A==
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.1.tgz#a49d119a1b9e47b7a9f5133ab14be2d8afaa183d"
+ integrity sha512-TvVk2QuIA0lQZcIMd6xbdGaGDVeNYIOa3l1ZVagAIk5K3t/WMYbcg4BISNDhzdVhm/TgQB26frAgd/GV81aHJA==
"@octokit/plugin-enterprise-rest@^6.0.1":
version "6.0.1"
@@ -2313,6 +2313,21 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
+"@types/react-dom@^17.0.1":
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.1.tgz#d92d77d020bfb083e07cc8e0ac9f933599a4d56a"
+ integrity sha512-yIVyopxQb8IDZ7SOHeTovurFq+fXiPICa+GV3gp0Xedsl+MwQlMLKmvrnEjFbQxjliH5YVAEWFh975eVNmKj7Q==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*":
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8"
+ integrity sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^3.0.2"
+
"@types/react@^16.8.12":
version "16.14.4"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.4.tgz#365f6a1e117d1eec960ba792c7e1e91ecad38e6f"
@@ -3393,9 +3408,9 @@ bcrypt-pbkdf@^1.0.0:
tweetnacl "^0.14.3"
before-after-hook@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.1.tgz#99ae36992b5cfab4a83f6bee74ab27835f28f405"
- integrity sha512-5ekuQOvO04MDj7kYZJaMab2S8SPjGJbotVNyv7QYFCOAwrGZs/YnoDNlh1U+m5hl7H2D/+n0taaAV/tfyd3KMA==
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.0.tgz#09c40d92e936c64777aa385c4e9b904f8147eaf0"
+ integrity sha512-jH6rKQIfroBbhEXVmI7XmXe3ix5S/PgJqpzdDPnR8JGLHWNYLsYZ6tK5iWOF/Ra3oqEX0NobXGlzbiylIzVphQ==
big.js@^3.1.3:
version "3.2.0"
@@ -4195,9 +4210,9 @@ cli-width@^2.0.0:
integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==
clipboard@^2.0.0:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
- integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.7.tgz#da927f817b1859426df39212ac81feb07dbaeadc"
+ integrity sha512-8M8WEZcIvs0hgOma+wAPkrUxpv0PMY1L6VsAJh/2DOKARIMpyWe6ZLcEoe1qktl6/ced5ceYHs+oGedSbgZ3sg==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
@@ -4299,9 +4314,9 @@ color-name@^1.0.0, color-name@~1.1.4:
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.5.3, color-string@^1.5.4:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6"
- integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014"
+ integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
@@ -5792,9 +5807,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.649:
- version "1.3.681"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.681.tgz#facd915ae46a020e8be566a2ecdc0b9444439be9"
- integrity sha512-W6uYvSUTHuyX2DZklIESAqx57jfmGjUkd7Z3RWqLdj9Mmt39ylhBuvFXlskQnvBHj0MYXIeQI+mjiwVddZLSvA==
+ version "1.3.682"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.682.tgz#f4b5c8d4479df96b61e508a721d6c32c1262ef23"
+ integrity sha512-zok2y37qR00U14uM6qBz/3iIjWHom2eRfC2S1StA0RslP7x34jX+j4mxv80t8OEOHLJPVG54ZPeaFxEI7gPrwg==
elegant-spinner@^1.0.1:
version "1.0.1"
@@ -7063,9 +7078,9 @@ gitconfiglocal@^1.0.0:
ini "^1.3.2"
github-buttons@^2.8.0:
- version "2.14.3"
- resolved "https://registry.yarnpkg.com/github-buttons/-/github-buttons-2.14.3.tgz#421691619d6becc451fe1ad175d5e29fe3ae2651"
- integrity sha512-kOXAjak/qEZYKORe1W80q+v8Ehas2yjHjyVWe4OO/MvmaRVH30m6n2xL4OM1+RBq3thVWxdCeVt3LIzbdATsKA==
+ version "2.14.4"
+ resolved "https://registry.yarnpkg.com/github-buttons/-/github-buttons-2.14.4.tgz#f4b335d1af235bfb4a4598162e8f2ca190635124"
+ integrity sha512-Fikb6lylJ2skQnoBaEv9m1yc6QwA8qbRFMRFWU08tMKXpbaql1LMKCghBAiuNpiWiGA25NiKuFO0oeD63030Kw==
github-from-package@0.0.0:
version "0.0.0"
@@ -7088,9 +7103,9 @@ glob-parent@^3.1.0:
path-dirname "^1.0.0"
glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
- integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
@@ -10072,9 +10087,9 @@ no-case@^3.0.4:
tslib "^2.0.3"
node-abi@^2.7.0:
- version "2.20.0"
- resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.20.0.tgz#0659ee1a4a04dacabd3ac4429fac6297ed58e92e"
- integrity sha512-6ldtfVR5l3RS8D0aT+lj/uM2Vv/PGEkeWzt2tl8DFBsGY/IuVnAIHl+dG6C14NlWClVv7Rn2+ZDvox+35Hx2Kg==
+ version "2.21.0"
+ resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.21.0.tgz#c2dc9ebad6f4f53d6ea9b531e7b8faad81041d48"
+ integrity sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg==
dependencies:
semver "^5.4.1"
@@ -14689,9 +14704,9 @@ uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0:
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
v8-compile-cache@^2.0.3:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"
- integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
+ integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3:
version "3.0.4"
@@ -15189,9 +15204,9 @@ ws@^6.2.1:
async-limiter "~1.0.0"
ws@^7.2.0:
- version "7.4.3"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd"
- integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==
+ version "7.4.4"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
+ integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
x-is-string@^0.1.0:
version "0.1.0"
@@ -15232,9 +15247,9 @@ y-leveldb@^0.1.0:
lib0 "^0.2.31"
y-prosemirror@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/y-prosemirror/-/y-prosemirror-1.0.6.tgz#75cfdd3ec65638f4c3112dd1a5ccd2daeb147f12"
- integrity sha512-rbYA/kssa/4yMlvdfYrKtZwG15UCdwCIO6fCitua4VaJSVN2ruLvR1OrPl8txhKzyiPiBAphFzjj+ZXkm4D/6w==
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/y-prosemirror/-/y-prosemirror-1.0.7.tgz#e0d3bbbc8b88bc4942d9720fd8413da393999200"
+ integrity sha512-AnlwGoz6+o6PkrBm09kY3+dXP3Yt6QHDIMHhtn0mGeUnSQRVcI0/raQwh/kYD7z1EUPghKfDaH8DoI0duAu5sg==
dependencies:
lib0 "^0.2.34"