From cd3203f6f092af123b37cea629e76acb842d169f Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Tue, 13 Feb 2024 16:08:20 +0800 Subject: [PATCH] Add an example for using Quill with React --- packages/website/src/data/playground.tsx | 4 ++ packages/website/src/pages/index.jsx | 9 --- .../website/src/pages/playground/[...id].jsx | 24 +++----- .../custom-formats/externalResources.json | 9 --- .../playground/custom-formats/playground.json | 12 ++++ .../playground/form/externalResources.json | 9 --- .../src/playground/form/playground.json | 12 ++++ packages/website/src/playground/react/App.js | 61 +++++++++++++++++++ .../website/src/playground/react/Editor.js | 55 +++++++++++++++++ .../src/playground/react/playground.json | 13 ++++ .../website/src/playground/react/styles.css | 20 ++++++ .../playground/snow/externalResources.json | 9 --- .../src/playground/snow/playground.json | 12 ++++ 13 files changed, 199 insertions(+), 50 deletions(-) delete mode 100644 packages/website/src/playground/custom-formats/externalResources.json create mode 100644 packages/website/src/playground/custom-formats/playground.json delete mode 100644 packages/website/src/playground/form/externalResources.json create mode 100644 packages/website/src/playground/form/playground.json create mode 100644 packages/website/src/playground/react/App.js create mode 100644 packages/website/src/playground/react/Editor.js create mode 100644 packages/website/src/playground/react/playground.json create mode 100644 packages/website/src/playground/react/styles.css delete mode 100644 packages/website/src/playground/snow/externalResources.json create mode 100644 packages/website/src/playground/snow/playground.json diff --git a/packages/website/src/data/playground.tsx b/packages/website/src/data/playground.tsx index 07d8b74c52..0d304dc56a 100644 --- a/packages/website/src/data/playground.tsx +++ b/packages/website/src/data/playground.tsx @@ -11,6 +11,10 @@ const playground = [ title: 'Custom font and formats', url: '/playground/custom-formats', }, + { + title: 'Using Quill with React', + url: '/playground/react', + }, ]; export default playground; diff --git a/packages/website/src/pages/index.jsx b/packages/website/src/pages/index.jsx index 67aaa4f4ed..e184757021 100644 --- a/packages/website/src/pages/index.jsx +++ b/packages/website/src/pages/index.jsx @@ -374,9 +374,6 @@ const IndexPage = () => { events through a simple API. Works consistently and deterministically with JSON as both input and output. - - View documentation -
@@ -388,12 +385,6 @@ const IndexPage = () => { Experience the same consistent behavior and produced HTML across platforms. - - See the Chart -
diff --git a/packages/website/src/pages/playground/[...id].jsx b/packages/website/src/pages/playground/[...id].jsx index 545d4a5b60..99baf8334a 100644 --- a/packages/website/src/pages/playground/[...id].jsx +++ b/packages/website/src/pages/playground/[...id].jsx @@ -45,11 +45,11 @@ export async function getStaticProps({ params }) { } function Playground({ pack, permalink, title }) { - const { 'externalResources.json': rawResources, ...files } = pack; + const { 'playground.json': raw, ...files } = pack; - let externalResources = []; + let metadata = {}; try { - externalResources = JSON.parse(rawResources); + metadata = JSON.parse(raw); } catch (err) {} const [overrides] = useState(() => { @@ -72,13 +72,14 @@ function Playground({ pack, permalink, title }) { { const fullName = name.startsWith('/') ? name : `/${name}`; return { @@ -87,12 +88,7 @@ function Playground({ pack, permalink, title }) { }; }, {})} > - +
{ + const [range, setRange] = useState(); + const [lastChange, setLastChange] = useState(); + const [readOnly, setReadOnly] = useState(false); + + // Use a ref to access the quill instance directly + const quillRef = useRef(); + + return ( +
+ +
+ + +
+
+
Current Range:
+ {range ? JSON.stringify(range) : 'Empty'} +
+
+
Last Change:
+ {lastChange ? JSON.stringify(lastChange.ops) : 'Empty'} +
+
+ ); +}; + +export default App; diff --git a/packages/website/src/playground/react/Editor.js b/packages/website/src/playground/react/Editor.js new file mode 100644 index 0000000000..eedc8ed377 --- /dev/null +++ b/packages/website/src/playground/react/Editor.js @@ -0,0 +1,55 @@ +import React, { forwardRef, useEffect, useLayoutEffect, useRef } from 'react'; + +// Editor is an uncontrolled React component +const Editor = forwardRef( + ({ readOnly, defaultValue, onTextChange, onSelectionChange }, ref) => { + const containerRef = useRef(null); + const defaultValueRef = useRef(defaultValue); + const onTextChangeRef = useRef(onTextChange); + const onSelectionChangeRef = useRef(onSelectionChange); + + useLayoutEffect(() => { + onTextChangeRef.current = onTextChange; + onSelectionChangeRef.current = onSelectionChange; + }); + + useEffect(() => { + ref.current?.enable(!readOnly); + }, [ref, readOnly]); + + useEffect(() => { + const container = containerRef.current; + const editorContainer = container.appendChild( + container.ownerDocument.createElement('div'), + ); + const quill = new Quill(editorContainer, { + theme: 'snow', + }); + + ref.current = quill; + + if (defaultValueRef.current) { + quill.setContents(defaultValueRef.current); + } + + quill.on(Quill.events.TEXT_CHANGE, (...args) => { + onTextChangeRef.current?.(...args); + }); + + quill.on(Quill.events.SELECTION_CHANGE, (...args) => { + onSelectionChangeRef.current?.(...args); + }); + + return () => { + ref.current = null; + container.innerHTML = ''; + }; + }, []); + + return
; + }, +); + +Editor.displayName = 'Editor'; + +export default Editor; diff --git a/packages/website/src/playground/react/playground.json b/packages/website/src/playground/react/playground.json new file mode 100644 index 0000000000..a91ebff8d6 --- /dev/null +++ b/packages/website/src/playground/react/playground.json @@ -0,0 +1,13 @@ +{ + "template": "react", + "externalResources": [ + "{{site.highlightjs}}/highlight.min.js", + "{{site.highlightjs}}/styles/atom-one-dark.min.css", + "{{site.katex}}/katex.min.js", + "{{site.katex}}/katex.min.css", + "{{site.cdn}}/quill.snow.css", + "{{site.cdn}}/quill.bubble.css", + "{{site.cdn}}/quill.js" + ], + "activeFile": "App.js" +} diff --git a/packages/website/src/playground/react/styles.css b/packages/website/src/playground/react/styles.css new file mode 100644 index 0000000000..d7f83157ce --- /dev/null +++ b/packages/website/src/playground/react/styles.css @@ -0,0 +1,20 @@ +.controls { + display: flex; + border: 1px solid #ccc; + border-top: 0; + padding: 10px; +} + +.controls-right { + margin-left: auto; +} + +.state { + margin: 10px 0; + font-family: monospace; +} + +.state-title { + color: #999; + text-transform: uppercase; +} diff --git a/packages/website/src/playground/snow/externalResources.json b/packages/website/src/playground/snow/externalResources.json deleted file mode 100644 index e84dc204d9..0000000000 --- a/packages/website/src/playground/snow/externalResources.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - "{{site.highlightjs}}/highlight.min.js", - "{{site.highlightjs}}/styles/atom-one-dark.min.css", - "{{site.katex}}/katex.min.js", - "{{site.katex}}/katex.min.css", - "{{site.cdn}}/quill.snow.css", - "{{site.cdn}}/quill.bubble.css", - "{{site.cdn}}/quill.js" -] diff --git a/packages/website/src/playground/snow/playground.json b/packages/website/src/playground/snow/playground.json new file mode 100644 index 0000000000..b3b4681b77 --- /dev/null +++ b/packages/website/src/playground/snow/playground.json @@ -0,0 +1,12 @@ +{ + "template": "static", + "externalResources": [ + "{{site.highlightjs}}/highlight.min.js", + "{{site.highlightjs}}/styles/atom-one-dark.min.css", + "{{site.katex}}/katex.min.js", + "{{site.katex}}/katex.min.css", + "{{site.cdn}}/quill.snow.css", + "{{site.cdn}}/quill.bubble.css", + "{{site.cdn}}/quill.js" + ] +}