Repository navigation
fix(console): a long flow screen or action parameter list keeps Submit / Confirm on screen (objectui#12080) - #12088
Merged
objectstack-fleet[bot] merged 1 commit intoOct 10, 2026
Conversation
… on screen (objectui#12080) A flat flow screen and the action parameter dialog had no height bound, so a screen or params list taller than the window overflowed both edges of the fixed, scroll-locked overlay: heading above the top, primary action below the bottom, nothing a mouse wheel could move. Both dialogs are now a flex column at most 90vh tall: the header on top, the fields in the one scrolling region, the footer outside it. More than eight declared fields (or shown params) also widens the dialog to the object-form step's sm:max-w-3xl with two columns from sm up; shorter screens and lists keep their width and single column. Claude-Session: https://claude.ai/code/session_01B1gHb9baeX7oioD5sHVm7z Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-12080-screen-dialog-reach
branch
October 10, 2026 10:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12080
Clause-②: no
A flow
screendialog without an object form, and the action parameter dialog, had no height bound. A screen or aparamslist taller than the window overflowed both edges of the fixed overlay: the heading above the top, Submit or Confirm below the bottom. The overlay locks page scrolling, so a mouse wheel moved nothing. This PR bounds both dialogs and keeps their primary action on screen. A long screen or list also gets a wider, two-column dialog.Implemented by the dispatched os-dev agent for the
domain:ui#3seat, sessionhttps://claude.ai/code/session_01B1gHb9baeX7oioD5sHVm7z, on the claim6095670021. It follows triage's first grade6093518840: reach first, width is the renderer's choice, and no new spec layout key.What changed
Two files, the ones the claim named:
FlowRunner.tsxandActionParamDialog.tsxinpackages/app-shell/src/views/.DialogContentbecomes a flex column at most90vhtall. Only the field region between the header and the footer getsmin-h-0 flex-1 overflow-y-auto, so it is the only part that gives up height and scrolls. The footer sits outside that region and stays on screen. The region runs to the dialog edges (-mx-6 px-6), so the scrollbar sits on the border and focus rings are not clipped.sm:max-w-3xl, the width the object-form step already used, and the screen body becomesgrid gap-4 sm:grid-cols-2. An action with more than eight shown params gets the same. Shorter screens and lists keep their width (sm:max-w-mdand the defaultmax-w-lg) and their single column. The screen counts declared fields, so a field thatvisibleWhenreveals mid-edit does not make the dialog jump width. The params dialog counts the params itsvisiblegate shows, which do not change while the dialog is open.sm:max-w-3xlandmax-h-[90vh]. The scroll moved from the whole dialog to the body, so the step's heading and close button now stay in view. Its own Save bar is still inside the body, as before.no).ScreenViewis unchanged: the runner passes the grid classes through its existingclassName.Why not a shared primitive. The unbounded default comes from
DialogContentin@object-ui/componentsui/dialog.tsx, the Shadcn-synced no-touch zone (AGENTS.md section 5, rule 7). A bounded wrapper undercustom/would be a new export of@object-ui/components, which would change Clause-②. It would also fix nothing until each consumer moved to it. So the fix stays in the two consumers named on the card. A parity pin makes sure their bounds cannot drift apart without a test going red.Measured in Chromium: a real mouse wheel and a real click
Harness: a scratch entry served by the console's own Vite config, aliases and
index.css. It mounts the realFlowRunner(13 flat fields, in the card's intake order) and the realActionParamDialog(22 params). The harness was never committed. Chromium 1194 (/opt/pw-browsers/chromium), reduced motion. Steps for each case:mouse.wheelticks of 300px.elementFromPointat its centre.mouse.clickthat point and read the result. This is the toast for missing required fields, or the dialog's required errors.Final run at
ca44673.023f00d, 13-field screen023f00d, 22 paramsOther windows, this PR only:
Unit pins (the class and structure contract that measurement rests on)
The test DOM has no layout, so these files pin the contract, not the pixels:
packages/app-shell/src/views/__tests__/FlowRunner.dialogReach-12080.test.tsxpackages/app-shell/src/views/ActionParamDialog.dialogReach-12080.test.tsxThey check five things:
DialogContent, and the dialog as a whole does not scroll.Reverse verification, from the committed fix.
git checkout 023f00d -- FlowRunner.tsx ActionParamDialog.tsx. Disk check:isLongScreen3 → 0 hits,isLongList3 → 0,max-h-[90vh]in the params dialog → 0. Result: 15 of 15 tests failed,Test Files 2 failed (2). Restored withgit checkout HEAD -- …. Both blobs then hash to HEAD's (481cb37d,f409340c),git diff HEADis empty, the index is clean, and both hit counts are back to 3. Read this together with the controls: the control cases fail on BASE because the scrolling body they read does not exist there, not because the width changed. Their unchanged width is shown by the browser rows above.Gates (at
ca44673)pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build→ exit 0 (dependency closure for type-check)pnpm --filter @object-ui/app-shell type-check→ exit 0 (tsc --noEmit && tsc -p tsconfig.test.json; the test config'sincludeissrc/**/*.test.tsx, so both new files are covered)pnpm exec vitest run --maxWorkers=2over the 24 affected files (the 9FlowRunner*+FlowRefusalNotice, the 9ActionParamDialog*, theScreenView*files, and the twoparamDialogTitleconsumers) →Test Files 24 passed (24),Tests 206 passed (206)--format json: 4 files, 0 errors). The 16 warnings are all on untouched lines (no-explicit-any,set-state-in-effect,only-export-components). The narrowing is sound because type-aware linting is off:eslint.config.jssets noparserOptions.projectorprojectService, so this diff cannot change a verdict on an untouched file.pnpm check:new-line-citations→0 new citation(s);pnpm check:control-bytes→ OKnode scripts/check-changeset-presence.mjs→ ok (1 changeset);check-changeset-no-major.mjs→ ok;check:changeset-claims,check:pending-changeset-literals,check:i18n-keys,check:test-path-roots,check:unreferenced-sources→ all exit 0check:eager-closure. Reason: it needs a full console production build. No module joins or leaves the first-load closure: the only new imports arecnfrom@object-ui/componentsandscreenFieldsfrom./ScreenView, and both modules were already imported. The byte delta is the added class literals and is left to CI's Bundle Analysis.Acceptance notes
DialogContent. Most of them show short, fixed content. None was measured, and none is touched here. Instrument:git grep -n "DialogContent" -- 'packages/*/src/**/*.tsx', read per call site. Carrier: none.90vhbound at 1440×900, measured once (above). The comment on the constant says that it is a one-time reading.Generated by Claude Code