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
128 changes: 128 additions & 0 deletions docs/6.x/docs/guides/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ The following component style props no longer support overriding their backgroun
- `Card`
- `Chip`
- `Dialog`
- `IconButton`
- `Menu`: `contentStyle`
- `Searchbar`
- `Snackbar`
Expand Down Expand Up @@ -546,6 +547,133 @@ An accordion with a `left` element now indents only its `List.Item` children. An

`theme` set on `List.Accordion` no longer reaches its children either. Pass it to the child that needs the override.

### IconButton

`IconButton` now follows the Material 3 Expressive spec. The color modes, size API, and toggle `selected` behavior have changed. Passing the old numeric `size` (for example `size={24}`) crashes at runtime, because `size` is now a named token and `IconButtonTokens.sizes[24]` is `undefined`.

#### Mode names

- **`contained`** → **`filled`**
- **`contained-tonal`** → **`tonal`**
- Unspecified mode is now **`standard`** (no container fill), which matches the previous default.

```tsx
// Before (v5)
<IconButton icon="camera" mode="contained" onPress={onPress} />
<IconButton icon="camera" mode="contained-tonal" onPress={onPress} />

// After (v6)
<IconButton icon="camera" mode="filled" onPress={onPress} />
<IconButton icon="camera" mode="tonal" onPress={onPress} />
```

#### Size

`size` is a named scale: `'extraSmall' | 'small' | 'medium' | 'large' | 'extraLarge'`. It defaults to `'small'`, which still uses a 24dp icon.

To set the glyph size in dp without changing the container scale, use `iconSize`.

```tsx
// Before (v5)
<IconButton icon="camera" size={24} onPress={onPress} />
<IconButton icon="camera" size={32} onPress={onPress} />

// After (v6)
<IconButton icon="camera" onPress={onPress} />
<IconButton icon="camera" iconSize={32} onPress={onPress} />
```

```tsx
// After (v6) — named container sizes
<IconButton icon="plus" size="extraSmall" onPress={onPress} />
<IconButton icon="plus" size="small" onPress={onPress} />
<IconButton icon="plus" size="medium" onPress={onPress} />
<IconButton icon="plus" size="large" onPress={onPress} />
<IconButton icon="plus" size="extraLarge" onPress={onPress} />
```

#### Shape

`style.borderRadius` no longer overrides the container corner. Use `shape`: `'round'` (default) or `'square'`. Toggle-ON inverts the resting shape; press uses a shared corner for both. Arbitrary radii from `style` are not supported.

```tsx
// Before (v5)
<IconButton icon="camera" style={{ borderRadius: 0 }} onPress={onPress} />

// After (v6)
<IconButton icon="camera" shape="square" onPress={onPress} />
```

#### `Appbar.Action` and `Appbar.BackAction`

`size` is no longer a numeric prop on `Appbar.Action` or `Appbar.BackAction`. They inherit `IconButton`'s named `size` (default `'small'`). Drop `size={24}`. For a custom glyph size, pass `iconSize`.

```tsx
// Before (v5)
<Appbar.Action icon="magnify" size={24} onPress={onPress} />
<Appbar.BackAction size={24} onPress={onPress} />

// After (v6)
<Appbar.Action icon="magnify" onPress={onPress} />
<Appbar.BackAction onPress={onPress} />
```

#### `selected={false}` uses toggle-off colors

`selected` is tri-state. Omit it for the default (non-toggle) colors. Pass `true` / `false` only for a toggle.

For `filled`, the default and toggle-on containers use `primary`. Toggle-off (`selected={false}`) uses `surfaceContainer` instead of `primary`.

```tsx
// Before (v5) — selected={false} still used the default (non-toggle) colors
<IconButton icon="star-outline" mode="contained" selected={false} onPress={onPress} />

// After (v6) — omit selected unless the button is a toggle
<IconButton icon="star-outline" mode="filled" onPress={onPress} />

// After (v6) — explicit toggle off / on
<IconButton
icon={isStarred ? 'star' : 'star-outline'}
mode="filled"
selected={isStarred}
onPress={toggleStarred}
/>
```

