fix(web): portal timeline hover tooltips

This commit is contained in:
2026-03-30 13:19:43 +02:00
parent e20bf64eef
commit 5a345cd2e4
@@ -1,5 +1,6 @@
"use client";
import { createPortal } from "react-dom";
import { formatCents, formatDateLong } from "~/lib/format.js";
function getVacationTitle(vacation: VacationHoverData): string {
@@ -78,9 +79,11 @@ export function TimelineTooltip({
demandHover,
}: TimelineTooltipProps) {
const vacationTitle = vacationHover ? getVacationTitle(vacationHover) : null;
const renderTooltip = (content: React.ReactNode) =>
typeof document === "undefined" ? content : createPortal(content, document.body);
if (demandHover && demandTooltipRef && demandTooltipPos) {
return (
return renderTooltip(
<div
ref={demandTooltipRef}
style={{
@@ -150,13 +153,13 @@ export function TimelineTooltip({
</div>
) : null}
</div>
</div>
</div>,
);
}
// When both are active, render a single merged tooltip using the heatmap position
if (heatmapHover && vacationHover) {
return (
return renderTooltip(
<div
ref={(el) => {
// Wire both refs to the same element so position updates work from either handler
@@ -230,13 +233,13 @@ export function TimelineTooltip({
<div className="mt-1 text-[11px] text-amber-200/60">{vacationHover.note}</div>
) : null}
</div>
</div>
</div>,
);
}
// Heatmap only
if (heatmapHover) {
return (
return renderTooltip(
<div
ref={heatmapTooltipRef}
style={{
@@ -289,13 +292,13 @@ export function TimelineTooltip({
<div className="text-[11px] text-gray-400">No bookings on this day.</div>
)}
</div>
</div>
</div>,
);
}
// Vacation only
if (vacationHover) {
return (
return renderTooltip(
<div
ref={vacationTooltipRef}
style={{
@@ -312,7 +315,7 @@ export function TimelineTooltip({
{vacationHover.note && vacationHover.type !== "PUBLIC_HOLIDAY" ? (
<div className="mt-2 text-[11px] text-amber-100/80">{vacationHover.note}</div>
) : null}
</div>
</div>,
);
}