mirror of
https://github.com/ae-utbm/sith.git
synced 2025-05-05 00:54:06 +00:00
Create basic tooltip library
This commit is contained in:
parent
73e9c3132b
commit
273944f2a7
62
core/static/bundled/core/tooltips-index.ts
Normal file
62
core/static/bundled/core/tooltips-index.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { type Placement, computePosition } from "@floating-ui/dom";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library usage:
|
||||||
|
* Add a `tooltip` attribute to any html element with it's tooltip text
|
||||||
|
* You can control the position of the tooltp with the `position` attribute
|
||||||
|
* Allowed placements are `top`, `right`, `bottom`, `left`
|
||||||
|
* You can add `-start` and `-end` to all allowed placement values
|
||||||
|
**/
|
||||||
|
|
||||||
|
function getPlacement(element: HTMLElement): Placement {
|
||||||
|
const position = element.getAttribute("position");
|
||||||
|
if (position) {
|
||||||
|
return position as Placement;
|
||||||
|
}
|
||||||
|
return "bottom";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTooltip(element: HTMLElement) {
|
||||||
|
for (const tooltip of document.body.getElementsByClassName("tooltip")) {
|
||||||
|
if (tooltip.textContent === element.getAttribute("tooltip")) {
|
||||||
|
return tooltip as HTMLElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tooltip = document.createElement("div");
|
||||||
|
document.body.append(tooltip);
|
||||||
|
tooltip.classList.add("tooltip");
|
||||||
|
tooltip.innerText = element.getAttribute("tooltip");
|
||||||
|
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener("mouseover", (event: MouseEvent) => {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (!target.hasAttribute("tooltip")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tooltip = getTooltip(target);
|
||||||
|
tooltip.setAttribute("tooltip-status", "open");
|
||||||
|
|
||||||
|
computePosition(target, tooltip, {
|
||||||
|
placement: getPlacement(target),
|
||||||
|
}).then(({ x, y }) => {
|
||||||
|
Object.assign(tooltip.style, {
|
||||||
|
left: `${x}px`,
|
||||||
|
top: `${y}px`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.append(tooltip);
|
||||||
|
});
|
||||||
|
|
||||||
|
addEventListener("mouseout", (event: MouseEvent) => {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (!target.hasAttribute("tooltip")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTooltip(target).setAttribute("tooltip-status", "close");
|
||||||
|
});
|
@ -45,17 +45,10 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[tooltip] {
|
.tooltip {
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
[tooltip]::before {
|
|
||||||
@include shadow;
|
@include shadow;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
content: attr(tooltip);
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border: 0.5px solid hsl(0, 0%, 50%);
|
border: 0.5px solid hsl(0, 0%, 50%);
|
||||||
@ -64,44 +57,20 @@ body {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 500ms ease-out;
|
transition: opacity 500ms ease-in;
|
||||||
top: 120%; // Put the tooltip under the element
|
|
||||||
|
position: absolute;
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[tooltip]:hover::before {
|
.tooltip[tooltip-status=open] {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 500ms ease-in;
|
transition: opacity 500ms ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
[no-hover][tooltip]::before {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 500ms ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
[position="top"][tooltip]::before {
|
|
||||||
top: initial;
|
|
||||||
bottom: 120%;
|
|
||||||
}
|
|
||||||
|
|
||||||
[position="bottom"][tooltip]::before {
|
|
||||||
top: 120%;
|
|
||||||
bottom: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
[position="left"][tooltip]::before {
|
|
||||||
top: initial;
|
|
||||||
bottom: 0%;
|
|
||||||
left: initial;
|
|
||||||
right: 65%;
|
|
||||||
}
|
|
||||||
|
|
||||||
[position="right"][tooltip]::before {
|
|
||||||
top: initial;
|
|
||||||
bottom: 0%;
|
|
||||||
left: 150%;
|
|
||||||
right: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ib {
|
.ib {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
<script type="module" src="{{ static('bundled/alpine-index.js') }}"></script>
|
<script type="module" src="{{ static('bundled/alpine-index.js') }}"></script>
|
||||||
<script type="module" src="{{ static('bundled/htmx-index.js') }}"></script>
|
<script type="module" src="{{ static('bundled/htmx-index.js') }}"></script>
|
||||||
<script type="module" src="{{ static('bundled/country-flags-index.ts') }}"></script>
|
<script type="module" src="{{ static('bundled/country-flags-index.ts') }}"></script>
|
||||||
|
<script type="module" src="{{ static('bundled/core/tooltips-index.ts') }}"></script>
|
||||||
|
|
||||||
<!-- Jquery declared here to be accessible in every django widgets -->
|
<!-- Jquery declared here to be accessible in every django widgets -->
|
||||||
<script src="{{ static('bundled/vendored/jquery.min.js') }}"></script>
|
<script src="{{ static('bundled/vendored/jquery.min.js') }}"></script>
|
||||||
|
26
package-lock.json
generated
26
package-lock.json
generated
@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alpinejs/sort": "^3.14.7",
|
"@alpinejs/sort": "^3.14.7",
|
||||||
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
||||||
|
"@floating-ui/dom": "^1.6.13",
|
||||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||||
"@fullcalendar/core": "^6.1.15",
|
"@fullcalendar/core": "^6.1.15",
|
||||||
"@fullcalendar/daygrid": "^6.1.15",
|
"@fullcalendar/daygrid": "^6.1.15",
|
||||||
@ -2162,6 +2163,31 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@floating-ui/core": {
|
||||||
|
"version": "1.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
|
||||||
|
"integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/utils": "^0.2.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/dom": {
|
||||||
|
"version": "1.6.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
|
||||||
|
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/core": "^1.6.0",
|
||||||
|
"@floating-ui/utils": "^0.2.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/utils": {
|
||||||
|
"version": "0.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||||
|
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-free": {
|
"node_modules/@fortawesome/fontawesome-free": {
|
||||||
"version": "6.7.2",
|
"version": "6.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alpinejs/sort": "^3.14.7",
|
"@alpinejs/sort": "^3.14.7",
|
||||||
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
||||||
|
"@floating-ui/dom": "^1.6.13",
|
||||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||||
"@fullcalendar/core": "^6.1.15",
|
"@fullcalendar/core": "^6.1.15",
|
||||||
"@fullcalendar/daygrid": "^6.1.15",
|
"@fullcalendar/daygrid": "^6.1.15",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user