Make search the v2 palette: centred on desktop, full screen on a phone #254
No reviewers
Labels
No labels
No milestone
No project
No assignees
5 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente!254
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "ui-v2-search"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Search in the UI language v2, to the Figma draft (Desktop · Search 42:2792 / 73:5839, Phone · Search 57:1615 / 73:12731, and the search parts in Calendar & search parts 34:180).
What changed
--keyboard-inset), so the last row can be scrolled into sight.date:today,date:week(datum:heute,datum:wochein German),tag:,@,board:. Each is lit while the parsed query uses it, sodatum:heutelightsdate:today; a date chip is a whole term and a second press takes it off; the others are typed on. Their mousedown is cancelled, so the field keeps focus (and a phone its keyboard). The old four rows of tips are gone; their explanations are the chips' tooltips./board/{key}?card={id}, the comment-only marker (now in the place line), Up/Down/Enter/Escape in C#, the arrows kept off the caret and the field letting go on Enter (#249),/and Ctrl/⌘-K,@bind, closing keeps the query (and opening now searches it again, since closing dropped the snapshot).aria-activedescendantowner; groups arerole="group"in the listbox.:has): the docked inspector (a.modal-backdropat 1000) used to paint over its right half, and Ctrl/⌘-K from inside a card dialog opened it invisibly behind.SearchDocumentlosesPreviewandTagNames, which only the old rows showed (oneCardPreview.Buildless per card per snapshot).search.md(The box, rewritten with the reasons),ui.md(the phone sheets),frontend.md(v2 status line,search-interop.js,CardPreview).design/trace/capture.mjs's desktop search scenario opens the palette from the new trigger.Judgement calls
card-due-soon,card.due.today/tomorrow,--warning) arrives with #252. Adding the keys here would collide with #252 or leave duplicates, so search rows wearcard-duepluscard-due-overdue, which #252 restyles automatically. Once #252 is in, the soon state is a three-line follow-up inSearchBox(I can do it).Verified
tools/verify.sh: build and 584 unit tests green.search.spec.jsrewritten for the new shapes and extended: the trigger opening a focused palette, chips (typing on, lighting, a second press, either language), grouping and counts, Escape from the padding, focus back on the trigger, Ctrl-K, the palette over a docked card, centring and the scrim at 960px, the 620px window, and the phone's full screen (edge to edge over the tab bar, field at the top, list below it, Cancel).🤖 Generated with Claude Code
🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
The change looks good to merge. I read the diff only and did not run the build or the Playwright suite, so I'm relying on the PR's reported results (584 unit tests, 162 e2e specs).
@bindis kept.Open()sets_openbefore its first await andOnShortcutreturns the task, so Ctrl/⌘-K and the triggers behave the same. Opening re-runs a kept query, which fixes the dropped-snapshot case.stopPropagationavoids a double dismiss.Dismiss()refocuses both triggers in turn, and focusing the hidden one is a harmless no-op.GroupBypreserves first occurrence, so grouped boards still follow their best hit and the first row is still the best. The_hits.Index()index matches the on-screen order.Useremoves a lit date in whichever language it was typed (DateOf(t) != date). Appending the other chips is unchanged.fieldfor amatches('.nav-search-input')check is sound, because the input exists only while the palette is open.reveal()runs after the render that moves the active row.Minor things, none blocking:
aria-modal="true"has no focus trap, so Tab can leave the palette for the page behind the scrim.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the whole results panel also blocks text selection there. Scrollbar dragging is probably fine, but I did not check it in all browsers.🧠 claude-sonnet-5-5 · ⏱ 0m 19s · 3 turns · tokens: 46.3k in / 2.5k out (+68.9k cache-read)
📜 Full session transcript
🤖 Resolving the merge conflicts — the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the fix runs.
Merge committed cleanly (
ee9c604). Everything verified — here's the summary for the PR comment.Merge conflict resolved
What conflicted:
docs/frontend.md— one bullet, "Two things lead the app" (the adopted v2 spec list in the design-canvas section). Both commits rewrote the same sentence from the same base.…the Done deck ([ui.md](ui.md)), drag physics (*Drag and drop* below) and the search palette, full screen on a phone ([search.md](search.md)).How I resolved it: Both additions survive in one bullet. For the tail, I kept main's newer version of the exceptions ("except large titles that collapse as a page scrolls and the large card sheet's receded page; and Escape saves where the draft reverts, and the footnote leaves out '⌘Z undoes'"). The branch's old exception — "the card sheet's two detents" — was true when the branch left main, but #251 has since built the card sheet at two heights, so keeping it would state the opposite of what the app now does; it's the same line #251 would have edited had this branch landed first.
The branch's other two edits merged cleanly and are kept:
CardPreviewno longer listed as "a search row" source (search rows lost preview in this PR), and thesearch-interop.jsbullet gained "scrolling the active row into sight".Verified:
<<<<<<</=======/>>>>>>>markers anywhere in the tree.wwwroot/js/inspector.jswithcard-dialog.js— nothing on this branch (code or docs) still references the deleted file;SearchBox.razordoesn't call into main's rewrittenCardModalinternals, and the palette's row-scrolling claim doesn't clash withcard-dialog.js's watcher slot.dotnet buildon the solution passes; the doc-checkingDocumentationTests(8 tests, which validate every doc page's links andCovers:paths in CI) pass.→ Merge resolved and pushed; a re-review follows.
⏱ 10m 42s · 19 steps · $0.0223 · tokens: 91.3k in / 3.1k out (+169.0k cache-read) · Go: 5h 0% · wk 12% · mo 89%
📜 Full session transcript
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
This is a re-review. I read the diff only and did not run the build or the e2e suite, so I'm relying on the PR's reported results (584 unit tests, 162 e2e specs).
The new commits don't change the picture from my last pass. The three minor notes from then are unchanged:
aria-modalhas no focus trap.<p>sits inside therole="listbox"element.@onmousedown:preventDefaulton the results panel blocks text selection there.None of them blocks merging.
I found no new correctness problems.
Open()re-runs a kept query, which fixes the dropped-snapshot case.🧠 claude-sonnet-5-5 · ⏱ 0m 3s · 2 turns · tokens: 45.5k in / 368 out (+12.2k cache-read)
📜 Full session transcript
💬 Verdict: comment — the reviewer did not submit a structured review; the raw output follows.
(empty)
⏱ 30m 2s · 17 steps · $0.0614 · tokens: 201.0k in / 857 out (+429.2k cache-read) · Go: 5h 1% · wk 12% · mo 89%
📜 Full session transcript
🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
✅ Verdict: approve — no blocking issues found.
Good to merge. Re-review: the new commits check out, and the three minor notes from my earlier passes remain — unchanged, none blocking:
aria-modal="true"has no focus trap, so Tab can walk out of the palette onto the dimmed page.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the whole results panel also blocks text selection there.Spot checks against the checked-out source rather than the diff alone:
SearchQuery's named-date table maps heute→today, woche→week (and morgen/gestern/monat), andParseDatetreats them all through the English names — soDateOf()is spelling-independent, the lit check only matches dated terms, andUseremoves a lit date however it was typed.DateFilteris a value-equal record, soDates.Containsworks.date:weekspans today..+7 anddate:todaytoday..today — two distinct filters, so the two date chips never light together.--board-color/--sidebar-wplumbing.BoardPalette.ColorOf(int)exists (BoardPalette.cs:27) and feeds the palette's inline--board-colorthat the marks, the active row and the lit chip mix against.--sidebar-wis 0px in:rootand 244px only from 960px — the breakpoint where the phone'sinset: 0 0 var(--keyboard-inset) 0overrides the desktop inset, so the centring math applies only where it is meant to.GroupBy+SelectManyflatten while preserving first-seen order, so boards sort by their best hit and the first row is still the best;_hits.Index()'s index is the row's on-screen position, matchingnav-search-hit-@indexagainstaria-activedescendant.A big shape change over SearchBox's state, with the e2e suite extended to pin the new geometry. Ready.
⏱ 5m 19s · 9 steps · $0.0234 · tokens: 102.9k in / 1.5k out (+171.6k cache-read) · Go: 5h 2% · wk 13% · mo 89%
📜 Full session transcript
🤖 Resolving the merge conflicts — the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the fix runs.
No container runtime is available in this environment, so the e2e stack isn't reachable — but the repo's own bar (
tools/verify.sh: build + unit tests, what CI runs) is fully met. The merge is committed; final summary:What conflicted
docs/ui.mdanddocs/frontend.md— both branches rewrote the same v2-adoption passages: the branch (this PR) declared the search palette (centred on desktop, full screen on a phone) part of the adopted v2 set, while main (#252 board screen, #253 Home) declared the board screen and Home part of it and listed search as still to come. Two smaller clashes rode along:search-interop.jsgained "scrolling the active row into sight" (branch) whilemodal-escape.jsgained "an open.menubefore either" (main) in adjacent bullets; and inui.md, main superseded the phone board's bar (Share/cog → a ⋯ menu, trayless board, drag hint) in the same hunk as the branch's sheets rewording.How I resolved it
search-interop.jsgains row-scrolling (matches its merged code),modal-escape.jsgains the.menuhandling.CardPreviewwording kept (verified: palette rows are mark + title + place + due chip; noCardPreviewinSearchBox.razor).mobile.spec.jspins,Covers:line); the branch's sheets wording survives — on a phone the search covers everything like the card sheet, so the stale "the search's dim is lifted over the bar instead (z-index: 150)" sentence is dropped, consistent withsearch.md(merged clean, full-screen palette) and the mergedapp.css(inset: 0, scrim hidden below 600px, header context rises to 1100).Cross-checked the auto-merged files both sides touched:
app.csshunks live in disjoint ranges (braces balanced, everynav-search-*class referenced),LocaleService.cshas both locales' search and board keys,NavHeader.razorstill renders<SearchBox />. Diffed the staged docs against each parent: vsorigin/mainonly the branch's search deltas remain, vsHEADonly main's v2 deltas — neither side dropped anything.Verified
dotnet build Ponente.sln: 0 warnings, 0 errors.dotnet test: 600/600 passed, including the branch'sCardSearchTestsand theDocumentationTeststhat validate the merged docs'Covers:paths and cross-references.38e6cc9with both parents intact.→ Merge resolved and pushed; a re-review follows.
⏱ 18m 45s · 41 steps · $0.1407 · tokens: 325.0k in / 8.4k out (+2352.6k cache-read) · Go: 5h 4% · wk 13% · mo 89%
📜 Full session transcript
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
I read the diff only and did not run the build or the e2e suite. I'm relying on the PR's reported results (584 unit tests, 162 e2e specs).
I found no new correctness problems. My earlier approvals stand.
The three minor notes from the earlier passes are still open. None blocks merging:
aria-modal="true"has no focus trap, so Tab can leave the palette for the page behind the scrim.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the results panel blocks text selection there.🧠 claude-sonnet-5-5 · ⏱ 0m 7s · 3 turns · tokens: 47.0k in / 366 out (+71.2k cache-read)
📜 Full session transcript
🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
✅ Verdict: approve — no blocking issues found.
Good to merge. Re-review: the checked-out source matches what I verified in my earlier passes; nothing landed since that changes the picture.
Still holding from before — spot checks against source, not just the diff:
SearchQuery's named-date table maps heute→today, woche→week etc., andDateFilteris a value-equal record, so the lit check andUse's removal are spelling-independent;date:todayanddate:weekare distinct filters, so the two date chips never light together.BoardPalette.ColorOf(int)exists and feeds the inline--board-color;--sidebar-wis 0px at:rootand 244px from 960px, matching the centring breakpoint;.board-headerat z-index 100 gains 1100 under:has, above the docked card's.modal-backdrop(1000), so the palette paints over it.GroupBy+SelectManyflattens preserving first-seen order, so boards sort by their best hit and the first row is still the best;_hits.Index()'s index matchesnav-search-hit-@indexagainstaria-activedescendant.@onkeydown:stopPropagationavoids a double dismiss; the dualFocusAsyncon the triggers is safe because focusing the hidden (display:none) one is a browser no-op.Three minor notes carried from my earlier passes, unchanged and non-blocking:
aria-modal="true"has no focus trap, so Tab can walk out of the palette onto the dimmed page.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the whole results panel also blocks text selection there.Relying on the PR's reported results (build + 584 unit tests green, 162 e2e passed) as in previous passes.
⏱ 1m 32s · 10 steps · $0.0176 · tokens: 46.3k in / 1.0k out (+298.5k cache-read) · Go: 5h 4% · wk 13% · mo 89%
📜 Full session transcript
38e6cc90330c876b9376🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
I read the diff only and did not run the build or the e2e suite. I'm relying on the PR's reported results (584 unit tests, 162 e2e specs).
I found no new correctness problems, so my earlier approvals stand.
Three minor notes from earlier passes are still open. None blocks merging:
aria-modal="true"has no focus trap, so Tab can leave the palette for the page behind the scrim.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the results panel blocks text selection there.🧠 claude-sonnet-5-5 · ⏱ 0m 4s · 2 turns · tokens: 47.8k in / 305 out (+12.2k cache-read)
📜 Full session transcript
✅ Verdict: approve — no blocking issues found.
Good to merge. Re-review against the checked-out source: it matches what my earlier passes verified, and nothing since has changed the picture. Relying, as before, on the PR's reported results (build + 584 unit tests green, 162 e2e passed).
Fresh spot checks, not just the diff:
SearchQuery'sDateWordsmaps heute→today and woche→week beside the English spellings, andDateFilteris a value-equal record, soDateOf()'s lit check andUse's removal work however the term was spelled;date:today(today..today) anddate:week(today..+7) are distinct filters, so the two date chips never light together.card-due-overdue/soon/later— the same ladderCardView.razoruses, with all three classes present inapp.css. Note the PR description's judgement-call section still says search rows wear onlycard-duepluscard-due-overduepending #252; the code has since taken the full state thatCardViewuses. If #252 restyles.card-due-soon, the follow-up it promises may already be done — worth confirming the description is just stale.--sidebar-wis 0px at:rootand 244px only from 960px, so the palette's centring math and the desktop trigger breakpoint agree; the phone'sinset: 0 0 var(--keyboard-inset, 0px) 0overrides the desktop inset exactly where the search goes full screen.tabindex="-1", so a click on its non-focusable content (the keys footer, exercised in the e2e spec) focuses the palette itself and its@onkeydownsees Escape; the field's@onkeydown:stopPropagationprevents a double dismiss.Three minor notes carried from my earlier passes, unchanged and non-blocking:
aria-modal="true"has no focus trap, so Tab can walk out of the palette onto the dimmed page.<p>sits inside therole="listbox"element, which is not a valid child for that role.@onmousedown:preventDefaulton the whole results panel also blocks text selection there.⏱ 1m 4s · 27 steps · $0.0520 · tokens: 88.7k in / 2.2k out (+1155.5k cache-read) · Go: 5h 6% · wk 14% · mo 90%
📜 Full session transcript