Fix long preview branch names (#2124)

* Truncate long branch names, don’t let the icon shrink

* Truncate and show tooltip for long branch names
This commit is contained in:
Matt Aitken
2025-05-29 14:36:24 +01:00
committed by GitHub
parent 47f4726515
commit 12f4653cd6
2 changed files with 62 additions and 4 deletions
@@ -6,6 +6,8 @@ import {
} from "~/assets/icons/EnvironmentIcons";
import type { RuntimeEnvironment } from "~/models/runtimeEnvironment.server";
import { cn } from "~/utils/cn";
import { SimpleTooltip } from "~/components/primitives/Tooltip";
import { useEffect, useRef, useState } from "react";
type Environment = Pick<RuntimeEnvironment, "type"> & { branchName?: string | null };
@@ -56,7 +58,10 @@ export function EnvironmentCombo({
}) {
return (
<span className={cn("flex items-center gap-1.5 text-sm text-text-bright", className)}>
<EnvironmentIcon environment={environment} className={cn("size-4.5", iconClassName)} />
<EnvironmentIcon
environment={environment}
className={cn("size-4.5 shrink-0", iconClassName)}
/>
<EnvironmentLabel environment={environment} />
</span>
);
@@ -69,11 +74,61 @@ export function EnvironmentLabel({
environment: Environment;
className?: string;
}) {
return (
<span className={cn(environmentTextClassName(environment), className)}>
{environment.branchName ? environment.branchName : environmentFullTitle(environment)}
const spanRef = useRef<HTMLSpanElement>(null);
const [isTruncated, setIsTruncated] = useState(false);
const text = environment.branchName ? environment.branchName : environmentFullTitle(environment);
useEffect(() => {
const checkTruncation = () => {
if (spanRef.current) {
const isTruncated = spanRef.current.scrollWidth > spanRef.current.clientWidth;
console.log(
"isTruncated",
isTruncated,
spanRef.current.scrollWidth,
spanRef.current.clientWidth
);
setIsTruncated(isTruncated);
}
};
checkTruncation();
// Add resize observer to recheck on window resize
const resizeObserver = new ResizeObserver(checkTruncation);
if (spanRef.current) {
resizeObserver.observe(spanRef.current);
}
return () => resizeObserver.disconnect();
}, [text]);
const content = (
<span
ref={spanRef}
className={cn("truncate text-left", environmentTextClassName(environment), className)}
>
{text}
</span>
);
if (isTruncated) {
return (
<SimpleTooltip
asChild
button={content}
content={
<span ref={spanRef} className={cn("text-left", environmentTextClassName(environment))}>
{text}
</span>
}
side="right"
variant="dark"
sideOffset={34}
/>
);
}
return content;
}
export function environmentTitle(environment: Environment, username?: string) {
@@ -62,6 +62,7 @@ function SimpleTooltip({
className,
buttonClassName,
asChild = false,
sideOffset,
}: {
button: React.ReactNode;
content: React.ReactNode;
@@ -72,6 +73,7 @@ function SimpleTooltip({
className?: string;
buttonClassName?: string;
asChild?: boolean;
sideOffset?: number;
}) {
return (
<TooltipProvider disableHoverableContent={disableHoverableContent}>
@@ -82,6 +84,7 @@ function SimpleTooltip({
<TooltipContent
side={side}
hidden={hidden}
sideOffset={sideOffset}
className={cn("text-xs", className)}
variant={variant}
>