diff --git a/clients/web/src/components/elements/EnlargeButton/EnlargeButton.test.tsx b/clients/web/src/components/elements/EnlargeButton/EnlargeButton.test.tsx index ccb37dc5..ad6fb88f 100644 --- a/clients/web/src/components/elements/EnlargeButton/EnlargeButton.test.tsx +++ b/clients/web/src/components/elements/EnlargeButton/EnlargeButton.test.tsx @@ -33,4 +33,14 @@ describe("EnlargeButton", () => { screen.getByRole("button", { name: "Enlarge Query" }), ).toBeInTheDocument(); }); + + it("is inert when the field it belongs to is disabled", async () => { + const user = userEvent.setup(); + const onClick = vi.fn(); + renderWithMantine(); + const button = screen.getByRole("button", { name: "Enlarge" }); + expect(button).toBeDisabled(); + await user.click(button); + expect(onClick).not.toHaveBeenCalled(); + }); }); diff --git a/clients/web/src/components/elements/EnlargeButton/EnlargeButton.tsx b/clients/web/src/components/elements/EnlargeButton/EnlargeButton.tsx index 193c0de2..3980ab68 100644 --- a/clients/web/src/components/elements/EnlargeButton/EnlargeButton.tsx +++ b/clients/web/src/components/elements/EnlargeButton/EnlargeButton.tsx @@ -11,6 +11,12 @@ export interface EnlargeButtonProps { * tell them apart; the visible tooltip stays the plain verb. */ ariaLabel?: string; + /** + * Mirrors the disabled state of the input this sits in. A live button on a + * disabled field would still swap in the text area — which mounts disabled and + * cannot take focus, dropping keyboard focus to the document. + */ + disabled?: boolean; } const EnlargeActionIcon = ActionIcon.withProps({ @@ -34,10 +40,18 @@ const EnlargeActionIcon = ActionIcon.withProps({ * of the tab order without cost; entering multiline mode has none, so removing * this one would put the feature out of reach of keyboard users entirely. */ -export function EnlargeButton({ onClick, ariaLabel }: EnlargeButtonProps) { +export function EnlargeButton({ + onClick, + ariaLabel, + disabled, +}: EnlargeButtonProps) { return ( - + diff --git a/clients/web/src/components/groups/SchemaForm/SchemaForm.test.tsx b/clients/web/src/components/groups/SchemaForm/SchemaForm.test.tsx index da10bfc6..d0ec70a8 100644 --- a/clients/web/src/components/groups/SchemaForm/SchemaForm.test.tsx +++ b/clients/web/src/components/groups/SchemaForm/SchemaForm.test.tsx @@ -1954,4 +1954,19 @@ describe("SchemaForm multiline strings (#2042)", () => { await user.keyboard("{Enter}more"); expect(textarea.value).toBe("typed\nmore"); }); + + // A disabled form (a tool call in flight) must be inert as a whole: a live + // button there would swap in a text area that mounts disabled, cannot take + // focus, and so drops keyboard focus to the document. + it("disables the enlarge button along with the field", () => { + renderWithMantine( + , + ); + expect(screen.getByRole("button", { name: "Enlarge Note" })).toBeDisabled(); + }); }); diff --git a/clients/web/src/components/groups/SchemaForm/SchemaForm.tsx b/clients/web/src/components/groups/SchemaForm/SchemaForm.tsx index 2b7e4258..307483f8 100644 --- a/clients/web/src/components/groups/SchemaForm/SchemaForm.tsx +++ b/clients/web/src/components/groups/SchemaForm/SchemaForm.tsx @@ -713,6 +713,7 @@ export function SchemaForm({ setEnlargedFields( (previous) => new Set([...previous, fieldName]),