From 9c4c21a9f7c3bdc19832d562101c397999dd8256 Mon Sep 17 00:00:00 2001 From: KentoMoriwaki Date: Mon, 20 Mar 2023 12:14:17 +0900 Subject: [PATCH 1/2] Add custom paragraph example --- .../CustomParagraph/React/Paragraph.jsx | 25 +++++++++ .../Examples/CustomParagraph/React/index.html | 0 .../Examples/CustomParagraph/React/index.jsx | 27 +++++++++ .../CustomParagraph/React/index.spec.js | 23 ++++++++ .../CustomParagraph/React/styles.scss | 24 ++++++++ .../CustomParagraph/Vue/Component.vue | 32 +++++++++++ .../Examples/CustomParagraph/Vue/Extension.js | 10 ++++ .../Examples/CustomParagraph/Vue/index.html | 0 .../CustomParagraph/Vue/index.spec.js | 23 ++++++++ .../Examples/CustomParagraph/Vue/index.vue | 55 +++++++++++++++++++ 10 files changed, 219 insertions(+) create mode 100644 demos/src/Examples/CustomParagraph/React/Paragraph.jsx create mode 100644 demos/src/Examples/CustomParagraph/React/index.html create mode 100644 demos/src/Examples/CustomParagraph/React/index.jsx create mode 100644 demos/src/Examples/CustomParagraph/React/index.spec.js create mode 100644 demos/src/Examples/CustomParagraph/React/styles.scss create mode 100644 demos/src/Examples/CustomParagraph/Vue/Component.vue create mode 100644 demos/src/Examples/CustomParagraph/Vue/Extension.js create mode 100644 demos/src/Examples/CustomParagraph/Vue/index.html create mode 100644 demos/src/Examples/CustomParagraph/Vue/index.spec.js create mode 100644 demos/src/Examples/CustomParagraph/Vue/index.vue diff --git a/demos/src/Examples/CustomParagraph/React/Paragraph.jsx b/demos/src/Examples/CustomParagraph/React/Paragraph.jsx new file mode 100644 index 0000000000..cec21f2fd6 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/React/Paragraph.jsx @@ -0,0 +1,25 @@ +import { Paragraph as BaseParagraph } from '@tiptap/extension-paragraph' +import { + NodeViewContent, + NodeViewWrapper, + ReactNodeViewRenderer, +} from '@tiptap/react' + +const ParagraphComponent = ({ node }) => { + return ( + + + {node.textContent.length} + + + + ) +} + +export const Paragraph = BaseParagraph.extend({ + addNodeView() { + return ReactNodeViewRenderer(ParagraphComponent) + }, +}) diff --git a/demos/src/Examples/CustomParagraph/React/index.html b/demos/src/Examples/CustomParagraph/React/index.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/src/Examples/CustomParagraph/React/index.jsx b/demos/src/Examples/CustomParagraph/React/index.jsx new file mode 100644 index 0000000000..67f7df514e --- /dev/null +++ b/demos/src/Examples/CustomParagraph/React/index.jsx @@ -0,0 +1,27 @@ +import './styles.scss' + +import { EditorContent, useEditor } from '@tiptap/react' +import StarterKit from '@tiptap/starter-kit' +import React from 'react' + +import { Paragraph } from './Paragraph.jsx' + +export default () => { + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + paragraph: false, + }), + Paragraph, + ], + content: ` +

+ Each line shows the number of characters in the paragraph. +

+ `, + }) + + return ( + + ) +} diff --git a/demos/src/Examples/CustomParagraph/React/index.spec.js b/demos/src/Examples/CustomParagraph/React/index.spec.js new file mode 100644 index 0000000000..1df3abf8d3 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/React/index.spec.js @@ -0,0 +1,23 @@ +context('/src/Examples/CustomParagraph/React/', () => { + beforeEach(() => { + cy.visit('/src/Examples/CustomParagraph/React/') + }) + + it('should have a working tiptap instance', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + // eslint-disable-next-line + expect(editor).to.not.be.null + }) + }) + + it('should have a paragraph and text length', () => { + cy.get('.ProseMirror p').should('exist').should('have.text', 'Each line shows the number of characters in the paragraph.') + cy.get('.ProseMirror .label').should('exist').should('have.text', '58') + }) + + it('should have new paragraph', () => { + cy.get('.ProseMirror').type('{selectall}{moveToEnd}{enter}') + cy.get('.ProseMirror p').eq(1).should('exist').should('have.text', '') + cy.get('.ProseMirror .label').eq(1).should('exist').should('have.text', '0') + }) +}) diff --git a/demos/src/Examples/CustomParagraph/React/styles.scss b/demos/src/Examples/CustomParagraph/React/styles.scss new file mode 100644 index 0000000000..85f390477a --- /dev/null +++ b/demos/src/Examples/CustomParagraph/React/styles.scss @@ -0,0 +1,24 @@ +/* Basic editor styles */ +.ProseMirror { + > * + * { + margin-top: 0.75em; + } +} + +/* Placeholder (at the top) */ +/*.ProseMirror p.is-editor-empty:first-child::before { + content: attr(data-placeholder); + float: left; + color: #ced4da; + pointer-events: none; + height: 0; +}*/ + +/* Placeholder (on every new line) */ +.ProseMirror .is-empty::before { + content: attr(data-placeholder); + float: left; + color: #ced4da; + pointer-events: none; + height: 0; +} diff --git a/demos/src/Examples/CustomParagraph/Vue/Component.vue b/demos/src/Examples/CustomParagraph/Vue/Component.vue new file mode 100644 index 0000000000..3dbaeac920 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/Vue/Component.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/demos/src/Examples/CustomParagraph/Vue/Extension.js b/demos/src/Examples/CustomParagraph/Vue/Extension.js new file mode 100644 index 0000000000..cc53c39195 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/Vue/Extension.js @@ -0,0 +1,10 @@ +import { Paragraph as BaseParagraph } from '@tiptap/extension-paragraph' +import { VueNodeViewRenderer } from '@tiptap/vue-3' + +import Component from './Component.vue' + +export default BaseParagraph.extend({ + addNodeView() { + return VueNodeViewRenderer(Component) + }, +}) diff --git a/demos/src/Examples/CustomParagraph/Vue/index.html b/demos/src/Examples/CustomParagraph/Vue/index.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/src/Examples/CustomParagraph/Vue/index.spec.js b/demos/src/Examples/CustomParagraph/Vue/index.spec.js new file mode 100644 index 0000000000..1df3abf8d3 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/Vue/index.spec.js @@ -0,0 +1,23 @@ +context('/src/Examples/CustomParagraph/React/', () => { + beforeEach(() => { + cy.visit('/src/Examples/CustomParagraph/React/') + }) + + it('should have a working tiptap instance', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + // eslint-disable-next-line + expect(editor).to.not.be.null + }) + }) + + it('should have a paragraph and text length', () => { + cy.get('.ProseMirror p').should('exist').should('have.text', 'Each line shows the number of characters in the paragraph.') + cy.get('.ProseMirror .label').should('exist').should('have.text', '58') + }) + + it('should have new paragraph', () => { + cy.get('.ProseMirror').type('{selectall}{moveToEnd}{enter}') + cy.get('.ProseMirror p').eq(1).should('exist').should('have.text', '') + cy.get('.ProseMirror .label').eq(1).should('exist').should('have.text', '0') + }) +}) diff --git a/demos/src/Examples/CustomParagraph/Vue/index.vue b/demos/src/Examples/CustomParagraph/Vue/index.vue new file mode 100644 index 0000000000..6dfb471955 --- /dev/null +++ b/demos/src/Examples/CustomParagraph/Vue/index.vue @@ -0,0 +1,55 @@ + + + + + +n From becfc68222d4391fb954e210cb44384515bd9f0d Mon Sep 17 00:00:00 2001 From: KentoMoriwaki Date: Mon, 20 Mar 2023 12:18:04 +0900 Subject: [PATCH 2/2] Remove unnecessary queueMicrotask --- packages/react/src/EditorContent.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react/src/EditorContent.tsx b/packages/react/src/EditorContent.tsx index 9f159c5190..0a7ea77323 100644 --- a/packages/react/src/EditorContent.tsx +++ b/packages/react/src/EditorContent.tsx @@ -75,9 +75,7 @@ export class PureEditorContent extends React.Component { - flushSync(fn) - }) + flushSync(fn) } else { fn() }