mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-17 03:04:26 +01:00
build: decouple package deps and introduce yarn workspaces (#7415)
* feat: decouple package deps and introduce yarn workspaces * update root directory * fix * fix scripts * fix lint * update path in scripts * remove yarn.lock files from packages * ignore workspace * dummy * dummy * remove comment check * revert workflow changes * ignore ws when installing gh actions * remove log * update path * fix * fix typo
This commit is contained in:
114
packages/excalidraw/components/Tooltip.tsx
Normal file
114
packages/excalidraw/components/Tooltip.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import "./Tooltip.scss";
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
export const getTooltipDiv = () => {
|
||||
const existingDiv = document.querySelector<HTMLDivElement>(
|
||||
".excalidraw-tooltip",
|
||||
);
|
||||
if (existingDiv) {
|
||||
return existingDiv;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
document.body.appendChild(div);
|
||||
div.classList.add("excalidraw-tooltip");
|
||||
return div;
|
||||
};
|
||||
|
||||
export const updateTooltipPosition = (
|
||||
tooltip: HTMLDivElement,
|
||||
item: {
|
||||
left: number;
|
||||
top: number;
|
||||
width: number;
|
||||
height: number;
|
||||
},
|
||||
position: "bottom" | "top" = "bottom",
|
||||
) => {
|
||||
const tooltipRect = tooltip.getBoundingClientRect();
|
||||
|
||||
const viewportWidth = window.innerWidth;
|
||||
const viewportHeight = window.innerHeight;
|
||||
|
||||
const margin = 5;
|
||||
|
||||
let left = item.left + item.width / 2 - tooltipRect.width / 2;
|
||||
if (left < 0) {
|
||||
left = margin;
|
||||
} else if (left + tooltipRect.width >= viewportWidth) {
|
||||
left = viewportWidth - tooltipRect.width - margin;
|
||||
}
|
||||
|
||||
let top: number;
|
||||
|
||||
if (position === "bottom") {
|
||||
top = item.top + item.height + margin;
|
||||
if (top + tooltipRect.height >= viewportHeight) {
|
||||
top = item.top - tooltipRect.height - margin;
|
||||
}
|
||||
} else {
|
||||
top = item.top - tooltipRect.height - margin;
|
||||
if (top < 0) {
|
||||
top = item.top + item.height + margin;
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(tooltip.style, {
|
||||
top: `${top}px`,
|
||||
left: `${left}px`,
|
||||
});
|
||||
};
|
||||
|
||||
const updateTooltip = (
|
||||
item: HTMLDivElement,
|
||||
tooltip: HTMLDivElement,
|
||||
label: string,
|
||||
long: boolean,
|
||||
) => {
|
||||
tooltip.classList.add("excalidraw-tooltip--visible");
|
||||
tooltip.style.minWidth = long ? "50ch" : "10ch";
|
||||
tooltip.style.maxWidth = long ? "50ch" : "15ch";
|
||||
|
||||
tooltip.textContent = label;
|
||||
|
||||
const itemRect = item.getBoundingClientRect();
|
||||
updateTooltipPosition(tooltip, itemRect);
|
||||
};
|
||||
|
||||
type TooltipProps = {
|
||||
children: React.ReactNode;
|
||||
label: string;
|
||||
long?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export const Tooltip = ({
|
||||
children,
|
||||
label,
|
||||
long = false,
|
||||
style,
|
||||
}: TooltipProps) => {
|
||||
useEffect(() => {
|
||||
return () =>
|
||||
getTooltipDiv().classList.remove("excalidraw-tooltip--visible");
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
className="excalidraw-tooltip-wrapper"
|
||||
onPointerEnter={(event) =>
|
||||
updateTooltip(
|
||||
event.currentTarget as HTMLDivElement,
|
||||
getTooltipDiv(),
|
||||
label,
|
||||
long,
|
||||
)
|
||||
}
|
||||
onPointerLeave={() =>
|
||||
getTooltipDiv().classList.remove("excalidraw-tooltip--visible")
|
||||
}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user