Skip to content

Commit 68973a5

Browse files
Paweł Kataclaude
andcommitted
feat(appbar): squash-rebase onto latest main
Squash all appbar-improvements commits and replay them on top of latest main to avoid replaying 37 commits individually through main's unrelated history (notably the v2->v3 Appbar rewrite mid-branch, which produced large, non-semantic conflicts when rebased commit-by-commit). Also adapts the new Appbar/AppbarContent code to the testID conventions established by #5099 (remove derived test IDs for internal, implementation-only elements): drops the `${testID}-title-text`/`${testID}-headline-text`/`${testID}-subtitle-text` derived test IDs on non-interactive text, updating the corresponding tests to query by text content instead, and updates the migration guide's "Test IDs" section accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 84fdd8e commit 68973a5

32 files changed

Lines changed: 2359 additions & 3444 deletions

‎docs/6.x/docs/guides/migration.md‎

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ React Native Paper 6 uses [Reanimated](https://docs.swmansion.com/react-native-r
1010

1111
The following props now accept animated styles returned from `useAnimatedStyle`. They no longer accept `Animated.Value` or `Animated.AnimatedInterpolation` where these were previously supported:
1212

13-
- `Appbar.Action` and `Appbar.BackAction`: `style`
13+
- `Appbar`: `style`
1414
- `Badge`: `style`
1515
- `Banner`: `style`
1616
- `Button`: `style`
@@ -73,8 +73,7 @@ You can use the component's color prop where available, or override the correspo
7373

7474
Hardcoded default test IDs have been removed for the components listed below:
7575

76-
- `Appbar.Content`: `appbar-content`
77-
- `Appbar.Header`: `appbar-header`
76+
- `Appbar`: `${testID}-root-layer`
7877
- `BottomNavigation`: `bottom-navigation`
7978
- `BottomNavigation.Bar`: `bottom-navigation-bar`
8079
- `Button`: `button`
@@ -111,9 +110,52 @@ Some components now accept explicit `testID` props for their interactable elemen
111110

112111
### Appbar
113112

114-
The `style` props for `Appbar` and `Appbar.Header` no longer accept `Animated.Value` or `Animated.AnimatedInterpolation`. They only accept static styles.
113+
The Paper 6.x `Appbar` is a big refatctor, which drops the previously used compound component approach.
115114

116-
The `style.elevation` property is no longer supported. Use the `elevated` prop to control Appbar elevation.
115+
#### Migrating from the compound API
116+
117+
`Appbar.Header`, `Appbar.Content`, `Appbar.Action`, and `Appbar.BackAction` have been removed. Render one `Appbar` and provide its headline, leading button, and trailing actions as props. The former `mode="medium"` and `mode="large"` values are now `variant="medium-flexible"` and `variant="large-flexible"`; centered content uses `headlineAlignment="center"`.
118+
119+
```tsx
120+
// Before (v5)
121+
122+
const MyComponent = () => (
123+
<Appbar.Header>
124+
<Appbar.BackAction onPress={() => {}} />
125+
<Appbar.Content title="Inbox" />
126+
<Appbar.Action icon="search" onPress={() => {}} />
127+
<Appbar.Action icon="dots-vertical" onPress={() => {}} />
128+
</Appbar.Header>
129+
);
130+
131+
// After (v6)
132+
133+
const MyComponent = () => (
134+
<Appbar
135+
variant="small"
136+
headline="Inbox"
137+
leadingButton={{ type: 'back', onPress: () => {} }}
138+
trailingActions={[
139+
{
140+
key: 'search',
141+
icon: 'magnify',
142+
'aria-label': 'Search',
143+
onPress: () => {},
144+
},
145+
{
146+
key: 'more',
147+
icon: 'dots-vertical',
148+
'aria-label': 'More options',
149+
onPress: () => {},
150+
},
151+
]}
152+
/>
153+
);
154+
```
155+
156+
#### Bottom toolbar support
157+
158+
Material Design 3 drops the bottom bar support contained previously in the `Appbar` scope and moves it to `Toolbars`, hence you can't use the component to construct a bottom bar anymore - for these cases please use the `Toolbar` component.
117159

118160
### Surface
119161

‎docs/6.x/docs/guides/react-navigation.md‎

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,7 @@ Now we will implement `CustomNavigationBar` using `AppBar` component:
136136
import { Appbar } from 'react-native-paper';
137137

138138
export default function CustomNavigationBar() {
139-
return (
140-
<Appbar.Header>
141-
<Appbar.Content title="My awesome app" />
142-
</Appbar.Header>
143-
);
139+
return <Appbar variant="small" headline="My awesome app" />;
144140
}
145141
```
146142

@@ -154,11 +150,7 @@ import { getHeaderTitle } from '@react-navigation/elements';
154150
export default function CustomNavigationBar({ route, options }) {
155151
const title = getHeaderTitle(options, route.name);
156152

157-
return (
158-
<Appbar.Header>
159-
<Appbar.Content title={title} />
160-
</Appbar.Header>
161-
);
153+
return <Appbar variant="small" headline={title} />;
162154
}
163155
```
164156

@@ -179,10 +171,13 @@ export default function CustomNavigationBar({
179171
const title = getHeaderTitle(options, route.name);
180172

181173
return (
182-
<Appbar.Header>
183-
{back ? <Appbar.BackAction onPress={navigation.goBack} /> : null}
184-
<Appbar.Content title={title} />
185-
</Appbar.Header>
174+
<Appbar
175+
variant="small"
176+
headline={title}
177+
leadingButton={
178+
back ? { type: 'back', onPress: navigation.goBack } : undefined
179+
}
180+
/>
186181
);
187182
}
188183
```
@@ -194,8 +189,8 @@ export default function CustomNavigationBar({
194189
Another interesting pattern that can be implemented with `react-native-paper` and `react-navigation` is a "menu" button. Thanks to the `Menu` component we can add a nice looking pop-up to our `Appbar`. To implement this feature we need to make a couple of changes in `CustomNavigationBar`:
195190

196191
- Render a `Menu` component
197-
- Pass `Appbar.Action` to the anchor prop
198-
- Add a state to control `Menu` visibility
192+
- Add a trailing action to `Appbar`
193+
- Store the action coordinates and menu visibility in state
199194

200195
:::note
201196
To have properly working `Menu` component, remember to wrap your root component with the `PaperProvider`:
@@ -236,21 +231,41 @@ export default function CustomNavigationBar({
236231
back,
237232
}) {
238233
const [visible, setVisible] = React.useState(false);
234+
const [menuAnchor, setMenuAnchor] = React.useState({ x: 0, y: 0 });
239235
const openMenu = () => setVisible(true);
240236
const closeMenu = () => setVisible(false);
241237

242238
const title = getHeaderTitle(options, route.name);
243239

244240
return (
245-
<Appbar.Header>
246-
{back ? <Appbar.BackAction onPress={navigation.goBack} /> : null}
247-
<Appbar.Content title={title} />
241+
<>
242+
<Appbar
243+
variant="small"
244+
headline={title}
245+
leadingButton={
246+
back ? { type: 'back', onPress: navigation.goBack } : undefined
247+
}
248+
trailingActions={
249+
back
250+
? []
251+
: [
252+
{
253+
key: 'more',
254+
icon: 'dots-vertical',
255+
'aria-label': 'More options',
256+
onPress: (event) => {
257+
setMenuAnchor({
258+
x: event.nativeEvent.pageX,
259+
y: event.nativeEvent.pageY,
260+
});
261+
openMenu();
262+
},
263+
},
264+
]
265+
}
266+
/>
248267
{!back ? (
249-
<Menu
250-
visible={visible}
251-
onDismiss={closeMenu}
252-
anchor={<Appbar.Action icon="dots-vertical" onPress={openMenu} />}
253-
>
268+
<Menu visible={visible} onDismiss={closeMenu} anchor={menuAnchor}>
254269
<Menu.Item
255270
onPress={() => {
256271
console.log('Option 1 was pressed');
@@ -272,7 +287,7 @@ export default function CustomNavigationBar({
272287
/>
273288
</Menu>
274289
) : null}
275-
</Appbar.Header>
290+
</>
276291
);
277292
}
278293
```

‎docs/6.x/docs/guides/theming-with-react-navigation.md‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,24 +249,25 @@ Now that the Context is available at every component, all we need to do is impor
249249
250250
```js
251251
import React from 'react';
252-
import { useTheme, Appbar, TouchableRipple, Switch } from 'react-native-paper';
252+
import { Appbar } from 'react-native-paper';
253253
import { PreferencesContext } from './PreferencesContext';
254254

255255
const Header = ({ scene }) => {
256-
const theme = useTheme();
257256
const { toggleTheme, isThemeDark } = React.useContext(PreferencesContext);
258257

259258
return (
260-
<Appbar.Header
261-
theme={{
262-
colors: {
263-
primary: theme?.colors.surface,
259+
<Appbar
260+
variant="small"
261+
headline={scene.route?.name}
262+
trailingActions={[
263+
{
264+
key: 'theme',
265+
icon: isThemeDark ? 'weather-sunny' : 'weather-night',
266+
'aria-label': 'Toggle color theme',
267+
onPress: toggleTheme,
264268
},
265-
}}
266-
>
267-
<Appbar.Content title={scene.route?.name} />
268-
<Switch color={'red'} value={isThemeDark} onValueChange={toggleTheme} />
269-
</Appbar.Header>
269+
]}
270+
/>
270271
);
271272
};
272273
```

‎docs/6.x/docs/guides/theming.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,14 @@ Now you can use your `FancyButton` component everywhere instead of using `Button
503503
## Dark Theme
504504

505505
Since 3.0 we adapt dark theme to follow [Material design guidelines](https://material.io/design/color/dark-theme.html). <br/>
506-
In contrast to light theme, dark theme by default uses `surface` colour instead of `primary` on large components like `AppBar` or `BottomNavigation`.<br/>
506+
In contrast to light theme, dark theme by default uses `surface` colour instead of `primary` on large components like `BottomNavigation`.<br/>
507507
The dark theme adds a white overlay with opacity depending on elevation of surfaces. It uses it for the better accentuation of surface elevation. Using only shadow is highly imperceptible on dark surfaces.
508508

509509
We are aware that users often use dark theme in their own ways and may not want to use the default dark theme features from the guidelines.<br/>
510510
That's why if you are using dark theme you can switch between two dark theme `mode`s:
511511

512-
- `exact` where everything is like it was before. `Appbar` and `BottomNavigation` will still use primary colour by default.<br/>
513-
- `adaptive` where we follow [Material design guidelines](https://material.io/design/color/dark-theme.html), the surface will use white overlay with opacity to show elevation, `Appbar` and `BottomNavigation` will use surface colour as a background.
512+
- `exact` where everything is like it was before. `BottomNavigation` will still use primary colour by default.<br/>
513+
- `adaptive` where we follow [Material design guidelines](https://material.io/design/color/dark-theme.html), the surface will use white overlay with opacity to show elevation, and `BottomNavigation` will use surface colour as a background.
514514

515515
If you don't use a custom theme, Paper will automatically change between the default theme and the default dark theme, depending on device settings.
516516

‎docs/component-docs.config.ts‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ export type Pages = Record<string, Page | Record<string, Page>>;
2121
type ComponentDocsConfig = {
2222
sourceRootDir: string;
2323
pages: Pages;
24+
typescriptProps: Record<
25+
string,
26+
{
27+
sourcePath: string;
28+
typeName: string;
29+
}
30+
>;
2431
customFields: {
2532
moreExamples: Record<string, Record<string, string>>;
2633
knownIssues: Record<string, Record<string, string>>;
@@ -32,13 +39,7 @@ type ComponentDocsConfig = {
3239

3340
const pages = {
3441
ActivityIndicator: 'ActivityIndicator',
35-
Appbar: {
36-
Appbar: 'Appbar/Appbar',
37-
AppbarAction: 'Appbar/AppbarAction',
38-
AppbarBackAction: 'Appbar/AppbarBackAction',
39-
AppbarContent: 'Appbar/AppbarContent',
40-
AppbarHeader: 'Appbar/AppbarHeader',
41-
},
42+
Appbar: 'Appbar/Appbar',
4243
Avatar: {
4344
AvatarIcon: 'Avatar/AvatarIcon',
4445
AvatarImage: 'Avatar/AvatarImage',
@@ -171,6 +172,19 @@ const pages = {
171172
const componentDocsConfig: ComponentDocsConfig = {
172173
sourceRootDir: path.join(__dirname, '..', 'src', 'components'),
173174
pages,
175+
typescriptProps: {
176+
'Appbar/Appbar': {
177+
sourcePath: path.join(
178+
__dirname,
179+
'..',
180+
'src',
181+
'components',
182+
'Appbar',
183+
'types.ts'
184+
),
185+
typeName: 'Props',
186+
},
187+
},
174188
customFields: {
175189
moreExamples: {
176190
Portal: {
90.1 KB
Loading
84.2 KB
Loading
70.9 KB
Loading
81.1 KB
Loading

‎docs/src/data/screenshots.ts‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
export const screenshots = {
22
ActivityIndicator: 'screenshots/activity-indicator.gif',
3-
Appbar: 'screenshots/appbar.png',
4-
'Appbar.Action': 'screenshots/appbar-action-android.png',
5-
'Appbar.BackAction': 'screenshots/appbar-backaction-android.png',
6-
'Appbar.Content': 'screenshots/appbar-content.png',
7-
'Appbar.Header': {
8-
small: 'screenshots/appbar-small.png',
9-
medium: 'screenshots/appbar-medium.png',
10-
large: 'screenshots/appbar-large.png',
11-
'center-aligned': 'screenshots/appbar-center-aligned.png',
12-
},
133
'Avatar.Icon': 'screenshots/avatar-icon.png',
144
'Avatar.Image': 'screenshots/avatar-image.png',
155
'Avatar.Text': 'screenshots/avatar-text.png',
6+
Appbar: {
7+
search: 'screenshots/appbar-v6-search.png',
8+
small: 'screenshots/appbar-v6-small.png',
9+
'medium flexible': 'screenshots/appbar-v6-medium-flexible.png',
10+
'large flexible': 'screenshots/appbar-v6-large-flexible.png',
11+
},
1612
Badge: {
1713
'with text': 'screenshots/badge-1.png',
1814
'without text': 'screenshots/badge-2.png',

0 commit comments

Comments
 (0)