Skip to content

feat(ui): migrate remaining P1/P2 surfaces to shadcn/Radix primitives#209

Merged
HomenShum merged 4 commits into
mainfrom
feat/radix-primitives
Jul 17, 2026
Merged

feat(ui): migrate remaining P1/P2 surfaces to shadcn/Radix primitives#209
HomenShum merged 4 commits into
mainfrom
feat/radix-primitives

Conversation

@HomenShum

Copy link
Copy Markdown
Owner

What

Migrates the remaining P1/P2 surfaces in docs/design/RADIX_PRIMITIVE_AUDIT.md onto
shared shadcn/Radix primitives: dialogs, command palette, notifications, People panel,
passive intelligence, mobile menus/sheets, nested readers, tooltips, cell history,
evidence previews, and notebook patch overlays.

Adds src/design/uiLayerPolicy.ts + scripts/ui-layer-audit.ts to gate the layer
boundary, wired into design:audit.

Specialized spreadsheet, notebook, deck, and graph interaction engines remain
intentionally specialized.

Honest scope note

This does not fix broken behaviour — it removes duplicated behaviour. A Playwright
probe against origin/main confirms focus trapping, Escape handling, outside dismissal
and focus restoration already worked. The value here is that every surface now inherits
one implementation instead of re-deriving it per surface.

Before/after proof

Captured with Playwright against built previews of origin/main (before) and this
branch (after) — see docs/design/ui-contract/20260717-radix-primitives/.

check before after
focus starts inside dialog yes yes
focus stays inside after 12 Tabs yes yes
Escape dismisses yes yes
focus restored to trigger yes yes
outside click dismisses yes yes
horizontal overflow @1280x860 / @390x844 0px / 0px 0px / 0px
console errors none none

Room surface is visually unchanged (before-02/after-02 identical size). Only visible
delta: command-palette rows are ~3px tighter from shadcn CommandItem padding, fitting
one more row in the height-capped list.

Gates

  • npm run floor: 2,499/2,501 passed. The 2 failures (proofloopStandaloneRunnerDogfood,
    spreadsheetBenchChunkedRepair) are pre-existing 5s-timeout load flakes and pass in
    isolation; neither is touched by this branch.
  • design:audit + ui:layer-audit: pass (588 source files). The 531 token-drift warnings
    are advisory and pre-existing.
  • Typecheck: clean. (400 pre-existing errors traced to a stale install missing
    @convex-dev/auth, which degraded DataModelFromSchemaDefinition to Id<string>;
    fixed by npm install, not by this branch.)

Known follow-up (not addressed here)

