Skip to content
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ type NativeProps = $ReadOnly<{|
on?: WithDefault<boolean, false>,
thumbTintColor?: ?ColorValue,
trackTintColor?: ?ColorValue,
android_minWidth?: number,

// Events
onChange?: BubblingEventHandler<SwitchChangeEvent>,
Expand Down
8 changes: 8 additions & 0 deletions Libraries/Components/Switch/Switch.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,6 +71,12 @@ export type Props = $ReadOnly<{|
*/
ios_backgroundColor?: ?ColorValue,

/**
* Only Android, custom switch minimum width size.
* Switch width should be also separately specified in the style prop.
**/
android_minWidth?: number,

/**
Invoked when the user tries to change the value of the switch. Receives
the change event as an argument. If you want to only receive the new
Expand DownExpand Up@@ -143,6 +149,7 @@ class Switch extends React.Component<Props> {
thumbColor,
trackColor,
value,
android_minWidth,
...props
} = this.props;

Expand All@@ -157,6 +164,7 @@ class Switch extends React.Component<Props> {
thumbTintColor: thumbColor,
trackColorForFalse: trackColorForFalse,
trackColorForTrue: trackColorForTrue,
android_minWidth,
trackTintColor: value === true ? trackColorForTrue : trackColorForFalse,
};

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -178,6 +178,12 @@ public void setTrackTintColor(ReactSwitch view, @Nullable Integer color) {
view.setTrackColor(color);
}

@ReactProp(name = "android_minWidth")
public void setSwitchMinWidth(ReactSwitch view, float dp) {
Integer pixels = Math.round(PixelUtil.toPixelFromDIP(dp));
view.setSwitchMinWidth(pixels);
}

@Override
public void setNativeValue(ReactSwitch view, boolean value) {
setValueInternal(view, value);
Expand Down
58 changes: 57 additions & 1 deletion packages/rn-tester/js/examples/Switch/SwitchExample.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
'use strict';

const React = require('react');
const {Switch, Text, View} = require('react-native');
const {Button, Switch, Text, View} = require('react-native');

type OnOffIndicatorProps = $ReadOnly<{|on: boolean, testID: string|}>;
function OnOffIndicator({on, testID}: OnOffIndicatorProps) {
Expand DownExpand Up@@ -202,6 +202,56 @@ class EventSwitchExample extends React.Component<{...}, $FlowFixMeState> {
}
}

type CustomSizeSwitchExampleState = $ReadOnly<{|
trueSwitchIsOn: boolean,
falseSwitchIsOn: boolean,
width: number,
|}>;

class CustomSizeSwitchExample extends React.Component<
{||},
CustomSizeSwitchExampleState,
> {
state = {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
width: 50,
};

render() {
const {width} = this.state;
return (
<>
<View
style={{
display: 'flex',
alignItems: 'flex-end',
}}>
<Switch
testID="on-off-initial-off"
onValueChange={value => this.setState({falseSwitchIsOn: value})}
trackColor={{
true: 'yellow',
false: 'purple',
}}
value={this.state.falseSwitchIsOn}
android_minWidth={width}
style={{width}}
/>
</View>
<Button
title="increase width"
onPress={() => this.setState({width: width + 50})}
/>
<Button
title="decrease width"
onPress={() => this.setState({width: width - 50})}
/>
</>
);
}
}

exports.title = 'Switch';
exports.documentationURL = 'https://reactnative.dev/docs/switch';
exports.category = 'UI';
Expand DownExpand Up@@ -238,4 +288,10 @@ exports.examples = [
return <ColorSwitchExample />;
},
},
{
title: 'Custom size',
render(): React.Element<any> {
return <CustomSizeSwitchExample />;
},
},
];