UNPKG

13.6 kBTypeScriptView Raw
1import * as React from 'react';
2import { Animated, ColorValue, EasingFunction, StyleProp, ViewStyle } from 'react-native';
3import type { ThemeProp } from '../../types';
4import type { IconSource } from '../Icon';
5import { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple';
6export type BaseRoute = {
7 key: string;
8 title?: string;
9 focusedIcon?: IconSource;
10 unfocusedIcon?: IconSource;
11 badge?: string | number | boolean;
12 /**
13 * @deprecated In v5.x works only with theme version 2.
14 */
15 color?: string;
16 accessibilityLabel?: string;
17 testID?: string;
18 lazy?: boolean;
19};
20type NavigationState<Route extends BaseRoute> = {
21 index: number;
22 routes: Route[];
23};
24type TabPressEvent = {
25 defaultPrevented: boolean;
26 preventDefault(): void;
27};
28type TouchableProps<Route extends BaseRoute> = TouchableRippleProps & {
29 key: string;
30 route: Route;
31 children: React.ReactNode;
32 borderless?: boolean;
33 centered?: boolean;
34 rippleColor?: ColorValue;
35};
36export type Props<Route extends BaseRoute> = {
37 /**
38 * Whether the shifting style is used, the active tab icon shifts up to show the label and the inactive tabs won't have a label.
39 *
40 * By default, this is `false` with theme version 3 and `true` when you have more than 3 tabs.
41 * Pass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation.
42 * Note that you need at least 2 tabs be able to run this animation.
43 */
44 shifting?: boolean;
45 /**
46 * Whether to show labels in tabs. When `false`, only icons will be displayed.
47 */
48 labeled?: boolean;
49 /**
50 * Whether tabs should be spread across the entire width.
51 */
52 compact?: boolean;
53 /**
54 * State for the bottom navigation. The state should contain the following properties:
55 *
56 * - `index`: a number representing the index of the active route in the `routes` array
57 * - `routes`: an array containing a list of route objects used for rendering the tabs
58 *
59 * Each route object should contain the following properties:
60 *
61 * - `key`: a unique key to identify the route (required)
62 * - `title`: title of the route to use as the tab label
63 * - `focusedIcon`: icon to use as the focused tab icon, can be a string, an image source or a react component @renamed Renamed from 'icon' to 'focusedIcon' in v5.x
64 * - `unfocusedIcon`: icon to use as the unfocused tab icon, can be a string, an image source or a react component @supported Available in v5.x with theme version 3
65 * - `color`: color to use as background color for shifting bottom navigation @deprecatedProperty In v5.x works only with theme version 2.
66 * - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text.
67 * - `accessibilityLabel`: accessibility label for the tab button
68 * - `testID`: test id for the tab button
69 *
70 * Example:
71 *
72 * ```js
73 * {
74 * index: 1,
75 * routes: [
76 * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},
77 * { key: 'albums', title: 'Albums', focusedIcon: 'album' },
78 * { key: 'recents', title: 'Recents', focusedIcon: 'history' },
79 * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },
80 * ]
81 * }
82 * ```
83 *
84 * `BottomNavigation` is a controlled component, which means the `index` needs to be updated via the `onIndexChange` callback.
85 */
86 navigationState: NavigationState<Route>;
87 /**
88 * Callback which is called on tab change, receives the index of the new tab as argument.
89 * The navigation state needs to be updated when it's called, otherwise the change is dropped.
90 */
91 onIndexChange: (index: number) => void;
92 /**
93 * Callback which returns a react element to render as the page for the tab. Receives an object containing the route as the argument:
94 *
95 * ```js
96 * renderScene = ({ route, jumpTo }) => {
97 * switch (route.key) {
98 * case 'music':
99 * return <MusicRoute jumpTo={jumpTo} />;
100 * case 'albums':
101 * return <AlbumsRoute jumpTo={jumpTo} />;
102 * }
103 * }
104 * ```
105 *
106 * Pages are lazily rendered, which means that a page will be rendered the first time you navigate to it.
107 * After initial render, all the pages stay rendered to preserve their state.
108 *
109 * You need to make sure that your individual routes implement a `shouldComponentUpdate` to improve the performance.
110 * To make it easier to specify the components, you can use the `SceneMap` helper:
111 *
112 * ```js
113 * renderScene = BottomNavigation.SceneMap({
114 * music: MusicRoute,
115 * albums: AlbumsRoute,
116 * });
117 * ```
118 *
119 * Specifying the components this way is easier and takes care of implementing a `shouldComponentUpdate` method.
120 * Each component will receive the current route and a `jumpTo` method as it's props.
121 * The `jumpTo` method can be used to navigate to other tabs programmatically:
122 *
123 * ```js
124 * this.props.jumpTo('albums')
125 * ```
126 */
127 renderScene: (props: {
128 route: Route;
129 jumpTo: (key: string) => void;
130 }) => React.ReactNode | null;
131 /**
132 * Callback which returns a React Element to be used as tab icon.
133 */
134 renderIcon?: (props: {
135 route: Route;
136 focused: boolean;
137 color: string;
138 }) => React.ReactNode;
139 /**
140 * Callback which React Element to be used as tab label.
141 */
142 renderLabel?: (props: {
143 route: Route;
144 focused: boolean;
145 color: string;
146 }) => React.ReactNode;
147 /**
148 * Callback which returns a React element to be used as the touchable for the tab item.
149 * Renders a `TouchableRipple` on Android and `Pressable` on iOS.
150 */
151 renderTouchable?: (props: TouchableProps<Route>) => React.ReactNode;
152 /**
153 * Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab.
154 * Uses `route.accessibilityLabel` by default.
155 */
156 getAccessibilityLabel?: (props: {
157 route: Route;
158 }) => string | undefined;
159 /**
160 * Get badge for the tab, uses `route.badge` by default.
161 */
162 getBadge?: (props: {
163 route: Route;
164 }) => boolean | number | string | undefined;
165 /**
166 * Get color for the tab, uses `route.color` by default.
167 */
168 getColor?: (props: {
169 route: Route;
170 }) => string | undefined;
171 /**
172 * Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component.
173 */
174 getLabelText?: (props: {
175 route: Route;
176 }) => string | undefined;
177 /**
178 * Get lazy for the current screen. Uses true by default.
179 */
180 getLazy?: (props: {
181 route: Route;
182 }) => boolean | undefined;
183 /**
184 * Get the id to locate this tab button in tests, uses `route.testID` by default.
185 */
186 getTestID?: (props: {
187 route: Route;
188 }) => string | undefined;
189 /**
190 * Function to execute on tab press. It receives the route for the pressed tab, useful for things like scroll to top.
191 */
192 onTabPress?: (props: {
193 route: Route;
194 } & TabPressEvent) => void;
195 /**
196 * Function to execute on tab long press. It receives the route for the pressed tab, useful for things like custom action when longed pressed.
197 */
198 onTabLongPress?: (props: {
199 route: Route;
200 } & TabPressEvent) => void;
201 /**
202 * Custom color for icon and label in the active tab.
203 */
204 activeColor?: string;
205 /**
206 * Custom color for icon and label in the inactive tab.
207 */
208 inactiveColor?: string;
209 /**
210 * Whether animation is enabled for scenes transitions in `shifting` mode.
211 * By default, the scenes cross-fade during tab change when `shifting` is enabled.
212 * Specify `sceneAnimationEnabled` as `false` to disable the animation.
213 */
214 sceneAnimationEnabled?: boolean;
215 /**
216 * The scene animation effect. Specify `'shifting'` for a different effect.
217 * By default, 'opacity' will be used.
218 */
219 sceneAnimationType?: 'opacity' | 'shifting';
220 /**
221 * The scene animation Easing.
222 */
223 sceneAnimationEasing?: EasingFunction | undefined;
224 /**
225 * Whether the bottom navigation bar is hidden when keyboard is shown.
226 * On Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`.
227 */
228 keyboardHidesNavigationBar?: boolean;
229 /**
230 * Safe area insets for the tab bar. This can be used to avoid elements like the navigation bar on Android and bottom safe area on iOS.
231 * The bottom insets for iOS is added by default. You can override the behavior with this option.
232 */
233 safeAreaInsets?: {
234 top?: number;
235 right?: number;
236 bottom?: number;
237 left?: number;
238 };
239 /**
240 * Style for the bottom navigation bar. You can pass a custom background color here:
241 *
242 * ```js
243 * barStyle={{ backgroundColor: '#694fad' }}
244 * ```
245 */
246 barStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
247 /**
248 * Specifies the largest possible scale a label font can reach.
249 */
250 labelMaxFontSizeMultiplier?: number;
251 style?: StyleProp<ViewStyle>;
252 activeIndicatorStyle?: StyleProp<ViewStyle>;
253 /**
254 * @optional
255 */
256 theme?: ThemeProp;
257 /**
258 * TestID used for testing purposes
259 */
260 testID?: string;
261};
262/**
263 * BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.
264 * It is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar).
265 *
266 * By default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.
267 * See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.
268 *
269 * ## Usage
270 * ```js
271 * import * as React from 'react';
272 * import { BottomNavigation, Text } from 'react-native-paper';
273 *
274 * const MusicRoute = () => <Text>Music</Text>;
275 *
276 * const AlbumsRoute = () => <Text>Albums</Text>;
277 *
278 * const RecentsRoute = () => <Text>Recents</Text>;
279 *
280 * const NotificationsRoute = () => <Text>Notifications</Text>;
281 *
282 * const MyComponent = () => {
283 * const [index, setIndex] = React.useState(0);
284 * const [routes] = React.useState([
285 * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},
286 * { key: 'albums', title: 'Albums', focusedIcon: 'album' },
287 * { key: 'recents', title: 'Recents', focusedIcon: 'history' },
288 * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },
289 * ]);
290 *
291 * const renderScene = BottomNavigation.SceneMap({
292 * music: MusicRoute,
293 * albums: AlbumsRoute,
294 * recents: RecentsRoute,
295 * notifications: NotificationsRoute,
296 * });
297 *
298 * return (
299 * <BottomNavigation
300 * navigationState={{ index, routes }}
301 * onIndexChange={setIndex}
302 * renderScene={renderScene}
303 * />
304 * );
305 * };
306 *
307 * export default MyComponent;
308 * ```
309 */
310declare const BottomNavigation: {
311 <Route extends BaseRoute>({ navigationState, renderScene, renderIcon, renderLabel, renderTouchable, getLabelText, getBadge, getColor, getAccessibilityLabel, getTestID, activeColor, inactiveColor, keyboardHidesNavigationBar, barStyle, labeled, style, activeIndicatorStyle, sceneAnimationEnabled, sceneAnimationType, sceneAnimationEasing, onTabPress, onTabLongPress, onIndexChange, shifting: shiftingProp, safeAreaInsets, labelMaxFontSizeMultiplier, compact: compactProp, testID, theme: themeOverrides, getLazy, }: Props<Route>): React.JSX.Element;
312 /**
313 * Function which takes a map of route keys to components.
314 * Pure components are used to minimize re-rendering of the pages.
315 * This drastically improves the animation performance.
316 */
317 SceneMap<Route_1 extends BaseRoute>(scenes: {
318 [key: string]: React.ComponentType<{
319 route: Route_1;
320 jumpTo: (key: string) => void;
321 }>;
322 }): ({ route, jumpTo, }: {
323 route: Route_1;
324 jumpTo: (key: string) => void;
325 }) => React.JSX.Element;
326 Bar: {
327 <Route_2 extends {
328 key: string;
329 title?: string | undefined;
330 focusedIcon?: IconSource | undefined;
331 unfocusedIcon?: IconSource | undefined;
332 badge?: string | number | boolean | undefined;
333 color?: string | undefined;
334 accessibilityLabel?: string | undefined;
335 testID?: string | undefined;
336 lazy?: boolean | undefined;
337 }>({ navigationState, renderIcon, renderLabel, renderTouchable, getLabelText, getBadge, getColor, getAccessibilityLabel, getTestID, activeColor, inactiveColor, keyboardHidesNavigationBar, style, activeIndicatorStyle, labeled, animationEasing, onTabPress, onTabLongPress, shifting: shiftingProp, safeAreaInsets, labelMaxFontSizeMultiplier, compact: compactProp, testID, theme: themeOverrides, }: import("./BottomNavigationBar").Props<Route_2>): React.JSX.Element;
338 displayName: string;
339 };
340};
341export default BottomNavigation;
342//# sourceMappingURL=BottomNavigation.d.ts.map
\No newline at end of file