Skip to content

Commit 6df29bd

Browse files
committed
Update tab view docs
1 parent 2df1134 commit 6df29bd

11 files changed

Lines changed: 329 additions & 31 deletions

File tree

-103 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

versioned_docs/version-8.x/drawer-layout.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@ title: React Native Drawer Layout
44
sidebar_label: Drawer Layout
55
---
66

7-
A cross-platform Drawer component for React Native implemented using [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) on native platforms and CSS transitions on Web.
7+
<div className="feature-grid">
8+
9+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/drawer/highlights/drawer-types.mp4" /></video>
10+
11+
[Multiple types](#drawertype)
12+
13+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/drawer/highlights/drawer-position.mp4" /></video>
814

9-
<video playsInline autoPlay muted loop>
10-
<source src="/assets/libraries/drawer-layout/drawer-layout.mp4" />
11-
</video>
15+
[Position on left or right](#drawerposition)
16+
17+
</div>
18+
19+
A cross-platform Drawer component for React Native implemented using [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) on native platforms and CSS transitions on Web.
1220

1321
If you need React Navigation integration, e.g. show screens in the drawer and be able to navigate between them using `navigation.navigate` etc, use [Drawer Navigator](drawer-navigator.md) instead.
1422

versioned_docs/version-8.x/material-top-tab-navigator.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ sidebar_label: Material Top Tabs
66

77
<div className="feature-grid">
88

9-
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/scrollable-tabbar.mp4" /></video>
9+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/primary-tabbar.mp4" /></video>
1010

11-
[Scrollable tab bar](#tabbarscrollenabled)
11+
[Primary](#tabbarvariant)
1212

13-
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/badge.mp4" /></video>
13+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/secondary-tabbar.mp4" /></video>
1414

15-
[Badges](#tabbarbadge)
15+
[Secondary](#tabbarvariant)
1616

17-
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/custom-indicator.mp4" /></video>
17+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/tab-icon.mp4" /></video>
1818

19-
[Custom indicator](#tabbarindicator)
19+
[Icons](#tabbaricon)
2020

21-
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/custom-tabbar.mp4" /></video>
21+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/scrollable-tabbar.mp4" /></video>
2222

23-
[Custom tab bar](#tabbar)
23+
[Scrollable tabs](#tabbarscrollenabled)
2424

2525
</div>
2626

@@ -528,21 +528,32 @@ Whether the tab icon should be visible. Defaults to `false`.
528528

529529
Function that returns a React element to use as a badge for the tab.
530530

531+
#### `tabBarVariant`
532+
533+
Variant of the tab bar. Supported values are:
534+
535+
- `'primary'` (default): the indicator matches the label & icon width and is centered under the tab, active color defaults to the theme's primary color.
536+
- `'secondary'`: the indicator spans the full tab width, active color defaults to the theme's text color.
537+
531538
#### `tabBarIndicator`
532539

533-
Function that returns a React element as the tab bar indicator.
540+
Function that returns a React element as the tab bar indicator. It receives the same props that you'd pass to [`TabBarIndicator`](tab-view.md#tabbarindicator) from `react-native-tab-view`.
534541

535542
#### `tabBarIndicatorStyle`
536543

537544
Style object for the tab bar indicator.
538545

539-
The indicator takes the same width as the tab item by default. It can be customized in a few ways:
546+
The default width of the indicator depends on [`tabBarVariant`](#tabbarvariant):
547+
548+
- With `tabBarVariant: 'primary'` (default), the indicator matches the width of the tab's label & icon and is centered under the tab.
549+
- With `tabBarVariant: 'secondary'`, the indicator spans the full tab width.
540550

541-
- To make it smaller by a certain amount, you can add a horizontal margin, e.g. `{ marginHorizontal: 10 }`.
542-
- Adding specific width will position the indicator at the left of the tab, e.g. `{ width: 20 }`.
543-
- To center it in the tab when a custom width is specified, you can specify `margin` as `'auto'`, e.g. `{ width: 20, marginHorizontal: 'auto' }`.
551+
You can customize the indicator in a few ways:
544552

545-
When the `tabStyle` has `width: 'auto'` and no explicit `width` is specified for the indicator, it is scaled to the width with `transform: [{ scaleX }]` for smooth animations. So specifying a `borderRadius` won't work as expected.
553+
- To shrink it by a fixed amount, add a horizontal margin, e.g. `{ marginHorizontal: 10 }`.
554+
- To give it a specific width, set `width`, e.g. `{ width: 20 }`. By default this aligns the indicator to the start.
555+
- To center a custom-width indicator inside the tab, set `margin` to `'auto'`, e.g. `{ width: 20, marginHorizontal: 'auto' }`.
556+
- To make the corners rounded, pass `borderRadius`,`borderTopLeftRadius`, or `borderTopRightRadius` etc. as a number, e.g. `{ borderRadius: 10 }`.
546557

547558
If you need more control, you can use [`tabBarIndicator`](#tabbarindicator) to render a custom indicator instead.
548559

@@ -578,7 +589,7 @@ Boolean indicating whether the tab bar bounces when overscrolling.
578589

579590
Boolean indicating whether to make the tab bar scrollable.
580591

581-
If you set this to `true`, you should also specify a width in `tabBarItemStyle` to improve the performance of initial render.
592+
When this is set to `true`, each tab is sized to fit its content by default. To use a fixed width instead, set `width` in `tabBarItemStyle`.
582593

583594
#### `tabBarLabelStyle`
584595

versioned_docs/version-8.x/tab-view.md

Lines changed: 136 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,30 @@ title: React Native Tab View
44
sidebar_label: Tab View
55
---
66

7+
<div className="feature-grid">
8+
9+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/primary-tabbar.mp4" /></video>
10+
11+
[Primary](#variant)
12+
13+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/secondary-tabbar.mp4" /></video>
14+
15+
[Secondary](#variant)
16+
17+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/tab-icon.mp4" /></video>
18+
19+
[Icons](#icon)
20+
21+
- <video playsInline autoPlay muted loop><source src="/assets/navigators/material-top-tabs/highlights/scrollable-tabbar.mp4" /></video>
22+
23+
[Scrollable tabs](#scrollenabled)
24+
25+
</div>
26+
727
React Native Tab View is a cross-platform Tab View component for React Native implemented using [`react-native-pager-view`](https://github.com/callstack/react-native-viewpager) on Android & iOS, and [PanResponder](https://reactnative.dev/docs/panresponder) on Web, macOS, and Windows.
828

929
It follows material design guidelines by default, but you can also use your own custom tab bar or position the tab bar at the bottom.
1030

11-
<video playsInline autoPlay muted loop>
12-
<source src="/assets/libraries/tab-view/tab-view.mp4" />
13-
</video>
14-
1531
If you need React Navigation integration, e.g. show screens in the tab bar and be able to navigate between them using `navigation.navigate` etc, use [Material Top Tab Navigator](material-top-tab-navigator.md) instead.
1632

1733
## Installation
@@ -596,13 +612,38 @@ return (
596612

597613
#### TabBar Props
598614

615+
##### `variant`
616+
617+
Variant of the tab bar. Supported values are:
618+
619+
- `'primary'` (default): the indicator matches the label & icon width and is centered under the tab, active color defaults to the theme's primary color.
620+
- `'secondary'`: the indicator spans the full tab width, active color defaults to the theme's text color.
621+
599622
##### `renderTabBarItem`
600623

601-
Function which takes a `TabBarItemProps` object and returns a custom React Element to be used as a tab button.
624+
Function that returns a custom React Element to be used as a tab button. By default, it uses [`TabBarItem`](#tabbaritem):
625+
626+
```js
627+
<TabBar
628+
renderTabBarItem={(props) => <TabBarItem {...props} style={myStyle} />}
629+
...
630+
/>
631+
```
632+
633+
See [`TabBarItem`](#tabbaritem) for the full list of props.
602634

603635
##### `renderIndicator`
604636

605-
Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
637+
Function that returns a custom React Element to be used as a tab indicator. By default, it uses [`TabBarIndicator`](#tabbarindicator):
638+
639+
```js
640+
<TabBar
641+
renderIndicator={(props) => <TabBarIndicator {...props} style={myStyle} />}
642+
...
643+
/>
644+
```
645+
646+
See [`TabBarIndicator`](#tabbarindicator) for the full list of props.
606647

607648
##### `onTabPress`
608649

@@ -647,7 +688,7 @@ Opacity for pressed tab (iOS and Android < 5.0 only).
647688

648689
Boolean indicating whether to make the tab bar scrollable.
649690

650-
If you set `scrollEnabled` to `true`, you should also specify a `width` in `tabStyle` to improve the initial render.
691+
When `scrollEnabled` is `true`, each tab is sized to fit its content by default. To use a fixed width instead, set `width` in `tabStyle`.
651692

652693
##### `bounces`
653694

@@ -663,13 +704,17 @@ By default, all tab items take up the same pre-calculated width based on the wid
663704

664705
Style to apply to the active indicator.
665706

666-
The indicator takes the same width as the tab item by default. It can be customized in a few ways:
707+
The default width of the indicator depends on the [`variant`](#variant):
667708

668-
- To make it smaller by a certain amount, you can add a horizontal margin, e.g. `{ marginHorizontal: 10 }`.
669-
- Adding specific width will position the indicator at the left of the tab, e.g. `{ width: 20 }`.
670-
- To center it in the tab when a custom width is specified, you can specify `margin` as `'auto'`, e.g. `{ width: 20, marginHorizontal: 'auto' }`.
709+
- With `variant="primary"` (default), the indicator matches the width of the tab's label & icon and is centered under the tab.
710+
- With `variant="secondary"`, the indicator spans the full tab width.
671711

672-
When the `tabStyle` has `width: 'auto'` and no explicit `width` is specified for the indicator, it is scaled to the width with `transform: [{ scaleX }]` for smooth animations. So specifying a `borderRadius` won't work as expected.
712+
You can customize the indicator in a few ways:
713+
714+
- To shrink it by a fixed amount, add a horizontal margin, e.g. `{ marginHorizontal: 10 }`.
715+
- To give it a specific width, set `width`, e.g. `{ width: 20 }`. By default this aligns the indicator to the start.
716+
- To center a custom-width indicator inside the tab, set `margin` to `'auto'`, e.g. `{ width: 20, marginHorizontal: 'auto' }`.
717+
- To make the corners rounded, pass `borderRadius`,`borderTopLeftRadius`, or `borderTopRightRadius` etc. as a number, e.g. `{ borderRadius: 10 }`.
673718

674719
If you need more control, you can use [`renderIndicator`](#renderindicator) to render a custom indicator instead.
675720

@@ -800,6 +845,85 @@ badge: ({ route }) => (
800845
801846
Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping.
802847
848+
### `TabBarIndicator`
849+
850+
The default indicator component used by `TabBar`. It accepts the following props:
851+
852+
- `variant` - Variant of the indicator. Same values as [`TabBar`'s `variant`](#variant). Determines the default size and position behavior:
853+
- `'primary'` (default): the indicator matches the label & icon width and is centered under the tab.
854+
- `'secondary'`: the indicator spans the full tab width.
855+
- `navigationState` - Same as [`TabView`'s `navigationState`](#navigationstate-required).
856+
- `widths` - Array of indicator widths in pixels, one entry per route in the same order as `navigationState.routes`. These are the widths computed by `TabBar` based on the current `variant`, `indicatorStyle`, and measured tab/label widths.
857+
- `offsets` - Array of indicator x offsets in pixels (absolute position within the tab bar), one entry per route in the same order as `navigationState.routes`. These already account for `gap`, padding, and any centering implied by `variant` or `marginHorizontal: 'auto'`.
858+
- `position` - Animated value that represents the current position. Goes from `0` to `routes.length - 1` based on the swipe progress. Use this together with `widths` and `offsets` to interpolate the indicator's translation between tabs.
859+
- `direction` - Layout direction of the tab bar. Either `'ltr'` or `'rtl'`.
860+
- `jumpTo` - Function to jump to another tab, takes a `route.key` as its argument.
861+
- `style` - Style to apply to the indicator. See [`indicatorStyle`](#indicatorstyle) for the full list of supported style customizations.
862+
863+
Internally, the indicator is rendered as multiple pieces to be able to support `borderRadius`, `borderTopLeftRadius`, or `borderTopRightRadius` etc. while still using `scale` transforms for animation. So it may not work with all style values properly as if it was a single view.
864+
865+
### `TabBarItem`
866+
867+
The default tab button component used by `TabBar`. It accepts the following props:
868+
869+
- `variant` - Variant of the tab. Same values as [`TabBar`'s `variant`](#variant). Determines the default active color.
870+
- `route` - The route object for this tab.
871+
- `navigationState` - Same as [`TabView`'s `navigationState`](#navigationstate-required).
872+
- `position` - Animated value that represents the current position, used to interpolate the active/inactive label opacity.
873+
- `activeColor` - Custom color for icon and label when the tab is active.
874+
- `inactiveColor` - Custom color for icon and label when the tab is inactive.
875+
- `pressColor` - Color for the material ripple (Android >= 5.0 only).
876+
- `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
877+
- `onPress` - Callback to invoke when the tab is pressed. The default `renderTabBarItem` wires this up to switch tabs.
878+
- `onLongPress` - Callback to invoke when the tab is long-pressed.
879+
- `onMeasureLayout` - Callback that receives the measured layout of the tab as `{ width, height }`. `TabBar` uses this to compute tab widths and indicator offsets when tabs are sized to their content (e.g. scrollable tab bars or `tabStyle: { width: 'auto' }`).
880+
- `onMeasureLabelLayout` - Callback that receives the measured layout of the label + icon as `{ width, height }`. `TabBar` uses this to size the indicator under the label for the `'primary'` variant.
881+
- `android_ripple` - Allows you to customize the Android ripple effect on tab press. See [`PressableAndroidRippleConfig`](https://reactnative.dev/docs/pressable#rippleconfig).
882+
- `style` - Style to apply to the tab container. Forwarded from `TabBar`'s `tabStyle`.
883+
884+
In addition to these, `TabBarItem` accepts all the [tab options](#options) (`label`, `labelText`, `labelStyle`, `icon`, `badge`, `href`, `accessibilityLabel`, `accessible`, `testID`, etc.).
885+
886+
If you render your own tab bar item via [`renderTabBarItem`](#rendertabbaritem) instead of using `TabBarItem`, you need to call `onMeasureLayout` and `onMeasureLabelLayout` for the indicator to work:
887+
888+
```tsx
889+
const containerRef = useRef<View>(null);
890+
const labelRef = useRef<View>(null);
891+
892+
useLayoutEffect(() => {
893+
containerRef.current?.measure((x, y, width, height) => {
894+
onMeasureLayout({ width, height });
895+
});
896+
897+
labelRef.current?.measure((x, y, width, height) => {
898+
onMeasureLabelLayout({ width, height });
899+
});
900+
}, [onMeasureLayout, onMeasureLabelLayout]);
901+
902+
return (
903+
<View
904+
ref={containerRef}
905+
onLayout={(event) => {
906+
const { width, height } = event.nativeEvent.layout;
907+
908+
onMeasureLayout({ width, height });
909+
}}
910+
>
911+
<View
912+
ref={labelRef}
913+
onLayout={(event) => {
914+
const { width, height } = event.nativeEvent.layout;
915+
916+
onMeasureLabelLayout({ width, height });
917+
}}
918+
>
919+
{/* ... */}
920+
</View>
921+
</View>
922+
);
923+
```
924+
925+
The measurement in `useLayoutEffect` is not required, but it provides the layout before paint, so the indicator can be rendered as early as possible.
926+
803927
## Optimization Tips
804928
805929
### Avoid unnecessary re-renders

0 commit comments

Comments
 (0)