refactoring

This commit is contained in:
Philipp Kühn
2021-03-16 22:22:13 +01:00
parent a76de1ab6d
commit 49fcf829f3
9 changed files with 91 additions and 55 deletions

View File

@@ -11,7 +11,9 @@ module.exports = {
{ {
files: [ files: [
'./**/*.ts', './**/*.ts',
'./**/*.tsx',
'./**/*.js', './**/*.js',
'./**/*.jsx',
'./**/*.vue', './**/*.vue',
], ],
plugins: [ plugins: [
@@ -27,6 +29,7 @@ module.exports = {
window: false, window: false,
}, },
extends: [ extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended',
'plugin:vue/strongly-recommended', 'plugin:vue/strongly-recommended',
'airbnb-base', 'airbnb-base',

View File

@@ -13,7 +13,7 @@ export class MentionList extends React.Component {
componentDidUpdate(oldProps) { componentDidUpdate(oldProps) {
if (this.props.items !== oldProps.items) { if (this.props.items !== oldProps.items) {
this.setState({ this.setState({
selectedIndex: 0 selectedIndex: 0,
}) })
} }
} }
@@ -39,13 +39,13 @@ export class MentionList extends React.Component {
upHandler() { upHandler() {
this.setState({ this.setState({
selectedIndex: ((this.state.selectedIndex + this.props.items.length) - 1) % this.props.items.length selectedIndex: ((this.state.selectedIndex + this.props.items.length) - 1) % this.props.items.length,
}) })
} }
downHandler() { downHandler() {
this.setState({ this.setState({
selectedIndex: (this.state.selectedIndex + 1) % this.props.items.length selectedIndex: (this.state.selectedIndex + 1) % this.props.items.length,
}) })
} }

View File

@@ -66,9 +66,9 @@ export default () => {
reactRenderer.destroy() reactRenderer.destroy()
}, },
} }
}
}, },
}) },
}),
], ],
content: ` content: `
<p> <p>
@@ -84,8 +84,8 @@ export default () => {
return ( return (
<div> <div>
<EditorContent editor={editor} /> <EditorContent editor={editor} />
{editor && {editor
<div className={`character-count ${editor.getCharacterCount() === limit ? 'character-count--warning' : ''}`}> && <div className={`character-count ${editor.getCharacterCount() === limit ? 'character-count--warning' : ''}`}>
<svg <svg
height="20" height="20"
width="20" width="20"

View File

@@ -1,6 +1,9 @@
/* eslint-disable */
import React, { useState } from 'react' import React, { useState } from 'react'
import tippy from 'tippy.js' import tippy from 'tippy.js'
import { useEditor, EditorContent, ReactRenderer, ReactNodeViewRenderer, NodeViewWrapper, NodeViewContent } from '@tiptap/react' import {
useEditor, EditorContent, ReactRenderer, ReactNodeViewRenderer, NodeViewWrapper, NodeViewContent,
} from '@tiptap/react'
import { defaultExtensions } from '@tiptap/starter-kit' import { defaultExtensions } from '@tiptap/starter-kit'
import Heading from '@tiptap/extension-heading' import Heading from '@tiptap/extension-heading'
import Paragraph from '@tiptap/extension-paragraph' import Paragraph from '@tiptap/extension-paragraph'
@@ -127,13 +130,13 @@ const MenuBar = ({ editor }) => {
) )
} }
const MentionList = (props) => { const MentionList = props => {
console.log({props}) console.log({ props })
return ( return (
<div> <div>
mentions mentions
{props.items.map((item) => ( {props.items.map(item => (
<div> <div>
{item} {item}
</div> </div>
@@ -174,7 +177,7 @@ export default () => {
Heading.extend({ Heading.extend({
draggable: true, draggable: true,
addNodeView() { addNodeView() {
return ReactNodeViewRenderer((props) => { return ReactNodeViewRenderer(props => {
return ( return (
<NodeViewWrapper> <NodeViewWrapper>
<div className="heading"> <div className="heading">
@@ -193,7 +196,7 @@ export default () => {
</NodeViewWrapper> </NodeViewWrapper>
) )
}) })
} },
}), }),
Mention.configure({ Mention.configure({
suggestion: { suggestion: {
@@ -238,45 +241,45 @@ export default () => {
reactRenderer.destroy() reactRenderer.destroy()
}, },
} }
}
}, },
}) },
}),
], ],
content: ` content: `
<h1>heading</h1> <h1>heading</h1>
<h2>heading</h2> <h2>heading</h2>
<p>paragraph</p> <p>paragraph</p>
`, `,
// content: ` // content: `
// <h2> // <h2>
// Hi there, // Hi there,
// </h2> // </h2>
// <p> // <p>
// this is a basic <em>basic</em> example of <strong>tiptap</strong>. Sure, there are all kind of basic text styles youd probably expect from a text editor. But wait until you see the lists: // this is a basic <em>basic</em> example of <strong>tiptap</strong>. Sure, there are all kind of basic text styles youd probably expect from a text editor. But wait until you see the lists:
// </p> // </p>
// <ul> // <ul>
// <li> // <li>
// Thats a bullet list with one … // Thats a bullet list with one …
// </li> // </li>
// <li> // <li>
// … or two list items. // … or two list items.
// </li> // </li>
// </ul> // </ul>
// <p> // <p>
// Isnt that great? And all of that is editable. But wait, theres more. Lets try a code block: // Isnt that great? And all of that is editable. But wait, theres more. Lets try a code block:
// </p> // </p>
// <pre><code class="language-css">body { // <pre><code class="language-css">body {
// display: none; // display: none;
// }</code></pre> // }</code></pre>
// <p> // <p>
// I know, I know, this is impressive. Its only the tip of the iceberg though. Give it a try and click a little bit around. Dont forget to check the other examples too. // I know, I know, this is impressive. Its only the tip of the iceberg though. Give it a try and click a little bit around. Dont forget to check the other examples too.
// </p> // </p>
// <blockquote> // <blockquote>
// Wow, thats amazing. Good work, boy! 👏 // Wow, thats amazing. Good work, boy! 👏
// <br /> // <br />
// — Mom // — Mom
// </blockquote> // </blockquote>
// `, // `,
}) })
return ( return (

View File

@@ -112,6 +112,16 @@ export type ValuesOf<T> = T[keyof T];
export type KeysWithTypeOf<T, Type> = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T] export type KeysWithTypeOf<T, Type> = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T]
export type NodeViewProps = {
editor: Editor,
node: ProseMirrorNode,
decorations: Decoration[],
selected: boolean,
extension: Node,
getPos: () => number,
updateAttributes: (attributes: AnyObject) => void,
}
export type NodeViewRendererProps = { export type NodeViewRendererProps = {
editor: Editor, editor: Editor,
node: ProseMirrorNode, node: ProseMirrorNode,

View File

@@ -1,5 +1,10 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { NodeView, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core' import {
NodeView,
NodeViewProps,
NodeViewRenderer,
NodeViewRendererProps,
} from '@tiptap/core'
import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view' import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'
import { Node as ProseMirrorNode } from 'prosemirror-model' import { Node as ProseMirrorNode } from 'prosemirror-model'
import { Editor } from './Editor' import { Editor } from './Editor'
@@ -16,7 +21,7 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor> {
renderer!: ReactRenderer renderer!: ReactRenderer
mount() { mount() {
const props = { const props: NodeViewProps = {
editor: this.editor, editor: this.editor,
node: this.node, node: this.node,
decorations: this.decorations, decorations: this.decorations,
@@ -35,10 +40,11 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor> {
this.component.displayName = capitalizeFirstChar(this.extension.config.name) this.component.displayName = capitalizeFirstChar(this.extension.config.name)
} }
const ReactNodeView: React.FunctionComponent = (props) => { const ReactNodeViewProvider: React.FunctionComponent = componentProps => {
const [isEditable, setIsEditable] = useState(this.editor.isEditable) const [isEditable, setIsEditable] = useState(this.editor.isEditable)
const onDragStart = this.onDragStart.bind(this) const onDragStart = this.onDragStart.bind(this)
const onViewUpdate = () => setIsEditable(this.editor.isEditable) const onViewUpdate = () => setIsEditable(this.editor.isEditable)
const Component = this.component
useEffect(() => { useEffect(() => {
this.editor.on('viewUpdate', onViewUpdate) this.editor.on('viewUpdate', onViewUpdate)
@@ -50,12 +56,14 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor> {
return ( return (
<ReactNodeViewContext.Provider value={{ onDragStart, isEditable }}> <ReactNodeViewContext.Provider value={{ onDragStart, isEditable }}>
<this.component {...props} /> <Component {...componentProps} />
</ReactNodeViewContext.Provider> </ReactNodeViewContext.Provider>
) )
} }
this.renderer = new ReactRenderer(ReactNodeView, { ReactNodeViewProvider.displayName = 'ReactNodeView'
this.renderer = new ReactRenderer(ReactNodeViewProvider, {
editor: this.editor, editor: this.editor,
props, props,
}) })

View File

@@ -46,7 +46,9 @@ export class ReactRenderer {
const props = this.props const props = this.props
if (isClassComponent(Component)) { if (isClassComponent(Component)) {
props.ref = (ref: React.Component) => this.ref = ref props.ref = (ref: React.Component) => {
this.ref = ref
}
} }
this.reactElement = <Component {...props } /> this.reactElement = <Component {...props } />

View File

@@ -1,4 +1,9 @@
import { NodeView, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core' import {
NodeView,
NodeViewProps,
NodeViewRenderer,
NodeViewRendererProps,
} from '@tiptap/core'
import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view' import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'
import { Node as ProseMirrorNode } from 'prosemirror-model' import { Node as ProseMirrorNode } from 'prosemirror-model'
import Vue from 'vue' import Vue from 'vue'
@@ -16,7 +21,7 @@ class VueNodeView extends NodeView<(Vue | VueConstructor), Editor> {
renderer!: VueRenderer renderer!: VueRenderer
mount() { mount() {
const props = { const props: NodeViewProps = {
editor: this.editor, editor: this.editor,
node: this.node, node: this.node,
decorations: this.decorations, decorations: this.decorations,

View File

@@ -1,4 +1,9 @@
import { NodeView, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core' import {
NodeView,
NodeViewProps,
NodeViewRenderer,
NodeViewRendererProps,
} from '@tiptap/core'
import { import {
ref, ref,
provide, provide,
@@ -20,7 +25,7 @@ class VueNodeView extends NodeView<Component, Editor> {
renderer!: VueRenderer renderer!: VueRenderer
mount() { mount() {
const props = { const props: NodeViewProps = {
editor: this.editor, editor: this.editor,
node: this.node, node: this.node,
decorations: this.decorations, decorations: this.decorations,