diff --git a/apps/web/src/components/ui/middle-truncate.browser.test.tsx b/apps/web/src/components/ui/middle-truncate.browser.test.tsx new file mode 100644 index 0000000000000..3b9b114d2f9f4 --- /dev/null +++ b/apps/web/src/components/ui/middle-truncate.browser.test.tsx @@ -0,0 +1,26 @@ +import { describe, expect, it } from "vite-plus/test"; + +import { render } from "../../../test/render"; +import { MiddleTruncate } from "./middle-truncate"; + +import "~/index.css"; + +const narrow = (value: string) => ( +
+ +
+); + +describe("MiddleTruncate", () => { + it("does not clip a short value that replaces a truncated one", async () => { + await using screen = await render(narrow("t3/investigate-release-build-times")); + const label = () => screen.container.querySelector("[title] > span"); + await expect.poll(() => label()?.hasAttribute("data-overflow")).toBe(true); + + await screen.rerender(narrow("main")); + + expect(label()).toHaveTextContent("main"); + expect(label()).not.toHaveAttribute("data-overflow"); + expect(label()).toHaveStyle({ clipPath: "none" }); + }); +}); diff --git a/apps/web/src/components/ui/middle-truncate.tsx b/apps/web/src/components/ui/middle-truncate.tsx index 8283006f45c8c..e4b74ec9ced9b 100644 --- a/apps/web/src/components/ui/middle-truncate.tsx +++ b/apps/web/src/components/ui/middle-truncate.tsx @@ -47,7 +47,10 @@ export function MiddleTruncate({ {split.tail} ) : ( - {value} + // Keyed so React does not reuse the head node and its imperative clip. + + {value} + )} );