#### `Card.Title` `right` props

`Card.Title` still calls `right({ size: 24 })`. Do not spread those props onto `IconButton`: `size` is no longer a number. Ignore the callback argument, or pass it as `iconSize`.

```tsx
// Before (v5)
<Card.Title
title="Card title"
right={(props) => (
<IconButton {...props} icon="dots-vertical" onPress={onPress} />
)}
/>

// After (v6)
<Card.Title
title="Card title"
right={() => <IconButton icon="dots-vertical" onPress={onPress} />}
/>
```

```tsx
// After (v6) — keep the 24dp glyph from Card.Title
<Card.Title
title="Card title"
right={(props) => (
<IconButton
icon="dots-vertical"
iconSize={props.size}
onPress={onPress}
/>
)}
/>
```

### ToggleButton

`ToggleButton`, `ToggleButton.Group` and `ToggleButton.Row` were removed. For an
Expand Down
Binary file removed docs/public/screenshots/icon-button-1.png
Binary file not shown.
Binary file removed docs/public/screenshots/icon-button-2.png
Binary file not shown.
Binary file removed docs/public/screenshots/icon-button-3.png
Binary file not shown.
Binary file removed docs/public/screenshots/icon-button-4.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion docs/src/components/ScreenshotTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ const ScreenshotTabs = ({ screenshotData }: ScreenshotTabsProps) => {

const screenshots = Object.entries(screenshotData).map(([key, value]) => (
<TabItem key={key} value={key} label={key} default>
{typeof value === 'string' ? renderScreenshot(value) : null}
{typeof value === 'string' ? (
renderScreenshot(value)
) : (
<ScreenshotTabs screenshotData={value} />
)}
</TabItem>
));

Expand Down
20 changes: 16 additions & 4 deletions docs/src/data/screenshots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,22 @@ export const screenshots = {
'FAB.Group': 'screenshots/fab-group.gif',
Icon: 'screenshots/icon.png',
IconButton: {
default: 'screenshots/icon-button-1.png',
outlined: 'screenshots/icon-button-4.png',
contained: 'screenshots/icon-button-2.png',
'contained-tonal': 'screenshots/icon-button-3.png',
standard: {
Android: 'screenshots/icon-button-standard.android.png',
iOS: 'screenshots/icon-button-standard.ios.png',
},
filled: {
Android: 'screenshots/icon-button-filled.android.png',
iOS: 'screenshots/icon-button-filled.ios.png',
},
tonal: {
Android: 'screenshots/icon-button-tonal.android.png',
iOS: 'screenshots/icon-button-tonal.ios.png',
},
outlined: {
Android: 'screenshots/icon-button-outlined.android.png',
iOS: 'screenshots/icon-button-outlined.ios.png',
},
},
'List.Accordion': {
'with left icon': 'screenshots/list-accordion-1.png',
Expand Down
64 changes: 40 additions & 24 deletions docs/src/data/themeColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,56 +191,72 @@ export const themeColors = {
},
},
IconButton: {
default: {
standard: {
iconColor: 'theme.colors.onSurfaceVariant',
},
outlined: {
iconColor: 'theme.colors.onSurfaceVariant',
borderColor: 'theme.colors.outlineVariant',
},
filled: {
backgroundColor: 'theme.colors.primary',
iconColor: 'theme.colors.onPrimary',
},
tonal: {
backgroundColor: 'theme.colors.secondaryContainer',
iconColor: 'theme.colors.onSecondaryContainer',
},
},
selected: {
default: {
standard: {
iconColor: 'theme.colors.primary',
},
outlined: {
backgroundColor: 'theme.colors.inverseSurface',
iconColor: 'theme.colors.inverseOnSurface',
},
contained: {
filled: {
backgroundColor: 'theme.colors.primary',
iconColor: 'theme.colors.onPrimary',
},
'contained-tonal': {
backgroundColor: 'theme.colors.secondaryContainer',
iconColor: 'theme.colors.onSecondaryContainer',
tonal: {
backgroundColor: 'theme.colors.secondary',
iconColor: 'theme.colors.onSecondary',
},
},
unselected: {
default: {
standard: {
iconColor: 'theme.colors.onSurfaceVariant',
},
outlined: {
iconColor: 'theme.colors.onSurfaceVariant',
borderColor: 'theme.colors.outline',
},
contained: {
backgroundColor: 'theme.colors.surfaceVariant',
iconColor: 'theme.colors.primary',
borderColor: 'theme.colors.outlineVariant',
},
'contained-tonal': {
backgroundColor: 'theme.colors.surfaceVariant',
filled: {
backgroundColor: 'theme.colors.surfaceContainer',
iconColor: 'theme.colors.onSurfaceVariant',
},
tonal: {
backgroundColor: 'theme.colors.secondaryContainer',
iconColor: 'theme.colors.onSecondaryContainer',
},
},
disabled: {
default: {
iconColor: 'theme.colors.onSurfaceDisabled',
standard: {
iconColor: 'theme.colors.onSurface',
},
outlined: {
backgroundColor: 'theme.colors.surfaceDisabled',
iconColor: 'theme.colors.onSurfaceDisabled',
borderColor: 'theme.colors.surfaceDisabled',
iconColor: 'theme.colors.onSurface',
borderColor: 'theme.colors.outlineVariant',
},
contained: {
backgroundColor: 'theme.colors.surfaceDisabled',
iconColor: 'theme.colors.onSurfaceDisabled',
filled: {
backgroundColor: 'theme.colors.onSurface',
iconColor: 'theme.colors.onSurface',
},
'contained-tonal': {
backgroundColor: 'theme.colors.surfaceDisabled',
iconColor: 'theme.colors.onSurfaceDisabled',
tonal: {
backgroundColor: 'theme.colors.onSurface',
iconColor: 'theme.colors.onSurface',
},
},
},
Expand Down
12 changes: 8 additions & 4 deletions example/src/Examples/BadgeExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ const BadgeExample = () => {
<List.Section title="Text">
<View style={styles.row}>
<View style={styles.item}>
<IconButton icon="palette-swatch" size={36} style={styles.button} />
<IconButton
icon="palette-swatch"
size="medium"
style={styles.button}
/>
<Badge visible={visible} style={styles.textBadge}>
12
</Badge>
</View>
<View style={styles.item}>
<IconButton icon="inbox" size={36} style={styles.button} />
<IconButton icon="inbox" size="medium" style={styles.button} />
<Badge
visible={visible}
style={[
Expand All @@ -53,11 +57,11 @@ const BadgeExample = () => {
<List.Section title="Dot">
<View style={styles.row}>
<View style={styles.item}>
<IconButton icon="book-open" size={36} style={styles.button} />
<IconButton icon="book-open" size="medium" style={styles.button} />
<Badge visible={visible} style={styles.dotBadge} />
</View>
<View style={styles.item}>
<IconButton icon="receipt" size={36} style={styles.button} />
<IconButton icon="receipt" size="medium" style={styles.button} />
<Badge visible={visible} style={styles.dotBadge} />
</View>
</View>
Expand Down
8 changes: 3 additions & 5 deletions example/src/Examples/CardExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ const CardExample = () => {
title="Berries that are trimmed at the end"
subtitle="Omega Ruby"
left={(props: any) => <Avatar.Icon {...props} icon="folder" />}
right={(props: any) => (
<IconButton {...props} icon="dots-vertical" onPress={() => {}} />
)}
right={() => <IconButton icon="dots-vertical" onPress={() => {}} />}
/>
<Card.Content>
<Text variant="bodyMedium">
Expand Down Expand Up @@ -144,10 +142,10 @@ const CardExample = () => {
<Card.Title
title="Just Strawberries"
subtitle="... and only Strawberries"
right={(props: any) => (
right={() => (
<IconButton
{...props}
icon={isSelected ? 'heart' : 'heart-outline'}
selected={isSelected}
onPress={() => setIsSelected(!isSelected)}
/>
)}
Expand Down
Loading
Loading