Skip to main content

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​

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​

PropTypeDefaultDescription
labelstring-Checkbox label text
descstring-Description text below label
isCheckedboolean-Checked state
isDisabledbooleanfalseDisabled state
isIndeterminatebooleanfalseIndeterminate state
onChangefunction-Change handler
sizestring'sm'Checkbox size
defaultValueany-Default value
registerfunction-React Hook Form register function
textStylestring-Text styling
colorstring-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​

PropTypeDefaultDescription
textstring-Checkbox label text
namestring-Field name for form registration
controlControl-React Hook Form control object
hiddenbooleanfalseWhether 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​

PropTypeDefaultDescription
namestring-Field name for form registration
labelstring | ReactNode-Radio group label
controlControl-React Hook Form control object
optionsOption[]-Array of radio options
defaultValuestring | number | boolean-Default selected value
errorobject-Error object from validation
isDisabledbooleanfalseDisabled state
isRequiredbooleanfalseRequired 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​

PropTypeDefaultDescription
dataRadioOption[]-Array of radio options
sizestring-Radio button size
isDisabledbooleanfalseDisabled state
defaultValuestring-Default selected value
onChangefunction-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 (
&lt;FormControl&gt;
<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 } }) => (
&lt;Box&gt;
<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​

  1. Clear Labels: Use descriptive labels that clearly indicate the purpose
  2. Logical Grouping: Group related options together
  3. Default Values: Provide sensible default selections
  4. Validation: Implement appropriate validation for required fields
  5. Accessibility: Ensure proper keyboard navigation and screen reader support
  6. Performance: Use memoization for large lists of options
  7. Visual Hierarchy: Use consistent spacing and typography
  8. Error Handling: Display clear error messages for validation failures

Migration Notes​

From Legacy to V2​

  1. React Hook Form Integration: V2 components have built-in form integration
  2. Styling Updates: Enhanced styling with better theming support
  3. Accessibility Improvements: Better accessibility features
  4. API Changes: Some prop names may have changed

Component Mapping​

  • WPCheckbox → V2WPCheckbox (for form integration)
  • CustomRadioButton → WPRadio (for form integration)