Skip to content

fix: Today picks save end-of-day again, edits commit on editor close#12

Merged
Bug-Finderr merged 3 commits into
mainfrom
today-eod
Jul 11, 2026
Merged

fix: Today picks save end-of-day again, edits commit on editor close#12
Bug-Finderr merged 3 commits into
mainfrom
today-eod

Conversation

@Bug-Finderr

@Bug-Finderr Bug-Finderr commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Fixes the Today-pick regressions reported on the deployed dashboard, in one coherent design instead of patches: rows now run the exact snap behavior the create form has had in production all along, and every editor transition was traced with real keystrokes.

The design (one behavior everywhere)

  • Snap at input time, identically for form and rows: when a datetime-local fills with the current wall-clock minute (the signature of a picker Today click), the field rewrites to 23:59 and the blur/showPicker dance makes the open picker reread it - so the popup stays open, anchored at the input, showing 23:59, still interactive. Hand-typed other times never match the current minute and are untouched.
  • Commit when the user actually leaves the editor: native focusout, or a body-level click-outside route for the post-dance state where the input is no longer focused. Unchanged closes are silent; per-segment change events never commit (Chromium fires them on every keystroke of a valid value).
  • Zero-reflow editor swap: the display button and the editor share one fixed 170px footprint. Previously the swap reflowed the row between mousedown and mouseup, so the next click (e.g. another row's edit button) landed on nothing - the "editor won't open again" symptom.
  • Popup anchoring: focus + a forced layout read precede showPicker(), so Chromium no longer anchors the popup to a pre-layout zero rect at the screen corner.
  • The 120s poll pauses on an .editing marker (activeElement stops being truthful after the dance).

Verification (real CDP keystrokes, isolated browser, every transition instrumented)

  • Today signature typed: field shows 23:59, the dance's blur does NOT close the editor (flag consumed), zero requests mid-edit, click-away commits, row renders 11:59 PM.
  • Deliberate future datetime: zero mid-edit PUTs across all per-segment change events, one PUT on close, saved to the minute.
  • Cancel and editor-switching: no spurious PUTs; clicking another row's edit button while an editor is open closes the first and opens the second (the eaten-click repro now passes).
  • Full gate: 84 unit + 19 compat + 4 python, tsc + biome clean.
  • The one machine-unverifiable inch remains the native popup's pixels (browser chrome, no CDP access): the reopened-picker-shows-23:59 leg rides the byte-identical code path the create form has used in production.

…r close

The dedup in #11 moved the create form's Today snap from input time to
submit time and then deleted it, so a picker Today click saved the
current minute and expired the token instantly. The snap is back at its
original site - the moment the picker fills the current minute - as one
body-level delegate serving the form and every row editor, rewriting
the field visibly; hand-typed other times never match it. Rows keep
focus (any picker recommit of the current minute just re-enters the
handler), while the form keeps the blur/showPicker reread dance.

Trusted-keystroke testing also showed Chromium fires change per segment
edit on a valid datetime-local, so the change trigger committed
half-edited values and swapped the row mid-edit. Row edits now commit
when the editor closes with a value different from what it opened with
(focusout fires a custom commit trigger); unchanged closes are silent.
…n a Today fill

showPicker() ran in the same tick the input flipped from display:none,
so Chromium anchored the popup to a zero rect at the screen corner -
focus and a forced layout read now precede it. And instead of leaving
the open popup displaying a stale time after the snap, a row's Today
fill commits immediately: the row re-renders to 11:59 PM and the popup
closes with the swapped editor, so there is no mismatch window at all.
The create form keeps its blur/showPicker reread dance.
…ting clicks

A Today fill no longer commits and closes the editor out from under the
user: rows now run the same snap dance the create form always has
(rewrite the field, blur, showPicker) so the reopened picker shows
23:59 and stays interactive; a flag keeps the dance's blur from closing
the editor. Commits happen when the user actually leaves: native
focusout, or a body-level click-outside route for the post-dance state
where the input is no longer focused. The poll pauses on an .editing
marker instead of activeElement for the same reason.

The display button and the editor also share one fixed footprint:
swapping them used to reflow the row between mousedown and mouseup, so
the click aimed at another row's edit button (or anything nearby) landed
on nothing - which is why the editor 'would not open again'.
@Bug-Finderr
Bug-Finderr merged commit 7c86478 into main Jul 11, 2026
4 checks passed
@Bug-Finderr
Bug-Finderr deleted the today-eod branch July 11, 2026 19:13
@Bug-Finderr Bug-Finderr self-assigned this Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant