Primitive · 6 of 13
Two variants that differ far more than the name suggests: one is a small filled pill, the other a 44px-radius outlined card. Note the variant naming is inverted relative to Checkbox.
| Prop | Type | Notes |
|---|---|---|
| id * | string | Doubles as the input's value and the emitted payload. |
| label * | string | 12px, whitespace-nowrap. |
| name * | string | Groups the inputs natively. |
| isChecked | boolean | Bound to :checked. |
| modelValue | string | Declared, but the component emits id rather than reading this. |
| variant | 'primary' | 'secondary' | primary = filled pill; secondary = outlined card. |
The secondary hover is dead code.
Source styles it with group-hover:bg-surface-tertiary, which
Tailwind only resolves when an ancestor carries the group class.
The component renders no such ancestor and no caller adds one, so the hover
never fires in the real app. The story above wraps each control in a
.group equivalent purely so the intended behavior is visible —
that wrapper is scaffolding, not source.
Same borrowed transition as Checkbox.
Line 61 declares
transition: var(--default-transition-duration) transform ease-in-out;
against a custom property the project never defines — it resolves to 150ms
only because Tailwind's default theme supplies it. Inside the site build
(and here) the dot eases; outside one, it snaps.
modelValue is declared but never read.
The component emits update:modelValue with its own
id on change, and drives its visual state from the separate
isChecked prop. So v-model alone will not check the
button — the parent has to pass isChecked as well. Two props
express one piece of state, and they can disagree.
Variant naming is inverted against Checkbox.
Checkbox's secondary is the boxed-pill treatment and
primary is bare. Radio's primary is the boxed pill
and secondary is the larger card. Reaching for the same variant
name across the two components gives opposite results.
The dot is 7px inside a 17px box.
Unlike Checkbox the sizes are hard-coded pixels rather than token steps, and
there is no size prop — so a radio cannot be matched to a small
checkbox in the same row.