Implement tooltip component
You are required to Implement an Tooltip component.
A tooltip
is a floating, non-actionable informative label used to explain a UI element or feature. It's appears when users hover over, focus on, or tap an element.
This is initial structure of HTML:
<div data-tooltip="Name description">Hi, my name is John</div>
Requirements:
- Show tooltip on hover on element with attribute
data-tooltip
- Maintain multiple tooltips per page
- Take content of the toolitp from
data-tooltip
attribute. It could be HTML - Optimisations
- Show tooltip with some delay, e.g. 500ms
Solution
<style>
[data-tooltip] {
text-decoration: underline;
cursor: help;
}
[role="tooltip"] {
opacity: 0;
position: absolute;
width: auto;
height: auto;
}
[role="tooltip"].active {
opacity: 1;
transform: translateX(-50%); /* Center tooltip according parent element*/
}
</style>
<div>
Many species of gecko have
<span data-tooltip="Hi there!">adhesive</span> toe pads which enable them to climb walls and even windows.
</div>
const tooltips = document.querySelectorAll("[data-tooltip]");
const DELAY = 300;
let tooltipTimer = null;
const createTooltip = (target) => {
let tooltip = document.createElement("div");
tooltip.setAttribute("role", "tooltip");
tooltip.setAttribute("inert", true);
tooltip.textContent = target.dataset.tooltip;
target.appendChild(tooltip);
};
const displayTooltip = (evt) => {
const target = evt.target;
const tooltip = target.querySelector("[role=tooltip]");
// Get the target element's position and dimensions
const { x, y, width, height } = target.getBoundingClientRect();
// Set the tooltip position to be centered above the target element
tooltip.style.left = `${Math.floor(x + width / 2)}px`;
tooltip.style.top = `${Math.floor(y + height)}px`;
tooltip.classList.add("active");
};
const hideTooltip = (evt) => {
const tooltip = evt.target.querySelector("[role=tooltip]");
tooltip.classList.remove("active");
};
tooltips.forEach((target) => {
createTooltip(target);
target.addEventListener("mouseenter", (e) => {
clearTimeout(tooltipTimer);
tooltipTimer = setTimeout(() => {
displayTooltip(e);
}, DELAY);
});
target.addEventListener("mouseleave", (e) => {
clearTimeout(tooltipTimer);
hideTooltip(e);
});
});