Neither implementation marks #root aria-hidden while a modal is open, so background
content stays in the a11y tree on both sides. before had aria-modal="true"; after
does not (Radix drops it in favour of hideOthers, which is not marking #root here).
Worth a focused follow-up.

🤖 Generated with Claude Code

HomenShum and others added 3 commits July 17, 2026 03:18
Replaces handwritten dialog/overlay/menu implementations with shared
shadcn+Radix primitives across dialogs, command palette, notifications,
People panel, passive intelligence, mobile menus/sheets, nested readers,
tooltips, cell history, evidence previews, and notebook patch overlays.

Focus trapping, Escape handling, outside dismissal, collision placement,
and focus restoration now route through the shared primitives instead of
per-surface hand-rolled logic. Specialized spreadsheet, notebook, deck,
and graph interaction engines remain intentionally specialized.

Adds src/design/uiLayerPolicy.ts + scripts/ui-layer-audit.ts to gate the
layer boundary, wired into design:audit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolves 6 conflicts. Import blocks in Chat.tsx and Artifact.tsx keep both
sides. All four xlsx-export conflicts in Artifact.tsx resolve to origin/main,
whose applyExportCell handles imported styles, fonts, fills, alignment,
borders and numFmts; the local side was an earlier draft superseded by
PRs #191-#208.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…migration

Playwright capture against built previews of origin/main (before) and this
branch (after), plus a behavioural probe of the command palette.

Records honestly that focus trap, Escape, outside-dismiss and focus restoration
already worked before this change, and that the background aria-hidden question
is unresolved on both sides.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
noderoom Ready Ready Preview, Comment Jul 17, 2026 7:39pm

Request Review

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Scaffold Handoff — For Your Coding Agent

Your coding agent (Codex, Claude Code, etc.) should apply the accepted
scaffold proposals below. Do NOT touch any immutable files.

Immutability Check

Mode: advisory

✅ No immutable files were modified in this branch.

Changed Files

  • docs/design/FRONTEND_LAYER_POLICY.md
  • docs/design/RADIX_PRIMITIVE_AUDIT.md
  • docs/design/ui-contract/20260717-radix-primitives/README.md
  • docs/design/ui-contract/20260717-radix-primitives/after-01-landing-desktop.png
  • docs/design/ui-contract/20260717-radix-primitives/after-02-room-desktop.png
  • docs/design/ui-contract/20260717-radix-primitives/after-03-command-palette.png
  • docs/design/ui-contract/20260717-radix-primitives/after-04-mobile-390x844.png
  • docs/design/ui-contract/20260717-radix-primitives/after-05-mobile-room.png
  • docs/design/ui-contract/20260717-radix-primitives/before-01-landing-desktop.png
  • docs/design/ui-contract/20260717-radix-primitives/before-02-room-desktop.png
  • docs/design/ui-contract/20260717-radix-primitives/before-03-command-palette.png
  • docs/design/ui-contract/20260717-radix-primitives/before-04-mobile-390x844.png
  • docs/design/ui-contract/20260717-radix-primitives/before-05-mobile-room.png
  • docs/eval/OFFICIAL_BENCHMARK_READINESS.md
  • docs/eval/OFFICIAL_BENCHMARK_TASK_COVERAGE.md
  • docs/eval/OPENROUTER_CONVEX_BENCHMARK.md
  • docs/eval/agent-improvement-loop.md
  • docs/eval/agent-improvement-loop.svg
  • docs/eval/agent-improvement-loop/20260717T193845Z.json
  • docs/eval/agent-improvement-loop/latest.json
  • docs/eval/agent-workspace-sandbox-smoke.json
  • docs/eval/algorithm-artifact-smoke.json
  • docs/eval/bankertoolbench-official-contract.json
  • docs/eval/docker-sandbox-probe.json
  • docs/eval/eval-runs.jsonl
  • docs/eval/halo-convex-context-telemetry.json
  • docs/eval/halo-self-improvement-smoke.json
  • docs/eval/halo-variant-selection.json
  • docs/eval/official-benchmark-readiness.json
  • docs/eval/official-benchmark-task-coverage.json
  • docs/eval/openrouter-convex-benchmark.json
  • docs/eval/professional-catalog-proofs.json
  • docs/eval/professional-proof-ledger.json
  • docs/eval/spreadsheetbench-chart-visual-probe.json
  • docs/eval/traces/credit/20260717T193854618Z-ca928d1d_dirty.515bdd75f3519687/cascade-healthy.json
  • docs/eval/traces/credit/20260717T193854618Z-ca928d1d_dirty.515bdd75f3519687/delta-incomplete.json
  • docs/eval/traces/credit/20260717T193854618Z-ca928d1d_dirty.515bdd75f3519687/mapping-correct.json
  • docs/eval/traces/credit/20260717T193854618Z-ca928d1d_dirty.515bdd75f3519687/mapping-misbind.json
  • docs/eval/traces/credit/20260717T193854618Z-ca928d1d_dirty.515bdd75f3519687/summit-stressed.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L1_read_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L2_edit_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L3_conflict_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L4_blocked_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L5_large_range_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L6_long_horizon_scripted.json
  • docs/eval/traces/ladder/20260717T193854128Z-ca928d1d_dirty.7fca92cc66b9ce3a/ladder_L7_resume_scripted.json
  • e2e/full-modern-ux-bar.spec.ts
  • package.json
  • scripts/ui-layer-audit.ts
  • src/app/styles.css
  • src/components/ai-elements/shimmer.tsx
  • src/components/ui/command.tsx
  • src/components/ui/dialog.tsx
  • src/components/ui/hover-card.tsx
  • src/components/ui/popover.tsx
  • src/design/uiLayerPolicy.ts
  • src/ui/Chat.tsx
  • src/ui/CommandPalette.tsx
  • src/ui/Landing.tsx
  • src/ui/NotificationsInbox.tsx
  • src/ui/PeoplePanel.tsx
  • src/ui/command-palette.css
  • src/ui/insights/NoteworthyInbox.tsx
  • src/ui/insights/PassiveAgentChip.tsx
  • src/ui/mobile/MobileApp.tsx
  • src/ui/mobile/MobileTooltip.tsx
  • src/ui/mobile/mobile.css
  • src/ui/mobile/mobile.shell.css
  • src/ui/mobile/mobileFrame.css
  • src/ui/mobile/shell/MobileHeader.tsx
  • src/ui/notifications.css
  • src/ui/panels/Artifact.tsx
  • src/ui/panels/artifact-receipts.css
  • src/ui/panels/notebook-paper.css
  • src/ui/people-panel.css
  • src/ui/primitives/FocusTrapDialog.tsx
  • tests/chatModelPickerPolish.test.tsx
  • tests/commandPalette.test.tsx
  • tests/mobileHeader.test.tsx
  • tests/mobileSheetDialog.test.tsx
  • tests/mobileTooltip.test.tsx
  • tests/peoplePanel.test.tsx
  • tests/setup/dom.ts
  • tests/uiLayerPolicy.test.ts

Needs Adversarial Review — Do NOT Apply Yet

These proposals passed the reject check but have not been approved by
an adversarial reviewer. A human or frozen LLM judge must approve them first.

  • scaf-001 (AGENTS.md): Add explicit instruction for step spreadsheetbench-runner-fixture: Step spreadsheetbench-runner-fixture failed — scaffold may need explicit instruction or evidence assertion.
  • scaf-002 (AGENTS.md): Add explicit instruction for step convex-boundaries: Step convex-boundaries failed — scaffold may need explicit instruction or evidence assertion.

Safety Boundary

Agent may improve the scaffold.
Agent may NOT weaken the proof gate.

Immutable files (never modify):

  • scripts/proofloop.mjs
  • scripts/agent-improvement-loop.ts
  • tests/harnessChangeEval.test.ts
  • .github/workflows/
  • src/eval/evalTrustPolicy.ts
  • src/eval/architectureBudget.ts
  • evals/evalStore.ts

Scaffold files (safe to modify):

  • AGENTS.md
  • CLAUDE.md
  • proofloop/scenarios/*.yaml
  • proofloop/rubrics/*.yaml
  • proofloop/subagents/*.md
  • proofloop/adapters/*.js
  • .proofloop/memory.jsonl
  • src/nodeagent/models/prompts/systemPrompt.ts

The mobile FAB fan migrated to Radix DropdownMenu, so its items expose
role=menuitem. Query the accurate role instead of the old literal <button>.
Verified against the built preview: 120s click-timeout -> 6.8s pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@HomenShum
HomenShum merged commit c89233c into main Jul 17, 2026
11 checks passed
@HomenShum
HomenShum deleted the feat/radix-primitives branch July 17, 2026 19:46
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