atomiks / tippyjs

Tooltip, popover, dropdown, and menu library
https://atomiks.github.io/tippyjs/
MIT License
11.93k stars 520 forks source link

"update" option needed for instances that has data-attributes inside dynamic DOM #490

Closed 7iomka closed 5 years ago

7iomka commented 5 years ago

Hi. I used your plugin inside content of slides of a slider (I used flickity). This slider when DOM is ready changes default html layout to another (wrap my layout to needed for slider works). I think that cause this kind of issue: all my tippy instances seems like working fine, except the options that declared from data attributes is not applied. It is possible to make an option like "update", that uses existing _.tippy instance to re-apply options defined in data-attributes? Thanks, and sorry for my english)

atomiks commented 5 years ago

You can coalesce the data-tippy-* into an object to pass into set() like this:

const keys = Object.keys(tippy.defaults);

function getDataAttributeOptions(reference) {
  return keys.reduce((acc, key) => {
    const valueAsString = (
      reference.getAttribute(`data-tippy-${key}`) || ''
    ).trim()

    if (!valueAsString) {
      return acc
    }

    if (key === 'content') {
      acc[key] = valueAsString
    } else {
      try {
        acc[key] = JSON.parse(valueAsString)
      } catch (e) {
        acc[key] = valueAsString
      }
    }

    return acc
  }, {})
}

element._tippy.set(getDataAttributeOptions(element))
7iomka commented 5 years ago

You can coalesce the data-tippy-* into an object to pass into set() like this:

used your code but it did nothing. I have a trigger in the defaults

tippy.setDefaults({
trigger: 'click',
});

and in my particular case, I redefined this behavior by setting the data-tippy-trigger='mouseenter focus' As before the installation of your code when my vendor slider is ready (dom manipulation's finished) and after it remains => works default behavior by clicking!

atomiks commented 5 years ago

Okay, you haven't shown your code so I don't know what you're doing

7iomka commented 5 years ago

OK. UPDATED I maked demo video with samples of my code. https://drive.google.com/open?id=1I9i5dSY7EqHCU_k3UD03PEPeIWn7UuLI In this demo I demonstrated you my problems: 1) When DOM is changed after tippy is initialized, all initialized instances will lose their finally computed options (defaults extended by data-attributes) and only setted in defaults will remain 2) Is optional (is off of this issue), but - it is possible to make individual groups of tippy instances? In my design I have multiple sliders, and need to always be open at least one tooltip (in the active slide). How to do that? I also need to when I click somewhere (inclusive current item) the tooltip does not hide. 3) In responsive mode slides is in transition (in the demo video is also seen). It is possible somehow to update tippy position? In my case, I cannot bind tippy to an slide container because the container of slider has overflow:hidden; At the moment - the only workaround is to write additional event-handlers that will run the tippyInstance.show() then when the position of the slide stopped moving.

Thanks for any help!

atomiks commented 5 years ago

From what I could make out from that video:

  1. I think you need to move my code inside the change callback, rather than ready
  2. Use hideOnClick: false if you won't want those open tooltips to hide when clicking somewhere on the document
  3. For the position, it should update already by default.. if not, you can use instance.popperInstance.update() to programmatically update the position
7iomka commented 5 years ago
  1. I think you need to move my code inside the change callback, rather than ready

I will make your demo on codepen or another source-site for demo of problem, if is hard for understand from video demo.

2. Use hideOnClick: false if you won't want those open tooltips to hide when clicking somewhere on the document

Hide on click prevents closing all tooltips! I need to have a group of tooltips, to make possible to toggle one of them in group (only one in group is shown). Current posibilites is, to show only one tooltip per page, or all tooltips without closing it.

3. For the position, it should update already by default.. if not, you can use instance.popperInstance.update() to programmatically update the position

Ok, thanks, I will try.

atomiks commented 5 years ago

If you can post a reproducing example I can reopen this. Unfortunately there's not much to go on for me at the moment