Skip to content

Commit

Permalink
add tooltip to avatar
Browse files Browse the repository at this point in the history
  • Loading branch information
bseber committed Oct 25, 2024
1 parent 544a901 commit a50d0ad
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 4 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dependencies": {
"@duetds/date-picker": "1.4.0",
"@hotwired/turbo": "8.0.12",
"@popperjs/core": "2.11.8",
"@rollup/plugin-commonjs": "28.0.1",
"@rollup/plugin-node-resolve": "15.3.0",
"@tsconfig/svelte": "5.0.0",
Expand Down
5 changes: 4 additions & 1 deletion src/main/css/1-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

:root {
--navigation-header-height: 3rem;
--z-index-tooltip: 99999; /* tooltips shown on pointer hover should always be on top */

/* 500 */
--absence-color-GRAY: #6b7280;
Expand Down Expand Up @@ -33,7 +34,9 @@ textarea:not([class*="rounded"]) {

@font-face {
font-family: "KaushanScript";
src: local("KaushanScript"), local("KaushanScript Regular"),
src:
local("KaushanScript"),
local("KaushanScript Regular"),
local("KaushanScript-Regular"),
url("/fonts/kaushanscript/KaushanScript-Regular.woff2") format("woff2"),
url("/fonts/kaushanscript/KaushanScript-Regular.woff") format("woff");
Expand Down
1 change: 1 addition & 0 deletions src/main/css/2-components.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@import "./components/feedback.css";
@import "./components/navigation.css";
@import "./components/time-clock.css";
@import "./components/tooltip.css";

.sloth-background {
background-image: url("/images/sloths_1280.png");
Expand Down
21 changes: 21 additions & 0 deletions src/main/css/components/tooltip.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[role="tooltip"] {
@apply py-1 px-2;
@apply text-xs;
@apply font-bold;
@apply text-white;
@apply bg-gray-800;
@apply rounded;
@apply whitespace-nowrap;
@apply invisible;
@apply opacity-0;
@apply transition-opacity;
@apply duration-200;
@apply delay-300;
@apply ease-in;

&[data-show] {
@apply visible;
@apply opacity-100;
z-index: var(--z-index-tooltip);
}
}
25 changes: 23 additions & 2 deletions src/main/javascript/components/avatar/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { doGet } from "../../http";
import { Tooltip } from "../tooltip";

export class Avatar extends HTMLImageElement {
connectedCallback() {
const altText = this.getAttribute("alt");

if (this.complete) {
doGet(this.src).then((response) => {
if (!response.ok || (response.status >= 400 && response.status < 500)) {
this.#useFallback();
this.#useFallback().finally(() => this.addTooltip(altText));
}
});
} else {
this.addEventListener("error", () => this.#useFallback());
this.addEventListener("error", () =>
this.#useFallback().finally(() => this.addTooltip(altText)),
);
}

// add tooltip for the img element.
// fallback replaces the img element with a svg and finally adds the tooltip again.
this.addTooltip(altText);
}

async #useFallback() {
Expand All @@ -32,6 +41,18 @@ export class Avatar extends HTMLImageElement {
parent.replaceChild(t.content, this);
parent.querySelector("svg").classList.add(...clazzes);
}

private addTooltip(altText: string) {
if (altText) {
const tooltipText = document.createElement("p");
tooltipText.textContent = altText;

const tooltip = new Tooltip();
tooltip.append(tooltipText);

this.parentElement.append(tooltip);
}
}
}

customElements.define("z-avatar", Avatar, { extends: "img" });
1 change: 1 addition & 0 deletions src/main/javascript/components/tooltip/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./tooltip";
35 changes: 35 additions & 0 deletions src/main/javascript/components/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createPopper, type Instance } from "@popperjs/core";

const showEvents = ["mouseenter", "focus"];
const hideEvents = ["mouseleave", "blur"];

export class Tooltip extends HTMLDivElement {
private popperInstance: Instance;

constructor() {
super();
this.setAttribute("role", "tooltip");
}

connectedCallback() {
// don't know yet if this is cool or not using `this.parentElement` as popper reference element
const parent = this.parentElement;

this.popperInstance = createPopper(parent, this);

for (const event of showEvents) {
parent.addEventListener(event, () => {
this.dataset.show = "";
this.popperInstance.update();
});
}

for (const event of hideEvents) {
parent.addEventListener(event, () => {
delete this.dataset.show;
});
}
}
}

customElements.define("z-tooltip", Tooltip, { extends: "div" });
3 changes: 2 additions & 1 deletion src/main/resources/templates/fragments/avatar.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
Expand All @@ -11,6 +11,7 @@
src="#"
th:src="@{/invalid-avatar-url}"
alt=""
th:alt="${fullName}"
class="rounded-full"
th:classappend="${className}"
th:width="${width == null ? '32px' : width}"
Expand Down

0 comments on commit a50d0ad

Please sign in to comment.