Skip to content

feat(shared): redesign checkbox & radio to match Toggle + Button system#6129

Open
tsahimatsliah wants to merge 6 commits into
mainfrom
feat/checkbox-radio-redesign
Open

feat(shared): redesign checkbox & radio to match Toggle + Button system#6129
tsahimatsliah wants to merge 6 commits into
mainfrom
feat/checkbox-radio-redesign

Conversation

@tsahimatsliah
Copy link
Copy Markdown
Member

@tsahimatsliah tsahimatsliah commented Jun 1, 2026

Summary

Brings Checkbox and Radio in line with the redesigned Toggle/Switch (#6117) and the Button system, so fields, buttons, toggles, checkboxes and radios read as one family.

  • Single semantic brand fill. Selected = accent-cabbage-default with a solid white glyph — a white check for the checkbox, a white center dot for the radio — identical in light & dark. Removes the old hardcoded raw.cabbage.* values and the per-theme .light/.auto override blocks.
  • Shared state language. A surface-hover halo on hover, an even surface-focus (blue) ring on :focus-visible, and a subtle press squeeze on :active — matching the Toggle's motion.
  • Non-breaking. Public API, control dimensions and label typography are unchanged, so the ~28 consumers don't shift. The redesign is purely the control visuals + states.

The biggest visible win is in light theme: the previous checked check was near-black on dark cabbage (low contrast) — now it's a clean white glyph.

Review page

Added /dev/checkbox-radio — a before/after comparison table covering every state and variant for both components, in light & dark, with live hover/focus/press. noindex/nofollow; reachable on preview + local, blocked on production.

Test plan

  • Open /dev/checkbox-radio on the preview domain; flip theme; click/hover/Tab through each control.
  • Confirm checked checkbox shows a white check and selected radio shows a white center dot in both themes.
  • Spot-check real forms (auth, report modals, feed settings, notifications) for checkbox/radio regressions.
  • shared strict typecheck + lint clean; Checkbox.spec + FormInputCheckboxGroup.spec pass.

🤖 Generated with Claude Code

Preview domain

https://feat-checkbox-radio-redesign.preview.app.daily.dev

Align Checkbox and RadioItem with the redesigned Toggle/Switch and Button
system so fields, buttons, toggles, checkboxes and radios read as one family:
- single semantic brand fill when selected (accent-cabbage-default) with a
  solid white glyph (white check / white center dot), identical in light & dark
- surface-hover halo, surface-focus blue keyboard ring, and a subtle press
  squeeze — theme-aware via semantic tokens, removing the per-theme overrides

Adds /dev/checkbox-radio: a before/after comparison table across all states
and variants in light & dark, with live hover/focus/press.

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

vercel Bot commented Jun 1, 2026

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

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview Jun 1, 2026 10:28pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored Jun 1, 2026 10:28pm

Request Review

- Checkbox: use the filled (secondary) V glyph, scaled up, so the checkmark
  reads bold and solid instead of thin/outlined.
- Radio: restore the legacy hover affordance where the ring thickens
  (border 2px → 4px) to text-primary on hover/focus, animated.

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

- Labels now match the redesigned Switch: font-medium, antialiased,
  typo-footnote, text-secondary at rest → text-primary when selected/hover
  (radio was font-bold/tertiary; checkbox was tertiary).
- Reduce the checkbox check glyph from scale-125 to scale-110.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Checkbox gains an `indeterminate` prop: renders a white dash, exposes
  aria-checked="mixed", and drives the native input.indeterminate property
  via a merged ref. For tri-state / "select all" patterns.
- Checkbox & radio disable their press/scale/fatten motion under
  prefers-reduced-motion (state changes still apply, just no movement).
- Review page: add an Indeterminate row to the checkbox states table.

Contrast verified (WCAG 1.4.11, 3:1 for graphics): white check on cabbage
is 3.76:1 (dark) / 5.18:1 (light) — passes; no cabbage change needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a spec asserting the native input.indeterminate property, the
  indeterminate label class, and aria-checked="mixed".
- Attach the merged ref after the prop spread so it can't be clobbered.

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

- Resting outline now uses text-secondary (the label tone) instead of the
  high-contrast border-subtlest-primary; hover/focus still lift it to
  text-primary, mirroring the field border behaviour. Stays >=3:1 (1.4.11).
- Radio selected hover/focus halo is now the brand cabbage tint (matching the
  checkbox) instead of grey-on-brand.
- Standardise motion to the toggle's timing: colours/box-shadow 0.12s linear,
  transforms 0.2s cubic-bezier(0.16,1,0.3,1).

Focus ring already matches the shared blueCheese token used by toggle, fields
and the .focus-outline button convention (surface-focus === accent-blueCheese-default).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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