Checkbox & Radio Components
Checkbox and Radio components provide selection input functionality with custom styling and React Hook Form integration for form validation and data management.
Component Overview
Core Components
- WPCheckbox - Basic checkbox component with labels
- V2WPCheckbox - React Hook Form integrated checkbox
- WPRadio - Radio button group component
- CustomRadioButton - Custom styled radio button group
Version Support
The components support multiple React Hook Form versions:
- V2 - Enhanced components with React Hook Form integration
- Legacy - Original components with basic functionality
WPCheckbox
Basic checkbox component with label and description support.
Component Location
import WPCheckbox from 'components/Checkbox/WPCheckbox';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | - | Checkbox label text |
desc | string | - | Description text below label |
isChecked | boolean | - | Checked state |
isDisabled | boolean | false | Disabled state |
isIndeterminate | boolean | false | Indeterminate state |
onChange | function | - | Change handler |
size | string | 'sm' | Checkbox size |
defaultValue | any | - | Default value |
register | function | - | React Hook Form register function |
textStyle | string | - | Text styling |
color | string | - | Text color |
Usage Examples
Basic Checkbox
import WPCheckbox from 'components/Checkbox/WPCheckbox';
import { useState } from 'react';
function BasicCheckbox() {
const [isChecked, setIsChecked] = useState(false);
return (
<WPCheckbox
label='Accept Terms and Conditions'
isChecked={isChecked}
onChange={e => setIsChecked(e.target.checked)}
/>
);
}
Checkbox with Description
import WPCheckbox from 'components/Checkbox/WPCheckbox';
function CheckboxWithDescription() {
const [isChecked, setIsChecked] = useState(false);
return (
<WPCheckbox
label='Enable Email Notifications'
desc='Receive email notifications for important updates and messages'
isChecked={isChecked}
onChange={e => setIsChecked(e.target.checked)}
size='md'
/>
);
}
Indeterminate Checkbox
import WPCheckbox from 'components/Checkbox/WPCheckbox';
function IndeterminateCheckbox() {
const [checkedItems, setCheckedItems] = useState([false, false, false]);
const allChecked = checkedItems.every(Boolean);
const isIndeterminate = checkedItems.some(Boolean) && !allChecked;
return (
<>
<WPCheckbox
label='Select All'
isChecked={allChecked}
isIndeterminate={isIndeterminate}
onChange={e =>
setCheckedItems([
e.target.checked,
e.target.checked,
e.target.checked,
])
}
/>
{checkedItems.map((isChecked, index) => (
<WPCheckbox
key={index}
label={`Option ${index + 1}`}
isChecked={isChecked}
onChange={e => {
const newItems = [...checkedItems];
newItems[index] = e.target.checked;
setCheckedItems(newItems);
}}
/>
))}
</>
);
}
Form Integration
import WPCheckbox from 'components/Checkbox/WPCheckbox';
import { useForm } from 'react-hook-form';
function FormCheckbox() {
const { register, errors } = useForm();
return (
<WPCheckbox
label='I agree to the terms'
register={register('agreeToTerms', {
required: 'You must agree to the terms',
})}
defaultValue={false}
/>
);
}
V2WPCheckbox
React Hook Form integrated checkbox component with automatic form handling.
Component Location
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | - | Checkbox label text |
name | string | - | Field name for form registration |
control | Control | - | React Hook Form control object |
hidden | boolean | false | Whether checkbox is hidden |
Usage Examples
Basic V2 Checkbox
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
import { useForm } from 'react-hook-form';
function V2CheckboxForm() {
const { control, handleSubmit } = useForm();
const onSubmit = data => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<V2WPCheckbox
text='Subscribe to newsletter'
name='newsletter'
control={control}
/>
<button type='submit'>Submit</button>
</form>
);
}
Multiple Checkboxes
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
import { Stack } from '@chakra-ui/react';
function MultipleCheckboxes() {
const { control } = useForm();
return (
<Stack spacing={4}>
<V2WPCheckbox
text='Email notifications'
name='emailNotifications'
control={control}
/>
<V2WPCheckbox
text='SMS notifications'
name='smsNotifications'
control={control}
/>
<V2WPCheckbox
text='Push notifications'
name='pushNotifications'
control={control}
/>
</Stack>
);
}
Conditional Checkbox
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
function ConditionalCheckbox() {
const { control, watch } = useForm();
const hasAccount = watch('hasAccount');
return (
<>
<V2WPCheckbox
text='I have an existing account'
name='hasAccount'
control={control}
/>
{hasAccount && (
<V2WPCheckbox text='Remember me' name='rememberMe' control={control} />
)}
</>
);
}
WPRadio
Radio button group component with React Hook Form integration.
Component Location
import WPRadio from 'components/Radio/WPRadio';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | Field name for form registration |
label | string | ReactNode | - | Radio group label |
control | Control | - | React Hook Form control object |
options | Option[] | - | Array of radio options |
defaultValue | string | number | boolean | - | Default selected value |
error | object | - | Error object from validation |
isDisabled | boolean | false | Disabled state |
isRequired | boolean | false | Required field |
Option Structure
interface Option {
value: string | number | boolean;
label: string;
desc?: string; // Optional description
}
Usage Examples
Basic Radio Group
import WPRadio from 'components/Radio/WPRadio';
import { useForm } from 'react-hook-form';
function BasicRadioGroup() {
const { control } = useForm();
const genderOptions = [
{ value: 'male', label: 'Male' },
{ value: 'female', label: 'Female' },
{ value: 'other', label: 'Other' },
];
return (
<WPRadio
name='gender'
label='Gender'
control={control}
options={genderOptions}
defaultValue='male'
/>
);
}
Radio Group with Descriptions
import WPRadio from 'components/Radio/WPRadio';
function RadioWithDescriptions() {
const { control } = useForm();
const planOptions = [
{
value: 'basic',
label: 'Basic Plan',
desc: 'Perfect for small teams with basic features',
},
{
value: 'premium',
label: 'Premium Plan',
desc: 'Advanced features for growing teams',
},
{
value: 'enterprise',
label: 'Enterprise Plan',
desc: 'Full feature set for large organizations',
},
];
return (
<WPRadio
name='plan'
label='Select a Plan'
control={control}
options={planOptions}
isRequired
/>
);
}
Radio Group with Custom Option
import WPRadio from 'components/Radio/WPRadio';
function RadioWithCustomOption() {
const { control, watch } = useForm();
const selectedOption = watch('paymentMethod');
const paymentOptions = [
{
value: 'credit_card',
label: 'Credit Card',
desc: 'Pay with Visa, MasterCard, or American Express',
},
{
value: 'bank_transfer',
label: 'Bank Transfer',
desc: 'Direct transfer from your bank account',
},
{
value: 'custom',
label: 'Other Payment Method',
desc: 'Specify a different payment method',
},
];
return (
<>
<WPRadio
name='paymentMethod'
label='Payment Method'
control={control}
options={paymentOptions}
isRequired
/>
{selectedOption === 'custom' && (
<WPInput
name='customPaymentMethod'
label='Specify Payment Method'
control={control}
placeholder='Enter payment method...'
rules={{ required: 'Please specify the payment method' }}
/>
)}
</>
);
}
Disabled Radio Group
import WPRadio from 'components/Radio/WPRadio';
function DisabledRadioGroup() {
const { control } = useForm();
const statusOptions = [
{ value: 'active', label: 'Active' },
{ value: 'inactive', label: 'Inactive' },
];
return (
<WPRadio
name='status'
label='Account Status'
control={control}
options={statusOptions}
defaultValue='active'
isDisabled
/>
);
}
CustomRadioButton
Custom styled radio button group with flexible layout options.
Component Location
import CustomRadioButton from 'components/Radio/CustomRadio';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | RadioOption[] | - | Array of radio options |
size | string | - | Radio button size |
isDisabled | boolean | false | Disabled state |
defaultValue | string | - | Default selected value |
onChange | function | - | Change handler |
RadioOption Structure
interface RadioOption {
defaultValue: string;
label: string;
desc?: string;
}
Usage Examples
Basic Custom Radio
import CustomRadioButton from 'components/Radio/CustomRadio';
import { useState } from 'react';
function CustomRadioExample() {
const [selectedValue, setSelectedValue] = useState('option1');
const radioData = [
{
defaultValue: 'option1',
label: 'Option 1',
desc: 'Description for option 1',
},
{
defaultValue: 'option2',
label: 'Option 2',
desc: 'Description for option 2',
},
{
defaultValue: 'option3',
label: 'Option 3',
desc: 'Description for option 3',
},
];
return (
<CustomRadioButton
data={radioData}
defaultValue={selectedValue}
onChange={setSelectedValue}
size='md'
/>
);
}
Priority Selection
import CustomRadioButton from 'components/Radio/CustomRadio';
function PrioritySelection() {
const [priority, setPriority] = useState('medium');
const priorityOptions = [
{
defaultValue: 'low',
label: 'Low Priority',
desc: 'Non-urgent tasks and requests',
},
{
defaultValue: 'medium',
label: 'Medium Priority',
desc: 'Standard tasks with normal timeline',
},
{
defaultValue: 'high',
label: 'High Priority',
desc: 'Urgent tasks requiring immediate attention',
},
];
return (
<CustomRadioButton
data={priorityOptions}
defaultValue={priority}
onChange={setPriority}
/>
);
}
Form Integration
import CustomRadioButton from 'components/Radio/CustomRadio';
import { useForm } from 'react-hook-form';
function FormWithCustomRadio() {
const { register, setValue, watch, handleSubmit } = useForm();
const selectedFrequency = watch('frequency');
const frequencyOptions = [
{
defaultValue: 'daily',
label: 'Daily',
desc: 'Execute every day',
},
{
defaultValue: 'weekly',
label: 'Weekly',
desc: 'Execute once per week',
},
{
defaultValue: 'monthly',
label: 'Monthly',
desc: 'Execute once per month',
},
];
const handleRadioChange = value => {
setValue('frequency', value);
};
return (
<form onSubmit={handleSubmit(console.log)}>
<input type='hidden' {...register('frequency', { required: true })} />
<CustomRadioButton
data={frequencyOptions}
defaultValue={selectedFrequency}
onChange={handleRadioChange}
/>
<button type='submit'>Submit</button>
</form>
);
}
Form Integration Patterns
React Hook Form Integration
import { useForm } from 'react-hook-form';
import { Stack } from '@chakra-ui/react';
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
import WPRadio from 'components/Radio/WPRadio';
function ComprehensiveForm() {
const { control, handleSubmit, watch } = useForm({
defaultValues: {
notifications: false,
marketing: false,
accountType: 'personal',
theme: 'light',
},
});
const accountType = watch('accountType');
const accountTypeOptions = [
{
value: 'personal',
label: 'Personal Account',
desc: 'For individual use',
},
{
value: 'business',
label: 'Business Account',
desc: 'For teams and organizations',
},
];
const themeOptions = [
{ value: 'light', label: 'Light Theme' },
{ value: 'dark', label: 'Dark Theme' },
{ value: 'auto', label: 'Auto (System)' },
];
const onSubmit = data => {
console.log('Form data:', data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={6}>
{/* Account Type Selection */}
<WPRadio
name='accountType'
label='Account Type'
control={control}
options={accountTypeOptions}
isRequired
/>
{/* Conditional Business Features */}
{accountType === 'business' && (
<V2WPCheckbox
text='Enable team collaboration features'
name='teamFeatures'
control={control}
/>
)}
{/* Notification Preferences */}
<Stack spacing={3}>
<h3>Notification Preferences</h3>
<V2WPCheckbox
text='Email notifications'
name='notifications'
control={control}
/>
<V2WPCheckbox
text='Marketing emails'
name='marketing'
control={control}
/>
</Stack>
{/* Theme Selection */}
<WPRadio
name='theme'
label='Theme Preference'
control={control}
options={themeOptions}
/>
<button type='submit'>Save Preferences</button>
</Stack>
</form>
);
}
Validation Patterns
import { useForm } from 'react-hook-form';
import WPRadio from 'components/Radio/WPRadio';
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
function ValidatedForm() {
const {
control,
handleSubmit,
watch,
formState: { errors },
} = useForm();
const agreeToTerms = watch('agreeToTerms');
const accountType = watch('accountType');
const accountTypeOptions = [
{ value: 'individual', label: 'Individual' },
{ value: 'corporate', label: 'Corporate' },
];
const onSubmit = data => {
console.log('Validated data:', data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<WPRadio
name='accountType'
label='Account Type'
control={control}
options={accountTypeOptions}
isRequired
error={errors.accountType}
/>
<V2WPCheckbox
text='I agree to the Terms and Conditions'
name='agreeToTerms'
control={control}
/>
{/* Conditional validation */}
{accountType === 'corporate' && (
<V2WPCheckbox
text='I have authority to bind this corporation'
name='corporateAuthority'
control={control}
/>
)}
<button type='submit' disabled={!agreeToTerms}>
Submit
</button>
</form>
);
}
Styling and Theming
Custom Checkbox Styling
import { Checkbox, FormControl, Text, Box } from '@chakra-ui/react';
import { Controller } from 'react-hook-form';
function StyledCheckbox({ name, label, control }) {
return (
<FormControl>
<Controller
name={name}
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<Checkbox
ref={ref}
isChecked={value}
onChange={onChange}
onBlur={onBlur}
colorScheme='green'
size='lg'
iconSize='1rem'
sx={{
'.chakra-checkbox__control': {
borderRadius: '4px',
_checked: {
bg: 'green.500',
borderColor: 'green.500',
_hover: {
bg: 'green.600',
borderColor: 'green.600',
},
},
},
}}
>
<Text fontSize='md' fontWeight='medium' color='gray.700'>
{label}
</Text>
</Checkbox>
)}
/>
</FormControl>
);
}
Custom Radio Styling
import {
RadioGroup,
Radio,
Stack,
Box,
Text,
useColorModeValue,
} from '@chakra-ui/react';
import { Controller } from 'react-hook-form';
function StyledRadioGroup({ name, label, options, control }) {
const bg = useColorModeValue('white', 'gray.800');
const borderColor = useColorModeValue('gray.200', 'gray.600');
return (
<Controller
name={name}
control={control}
render={({ field: { onChange, value } }) => (
<Box>
<Text fontSize='lg' fontWeight='semibold' mb={4}>
{label}
</Text>
<RadioGroup onChange={onChange} value={value}>
<Stack spacing={3}>
{options.map(option => (
<Box
key={option.value}
p={4}
border='1px'
borderColor={
value === option.value ? 'green.500' : borderColor
}
borderRadius='md'
bg={bg}
cursor='pointer'
_hover={{ borderColor: 'green.300' }}
onClick={() => onChange(option.value)}
>
<Radio value={option.value} colorScheme='green'>
<Stack spacing={1}>
<Text fontWeight='medium'>{option.label}</Text>
{option.desc && (
<Text fontSize='sm' color='gray.600'>
{option.desc}
</Text>
)}
</Stack>
</Radio>
</Box>
))}
</Stack>
</RadioGroup>
</Box>
)}
/>
);
}
Accessibility Features
Keyboard Navigation
- Tab Navigation: All components support keyboard navigation
- Space Key: Toggles checkbox state or selects radio option
- Arrow Keys: Navigate between radio options in a group
Screen Reader Support
- ARIA Labels: Proper labeling for assistive technologies
- Role Attributes: Correct semantic roles for checkboxes and radio groups
- State Announcements: Changes in selection state are announced
Focus Management
import { useRef, useEffect } from 'react';
import WPCheckbox from 'components/Checkbox/WPCheckbox';
function FocusManagement() {
const firstCheckboxRef = useRef();
useEffect(() => {
// Focus first checkbox on component mount
if (firstCheckboxRef.current) {
firstCheckboxRef.current.focus();
}
}, []);
return (
<div>
<WPCheckbox
ref={firstCheckboxRef}
label='First option'
// ... other props
/>
{/* Other checkboxes */}
</div>
);
}
Performance Optimization
Memoized Components
import { memo } from 'react';
import WPCheckbox from 'components/Checkbox/WPCheckbox';
const MemoizedCheckbox = memo(WPCheckbox);
function OptimizedCheckboxList({ items }) {
return (
<>
{items.map(item => (
<MemoizedCheckbox
key={item.id}
label={item.label}
// ... other props
/>
))}
</>
);
}
Efficient State Management
import { useReducer } from 'react';
import V2WPCheckbox from 'components/Checkbox/V2WPCheckbox';
function checkboxReducer(state, action) {
switch (action.type) {
case 'TOGGLE':
return {
...state,
[action.name]: !state[action.name],
};
case 'SET_ALL':
return Object.keys(state).reduce((acc, key) => {
acc[key] = action.value;
return acc;
}, {});
default:
return state;
}
}
function EfficientCheckboxGroup() {
const [checkboxState, dispatch] = useReducer(checkboxReducer, {
option1: false,
option2: false,
option3: false,
});
const handleToggle = name => {
dispatch({ type: 'TOGGLE', name });
};
const handleSelectAll = () => {
const allSelected = Object.values(checkboxState).every(Boolean);
dispatch({ type: 'SET_ALL', value: !allSelected });
};
return (
<div>
<button onClick={handleSelectAll}>
{Object.values(checkboxState).every(Boolean)
? 'Deselect All'
: 'Select All'}
</button>
{Object.entries(checkboxState).map(([name, isChecked]) => (
<WPCheckbox
key={name}
label={name}
isChecked={isChecked}
onChange={() => handleToggle(name)}
/>
))}
</div>
);
}
Best Practices
- Clear Labels: Use descriptive labels that clearly indicate the purpose
- Logical Grouping: Group related options together
- Default Values: Provide sensible default selections
- Validation: Implement appropriate validation for required fields
- Accessibility: Ensure proper keyboard navigation and screen reader support
- Performance: Use memoization for large lists of options
- Visual Hierarchy: Use consistent spacing and typography
- Error Handling: Display clear error messages for validation failures
Migration Notes
From Legacy to V2
- React Hook Form Integration: V2 components have built-in form integration
- Styling Updates: Enhanced styling with better theming support
- Accessibility Improvements: Better accessibility features
- API Changes: Some prop names may have changed
Component Mapping
WPCheckbox→V2WPCheckbox(for form integration)CustomRadioButton→WPRadio(for form integration)
Related Components
- WP Input Components - Text input components
- Form Components - Form architecture and patterns
- Selects - Selection input components
- Date & Time Inputs - Date and time input components