Using Tippy.js with Turbolinks
Tippy.js is a nice library to show popups. It may, however, not always be obvious how to use Tippy.js with Turbolinks (or any other library that modifies the DOM). The basic ingredient is somewhat hidden in the docs: deffered
. But loading a HTML template requires a slight adaptation of what is presented in their documentation to make loading of these templates deferred.
From beginning to start. Add the library:
$ yarn add tippy.js
Add a CSS-class for your templates to be hidden by default:
.tippy-template-content {
display: none;
}
And then add the following to your application.js (or equivalent in your setup):
import {delegate} from 'tippy.js';
delegate('html', {
content(reference) {
const id = reference.getAttribute('data-tippy-template');
if (id) {
const template = document.getElementById(id);
return template.innerHTML;
}
},
allowHTML: true,
target: "*[data-tippy-content],*[data-tippy-template]",
});
This does the following:
- bind tippy using
delegate
to thehtml
element, which is present while the javascript is being parsed. It will then make tippy work for all elements with either the data attributedata-tippy-content
or alternatively thedata-tippy-template
attribute (as seen in thetarget
-property). - add a
content
-method (instead of a property) to the configuration, which uses thedata-tippy-template
attribute to present the content. We have to check for the existence of a template id-reference, as at first run it tries to get thedata-tippy-template
from thehtml
-tag. - allow for HTML (warning: always sanitise HTML before inclusion in the DOM)
Our HTML can now look like this:
<button data-tippy-template="tippy-content-a3ffa">
<div id="tippy-content-a3ffa" class="tippy-template-content">
<h3>Tippy content</h3>
<p>With <strong>HTML</strong>!</p>
</div>
Further fine tuning can be done via the button’s data-attributes.