Skip to content

Upgrade Tippy.js 2.x to latest and rewrite integration #1

@Ambient-Impact

Description

@Ambient-Impact

The current integration was written years ago for Tippy.js 2.x; since then, Tippy has released several major versions, with the latest at the time of writing being 6.3.7, and my skills and knowledge of object-oriented programming best practices has come a long way; this would be a good opportunity to completely rewrite the integration as JavaScript class(es) and clean up/remove what's no longer needed to simplify it.

Tasks for basic implementation

  • Upgrade dependencies:
    • tippy.js:^2.6.0 to tippy.js:^6.3.7
    • popper.js:^1.15.0 to @popperjs/core:^2.11.8
  • Rewrite integration; features to be ported over:
    • Automatic title attribute use (Tippy.js no longer does this automagically)
    • Hide on ESC key
    • Hide on out of bounds

Follow up

Discussion

After implementing and refining this somewhat, a few issues have become apparent:

  1. The classes we create barely have a reason for existing; they primarily just wrap the Tippy.js initialization but otherwise don't do anything that can't just be done by setting our plug-ins and defaults via tippy.setDefaultProps()
  2. We're still setting a bunch of defaults in the component that probably makes more sense in a theme that implements this.

So we have some possible paths forward:

  1. We could keep the classes, merge them into a single class, and give it a reason to exist by having it wrap event delegation and creating singletons by searching for data attributes within the provided container:
    • data-tippy-singleton-group="group-name" could be used to automagically create singletons, grouped by a group name.
    • data-tippy-delegate or similar could be set on the container (or maybe a subtree? That might be too complicated) to define an event delegation container. This is mostly useful for performance reasons, as Drupal behaviours already allow us to attach to DOM elements added later via Ajax and other means.
  2. Or we could completely remove the classes, not set any defaults, and just provide the plug-ins for a theme to use.

Additional features

  • Housekeeping: move each plug-in to its own JavaScript file, wrapped in a component callback, and have them automatically add themselves to the default set of plug-ins; main tooltip component should not depend on them.
  • Plug-in: HTML content from data attribute; should be able to safely decode HTML entities while protecting against XSS exploits
  • Plug-in: hide on blur plug-in
  • Plug-in: trigger events on all callbacks
  • Plug-in: shrink wrap; this is either impossible or nearly impossible using CSS alone, as the container doesn't seem to know that text has wrapped with space left on one side:
  • Add custom properties to allow themes to specify viewport padding for placing tooltips; see Popper v2 overflow docs.
  • Plug-in: placement fallback as shorthand for Popper fallback placements
  • Plug-in: hoverIntent instead of Tippy.js mouse triggers
  • Plug-in: Background contrast-aware tooltip theme switching:
    • Would choose a light or dark theme based on the background colour of the reference element or nearest container.
    • I.e. on a dark background, chooses light theme, and on a light background chooses dark theme. This can be configurable so you can choose what theme gets set in each case.
    • Can use the existing light/dark Sass framework as that already has the capability to distinguish between light and dark, so it can be extended to output a custom property (e.g. --background-colour-type) with a value of light or dark, which can then be read in JavaScript; this would allow inheriting/cascading so it can be anywhere up the tree from the reference element.
    • This is initially useful for Omnipedia, but seems like it would be useful for other projects too.

Links

Sub-issues

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions