Skip to content

Commit 35e35bb

Browse files
mxmzbclaude
andcommitted
fix(react-core): preserve cache across layout toggles and reject zero-width entries
Self-inflicted resizes (compact↔expanded) were clearing the cache before the ignoreResizeRef guard, forcing a full re-measurement on the very next keystroke. Move the guard ahead of invalidation so layout toggles keep the cache warm — container dimensions don't change during these transitions. Also reject compactWidth <= 0 from being cached, preventing a zero-width entry from silently disabling text-width expansion until the next resize. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 84d531c commit 35e35bb

2 files changed

Lines changed: 13 additions & 9 deletions

File tree

packages/react-core/src/v2/components/chat/CopilotChatInput.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,8 @@ export function CopilotChatInput({
706706
0,
707707
);
708708

709+
if (compactWidth <= 0) return null;
710+
709711
const result = { compactWidth };
710712
containerCacheRef.current = result;
711713
return result;
@@ -857,15 +859,17 @@ export function CopilotChatInput({
857859
]);
858860

859861
const scheduleEvaluation = (invalidateCache: boolean) => {
860-
if (invalidateCache) {
861-
containerCacheRef.current = null;
862-
}
863-
864862
if (ignoreResizeRef.current) {
865863
ignoreResizeRef.current = false;
864+
// Self-inflicted resize from a layout toggle — container dimensions
865+
// are unchanged, so keep the cache warm.
866866
return;
867867
}
868868

869+
if (invalidateCache) {
870+
containerCacheRef.current = null;
871+
}
872+
869873
if (typeof window === "undefined") {
870874
evaluateLayout();
871875
return;

packages/react-core/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,7 @@ describe("CopilotChatInput", () => {
14621462
expect(addRectSpy).toHaveBeenCalled();
14631463
});
14641464

1465-
it("invalidates cache but skips re-evaluation during layout toggle (ignoreResizeRef path)", async () => {
1465+
it("keeps cache warm during layout toggle (ignoreResizeRef path)", async () => {
14661466
const { container } = renderWithProvider(
14671467
<CopilotChatInput onSubmitMessage={mockOnSubmitMessage} />,
14681468
);
@@ -1487,10 +1487,10 @@ describe("CopilotChatInput", () => {
14871487
});
14881488

14891489
// Simulate observer firing from the layout toggle.
1490-
// The guard consumes ignoreResizeRef; cache is invalidated but no re-eval loop.
1490+
// Self-inflicted resize: ignoreResizeRef is consumed, cache stays warm.
14911491
triggerAllResizeObservers();
14921492

1493-
// Go back to short text — cache was invalidated, so updateContainerCache must rebuild.
1493+
// Go back to short text — cache should still be warm from before the toggle.
14941494
const grid = container.querySelector("div.cpk\\:grid") as HTMLElement;
14951495
const addContainer = grid.children[0] as HTMLElement;
14961496
const addRectSpy = vi.fn(
@@ -1508,8 +1508,8 @@ describe("CopilotChatInput", () => {
15081508
);
15091509
});
15101510

1511-
// Confirms cache was invalidated (needed getBoundingClientRect to rebuild)
1512-
expect(addRectSpy).toHaveBeenCalled();
1511+
// Cache was NOT invalidated — no getBoundingClientRect needed
1512+
expect(addRectSpy).not.toHaveBeenCalled();
15131513
});
15141514
});
15151515

0 commit comments

Comments
 (0)