Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"eas-build-pre-install": "cd .. && yarn",
"start": "EXPO_NO_TYPESCRIPT_SETUP=1 expo start --dev-client",
"android": "EXPO_NO_TYPESCRIPT_SETUP=1 expo run:android",
"ios": "EXPO_NO_TYPESCRIPT_SETUP=1 expo run:ios"
"ios": "EXPO_NO_TYPESCRIPT_SETUP=1 expo run:ios",
"web": "EXPO_NO_TYPESCRIPT_SETUP=1 expo start --web"
},
"dependencies": {
"@react-native-async-storage/async-storage": "2.2.0",
Expand Down
248 changes: 201 additions & 47 deletions example/src/Examples/CheckboxExample.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,229 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';

import { Checkbox, Palette, Text, TouchableRipple } from 'react-native-paper';
import { Checkbox, Text, useTheme } from 'react-native-paper';

import ScreenWrapper from '../ScreenWrapper';

const CheckboxExample = () => {
const [checkedNormal, setCheckedNormal] = React.useState<boolean>(true);
const [checkedCustom, setCheckedCustom] = React.useState<boolean>(true);
const [indeterminate, setIndeterminate] = React.useState<boolean>(true);
type Status = 'unchecked' | 'checked' | 'indeterminate';

const STATUSES: Status[] = ['unchecked', 'checked', 'indeterminate'];

type Row = {
label: string;
render: (status: Status) => React.ReactNode;
};

const ROWS: Row[] = [
{
label: 'Default',
render: (status) => <Checkbox status={status} onPress={() => {}} />,
},
{
label: 'Disabled',
render: (status) => <Checkbox status={status} disabled />,
},
{
label: 'Custom color (tertiary)',
render: (status) => <CustomColorCheckbox status={status} />,
},
{
label: 'Error',
render: (status) => <Checkbox status={status} error onPress={() => {}} />,
},
];

const CustomColorCheckbox = ({ status }: { status: Status }) => {
const theme = useTheme();
return (
<ScreenWrapper style={styles.container}>
<TouchableRipple onPress={() => setCheckedNormal(!checkedNormal)}>
<View style={styles.row}>
<Text>Normal</Text>
<View pointerEvents="none">
<Checkbox status={checkedNormal ? 'checked' : 'unchecked'} />
</View>
</View>
</TouchableRipple>
<Checkbox
status={status}
color={theme.colors.tertiary}
uncheckedColor={theme.colors.tertiary}
onPress={() => {}}
/>
);
};

<TouchableRipple onPress={() => setCheckedCustom(!checkedCustom)}>
<View style={styles.row}>
<Text>Custom</Text>
<View pointerEvents="none">
<Checkbox
color={Palette.error70}
status={checkedCustom ? 'checked' : 'unchecked'}
/>
</View>
const Interactive = () => {
const theme = useTheme();
const [aChecked, setAChecked] = React.useState(false);
const [bIndeterminate, setBIndeterminate] = React.useState(false);
return (
<View style={styles.interactive}>
<Text style={[styles.rowLabel, { color: theme.colors.onSurfaceVariant }]}>
Tap to toggle
</Text>
<View style={styles.interactiveRow}>
<View style={styles.cell}>
<Checkbox
status={aChecked ? 'checked' : 'unchecked'}
onPress={() => setAChecked((v) => !v)}
/>
</View>
</TouchableRipple>

<TouchableRipple onPress={() => setIndeterminate(!indeterminate)}>
<View style={styles.row}>
<Text>Indeterminate</Text>
<View pointerEvents="none">
<Checkbox status={indeterminate ? 'indeterminate' : 'unchecked'} />
</View>
<Text
style={[
styles.interactiveLabel,
{ color: theme.colors.onSurfaceVariant },
]}
>
unchecked ↔ checked
</Text>
</View>
<View style={[styles.interactiveRow, styles.interactiveRowSpacing]}>
<View style={styles.cell}>
<Checkbox
status={bIndeterminate ? 'indeterminate' : 'unchecked'}
onPress={() => setBIndeterminate((v) => !v)}
/>
</View>
</TouchableRipple>
<Text
style={[
styles.interactiveLabel,
{ color: theme.colors.onSurfaceVariant },
]}
>
unchecked ↔ indeterminate
</Text>
</View>
</View>
);
};

<View style={styles.row}>
<Text>Checked (Disabled)</Text>
<Checkbox status="checked" disabled />
const IndeterminateParent = () => {
const theme = useTheme();
const [child1, setChild1] = React.useState(true);
const [child2, setChild2] = React.useState(false);
const [child3, setChild3] = React.useState(true);
const allChecked = child1 && child2 && child3;
const noneChecked = !child1 && !child2 && !child3;
const parentStatus: Status = allChecked
? 'checked'
: noneChecked
? 'unchecked'
: 'indeterminate';
const toggleAll = () => {
const next = !allChecked;
setChild1(next);
setChild2(next);
setChild3(next);
};
return (
<View style={styles.row}>
<Text style={[styles.rowLabel, { color: theme.colors.onSurfaceVariant }]}>
Parent / children (indeterminate)
</Text>
<View style={styles.parentRow}>
<Checkbox status={parentStatus} onPress={toggleAll} />
<Text
style={[styles.interactiveLabel, { color: theme.colors.onSurface }]}
>
Select all
</Text>
</View>
<View style={styles.childRow}>
<Checkbox
status={child1 ? 'checked' : 'unchecked'}
onPress={() => setChild1((v) => !v)}
/>
<Text
style={[styles.interactiveLabel, { color: theme.colors.onSurface }]}
>
Apples
</Text>
</View>
<View style={styles.row}>
<Text>Unchecked (Disabled)</Text>
<Checkbox status="unchecked" disabled />
<View style={styles.childRow}>
<Checkbox
status={child2 ? 'checked' : 'unchecked'}
onPress={() => setChild2((v) => !v)}
/>
<Text
style={[styles.interactiveLabel, { color: theme.colors.onSurface }]}
>
Bananas
</Text>
</View>
<View style={styles.row}>
<Text>Indeterminate (Disabled)</Text>
<Checkbox status="indeterminate" disabled />
<View style={styles.childRow}>
<Checkbox
status={child3 ? 'checked' : 'unchecked'}
onPress={() => setChild3((v) => !v)}
/>
<Text
style={[styles.interactiveLabel, { color: theme.colors.onSurface }]}
>
Cherries
</Text>
</View>
</View>
);
};

const CheckboxExample = () => {
const theme = useTheme();
return (
<ScreenWrapper contentContainerStyle={styles.scrollContent}>
<Interactive />
{ROWS.map((row) => (
<View key={row.label} style={styles.row}>
<Text
style={[styles.rowLabel, { color: theme.colors.onSurfaceVariant }]}
>
{row.label}
</Text>
<View style={styles.cells}>
{STATUSES.map((status) => (
<View key={status} style={styles.cell}>
{row.render(status)}
</View>
))}
</View>
</View>
))}
<IndeterminateParent />
</ScreenWrapper>
);
};

CheckboxExample.title = 'Checkbox';

const styles = StyleSheet.create({
container: {
paddingVertical: 8,
scrollContent: { paddingHorizontal: 16, paddingTop: 16, paddingBottom: 32 },
row: { marginBottom: 20 },
rowLabel: {
fontSize: 14,
fontWeight: '500',
marginBottom: 6,
opacity: 0.7,
},
cells: {
flexDirection: 'row',
alignItems: 'center',
},
cell: {
width: 60,
alignItems: 'center',
},
interactive: { marginBottom: 24 },
interactiveRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
interactiveRowSpacing: { marginTop: 8 },
interactiveLabel: {
fontSize: 14,
opacity: 0.7,
},
parentRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
row: {
childRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 8,
paddingHorizontal: 16,
gap: 12,
paddingLeft: 32,
},
});

Expand Down
Loading
Loading