components/tooltip/tooltip.ts
50 lines and 8 functions in DrDustinEdwards/capsomer, at commit d3966cc on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| attach | 17 to 28 | 4 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:24> | 24 to 27 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| showTip | 31 to 34 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| hideTip | 35 to 38 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| enhance | 42 to 55 | 4 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:49> | 49 to 52 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:54> | 54 to 54 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:54> | 54 to 54 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
Imports
It imports components/popover/popover.ts. Imported by components/admin-shell/admin-shell.react.tsx, components/admin-shell/admin-shell.ts, components/admin-shell/examples.tsx, components/site-header/site-header-parts.react.tsx, components/site-header/site-header.ts, components/theme-switch/theme-switch.react.tsx, components/theme-switch/theme-switch.ts, components/tooltip/tooltip.react.tsx.
Source
// A tooltip: extra detail about a control, never the only place its label appears. It is the
// shared popover's tooltip variant (components/popover): the Popover API (popover="manual",
// role="tooltip"), shown on hover after 300 ms (at once when another tip is open or has just
// closed) and on keyboard focus, hidden on Esc, on blur and when the pointer leaves, and the
// pointer can move onto it without it closing (WCAG 1.4.13: dismissible, hoverable,
// persistent). This module keeps the 0.1 contract on top of it: a trigger names its tip with
// data-cap-tip="<id>", and attach(trigger, tip) wires one pair.
import { attach as attachPopover, close, open } from "../popover/popover.ts";
export { HIDE_GRACE_MS, SHOW_DELAY_MS, place, supportsAnchor } from "../popover/popover.ts";
const tips = new WeakMap<HTMLElement, HTMLElement>();
// Wires one trigger to its tip: the tip gets the popover surface (cap-popover, the tooltip
// variant), popover="manual" and role="tooltip", and the trigger aria-describedby. Returns a
// function that unwires it.
export function attach(trigger: HTMLElement, tip: HTMLElement): () => void {
tip.classList.add("cap-popover");
tip.dataset.variant ??= "tooltip";
if (!tip.hasAttribute("popover")) tip.setAttribute("popover", "manual");
if (!tip.getAttribute("role")) tip.setAttribute("role", "tooltip");
tips.set(trigger, tip);
const detach = attachPopover(trigger, tip);
return () => {
detach();
tips.delete(trigger);
};
}
// Shows or hides the tip of a trigger that is attached.
export function showTip(trigger: HTMLElement): void {
const tip = tips.get(trigger);
if (tip) open(tip);
}
export function hideTip(trigger: HTMLElement): void {
const tip = tips.get(trigger);
if (tip) close(tip);
}
// Attaches to every [data-cap-tip] trigger under root not yet attached; the attribute's
// value is the id of its tip. Returns a function that detaches.
export function enhance(root: ParentNode = document): () => void {
const undo: Array<() => void> = [];
for (const trigger of root.querySelectorAll<HTMLElement>("[data-cap-tip]:not([data-cap-ready])")) {
const tip = document.getElementById(trigger.dataset.capTip ?? "");
if (!tip) continue;
trigger.dataset.capReady = "";
const detach = attach(trigger, tip);
undo.push(() => {
detach();
delete trigger.dataset.capReady;
});
}
return () => undo.forEach((f) => f());
}