Skip to content
Closed
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
47 changes: 28 additions & 19 deletions docs/6.x/docs/components/Switch/Switch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ const Example = () => {

## Theming
Customize by overriding these `theme.colors` roles:
- `primary` / `onPrimary`: selected track + icon / selected handle
- `primaryContainer`: selected handle on hover, press
- `primary` / `onPrimary`: selected track / selected handle
- `onPrimaryContainer`: selected icon
- `primaryContainer`: selected handle on hover, focus, press
- `surfaceContainerHighest`: unselected track + icon
- `outline`: unselected resting handle, unselected track outline
- `onSurfaceVariant`: unselected handle on hover, press
- `onSurfaceVariant`: unselected handle on hover, focus, press
- `onSurface`: disabled track, handle, and icon fills
- `surface`: disabled selected handle
- `secondary`: focus indicator
Expand All @@ -54,22 +55,6 @@ Customize by overriding these `theme.colors` roles:

<div>

### onValueChange

</div>

<PropTable componentLink="Switch/Switch" prop="onValueChange" />

<div>

### disabled

</div>

<PropTable componentLink="Switch/Switch" prop="disabled" />

<div>

### checkedIcon

</div>
Expand Down Expand Up @@ -116,6 +101,30 @@ Customize by overriding these `theme.colors` roles:

<PropTable componentLink="Switch/Switch" prop="aria-label" />

<div>

### onValueChange

</div>

<PropTable componentLink="Switch/Switch" prop="onValueChange" />

<div>

### readOnly

</div>

<PropTable componentLink="Switch/Switch" prop="readOnly" />

<div>

### disabled

</div>

<PropTable componentLink="Switch/Switch" prop="disabled" />



<span />
Expand Down
36 changes: 36 additions & 0 deletions docs/6.x/docs/guides/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,39 @@ const theme = {
style={{ fontSize: 16, color: '#1C1B1F' }}
/>
```

### Switch

#### Explicit operability

A `Switch` now has to declare how it can be operated. Previously a switch with no `onValueChange` still rendered as an enabled, focusable control that did nothing when activated, and screen readers announced it as operable.

Pass `onValueChange` to make it interactive, or mark it `readOnly` or `disabled` to render it as a state indicator. A read-only switch keeps its enabled appearance and is still announced with its on/off state, but it is neither focusable nor pressable — it is not reported as disabled.

```tsx
// Before (v5) — an enabled switch that does nothing
<Switch value={isDarkTheme} />

// After (v6) — say which it is
<Switch value={isDarkTheme} onValueChange={setIsDarkTheme} />
<Switch value={isDarkTheme} readOnly />
<Switch value={isDarkTheme} disabled />
```

This most often shows up where the switch sits inside a row that owns the press:

```tsx
// After (v6)
<TouchableRipple onPress={toggleTheme}>
<View style={styles.row}>
<Text>Dark Theme</Text>
<View pointerEvents="none">
<Switch value={isDarkTheme} readOnly />
</View>
</View>
</TouchableRipple>
```

#### Touch target height

`Switch` now reserves the 48dp minimum touch target Material Design requires, so it occupies 48dp of height instead of 40dp. Nothing painted changed size — the track is still 52×32 — but rows containing a switch may become slightly taller.
69 changes: 38 additions & 31 deletions docs/src/data/componentDocs6x.json
Original file line number Diff line number Diff line change
Expand Up @@ -11354,10 +11354,10 @@
"Switch/Switch": {
"filepath": "Switch/Switch.tsx",
"title": "Switch",
"description": "Material 3 toggle between two mutually exclusive states (on / off).\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Switch } from 'react-native-paper';\n\nconst Example = () => {\n const [on, setOn] = React.useState(false);\n return <Switch value={on} onValueChange={setOn} />;\n};\n```\n\n## Theming\nCustomize by overriding these `theme.colors` roles:\n- `primary` / `onPrimary`: selected track + icon / selected handle\n- `primaryContainer`: selected handle on hover, press\n- `surfaceContainerHighest`: unselected track + icon\n- `outline`: unselected resting handle, unselected track outline\n- `onSurfaceVariant`: unselected handle on hover, press\n- `onSurface`: disabled track, handle, and icon fills\n- `surface`: disabled selected handle\n- `secondary`: focus indicator",
"description": "Material 3 toggle between two mutually exclusive states (on / off).\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Switch } from 'react-native-paper';\n\nconst Example = () => {\n const [on, setOn] = React.useState(false);\n return <Switch value={on} onValueChange={setOn} />;\n};\n```\n\n## Theming\nCustomize by overriding these `theme.colors` roles:\n- `primary` / `onPrimary`: selected track / selected handle\n- `onPrimaryContainer`: selected icon\n- `primaryContainer`: selected handle on hover, focus, press\n- `surfaceContainerHighest`: unselected track + icon\n- `outline`: unselected resting handle, unselected track outline\n- `onSurfaceVariant`: unselected handle on hover, focus, press\n- `onSurface`: disabled track, handle, and icon fills\n- `surface`: disabled selected handle\n- `secondary`: focus indicator",
"link": "switch",
"data": {
"description": "Material 3 toggle between two mutually exclusive states (on / off).\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Switch } from 'react-native-paper';\n\nconst Example = () => {\n const [on, setOn] = React.useState(false);\n return <Switch value={on} onValueChange={setOn} />;\n};\n```\n\n## Theming\nCustomize by overriding these `theme.colors` roles:\n- `primary` / `onPrimary`: selected track + icon / selected handle\n- `primaryContainer`: selected handle on hover, press\n- `surfaceContainerHighest`: unselected track + icon\n- `outline`: unselected resting handle, unselected track outline\n- `onSurfaceVariant`: unselected handle on hover, press\n- `onSurface`: disabled track, handle, and icon fills\n- `surface`: disabled selected handle\n- `secondary`: focus indicator",
"description": "Material 3 toggle between two mutually exclusive states (on / off).\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Switch } from 'react-native-paper';\n\nconst Example = () => {\n const [on, setOn] = React.useState(false);\n return <Switch value={on} onValueChange={setOn} />;\n};\n```\n\n## Theming\nCustomize by overriding these `theme.colors` roles:\n- `primary` / `onPrimary`: selected track / selected handle\n- `onPrimaryContainer`: selected icon\n- `primaryContainer`: selected handle on hover, focus, press\n- `surfaceContainerHighest`: unselected track + icon\n- `outline`: unselected resting handle, unselected track outline\n- `onSurfaceVariant`: unselected handle on hover, focus, press\n- `onSurface`: disabled track, handle, and icon fills\n- `surface`: disabled selected handle\n- `secondary`: focus indicator",
"displayName": "Switch",
"methods": [],
"statics": [],
Expand All @@ -11369,35 +11369,6 @@
},
"description": "Whether the switch is on."
},
"onValueChange": {
"required": false,
"tsType": {
"name": "signature",
"type": "function",
"raw": "(value: boolean) => void",
"signature": {
"arguments": [
{
"name": "value",
"type": {
"name": "boolean"
}
}
],
"return": {
"name": "void"
}
}
},
"description": "Called with the new value when the user toggles the switch."
},
"disabled": {
"required": false,
"tsType": {
"name": "boolean"
},
"description": "Disables interaction and renders the disabled visual state."
},
"checkedIcon": {
"required": false,
"tsType": {
Expand Down Expand Up @@ -11445,6 +11416,42 @@
"name": "string"
},
"description": "Accessibility label for the switch. This is read by the screen reader when the user focuses the switch."
},
"onValueChange": {
"required": false,
"tsType": {
"name": "signature",
"type": "function",
"raw": "(value: boolean) => void",
"signature": {
"arguments": [
{
"name": "value",
"type": {
"name": "boolean"
}
}
],
"return": {
"name": "void"
}
}
},
"description": "Called with the new value when the user toggles the switch. Required\nunless the switch is `readOnly` or `disabled`."
},
"readOnly": {
"required": false,
"tsType": {
"name": "boolean"
},
"description": "Reports state the user cannot change here. The switch keeps its enabled\nappearance and is still announced by a screen reader, but it is neither\nfocusable nor pressable."
},
"disabled": {
"required": false,
"tsType": {
"name": "boolean"
},
"description": "Disables interaction and renders the disabled visual state."
}
}
},
Expand Down
12 changes: 6 additions & 6 deletions example/src/DrawerItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ function DrawerItems() {
<View style={[styles.preference, styles.v3Preference]}>
<Text variant="labelLarge">Use Dynamic Theme</Text>
<View pointerEvents="none">
<Switch value={shouldUseDynamicTheme} />
<Switch value={shouldUseDynamicTheme} readOnly />
</View>
</View>
</TouchableRipple>
Expand All @@ -187,7 +187,7 @@ function DrawerItems() {
<View style={[styles.preference, styles.v3Preference]}>
<Text variant="labelLarge">Dark Theme</Text>
<View pointerEvents="none">
<Switch value={isDarkTheme} />
<Switch value={isDarkTheme} readOnly />
</View>
</View>
</TouchableRipple>
Expand All @@ -196,7 +196,7 @@ function DrawerItems() {
<View style={[styles.preference, styles.v3Preference]}>
<Text variant="labelLarge">RTL</Text>
<View pointerEvents="none">
<Switch value={isRTL} />
<Switch value={isRTL} readOnly />
</View>
</View>
</TouchableRipple>
Expand All @@ -205,7 +205,7 @@ function DrawerItems() {
<View style={[styles.preference, styles.v3Preference]}>
<Text variant="labelLarge">Collapsed drawer *</Text>
<View pointerEvents="none">
<Switch value={collapsed} />
<Switch value={collapsed} readOnly />
</View>
</View>
</TouchableRipple>
Expand All @@ -214,7 +214,7 @@ function DrawerItems() {
<View style={[styles.preference, styles.v3Preference]}>
<Text variant="labelLarge">Custom font *</Text>
<View pointerEvents="none">
<Switch value={customFontLoaded} />
<Switch value={customFontLoaded} readOnly />
</View>
</View>
</TouchableRipple>
Expand All @@ -225,7 +225,7 @@ function DrawerItems() {
{isIOS ? 'Highlight' : 'Ripple'} effect *
</Text>
<View pointerEvents="none">
<Switch value={rippleEffectEnabled} />
<Switch value={rippleEffectEnabled} readOnly />
</View>
</View>
</TouchableRipple>
Expand Down
2 changes: 1 addition & 1 deletion example/src/Examples/FABExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const FABExample = () => {
title="Show FAB"
right={() => (
<View pointerEvents="none">
<Switch value={showFab} />
<Switch value={showFab} readOnly />
</View>
)}
onPress={() => setShowFab((v) => !v)}
Expand Down
4 changes: 4 additions & 0 deletions example/src/Examples/SwitchExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ const SwitchExample = () => {
/>
</Row>

<Row label="Read-only">
<Switch value={defaultOn} readOnly />
</Row>

<View
style={[
styles.separator,
Expand Down
2 changes: 1 addition & 1 deletion example/src/Examples/TextInputExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const TextInputDemo = ({ variant }: TextInputDemoProps) => {
<View style={styles.switchRow}>
<Text variant="bodyMedium">{label}</Text>
<View pointerEvents="none">
<Switch value={controls[key]} />
<Switch value={controls[key]} readOnly />
</View>
</View>
</TouchableRipple>
Expand Down
Loading