Skip to content

Center the indeterminate checkbox mark (#376) - #437

Merged
czarandy merged 1 commit into
mainfrom
fix/checkbox-indeterminate-nudge
Aug 6, 2026
Merged

Center the indeterminate checkbox mark (#376)#437
czarandy merged 1 commit into
mainfrom
fix/checkbox-indeterminate-nudge

Conversation

@czarandy

@czarandy czarandy commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Fixes #376.

What was wrong

CheckboxInput's checked and indeterminate marks render through one recipe slot, and that slot carried mt: '1px' unconditionally. The nudge is an optical correction shaped for the lucide Check glyph, whose stroke sits above the middle of its 24×24 viewBox. The Minus bar is already on that centre line, so it inherited a correction it never needed.

The isChecked variant collapsed both states (isChecked: isCheckedOrIndeterminate), so there was no seam to hang a per-glyph rule on.

The shift is 0.5px, not the full 1px: the icon is centred by the box's flex layout, and a top margin on a flex-centred item only moves it by half the margin ((H − h − 1) / 2 + 1).

Changes

  • isChecked becomes a three-state mark variant (none / check / indeterminate). Both marked states still paint the same filled box — that's shared through a local markedBox constant — but only check carries the nudge.
  • The 1px literal stays. It's the smallest thing the design needs and the spacing scale bottoms out at 0.5 (2px), so there's no token that fits; it now sits next to a comment explaining which glyph it belongs to.
  • ColorSwatchPicker.recipe.ts:62 has the same literal, but that recipe only ever renders Check, so its nudge is on the right glyph and is left alone.

Verified in a browser

Measured in headless Chromium against Storybook — the painted bounding box of the glyph's <path> against the box's border-box centre, at every size:

before after
indeterminate (sm/md/lg) +0.5px 0px
checked (sm/md/lg) +0.083px +0.083px (unchanged)

The red marks are the box's true vertical centre, placed from the measured geometry (verified to land within 0.008px of it). Full-width in the overview; ticks only in the magnified row so nothing covers the glyph.

Before and after: the indeterminate Minus bar moves onto the checkbox's vertical centre line at sm, md and lg, while the checked glyph is unchanged

Tests

Two regression tests in CheckboxInput.test.tsx:

  • the checked mark carries silver-mt_1px and the indeterminate mark does not — fails on main, where the Minus glyph renders with that class;
  • both marked states still fill the box and the unchecked state does not, guarding the isCheckedmark refactor.

Full suite green (3179 tests), lint and typecheck clean.

Note: the screenshot is hosted on a throwaway screenshots/issue-376 branch — safe to delete once this is reviewed.

https://claude.ai/code/session_01XFkkvUQfynGRedEYDNxKoY

The checked and indeterminate marks shared the icon slot's `mt: '1px'`,
an optical correction shaped for the lucide Check glyph, whose stroke
sits above the middle of its viewBox. The Minus bar is already on that
centre line, so the shared nudge pushed it 0.5px below the box's centre
at every size (a flex-centred item with a 1px top margin shifts by half
the margin).

Replace the `isChecked` variant, which collapsed both marked states,
with a three-state `mark` variant. Both marked states still paint the
same filled box; only `check` carries the nudge.

Measured in headless Chromium against Storybook, comparing the glyph's
painted bounding box to the box's centre at sm/md/lg: indeterminate goes
from +0.5px to 0px, checked stays at +0.083px.

Claude-Session: https://claude.ai/code/session_01XFkkvUQfynGRedEYDNxKoY
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
silver-ui-site Ready Ready Preview Aug 5, 2026 11:34pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
silver-ui Ignored Ignored Preview Aug 5, 2026 11:34pm

@czarandy
czarandy merged commit c0a04de into main Aug 6, 2026
4 checks passed
@czarandy
czarandy deleted the fix/checkbox-indeterminate-nudge branch August 6, 2026 07:34
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.

CheckboxInput: indeterminate mark inherits the check glyph's 1px nudge and sits off-center

1 participant