fix(files): a folder made from the upload dialog gives the keyboard back the target once it is made

This commit is contained in:
2026-11-06 00:23:09 +01:00
parent 8383459f70
commit 2baad2ebae
2 changed files with 14 additions and 8 deletions
@@ -218,8 +218,9 @@ describe("UploadDialog · where the file goes", () => {
await waitFor(() => expect(h.createFolder).toHaveBeenCalledWith("Trips"));
});
it("says a new folder is being made while Upload waits for it", async () => {
h.createFolder.mockReturnValue(new Promise(() => {}));
it("says a new folder is being made, then gives the keyboard back the list", async () => {
let made: (f: unknown) => void = () => {};
h.createFolder.mockReturnValue(new Promise((res) => (made = res)));
wrap();
fireEvent.click(await target());
fireEvent.click(await screen.findByTestId("upload-target-new"));
@@ -227,6 +228,8 @@ describe("UploadDialog · where the file goes", () => {
fireEvent.change(field, { target: { value: "Trips" } });
fireEvent.keyDown(field, { key: "Enter" });
expect(await screen.findByText("downloads.upload.makingFolder")).toBeTruthy();
made({ ...FOLDERS[1], id: 7, name: "Trips" });
await waitFor(async () => expect(document.activeElement).toBe(await target()));
});
// A failed refetch keeps the list it had: the target the file goes to stays shown.
+9 -6
View File
@@ -81,13 +81,7 @@ export default function UploadDialog({
const foldersQ = useQuery({ queryKey: qk.fileFolders(), queryFn: api.fileFolders });
const [naming, setNaming] = useState(false);
const targetBox = useRef<HTMLDivElement>(null);
// A new folder's name ended by a key leaves the keyboard's focus nowhere: back on the list.
const refocusTarget = useRef(false);
useEffect(() => {
if (naming || !refocusTarget.current) return;
refocusTarget.current = false;
targetBox.current?.querySelector("button")?.focus();
}, [naming]);
// A press on Cancel, the ✕ or the backdrop blurs the name field before the dialog closes, and the
// field saves on blur: that press is "never mind", not "make it". The press is seen before the
// blur it causes, in every browser (which control takes the focus, if any, differs: Safari
@@ -112,6 +106,15 @@ export default function UploadDialog({
},
meta: { failTitle: "errors.writeFailed.folder.create" },
});
// A new folder's name ended by a key leaves the keyboard's focus nowhere: back on the list — once
// it is back, as the folder is made (or fails): until then its place says it is being made.
useEffect(() => {
if (naming || !refocusTarget.current) return;
const list = targetBox.current?.querySelector("button");
if (!list) return;
refocusTarget.current = false;
list.focus();
}, [naming, makeFolder.isPending]);
// Not while a folder is being named or made: the file would go to the last target, not that one.
const targetSettling = naming || makeFolder.isPending;
const targets = (foldersQ.data ?? []).filter(takesUploads);