slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
43.18k stars 3.35k forks source link

How can I show the toolbar programmatically #3856

Closed artknight closed 12 months ago

artknight commented 1 year ago

I am currently running QuillJS v2.0.0-dev.4. According to the docs, I should be able to do something along these lines

const quill = new Quill($target[0]);

function openToolbar(range, context){
   //what code goes here?
}

quill.keyboard.addBinding({ key:'/' }, openToolbar);

In other words, when a user presses the / (forward slash) key on the keyboard, I need to open the QuillJS toolbar. Right now the only way to open that toolbar is by selecting something inside the editor. Screenshot attached.

enter image description here

What is the code that needs to go into the openToolbar function?

MMMJB commented 1 year ago

This did the trick for me:

// Import quill
import { Range } from "quill/core/selection";

// Initialize quill

const e = quill.theme.tooltip; // Bubble popup;

const openToolbar = (_) => {
  const range = quill.getSelection(); // Current cursor position
  const collapsed = range.length === 0;

  // https://github.com/quilljs/quill/blob/e33f352b9ede51759cb3d616835d1e1e80694251/themes/bubble.ts#L37
  e.show();

  e.root.style.left = "0px";
  e.root.style.width = "";
  e.root.style.width = `${e.root.offsetWidth}px`;
  const lines = quill.getLines(range.index, collapsed ? 1 : range.length);
  if (lines.length === 1) {
    const bounds = quill.getBounds(range);
    if (bounds != null) {
      e.position(bounds);
    }
  } else {
    const lastLine = lines[lines.length - 1];
    const index = quill.getIndex(lastLine);
    const length = Math.min(
      lastLine.length() - 1,
      range.index + range.length - index
    );
    const indexBounds = quill.getBounds(new Range(index, length));
    if (indexBounds != null) {
      e.position(indexBounds);
    }
  }
};

const closeToolbar = (r, o, s) => {
  if (r !== null && r.length > 0 && s === "user")
    // https://github.com/quilljs/quill/blob/develop/ui/tooltip.ts#L29
    e.root.classList.add("ql-hidden");
};

quill.keyboard.addBinding({ key: "/" }, openToolbar);
quill.on("selection-change", closeToolbar);

Note that this approach will never allow the character "/" to be typed. Consider changing the keyboard shortcut to ctrl + /.

artknight commented 1 year ago

@MMMJB Thanks for getting back to me!. I actually had something similar implemented, including the ctrl + / shortcut (great minds think alike ... LOL). However, my code ended up being much shorter than yours.

//this opens the editor toolbar when 'ctrl+/' is pressed
quill.keyboard.addBinding({ key:'/', ctrlKey:true }, (range, context) => {
    quill.theme.tooltip.edit();
    quill.theme.tooltip.show();
});
MMMJB commented 1 year ago

Wow, well done! Most of the complexity in my solution came from centering the toolbar around the selection, but if that's unnecessary, then hats off to you.

artknight commented 1 year ago

@MMMJB Hey, this is prob not the best place to ask this, but do you know of any table plugin I can use in Quill. I ended up using this one - https://github.com/soccerloway/quill-better-table - but its pretty buggy.

Thanks :)

MMMJB commented 1 year ago

@artknight No clue. A quick google search says it's a built-in module on 2.0 (example here), but it seems like it's still in development and/or I'm misinterpreting it's implementation.

artknight commented 1 year ago

I did see that. That table implementation is pretty sad, you can't even add a second row inside the table cell.. Anyways, thanks

MMMJB commented 1 year ago

That does seem to be the case with most Quill modules sadly... good luck on the rest of your project, though :)