diff --git a/demos/src/GuideContent/ExportJSON/React/index.html b/demos/src/GuideContent/ExportJSON/React/index.html new file mode 100644 index 00000000..da7eea75 --- /dev/null +++ b/demos/src/GuideContent/ExportJSON/React/index.html @@ -0,0 +1,15 @@ + + +
+ + + + + + + + diff --git a/demos/src/GuideContent/ExportJSON/React/index.jsx b/demos/src/GuideContent/ExportJSON/React/index.jsx new file mode 100644 index 00000000..be66a7ff --- /dev/null +++ b/demos/src/GuideContent/ExportJSON/React/index.jsx @@ -0,0 +1,96 @@ +import React, { useState, useEffect, useCallback } from 'react' +import { useEditor, EditorContent } from '@tiptap/react' +import StarterKit from '@tiptap/starter-kit' +import './styles.scss' + +export default () => { + const [json, setJson] = useState(null) + const editor = useEditor({ + content: ` ++ Wow, this editor instance exports its content as JSON. +
+ `, + extensions: [StarterKit], + }) + + useEffect(() => { + if (!editor) { + return null + } + + // Get the initial content … + setJson(editor.getJSON()) + + // … and get the content after every change. + editor.on('update', () => { + setJson(editor.getJSON()) + }) + }, [editor]) + + const setContent = useCallback(() => { + // You can pass a JSON document to the editor. + editor.commands.setContent( + { + type: 'doc', + content: [ + { + type: 'paragraph', + content: [ + { + type: 'text', + text: 'It’s 19871. You can’t turn on a radio, or go to a mall without hearing Olivia Newton-John’s hit song, Physical.', + }, + ], + }, + ], + }, + true, + ) + + // It’s likely that you’d like to focus the Editor after most commands. + editor.commands.focus() + }, [editor]) + + const clearContent = useCallback(() => { + editor.chain().clearContent(true).focus().run() + }, [editor]) + + if (!editor) { + return null + } + + return ( + <> +
+ {JSON.stringify(json)}
+
+ Example Text
') + }) + }) + + it('should return json', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + const json = editor.getJSON() + + expect(json).to.deep.equal({ + type: 'doc', + content: [ + { + type: 'paragraph', + content: [ + { + type: 'text', + text: 'Example Text', + }, + ], + }, + ], + }) + }) + }) +}) diff --git a/demos/src/GuideContent/ExportJSON/React/styles.scss b/demos/src/GuideContent/ExportJSON/React/styles.scss new file mode 100644 index 00000000..4ebe7f6a --- /dev/null +++ b/demos/src/GuideContent/ExportJSON/React/styles.scss @@ -0,0 +1,77 @@ +/* Style the export */ +.export { + padding: 1rem 0 0; + + h3 { + margin: 1rem 0 0.5rem; + } + + pre { + border-radius: 5px; + color: #333; + } + + code { + background-color: #e9ecef; + color: #495057; + display: block; + font-size: 0.8rem; + padding: 0.75rem 1rem; + white-space: pre-wrap; + } +} + +/* Basic editor styles */ +.ProseMirror { + > * + * { + margin-top: 0.75em; + } + + ul, + ol { + padding: 0 1rem; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1.1; + } + + code { + background-color: rgba(#616161, 0.1); + color: #616161; + } + + pre { + background: #0d0d0d; + border-radius: 0.5rem; + color: #fff; + font-family: "JetBrainsMono", monospace; + padding: 0.75rem 1rem; + + code { + background: none; + color: inherit; + font-size: 0.8rem; + padding: 0; + } + } + + img { + height: auto; + max-width: 100%; + } + + hr { + margin: 1rem 0; + } + + blockquote { + border-left: 2px solid rgba(#0d0d0d, 0.1); + padding-left: 1rem; + } +}