3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger

3 horizontal lines, burger
Remove all
LOADING ...

Content



    Quill tooltip, how to make your own. Example on links

    Clock
    25.10.2024
    /
    Clock
    11.03.2026
    /
    Clock
    4 minutes
    An eye
    3072
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0

    How quill tooltip works, introduction

    It's time to tell you how to make your own tooltip. And first, let's find out how the tooltip from quill works.
    All Quill tooltips are inherited from the common BaseTooltip class. What should concern me, and you in particular, are the following lines of code:
    save() { let { value } = this.textbox; switch (this.root.getAttribute('data-mode')) { case 'link': { ... } case 'video': { ... } case 'formula': { ... } default: } // @ts-expect-error Fix me later this.textbox.value = ''; this.hide(); } }
    I don't like them very much. Why? I just don't see a way to organically add a new tooltip or extend the old one. I myself have been tormented for a long time and wondered how I could extend an existing class. But the only way I came to was to inherit not from BaseTooltip but from Tooltip class.
    Another option is to create your own theme. After all, the Quill tooltip is not a module (which would actually be more logical, in my opinion), but a part of the theme. And there are two themes: snow and bubble. But again, for me, this is too much work, just to show one extra window on the screen.
    Honestly, my solution to the problem is not elegant at all. But it works ¯\_(ツ)_/¯. And I'm going to show it to you anyway ;)

    Developing a custom quill tooltip

    As you already know (and if you don't, you can find out (☞゚ヮ゚)☞), my html editor has three types of links: internal, external and downloadable. External leads to other pages. Internal leads to other parts of the same page. Downloadable, well ... these are just links to files that can be downloaded ???
    Let's create new blots using inline format. Please note, I do not inherit from 'formats/link' !!! The thing is, this format has a default tooltip attached to it, and I do not need the extra fuss created by this tooltip.
    Instead, I created custom blots and registered new formatters for them. I also added click handlers for links. They cause the creation, or rather, the appearance of the tooltip.
    class InternalLink extends Quill.import('blots/inline'){ constructor(scroll, domNode){ super(scroll, domNode); domNode.addEventListener('click', (ev) => { domNode.setAttribute('ref', 'me') let tooltip = new LinkTooltip(quill, this.domNode, '#ID_SOME') tooltip.setHeight(document.querySelector('footer').getBoundingClientRect().height) tooltip.show() }) } } InternalLink.tagName = 'a' InternalLink.className = 'ref-int' InternalLink.blotName = 'internal-link' Quill.register({'formats/internal-link': InternalLink}) class DownloadableLink extends Quill.import('blots/inline'){ constructor(scroll, domNode){ super(scroll, domNode); domNode.setAttribute('ref', 'me') domNode.addEventListener('click', (ev) => { let tooltip = new LinkTooltip(quill, this.domNode, '?') tooltip.setHeight(document.querySelector('footer').getBoundingClientRect().height) tooltip.show() tooltip.root.querySelector('input').remove() tooltip.root.querySelector('.add_button').remove( ) }) } } DownloadableLink.tagName = 'a' DownloadableLink.className = 'ref-downloadable' DownloadableLink.blotName = 'downloadable-link' Quill.register({'formats/downloadable-link': DownloadableLink}) class ExternalLink extends Quill.import('blots/inline'){ constructor(scroll, domNode){ super(scroll, domNode); domNode.setAttribute('target', '_blank') domNode.setAttribute('ref', 'noreferrer nofollow external') domNode.addEventListener('click', (ev) => { let tooltip = new LinkTooltip(quill, this.domNode, 'http(s)://website.com') tooltip.setHeight(document.querySelector('footer').getBoundingClientRect().height) tooltip.show() }) } } ExternalLink.tagName = 'a' ExternalLink.className = 'ref-ext' ExternalLink.blotName = 'external-link' Quill.register({'formats/external-link': ExternalLink})
    A little more about position and height. I use CSS styles to control the position on the screen. In case you wish to see this style, here they are:
    .link-tooltip{ display: flex; flex-wrap: wrap; align-items: center; gap: var(--min_pm); position: fixed !important; bottom: 0; left: 0; background-color: var(--main_color) !important; width: 100%; color: white !important; transform: translateY(0px) !important; z-index: 3; }
    I set the height because I wanted it to overlap the "sticky" footer. You do not have to do this.
    Now we can move on to the tooltip itself. What does it consist of, what are its features, etc. I created my tooltip by analogy with BaseTooltip. Therefore, many methods are purely for internal use. Here it is:
    class LinkTooltip extends Quill.import('ui/tooltip'){ static create(value){ let node = super.create(value) return node } static remove(){ let prev = document.querySelector('.link-tooltip') if (prev){ prev.remove() } } constructor(scroll, domNode, placeholder = ''){ let prev = document.querySelector('.link-tooltip') if (prev){ prev.remove() } super(scroll, domNode); this.textbox = null this.root.innerText = "" this.root.classList.add('link-tooltip') this.insertTextInput(placeholder) this.insertAddBtn() this.insertRemoveBtn() } insertTextInput(placeholder){ this.textbox = document.createElement('input') this.textbox.setAttribute('type', 'text') this.textbox.placeholder = placeholder this.textbox.addEventListener('keydown', (event) => { if (event.key === 'Enter') { this.save(this); event.preventDefault(); } else if (event.key === 'Escape') { this.cancel(); event.preventDefault(); } }); this.root.insertAdjacentElement('beforeend', this.textbox) } insertAddBtn(){ let add = document.createElement('div') add.classList.add('add_button') add.classList.add('text_button') add.innerText = document.querySelector('#save_text').innerText add.addEventListener('click', () => {this.save(this)}) this.root.insertAdjacentElement('beforeend', add) } insertRemoveBtn(){ let add = document.createElement('div') add.classList.add('remove_button') add.classList.add('text_button') add.innerText = document.querySelector('#remove_text').innerText add.addEventListener('click', () => {this.remove(this)}) this.root.insertAdjacentElement('beforeend', add) } cancel() { this.hide(); this.restoreFocus(); } restoreFocus() { this.quill.focus({ preventScroll: true }); } remove(tooltip){ let text = tooltip.boundsContainer.innerText tooltip.boundsContainer.outerHTML = text tooltip.hide(); LinkTooltip.remove(); } setHeight(height){ this.root.style.height = `${height}px` } }
    The constructor defines the shape, height, and structure of the tooltip. I want to note that the original tooltip (from quill) defines its structure using a static member of the class called TEMPLATE , which is located in https://github.com/slab/quill/blob/main/packages/quill/src/themes/snow.ts. I decided that I needed a more modular system. (Yes, by modular system I meant those 3 pathetic functions for creating buttons ¯\(°_o)/¯) Here they are:
    1. insertRemoveBtn
    2. insertAddBtn
    3. insertTextInput
    The save and remove functions were also redefined. This is how my tooltips work in the editor. Not pretty, not elegant, but they work. I hope this example was useful to you and you learned at least something from it.

    Do not forget to share, like and leave a comment :)

    Comments

    (0)

    captcha
    Send
    LOADING ...
    It's empty now. Be the first (o゚v゚)ノ

    Other

    Similar articles


    All about quill blots, blocks and how to make a custom blot

    Clock
    24.10.2024
    /
    Clock
    11.03.2026
    An eye
    7921
    Hearts
    0
    Connected dots
    0
    Connected dots
    1
    Connected dots
    0
    In this article, I will tell you about kinds of quill blots and quill blocks, their differencies, how they are used (including an examples of realisation those blots, blocks). Also, …

    Custom toolbar button, how to make for quill editor

    Clock
    25.10.2024
    /
    Clock
    11.03.2026
    An eye
    5416
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article I will show you how to create custom buttons for your quill editor. You will also learn how to add a drop-down list for the same quill …

    How to make custom quill module – table of content as an example

    Clock
    29.10.2024
    /
    Clock
    11.03.2026
    An eye
    2890
    Hearts
    0
    Connected dots
    0
    Connected dots
    4
    Connected dots
    0
    In this article I will show how to make custom quill module for an editors. This module will generate the table of contents of the article. I will also show …

    Used termins


    Related questions