@fvc/radio
v1.0.3
Published
`@fvc/radio` provides FE-VIS styled radio button primitives on top of Ant Design. It keeps the Ant Design Radio API familiar while applying the design-system token palette used across FE-VIS applications: themed border and dot colors, a disabled state, a
Downloads
2,337
Readme
@fvc/radio
@fvc/radio provides FE-VIS styled radio button primitives on top of Ant Design. It keeps the Ant Design Radio API familiar while applying the design-system token palette used across FE-VIS applications: themed border and dot colors, a disabled state, a block layout option for full-width groups, and a test-friendly testId prop.
Installation
bun add @fvc/radioPeer Dependencies
The package expects these dependencies to be available in the consuming application:
bun add react antdImport
import { Radio } from '@fvc/radio';Quick Start
import { Radio } from '@fvc/radio';
import { useState } from 'react';
export function AgreementForm() {
const [value, setValue] = useState('yes');
return (
<Radio.Group value={value} onChange={(e) => setValue(e.target.value)}>
<Radio value="yes">Yes</Radio>
<Radio value="no">No</Radio>
</Radio.Group>
);
}Common Usage
Standalone Radio
<Radio value="a">Option A</Radio>Controlled Group
Wrap multiple Radio items in Radio.Group to manage a set of mutually exclusive choices.
const [value, setValue] = useState('a');
<Radio.Group value={value} onChange={(e) => setValue(e.target.value)}>
<Radio value="a">Option A</Radio>
<Radio value="b">Option B</Radio>
<Radio value="c">Option C</Radio>
</Radio.Group>;Block Group
The block prop stretches every radio item to fill the full width of its container.
<Radio.Group block value={value} onChange={(e) => setValue(e.target.value)}>
<Radio value="a">Option A</Radio>
<Radio value="b">Option B</Radio>
</Radio.Group>Disabled
Both individual radios and the entire group can be disabled.
<Radio disabled value="a">Disabled option</Radio>
<Radio.Group disabled value={value}>
<Radio value="a">Option A</Radio>
<Radio value="b">Option B</Radio>
</Radio.Group>Props
<Radio>
Extends all Ant Design RadioProps.
| Prop | Type | Description |
| ---------- | ----------- | ------------------------------------------------- |
| value | any | The value bound to the radio input. |
| checked | boolean | Whether the radio is selected (controlled). |
| disabled | boolean | Disables the radio and removes it from tab order. |
| onChange | function | Callback fired when the radio selection changes. |
| testId | string | Maps to data-testid on the inner <input>. |
| children | ReactNode | Label displayed alongside the radio. |
<Radio.Group>
Extends all Ant Design RadioGroupProps.
| Prop | Type | Description |
| -------------- | ---------- | -------------------------------------------------- |
| value | any | Currently selected value (controlled). |
| defaultValue | any | Initially selected value (uncontrolled). |
| disabled | boolean | Disables all radios within the group. |
| onChange | function | Callback fired when selection changes. |
| block | boolean | Stretches each radio item to full container width. |
| className | string | Additional CSS class names on the group wrapper. |
TypeScript
The package ships with type definitions. No @types/ install needed.
import type { RadioProps, GroupProps } from '@fvc/radio/types';Consumer Example
import { Radio } from '@fvc/radio';
import { useState } from 'react';
export function NotificationSettings({ onChange }) {
const [frequency, setFrequency] = useState('daily');
function handleChange(e) {
setFrequency(e.target.value);
onChange(e.target.value);
}
return (
<Radio.Group block value={frequency} onChange={handleChange}>
<Radio value="realtime">Real-time</Radio>
<Radio value="daily">Daily digest</Radio>
<Radio value="weekly">Weekly summary</Radio>
<Radio value="never" disabled>
Never (disabled by admin)
</Radio>
</Radio.Group>
);
}Testing
Use testId when a stable test selector is needed.
<Radio testId="agree-radio" value="agree">
I agree
</Radio>screen.getByTestId('agree-radio');Customisation
@fvc/radio exposes a CSS customisation API through variables declared on :root in src/styles/variables.scss. Override the --radio-* variables in your application stylesheet to restyle the component without editing the package source, shipping a fork, or rebundling the component.
| Variable | Default | Description |
| --- | --- | --- |
| --radio-default-bg-color | var(--neutral-0) | Background color of the radio control in the default state. |
| --radio-default-border-color | var(--blue-500) | Border color of the radio control in the default state. |
| --radio-default-border-width | 2px | Border width of the radio control. |
| --radio-default-border-style | solid | Border style of the radio control. |
| --radio-hover-bg-color | var(--neutral-0) | Background color of the radio control on hover. |
| --radio-hover-border-color | var(--blue-500) | Border color of the radio control on hover. |
| --radio-checked-bg-color | var(--neutral-0) | Background color of the radio control when checked. |
| --radio-checked-border-color | var(--blue-500) | Border color of the radio control when checked. |
| --radio-checked-dot-bg-color | var(--blue-500) | Fill color of the inner dot when checked. |
| --radio-disabled-bg-color | var(--neutral-0) | Background color of the radio control when disabled. |
| --radio-disabled-border-color | var(--blue-300) | Border color of the radio control when disabled. |
| --radio-disabled-checked-dot-bg-color | var(--blue-300) | Fill color of the inner dot when checked and disabled. |
| --radio-group-block-width | 100% | Width used by block radio groups. |
| --radio-group-block-item-width-offset | 22px | Width offset subtracted from each block radio item. |
Copy this into your global stylesheet and adjust the values you need:
:root {
--radio-default-bg-color: #fafafa;
--radio-default-border-color: #d4d4d8;
--radio-hover-border-color: #71717a;
--radio-checked-border-color: #2563eb;
--radio-checked-dot-bg-color: #2563eb;
--radio-disabled-border-color: #cbd5e1;
}Development
bun run lint
bun run type-check
bun run test
bun run build