mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(sheets): put a swiped sheet back when it asks before closing
A swipe past the close point paints the sheet where the finger let go and asks the owner to close it. A sheet holding unsaved input asks about discarding first and stays open, so it sat half pushed off the screen behind the question. One frame after the close, a sheet whose content is still open now glides back to its resting place. The function's size baseline rises by the seven lines this takes.
This commit is contained in:
1 parent
5533b6edf9
commit
8f3b640ab6
3 files changed
+37
-2
No files matched your search
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$comment": "Production functions over 200 lines, keyed \"file :: name\", and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
|
||||
"count": 336,
|
||||
"total": 109378,
|
||||
"total": 109385,
|
||||
"entries": {
|
||||
"app/achievements/page.tsx :: AchievementsPage": 206,
|
||||
"app/api/admin/backups/upload/route.ts :: apiHandler(arg)": 275,
|
||||
@@ -231,7 +231,7 @@
|
||||
"components/vaccinations/custom-vaccine-sheet.tsx :: CustomVaccineSheet": 246,
|
||||
"components/vaccinations/vaccination-form.tsx :: VaccinationForm": 218,
|
||||
"components/workouts/manual-workout-form.tsx :: ManualWorkoutForm": 321,
|
||||
"hooks/use-sheet-drag.ts :: createSheetDrag": 312,
|
||||
"hooks/use-sheet-drag.ts :: createSheetDrag": 319,
|
||||
"lib/activity/calendar-math.ts :: buildActivityCalendar": 204,
|
||||
"lib/ai/anthropic-client.ts :: generateCompletion": 294,
|
||||
"lib/ai/coach/cycle-snapshot.ts :: buildCycleSnapshotBlock": 202,
|
||||
|
||||
@@ -23,6 +23,9 @@ interface FakeEl {
|
||||
parentElement: FakeEl | null;
|
||||
overflowY: string;
|
||||
own?: boolean;
|
||||
/** Radix's `data-state` on the sheet content. */
|
||||
state?: "open" | "closed";
|
||||
getAttribute: (name: string) => string | null;
|
||||
closest: (selector: string) => FakeEl | null;
|
||||
getAnimations: () => Animation[];
|
||||
setPointerCapture: (id: number) => void;
|
||||
@@ -39,6 +42,8 @@ function fake(partial: Partial<FakeEl> = {}): FakeEl {
|
||||
parentElement: null,
|
||||
overflowY: "visible",
|
||||
closest: () => (node.own ? node : null),
|
||||
getAttribute: (name) =>
|
||||
name === "data-state" ? (node.state ?? null) : null,
|
||||
getAnimations: () => [],
|
||||
setPointerCapture: vi.fn(),
|
||||
querySelector: () => null,
|
||||
@@ -173,6 +178,29 @@ describe("createSheetDrag", () => {
|
||||
expect(s.controller.swallowClick()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns to its rest when a guarded sheet stays open after the swipe", () => {
|
||||
const s = setup();
|
||||
// The owner asks about unsaved input instead of closing.
|
||||
s.content.state = "open";
|
||||
s.drag(s.header, 140, { stepMs: 40, restMs: 200 });
|
||||
expect(s.onClose).toHaveBeenCalledTimes(1);
|
||||
expect(s.content.style.transform).toBe("translate3d(0, 140px, 0)");
|
||||
|
||||
s.flushFrames();
|
||||
expect(s.content.style.transform).toBe("translate3d(0, 0px, 0)");
|
||||
expect(s.overlay.style.opacity).toBe("1");
|
||||
s.timers.forEach((run) => run());
|
||||
expect(s.content.style.transform).toBe("");
|
||||
});
|
||||
|
||||
it("leaves a closing sheet where it was let go", () => {
|
||||
const s = setup();
|
||||
s.content.state = "closed";
|
||||
s.drag(s.header, 140, { stepMs: 40, restMs: 200 });
|
||||
s.flushFrames();
|
||||
expect(s.content.style.transform).toBe("translate3d(0, 140px, 0)");
|
||||
});
|
||||
|
||||
it("lets its own close through: the swallowed click comes after it", () => {
|
||||
const s = setup();
|
||||
let swallowedDuringClose: boolean | null = null;
|
||||
|
||||
@@ -354,6 +354,13 @@ export function createSheetDrag(
|
||||
// Before the swallow is armed: the close is itself a click.
|
||||
options.onClose();
|
||||
swallow = true;
|
||||
// A sheet holding unsaved input asks first and stays open meanwhile;
|
||||
// put it back where it rests rather than where it was let go.
|
||||
frame(() => {
|
||||
if (options.content()?.getAttribute("data-state") === "open") {
|
||||
settleTo(g, options.snap());
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
swallow = true;
|
||||
|
||||
Reference in new issue
Block a user