Repository navigation
feat(console): dialog and drawer pattern - #2879
Conversation
One .dialog chrome (radius, border, shadow, backdrop, open motion) for the Stop, Delete, Plugins, Slack and Secret dialogs, with --wide and --drawer variants and a bottom sheet under 760px.
…urn focus Sheets hug their content (height fit-content, not auto, which stretched the Stop sheet to full height under the UA inset).
…ecret dialog spacing Close no longer becomes a full-width bar under the title at 760px and below, and the Secret dialog's fields no longer add page margins to the form gap.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
…ot replay it Resizing an open plugin dialog into the phone breakpoint switched the animation name and replayed the sheet slide, so console-agent-presets found Next page off screen. Every variant now runs dialog-open with a per-variant starting offset; phone sheets start 32px low with a fade instead of a full slide. Widths use % of the modal's viewport box rather than 100vw, the Delete dialog's form-actions match dialog-actions, and the Secret dialog spacing moves next to the pattern. The test checks the drawer geometry, the exact animation, and no replay on resize.
|
Codex review: needs changes before merge. What this changesThis PR gives five console dialogs shared styling, opening animations, and bottom-sheet layouts on narrow screens. Example: Open Create Secret at a 390 × 844 viewport.
Review scores
ProductKind: Feature · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Needs changes before merge - 2 items remain Keep this PR open: it consolidates inconsistent console dialogs with maintainer-approved direction, but the required Storybook updates remain incomplete and the failed browser check needs diagnosis. Priority: P3 Before merge
Findings
Tests
Agent review detailsHow this fits togetherThe controller serves console JavaScript and styles; existing Agent, channel, and Secret controls construct native dialogs whose layout responds to viewport size and motion preferences. flowchart TB
User[Console user] --> Controls[Existing console controls]
Controls --> Dialogs[Native modal dialogs]
Styles[Shared dialog CSS] --> Dialogs
Viewport[Viewport and motion preferences] --> Styles
Dialogs --> Actions[Existing guarded actions]
Technical reviewBest possible solution: Retain the shared CSS owner and existing action guards, complete the Storybook coverage, and establish a clean browser-check result. Do we have a high-confidence way to reproduce the issue? Current main has separate Stop/Delete, plugin, and channel dialog sizing and chrome; source inspection confirms the inconsistency, while the reported browser runs were not independently executed. Is this the best way to solve the issue? Consolidating presentation in the existing console stylesheet is a focused solution that preserves the existing lifecycle and security owners. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 39dead53499d. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
Likely related people:
Review metrics
LabelsLabel changes:
Label justifications:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 18, 2026, 6:12 PM ET / 22:12 UTC. |
Components/Dialogs frames the Stop, Delete, Plugins, Slack drawer and Create Secret scenarios at desktop and phone width, and dialog-pattern-workflow.md walks the chrome, focus, dismissal, sheets and reduced motion.
Problem
The console has four dialog styles (UX audit 2.8, findings 1915 and 1926):
The backdrop is defined in four places. On a phone there are three behaviours: the channel drawer becomes a bottom sheet, the plugin dialog a full card, and Stop/Delete a centred box. The Secret and Slack sheets are clamped to 341 px and pinned left by the browser's
dialog:modalmax-width (finding 1915), and the drawer's Close button becomes a full-width bar under the title.Change
UX plan C6, following the Dialog row of the design language.
.dialog(console.css):--radius-lg,--color-border,--shadow-2,--space-6padding,width: min(32rem, 100vw - 2 * --space-4), one::backdrop(--color-overlay), and one--duration-baseopen animation (dialog-open; each variant sets only its starting offset). Reduced motion turns the animation off (the duration token is already 1 ms there; the rule setsanimation: none)..dialog--wide: the plugin workspace, 72 x 52 rem..dialog--drawer: Slack and the other channels. It floats at the right edge, full height, and slides in from the right.%of the modal's viewport box, not100vw, so a classic scrollbar gutter does not eat the side gap (finding 1520).max-width: 100%lifts the browser clamp), as tall as its content up to the viewport less--space-8, rounded top corners, square bottom corners,--space-4padding. The design language's P6 rule (dialogs become sheets under 760 px) sets the breakpoint, and the channel drawer already switched there..dialog-actions: Cancel first (left), the confirming action last (right). Used by Stop, Slack and Secret.stop.mjs), Delete (deletion.mjs), Plugins (plugin-fields.mjs, where that dialog is built), the channel drawer (channels/shared-ui.mjs) and Create Secret (secret-picker.mjs, now a centred.dialoginstead of a drawer). The old class names stay on the elements because tests, stories and open PRs select them. Only their chrome rules are gone: the pink Stop/Delete edge, the plugin dialog's size/border/radius/shadow/backdrop, and.channel-dialog's size/margin/shadow/backdrop and phone sheet.channels.css)..form-fieldand empty.errormargins no longer add to the form's grid gap. That gap left about 60 px holes between Name and Value. The empty alert keeps its live region and only loses its margin.Follow-ups, left out for zero new conflict hunks:
deletion.mjskeeps theform-actionsclass instead ofdialog-actions, because feat(console): stop and delete Agents from the Agents list #2524 changes the line directly above it..dialog > .form-actionsgives it the same layout until it can be renamed.Verification
tests/browser/console-dialogs.test.mjs(mapped inchecks-browser-2.json) opens Stop, Delete, Plugins, Slack and Create Secret at 1440 x 900 and at 390 x 844. It reads each dialog after its open animation has finished (getAnimations().finished, no timers) and checks:dialog-open 0.2s; the drawer sits 16 px from the right, top and bottom edges, and the others are centred;reducedMotion: reducethe animation isnone.origin/main, same test): fails. The animation isnone 0sand the chrome differs (Stop's pink border and--shadow-1vs the others). The focus-return checks already pass on main: the rule existed, and this test now pins it for all five dialogs.taskset -c 22,23).console-agent-channels,console-agent-detail,console-agent-detail-2,console-agent-plugin-approvers,console-agent-plugin-refusals,console-agents,console-agents-2,console-repository-dedicated,console-runtime-credentials= 192/192 pass. After thechannels.csschange I re-ran the channel and Secret files: 70/70.tests/conformance/console-design-tokens.test.mjs: pass (everyvar()is defined).node scripts/ci/run-tests.mjs audit: no issues. prettier and eslint clean on touched files.cd5ce0c40):7fe4fb5a3(see Media).%instead of100vwwidths, so a classic scrollbar gutter no longer eats the side gap;form-actionsgets the.dialog-actionslayout through.dialog > .form-actions;cd5ce0c40) failed Console Browser 2 inconsole-agent-presets.test.mjs:602: "Catalog pagination must be reachable without scrolling the whole dialog". That test resizes an open plugin dialog to 390 px. The breakpoint switched the animation name, which replayed the sheet slide, so Next page was still off screen.f0536a0d1uses one animation name. That test and the new "no replay on resize" assertion pass.checks-browserandchecks-browser-2that touches the console passes locally: 579/579 in 24 files, then 112/112 for the dialog, focus-ring, presets, channels and detail-2 files after the merge. Main merged again for fix(console): repository access copy without a Repo Driver #2874 and fix(console): Create Agent harness outcome copy and workspace missing-file copy #2875 (no overlap with these files).git merge-treeof this head and oforigin/mainagainst feat(console): tabs with tablist semantics #2878, feat(console): responsive table rows for the Agents list #2877, fix(console): keep a focused workspace caret on reread and quiet plugin live regions #2860, feat: add per-agent sandbox network policies and denial review #2599, feat(console): show the authorized native Gateway people roster #2596, feat(console): stop and delete Agents from the Agents list #2524, Add OCE policy simulation and tester for network and plugin actions #2445, feat(auth): sign people in to occ with a device code (rfc-0019) #1619 and feat: assign configured OpenClaw roles to Agent users #906. Every pair has the same conflicted files and hunk counts (0 for feat(console): tabs with tablist semantics #2878, feat(console): responsive table rows for the Agents list #2877, fix(console): keep a focused workspace caret on reread and quiet plugin live regions #2860 and feat(console): show the authorized native Gateway people roster #2596; the existing conflicts of feat: add per-agent sandbox network policies and denial review #2599, feat(console): stop and delete Agents from the Agents list #2524, Add OCE policy simulation and tester for network and plugin actions #2445, feat(auth): sign people in to occ with a device code (rfc-0019) #1619 and feat: assign configured OpenClaw roles to Agent users #906 are unchanged). This PR adds no new conflicted file and no new hunk.Media
Before (main) on the left, this PR on the right. The 1440 pairs are scaled to half size. Committed in
db45acae9and deleted again before the squash. The screenshots come from the new browser test against the real console:tests/browser/console-dialogs.test.mjswith its artifact directory set. Storybook's existingstopConfirmand delete stories pick up the same classes.Walkthrough recordings, committed in
7c6697d24and deleted again: Storybook fixtures with simulated data, built from this branch's console source withprepare-assets.mjs. Each one opens Stop, Delete, Plugins, the Slack drawer and Create Secret (nested over the drawer), then closes each with Escape. Focus returns to the opener every time (Stop Agent, Delete Agent, Configure plugins, Edit Slack).prefers-reduced-motion: reduce, Stop and the Slack drawer appear without the animation (computedanimation-name: none).Storybook: new Components / Dialogs stories (Stop confirmation, Delete confirmation, Plugins (wide), Slack editor (drawer) and Create Secret, each also as a 390 px "(phone)" story) reuse the existing scenarios. New
scripts/console-storybook/dialog-pattern-workflow.mdwalks the chrome, focus, Escape and backdrop rules, phone sheets and reduced motion. I did not run the full Storybook build: the worktree has no Storybook dependencies. I prepared the fixture assets withprepare-assets.mjsand droveframe.htmlfor the recordings above.Risks