quill icon indicating copy to clipboard operation
quill copied to clipboard

Custom toolbar: buttons mouse clicks get broken if Quill is re-instantiated

Open ViktorZhurbin opened this issue 1 year ago • 3 comments

When Quill editor with a custom toolbar is re-instantiated, toolbar buttons get new event listeners added on top of each other, breaking mouse click behaviour.

In our setup, modules need to be updated based on user preferences, which requires re-instantiating Quill, afaik. I opened #4234 to check if it can be avoided, but this current issue seems like a separate bug.

My guess is that since these listeners are added as anonymous functions they are added each time editor is instantiated, rather than being ignored (reference)

Steps for Reproduction

Here's a demo

https://github.com/slab/quill/assets/34838167/ebf4de7c-a2d0-4e34-ba4e-063bbdcfae91

  1. Visit quilljs playground
  2. Click "Re-create" button
  3. Try to mouse-click any formatting button in toolbar
  4. Check event listeners in dev tools

Expected behavior: Format buttons work as usual

Actual behavior: Format buttons can't be toggled

Platforms: Chrome 125.0.6422.141, MacOS

Version: 2.0.2

ViktorZhurbin avatar Jun 04 '24 14:06 ViktorZhurbin

I'm also experiencing this issue in my own code. However, when I try your example @ViktorZhurbin it seems to work for me (in Firefox)? In my own code I experience this issue on Firefox.

This also sounds similar to #4360

elindgren avatar Aug 08 '24 07:08 elindgren

Quill seems to use eventemitter3 for the event listeners, which states that it should remove all event listeners when off is called. However, that does not seem to happen for some reason?

elindgren avatar Aug 08 '24 07:08 elindgren

This also a problem in case you use Quill with React. Since listeners are not cleared, in StrictMode the toolbar will be broken because quill is being initialized twice.

Possible solution until they fix: when you need to re-initialize quill, clone your sidebar using node.clone(true) and replace it with the clone - event listeners will be cleared

osx11 avatar Aug 22 '24 13:08 osx11

In my case using React StricMode leads to toolbar rendering twice. I'm a bit newbie to React so not sure if related. Solved checking if the Quill ref already exists:

function QuillEditorComponent({ value, onChange }) {
  const quillRef = useRef(null); 
  const quillInstance = useRef(null); 

  useEffect(() => {
    // Ensure Quill is only initialized once
    if (quillRef.current.className === 'ql-container ql-snow') return;

    // Initialize Quill instance
    quillInstance.current = new Quill(quillRef.current, {
      theme: 'snow', // Use the "snow" theme
      placeholder,
      modules: {
        toolbar: [
          ['bold', 'italic', 'underline', 'strike'],
          [{ list: 'ordered' }, { list: 'bullet' }],
        ],
      },
    });
// ...

luismisanchez avatar Feb 19 '25 12:02 luismisanchez