Skip to content

Compose react-ui primitives instead of raw controls - #217

Merged
TheGreatAxios merged 3 commits into
mainfrom
cl-react-ui-drift
Aug 21, 2026
Merged

TheGreatAxios merged 3 commits into
mainfrom
cl-react-ui-drift

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Summary

  • Swap hand-rolled raw DOM for react-ui primitives at 5 of the flagged check:react-ui-drift sites:
    • agent-skills-picker.tsx: raw <button> → Button (variant="link"), raw checkbox → Checkbox (labeled row mode)
    • create-agent-panel.tsx: raw <textarea> → Textarea (dropped the now-redundant custom CSS)
    • diff-view.tsx: raw <table> → Table/TableBody/TableRow/TableCell (cancelled the primitive's default row border/hover to preserve the diff's contiguous-block look)
    • routine-panel.tsx: raw <textarea> → Textarea
  • Lowered REACT_UI_DRIFT_SNAPSHOT from 52 to 48 to lock in the reduction.

Left raw, deliberately

  • apps/web/src/shell/stage-search.tsx — the magnifier-to-inline-palette morph: react-ui's Button isn't a forwardRef component, so ref={buttonRef} (used to restore focus when the palette closes) may not attach reliably, and the width transition is authored specifically on .stage-search-button. Matches the task's own carve-out.
  • apps/web/src/shell/workbench-list.tsx (3 sites: the stub row, the workbench row, and the row's menu-trigger button) — these are structural, custom-CSS-classed row/hover-reveal controls (shell-ch-row, chat-sidebar-row-menu-trigger), not label-style action buttons. Wrapping them in react-ui's Button (fixed height, rounded-md, justify-center, forced padding) would fight the row's avatar+meta+badge layout. This matches an existing, accepted pattern elsewhere in the shell (sidebar.tsx's shell-sidebar-account-btn/shell-sidebar-footer-row, chat-ui/timeline.tsx's chat-hover-ellipsis) — both already exempted from this check only because each file happens to import Button for an unrelated action elsewhere, per the allowlist file's own comments.

Neither site was added to REACT_UI_DRIFT_ALLOWLIST (that requires an open ticket, which doesn't exist yet) — the check's ratchet has enough headroom (48 vs. snapshot 48... actually passes exactly at parity) without them, so nothing needed forcing. Recommend an owner decision on whether to formally allowlist these or leave the convention implicit.

Test plan

  • bun run check:react-ui-drift passes (48 vs. snapshot 48)
  • apps/web: bun run test (build + full suite) — 775 pass, 0 fail across 91 files
  • apps/web: bun run typecheck — clean
  • repo-root bun run lint — clean (0 errors; pre-existing unrelated warnings only)

Do not merge — left for a peer reviewer per the requesting task.

Swap hand-rolled <button>/<input type=checkbox>/<textarea>/<table>
markup for react-ui's Button, Checkbox, Textarea, and Table family in
agent-skills-picker, create-agent-panel, diff-view, and routine-panel.
Drop the now-redundant custom textarea CSS in create-agent-panel now
that Textarea supplies its own styling.
The primitive swaps in the previous commit cut the ratcheted violation
count from 53 to 48; lock in the reduction so it can't silently creep
back up.
Textarea's defaults (bg-card, text-sm) don't match what the removed
.create-agent-quiet-field > textarea CSS rule set. Preflight already
covers resize:vertical and font-family:inherit for every textarea, so
only background and font-size needed restoring via className.
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