@xsolla/xui-radio-group
v0.106.0
Published
A cross-platform React radio group component that manages single selection across multiple radio buttons. Provides context to child Radio components for coordinated selection.
Readme
Radio Group
A cross-platform React radio group component that manages single selection across multiple radio buttons. Provides context to child Radio components for coordinated selection.
Installation
npm install @xsolla/xui-radio-group @xsolla/xui-radio
# or
yarn add @xsolla/xui-radio-group @xsolla/xui-radioDemo
Basic Radio Group
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
export default function BasicRadioGroup() {
const [value, setValue] = React.useState('option1');
return (
<RadioGroup value={value} onChange={setValue}>
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
<Radio value="option3" label="Option 3" />
</RadioGroup>
);
}Horizontal Layout
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
export default function HorizontalRadioGroup() {
const [size, setSize] = React.useState('md');
return (
<RadioGroup value={size} onChange={setSize} flexDirection="row" gap={24}>
<Radio value="sm" label="Small" />
<Radio value="md" label="Medium" />
<Radio value="lg" label="Large" />
</RadioGroup>
);
}Radio Group with Descriptions
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
export default function RadioGroupWithDescriptions() {
const [plan, setPlan] = React.useState('starter');
return (
<RadioGroup value={plan} onChange={setPlan} gap={16}>
<Radio
value="starter"
label="Starter"
description="$9/month - Best for personal projects"
/>
<Radio
value="professional"
label="Professional"
description="$29/month - Best for small teams"
/>
<Radio
value="enterprise"
label="Enterprise"
description="Custom pricing - For large organizations"
/>
</RadioGroup>
);
}Disabled Radio Group
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
export default function DisabledRadioGroup() {
return (
<RadioGroup value="option1" disabled>
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
<Radio value="option3" label="Option 3" />
</RadioGroup>
);
}Anatomy
Import the components and compose them:
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
<RadioGroup
value={selectedValue} // Currently selected value
onChange={handleChange} // Selection change handler
size="md" // Size for all child radios
disabled={false} // Disable all radios
flexDirection="column" // Layout direction
gap={12} // Gap between items
>
<Radio value="a" label="Option A" />
<Radio value="b" label="Option B" />
<Radio value="c" label="Option C" />
</RadioGroup>Examples
Form Integration
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
import { Button } from '@xsolla/xui-button';
export default function FormRadioGroup() {
const [shipping, setShipping] = React.useState('');
const [error, setError] = React.useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!shipping) {
setError('Please select a shipping method');
return;
}
console.log('Selected shipping:', shipping);
};
return (
<form onSubmit={handleSubmit}>
<h3 id="shipping-label">Select Shipping Method</h3>
<RadioGroup
value={shipping}
onChange={(v) => { setShipping(v); setError(''); }}
aria-labelledby="shipping-label"
aria-describedby={error ? 'shipping-error' : undefined}
>
<Radio
value="standard"
label="Standard Shipping"
description="5-7 business days - Free"
/>
<Radio
value="express"
label="Express Shipping"
description="2-3 business days - $9.99"
/>
<Radio
value="overnight"
label="Overnight Shipping"
description="Next business day - $24.99"
/>
</RadioGroup>
{error && <p id="shipping-error" role="alert" style={{ color: 'red' }}>{error}</p>}
<Button type="submit" style={{ marginTop: 16 }}>Continue</Button>
</form>
);
}Different Sizes
import * as React from 'react';
import { RadioGroup } from '@xsolla/xui-radio-group';
import { Radio } from '@xsolla/xui-radio';
export default function RadioGroupSizes() {
const [value, setValue] = React.useState('a');
return (
<div style={{ display: 'flex', gap: 48 }}>
<div>
<h4>Small</h4>
<RadioGroup value={value} onChange={setValue} size="sm">
<Radio value="a" label="Option A" />
<Radio value="b" label="Option B" />
</RadioGroup>
</div>
<div>
<h4>Large</h4>
<RadioGroup value={value} onChange={setValue} size="lg">
<Radio value="a" label="Option A" />
<Radio value="b" label="Option B" />
</RadioGroup>
</div>
</div>
);
}API Reference
RadioGroup
Container component that provides selection context to Radio children.
RadioGroup Props:
| Prop | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| children | ReactNode | - | Required. Radio components to group. |
| value | string | - | Currently selected value. |
| onChange | (value: string) => void | - | Callback when selection changes. |
| size | "sm" \| "md" \| "lg" \| "xl" | "md" | Size applied to all child Radio components. |
| disabled | boolean | false | Whether all radios are disabled. |
| flexDirection | "row" \| "column" | "column" | Layout direction of the group. |
| gap | number | 12 | Gap between radio items in pixels. |
RadioGroup Context
RadioGroup provides context to child Radio components:
interface RadioGroupContextProps {
value?: string; // Currently selected value
onChange?: (value: string) => void; // Selection handler
size?: "sm" | "md" | "lg" | "xl"; // Size for radios
disabled?: boolean; // Disabled state
}Child Radio components automatically:
- Sync their checked state with the group value
- Call the group's onChange when selected
- Inherit size and disabled props from the group
Theming
RadioGroup uses flexbox layout with theme-based spacing. Child Radio components use the design system theme for colors.
Accessibility
- RadioGroup provides proper grouping semantics
- Only one radio can be selected at a time
- Arrow keys navigate between options when focused
- Tab key moves focus to/from the group
- Disabled state properly communicated to all children
