The Radio component has the same structural problems as Checkbox (see #1714) and should be fixed in the same way as outlined in #1753 for consistency:
1. Native <input> in normal flow inflates wrapper height
The mock radio wrapper (div.juno-radio) is relative w-4 h-4, and the checked indicator <span> is absolute — but the native <input> is in normal flow. Same as with Checkbox, this causes the wrapper height to be inflated by the browser's implicit inline-block rendering of the input, shifting the radio upward in items-center flex contexts.
Fix: add absolute inset-0 to the input's styles and remove the now-redundant w-4 h-4 from them.
2. ...props spreads onto a decorative div, not the <input>
RadioProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> and ...props is spread onto div.juno-radio. Attributes like aria-label, aria-describedby, data-testid etc. land on a decorative element rather than the native input.
Fix: change RadioProps to extend Omit<InputHTMLAttributes<HTMLInputElement>, "onChange"> (keeping the existing custom onChange signature (value: string) => void) and route ...props including className to the native <input>. Introduce a new wrapperClassName prop for callers who need to style the outer container element, consistent with the pattern used across the library and the equivalent fix applied to Checkbox.
3. Copy-paste bug in RadioGroup
The inner options container in RadioGroup carries the class juno-checkbox-group-options instead of juno-radio-group-options.
Fix: correct the class name.
Acceptance criteria
The Radio component has the same structural problems as Checkbox (see #1714) and should be fixed in the same way as outlined in #1753 for consistency:
1. Native
<input>in normal flow inflates wrapper heightThe mock radio wrapper (
div.juno-radio) isrelativew-4h-4, and the checked indicator<span>is absolute — but the native<input>is in normal flow. Same as withCheckbox, this causes the wrapper height to be inflated by the browser's implicit inline-block rendering of the input, shifting the radio upward initems-centerflex contexts.Fix: add
absoluteinset-0to the input's styles and remove the now-redundantw-4h-4from them.2.
...propsspreads onto a decorativediv, not the<input>RadioPropsextendsOmit<HTMLAttributes<HTMLDivElement>, "onChange">and...propsis spread ontodiv.juno-radio. Attributes likearia-label,aria-describedby,data-testidetc. land on a decorative element rather than the native input.Fix: change
RadioPropsto extendOmit<InputHTMLAttributes<HTMLInputElement>, "onChange">(keeping the existing customonChangesignature (value: string) => void) and route...propsincludingclassNameto the native<input>. Introduce a newwrapperClassNameprop for callers who need to style the outer container element, consistent with the pattern used across the library and the equivalent fix applied toCheckbox.3. Copy-paste bug in
RadioGroupThe inner options container in
RadioGroupcarries the classjuno-checkbox-group-optionsinstead ofjuno-radio-group-options.Fix: correct the class name.
Acceptance criteria
<Radio>placed in an items-center flex container is vertically centered correctly<Radio>inside a<RadioGroup>renders with consistent spacing in the vertical stack (no regression)RadioGrouprenders and functions correctly with no regressionsaria-*,data-*and other HTML attributes passed to<Radio>are forwarded to the native<input>classNameis forwarded to the native<input>wrapperClassNameprop is accepted and applied to the outer container, consistent withCheckboxand other components in the libraryjuno-checkbox-group-optionsclass in RadioGroup is corrected tojuno-radio-group-optionswrapperClassName