Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mode to radio button #2379

Merged
merged 2 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions example/src/ExampleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import TextInputExample from './Examples/TextInputExample';
import ToggleButtonExample from './Examples/ToggleButtonExample';
import TouchableRippleExample from './Examples/TouchableRippleExample';
import ThemeExample from './Examples/ThemeExample';
import RadioButtonItemExample from './Examples/RadioButtonItemExample';

export const examples: Record<
string,
Expand Down Expand Up @@ -64,6 +65,7 @@ export const examples: Record<
progressbar: ProgressBarExample,
radio: RadioButtonExample,
radioGroup: RadioButtonGroupExample,
radioItem: RadioButtonItemExample,
searchbar: SearchbarExample,
snackbar: SnackbarExample,
surface: SurfaceExample,
Expand Down
56 changes: 56 additions & 0 deletions example/src/Examples/RadioButtonItemExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { RadioButton, Colors, useTheme } from 'react-native-paper';

const RadioButtonItemExample = () => {
const [checkedDefault, setCheckedDefault] = React.useState<boolean>(true);
const [checkedAndroid, setCheckedAndroid] = React.useState<boolean>(true);
const [checkedIOS, setCheckedIOS] = React.useState<boolean>(true);
const {
colors: { background },
} = useTheme();

return (
<View
style={[
styles.container,
{
backgroundColor: background,
},
]}
>
<RadioButton.Item
label="Default (will look like whatever system this is running on)"
status={checkedDefault ? 'checked' : 'unchecked'}
onPress={() => setCheckedDefault(!checkedDefault)}
value="default"
/>
<RadioButton.Item
label="Android"
mode="android"
status={checkedAndroid ? 'checked' : 'unchecked'}
onPress={() => setCheckedAndroid(!checkedAndroid)}
value="android"
/>
<RadioButton.Item
label="iOS"
mode="ios"
status={checkedIOS ? 'checked' : 'unchecked'}
onPress={() => setCheckedIOS(!checkedIOS)}
value="iOS"
/>
</View>
);
};

RadioButtonItemExample.title = 'Radio Button Item';

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.white,
paddingVertical: 8,
},
});

export default RadioButtonItemExample;
85 changes: 50 additions & 35 deletions src/components/RadioButton/RadioButtonItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { handlePress } from './utils';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
import RadioButton from './RadioButton';
import Text from '../Typography/Text';
import RadioButtonAndroid from './RadioButtonAndroid';
import RadioButtonIOS from './RadioButtonIOS';

export type Props = {
/**
Expand Down Expand Up @@ -62,6 +64,11 @@ export type Props = {
* testID to be used on tests.
*/
testID?: string;
/**
* Whether `<RadioButton.Android />` or `<RadioButton.IOS />` should be used.
* Left undefined `<RadioButton />` will be used.
*/
mode?: 'android' | 'ios';
};

/**
Expand Down Expand Up @@ -106,41 +113,49 @@ const RadioButtonItem = ({
theme: { colors },
accessibilityLabel,
testID,
}: Props) => (
<RadioButtonContext.Consumer>
{(context?: RadioButtonContextType) => {
return (
<TouchableRipple
onPress={
disabled
? undefined
: () =>
handlePress({
onPress: onPress,
onValueChange: context?.onValueChange,
value,
})
}
accessibilityLabel={accessibilityLabel}
testID={testID}
>
<View style={[styles.container, style]} pointerEvents="none">
<Text style={[styles.label, { color: colors.text }, labelStyle]}>
{label}
</Text>
<RadioButton
value={value}
disabled={disabled}
status={status}
color={color}
uncheckedColor={uncheckedColor}
/>
</View>
</TouchableRipple>
);
}}
</RadioButtonContext.Consumer>
);
mode,
}: Props) => {
const radioButtonProps = { value, disabled, status, color, uncheckedColor };
let radioButton: any;

if (mode === 'android') {
radioButton = <RadioButtonAndroid {...radioButtonProps} />;
} else if (mode === 'ios') {
radioButton = <RadioButtonIOS {...radioButtonProps} />;
} else {
radioButton = <RadioButton {...radioButtonProps} />;
}

return (
<RadioButtonContext.Consumer>
{(context?: RadioButtonContextType) => {
return (
<TouchableRipple
onPress={
disabled
? undefined
: () =>
handlePress({
onPress: onPress,
onValueChange: context?.onValueChange,
value,
})
}
accessibilityLabel={accessibilityLabel}
testID={testID}
>
<View style={[styles.container, style]} pointerEvents="none">
<Text style={[styles.label, { color: colors.text }, labelStyle]}>
{label}
</Text>
{radioButton}
</View>
</TouchableRipple>
);
}}
</RadioButtonContext.Consumer>
);
};

RadioButtonItem.displayName = 'RadioButton.Item';

Expand Down
50 changes: 50 additions & 0 deletions src/components/__tests__/RadioButton/RadioButtonItem.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as React from 'react';
import { Platform } from 'react-native';
import renderer from 'react-test-renderer';
import RadioButtonItem from '../../RadioButton/RadioButtonItem';

it('renders unchecked', () => {
const tree = renderer
.create(
<RadioButtonItem
status="unchecked"
label="Unchecked Button"
value="unchecked"
/>
)
.toJSON();

expect(tree).toMatchSnapshot();
});

it('can render the iOS radio button on different platforms', () => {
Platform.OS = 'android';
const tree = renderer
.create(
<RadioButtonItem
status="unchecked"
label="iOS Radio button"
mode="ios"
value="ios"
/>
)
.toJSON();

expect(tree).toMatchSnapshot();
});

it('can render the Android radio button on different platforms', () => {
Platform.OS = 'ios';
const tree = renderer
.create(
<RadioButtonItem
status="unchecked"
label="iOS Checkbox"
mode="android"
value="android"
/>
)
.toJSON();

expect(tree).toMatchSnapshot();
});