Skip to content

Render real document context and control states in the audit's content and controls plates - #633

Merged
MaggieAppleton merged 6 commits into
mainfrom
audit-content-controls
Oct 15, 2026
Merged

MaggieAppleton merged 6 commits into
mainfrom
audit-content-controls

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Part of the design-audit honesty pass (base: #626). The authored-content, controls, errors and foundations plates now render the components and rules the app renders.

What was fake, and what it renders now

Authored content. StaticPlanEditor hard-coded design-audit-static-plan inside @chopin/editor, and the audit used it to override .plan-content padding, .plan-workspace/.plan-document height, .mdxeditor min-height, image and diagram max-height, the research composer's width and the research cards' height. StaticPlanEditor now takes a className. Every specimen sits on the real paper and measure. The only context the plate sets is --document-trailing-space: 0px, so a specimen ends where its content ends.

Research. The composer now renders inside ResearchDraftShell, the shell the live composer opens in. The cards stack in the document column at their real width, not in a 15rem grid.

Tables. The selected-cell, toolbar and overflow states were a hand-built <table> with fake "Add row/Add column" buttons. They are now:

  • the default table at document size
  • a phone-width document (with the compact gutter its media query picks), where the real table overflow lane shows
  • the real phone action dock, rendered through TableActionToolbarView

Tables before
Tables after
Research before
Research after

Buttons. Hover and press were faked with [data-audit-state] rules that copied theme.css values, and btn-outline had none. theme.css now has a data-force-state seam inside each button variant's hover and press selectors (&:is(:hover, [data-force-state="hover"]):not(:disabled)) and on the global focus ring. The copied rules are deleted. Specificity is unchanged and nothing in the app sets the attribute. Outline now shows its real hover and press.

Buttons before
Buttons after

Icon buttons render the real IconButton in its ghost, nested and compact recipes. Its hover/focus fill in navigation.css also answers data-force-state, and IconButton passes the attribute through. The sidebar-placement variants only reveal on row hover, so they belong to the sidebar plate.

Icon buttons after

Links. .design-audit-link was invented. A new link utility in theme.css uses the dominant live treatment (brand ink, underline on hover). repository-picker.tsx ("Configure", "Try again") and build-view (.build-link) now use it; both were the same treatment written ad hoc. The plate shows only the states links actually have: Default, Hover and Focus. Two call sites were left alone because they look different: new-document-dialog's always-underlined text-brand link and .navigation-creation-status button.

Links before
Links after

Fields. The overrides of .field padding, font and width are removed, and the inputs use the live classes (field h-8 w-full px-2 text-sm; the textarea uses excerpt-correction's classes). The visuals Select was never used live, so it leaves the plate. The adoption plate now says no shared control is adopted.

Fields before
Fields after

Errors. TerminalAlert took its colour from audit CSS; it now passes text-sm text-destructive-ink as production does. The recoverable case is the real NavigationError (InlineNotice with its retry), not a fake box.

Errors before
Errors after

Foundations. The presentation table's forced min-width is gone; the narrow example is now labelled a narrow container. The invented icon "active/disabled" colours are replaced by the real default and icon-danger roles.

Presentation tables after

Extractions

  • TableActionToolbarView in packages/editor/src/table/action-toolbar.tsx is a pure move of the dock markup. TableActionToolbar keeps the Lexical selection sync, placement and scroll padding, and renders the view with the same props, classes, aria and handlers. A unit test covers the view's groups, align label and placement.
  • ResearchDraftShell and TableActionToolbarView are now exported from @chopin/editor.

Risks

  • theme.css touches every button variant and the global focus ring. The selectors keep their specificity, and the button plate renders identically to before, apart from Outline gaining its real states.
  • .build-link hover underline is now gated by @media (hover: hover), like Tailwind's hover: on the other two sites. Touch devices no longer keep a sticky underline.
  • The table rails (TableChrome in full mode) need an editable editor with a live cell selection, so they are not shown. The phone dock shows no selected-cell wash for the same reason.
  • e2e/design/snapshots baselines will change for these plates. responsive.e2e.ts now checks the real table's overflow lane. The old keyboard-scroll check exercised the fake focusable wrapper; a read-only editor table has no focus stop.

Design contract

The reviewed hashes are renewed in a separate commit. Data flow is unchanged for foundations.tsx, icons.tsx, controls.tsx, repository-picker.tsx and static-plan-editor.tsx. One new exact exception covers StaticPlanEditor's forwarded className, using the same reason as the other class-forwarding components.

Checks

bun run types, bun test apps/web packages/editor (1677 pass), bun scripts/check-design-contract.ts, bun scripts/check-tokens.ts, bunx oxlint on changed files.

🤖 Generated with Claude Code

Base automatically changed from audit-split-plates to main October 15, 2026 10:34
@MaggieAppleton
MaggieAppleton force-pushed the audit-content-controls branch 4 times, most recently from 6171eb1 to ce6401a Compare October 15, 2026 11:29
MaggieAppleton and others added 6 commits October 15, 2026 12:54
StaticPlanEditor takes a className instead of hard-coding the audit's.
The audit drops its padding, height, width and max-height overrides and
renders each specimen on the real paper and measure. Research shows the
composer inside its live draft shell. The table plate's hand-built
toolbar and selected table are replaced by TableActionToolbarView, a
pure extraction of the phone dock's markup from TableActionToolbar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Buttons, icon buttons, links and fields now render the app's own rules
in each state. theme.css gains a data-force-state seam inside each
button variant's hover and press selectors and the global focus ring,
and navigation.css lets IconButton's hover fill answer it; nothing in
the app sets the attribute. The audit's copied state rules are gone.

Icon buttons render IconButton in its tones and sizes. A new link
utility (brand ink, underline on hover) replaces the invented audit
link and the two identical ad hoc treatments in repository-picker and
build-view. Fields lose their padding and font overrides and use the
live field classes; the unused Select leaves the plate, and the adoption
plate now says no shared control is adopted.

Errors pass text-destructive-ink as production does and render the
real NavigationError for the recoverable case. Foundations drop the
presentation table's forced min-width and the invented icon states,
showing the real default and danger icon roles instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Renews the reviewed source hashes for:
- apps/web/src/design-audit/foundations.tsx: type-scale labels lose their
  middle dots and the narrow table example is renamed. The dynamic var()
  names still come from the same finite token lists.
- apps/web/src/design-audit/icons.tsx: the icon state row shows the real
  default and danger roles. Glyph classes still come from NUCLEO_ICONS.
- apps/web/src/design-audit/controls.tsx: ButtonRow still combines
  btn btn-md with static tier classes from its callers; the other plates
  pass only static classes and literal IconButton recipes.
- apps/web/src/repository-picker.tsx: two static class strings become
  the link utility. Popup position and presence classes are unchanged.
- packages/editor/src/static-plan-editor.tsx: the plugin params spread
  is unchanged.

Data flow of every reviewed sink is unchanged. One new exact exception
covers StaticPlanEditor's new className, which forwards the caller's
static class beside plan, as other class-forwarding components do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test

IconButton's new data-force-state prop pushed the initial JavaScript 33 B
over its budget. The audit now sets the attribute on the mounted button
through its existing ref, so IconButton is unchanged from the base.

The design behaviour suite still drove the shared Select in the fields
plate, which this branch removed because the app never uses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ebase

On top of main's 16px icons, controls.tsx keeps this branch's IconButton
recipes and icons.tsx its real colour roles; no class, style or spread data
flow changed. Approved by the design owner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton enabled auto-merge (rebase) October 15, 2026 11:55
@MaggieAppleton
MaggieAppleton merged commit c08e96e into main Oct 15, 2026
24 checks passed
@MaggieAppleton
MaggieAppleton deleted the audit-content-controls branch October 15, 2026 11:59
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