Radio
Radio components allow users to select a single option from a set. They are typically used within a RadioGroup
for managing selection state and layout.
Installation
$ cbui-cli install radio
cbui-cli
globally and authenticated your account. This will ensure you can access all the necessary features.Import
1import { RadioGroup, Radio, RadioGroupContext, useRadioGroupContext } from '@/crossbuildui/radio';
isGlass
feature for RadioGroup
(which styles the individual radio indicators) uses expo-blur
. Ensure this library is installed and linked if you plan to use this feature. Animations also rely on react-native-reanimated
.RadioGroup Component
The RadioGroup
component is a container for Radio
buttons. It manages the selection state, layout, and common properties for its children.
Basic Usage
Wrap Radio
components within a RadioGroup
. Provide a label
for the group.
1<RadioGroup label="Favorite Pet">
2 <Radio value="dog">Dog</Radio>
3 <Radio value="cat">Cat</Radio>
4 <Radio value="dragon">Dragon</Radio>
5</RadioGroup>
Orientation
Use the orientation
prop to lay out radio buttons vertically (default) or horizontally.
1<View style={{gap: 24}}>
2 <RadioGroup label="Preferred Contact (Vertical)" orientation="vertical">
3 <Radio value="email">Email</Radio>
4 <Radio value="phone">Phone</Radio>
5 <Radio value="sms">SMS</Radio>
6 </RadioGroup>
7 <RadioGroup label="Preferred Contact (Horizontal)" orientation="horizontal">
8 <Radio value="email">Email</Radio>
9 <Radio value="phone">Phone</Radio>
10 <Radio value="sms">SMS</Radio>
11 </RadioGroup>
12</View>
Colors
The color
prop on RadioGroup
sets the default color for all child Radio
components. Individual Radio
components can override this.
1<RadioGroup label="Notification Color" defaultValue="primary">
2 <Radio value="primary" color="primary">Primary</Radio>
3 <Radio value="secondary" color="secondary">Secondary</Radio>
4 <Radio value="success" color="success">Success</Radio>
5 <Radio value="warning" color="warning">Warning</Radio>
6 <Radio value="danger" color="danger">Danger</Radio>
7 <Radio value="default" color="default">Default</Radio>
8</RadioGroup>
Controlled and Uncontrolled
Manage selection state externally using value
and onValueChange
, or use defaultValue
for an uncontrolled group.
1function ControlledRadioGroup() {
2 const [selected, setSelected] = React.useState('apple');
3
4 return (
5 <View style={{gap: 8}}>
6 <RadioGroup
7 label="Choose a fruit:"
8 value={selected}
9 onValueChange={setSelected}
10 >
11 <Radio value="apple">Apple</Radio>
12 <Radio value="banana">Banana</Radio>
13 <Radio value="orange">Orange</Radio>
14 </RadioGroup>
15 <Text>Selected: {selected}</Text>
16 </View>
17 );
18}
19
20// Uncontrolled (uses defaultValue)
21// <RadioGroup label="Choose a color (Uncontrolled)" defaultValue="red">
22// <Radio value="red">Red</Radio>
23// <Radio value="blue">Blue</Radio>
24// </RadioGroup>
25
Description and Error Message
Provide context with description
or display validation feedback using errorMessage
.
1<View style={{gap: 16}}>
2 <RadioGroup
3 label="Subscription Tier"
4 description="Select your preferred subscription plan."
5 >
6 <Radio value="free">Free Tier</Radio>
7 <Radio value="pro">Pro Tier</Radio>
8 </RadioGroup>
9 <RadioGroup
10 label="Confirm Choice"
11 value="no" // Example to show error state
12 errorMessage="You must select 'Yes' to proceed."
13 // isInvalid prop would typically be used here if available on RadioGroup
14 >
15 <Radio value="yes">Yes, I confirm</Radio>
16 <Radio value="no">No, I do not confirm</Radio>
17 </RadioGroup>
18</View>
Disabled State
Disable the entire group with isDisabled
on RadioGroup
, or disable individual Radio
components.
1<View style={{gap: 16}}>
2 <RadioGroup label="Disabled Group" isDisabled>
3 <Radio value="a">Option A (Inherits disabled)</Radio>
4 <Radio value="b">Option B (Inherits disabled)</Radio>
5 </RadioGroup>
6 <RadioGroup label="Group with one disabled Radio">
7 <Radio value="c">Option C (Enabled)</Radio>
8 <Radio value="d" isDisabled>Option D (Specifically disabled)</Radio>
9 </RadioGroup>
10</View>
Disable Animation
Set disableAnimation
on RadioGroup
to turn off selection animations for all child Radio
components.
1<RadioGroup label="Animation Options" disableAnimation>
2 <Radio value="animated_off">Animation Disabled for this group</Radio>
3 <Radio value="another_off">Another one with animation off</Radio>
4</RadioGroup>
Styling RadioGroup
Customize RadioGroup
slots: base
, label
, radioWrapper
, description
, errorMessage
.
1<RadioGroup
2 label="Styled Radio Group"
3 description="This group has custom styles."
4 style={{ padding: 10, backgroundColor: '#f0f0f0', borderRadius: 8 }} // Base style for RadioGroup
5 styles={{
6 label: { color: 'purple', fontSize: 18, fontWeight: 'bold' },
7 radioWrapper: { backgroundColor: '#e6e6fa', padding: 8, borderRadius: 4, gap: 12 },
8 description: { color: 'green', fontStyle: 'italic' },
9 errorMessage: { color: 'orange', fontWeight: '600' }
10 }}
11>
12 <Radio value="style1">Styled Option 1</Radio>
13 <Radio value="style2">Styled Option 2</Radio>
14</RadioGroup>
Glass Indicator Effect
Apply a frosted glass effect to the background of selected radio indicators using the isGlass
prop on RadioGroup
. Customize it with glassIntensity
(0-100) and glassTint
('light'
, 'dark'
, 'default'
). The indicator's border and dot colors adapt for better contrast on the blurred background. This effect is applied to the individual Radio
indicators within the group.
1<View style={{gap: 16}}>
2 <RadioGroup
3 label="Light Glass Radios"
4 defaultValue="opt1"
5 isGlass
6 glassIntensity={70}
7 glassTint="light"
8 >
9 <Radio value="opt1">Option 1 (Light Glass)</Radio>
10 <Radio value="opt2">Option 2 (Light Glass)</Radio>
11 </RadioGroup>
12 <RadioGroup
13 label="Dark Glass Radios"
14 defaultValue="optA"
15 isGlass
16 glassIntensity={40}
17 glassTint="dark"
18 >
19 <Radio value="optA" description="Selected indicator dot will be theme foreground">Option A (Dark Glass)</Radio>
20 <Radio value="optB">Option B (Dark Glass)</Radio>
21 </RadioGroup>
22</View>
Using RadioGroup Context
For advanced scenarios or creating custom components that interact deeply with the RadioGroup
, you can use the useRadioGroupContext
hook. This hook provides access to the RadioGroupContext
, which includes properties like name
(group identifier), selectedValue
, setSelectedValue
(setter function), color
, size
, orientation
, isDisabled
, and glass props.
Any component calling useRadioGroupContext
must be a descendant of a RadioGroup
component. This allows for building custom layouts or informational displays related to the group's state.
setSelectedValue
from deep children might make state flow harder to track. Prefer standard Radio
interactions where possible.1import { RadioGroup, Radio, useRadioGroupContext } from '@/crossbuildui/radio';
2import { Text, View } from 'react-native';
3
4const RadioGroupInfo = () => {
5 const context = useRadioGroupContext();
6
7 if (!context) {
8 return <Text>This component must be used within a RadioGroup.</Text>;
9 }
10
11 const { name, selectedValue, color, size, orientation, isDisabled } = context;
12
13 return (
14 <View style={{ marginTop: 8, padding: 8, backgroundColor: '#f0f0f0', borderRadius: 4 }}>
15 <Text>RadioGroup Context Info (Name: {name}):</Text>
16 <Text>- Selected: {selectedValue ?? 'None'}</Text>
17 <Text>- Color: {color}, Size: {size}, Orientation: {orientation}</Text>
18 <Text>- Disabled: {isDisabled ? 'Yes' : 'No'}</Text>
19 </View>
20 );
21};
22
23// <RadioGroup label="Options" color="success" size="sm"><Radio value="1">One</Radio><RadioGroupInfo /></RadioGroup>
RadioGroup Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | ReactNode[] | - | The Radio components. |
label | ReactNode | - | Label for the radio group. |
color | RadioColor | 'primary' | Default color for child Radios. |
orientation | 'horizontal' | 'vertical' | 'vertical' | Layout orientation. |
value | string | number | null | - | Controlled selected value. |
defaultValue | string | number | null | - | Initial selected value (uncontrolled). |
onValueChange | (value) => void | - | Callback on selection change. |
description | ReactNode | - | Helper text for the group. |
errorMessage | ReactNode | - | Error message for the group. |
styles | RadioGroupSlotsStyles | - | Custom styles for group slots. |
style | StyleProp<ViewStyle> | - | Style for the outermost container. |
disableAnimation | boolean | false | Disable selection animation for child Radios. |
isDisabled | boolean | false | Disable the entire group. |
isGlass | boolean | false | Apply glassmorphism to selected radio indicators. |
glassTint | 'default' | 'light' | 'dark' | Theme-derived | Tint for the glass effect on indicators. |
glassIntensity | number | 30 | Intensity (0-100) for the glass effect on indicators. |
Radio Component
The Radio
component represents a single selectable option within a RadioGroup
.
Sizes
Adjust radio button and label size with sm
, md
(default), or lg
on individual Radio
components.
1// Size is set on individual Radio components
2<RadioGroup label="T-Shirt Size">
3 <Radio value="sm" size="sm">Small</Radio>
4 <Radio value="md" size="md">Medium (Default)</Radio>
5 <Radio value="lg" size="lg">Large</Radio>
6</RadioGroup>
Individual Labels & Descriptions
Each Radio
can have its own label (via children
or label
prop) and an optional description
.
1<RadioGroup label="User Preferences">
2 <Radio value="email_notifications">
3 Email Notifications
4 </Radio>
5 <Radio value="sms_alerts" label="SMS Alerts (Explicit Label)" />
6 <Radio value="push_updates" description="Receive updates via push notifications.">
7 Push Updates
8 </Radio>
9 <Radio
10 value="newsletter"
11 label="Newsletter Subscription"
12 description="Monthly news and offers."
13 />
14</RadioGroup>
Styling Radio
Customize individual Radio
slots: base
, indicator
, indicatorDot
, label
, labelWrapper
, description
.
If isGlass
is enabled on the parent RadioGroup
, the indicator
style's backgroundColor
will be transparent when selected, allowing the BlurView
to show through. The indicatorDot
color will adapt to the theme's foreground for contrast.
1<RadioGroup label="Radios with Custom Styling">
2 <Radio
3 value="custom1"
4 style={{ paddingVertical: 12, backgroundColor: '#e0ffff', borderRadius: 6 }} // Base style for this Radio
5 styles={{
6 indicator: { borderColor: 'teal', borderWidth: 3 },
7 indicatorDot: { backgroundColor: 'darkcyan' },
8 label: { color: 'navy', fontWeight: 'bold' },
9 description: { color: 'dodgerblue' },
10 labelWrapper: { marginLeft: 12 }
11 }}
12 description="Custom styled radio."
13 >
14 Option Alpha
15 </Radio>
16 <Radio value="custom2">Option Beta (Default Styling)</Radio>
17</RadioGroup>
Radio Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
value | string | number | - | Unique value for this radio. Required. |
children | ReactNode | - | Label content if label prop is not used. |
label | ReactNode | - | Explicit label for the radio. |
size | RadioSize | 'md' | Size of the radio. Inherits from group. |
color | RadioColor | Inherited | Color of the radio. Inherits from group. |
description | ReactNode | - | Helper text for this radio option. |
isDisabled | boolean | false | Disable this specific radio. Overrides group. |
styles | RadioSlotsStyles | - | Custom styles for radio slots. |
style | StyleProp<ViewStyle> | - | Style for the outermost Pressable container. |
Accessibility
Both RadioGroup
and Radio
components include accessibility features:
RadioGroup
hasaccessibilityRole="radiogroup"
. Itslabel
prop is used asaccessibilityLabel
.- Individual
Radio
components haveaccessibilityRole="radio"
. accessibilityState
onRadio
includes{ checked: isSelected, disabled: isDisabled }
.- The label of a
Radio
(fromchildren
orlabel
prop) is used as itsaccessibilityLabel
if it's a string.