How to properly condiotionaly display the React Quill Custom Toolbar?

240 views Asked by At

I'm using React Quill and I need a custom toolbar because I want to add two buttons on the very right of the toolbar.

The problem is, I want this toolbar to conditionally render (based on the isOpen state) due a UI design.

This is my code:

import { useState } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import './OpinionInput.css';

const OPINION_PLACEHOLDER = 'Qual sua opiniĆ£o?';


export default function OpinionInput() {
  const [isOpen, setIsOpen] = useState(false);
  const [value, setValue] = useState('');
  
  const handleOpen = () => {
    setIsOpen(true);
  };

  const handleClose = () => {
    setIsOpen(false);
  };

  const CustomToolbar = () => {
    return (
      <div
        className={`
          flex justify-between items-center
        `}
        style={{ display: isOpen ? 'flex' : 'none' }}
      >
        <div id="toolbar">
          <button className="ql-bold"></button>
          <button className="ql-italic"></button>
        </div>
  
        <div className="space-x-3">
          <button
            className={`
              ql-custom text-grey-500 text-center focus:outline-none
              hover:text-grey-700 hover:bg-grey-100
            `}
            onClick={handleClose}
          >
            Cancelar
          </button>
  
          <button
            className="bg-brandGreen text-greys-0 px-3 py-1 rounded-full"
          >
            Opinar
          </button>
        </div>
      </div>
    );
  };

  return (
    <div className="flex flex-col">
      <div
        className={`
          flex flex-row items-center space-x-2
          ${isOpen ? 'visible' : 'hidden'}
        `}
      >
        <div
          className="w-8 h-8 bg-brandGreen rounded-full"
        ></div>

        <span className="text-body-medium">Pedro Silva</span>
      </div>

      <ReactQuill
        theme="snow"
        value={value}
        onChange={setValue}
        placeholder={OPINION_PLACEHOLDER}
        modules={{
          toolbar: { container: '#toolbar' },
        }}
        onFocus={handleOpen}
      />

      <CustomToolbar />
    </div>
  )
}

So basically if isOpen is true, the toolbar should be rendered, otherwise it should not. The CustomToolbar only renders that div that contains className="space-x-3" but the div with the id "toolbar" does not render.

Important The toolbar div doesn't render just after the isOpen became false once (it means, once the div is "unmounted" so it won't mount again).

1

There are 1 answers

0
PedroB On BEST ANSWER

Funny. It's working after I did this:

{isOpen
  ? <CustomToolbar />
  : <div id="toolbar"></div>
}

Since React Quill always try to look for a "toolbar" id, the provided code always render a div with that id. It didn't work before but I think it was some cache lol