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

  • WPCheckboxV2WPCheckbox (for form integration)
  • CustomRadioButtonWPRadio (for form integration)