@atom_design/controls
v1.0.1
Published
React Native Controls component: checkbox, radio, toggle with check-all support and full accessibility.
Readme
@atom_design/controls
A flexible and accessible Controls Component for React Native — supporting Checkbox, Radio, and Toggle controls with consistent styling and full accessibility support. Part of the Atom Design System.
✨ Features
- 📦 Three Control Types - Checkbox, Radio, and Toggle in one component
- ✅ Check All Support - Built-in "Select All" for checkbox groups
- 🎨 Customizable Styling - Colors, sizes, and layout options
- ♿ Fully Accessible - Screen reader support with proper ARIA roles
- 📱 Touch-Friendly - Optimized touch targets for mobile
- 🔒 Disabled States - Per-option and global disable support
- 📐 Flexible Layouts - Row and column arrangements
- 🎯 TypeScript Support - Full type definitions included
📦 Installation
npm install @atom_design/controlsOr with yarn:
yarn add @atom_design/controlsPeer Dependencies
Make sure you have the required peer dependencies installed:
npm install react-native-vector-icons prop-typesFor react-native-vector-icons setup, follow the installation guide.
📥 Import
import Controls from '@atom_design/controls';
// or
import { Controls } from '@atom_design/controls';🎯 Basic Usage
Checkbox Group
import React, { useState } from 'react';
import Controls from '@atom_design/controls';
function CheckboxExample() {
const [selected, setSelected] = useState([]);
return (
<Controls
type="checkbox"
options={[
{ label: 'Email notifications', value: 'email' },
{ label: 'SMS notifications', value: 'sms' },
{ label: 'Push notifications', value: 'push' },
]}
value={selected}
onChange={setSelected}
checkAll
/>
);
}Radio Group
import React, { useState } from 'react';
import Controls from '@atom_design/controls';
function RadioExample() {
const [size, setSize] = useState('medium');
return (
<Controls
type="radio"
options={[
{ label: 'Small', value: 'small' },
{ label: 'Medium', value: 'medium' },
{ label: 'Large', value: 'large' },
]}
value={size}
onChange={setSize}
layout="row"
/>
);
}Toggle Switch
import React, { useState } from 'react';
import Controls from '@atom_design/controls';
function ToggleExample() {
const [enabled, setEnabled] = useState(false);
return (
<Controls
type="toggle"
label="Dark mode"
value={enabled}
onChange={setEnabled}
/>
);
}📋 Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| type | 'checkbox' \| 'radio' \| 'toggle' | 'checkbox' | Type of control to render |
| options | Option[] | [] | Array of options (for checkbox/radio) |
| value | string[] \| string \| boolean | - | Current value(s) based on type |
| onChange | function | - | Callback when value changes |
| label | string | - | Label text for toggle control |
| layout | 'row' \| 'column' | 'column' | Layout direction for radio/checkbox |
| checkAll | boolean | false | Show "Check All" option for checkbox |
| onCheckAll | function | - | Callback when check all is toggled |
| disabled | boolean | false | Disable all controls |
| size | 'small' \| 'medium' \| 'large' | 'medium' | Size of controls |
| activeColor | string | '#d9232d' | Color when selected/active |
| inactiveColor | string | '#ccc' | Color when unselected/inactive |
| checkAllLabel | string | 'Select All' | Label for check all option |
| style | ViewStyle | - | Container style override |
| labelStyle | TextStyle | - | Label text style override |
| testID | string | - | Test ID for testing frameworks |
| accessibilityLabel | string | - | Accessibility label for screen readers |
Option Interface
interface Option {
label: string; // Display text
value: string; // Unique identifier
disabled?: boolean; // Disable specific option
}🎨 Customization Examples
Custom Colors
<Controls
type="checkbox"
options={options}
value={selected}
onChange={setSelected}
activeColor="#4CAF50"
inactiveColor="#9E9E9E"
/>Different Sizes
// Small controls
<Controls type="radio" options={options} value={value} onChange={setValue} size="small" />
// Large controls
<Controls type="checkbox" options={options} value={selected} onChange={setSelected} size="large" />Disabled Options
<Controls
type="checkbox"
options={[
{ label: 'Available', value: '1' },
{ label: 'Coming Soon', value: '2', disabled: true },
{ label: 'Also Available', value: '3' },
]}
value={selected}
onChange={setSelected}
/>Row Layout for Radio
<Controls
type="radio"
options={[
{ label: 'S', value: 'small' },
{ label: 'M', value: 'medium' },
{ label: 'L', value: 'large' },
{ label: 'XL', value: 'xlarge' },
]}
value={size}
onChange={setSize}
layout="row"
/>🧪 Test Screen Example
import React, { useState } from 'react';
import { View, Text, ScrollView, StyleSheet } from 'react-native';
import Controls from '@atom_design/controls';
const ControlsTestScreen = () => {
// Checkbox state
const [notifications, setNotifications] = useState(['email']);
// Radio state
const [priority, setPriority] = useState('medium');
// Toggle states
const [darkMode, setDarkMode] = useState(false);
const [autoSave, setAutoSave] = useState(true);
const notificationOptions = [
{ label: 'Email notifications', value: 'email' },
{ label: 'SMS notifications', value: 'sms' },
{ label: 'Push notifications', value: 'push' },
{ label: 'In-app notifications', value: 'inapp' },
];
const priorityOptions = [
{ label: 'Low', value: 'low' },
{ label: 'Medium', value: 'medium' },
{ label: 'High', value: 'high' },
{ label: 'Urgent', value: 'urgent' },
];
return (
<ScrollView style={styles.container}>
<Text style={styles.header}>Atom Design - Controls</Text>
{/* Checkbox Demo */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Checkbox Group</Text>
<Text style={styles.description}>With "Check All" option</Text>
<Controls
type="checkbox"
options={notificationOptions}
value={notifications}
onChange={setNotifications}
checkAll
onCheckAll={(all) => console.log('All checked:', all)}
/>
<Text style={styles.result}>
Selected: {notifications.length > 0 ? notifications.join(', ') : 'None'}
</Text>
</View>
{/* Radio Demo - Column Layout */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Radio Group (Column)</Text>
<Controls
type="radio"
options={priorityOptions}
value={priority}
onChange={setPriority}
layout="column"
/>
<Text style={styles.result}>Selected: {priority}</Text>
</View>
{/* Radio Demo - Row Layout */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Radio Group (Row)</Text>
<Controls
type="radio"
options={[
{ label: 'S', value: 'small' },
{ label: 'M', value: 'medium' },
{ label: 'L', value: 'large' },
]}
value={priority === 'low' ? 'small' : priority === 'high' ? 'large' : 'medium'}
onChange={(v) => console.log('Size:', v)}
layout="row"
activeColor="#FF5722"
/>
</View>
{/* Toggle Demos */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Toggle Switches</Text>
<View style={styles.toggleRow}>
<Controls
type="toggle"
label="Dark Mode"
value={darkMode}
onChange={setDarkMode}
/>
</View>
<View style={styles.toggleRow}>
<Controls
type="toggle"
label="Auto-save documents"
value={autoSave}
onChange={setAutoSave}
activeColor="#4CAF50"
/>
</View>
<View style={styles.toggleRow}>
<Controls
type="toggle"
label="Disabled toggle"
value={false}
onChange={() => {}}
disabled
/>
</View>
</View>
{/* Size Variants */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Size Variants</Text>
<Text style={styles.label}>Small:</Text>
<Controls
type="checkbox"
options={[{ label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }]}
value={['a']}
onChange={() => {}}
size="small"
/>
<Text style={styles.label}>Medium (default):</Text>
<Controls
type="checkbox"
options={[{ label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }]}
value={['a']}
onChange={() => {}}
size="medium"
/>
<Text style={styles.label}>Large:</Text>
<Controls
type="checkbox"
options={[{ label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }]}
value={['a']}
onChange={() => {}}
size="large"
/>
</View>
{/* Disabled States */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Disabled Controls</Text>
<Controls
type="checkbox"
options={[
{ label: 'Available option', value: '1' },
{ label: 'Disabled option', value: '2', disabled: true },
{ label: 'Another available', value: '3' },
]}
value={['1']}
onChange={() => {}}
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5F5F5',
},
header: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 20,
color: '#1A1A1A',
},
section: {
backgroundColor: '#FFFFFF',
marginHorizontal: 16,
marginBottom: 16,
padding: 16,
borderRadius: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
sectionTitle: {
fontSize: 18,
fontWeight: '600',
marginBottom: 8,
color: '#1A1A1A',
},
description: {
fontSize: 14,
color: '#666',
marginBottom: 12,
},
label: {
fontSize: 14,
fontWeight: '500',
marginTop: 12,
marginBottom: 8,
color: '#333',
},
result: {
marginTop: 12,
fontSize: 14,
color: '#d9232d',
fontStyle: 'italic',
},
toggleRow: {
marginVertical: 8,
},
});
export default ControlsTestScreen;♿ Accessibility
The Controls component includes comprehensive accessibility support:
- Checkbox: Uses
accessibilityRole="checkbox"with properaccessibilityState - Radio: Uses
accessibilityRole="radio"with checked state - Toggle: Uses
accessibilityRole="switch"with on/off state - All controls support
accessibilityLabelandaccessibilityHint - Proper keyboard navigation support
- Screen reader friendly labels
📝 TypeScript
Full TypeScript definitions are included:
import Controls, { ControlsProps, Option } from '@atom_design/controls';
const options: Option[] = [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
];
const MyComponent: React.FC = () => {
const [value, setValue] = useState<string[]>([]);
return (
<Controls
type="checkbox"
options={options}
value={value}
onChange={setValue}
/>
);
};📄 License
MIT © Atom Design
👤 Author
Atom Design Team
Part of the Atom Design System for React Native.
