fix(web): keep focus in place after removing a media API key (#148)

Remove unmounts itself once clicked, so focus fell to the body and the
settings dialog pulled it back to its popup a frame later. Whatever field
the user (or a test) focused in that frame lost focus again; in CI the
cleared transcription URL was still sent on the next save. Remove now
moves focus to the key field before it disappears.


Claude-Session: https://claude.ai/code/session_01UfVneQG6488JGLiHYAc9RZ

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
cynarAI 2026-10-05 06:16:36 +02:00 committed by GitHub
parent ca57ebda85
commit f3fb07e41f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 2 deletions

View File

@ -105,6 +105,7 @@ test("the deployment owner points media at their own servers", async ({ page },
await expect(comfyKey).toHaveAttribute("placeholder", "Saved");
await comfy.getByRole("button", { name: "Remove", exact: true }).click();
await expect(comfyKey).toBeFocused();
await transcription.getByLabel("Server URL", { exact: true }).fill("");
await panel.getByRole("button", { name: "Save", exact: true }).click();
await expect.poll(() => saved.length).toBe(2);

View File

@ -1,7 +1,7 @@
import { Trans, useLingui } from "@lingui/react/macro";
import type { MediaSettingsUpdate, MediaSettingsView } from "@rakazo/contracts";
import { Button, Field, FieldLabel, Input, Textarea } from "@rakazo/ui-web";
import { useEffect, useId, useState } from "react";
import { useEffect, useId, useRef, useState } from "react";
import { rpc } from "../lib/rpc";
import { SuccessPop } from "./ai/primitives";
@ -28,6 +28,7 @@ function ApiKeyField({
}) {
const { t } = useLingui();
const id = useId();
const inputRef = useRef<HTMLInputElement>(null);
const showSaved = saved && !draft.remove;
return (
<Field className="mt-4">
@ -41,13 +42,19 @@ function ApiKeyField({
variant="ghost"
size="xs"
disabled={disabled}
onClick={() => onChange({ value: "", remove: true })}
onClick={() => {
// The button unmounts once clicked; hand focus to the field so the dialog
// does not pull it back to its popup a frame later.
inputRef.current?.focus();
onChange({ value: "", remove: true });
}}
>
<Trans>Remove</Trans>
</Button>
) : null}
</div>
<Input
ref={inputRef}
id={id}
type="password"
autoComplete="new-password"