# Files changed · PR \#9540 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/9540/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[fix\(web\): measure collapsed model labels at their visible width](https://git.cafe/pingdotgg/t3code/pull/9540.md)

Version: 2

Head commit: 8309a40d3aa36566409fcbfba2909a88fc11fe42

Base commit: 4268800cb893e232484f21865c4a63e74f2ffb52

Comparison base: 4268800cb893e232484f21865c4a63e74f2ffb52

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/web/src/components/chat/restingComposerControlsMeasurement.test.ts

Status: added; +72; −0

```diff
@@ -1,0 +1,72 @@
+import { afterEach, describe, expect, it, vi } from "vite-plus/test";
+
+import {
+  resolveRestingComposerControlsLayout,
+  resolveRestingComposerControlsNaturalWidth,
+} from "../composerFooterLayout";
+import { measureRestingComposerControls } from "./restingComposerControlsMeasurement";
+
+function measurePicker(input: { clientWidth: number; flexGrow: string; maxWidth?: string }) {
+  const label = { clientWidth: input.clientWidth, scrollWidth: 160 };
+  const picker = {
+    getBoundingClientRect: () => ({ width: 52 }),
+    querySelector: () => label,
+  };
+  const controls = {
+    querySelector: (selector: string) => {
+      if (selector === "[data-chat-provider-model-picker]") return picker;
+      if (selector === "[data-resting-controls-overflow]") {
+        return { getBoundingClientRect: () => ({ width: 24 }) };
+      }
+      return null;
+    },
+    querySelectorAll: () => [{ getBoundingClientRect: () => ({ width: 140 }) }],
+  };
+  vi.stubGlobal("getComputedStyle", (element: unknown) => {
+    if (element === label) return { flexGrow: input.flexGrow };
+    if (element === picker) return { minWidth: "52px", maxWidth: input.maxWidth ?? "none" };
+    return { columnGap: "4px" };
+  });
+  return measureRestingComposerControls(controls as unknown as HTMLElement)!;
+}
+
+afterEach(() => vi.unstubAllGlobals());
+
+describe("measureRestingComposerControls", () => {
+  it("keeps controls inline when the model label is deliberately collapsed", () => {
+    const measurement = measurePicker({ clientWidth: 0, flexGrow: "0" });
+
+    expect(measurement.naturalFixedWidth).toBe(52);
+    expect(resolveRestingComposerControlsNaturalWidth(measurement)).toBe(196);
+    expect(resolveRestingComposerControlsLayout({ ...measurement, hostWidth: 200 })).toEqual({
+      hiddenCount: 0,
+      visible: true,
+    });
+  });
+
+  it("recovers truncated text while the model label is flexible", () => {
+    const measurement = measurePicker({ clientWidth: 20, flexGrow: "1" });
+
+    expect(measurement.naturalFixedWidth).toBe(192);
+    expect(resolveRestingComposerControlsLayout({ ...measurement, hostWidth: 200 })).toEqual({
+      hiddenCount: 1,
+      visible: true,
+    });
+  });
+
+  it("recovers flexible text squeezed to zero instead of mistaking it for collapsed text", () => {
+    const measurement = measurePicker({ clientWidth: 0, flexGrow: "1" });
+
+    expect(measurement.naturalFixedWidth).toBe(212);
+    expect(resolveRestingComposerControlsLayout({ ...measurement, hostWidth: 200 })).toEqual({
+      hiddenCount: 1,
+      visible: true,
+    });
+  });
+
+  it("still caps recovered text at the model picker's maximum width", () => {
+    expect(
+      measurePicker({ clientWidth: 0, flexGrow: "1", maxWidth: "180px" }).naturalFixedWidth,
+    ).toBe(180);
+  });
+});
```

## apps/web/src/components/chat/restingComposerControlsMeasurement.ts

Status: modified; +5; −1

```diff
@@ -24,7 +24,11 @@
   if (renderedWidth === 0) return 0;
   const style = getComputedStyle(picker);
   const label = picker.querySelector<HTMLElement>('[data-chat-provider-model-picker-label="true"]');
+  // Narrow composers deliberately collapse the label with w-0 and flex-none.
+  // A flexible label squeezed to zero still needs its natural width recovered.
-  const hiddenLabelWidth = label ? Math.max(0, label.scrollWidth - label.clientWidth) : 0;
+  const labelIsCollapsed = label?.clientWidth === 0 && getComputedStyle(label).flexGrow === "0";
+  const hiddenLabelWidth =
+    label && !labelIsCollapsed ? Math.max(0, label.scrollWidth - label.clientWidth) : 0;
   const maxWidth = Number.parseFloat(style.maxWidth);
   const naturalWidth = Math.min(
     renderedWidth + hiddenLabelWidth,
```
