Repository navigation
fix(plugin-form): each form section draws its own columns count per row (objectui#12548) - #12556
Conversation
…ow (objectui#12548) A sectioned form draws every section in one field grid sized by the widest section, and each field spanned Math.round(grid / sectionColumns) cells. A section whose count did not fit that grid drew the wrong number per row: a columns: 2 section beside a columns: 3 one drew one field per row, and a columns: 3 section beside a columns: 4 one drew four. The five sectioned hosts now share one rule, sectionedGridLayout in autoLayout.ts. A form whose sections are all 1 or the grid width keeps its grid and spans byte for byte. Otherwise the grid is 12 tracks from @md and a field spans twelfths of the row; the components form renderer draws a twelfths colSpan with each count's existing step ladder (2 per row at @md, 3 at @2XL, 4 at @4XL). Claude-Session: https://claude.ai/code/session_01DN3fpUznSTqNMkk9nXd5BG Co-authored-by: Claude <noreply@anthropic.com>
✅ 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
|
Seat ACCEPT: objectui PR #12556 at
|
| Claim | Head | Base | Verdict |
|---|---|---|---|
| A. Leads → New, 1440 | Contact rows [2,1,2,2,2] at 627 / 627 px, last_name alone at 1270; Classification [3,3,1] at 412.7 |
Contact 1 per row at 841.3 (the card's reading); Classification [3,3,1] at 412.7 | PASS |
A, the collapsed sections, on the full-page /crm_lead/new |
Company [2] at 440 / 440, Privacy [2], Additional [1,1], Address [1] (its one field is span: 'full') |
Company and Privacy 1 per row at 592 | PASS |
B. 1024 (container 874.8, the @2xl tier) |
Contact 2 per row at 429.4; Classification [3,3,1] at 280.9 | Contact 1 per row at 577.9 | PASS |
B. 768 (container 631.6, the @md tier) |
Contact 2 per row; Classification [2,2,2,1], so a 3-column section reads 2 per row at @md as claimed |
Contact 1 per row | PASS |
| C. Phone sheet, 390 | 1 column, 358 px | identical | PASS |
D. CONTROL, crm_task (all columns: 2) |
grid @md:grid-cols-2, counts and widths identical to base, 0 px difference |
— | PASS |
E. Lead → Edit (the same dialog, ?form=) |
identical to A | Contact 1 per row | PASS |
The dev's open questions, answered by the seat. Each is an implementation choice inside the rulings:
- B: keep each density's step ladder through the literal table, which leaves the classification section's widths unchanged.
- A: in a mixed form, an authored
colSpancounts its own section's columns, read against the per-sectionFormSectionSchema.columns. A single-density form keeps the old reading. - A: one function, which returns the old grid when every section fits, so the byte-identical CONTROL holds.
Out of scope:
- The components
style.cssscan note goes to Acceptance notes, with no carrier. - The helper found a defect on head and base alike: in the Leads create/edit dialog, clicking a collapsed section's header remounts the dialog and the section stays collapsed. It is filed as a
finding(next comment on the card).
Serial: PR objectui#12546 (objectui#12521, held on a decision) edits ModalForm.tsx and autoLayout.ts in other regions. It merges main in its rework round.
Landing: ready and auto-merge now. Its merge closes objectui#12548. The seat archives the cloud session session_01DN3fpUznSTqNMkk9nXd5BG after the merge.
Generated by Claude Code
Resolves ModalForm.tsx against objectui#12548 (PR #12556, the per-section 12-track grid) and objectui#12559 (PR #12571, the dialog-owned Suspense boundary). The sectioned dialog keeps this branch's grid width (sectionedDialogColumns) and lays each section out through sectionedGridLayout, so both landed behaviours stand. Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB Co-authored-by: Claude <noreply@anthropic.com>
Fixes #12548
Clause-②: no — no type, prop, export or spec declaration changes;
sectionedGridLayout/TWELVE_TRACK_GRID_COLSlive inautoLayout.tsand are not re-exported from the package entry.What changed
A sectioned form draws all its sections in ONE field grid, sized by the widest section, and each field spanned
Math.round(grid / sectionColumns)cells of it. When a section's count did not fit that grid, the section drew the wrong number of fields per row. Measured onmainat9c2785b, ModalForm, 2 / 3 / 1 form:columns: 2fieldgrid-cols-1 @md:grid-cols-2 @2xl:grid-cols-3@md:col-span-2→ one per row at every tiercolumns: 3fieldcolumns: 1field,span: 'full'@md:col-span-2 @2xl:col-span-3(correct)columns: 3besidecolumns: 4… @4xl:grid-cols-4@4xlObjectForm, SplitForm, TabbedForm and WizardForm (under a form-level
columns: 3) drew the same classes.One shared rule,
sectionedGridLayout(formColumns, sectionColumns[])inpackages/plugin-form/src/autoLayout.ts, now called by all five hosts in place of the per-hostapplyAutoColSpan+containerGridColsForpair:CONTAINER_GRID_COLSgrid and the oldapplyAutoColSpanspans. Single-density forms, and forms with no sectioncolumns, are therefore byte-identical.grid gap-4 grid-cols-1 @md:grid-cols-12, and each field'scolSpancounts twelfths of the row:span: 'full'and wide widgets take 12;colSpancounts that many of its own section's columns, clamped to them;columnsstill outranks it.@object-ui/componentsform renderer (where the span classes are drawn): on a container carrying@md:grid-cols-12, a twelfthscolSpanmaps through a literal table,TWELVE_TRACK_SPAN_CLASS. The table keeps each count's existing step ladder:columns@md/@2xl/@4xl@md:col-span-12@md:col-span-6@md:col-span-6 @2xl:col-span-4@md:col-span-6 @2xl:col-span-4 @4xl:col-span-3@md:col-span-12 @2xl:col-span-8@md:col-span-12 @4xl:col-span-9Below
@mdthe form stays one column. Every other container is rendered by the old code path, unchanged. The literal'@md:grid-cols-12'sits in components' source, so the publishedstyle.csscarries the utility too.Verification record (at
88bfef0)plugin-form/src/__tests__/mixedSectionColumns-12548.test.tsx(25 tests):columns: 3), a 2 / 3 / 1 form reads 2 / 3 / 1 per row at@4xland 2 / 2 / 1 at@md, and the 3-column section reads 3 at@2xl;span: 'full'takes the row; basegrid-cols-1; 3-beside-4 reads three per row;columns: 2and allcolumns: 3, per host, keep the literal grid and span classesmaindrew;min(columns, tier)againstCONTAINER_GRID_COLS[4]'s tiers;components/src/renderers/form/__tests__/form-twelve-track-span-12548.test.tsx(7), including a CONTROL that the 1–4 containers emit as before.main: the mixed pins red, the CONTROLs green.sectionedGridLayoutforced to the old path. 12 mixed pins red, 13 green (all 8 CONTROLs among them). Restore was proven by blob hash and an emptygit diff HEAD.pnpm --filter '@object-ui/plugin-form^...' build→ 0pnpm --filter @object-ui/plugin-form type-check→ 0pnpm --filter @object-ui/components type-check→ 0packages/plugin-formsuite: 184 files, 2269 passed, 1 skipped → 0components/src/renderers/form/__tests__/*: 225 files → 0check:control-bytes,check:new-line-citations(0 new),check-changeset-presence,check-changeset-no-major,check:changeset-claims,check:pending-changeset-literals,check:test-path-roots,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:unreferenced-sources, eslint on the 9 changed files (0 errors) → all 0apps/console/src/index.cssemits@md:grid-cols-12,@md:col-span-{6,12},@2xl:col-span-{4,8}and@4xl:col-span-{3,9};@md:col-span-8and@2xl:col-span-12are absent, as expected. Compilingpackages/components/src/index.cssalso emits@md:grid-cols-12.check:readme-exports(needs every package's dist; no export changed) andperformance-budget(a full console build). Both are left to CI.What the landing seat's browser reading should show
HotCRM Leads → New. Pre-merge reading: the HotCRM-shaped DOM rendered by
ModalForm, measured in Chromium with the console's Tailwind build:last_name(span: 'full')At 1440 the seat should see:
last_nameon its own full row;Acceptance notes
inferModalSize,modalSize,AppContent.tsx) and the no-section-columnsdefault are untouched. objectui#12521 and PR fix(plugin-form): a record dialog with no authored layout opens bounded with a two-column grid (objectui#12521) #12546 keep them. fix(plugin-form): a record dialog with no authored layout opens bounded with a two-column grid (objectui#12521) #12546 touchesModalForm.tsxandautoLayout.tsin different regions, so expect a merge ofmainin its rework round.colSpancounts its SECTION's columns (2 in a 3-column section = two thirds of the row). Before, it counted cells of the widest section's grid. A single-density form keeps the old reading.colSpan: 2in acolumns: 4section of a mixed form reduces to one half and reads half the row at every tier. On a 4-only grid it reads full / two thirds / half.gridClassNamein a tabbed or split form with mixed densities sits beside twelfths spans. That combination was already inconsistent before this change.scripts/pm/dispatch-gates.mjs, so the gate list was derived by hand frompackage.jsoncheck:*and the workflows.🤖 Generated with Claude Code
https://claude.ai/code/session_01DN3fpUznSTqNMkk9nXd5BG