gtgalone / react-quilljs

React Hook Wrapper for Quill, powerful rich text editor.
https://www.npmjs.com/package/react-quilljs
MIT License
248 stars 28 forks source link

Multiple instances on a single page #81

Closed lukematthews closed 4 months ago

lukematthews commented 5 months ago

Hi, I've taken your basic example and I'm trying to add a second editor below the first one.

Any advice?

import React from "react";

import { useQuill } from "react-quilljs";
// or const { useQuill } = require('react-quilljs');

import "quill/dist/quill.snow.css"; // Add css for snow theme
// or import 'quill/dist/quill.bubble.css'; // Add css for bubble theme

export default () => {
  const { quill, quillRef } = useQuill();
  const { quill2, quillRef2 } = useQuill();

  console.log(quill); // undefined > Quill Object
  console.log(quillRef); // { current: undefined } > { current: Quill Editor Reference }

  return (<>
    <div style={{ width: 500, height: 300 }}>
      <div ref={quillRef} />
    </div>
    <div style={{ width: 500, height: 300 }}>
      <div ref={quillRef2} />
    </div>
  </>
);
};
rodriguezjosetk commented 4 months ago

Hey! this should be quite simple only by doing a component based on this library, e.g.: my custom base implementation using chakra)

import { FC, useEffect } from 'react'
import { useQuill } from 'react-quilljs'
import DOMPurify from 'dompurify'
import { Box, Flex } from '@chakra-ui/react'
import { EmitterSource } from 'quill'
import { QUILL_EMPTY_VALUE } from './constants'

import 'quill/dist/quill.snow.css'

interface WysiwygProps {
  defaultValue?: string
  placeholder?: string
  onChange?: (value: string, source: EmitterSource) => void
}

export const Wysiwyg: FC<WysiwygProps> = ({
  defaultValue,
  placeholder,
  onChange,
}) => {
  const { quill, quillRef } = useQuill({ placeholder })

  useEffect(() => {
    if (quill) {
      if (defaultValue) {
        quill.clipboard.dangerouslyPasteHTML(DOMPurify.sanitize(defaultValue))
      }

      quill.on('text-change', (_delta, _oldDelta, source) => {
        if (onChange) {
          const rawValue = quill.root.innerHTML
          const value = rawValue === <p></br></p> ? '' : rawValue

          onChange(value, source)
        }
      })
    }
  }, [quill])

  return (
    <Flex
      direction="column"
      sx={{
        '& .ql-editor': {
          minHeight: '7.25rem',
          overflow: 'auto',
          resize: 'vertical',
        },
      }}
    >
      <Box ref={quillRef} />
    </Flex>
  )
}

And then, wherever in your app:

<Wysiwyg placeholder="Editor 1" />
<Wysiwyg placeholder="Editor 2" />
gtgalone commented 4 months ago

@rodriguezjosetk Thanks for the nice solution!