aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Tooltip/LinkedTooltip.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Tooltip/LinkedTooltip.svelte')
-rw-r--r--src/lib/Tooltip/LinkedTooltip.svelte328
1 files changed, 179 insertions, 149 deletions
diff --git a/src/lib/Tooltip/LinkedTooltip.svelte b/src/lib/Tooltip/LinkedTooltip.svelte
index 4c90d9af..82147536 100644
--- a/src/lib/Tooltip/LinkedTooltip.svelte
+++ b/src/lib/Tooltip/LinkedTooltip.svelte
@@ -1,12 +1,12 @@
<script lang="ts">
-import tooltipPosition from '$stores/tooltipPosition';
-import { fade } from 'svelte/transition';
+import tooltipPosition from "$stores/tooltipPosition";
+import { fade } from "svelte/transition";
export let id: string | undefined = undefined;
export let pin: string | undefined = undefined;
export let content: string;
export let disable = false;
-export let pinPosition: 'top' | 'bottom' | 'left' | 'right' = 'top';
+export let pinPosition: "top" | "bottom" | "left" | "right" = "top";
export let offset = 10;
export let tooltipTransitionTime = 200;
export let tooltipHideDelay = 10;
@@ -21,178 +21,208 @@ let debounceTimer: number | null = null;
let opacity = 0;
const createTooltip = () => {
- if (!tooltipDiv) {
- tooltipDiv = document.createElement('div');
- tooltipDiv.style.position = 'absolute';
- tooltipDiv.style.zIndex = '1000';
- opacity = 0;
- tooltipDiv.style.pointerEvents = 'none';
- tooltipDiv.style.whiteSpace = 'nowrap';
-
- tooltipDiv.classList.add('card');
- tooltipDiv.classList.add('card-small');
- document.body.appendChild(tooltipDiv);
- }
+ if (!tooltipDiv) {
+ tooltipDiv = document.createElement("div");
+ tooltipDiv.style.position = "absolute";
+ tooltipDiv.style.zIndex = "1000";
+ opacity = 0;
+ tooltipDiv.style.pointerEvents = "none";
+ tooltipDiv.style.whiteSpace = "nowrap";
+
+ tooltipDiv.classList.add("card");
+ tooltipDiv.classList.add("card-small");
+ document.body.appendChild(tooltipDiv);
+ }
};
const updateTooltipPosition = (x: number, y: number) => {
- if (tooltipDiv) {
- if (pin) {
- const pinnedElement = document.getElementById(pin);
-
- if (pinnedElement) {
- const rectangle = pinnedElement.getBoundingClientRect();
- const parentRectangle = pinnedElement.offsetParent?.getBoundingClientRect();
- const tooltipWidth = tooltipDiv.offsetWidth;
- const tooltipHeight = tooltipDiv.offsetHeight;
- let top = 0;
- let left = 0;
-
- switch (pinPosition) {
- case 'top':
- if (relative && parentRectangle) {
- top = rectangle.top - tooltipHeight - offset - parentRectangle.top;
- left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2 - parentRectangle.left;
- } else {
- top = rectangle.top - tooltipHeight - offset;
- left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2;
- }
-
- break;
- case 'bottom':
- if (relative && parentRectangle) {
- top = rectangle.top + rectangle.height + offset - parentRectangle.top;
- left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2 - parentRectangle.left;
- } else {
- top = rectangle.top + rectangle.height + offset;
- left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2;
- }
-
- break;
- case 'left':
- if (relative && parentRectangle) {
- top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2 - parentRectangle.top;
- left = rectangle.left - tooltipWidth - offset - parentRectangle.left;
- } else {
- top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2;
- left = rectangle.left - tooltipWidth - offset;
- }
-
- break;
- case 'right':
- if (relative && parentRectangle) {
- top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2 - parentRectangle.top;
- left = rectangle.left + rectangle.width + offset - parentRectangle.left;
- } else {
- top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2;
- left = rectangle.left + rectangle.width + offset;
- }
-
- break;
- }
-
- if (relative && parentRectangle) {
- if (left + parentRectangle.left < 0) left = offset - parentRectangle.left;
- if (left + tooltipWidth + parentRectangle.left > window.innerWidth)
- left = window.innerWidth - tooltipWidth - offset - parentRectangle.left;
- if (top + parentRectangle.top < 0)
- top = rectangle.top + rectangle.height + offset - parentRectangle.top;
- if (top + tooltipHeight + parentRectangle.top > window.innerHeight)
- top = window.innerHeight - tooltipHeight - offset - parentRectangle.top;
- } else {
- if (left < 0) left = offset;
- if (left + tooltipWidth > window.innerWidth)
- left = window.innerWidth - tooltipWidth - offset;
- if (top < 0) top = rectangle.top + rectangle.height + offset;
- if (top + tooltipHeight > window.innerHeight)
- top = window.innerHeight - tooltipHeight - offset;
- }
-
- tooltipPosition.set({
- x: left,
- y: top + (relative ? 0 : window.scrollY)
- });
-
- return;
- }
- }
-
- const tooltipWidth = tooltipDiv.offsetWidth;
- const tooltipHeight = tooltipDiv.offsetHeight;
- let top = y - tooltipHeight - offset;
- let left = x - tooltipWidth / 2;
-
- if (left < 0) left = offset;
- if (left + tooltipWidth > window.innerWidth) left = window.innerWidth - tooltipWidth - offset;
- if (top < 0) top = y + offset;
-
- tooltipPosition.set({
- x: left,
- y: top
- });
- }
+ if (tooltipDiv) {
+ if (pin) {
+ const pinnedElement = document.getElementById(pin);
+
+ if (pinnedElement) {
+ const rectangle = pinnedElement.getBoundingClientRect();
+ const parentRectangle =
+ pinnedElement.offsetParent?.getBoundingClientRect();
+ const tooltipWidth = tooltipDiv.offsetWidth;
+ const tooltipHeight = tooltipDiv.offsetHeight;
+ let top = 0;
+ let left = 0;
+
+ switch (pinPosition) {
+ case "top":
+ if (relative && parentRectangle) {
+ top =
+ rectangle.top - tooltipHeight - offset - parentRectangle.top;
+ left =
+ rectangle.left +
+ rectangle.width / 2 -
+ tooltipWidth / 2 -
+ parentRectangle.left;
+ } else {
+ top = rectangle.top - tooltipHeight - offset;
+ left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2;
+ }
+
+ break;
+ case "bottom":
+ if (relative && parentRectangle) {
+ top =
+ rectangle.top + rectangle.height + offset - parentRectangle.top;
+ left =
+ rectangle.left +
+ rectangle.width / 2 -
+ tooltipWidth / 2 -
+ parentRectangle.left;
+ } else {
+ top = rectangle.top + rectangle.height + offset;
+ left = rectangle.left + rectangle.width / 2 - tooltipWidth / 2;
+ }
+
+ break;
+ case "left":
+ if (relative && parentRectangle) {
+ top =
+ rectangle.top +
+ rectangle.height / 2 -
+ tooltipHeight / 2 -
+ parentRectangle.top;
+ left =
+ rectangle.left - tooltipWidth - offset - parentRectangle.left;
+ } else {
+ top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2;
+ left = rectangle.left - tooltipWidth - offset;
+ }
+
+ break;
+ case "right":
+ if (relative && parentRectangle) {
+ top =
+ rectangle.top +
+ rectangle.height / 2 -
+ tooltipHeight / 2 -
+ parentRectangle.top;
+ left =
+ rectangle.left +
+ rectangle.width +
+ offset -
+ parentRectangle.left;
+ } else {
+ top = rectangle.top + rectangle.height / 2 - tooltipHeight / 2;
+ left = rectangle.left + rectangle.width + offset;
+ }
+
+ break;
+ }
+
+ if (relative && parentRectangle) {
+ if (left + parentRectangle.left < 0)
+ left = offset - parentRectangle.left;
+ if (left + tooltipWidth + parentRectangle.left > window.innerWidth)
+ left =
+ window.innerWidth - tooltipWidth - offset - parentRectangle.left;
+ if (top + parentRectangle.top < 0)
+ top =
+ rectangle.top + rectangle.height + offset - parentRectangle.top;
+ if (top + tooltipHeight + parentRectangle.top > window.innerHeight)
+ top =
+ window.innerHeight - tooltipHeight - offset - parentRectangle.top;
+ } else {
+ if (left < 0) left = offset;
+ if (left + tooltipWidth > window.innerWidth)
+ left = window.innerWidth - tooltipWidth - offset;
+ if (top < 0) top = rectangle.top + rectangle.height + offset;
+ if (top + tooltipHeight > window.innerHeight)
+ top = window.innerHeight - tooltipHeight - offset;
+ }
+
+ tooltipPosition.set({
+ x: left,
+ y: top + (relative ? 0 : window.scrollY),
+ });
+
+ return;
+ }
+ }
+
+ const tooltipWidth = tooltipDiv.offsetWidth;
+ const tooltipHeight = tooltipDiv.offsetHeight;
+ let top = y - tooltipHeight - offset;
+ let left = x - tooltipWidth / 2;
+
+ if (left < 0) left = offset;
+ if (left + tooltipWidth > window.innerWidth)
+ left = window.innerWidth - tooltipWidth - offset;
+ if (top < 0) top = y + offset;
+
+ tooltipPosition.set({
+ x: left,
+ y: top,
+ });
+ }
};
const showTooltip = (content: string, x: number, y: number) => {
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
- hideTimeout = null;
- }
+ hideTimeout = null;
+ }
- createTooltip();
+ createTooltip();
- if (tooltipDiv) {
- tooltipDiv.innerHTML = content.replace(/\n/g, '<br>');
- tooltipDiv.style.opacity = '0';
+ if (tooltipDiv) {
+ tooltipDiv.innerHTML = content.replace(/\n/g, "<br>");
+ tooltipDiv.style.opacity = "0";
- updateTooltipPosition(x, y);
- setTimeout(() => {
- if (tooltipDiv) {
- opacity = 1;
- }
- }, 10);
- }
+ updateTooltipPosition(x, y);
+ setTimeout(() => {
+ if (tooltipDiv) {
+ opacity = 1;
+ }
+ }, 10);
+ }
};
const hideTooltip = () => {
- setTimeout(() => {
- if (tooltipDiv) {
- opacity = 0;
-
- hideTimeout = window.setTimeout(() => {
- if (tooltipDiv) {
- document.body.removeChild(tooltipDiv);
-
- tooltipDiv = null;
- }
- }, tooltipTransitionTime);
- }
- }, tooltipHideDelay);
+ setTimeout(() => {
+ if (tooltipDiv) {
+ opacity = 0;
+
+ hideTimeout = window.setTimeout(() => {
+ if (tooltipDiv) {
+ document.body.removeChild(tooltipDiv);
+
+ tooltipDiv = null;
+ }
+ }, tooltipTransitionTime);
+ }
+ }, tooltipHideDelay);
};
const handleMouseEnter = (event: MouseEvent) => {
- if (disable) return;
+ if (disable) return;
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
- hideTimeout = null;
- }
+ hideTimeout = null;
+ }
- if (!tooltipDiv) showTooltip(content, event.pageX, event.pageY);
+ if (!tooltipDiv) showTooltip(content, event.pageX, event.pageY);
};
const handleMouseMove = (event: MouseEvent) => {
- if (debounceTimer !== null) clearTimeout(debounceTimer);
+ if (debounceTimer !== null) clearTimeout(debounceTimer);
- debounceTimer = window.setTimeout(() => {
- if (tooltipDiv && opacity === 1) updateTooltipPosition(event.pageX, event.pageY);
- }, debounceDelay);
+ debounceTimer = window.setTimeout(() => {
+ if (tooltipDiv && opacity === 1)
+ updateTooltipPosition(event.pageX, event.pageY);
+ }, debounceDelay);
};
const handleMouseLeave = () => {
- hideTooltip();
+ hideTooltip();
};
</script>