fix(sheets): let Back answer the discard question with "keep editing"

Back on a sheet with unsaved input asks whether to discard it. A second
Back while that question was open put the sheet's entry back and asked
again, so the Android button could never get past the question. It now
closes the question and keeps the sheet and its entry, like Cancel.
This commit is contained in:
Marc-André Bombeck committed 2026-11-12 15:09:22 +01:00
1 parent 555a529260
commit 218986ea89
2 files changed
+42 -2

No files matched your search

@@ -8,10 +8,13 @@
* entry's own state copied in (`HistoryUpdater`), and that write can land
* after a sheet's close has asked for Back but before Back arrives.
*/
import { useState } from "react";
import { describe, expect, it, vi } from "vitest";
import { DAY_HISTORY_KEY } from "@/components/day/day-url";
import { renderWithApp } from "../../../../tests/browser/render";
import { ResponsiveSheet } from "../responsive-sheet";
import { sheetHistory } from "../sheet-history";
type Navigation = { currentEntry: { index: number } };
@@ -97,4 +100,40 @@ describe("sheet history in the browser", () => {
expect(state()[DAY_HISTORY_KEY]).toBe("2026-11-10");
expect(state()[MARK]).toBeUndefined();
});
it("answers Back during the discard question by keeping the sheet open", async () => {
window.history.pushState(null, "", "?step=form");
const page = index();
function EditedSheet() {
const [open, setOpen] = useState(true);
return (
<ResponsiveSheet
open={open}
onOpenChange={setOpen}
title="Add a reading"
dirty
>
<p>Typed but not saved</p>
</ResponsiveSheet>
);
}
const { screen } = await renderWithApp(<EditedSheet />);
await expect.element(screen.getByText("Typed but not saved")).toBeVisible();
await vi.waitFor(() => expect(index()).toBe(page + 1));
// Back with unsaved input asks first and puts the sheet's entry back.
window.history.back();
await settle(1);
await expect.element(screen.getByRole("alertdialog")).toBeVisible();
expect(index()).toBe(page + 1);
// Back again means "not now": the question goes, the sheet stays.
window.history.back();
await settle(1);
await expect
.element(screen.getByRole("alertdialog"))
.not.toBeInTheDocument();
await expect.element(screen.getByText("Typed but not saved")).toBeVisible();
expect(index()).toBe(page + 1);
});
});
+3 -2
View File
@@ -235,9 +235,10 @@ function useSheetDismissal({
};
const handleBack = React.useEffectEvent(() => {
if (hasUnsavedInput()) {
// Back while the question is open answers it with "keep editing".
if (asking || hasUnsavedInput()) {
entryRef.current?.restore();
setAsking(true);
setAsking(!asking);
return;
}
countBack();