react-quill icon indicating copy to clipboard operation
react-quill copied to clipboard

Toolbar requires double click to disable button...?

Open slashwhatever opened this issue 6 years ago • 11 comments

Here's my relatively simple setup (cut down code shown but this code exhibits the exact same issue I'm having):

import React, { Component } from 'react';
import ReactQuill from 'react-quill';

class RulesPanel extends Component {
  constructor(props) {
    super(props);
    this.displayName = 'RulesPanel';
    this.onChangeRulesText = this.onChangeRulesText.bind(this);
  }
  onChangeRulesText(value) {
    this.onChange({ rules: { text: value } });
  }
  render() {
    return (
      <div className="rules-text__editor-container">
        <ReactQuill
          className="ck inverted hasToolbar"
          theme="snow"
          formats={RulesPanel.formats}
          modules={RulesPanel.modules}
          value={this.props.rulesConfig.text}
          onChange={this.props.onChangeRulesText}
        />
      </div>
    );
  }
}

RulesPanel.modules = {
  toolbar: [
    [{ header: [1, 2, 3, false] }],
    ['bold', 'italic', 'underline', 'strike'],
    [{ list: 'ordered' }, { list: 'bullet' }],
    ['link'],
    [{ align: [] }],
    ['clean'],
  ],
  clipboard: {
    matchVisual: false,
  },
};

RulesPanel.formats = [
  'header',
  'font',
  'size',
  'bold',
  'italic',
  'underline',
  'strike',
  'blockquote',
  'list',
  'bullet',
  'indent',
  'link',
  'image',
  'color',
  'align',
];

export default RulesPanel;

Looks pretty normal, right?

Only issue I'm having is that for some reason, disabling any format option on the toolbar requires a double click - not a single click as per all the demo code and I've no idea why!

Applying formatting works on a single click as expected but to remove that same formatting, a single click won't do anything - it has to be a double click.

Not sure if this is a bug, an undocumented feature I missed or even a well documented feature I skimmed past....?

EDIT: after some testing, I've noticed this behaviour only happens when the Quill instance is in a Modal. The change event doesn't get fired on single clicks when the Quill instance is in a Modal. As far as I can tell, it's something to do with the attach method of Toolbar. At line 81 when checking for the active class, it's not there on the element when used in a Modal. Double clicking presumably forces a race condition to work out in our favour.

slashwhatever avatar May 15 '18 10:05 slashwhatever

I'm having a very similar problem, also in a modal. However, I cannot disable format options at all, neither single nor double click work.

Did you find any solution/workaround?

darioseidl avatar Oct 09 '18 13:10 darioseidl

I am also facing the same problem. Any Solution to it?

dewanhimanshu avatar Jan 11 '19 11:01 dewanhimanshu

I haven't found a solution yet. We're still using Quill but with a custom toolbar definition in a slightly altered use case.

No doubt I'll come back and address this more complex use case at some point.

slashwhatever avatar Jan 11 '19 11:01 slashwhatever

@slashwhatever thank you for your response . Can me how to use with custom toolbar so i can use quill . I will be highly obliqued if you could share code snippet for it.

dewanhimanshu avatar Jan 11 '19 13:01 dewanhimanshu

Bear in mind the following code block was very quickly hacked out from our working code. It's not likely to work as it is without additional work, but it should give you some idea of how to get started.

This example shows a Quill component with a custom toolbar of one button that adds and removes a custom tag to the selected text in the component. In our platform, this works fine in a modal without the double click issues we've seen with the standard toolbar.

import React from 'react';
import ReactQuill, { Quill } from 'react-quill';

import MyButton from './components';

// *** add your custom Blots to Quill
const Inline = Quill.import('blots/inline');

class CustomTag extends Inline {
  static blotName = 'custom-tag';
  static tagName = 'custom-tag';
}

Quill.register(CustomTag);

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleButtonClick = this.handleButtonClick.bind(this)
  }
  handleButtonClick() {
    maybeApplyFormat(this.refs.quillEditorRef.getEditor(), 'custom-tag');
  }
  render() {
    return (
      <div className="quill__editor-container">
        <CustomToolbar
          handleButtonClick={this.handleButtonClick}
        />
        <ReactQuill
          className="my-quill"
          theme={null}
          ref="quillEditorRef"
          formats={['custom-tag']}
          modules={modules}
          defaultValue=""
          onChange={this.props.onChange}
        />
      </div>
    );
  }
};

const CustomToolbar = ({ handleButtonClick }) => (
  <div id="toolbar" className="editor-toolbar">
    <div className="ql-insertCustomTag">
      <MyButton
        text="Custom Tag"
        onClick={handleButtonClick}
      />
    </div>
  </div>
);

// checks the selected text has some length > 0 and applies the relevant formatting
const maybeApplyFormat = (quill, format) => {
  const sel = quill.getSelection();
  const length = sel ? sel.length : 0;
  const hasFormat = quill.getFormat()[format];
  if (length > 0) {
    quill.removeFormat(quill.getSelection());
    quill.format(format, !hasFormat);
  }
};

const modules = {
  toolbar: {
    container: '#toolbar',
  },
  clipboard: {
    matchVisual: false,
  },
};

export default MyComponent;

slashwhatever avatar Jan 11 '19 14:01 slashwhatever

Thank You for your Help

dewanhimanshu avatar Jan 17 '19 09:01 dewanhimanshu

We are also facing this problem. Activating "bold" needs one click, disabling needs double click.

laurisbernhart avatar Jan 21 '19 16:01 laurisbernhart

We are also facing this problem. Activating "bold" needs one click, disabling needs double click.

Which browser and what CSS are you using? We are seeing this behaviour in Google Chrome, albeit not with react-quill but with React and Quill separately. It looks like the button behaviour is affected by the ### user-select CSS property. We have user-select: none in our application and user-select: text for the div surrounding the Quill editor. Then we get this behaviour. If the latter is changed to user-select: auto the behaviour is as expected.

jaapspiering avatar Feb 14 '19 07:02 jaapspiering

@jaapspiering Thanks for the hint!

We also have user-select: text on our modal that contains the quill editor, and setting that to user-select: none or user-select: auto fixes the problem in Chrome like you said.

~~It still doesn't work in Firefox for us, with neither single nor double click.~~ Nevermind. There was another -moz-user-select somewhere.

(I haven't tested anything else yet.)

darioseidl avatar Feb 14 '19 11:02 darioseidl

Which browser and what CSS are you using? Chrome v72

@jaapspiering user-select: auto; fixed it! Thank you!!

laurisbernhart avatar Feb 16 '19 06:02 laurisbernhart

Just updating this issue, in case someone else needs a fix for this issue when the editor is not in a modal.

I managed to fix the toolbar behavior by following the comments on this issue: https://github.com/quilljs/quill/issues/1290

I simply added the following useEffect to my editor component:

useEffect(() => {
    document.querySelector('.ql-toolbar').addEventListener('mousedown', (e) => {
      e.preventDefault();
    });
  }, []);

Hope it helps.

joaomotaalmeida avatar Jun 05 '23 14:06 joaomotaalmeida