(front) handle item title overflow in explorer

When there is a an overflow, we display a tooltip on hover.

Fixes #58
This commit is contained in:
Nathan Vasse
2025-03-24 17:38:10 +01:00
committed by NathanVss
parent 2d128b3041
commit 2e7f2e40b8
2 changed files with 60 additions and 7 deletions
@@ -83,10 +83,25 @@
text-decoration: none;
color: var(--c--theme--colors--greyscale-700);
.c__tooltip {
max-width: 100%;
}
> img {
// Need to set width and height to prevent layout shift
// and to make overflow calculations work correctly before
// the image is loaded
width: 32px;
height: 32px;
}
&__text {
font-size: 14px;
font-weight: 400;
color: var(--c--theme--colors--greyscale-1000);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
@@ -7,7 +7,7 @@ import {
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useCallback, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { NavigationEventType, useExplorer } from "./ExplorerContext";
import clsx from "clsx";
@@ -36,12 +36,7 @@ export const ExplorerGrid = () => {
// icon as <img> which get re-fetched on every render.
const nameCellRenderer = useCallback(
(params: CellContext<Item, string>) => (
<div className="explorer__grid__item__name">
<ItemIcon item={params.row.original} />
<span className="explorer__grid__item__name__text">
{params.row.original.title}
</span>
</div>
<ItemTitle item={params.row.original} />
),
[]
);
@@ -320,3 +315,46 @@ const ItemActions = ({ item }: { item: Item }) => {
</DropdownMenu>
);
};
const ItemTitle = ({ item }: { item: Item }) => {
const ref = useRef<HTMLSpanElement>(null);
const [isOverflown, setIsOverflown] = useState(false);
useEffect(() => {
const checkOverflow = () => {
const element = ref.current;
// Should always be defined, but just in case.
if (element) {
setIsOverflown(element.scrollWidth > element.clientWidth);
}
};
checkOverflow();
window.addEventListener("resize", checkOverflow);
return () => {
window.removeEventListener("resize", checkOverflow);
};
}, [item.title]);
const renderTitle = () => {
// We need to have the element holding the ref nested because the Tooltip component
// seems to make the top-most children ref null.
return (
<div style={{ display: "flex", overflow: "hidden" }}>
<span className="explorer__grid__item__name__text" ref={ref}>
{item.title}
</span>
</div>
);
};
return (
<div className="explorer__grid__item__name">
<ItemIcon item={item} />
{isOverflown ? (
<Tooltip content={item.title}>{renderTitle()}</Tooltip>
) : (
renderTitle()
)}
</div>
);
};