diff --git a/docs/6.x/docs/components/BottomNavigation/BottomNavigation.mdx b/docs/6.x/docs/components/BottomNavigation/BottomNavigation.mdx deleted file mode 100644 index c4fe55af84..0000000000 --- a/docs/6.x/docs/components/BottomNavigation/BottomNavigation.mdx +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: BottomNavigation ---- - -import PropTable from '@docs/components/PropTable.tsx'; -import ExtendsLink from '@docs/components/ExtendsLink.tsx'; -import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx'; -import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx'; -import ExtendedExample from '@docs/components/ExtendedExample.tsx'; - -BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar. -It is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar). - -By default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead. -See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information. - - - - - - - -## Usage -```js -import * as React from 'react'; -import { BottomNavigation, Text } from 'react-native-paper'; - -const MusicRoute = () => Music; - -const AlbumsRoute = () => Albums; - -const RecentsRoute = () => Recents; - -const NotificationsRoute = () => Notifications; - -const MyComponent = () => { - const [index, setIndex] = React.useState(0); - const [routes] = React.useState([ - { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'}, - { key: 'albums', title: 'Albums', focusedIcon: 'album' }, - { key: 'recents', title: 'Recents', focusedIcon: 'history' }, - { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' }, - ]); - - const renderScene = BottomNavigation.SceneMap({ - music: MusicRoute, - albums: AlbumsRoute, - recents: RecentsRoute, - notifications: NotificationsRoute, - }); - - return ( - - ); -}; - -export default MyComponent; -``` - - - ## Props - - - - -
- -### shifting - -
- - - -
- -### labeled - -
- - - -
- -### compact - -
- - - -
- -### navigationState (required) - -
- - - -
- -### onIndexChange (required) - -
- - - -
- -### renderScene (required) - -
- - - -
- -### renderIcon - -
- - - -
- -### renderLabel - -
- - - -
- -### renderTouchable - -
- - - -
- -### getAccessibilityLabel - -
- - - -
- -### getBadge - -
- - - -
- -### getLabelText - -
- - - -
- -### getLazy - -
- - - -
- -### getTestID - -
- - - -
- -### onTabPress - -
- - - -
- -### onTabLongPress - -
- - - -
- -### activeColor - -
- - - -
- -### inactiveColor - -
- - - -
- -### sceneAnimationEnabled - -
- - - -
- -### sceneAnimationType - -
- - - -
- -### sceneAnimationEasing - -
- - - -
- -### keyboardHidesNavigationBar - -
- - - -
- -### safeAreaInsets - -
- - - -
- -### barStyle - -
- - - -
- -### labelMaxFontSizeMultiplier - -
- - - -
- -### style - -
- - - -
- -### activeIndicatorStyle - -
- - - -
- -### theme - -
- - - -
- -### testID - -
- - - - - - - - - - diff --git a/docs/6.x/docs/components/BottomNavigation/BottomNavigationBar.mdx b/docs/6.x/docs/components/BottomNavigation/BottomNavigationBar.mdx deleted file mode 100644 index a93d41ee74..0000000000 --- a/docs/6.x/docs/components/BottomNavigation/BottomNavigationBar.mdx +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: BottomNavigation.Bar ---- - -import PropTable from '@docs/components/PropTable.tsx'; -import ExtendsLink from '@docs/components/ExtendsLink.tsx'; -import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx'; -import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx'; -import ExtendedExample from '@docs/components/ExtendedExample.tsx'; - -A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/). - - - - - - - - - ## Usage -### without React Navigation -```js -import React from 'react'; -import { useState } from 'react'; -import { View } from 'react-native'; -import { BottomNavigation, Text, Provider } from 'react-native-paper'; -import MaterialCommunityIcons from '@react-native-vector-icons/material-design-icons'; - -function HomeScreen() { - return ( - - Home! - - ); -} - -function SettingsScreen() { - return ( - - Settings! - - ); -} - -export default function MyComponent() { - const [index, setIndex] = useState(0); - - const routes = [ - { key: 'home', title: 'Home', icon: 'home' }, - { key: 'settings', title: 'Settings', icon: 'cog' }, - ]; - - const renderScene = ({ route }) => { - switch (route.key) { - case 'home': - return ; - case 'settings': - return ; - default: - return null; - } - }; - - return ( - - {renderScene({ route: routes[index] })} - { - const newIndex = routes.findIndex((r) => r.key === route.key); - if (newIndex !== -1) { - setIndex(newIndex); - } - }} - renderIcon={({ route, color }) => ( - - )} - getLabelText={({ route }) => route.title} - /> - - ); -} -``` - - ### with React Navigation - \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nconst MyTabs = createBottomTabNavigator({\n screenOptions: {\n animation: 'shift',\n },\n tabBar: ({ navigation, state, descriptors, insets }) => (\n {\n const event = navigation.emit({\n type: 'tabPress',\n target: route.key,\n canPreventDefault: true,\n });\n\n if (event.defaultPrevented) {\n preventDefault();\n } else {\n navigation.dispatch({\n ...CommonActions.navigate(route.name, route.params),\n target: state.key,\n });\n }\n }}\n renderIcon={({ route, focused, color }) =>\n descriptors[route.key].options.tabBarIcon?.({\n focused,\n color,\n size: 24,\n }) || null\n }\n getLabelText={({ route }) => {\n const { options } = descriptors[route.key];\n const label =\n typeof options.tabBarLabel === 'string'\n ? options.tabBarLabel\n : typeof options.title === 'string'\n ? options.title\n : route.name;\n\n return label;\n }}\n />\n ),\n screens: {\n Home: {\n screen: HomeScreen,\n options: {\n tabBarIcon: ({ color }) => (\n \n ),\n },\n },\n Settings: {\n screen: SettingsScreen,\n options: {\n tabBarIcon: ({ color }) => (\n \n ),\n },\n },\n },\n});\n\nconst Navigation = createStaticNavigation(MyTabs);\n\nexport default function App() {\n return (\n \n \n \n \n \n );\n}","dynamic":"import { Text, View } from 'react-native';\nimport { NavigationContainer, CommonActions } from '@react-navigation/native';\nimport { createBottomTabNavigator } from '@react-navigation/bottom-tabs';\nimport { Provider, BottomNavigation } from 'react-native-paper';\nimport MaterialCommunityIcons from '@react-native-vector-icons/material-design-icons';\n\nfunction HomeScreen() {\n return (\n \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nconst Tab = createBottomTabNavigator();\n\nexport default function App() {\n return (\n \n \n (\n {\n const event = navigation.emit({\n type: 'tabPress',\n target: route.key,\n canPreventDefault: true,\n });\n\n if (event.defaultPrevented) {\n preventDefault();\n } else {\n navigation.dispatch({\n ...CommonActions.navigate(route.name, route.params),\n target: state.key,\n });\n }\n }}\n renderIcon={({ route, focused, color }) =>\n descriptors[route.key].options.tabBarIcon?.({\n focused,\n color,\n size: 24,\n }) || null\n }\n getLabelText={({ route }) => {\n const { options } = descriptors[route.key];\n const label =\n typeof options.tabBarLabel === 'string'\n ? options.tabBarLabel\n : typeof options.title === 'string'\n ? options.title\n : route.name;\n\n return label;\n }}\n />\n )}>\n (\n \n ),\n }}\n />\n (\n \n ),\n }}\n />\n \n \n \n );\n}\n"}}} /> - - - - ## Props - - - - -
- -### shifting - -
- - - -
- -### labeled - -
- - - -
- -### compact - -
- - - -
- -### navigationState (required) - -
- - - -
- -### renderIcon - -
- - - -
- -### renderLabel - -
- - - -
- -### renderTouchable - -
- - - -
- -### getAccessibilityLabel - -
- - - -
- -### getBadge - -
- - - -
- -### getLabelText - -
- - - -
- -### getTestID - -
- - - -
- -### onTabPress (required) - -
- - - -
- -### onTabLongPress - -
- - - -
- -### activeColor - -
- - - -
- -### inactiveColor - -
- - - -
- -### animationEasing - -
- - - -
- -### keyboardHidesNavigationBar - -
- - - -
- -### safeAreaInsets - -
- - - -
- -### labelMaxFontSizeMultiplier - -
- - - -
- -### style - -
- - - -
- -### activeIndicatorStyle - -
- - - -
- -### theme - -
- - - -
- -### testID - -
- - - - - - - - - - diff --git a/docs/6.x/docs/components/BottomNavigation/_meta.json b/docs/6.x/docs/components/BottomNavigation/_meta.json deleted file mode 100644 index 94a0b010f3..0000000000 --- a/docs/6.x/docs/components/BottomNavigation/_meta.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "BottomNavigation", - "BottomNavigationBar" -] diff --git a/docs/6.x/docs/components/NavigationBar/NavigationBar.mdx b/docs/6.x/docs/components/NavigationBar/NavigationBar.mdx new file mode 100644 index 0000000000..457c250ccc --- /dev/null +++ b/docs/6.x/docs/components/NavigationBar/NavigationBar.mdx @@ -0,0 +1,269 @@ +--- +title: NavigationBar +--- + +import PropTable from '@docs/components/PropTable.tsx'; +import ExtendsLink from '@docs/components/ExtendsLink.tsx'; +import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx'; +import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx'; +import ExtendedExample from '@docs/components/ExtendedExample.tsx'; + +The Material Design 3 flexible navigation bar. It can easily be integrated +with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/). + +Set the `variant` prop to `'horizontal'` to lay items out horizontally +(icon beside label) in medium-width windows. + + + + + +## Usage +### without React Navigation +```js +import * as React from 'react'; +import { View } from 'react-native'; +import { NavigationBar, Text, Provider } from 'react-native-paper'; + +function HomeScreen() { + return ( + + Home! + + ); +} + +function SettingsScreen() { + return ( + + Settings! + + ); +} + +export default function MyComponent() { + const [index, setIndex] = React.useState(0); + + const routes = [ + { key: 'home', title: 'Home', focusedIcon: 'home' }, + { key: 'settings', title: 'Settings', focusedIcon: 'cog' }, + ]; + + const renderScene = ({ route }) => { + switch (route.key) { + case 'home': + return ; + case 'settings': + return ; + default: + return null; + } + }; + + return ( + + {renderScene({ route: routes[index] })} + { + const newIndex = routes.findIndex((r) => r.key === route.key); + if (newIndex !== -1) { + setIndex(newIndex); + } + }} + getLabelText={({ route }) => route.title} + /> + + ); +} +``` + + + ## Props + + + + +
+ +### labeled + +
+ + + +
+ +### variant + +
+ + + +
+ +### compact + +
+ + + +
+ +### navigationState (required) + +
+ + + +
+ +### renderIcon + +
+ + + +
+ +### renderLabel + +
+ + + +
+ +### renderTouchable + +
+ + + +
+ +### getAccessibilityLabel + +
+ + + +
+ +### getBadge + +
+ + + +
+ +### getLabelText + +
+ + + +
+ +### getTestID + +
+ + + +
+ +### onTabPress (required) + +
+ + + +
+ +### onTabLongPress + +
+ + + +
+ +### activeColor + +
+ + + +
+ +### inactiveColor + +
+ + + +
+ +### keyboardHidesNavigationBar + +
+ + + +
+ +### safeAreaInsets + +
+ + + +
+ +### labelMaxFontSizeMultiplier + +
+ + + +
+ +### style + +
+ + + +
+ +### activeIndicatorStyle + +
+ + + +
+ +### theme + +
+ + + +
+ +### testID + +
+ + + + + + + + + + diff --git a/docs/6.x/docs/components/NavigationBar/_meta.json b/docs/6.x/docs/components/NavigationBar/_meta.json new file mode 100644 index 0000000000..78af3034f5 --- /dev/null +++ b/docs/6.x/docs/components/NavigationBar/_meta.json @@ -0,0 +1,3 @@ +[ + "NavigationBar" +] diff --git a/docs/6.x/docs/components/_meta.json b/docs/6.x/docs/components/_meta.json index 6f793d41a3..9c240c0452 100644 --- a/docs/6.x/docs/components/_meta.json +++ b/docs/6.x/docs/components/_meta.json @@ -16,13 +16,6 @@ }, "Badge", "Banner", - { - "type": "dir", - "name": "BottomNavigation", - "label": "BottomNavigation", - "collapsible": true, - "collapsed": false - }, { "type": "dir", "name": "Button", @@ -103,6 +96,13 @@ "collapsed": false }, "Modal", + { + "type": "dir", + "name": "NavigationBar", + "label": "NavigationBar", + "collapsible": true, + "collapsed": false + }, { "type": "dir", "name": "Portal", diff --git a/docs/component-docs.config.ts b/docs/component-docs.config.ts index bad25d4eec..4bc2d8e404 100644 --- a/docs/component-docs.config.ts +++ b/docs/component-docs.config.ts @@ -38,10 +38,6 @@ const pages = { }, Badge: 'Badge', Banner: 'Banner', - BottomNavigation: { - BottomNavigation: 'BottomNavigation/BottomNavigation', - BottomNavigationBar: 'BottomNavigation/BottomNavigationBar', - }, Button: { Button: 'Button/Button', }, @@ -103,6 +99,9 @@ const pages = { MenuItem: 'Menu/MenuItem', }, Modal: 'Modal', + NavigationBar: { + NavigationBar: 'NavigationBar/NavigationBar', + }, Portal: { Portal: 'Portal/Portal', PortalHost: 'Portal/PortalHost', diff --git a/docs/scripts/generate-rspress-content.ts b/docs/scripts/generate-rspress-content.ts index 1c9accd93a..552c995b7f 100644 --- a/docs/scripts/generate-rspress-content.ts +++ b/docs/scripts/generate-rspress-content.ts @@ -128,8 +128,18 @@ const getVersionComponentOrder = (version: string): MetaEntry[] => { return fromConfig; } + const componentsDir = path.join(getVersionDocsDir(version), 'components'); + const filteredFromConfig = fromConfig.filter((entry) => { + const name = typeof entry === 'string' ? entry : entry.name; + return ( + fs.existsSync(path.join(componentsDir, name)) || + fs.existsSync(path.join(componentsDir, `${name}.mdx`)) || + fs.existsSync(path.join(componentsDir, `${name}.md`)) + ); + }); + return [ - ...fromConfig, + ...filteredFromConfig, { type: 'dir', name: 'HelperText', diff --git a/docs/src/data/componentDocs6x.json b/docs/src/data/componentDocs6x.json index 56b356912b..6794adf984 100644 --- a/docs/src/data/componentDocs6x.json +++ b/docs/src/data/componentDocs6x.json @@ -1263,10 +1263,10 @@ "BottomNavigation/BottomNavigation": { "filepath": "BottomNavigation/BottomNavigation.tsx", "title": "BottomNavigation", - "description": "BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.\nIt is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar).\n\nBy default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.\nSee [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { BottomNavigation, Text } from 'react-native-paper';\n\nconst MusicRoute = () => Music;\n\nconst AlbumsRoute = () => Albums;\n\nconst RecentsRoute = () => Recents;\n\nconst NotificationsRoute = () => Notifications;\n\nconst MyComponent = () => {\n const [index, setIndex] = React.useState(0);\n const [routes] = React.useState([\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]);\n\n const renderScene = BottomNavigation.SceneMap({\n music: MusicRoute,\n albums: AlbumsRoute,\n recents: RecentsRoute,\n notifications: NotificationsRoute,\n });\n\n return (\n \n );\n};\n\nexport default MyComponent;\n```", + "description": "BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.\nIt is primarily designed for use on mobile. If you want to use the navigation bar only see [`NavigationBar`](../NavigationBar/NavigationBar).\n\nBy default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.\nSee [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { BottomNavigation, Text } from 'react-native-paper';\n\nconst MusicRoute = () => Music;\n\nconst AlbumsRoute = () => Albums;\n\nconst RecentsRoute = () => Recents;\n\nconst NotificationsRoute = () => Notifications;\n\nconst MyComponent = () => {\n const [index, setIndex] = React.useState(0);\n const [routes] = React.useState([\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]);\n\n const renderScene = BottomNavigation.SceneMap({\n music: MusicRoute,\n albums: AlbumsRoute,\n recents: RecentsRoute,\n notifications: NotificationsRoute,\n });\n\n return (\n \n );\n};\n\nexport default MyComponent;\n```", "link": "bottom-navigation", "data": { - "description": "BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.\nIt is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar).\n\nBy default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.\nSee [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { BottomNavigation, Text } from 'react-native-paper';\n\nconst MusicRoute = () => Music;\n\nconst AlbumsRoute = () => Albums;\n\nconst RecentsRoute = () => Recents;\n\nconst NotificationsRoute = () => Notifications;\n\nconst MyComponent = () => {\n const [index, setIndex] = React.useState(0);\n const [routes] = React.useState([\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]);\n\n const renderScene = BottomNavigation.SceneMap({\n music: MusicRoute,\n albums: AlbumsRoute,\n recents: RecentsRoute,\n notifications: NotificationsRoute,\n });\n\n return (\n \n );\n};\n\nexport default MyComponent;\n```", + "description": "BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.\nIt is primarily designed for use on mobile. If you want to use the navigation bar only see [`NavigationBar`](../NavigationBar/NavigationBar).\n\nBy default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.\nSee [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { BottomNavigation, Text } from 'react-native-paper';\n\nconst MusicRoute = () => Music;\n\nconst AlbumsRoute = () => Albums;\n\nconst RecentsRoute = () => Recents;\n\nconst NotificationsRoute = () => Notifications;\n\nconst MyComponent = () => {\n const [index, setIndex] = React.useState(0);\n const [routes] = React.useState([\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]);\n\n const renderScene = BottomNavigation.SceneMap({\n music: MusicRoute,\n albums: AlbumsRoute,\n recents: RecentsRoute,\n notifications: NotificationsRoute,\n });\n\n return (\n \n );\n};\n\nexport default MyComponent;\n```", "displayName": "BottomNavigation", "methods": [ { @@ -1346,13 +1346,6 @@ ], "statics": [], "props": { - "shifting": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "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.\n\nBy default, this is `false` with theme version 3 and `true` when you have more than 3 tabs.\nPass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation.\nNote that you need at least 2 tabs be able to run this animation." - }, "labeled": { "required": false, "tsType": { @@ -2051,7 +2044,7 @@ "tsType": { "name": "boolean" }, - "description": "Whether animation is enabled for scenes transitions in `shifting` mode.\nBy default, the scenes cross-fade during tab change when `shifting` is enabled.\nSpecify `sceneAnimationEnabled` as `false` to disable the animation.", + "description": "Whether animation is enabled for scene transitions.\nBy default, the scenes cross-fade during tab change.\nSpecify `sceneAnimationEnabled` as `false` to disable the animation.", "defaultValue": { "value": "false", "computed": false @@ -2228,512 +2221,425 @@ "src/components/BottomNavigation/BottomNavigation.tsx" ] }, - "BottomNavigation/BottomNavigationBar": { - "filepath": "BottomNavigation/BottomNavigationBar.tsx", - "title": "BottomNavigation.Bar", - "description": "A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/).\n\n## Usage\n### without React Navigation\n```js\nimport React from 'react';\nimport { useState } from 'react';\nimport { View } from 'react-native';\nimport { BottomNavigation, Text, Provider } from 'react-native-paper';\nimport MaterialCommunityIcons from '@react-native-vector-icons/material-design-icons';\n\nfunction HomeScreen() {\n return (\n \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nexport default function MyComponent() {\n const [index, setIndex] = useState(0);\n\n const routes = [\n { key: 'home', title: 'Home', icon: 'home' },\n { key: 'settings', title: 'Settings', icon: 'cog' },\n ];\n\n const renderScene = ({ route }) => {\n switch (route.key) {\n case 'home':\n return ;\n case 'settings':\n return ;\n default:\n return null;\n }\n };\n\n return (\n \n {renderScene({ route: routes[index] })}\n {\n const newIndex = routes.findIndex((r) => r.key === route.key);\n if (newIndex !== -1) {\n setIndex(newIndex);\n }\n }}\n renderIcon={({ route, color }) => (\n \n )}\n getLabelText={({ route }) => route.title}\n />\n \n );\n}\n```", - "link": "bottom-navigation-bar", + "Button/Button": { + "filepath": "Button/Button.tsx", + "title": "Button", + "description": "A button is component that the user can press to trigger an action.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "link": "button", "data": { - "description": "A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/).\n\n## Usage\n### without React Navigation\n```js\nimport React from 'react';\nimport { useState } from 'react';\nimport { View } from 'react-native';\nimport { BottomNavigation, Text, Provider } from 'react-native-paper';\nimport MaterialCommunityIcons from '@react-native-vector-icons/material-design-icons';\n\nfunction HomeScreen() {\n return (\n \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nexport default function MyComponent() {\n const [index, setIndex] = useState(0);\n\n const routes = [\n { key: 'home', title: 'Home', icon: 'home' },\n { key: 'settings', title: 'Settings', icon: 'cog' },\n ];\n\n const renderScene = ({ route }) => {\n switch (route.key) {\n case 'home':\n return ;\n case 'settings':\n return ;\n default:\n return null;\n }\n };\n\n return (\n \n {renderScene({ route: routes[index] })}\n {\n const newIndex = routes.findIndex((r) => r.key === route.key);\n if (newIndex !== -1) {\n setIndex(newIndex);\n }\n }}\n renderIcon={({ route, color }) => (\n \n )}\n getLabelText={({ route }) => route.title}\n />\n \n );\n}\n```", - "displayName": "BottomNavigation.Bar", + "description": "A button is component that the user can press to trigger an action.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "displayName": "Button", "methods": [], "statics": [], "props": { - "shifting": { + "mode": { "required": false, "tsType": { - "name": "boolean" + "name": "union", + "raw": "'text' | 'outlined' | 'contained' | 'elevated' | 'contained-tonal'", + "elements": [ + { + "name": "literal", + "value": "'text'" + }, + { + "name": "literal", + "value": "'outlined'" + }, + { + "name": "literal", + "value": "'contained'" + }, + { + "name": "literal", + "value": "'elevated'" + }, + { + "name": "literal", + "value": "'contained-tonal'" + } + ] }, - "description": "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.\n\nBy default, this is `false` with theme version 3 and `true` when you have more than 3 tabs.\nPass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation.\nNote that you need at least 2 tabs be able to run this animation." + "description": "Mode of the button. You can change the mode to adjust the styling to give it desired emphasis.\n- `text` - flat button without background or outline, used for the lowest priority actions, especially when presenting multiple options.\n- `outlined` - button with an outline without background, typically used for important, but not primary action – represents medium emphasis.\n- `contained` - button with a background color, used for important action, have the most visual impact and high emphasis.\n- `elevated` - button with a background color and elevation, used when absolutely necessary e.g. button requires visual separation from a patterned background. @supported Available in v5.x with theme version 3\n- `contained-tonal` - button with a secondary background color, an alternative middle ground between contained and outlined buttons. @supported Available in v5.x with theme version 3", + "defaultValue": { + "value": "'text'", + "computed": false + } }, - "labeled": { + "dark": { "required": false, "tsType": { "name": "boolean" }, - "description": "Whether to show labels in tabs. When `false`, only icons will be displayed.", - "defaultValue": { - "value": "true", - "computed": false - } + "description": "Whether the color is a dark color. A dark button will render light text and vice-versa. Only applicable for:\n * `contained` mode for theme version 2\n * `contained`, `contained-tonal` and `elevated` modes for theme version 3." }, "compact": { "required": false, "tsType": { "name": "boolean" }, - "description": "Whether tabs should be spread across the entire width." + "description": "Use a compact look, useful for `text` buttons in a row." }, - "navigationState": { + "buttonColor": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "Custom button's background color." + }, + "textColor": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "Custom button's text color." + }, + "loading": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether to show a loading indicator." + }, + "icon": { + "required": false, + "tsType": { + "name": "IconSource" + }, + "description": "Icon to display for the `Button`." + }, + "disabled": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch." + }, + "children": { "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Label text of the button." + }, + "uppercase": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Make the label text uppercased. Note that this won't work if you pass React elements as children." + }, + "background": { + "required": false, + "tsType": { + "name": "PressableAndroidRippleConfig" + }, + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + }, + "aria-label": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + }, + "accessibilityHint": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Accessibility hint for the button. This is read by the screen reader when the user taps the button." + }, + "role": { + "required": false, + "tsType": { + "name": "Role" + }, + "description": "Accessibility role for the button. The \"button\" role is set by default.", + "defaultValue": { + "value": "'button'", + "computed": false + } + }, + "onPress": { + "required": false, "tsType": { "name": "signature", - "type": "object", - "raw": "{\n index: number;\n routes: Route[];\n}", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", "signature": { - "properties": [ - { - "key": "index", - "value": { - "name": "number", - "required": true - } - }, + "arguments": [ { - "key": "routes", - "value": { - "name": "Array", - "elements": [ - { - "name": "Route" - } - ], - "raw": "Route[]", - "required": true + "name": "e", + "type": { + "name": "GestureResponderEvent" } } - ] + ], + "return": { + "name": "void" + } } }, - "description": "State for the bottom navigation. The state should contain the following properties:\n\n- `index`: a number representing the index of the active route in the `routes` array\n- `routes`: an array containing a list of route objects used for rendering the tabs\n\nEach route object should contain the following properties:\n\n- `key`: a unique key to identify the route (required)\n- `title`: title of the route to use as the tab label\n- `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\n- `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\n- `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text.\n- `aria-label`: accessibility label for the tab button\n- `testID`: test id for the tab button\n\nExample:\n\n```js\n{\n index: 1,\n routes: [\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]\n}\n```\n\n`BottomNavigation.Bar` is a controlled component, which means the `index` needs to be updated via the `onTabPress` callback." + "description": "Function to execute on press." }, - "renderIcon": { + "onPressIn": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: {\n route: Route;\n focused: boolean;\n color: ColorValue;\n}) => React.ReactNode", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "signature", - "type": "object", - "raw": "{\n route: Route;\n focused: boolean;\n color: ColorValue;\n}", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - }, - { - "key": "focused", - "value": { - "name": "boolean", - "required": true - } - }, - { - "key": "color", - "value": { - "name": "ColorValue", - "required": true - } - } - ] - } + "name": "GestureResponderEvent" } } ], "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "void" } } }, - "description": "Callback which returns a React Element to be used as tab icon." + "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." }, - "renderLabel": { + "onPressOut": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: {\n route: Route;\n focused: boolean;\n color: ColorValue;\n}) => React.ReactNode", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "signature", - "type": "object", - "raw": "{\n route: Route;\n focused: boolean;\n color: ColorValue;\n}", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - }, - { - "key": "focused", - "value": { - "name": "boolean", - "required": true - } - }, - { - "key": "color", - "value": { - "name": "ColorValue", - "required": true - } - } - ] - } + "name": "GestureResponderEvent" } } ], "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "void" } } }, - "description": "Callback which React Element to be used as tab label." + "description": "Function to execute as soon as the touch is released even before onPress." }, - "renderTouchable": { + "onLongPress": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: TouchableProps) => React.ReactNode", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "intersection", - "raw": "TouchableRippleProps & {\n key: string;\n route: Route;\n children: React.ReactNode;\n borderless?: boolean;\n centered?: boolean;\n rippleColor?: ColorValue;\n}", - "elements": [ - { - "name": "TouchableRippleProps" - }, - { - "name": "signature", - "type": "object", - "raw": "{\n key: string;\n route: Route;\n children: React.ReactNode;\n borderless?: boolean;\n centered?: boolean;\n rippleColor?: ColorValue;\n}", - "signature": { - "properties": [ - { - "key": "key", - "value": { - "name": "string", - "required": true - } - }, - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - }, - { - "key": "children", - "value": { - "name": "ReactReactNode", - "raw": "React.ReactNode", - "required": true - } - }, - { - "key": "borderless", - "value": { - "name": "boolean", - "required": false - } - }, - { - "key": "centered", - "value": { - "name": "boolean", - "required": false - } - }, - { - "key": "rippleColor", - "value": { - "name": "ColorValue", - "required": false - } - } - ] - } - } - ] + "name": "GestureResponderEvent" } } ], "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "void" } } }, - "description": "Callback which returns a React element to be used as the touchable for the tab item.\nRenders a `TouchableRipple` on Android and `Pressable` on iOS.", - "defaultValue": { - "value": "({ key, ...props }: TouchableProps) => (\n \n)", - "computed": false - } + "description": "Function to execute on long press." }, - "getAccessibilityLabel": { + "delayLongPress": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { route: Route }) => string | undefined", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - } - } - ], - "return": { - "name": "union", - "raw": "string | undefined", - "elements": [ - { - "name": "string" - }, - { - "name": "undefined" - } - ] + "name": "number" + }, + "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." + }, + "contentStyle": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab.\nUses `route['aria-label']` by default.", - "defaultValue": { - "value": "({ route }: { route: Route }) => route['aria-label']", - "computed": false - } + "description": "Style of button's inner content.\nUse this prop to apply custom height and width, to set a custom padding or to set the icon on the right with `flexDirection: 'row-reverse'`." }, - "getBadge": { + "maxFontSizeMultiplier": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { route: Route }) => boolean | number | string | undefined", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - } - } - ], - "return": { - "name": "union", - "raw": "boolean | number | string | undefined", + "name": "number" + }, + "description": "Specifies the largest possible scale a text font can reach." + }, + "hitSlop": { + "required": false, + "tsType": { + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" + }, + "description": "Sets additional distance outside of element in which a press can be detected." + }, + "style": { + "required": false, + "tsType": { + "name": "Animated.WithAnimatedValue", + "elements": [ + { + "name": "StyleProp", "elements": [ { - "name": "boolean" - }, - { - "name": "number" - }, - { - "name": "string" - }, - { - "name": "undefined" + "name": "ViewStyle" } - ] + ], + "raw": "StyleProp" } - } + ], + "raw": "Animated.WithAnimatedValue>" }, - "description": "Get badge for the tab, uses `route.badge` by default.", - "defaultValue": { - "value": "({ route }: { route: Route }) => route.badge", - "computed": false - } + "description": "" }, - "getLabelText": { + "labelStyle": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { route: Route }) => string | undefined", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - } - } - ], - "return": { - "name": "union", - "raw": "string | undefined", - "elements": [ - { - "name": "string" - }, - { - "name": "undefined" - } - ] + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component.", - "defaultValue": { - "value": "({ route }: { route: Route }) => route.title", - "computed": false - } + "description": "Style for the button text." }, - "getTestID": { + "theme": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { route: Route }) => string | undefined", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - } - } - ], - "return": { - "name": "union", - "raw": "string | undefined", - "elements": [ - { - "name": "string" - }, - { - "name": "undefined" - } - ] + "name": "ThemeProp" + }, + "description": "" + }, + "touchableRef": { + "required": false, + "tsType": { + "name": "ReactRefObject", + "raw": "React.RefObject", + "elements": [ + { + "name": "View" } - } + ] }, - "description": "Get the id to locate this tab button in tests, uses `route.testID` by default.", + "description": "Reference for the touchable" + }, + "ref": { + "required": false, + "tsType": { + "name": "ReactRef", + "raw": "React.Ref", + "elements": [ + { + "name": "View" + } + ] + }, + "description": "" + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "testID to be used on tests.", "defaultValue": { - "value": "({ route }: { route: Route }) => route.testID", + "value": "'button'", + "computed": false + } + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Button/Button.tsx" + ] + }, + "Card/Card": { + "filepath": "Card/Card.tsx", + "title": "Card", + "description": "A card is a sheet of material that serves as an entry point to more detailed information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Button, Card, Text } from 'react-native-paper';\n\nconst LeftContent = props => \n\nconst MyComponent = () => (\n \n \n \n Card title\n Card content\n \n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "link": "card", + "data": { + "description": "A card is a sheet of material that serves as an entry point to more detailed information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Button, Card, Text } from 'react-native-paper';\n\nconst LeftContent = props => \n\nconst MyComponent = () => (\n \n \n \n Card title\n Card content\n \n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "Card", + "methods": [], + "statics": [], + "props": { + "mode": { + "required": false, + "tsType": { + "name": "union", + "raw": "'elevated' | 'outlined' | 'contained'", + "elements": [ + { + "name": "literal", + "value": "'elevated'" + }, + { + "name": "literal", + "value": "'outlined'" + }, + { + "name": "literal", + "value": "'contained'" + } + ] + }, + "description": "Mode of the Card.\n- `elevated` - Card with elevation.\n- `contained` - Card without outline and elevation @supported Available in v5.x with theme version 3\n- `outlined` - Card with an outline.", + "defaultValue": { + "value": "'elevated'", "computed": false } }, - "onTabPress": { + "children": { "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Content of the `Card`." + }, + "onLongPress": { + "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: { route: Route } & TabPressEvent) => void", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + } + }, + "description": "Function to execute on long press." + }, + "onPress": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "intersection", - "raw": "{ route: Route } & TabPressEvent", - "elements": [ - { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - }, - { - "name": "signature", - "type": "object", - "raw": "{\n defaultPrevented: boolean;\n preventDefault(): void;\n}", - "signature": { - "properties": [ - { - "key": "defaultPrevented", - "value": { - "name": "boolean", - "required": true - } - }, - { - "key": "preventDefault", - "value": { - "name": "void", - "required": true - } - } - ] - } - } - ] + "name": "GestureResponderEvent" } } ], @@ -2742,62 +2648,20 @@ } } }, - "description": "Function to execute on tab press. It receives the route for the pressed tab. Use this to update the navigation state." + "description": "Function to execute on press." }, - "onTabLongPress": { + "onPressIn": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: { route: Route } & TabPressEvent) => void", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "intersection", - "raw": "{ route: Route } & TabPressEvent", - "elements": [ - { - "name": "signature", - "type": "object", - "raw": "{ route: Route }", - "signature": { - "properties": [ - { - "key": "route", - "value": { - "name": "Route", - "required": true - } - } - ] - } - }, - { - "name": "signature", - "type": "object", - "raw": "{\n defaultPrevented: boolean;\n preventDefault(): void;\n}", - "signature": { - "properties": [ - { - "key": "defaultPrevented", - "value": { - "name": "boolean", - "required": true - } - }, - { - "key": "preventDefault", - "value": { - "name": "void", - "required": true - } - } - ] - } - } - ] + "name": "GestureResponderEvent" } } ], @@ -2806,101 +2670,98 @@ } } }, - "description": "Function to execute on tab long press. It receives the route for the pressed tab" - }, - "activeColor": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Custom color for icon and label in the active tab." - }, - "inactiveColor": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Custom color for icon and label in the inactive tab." + "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." }, - "animationEasing": { + "onPressOut": { "required": false, "tsType": { - "name": "union", - "raw": "EasingFunction | undefined", - "elements": [ - { - "name": "EasingFunction" - }, - { - "name": "undefined" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" } - ] + } }, - "description": "The scene animation Easing." + "description": "Function to execute as soon as the touch is released even before onPress." }, - "keyboardHidesNavigationBar": { + "delayLongPress": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether the bottom navigation bar is hidden when keyboard is shown.\nOn Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`.", - "defaultValue": { - "value": "Platform.OS === 'android'", - "computed": false - } + "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." }, - "safeAreaInsets": { + "disabled": { "required": false, "tsType": { - "name": "signature", - "type": "object", - "raw": "{\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}", - "signature": { - "properties": [ - { - "key": "top", - "value": { - "name": "number", - "required": false - } - }, - { - "key": "right", - "value": { - "name": "number", - "required": false - } - }, - { - "key": "bottom", - "value": { - "name": "number", - "required": false - } - }, - { - "key": "left", - "value": { - "name": "number", - "required": false - } - } - ] - } + "name": "boolean" }, - "description": "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.\nThe bottom insets for iOS is added by default. You can override the behavior with this option." + "description": "If true, disable all interactions for this component." }, - "labelMaxFontSizeMultiplier": { + "elevation": { "required": false, "tsType": { - "name": "number" + "name": "union", + "raw": "0 | 1 | 2 | 3 | 4 | 5 | Animated.Value", + "elements": [ + { + "name": "literal", + "value": "0" + }, + { + "name": "literal", + "value": "1" + }, + { + "name": "literal", + "value": "2" + }, + { + "name": "literal", + "value": "3" + }, + { + "name": "literal", + "value": "4" + }, + { + "name": "literal", + "value": "5" + }, + { + "name": "Animated.Value" + } + ] }, - "description": "Specifies the largest possible scale a label font can reach.", + "description": "Changes Card shadow and background on iOS and Android.", "defaultValue": { "value": "1", "computed": false } }, + "contentStyle": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "Style of card's inner content." + }, "style": { "required": false, "tsType": { @@ -2920,19 +2781,6 @@ }, "description": "" }, - "activeIndicatorStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "" - }, "theme": { "required": false, "tsType": { @@ -2945,346 +2793,531 @@ "tsType": { "name": "string" }, - "description": "TestID used for testing purposes", + "description": "Pass down testID from card props to touchable", "defaultValue": { - "value": "'bottom-navigation-bar'", + "value": "'card'", "computed": false } + }, + "accessible": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Pass down accessible from card props to touchable" } } }, "type": "component", "dependencies": [ - "src/components/BottomNavigation/BottomNavigationBar.tsx" - ], - "group": "BottomNavigation" + "src/components/Card/Card.tsx" + ] }, - "Button/Button": { - "filepath": "Button/Button.tsx", - "title": "Button", - "description": "A button is component that the user can press to trigger an action.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "link": "button", + "Card/CardActions": { + "filepath": "Card/CardActions.tsx", + "title": "Card.Actions", + "description": "A component to show a list of actions inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "link": "card-actions", "data": { - "description": "A button is component that the user can press to trigger an action.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "displayName": "Button", + "description": "A component to show a list of actions inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "Card.Actions", "methods": [], "statics": [], "props": { - "mode": { + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Items inside the `CardActions`." + }, + "style": { "required": false, "tsType": { - "name": "union", - "raw": "'text' | 'outlined' | 'contained' | 'elevated' | 'contained-tonal'", + "name": "StyleProp", "elements": [ { - "name": "literal", - "value": "'text'" - }, - { - "name": "literal", - "value": "'outlined'" - }, - { - "name": "literal", - "value": "'contained'" - }, - { - "name": "literal", - "value": "'elevated'" - }, - { - "name": "literal", - "value": "'contained-tonal'" + "name": "ViewStyle" } - ] + ], + "raw": "StyleProp" }, - "description": "Mode of the button. You can change the mode to adjust the styling to give it desired emphasis.\n- `text` - flat button without background or outline, used for the lowest priority actions, especially when presenting multiple options.\n- `outlined` - button with an outline without background, typically used for important, but not primary action – represents medium emphasis.\n- `contained` - button with a background color, used for important action, have the most visual impact and high emphasis.\n- `elevated` - button with a background color and elevation, used when absolutely necessary e.g. button requires visual separation from a patterned background. @supported Available in v5.x with theme version 3\n- `contained-tonal` - button with a secondary background color, an alternative middle ground between contained and outlined buttons. @supported Available in v5.x with theme version 3", - "defaultValue": { - "value": "'text'", - "computed": false - } + "description": "" }, - "dark": { + "theme": { "required": false, "tsType": { - "name": "boolean" + "name": "ThemeProp" }, - "description": "Whether the color is a dark color. A dark button will render light text and vice-versa. Only applicable for:\n * `contained` mode for theme version 2\n * `contained`, `contained-tonal` and `elevated` modes for theme version 3." - }, - "compact": { - "required": false, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Card/CardActions.tsx" + ], + "group": "Card" + }, + "Card/CardContent": { + "filepath": "Card/CardContent.tsx", + "title": "Card.Content", + "description": "A component to show content inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n Card title\n Card content\n \n \n);\n\nexport default MyComponent;\n```", + "link": "card-content", + "data": { + "description": "A component to show content inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n Card title\n Card content\n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "Card.Content", + "methods": [], + "statics": [], + "props": { + "children": { + "required": true, "tsType": { - "name": "boolean" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Use a compact look, useful for `text` buttons in a row." + "description": "Items inside the `Card.Content`." }, - "buttonColor": { + "index": { "required": false, "tsType": { - "name": "ColorValue" + "name": "number" }, - "description": "Custom button's background color." + "description": "@internal" }, - "textColor": { + "total": { "required": false, "tsType": { - "name": "ColorValue" + "name": "number" }, - "description": "Custom button's text color." + "description": "@internal" }, - "loading": { + "siblings": { "required": false, "tsType": { - "name": "boolean" - }, - "description": "Whether to show a loading indicator." + "name": "Array", + "elements": [ + { + "name": "string" + } + ], + "raw": "Array" + }, + "description": "@internal" }, - "icon": { + "style": { "required": false, "tsType": { - "name": "IconSource" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "Icon to display for the `Button`." + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Card/CardContent.tsx" + ], + "group": "Card" + }, + "Card/CardCover": { + "filepath": "Card/CardCover.tsx", + "title": "Card.Cover", + "description": "A component to show a cover image inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```\n\n@extends Image props https://reactnative.dev/docs/image#props", + "link": "card-cover", + "data": { + "description": "A component to show a cover image inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```\n\n@extends Image props https://reactnative.dev/docs/image#props", + "displayName": "Card.Cover", + "methods": [], + "statics": [], + "props": { + "index": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "@internal" }, - "disabled": { + "total": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch." + "description": "@internal" }, - "children": { + "style": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "" + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Card/CardCover.tsx" + ], + "group": "Card" + }, + "Card/CardTitle": { + "filepath": "Card/CardTitle.tsx", + "title": "Card.Title", + "description": "A component to show a title, subtitle and an avatar inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Card, IconButton } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n right={(props) => {}} />}\n />\n);\n\nexport default MyComponent;\n```", + "link": "card-title", + "data": { + "description": "A component to show a title, subtitle and an avatar inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Card, IconButton } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n right={(props) => {}} />}\n />\n);\n\nexport default MyComponent;\n```", + "displayName": "Card.Title", + "methods": [], + "statics": [], + "props": { + "title": { "required": true, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Label text of the button." + "description": "Text for the title. Note that this will only accept a string or ``-based node." }, - "uppercase": { + "titleStyle": { "required": false, "tsType": { - "name": "boolean" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "Make the label text uppercased. Note that this won't work if you pass React elements as children." + "description": "Style for the title." }, - "background": { + "titleNumberOfLines": { "required": false, "tsType": { - "name": "PressableAndroidRippleConfig" + "name": "number" }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + "description": "Number of lines for the title.", + "defaultValue": { + "value": "1", + "computed": false + } }, - "aria-label": { + "titleVariant": { "required": false, "tsType": { - "name": "string" + "name": "TypescaleKey" }, - "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + "description": "@supported Available in v5.x with theme version 3\n\nTitle text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "defaultValue": { + "value": "'bodyLarge'", + "computed": false + } }, - "accessibilityHint": { + "subtitle": { "required": false, "tsType": { - "name": "string" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Accessibility hint for the button. This is read by the screen reader when the user taps the button." + "description": "Text for the subtitle. Note that this will only accept a string or ``-based node." }, - "role": { + "subtitleStyle": { "required": false, "tsType": { - "name": "Role" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "Accessibility role for the button. The \"button\" role is set by default.", + "description": "Style for the subtitle." + }, + "subtitleNumberOfLines": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "Number of lines for the subtitle.", "defaultValue": { - "value": "'button'", + "value": "1", "computed": false } }, - "onPress": { + "subtitleVariant": { + "required": false, + "tsType": { + "name": "TypescaleKey" + }, + "description": "@supported Available in v5.x with theme version 3\n\nSubtitle text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "defaultValue": { + "value": "'bodyMedium'", + "computed": false + } + }, + "left": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(e: GestureResponderEvent) => void", + "raw": "(props: { size: number }) => React.ReactNode", "signature": { "arguments": [ { - "name": "e", + "name": "props", "type": { - "name": "GestureResponderEvent" + "name": "signature", + "type": "object", + "raw": "{ size: number }", + "signature": { + "properties": [ + { + "key": "size", + "value": { + "name": "number", + "required": true + } + } + ] + } } } ], "return": { - "name": "void" + "name": "ReactReactNode", + "raw": "React.ReactNode" } } }, - "description": "Function to execute on press." + "description": "Callback which returns a React element to display on the left side." }, - "onPressIn": { + "leftStyle": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." + "description": "Style for the left element wrapper." }, - "onPressOut": { + "right": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(e: GestureResponderEvent) => void", + "raw": "(props: { size: number }) => React.ReactNode", "signature": { "arguments": [ { - "name": "e", + "name": "props", "type": { - "name": "GestureResponderEvent" + "name": "signature", + "type": "object", + "raw": "{ size: number }", + "signature": { + "properties": [ + { + "key": "size", + "value": { + "name": "number", + "required": true + } + } + ] + } } } ], "return": { - "name": "void" + "name": "ReactReactNode", + "raw": "React.ReactNode" } } }, - "description": "Function to execute as soon as the touch is released even before onPress." + "description": "Callback which returns a React element to display on the right side." }, - "onLongPress": { + "rightStyle": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Function to execute on long press." + "description": "Style for the right element wrapper." }, - "delayLongPress": { + "index": { "required": false, "tsType": { "name": "number" }, - "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." + "description": "@internal" }, - "contentStyle": { + "total": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "number" }, - "description": "Style of button's inner content.\nUse this prop to apply custom height and width, to set a custom padding or to set the icon on the right with `flexDirection: 'row-reverse'`." + "description": "@internal" }, - "maxFontSizeMultiplier": { + "titleMaxFontSizeMultiplier": { "required": false, "tsType": { "name": "number" }, - "description": "Specifies the largest possible scale a text font can reach." + "description": "Specifies the largest possible scale a title font can reach." }, - "hitSlop": { + "subtitleMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" + "name": "number" }, - "description": "Sets additional distance outside of element in which a press can be detected." + "description": "Specifies the largest possible scale a subtitle font can reach." }, "style": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", + "name": "StyleProp", "elements": [ { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "ViewStyle" } ], - "raw": "Animated.WithAnimatedValue>" + "raw": "StyleProp" }, "description": "" }, - "labelStyle": { + "theme": { "required": false, "tsType": { - "name": "StyleProp", + "name": "ThemeProp" + }, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Card/CardTitle.tsx" + ], + "group": "Card" + }, + "Checkbox/Checkbox": { + "filepath": "Checkbox/Checkbox.tsx", + "title": "Checkbox", + "description": "Checkboxes allow the selection of multiple options from a set.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [checked, setChecked] = React.useState(false);\n\n return (\n {\n setChecked(!checked);\n }}\n />\n );\n};\n\nexport default MyComponent;\n```", + "link": "checkbox", + "data": { + "description": "Checkboxes allow the selection of multiple options from a set.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [checked, setChecked] = React.useState(false);\n\n return (\n {\n setChecked(!checked);\n }}\n />\n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Checkbox", + "methods": [], + "statics": [], + "props": { + "status": { + "required": true, + "tsType": { + "name": "union", + "raw": "'checked' | 'unchecked' | 'indeterminate'", "elements": [ { - "name": "TextStyle" + "name": "literal", + "value": "'checked'" + }, + { + "name": "literal", + "value": "'unchecked'" + }, + { + "name": "literal", + "value": "'indeterminate'" } - ], - "raw": "StyleProp" + ] }, - "description": "Style for the button text." + "description": "Status of checkbox." }, - "theme": { + "disabled": { "required": false, "tsType": { - "name": "ThemeProp" + "name": "boolean" }, - "description": "" + "description": "Whether checkbox is disabled." }, - "touchableRef": { + "onPress": { "required": false, "tsType": { - "name": "ReactRefObject", - "raw": "React.RefObject", - "elements": [ - { - "name": "View" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" } - ] + } }, - "description": "Reference for the touchable" + "description": "Function to execute on press." }, - "ref": { + "uncheckedColor": { "required": false, "tsType": { - "name": "ReactRef", - "raw": "React.Ref", - "elements": [ - { - "name": "View" - } - ] + "name": "ColorValue" + }, + "description": "Custom color for unchecked checkbox." + }, + "color": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "Custom color for checkbox." + }, + "error": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether the checkbox is in an error state. When true, the outline\n(unchecked) and container (selected) use `theme.colors.error`.\n`disabled` and explicit `color`/`uncheckedColor` overrides take\nprecedence." + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" }, "description": "" }, @@ -3293,78 +3326,74 @@ "tsType": { "name": "string" }, - "description": "testID to be used on tests.", - "defaultValue": { - "value": "'button'", - "computed": false - } + "description": "testID to be used on tests." + }, + "style": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "Custom style to override the default tap target. Passed through to\nthe underlying `TouchableRipple`." } } }, "type": "component", "dependencies": [ - "src/components/Button/Button.tsx" + "src/components/Checkbox/Checkbox.tsx" ] }, - "Card/Card": { - "filepath": "Card/Card.tsx", - "title": "Card", - "description": "A card is a sheet of material that serves as an entry point to more detailed information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Button, Card, Text } from 'react-native-paper';\n\nconst LeftContent = props => \n\nconst MyComponent = () => (\n \n \n \n Card title\n Card content\n \n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "link": "card", + "Checkbox/CheckboxItem": { + "filepath": "Checkbox/CheckboxItem.tsx", + "title": "Checkbox.Item", + "description": "Checkbox.Item allows you to press the whole row (item) instead of only the Checkbox.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```", + "link": "checkbox-item", "data": { - "description": "A card is a sheet of material that serves as an entry point to more detailed information.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Button, Card, Text } from 'react-native-paper';\n\nconst LeftContent = props => \n\nconst MyComponent = () => (\n \n \n \n Card title\n Card content\n \n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "Card", + "description": "Checkbox.Item allows you to press the whole row (item) instead of only the Checkbox.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "Checkbox.Item", "methods": [], "statics": [], "props": { - "mode": { - "required": false, + "status": { + "required": true, "tsType": { "name": "union", - "raw": "'elevated' | 'outlined' | 'contained'", + "raw": "'checked' | 'unchecked' | 'indeterminate'", "elements": [ { "name": "literal", - "value": "'elevated'" + "value": "'checked'" }, { "name": "literal", - "value": "'outlined'" + "value": "'unchecked'" }, { "name": "literal", - "value": "'contained'" + "value": "'indeterminate'" } ] }, - "description": "Mode of the Card.\n- `elevated` - Card with elevation.\n- `contained` - Card without outline and elevation @supported Available in v5.x with theme version 3\n- `outlined` - Card with an outline.", - "defaultValue": { - "value": "'elevated'", - "computed": false - } + "description": "Status of checkbox." }, - "children": { - "required": true, + "disabled": { + "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "boolean" }, - "description": "Content of the `Card`." + "description": "Whether checkbox is disabled." }, - "onLongPress": { - "required": false, + "label": { + "required": true, "tsType": { - "name": "signature", - "type": "function", - "raw": "() => void", - "signature": { - "arguments": [], - "return": { - "name": "void" - } - } + "name": "string" }, - "description": "Function to execute on long press." + "description": "Label to be displayed on the item." }, "onPress": { "required": false, @@ -3388,7 +3417,7 @@ }, "description": "Function to execute on press." }, - "onPressIn": { + "onLongPress": { "required": false, "tsType": { "name": "signature", @@ -3408,86 +3437,41 @@ } } }, - "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." + "description": "Function to execute on long press." }, - "onPressOut": { + "background": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } + "name": "PressableAndroidRippleConfig" }, - "description": "Function to execute as soon as the touch is released even before onPress." + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, - "delayLongPress": { + "aria-label": { "required": false, "tsType": { - "name": "number" + "name": "string" }, - "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." + "description": "Accessibility label for the touchable. This is read by the screen reader when the user taps the touchable.", + "defaultValue": { + "value": "label", + "computed": true + } }, - "disabled": { + "uncheckedColor": { "required": false, "tsType": { - "name": "boolean" + "name": "string" }, - "description": "If true, disable all interactions for this component." + "description": "Custom color for unchecked checkbox." }, - "elevation": { + "color": { "required": false, "tsType": { - "name": "union", - "raw": "0 | 1 | 2 | 3 | 4 | 5 | Animated.Value", - "elements": [ - { - "name": "literal", - "value": "0" - }, - { - "name": "literal", - "value": "1" - }, - { - "name": "literal", - "value": "2" - }, - { - "name": "literal", - "value": "3" - }, - { - "name": "literal", - "value": "4" - }, - { - "name": "literal", - "value": "5" - }, - { - "name": "Animated.Value" - } - ] + "name": "string" }, - "description": "Changes Card shadow and background on iOS and Android.", - "defaultValue": { - "value": "1", - "computed": false - } + "description": "Custom color for checkbox." }, - "contentStyle": { + "style": { "required": false, "tsType": { "name": "StyleProp", @@ -3498,26 +3482,42 @@ ], "raw": "StyleProp" }, - "description": "Style of card's inner content." + "description": "Additional styles for container View." }, - "style": { + "labelMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", + "name": "number" + }, + "description": "Specifies the largest possible scale a label font can reach.", + "defaultValue": { + "value": "1.5", + "computed": false + } + }, + "labelStyle": { + "required": false, + "tsType": { + "name": "StyleProp", "elements": [ { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "TextStyle" } ], - "raw": "Animated.WithAnimatedValue>" + "raw": "StyleProp" }, - "description": "" + "description": "Style that is passed to Label element." + }, + "labelVariant": { + "required": false, + "tsType": { + "name": "TypescaleKey" + }, + "description": "@supported Available in v5.x with theme version 3\n\nLabel text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "defaultValue": { + "value": "'bodyLarge'", + "computed": false + } }, "theme": { "required": false, @@ -3531,540 +3531,407 @@ "tsType": { "name": "string" }, - "description": "Pass down testID from card props to touchable", + "description": "testID to be used on tests." + }, + "position": { + "required": false, + "tsType": { + "name": "union", + "raw": "'leading' | 'trailing'", + "elements": [ + { + "name": "literal", + "value": "'leading'" + }, + { + "name": "literal", + "value": "'trailing'" + } + ] + }, + "description": "Checkbox control position.", "defaultValue": { - "value": "'card'", + "value": "'trailing'", "computed": false } }, - "accessible": { + "hitSlop": { "required": false, "tsType": { - "name": "boolean" + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" }, - "description": "Pass down accessible from card props to touchable" + "description": "Sets additional distance outside of element in which a press can be detected." } } }, "type": "component", "dependencies": [ - "src/components/Card/Card.tsx" - ] + "src/components/Checkbox/CheckboxItem.tsx" + ], + "group": "Checkbox" }, - "Card/CardActions": { - "filepath": "Card/CardActions.tsx", - "title": "Card.Actions", - "description": "A component to show a list of actions inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "link": "card-actions", + "Chip/Chip": { + "filepath": "Chip/Chip.tsx", + "title": "Chip", + "description": "Chips are compact elements that can represent inputs, attributes, or actions.\nThey can have an icon or avatar on the left, and a close button icon on the right.\nThey are typically used to:\n
    \n
  • Present multiple options
  • \n
  • Represent attributes active or chosen
  • \n
  • Present filter options
  • \n
  • Trigger actions related to primary content
  • \n
\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Chip } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}>Example Chip\n);\n\nexport default MyComponent;\n```", + "link": "chip", "data": { - "description": "A component to show a list of actions inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Button } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "Card.Actions", + "description": "Chips are compact elements that can represent inputs, attributes, or actions.\nThey can have an icon or avatar on the left, and a close button icon on the right.\nThey are typically used to:\n
    \n
  • Present multiple options
  • \n
  • Represent attributes active or chosen
  • \n
  • Present filter options
  • \n
  • Trigger actions related to primary content
  • \n
\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Chip } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}>Example Chip\n);\n\nexport default MyComponent;\n```", + "displayName": "Chip", "methods": [], "statics": [], "props": { + "mode": { + "required": false, + "tsType": { + "name": "union", + "raw": "'flat' | 'outlined'", + "elements": [ + { + "name": "literal", + "value": "'flat'" + }, + { + "name": "literal", + "value": "'outlined'" + } + ] + }, + "description": "Mode of the chip.\n- `flat` - flat chip without outline.\n- `outlined` - chip with an outline.", + "defaultValue": { + "value": "'flat'", + "computed": false + } + }, "children": { "required": true, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Items inside the `CardActions`." + "description": "Text content of the `Chip`." }, - "style": { + "icon": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "IconSource" }, - "description": "" + "description": "Icon to display for the `Chip`. Both icon and avatar cannot be specified." }, - "theme": { + "avatar": { "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Card/CardActions.tsx" - ], - "group": "Card" - }, - "Card/CardContent": { - "filepath": "Card/CardContent.tsx", - "title": "Card.Content", - "description": "A component to show content inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n Card title\n Card content\n \n \n);\n\nexport default MyComponent;\n```", - "link": "card-content", - "data": { - "description": "A component to show content inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n Card title\n Card content\n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "Card.Content", - "methods": [], - "statics": [], - "props": { - "children": { - "required": true, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Items inside the `Card.Content`." + "description": "Avatar to display for the `Chip`. Both icon and avatar cannot be specified." }, - "index": { + "closeIcon": { "required": false, "tsType": { - "name": "number" + "name": "IconSource" }, - "description": "@internal" + "description": "Icon to display as the close button for the `Chip`. The icon appears only when the onClose prop is specified." }, - "total": { + "selected": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "@internal" + "description": "Whether chip is selected.", + "defaultValue": { + "value": "false", + "computed": false + } }, - "siblings": { + "selectedColor": { "required": false, "tsType": { - "name": "Array", - "elements": [ - { - "name": "string" - } - ], - "raw": "Array" + "name": "ColorValue" }, - "description": "@internal" + "description": "Whether to style the chip color as selected.\nNote: With theme version 3 `selectedColor` doesn't apply to the `icon`.\n If you want specify custom color for the `icon`, render your own `Icon` component." }, - "style": { + "showSelectedOverlay": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Card/CardContent.tsx" - ], - "group": "Card" - }, - "Card/CardCover": { - "filepath": "Card/CardCover.tsx", - "title": "Card.Cover", - "description": "A component to show a cover image inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```\n\n@extends Image props https://reactnative.dev/docs/image#props", - "link": "card-cover", - "data": { - "description": "A component to show a cover image inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Card } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```\n\n@extends Image props https://reactnative.dev/docs/image#props", - "displayName": "Card.Cover", - "methods": [], - "statics": [], - "props": { - "index": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "@internal" - }, - "total": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "@internal" - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "" - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Card/CardCover.tsx" - ], - "group": "Card" - }, - "Card/CardTitle": { - "filepath": "Card/CardTitle.tsx", - "title": "Card.Title", - "description": "A component to show a title, subtitle and an avatar inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Card, IconButton } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n right={(props) => {}} />}\n />\n);\n\nexport default MyComponent;\n```", - "link": "card-title", - "data": { - "description": "A component to show a title, subtitle and an avatar inside a Card.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Avatar, Card, IconButton } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n right={(props) => {}} />}\n />\n);\n\nexport default MyComponent;\n```", - "displayName": "Card.Title", - "methods": [], - "statics": [], - "props": { - "title": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Text for the title. Note that this will only accept a string or ``-based node." - }, - "titleStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "boolean" }, - "description": "Style for the title." + "description": "@supported Available in v5.x with theme version 3\nWhether to display overlay on selected chip" }, - "titleNumberOfLines": { + "showSelectedCheck": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "Number of lines for the title.", + "description": "Whether to display default check icon on selected chip.\nNote: Check will not be shown if `icon` is specified. If specified, `icon` will be shown regardless of `selected`.", "defaultValue": { - "value": "1", + "value": "true", "computed": false } }, - "titleVariant": { + "disabled": { "required": false, "tsType": { - "name": "TypescaleKey" + "name": "boolean" }, - "description": "@supported Available in v5.x with theme version 3\n\nTitle text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "description": "Whether the chip is disabled. A disabled chip is greyed out and `onPress` is not called on touch.", "defaultValue": { - "value": "'bodyLarge'", + "value": "false", "computed": false } }, - "subtitle": { - "required": false, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Text for the subtitle. Note that this will only accept a string or ``-based node." - }, - "subtitleStyle": { + "background": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "PressableAndroidRippleConfig" }, - "description": "Style for the subtitle." + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, - "subtitleNumberOfLines": { + "aria-label": { "required": false, "tsType": { - "name": "number" + "name": "string" }, - "description": "Number of lines for the subtitle.", - "defaultValue": { - "value": "1", - "computed": false - } + "description": "Accessibility label for the chip. This is read by the screen reader when the user taps the chip." }, - "subtitleVariant": { + "closeIconAccessibilityLabel": { "required": false, "tsType": { - "name": "TypescaleKey" + "name": "string" }, - "description": "@supported Available in v5.x with theme version 3\n\nSubtitle text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "description": "Accessibility label for the close icon. This is read by the screen reader when the user taps the close icon.", "defaultValue": { - "value": "'bodyMedium'", + "value": "'Close'", "computed": false } }, - "left": { + "onPress": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: { size: number }) => React.ReactNode", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "signature", - "type": "object", - "raw": "{ size: number }", - "signature": { - "properties": [ - { - "key": "size", - "value": { - "name": "number", - "required": true - } - } - ] - } + "name": "GestureResponderEvent" } } ], "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "void" } } }, - "description": "Callback which returns a React element to display on the left side." + "description": "Function to execute on press." }, - "leftStyle": { + "onLongPress": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" } - ], - "raw": "StyleProp" + } }, - "description": "Style for the left element wrapper." + "description": "Function to execute on long press." }, - "right": { + "onPressIn": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(props: { size: number }) => React.ReactNode", + "raw": "(e: GestureResponderEvent) => void", "signature": { "arguments": [ { - "name": "props", + "name": "e", "type": { - "name": "signature", - "type": "object", - "raw": "{ size: number }", - "signature": { - "properties": [ - { - "key": "size", - "value": { - "name": "number", - "required": true - } - } - ] - } + "name": "GestureResponderEvent" } } ], "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "void" } } }, - "description": "Callback which returns a React element to display on the right side." + "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." }, - "rightStyle": { + "onPressOut": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" } - ], - "raw": "StyleProp" - }, - "description": "Style for the right element wrapper." - }, - "index": { - "required": false, - "tsType": { - "name": "number" + } }, - "description": "@internal" + "description": "Function to execute as soon as the touch is released even before onPress." }, - "total": { + "onClose": { "required": false, "tsType": { - "name": "number" + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + } }, - "description": "@internal" + "description": "Function to execute on close button press. The close button appears only when this prop is specified." }, - "titleMaxFontSizeMultiplier": { + "delayLongPress": { "required": false, "tsType": { "name": "number" }, - "description": "Specifies the largest possible scale a title font can reach." + "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." }, - "subtitleMaxFontSizeMultiplier": { + "compact": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "Specifies the largest possible scale a subtitle font can reach." + "description": "@supported Available in v5.x with theme version 3\nSets smaller horizontal paddings `12dp` around label, when there is only label." }, - "style": { + "elevated": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "@supported Available in v5.x with theme version 3\nWhether chip should have the elevation.", + "defaultValue": { + "value": "false", + "computed": false + } + }, + "textStyle": { "required": false, "tsType": { "name": "StyleProp", "elements": [ { - "name": "ViewStyle" + "name": "TextStyle" } ], - "raw": "StyleProp" + "raw": "StyleProp" }, - "description": "" + "description": "Style of chip's text" }, - "theme": { + "style": { "required": false, "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Card/CardTitle.tsx" - ], - "group": "Card" - }, - "Checkbox/Checkbox": { - "filepath": "Checkbox/Checkbox.tsx", - "title": "Checkbox", - "description": "Checkboxes allow the selection of multiple options from a set.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [checked, setChecked] = React.useState(false);\n\n return (\n {\n setChecked(!checked);\n }}\n />\n );\n};\n\nexport default MyComponent;\n```", - "link": "checkbox", - "data": { - "description": "Checkboxes allow the selection of multiple options from a set.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [checked, setChecked] = React.useState(false);\n\n return (\n {\n setChecked(!checked);\n }}\n />\n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Checkbox", - "methods": [], - "statics": [], - "props": { - "status": { - "required": true, - "tsType": { - "name": "union", - "raw": "'checked' | 'unchecked' | 'indeterminate'", + "name": "Animated.WithAnimatedValue", "elements": [ { - "name": "literal", - "value": "'checked'" - }, - { - "name": "literal", - "value": "'unchecked'" - }, - { - "name": "literal", - "value": "'indeterminate'" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" } - ] + ], + "raw": "Animated.WithAnimatedValue>" }, - "description": "Status of checkbox." + "description": "" }, - "disabled": { + "hitSlop": { "required": false, "tsType": { - "name": "boolean" + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" }, - "description": "Whether checkbox is disabled." + "description": "Sets additional distance outside of element in which a press can be detected." }, - "onPress": { + "theme": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } + "name": "ThemeProp" }, - "description": "Function to execute on press." + "description": "" }, - "uncheckedColor": { + "testID": { "required": false, "tsType": { - "name": "ColorValue" + "name": "string" }, - "description": "Custom color for unchecked checkbox." + "description": "Pass down testID from chip props to touchable for Detox tests.", + "defaultValue": { + "value": "'chip'", + "computed": false + } }, - "color": { + "ellipsizeMode": { "required": false, "tsType": { - "name": "ColorValue" + "name": "EllipsizeProp" }, - "description": "Custom color for checkbox." + "description": "Ellipsize Mode for the children text" }, - "error": { + "maxFontSizeMultiplier": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether the checkbox is in an error state. When true, the outline\n(unchecked) and container (selected) use `theme.colors.error`.\n`disabled` and explicit `color`/`uncheckedColor` overrides take\nprecedence." + "description": "Specifies the largest possible scale a text font can reach." }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" + "role": { + "defaultValue": { + "value": "'button'", + "computed": false }, - "description": "" - }, - "testID": { "required": false, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Chip/Chip.tsx" + ] + }, + "DataTable/DataTable": { + "filepath": "DataTable/DataTable.tsx", + "title": "DataTable", + "description": "Data tables allow displaying sets of data.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPageList] = React.useState([2, 3, 4]);\n const [itemsPerPage, onItemsPerPageChange] = React.useState(\n numberOfItemsPerPageList[0]\n );\n\n const [items] = React.useState([\n {\n key: 1,\n name: 'Cupcake',\n calories: 356,\n fat: 16,\n },\n {\n key: 2,\n name: 'Eclair',\n calories: 262,\n fat: 16,\n },\n {\n key: 3,\n name: 'Frozen yogurt',\n calories: 159,\n fat: 6,\n },\n {\n key: 4,\n name: 'Gingerbread',\n calories: 305,\n fat: 3.7,\n },\n ]);\n\n const from = page * itemsPerPage;\n const to = Math.min((page + 1) * itemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [itemsPerPage]);\n\n return (\n \n \n Dessert\n Calories\n Fat\n \n\n {items.slice(from, to).map((item) => (\n \n {item.name}\n {item.calories}\n {item.fat}\n \n ))}\n\n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={itemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n showFastPaginationControls\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "link": "data-table", + "data": { + "description": "Data tables allow displaying sets of data.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPageList] = React.useState([2, 3, 4]);\n const [itemsPerPage, onItemsPerPageChange] = React.useState(\n numberOfItemsPerPageList[0]\n );\n\n const [items] = React.useState([\n {\n key: 1,\n name: 'Cupcake',\n calories: 356,\n fat: 16,\n },\n {\n key: 2,\n name: 'Eclair',\n calories: 262,\n fat: 16,\n },\n {\n key: 3,\n name: 'Frozen yogurt',\n calories: 159,\n fat: 6,\n },\n {\n key: 4,\n name: 'Gingerbread',\n calories: 305,\n fat: 3.7,\n },\n ]);\n\n const from = page * itemsPerPage;\n const to = Math.min((page + 1) * itemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [itemsPerPage]);\n\n return (\n \n \n Dessert\n Calories\n Fat\n \n\n {items.slice(from, to).map((item) => (\n \n {item.name}\n {item.calories}\n {item.fat}\n \n ))}\n\n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={itemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n showFastPaginationControls\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "DataTable", + "methods": [], + "statics": [], + "props": { + "children": { + "required": true, "tsType": { - "name": "string" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "testID to be used on tests." + "description": "Content of the `DataTable`." }, "style": { "required": false, @@ -4077,61 +3944,40 @@ ], "raw": "StyleProp" }, - "description": "Custom style to override the default tap target. Passed through to\nthe underlying `TouchableRipple`." + "description": "" } } }, "type": "component", "dependencies": [ - "src/components/Checkbox/Checkbox.tsx" + "src/components/DataTable/DataTable.tsx" ] }, - "Checkbox/CheckboxItem": { - "filepath": "Checkbox/CheckboxItem.tsx", - "title": "Checkbox.Item", - "description": "Checkbox.Item allows you to press the whole row (item) instead of only the Checkbox.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```", - "link": "checkbox-item", + "DataTable/DataTableCell": { + "filepath": "DataTable/DataTableCell.tsx", + "title": "DataTable.Cell", + "description": "A component to show a single cell inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\nIf you want to support multiline text, please use View instead, as multiline text doesn't comply with\nMD Guidelines (https://github.com/callstack/react-native-paper/issues/2381).\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "link": "data-table-cell", "data": { - "description": "Checkbox.Item allows you to press the whole row (item) instead of only the Checkbox.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Checkbox } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "Checkbox.Item", + "description": "A component to show a single cell inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\nIf you want to support multiline text, please use View instead, as multiline text doesn't comply with\nMD Guidelines (https://github.com/callstack/react-native-paper/issues/2381).\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "displayName": "DataTable.Cell", "methods": [], "statics": [], "props": { - "status": { + "children": { "required": true, "tsType": { - "name": "union", - "raw": "'checked' | 'unchecked' | 'indeterminate'", - "elements": [ - { - "name": "literal", - "value": "'checked'" - }, - { - "name": "literal", - "value": "'unchecked'" - }, - { - "name": "literal", - "value": "'indeterminate'" - } - ] + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Status of checkbox." + "description": "Content of the `DataTableCell`." }, - "disabled": { + "numeric": { "required": false, "tsType": { "name": "boolean" }, - "description": "Whether checkbox is disabled." - }, - "label": { - "required": true, - "tsType": { - "name": "string" - }, - "description": "Label to be displayed on the item." + "description": "Align the text to the right. Generally monetary or number fields are aligned to right." }, "onPress": { "required": false, @@ -4155,59 +4001,72 @@ }, "description": "Function to execute on press." }, - "onLongPress": { + "style": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Function to execute on long press." + "description": "" }, - "background": { + "textStyle": { "required": false, "tsType": { - "name": "PressableAndroidRippleConfig" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + "description": "Text content style of the `DataTableCell`." }, - "aria-label": { + "maxFontSizeMultiplier": { "required": false, "tsType": { - "name": "string" + "name": "number" }, - "description": "Accessibility label for the touchable. This is read by the screen reader when the user taps the touchable.", - "defaultValue": { - "value": "label", - "computed": true - } + "description": "Specifies the largest possible scale a text font can reach." }, - "uncheckedColor": { + "testID": { "required": false, "tsType": { "name": "string" }, - "description": "Custom color for unchecked checkbox." - }, - "color": { - "required": false, + "description": "testID to be used on tests." + } + } + }, + "type": "component", + "dependencies": [ + "src/components/DataTable/DataTableCell.tsx" + ], + "group": "DataTable" + }, + "DataTable/DataTableHeader": { + "filepath": "DataTable/DataTableHeader.tsx", + "title": "DataTable.Header", + "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", + "link": "data-table-header", + "data": { + "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "DataTable.Header", + "methods": [], + "statics": [], + "props": { + "children": { + "required": true, "tsType": { - "name": "string" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Custom color for checkbox." + "description": "Content of the `DataTableHeader`." }, "style": { "required": false, @@ -4220,40 +4079,78 @@ ], "raw": "StyleProp" }, - "description": "Additional styles for container View." + "description": "" }, - "labelMaxFontSizeMultiplier": { + "theme": { "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/DataTable/DataTableHeader.tsx" + ], + "group": "DataTable" + }, + "DataTable/DataTablePagination": { + "filepath": "DataTable/DataTablePagination.tsx", + "title": "DataTable.Pagination", + "description": "A component to show pagination for data table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst numberOfItemsPerPageList = [2, 3, 4];\n\nconst items = [\n {\n key: 1,\n name: 'Page 1',\n },\n {\n key: 2,\n name: 'Page 2',\n },\n {\n key: 3,\n name: 'Page 3',\n },\n];\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPage, onItemsPerPageChange] = React.useState(numberOfItemsPerPageList[0]);\n const from = page * numberOfItemsPerPage;\n const to = Math.min((page + 1) * numberOfItemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [numberOfItemsPerPage]);\n\n return (\n \n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n showFastPaginationControls\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={numberOfItemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "link": "data-table-pagination", + "data": { + "description": "A component to show pagination for data table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst numberOfItemsPerPageList = [2, 3, 4];\n\nconst items = [\n {\n key: 1,\n name: 'Page 1',\n },\n {\n key: 2,\n name: 'Page 2',\n },\n {\n key: 3,\n name: 'Page 3',\n },\n];\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPage, onItemsPerPageChange] = React.useState(numberOfItemsPerPageList[0]);\n const from = page * numberOfItemsPerPage;\n const to = Math.min((page + 1) * numberOfItemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [numberOfItemsPerPage]);\n\n return (\n \n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n showFastPaginationControls\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={numberOfItemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "DataTable.Pagination", + "methods": [], + "statics": [], + "props": { + "page": { + "required": true, "tsType": { "name": "number" }, - "description": "Specifies the largest possible scale a label font can reach.", - "defaultValue": { - "value": "1.5", - "computed": false - } + "description": "The currently visible page (starting with 0)." }, - "labelStyle": { - "required": false, + "numberOfPages": { + "required": true, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" + "name": "number" + }, + "description": "The total number of pages." + }, + "onPageChange": { + "required": true, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(page: number) => void", + "signature": { + "arguments": [ + { + "name": "page", + "type": { + "name": "number" + } + } + ], + "return": { + "name": "void" } - ], - "raw": "StyleProp" + } }, - "description": "Style that is passed to Label element." + "description": "Function to execute on page change." }, - "labelVariant": { + "showFastPaginationControls": { "required": false, "tsType": { - "name": "TypescaleKey" + "name": "boolean" }, - "description": "@supported Available in v5.x with theme version 3\n\nLabel text variant defines appropriate text styles for type role and its size.\nAvailable variants:\n\n Display: `displayLarge`, `displayMedium`, `displaySmall`\n\n Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`\n\n Title: `titleLarge`, `titleMedium`, `titleSmall`\n\n Label: `labelLarge`, `labelMedium`, `labelSmall`\n\n Body: `bodyLarge`, `bodyMedium`, `bodySmall`", + "description": "Whether to show fast forward and fast rewind buttons in pagination. False by default.", "defaultValue": { - "value": "'bodyLarge'", + "value": "false", "computed": false } }, @@ -4264,183 +4161,228 @@ }, "description": "" }, - "testID": { + "numberOfItemsPerPage": { "required": false, "tsType": { - "name": "string" + "name": "number" }, - "description": "testID to be used on tests." + "description": "The current number of rows per page." }, - "position": { + "numberOfItemsPerPageList": { "required": false, "tsType": { - "name": "union", - "raw": "'leading' | 'trailing'", + "name": "Array", "elements": [ { - "name": "literal", - "value": "'leading'" - }, - { - "name": "literal", - "value": "'trailing'" + "name": "number" } - ] + ], + "raw": "Array" }, - "description": "Checkbox control position.", - "defaultValue": { - "value": "'trailing'", - "computed": false - } + "description": "Options for a number of rows per page to choose from." }, - "hitSlop": { - "required": false, - "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" - }, - "description": "Sets additional distance outside of element in which a press can be detected." - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Checkbox/CheckboxItem.tsx" - ], - "group": "Checkbox" - }, - "Chip/Chip": { - "filepath": "Chip/Chip.tsx", - "title": "Chip", - "description": "Chips are compact elements that can represent inputs, attributes, or actions.\nThey can have an icon or avatar on the left, and a close button icon on the right.\nThey are typically used to:\n
    \n
  • Present multiple options
  • \n
  • Represent attributes active or chosen
  • \n
  • Present filter options
  • \n
  • Trigger actions related to primary content
  • \n
\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Chip } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}>Example Chip\n);\n\nexport default MyComponent;\n```", - "link": "chip", - "data": { - "description": "Chips are compact elements that can represent inputs, attributes, or actions.\nThey can have an icon or avatar on the left, and a close button icon on the right.\nThey are typically used to:\n
    \n
  • Present multiple options
  • \n
  • Represent attributes active or chosen
  • \n
  • Present filter options
  • \n
  • Trigger actions related to primary content
  • \n
\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Chip } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}>Example Chip\n);\n\nexport default MyComponent;\n```", - "displayName": "Chip", - "methods": [], - "statics": [], - "props": { - "mode": { + "onItemsPerPageChange": { "required": false, "tsType": { - "name": "union", - "raw": "'flat' | 'outlined'", - "elements": [ - { - "name": "literal", - "value": "'flat'" - }, - { - "name": "literal", - "value": "'outlined'" + "name": "signature", + "type": "function", + "raw": "(numberOfItemsPerPage: number) => void", + "signature": { + "arguments": [ + { + "name": "numberOfItemsPerPage", + "type": { + "name": "number" + } + } + ], + "return": { + "name": "void" } - ] + } }, - "description": "Mode of the chip.\n- `flat` - flat chip without outline.\n- `outlined` - chip with an outline.", - "defaultValue": { - "value": "'flat'", - "computed": false - } + "description": "The function to set the number of rows per page." }, - "children": { - "required": true, + "selectPageDropdownLabel": { + "required": false, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Text content of the `Chip`." + "description": "Label text for select page dropdown to display." }, - "icon": { + "selectPageDropdownAccessibilityLabel": { "required": false, "tsType": { - "name": "IconSource" + "name": "string" }, - "description": "Icon to display for the `Chip`. Both icon and avatar cannot be specified." + "description": "AccessibilityLabel for `selectPageDropdownLabel`." }, - "avatar": { + "label": { "required": false, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Avatar to display for the `Chip`. Both icon and avatar cannot be specified." + "description": "Label text to display which indicates current pagination." }, - "closeIcon": { + "aria-label": { "required": false, "tsType": { - "name": "IconSource" + "name": "string" }, - "description": "Icon to display as the close button for the `Chip`. The icon appears only when the onClose prop is specified." + "description": "AccessibilityLabel for `label`." }, - "selected": { + "style": { "required": false, "tsType": { - "name": "boolean" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "Whether chip is selected.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/DataTable/DataTablePagination.tsx" + ], + "group": "DataTable" + }, + "DataTable/DataTableRow": { + "filepath": "DataTable/DataTableRow.tsx", + "title": "DataTable.Row", + "description": "A component to show a single row inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "link": "data-table-row", + "data": { + "description": "A component to show a single row inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "displayName": "DataTable.Row", + "methods": [], + "statics": [], + "props": { + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Content of the `DataTableRow`." }, - "selectedColor": { + "onPress": { "required": false, "tsType": { - "name": "ColorValue" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" + } + } }, - "description": "Whether to style the chip color as selected.\nNote: With theme version 3 `selectedColor` doesn't apply to the `icon`.\n If you want specify custom color for the `icon`, render your own `Icon` component." + "description": "Function to execute on press." }, - "showSelectedOverlay": { + "style": { "required": false, "tsType": { - "name": "boolean" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "@supported Available in v5.x with theme version 3\nWhether to display overlay on selected chip" + "description": "" }, - "showSelectedCheck": { + "theme": { "required": false, "tsType": { - "name": "boolean" + "name": "ThemeProp" }, - "description": "Whether to display default check icon on selected chip.\nNote: Check will not be shown if `icon` is specified. If specified, `icon` will be shown regardless of `selected`.", - "defaultValue": { - "value": "true", - "computed": false - } + "description": "" }, - "disabled": { + "pointerEvents": { "required": false, "tsType": { - "name": "boolean" + "name": "ViewProps['pointerEvents']", + "raw": "ViewProps['pointerEvents']" }, - "description": "Whether the chip is disabled. A disabled chip is greyed out and `onPress` is not called on touch.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "`pointerEvents` passed to the `View` container, which is wrapping children within `TouchableRipple`." + } + } + }, + "type": "component", + "dependencies": [ + "src/components/DataTable/DataTableRow.tsx" + ], + "group": "DataTable" + }, + "DataTable/DataTableTitle": { + "filepath": "DataTable/DataTableTitle.tsx", + "title": "DataTable.Title", + "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", + "link": "data-table-title", + "data": { + "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "DataTable.Title", + "methods": [], + "statics": [], + "props": { + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Text content of the `DataTableTitle`." }, - "background": { + "numeric": { "required": false, "tsType": { - "name": "PressableAndroidRippleConfig" + "name": "boolean" }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + "description": "Align the text to the right. Generally monetary or number fields are aligned to right." }, - "aria-label": { + "sortDirection": { "required": false, "tsType": { - "name": "string" + "name": "union", + "raw": "'ascending' | 'descending'", + "elements": [ + { + "name": "literal", + "value": "'ascending'" + }, + { + "name": "literal", + "value": "'descending'" + } + ] }, - "description": "Accessibility label for the chip. This is read by the screen reader when the user taps the chip." + "description": "Direction of sorting. An arrow indicating the direction is displayed when this is given." }, - "closeIconAccessibilityLabel": { + "numberOfLines": { "required": false, "tsType": { - "name": "string" + "name": "number" }, - "description": "Accessibility label for the close icon. This is read by the screen reader when the user taps the close icon.", + "description": "The number of lines to show.", "defaultValue": { - "value": "'Close'", + "value": "1", "computed": false } }, @@ -4466,117 +4408,120 @@ }, "description": "Function to execute on press." }, - "onLongPress": { + "style": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "() => void", - "signature": { - "arguments": [], - "return": { - "name": "void" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Function to execute on long press." + "description": "" }, - "onPressIn": { + "textStyle": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" } - } + ], + "raw": "StyleProp" }, - "description": "Function to execute as soon as the touchable element is pressed and invoked even before onPress." + "description": "Text content style of the `DataTableTitle`." }, - "onPressOut": { + "maxFontSizeMultiplier": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } + "name": "number" }, - "description": "Function to execute as soon as the touch is released even before onPress." + "description": "Specifies the largest possible scale a text font can reach." }, - "onClose": { + "theme": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "() => void", - "signature": { - "arguments": [], - "return": { - "name": "void" - } - } + "name": "ThemeProp" }, - "description": "Function to execute on close button press. The close button appears only when this prop is specified." - }, - "delayLongPress": { + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/DataTable/DataTableTitle.tsx" + ], + "group": "DataTable" + }, + "Dialog/Dialog": { + "filepath": "Dialog/Dialog.tsx", + "title": "Dialog", + "description": "Dialogs inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks.\nTo render the `Dialog` above other components, you'll need to wrap it with the [`Portal`](../Portal) component.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Dialog, Portal, PaperProvider, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showDialog = () => setVisible(true);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n Alert\n \n This is simple dialog\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "dialog", + "data": { + "description": "Dialogs inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks.\nTo render the `Dialog` above other components, you'll need to wrap it with the [`Portal`](../Portal) component.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Dialog, Portal, PaperProvider, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showDialog = () => setVisible(true);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n Alert\n \n This is simple dialog\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Dialog", + "methods": [], + "statics": [], + "props": { + "dismissable": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." + "description": "Determines whether clicking outside the dialog dismiss it.", + "defaultValue": { + "value": "true", + "computed": false + } }, - "compact": { + "dismissableBackButton": { "required": false, "tsType": { "name": "boolean" }, - "description": "@supported Available in v5.x with theme version 3\nSets smaller horizontal paddings `12dp` around label, when there is only label." + "description": "Determines whether clicking Android hardware back button dismiss dialog.", + "defaultValue": { + "value": "dismissable", + "computed": true + } }, - "elevated": { + "onDismiss": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + } + }, + "description": "Callback that is called when the user dismisses the dialog." + }, + "visible": { "required": false, "tsType": { "name": "boolean" }, - "description": "@supported Available in v5.x with theme version 3\nWhether chip should have the elevation.", + "description": "Determines Whether the dialog is visible.", "defaultValue": { "value": "false", "computed": false } }, - "textStyle": { - "required": false, + "children": { + "required": true, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Style of chip's text" + "description": "Content of the `Dialog`." }, "style": { "required": false, @@ -4597,14 +4542,6 @@ }, "description": "" }, - "hitSlop": { - "required": false, - "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" - }, - "description": "Sets additional distance outside of element in which a press can be detected." - }, "theme": { "required": false, "tsType": { @@ -4617,49 +4554,23 @@ "tsType": { "name": "string" }, - "description": "Pass down testID from chip props to touchable for Detox tests.", - "defaultValue": { - "value": "'chip'", - "computed": false - } - }, - "ellipsizeMode": { - "required": false, - "tsType": { - "name": "EllipsizeProp" - }, - "description": "Ellipsize Mode for the children text" - }, - "maxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a text font can reach." - }, - "role": { - "defaultValue": { - "value": "'button'", - "computed": false - }, - "required": false, - "description": "" + "description": "testID to be used on tests." } } }, "type": "component", "dependencies": [ - "src/components/Chip/Chip.tsx" + "src/components/Dialog/Dialog.tsx" ] }, - "DataTable/DataTable": { - "filepath": "DataTable/DataTable.tsx", - "title": "DataTable", - "description": "Data tables allow displaying sets of data.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPageList] = React.useState([2, 3, 4]);\n const [itemsPerPage, onItemsPerPageChange] = React.useState(\n numberOfItemsPerPageList[0]\n );\n\n const [items] = React.useState([\n {\n key: 1,\n name: 'Cupcake',\n calories: 356,\n fat: 16,\n },\n {\n key: 2,\n name: 'Eclair',\n calories: 262,\n fat: 16,\n },\n {\n key: 3,\n name: 'Frozen yogurt',\n calories: 159,\n fat: 6,\n },\n {\n key: 4,\n name: 'Gingerbread',\n calories: 305,\n fat: 3.7,\n },\n ]);\n\n const from = page * itemsPerPage;\n const to = Math.min((page + 1) * itemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [itemsPerPage]);\n\n return (\n \n \n Dessert\n Calories\n Fat\n \n\n {items.slice(from, to).map((item) => (\n \n {item.name}\n {item.calories}\n {item.fat}\n \n ))}\n\n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={itemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n showFastPaginationControls\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "link": "data-table", + "Dialog/DialogActions": { + "filepath": "Dialog/DialogActions.tsx", + "title": "Dialog.Actions", + "description": "A component to show a list of actions in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button, Dialog, Portal } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "dialog-actions", "data": { - "description": "Data tables allow displaying sets of data.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPageList] = React.useState([2, 3, 4]);\n const [itemsPerPage, onItemsPerPageChange] = React.useState(\n numberOfItemsPerPageList[0]\n );\n\n const [items] = React.useState([\n {\n key: 1,\n name: 'Cupcake',\n calories: 356,\n fat: 16,\n },\n {\n key: 2,\n name: 'Eclair',\n calories: 262,\n fat: 16,\n },\n {\n key: 3,\n name: 'Frozen yogurt',\n calories: 159,\n fat: 6,\n },\n {\n key: 4,\n name: 'Gingerbread',\n calories: 305,\n fat: 3.7,\n },\n ]);\n\n const from = page * itemsPerPage;\n const to = Math.min((page + 1) * itemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [itemsPerPage]);\n\n return (\n \n \n Dessert\n Calories\n Fat\n \n\n {items.slice(from, to).map((item) => (\n \n {item.name}\n {item.calories}\n {item.fat}\n \n ))}\n\n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={itemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n showFastPaginationControls\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "DataTable", + "description": "A component to show a list of actions in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button, Dialog, Portal } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Dialog.Actions", "methods": [], "statics": [], "props": { @@ -4669,7 +4580,7 @@ "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Content of the `DataTable`." + "description": "Content of the `DialogActions`." }, "style": { "required": false, @@ -4683,22 +4594,30 @@ "raw": "StyleProp" }, "description": "" + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" } } }, "type": "component", "dependencies": [ - "src/components/DataTable/DataTable.tsx" - ] + "src/components/Dialog/DialogActions.tsx" + ], + "group": "Dialog" }, - "DataTable/DataTableCell": { - "filepath": "DataTable/DataTableCell.tsx", - "title": "DataTable.Cell", - "description": "A component to show a single cell inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\nIf you want to support multiline text, please use View instead, as multiline text doesn't comply with\nMD Guidelines (https://github.com/callstack/react-native-paper/issues/2381).\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "link": "data-table-cell", + "Dialog/DialogContent": { + "filepath": "Dialog/DialogContent.tsx", + "title": "Dialog.Content", + "description": "A component to show content in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "dialog-content", "data": { - "description": "A component to show a single cell inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\nIf you want to support multiline text, please use View instead, as multiline text doesn't comply with\nMD Guidelines (https://github.com/callstack/react-native-paper/issues/2381).\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "displayName": "DataTable.Cell", + "description": "A component to show content in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Dialog.Content", "methods": [], "statics": [], "props": { @@ -4708,36 +4627,7 @@ "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Content of the `DataTableCell`." - }, - "numeric": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Align the text to the right. Generally monetary or number fields are aligned to right." - }, - "onPress": { - "required": false, - "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } - }, - "description": "Function to execute on press." + "description": "Content of the `DialogContent`." }, "style": { "required": false, @@ -4751,50 +4641,74 @@ "raw": "StyleProp" }, "description": "" - }, - "textStyle": { + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Dialog/DialogContent.tsx" + ], + "group": "Dialog" + }, + "Dialog/DialogIcon": { + "filepath": "Dialog/DialogIcon.tsx", + "title": "Dialog.Icon", + "description": "@supported Available in v5.x with theme version 3\nA component to show an icon in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nconst styles = StyleSheet.create({\n title: {\n textAlign: 'center',\n },\n})\n\nexport default MyComponent;\n```", + "link": "dialog-icon", + "data": { + "description": "@supported Available in v5.x with theme version 3\nA component to show an icon in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nconst styles = StyleSheet.create({\n title: {\n textAlign: 'center',\n },\n})\n\nexport default MyComponent;\n```", + "displayName": "Dialog.Icon", + "methods": [], + "statics": [], + "props": { + "color": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "ColorValue" }, - "description": "Text content style of the `DataTableCell`." + "description": "Custom color for action icon." }, - "maxFontSizeMultiplier": { + "icon": { + "required": true, + "tsType": { + "name": "IconSource" + }, + "description": "Name of the icon to show." + }, + "size": { "required": false, "tsType": { "name": "number" }, - "description": "Specifies the largest possible scale a text font can reach." + "description": "Optional icon size.", + "defaultValue": { + "value": "24", + "computed": false + } }, - "testID": { + "theme": { "required": false, "tsType": { - "name": "string" + "name": "ThemeProp" }, - "description": "testID to be used on tests." + "description": "" } } }, "type": "component", "dependencies": [ - "src/components/DataTable/DataTableCell.tsx" + "src/components/Dialog/DialogIcon.tsx" ], - "group": "DataTable" + "group": "Dialog" }, - "DataTable/DataTableHeader": { - "filepath": "DataTable/DataTableHeader.tsx", - "title": "DataTable.Header", - "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", - "link": "data-table-header", + "Dialog/DialogScrollArea": { + "filepath": "Dialog/DialogScrollArea.tsx", + "title": "Dialog.ScrollArea", + "description": "A component to show a scrollable content in a Dialog. The component only provides appropriate styling.\nFor the scrollable content you can use `ScrollView`, `FlatList` etc. depending on your requirement.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { ScrollView } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n This is a scrollable area\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "dialog-scroll-area", "data": { - "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "DataTable.Header", + "description": "A component to show a scrollable content in a Dialog. The component only provides appropriate styling.\nFor the scrollable content you can use `ScrollView`, `FlatList` etc. depending on your requirement.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { ScrollView } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n This is a scrollable area\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Dialog.ScrollArea", "methods": [], "statics": [], "props": { @@ -4804,7 +4718,7 @@ "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Content of the `DataTableHeader`." + "description": "Content of the `DialogScrollArea`." }, "style": { "required": false, @@ -4830,186 +4744,192 @@ }, "type": "component", "dependencies": [ - "src/components/DataTable/DataTableHeader.tsx" + "src/components/Dialog/DialogScrollArea.tsx" ], - "group": "DataTable" + "group": "Dialog" }, - "DataTable/DataTablePagination": { - "filepath": "DataTable/DataTablePagination.tsx", - "title": "DataTable.Pagination", - "description": "A component to show pagination for data table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst numberOfItemsPerPageList = [2, 3, 4];\n\nconst items = [\n {\n key: 1,\n name: 'Page 1',\n },\n {\n key: 2,\n name: 'Page 2',\n },\n {\n key: 3,\n name: 'Page 3',\n },\n];\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPage, onItemsPerPageChange] = React.useState(numberOfItemsPerPageList[0]);\n const from = page * numberOfItemsPerPage;\n const to = Math.min((page + 1) * numberOfItemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [numberOfItemsPerPage]);\n\n return (\n \n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n showFastPaginationControls\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={numberOfItemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "link": "data-table-pagination", + "Dialog/DialogTitle": { + "filepath": "Dialog/DialogTitle.tsx", + "title": "Dialog.Title", + "description": "A component to show a title in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "dialog-title", "data": { - "description": "A component to show pagination for data table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst numberOfItemsPerPageList = [2, 3, 4];\n\nconst items = [\n {\n key: 1,\n name: 'Page 1',\n },\n {\n key: 2,\n name: 'Page 2',\n },\n {\n key: 3,\n name: 'Page 3',\n },\n];\n\nconst MyComponent = () => {\n const [page, setPage] = React.useState(0);\n const [numberOfItemsPerPage, onItemsPerPageChange] = React.useState(numberOfItemsPerPageList[0]);\n const from = page * numberOfItemsPerPage;\n const to = Math.min((page + 1) * numberOfItemsPerPage, items.length);\n\n React.useEffect(() => {\n setPage(0);\n }, [numberOfItemsPerPage]);\n\n return (\n \n setPage(page)}\n label={`${from + 1}-${to} of ${items.length}`}\n showFastPaginationControls\n numberOfItemsPerPageList={numberOfItemsPerPageList}\n numberOfItemsPerPage={numberOfItemsPerPage}\n onItemsPerPageChange={onItemsPerPageChange}\n selectPageDropdownLabel={'Rows per page'}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "DataTable.Pagination", + "description": "A component to show a title in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Dialog.Title", "methods": [], "statics": [], "props": { - "page": { + "children": { "required": true, "tsType": { - "name": "number" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "The currently visible page (starting with 0)." + "description": "Title text for the `DialogTitle`." }, - "numberOfPages": { - "required": true, + "style": { + "required": false, "tsType": { - "name": "number" - }, - "description": "The total number of pages." + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" + }, + "description": "" }, - "onPageChange": { - "required": true, + "theme": { + "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(page: number) => void", - "signature": { - "arguments": [ - { - "name": "page", - "type": { - "name": "number" - } - } - ], - "return": { - "name": "void" - } - } + "name": "ThemeProp" }, - "description": "Function to execute on page change." + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Dialog/DialogTitle.tsx" + ], + "group": "Dialog" + }, + "Divider": { + "filepath": "Divider.tsx", + "title": "Divider", + "description": "A divider is a thin, lightweight separator that groups content in lists and page layouts.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Divider, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Lemon\n \n Mango\n \n \n);\n\nexport default MyComponent;\n```", + "link": "divider", + "data": { + "description": "A divider is a thin, lightweight separator that groups content in lists and page layouts.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Divider, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Lemon\n \n Mango\n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "Divider", + "methods": [], + "statics": [], + "props": { + "leftInset": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "@renamed Renamed from 'inset' to 'leftInset` in v5.x\nWhether divider has a left inset." }, - "showFastPaginationControls": { + "horizontalInset": { "required": false, "tsType": { "name": "boolean" }, - "description": "Whether to show fast forward and fast rewind buttons in pagination. False by default.", + "description": "@supported Available in v5.x with theme version 3\n Whether divider has a horizontal inset on both sides.", "defaultValue": { "value": "false", "computed": false } }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - }, - "numberOfItemsPerPage": { + "bold": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "The current number of rows per page." + "description": "@supported Available in v5.x with theme version 3\n Whether divider should be bolded.", + "defaultValue": { + "value": "false", + "computed": false + } }, - "numberOfItemsPerPageList": { + "style": { "required": false, "tsType": { - "name": "Array", + "name": "StyleProp", "elements": [ { - "name": "number" + "name": "ViewStyle" } ], - "raw": "Array" + "raw": "StyleProp" }, - "description": "Options for a number of rows per page to choose from." + "description": "" }, - "onItemsPerPageChange": { + "theme": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(numberOfItemsPerPage: number) => void", - "signature": { - "arguments": [ - { - "name": "numberOfItemsPerPage", - "type": { - "name": "number" - } - } - ], - "return": { - "name": "void" - } - } + "name": "ThemeProp" }, - "description": "The function to set the number of rows per page." - }, - "selectPageDropdownLabel": { + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Divider.tsx" + ] + }, + "Drawer/DrawerCollapsedItem": { + "filepath": "Drawer/DrawerCollapsedItem.tsx", + "title": "Drawer.CollapsedItem", + "description": "Note: Available in v5.x with theme version 3\n\nCollapsed component used to show an action item with an icon and optionally label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "link": "drawer-collapsed-item", + "data": { + "description": "Note: Available in v5.x with theme version 3\n\nCollapsed component used to show an action item with an icon and optionally label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "displayName": "Drawer.CollapsedItem", + "methods": [], + "statics": [], + "props": { + "label": { "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "string" }, - "description": "Label text for select page dropdown to display." + "description": "The label text of the item." }, - "selectPageDropdownAccessibilityLabel": { + "badge": { "required": false, "tsType": { - "name": "string" + "name": "union", + "raw": "string | number | boolean", + "elements": [ + { + "name": "string" + }, + { + "name": "number" + }, + { + "name": "boolean" + } + ] }, - "description": "AccessibilityLabel for `selectPageDropdownLabel`." + "description": "Badge to show on the icon, can be `true` to show a dot, `string` or `number` to show text.", + "defaultValue": { + "value": "false", + "computed": false + } }, - "label": { + "disabled": { "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "boolean" }, - "description": "Label text to display which indicates current pagination." + "description": "Whether the item is disabled." }, - "aria-label": { + "focusedIcon": { "required": false, "tsType": { - "name": "string" + "name": "IconSource" }, - "description": "AccessibilityLabel for `label`." + "description": "@renamed Renamed from 'icon' to 'focusedIcon' in v5.x\nIcon to use as the focused destination icon, can be a string, an image source or a react component" }, - "style": { + "unfocusedIcon": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "IconSource" }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/DataTable/DataTablePagination.tsx" - ], - "group": "DataTable" - }, - "DataTable/DataTableRow": { - "filepath": "DataTable/DataTableRow.tsx", - "title": "DataTable.Row", - "description": "A component to show a single row inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "link": "data-table-row", - "data": { - "description": "A component to show a single row inside of a table.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n 1\n 2\n 3\n 4\n \n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "displayName": "DataTable.Row", - "methods": [], - "statics": [], - "props": { - "children": { - "required": true, + "description": "@renamed Renamed from 'icon' to 'focusedIcon' in v5.x\nIcon to use as the unfocused destination icon, can be a string, an image source or a react component" + }, + "active": { + "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "boolean" }, - "description": "Content of the `DataTableRow`." + "description": "Whether to highlight the drawer item as active." }, "onPress": { "required": false, @@ -5033,6 +4953,20 @@ }, "description": "Function to execute on press." }, + "labelMaxFontSizeMultiplier": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "Specifies the largest possible scale a label font can reach." + }, + "aria-label": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + }, "style": { "required": false, "tsType": { @@ -5053,76 +4987,63 @@ }, "description": "" }, - "pointerEvents": { + "testID": { "required": false, "tsType": { - "name": "ViewProps['pointerEvents']", - "raw": "ViewProps['pointerEvents']" + "name": "string" }, - "description": "`pointerEvents` passed to the `View` container, which is wrapping children within `TouchableRipple`." + "description": "TestID used for testing purposes", + "defaultValue": { + "value": "'drawer-collapsed-item'", + "computed": false + } } } }, "type": "component", "dependencies": [ - "src/components/DataTable/DataTableRow.tsx" + "src/components/Drawer/DrawerCollapsedItem.tsx" ], - "group": "DataTable" + "group": "Drawer" }, - "DataTable/DataTableTitle": { - "filepath": "DataTable/DataTableTitle.tsx", - "title": "DataTable.Title", - "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", - "link": "data-table-title", + "Drawer/DrawerItem": { + "filepath": "Drawer/DrawerItem.tsx", + "title": "Drawer.Item", + "description": "A component used to show an action item with an icon and a label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "link": "drawer-item", "data": { - "description": "A component to display title in table header.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { DataTable } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n Dessert\n \n Calories\n Fat (g)\n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "DataTable.Title", + "description": "A component used to show an action item with an icon and a label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "displayName": "Drawer.Item", "methods": [], "statics": [], "props": { - "children": { + "label": { "required": true, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "string" }, - "description": "Text content of the `DataTableTitle`." + "description": "The label text of the item." }, - "numeric": { + "icon": { "required": false, "tsType": { - "name": "boolean" + "name": "IconSource" }, - "description": "Align the text to the right. Generally monetary or number fields are aligned to right." + "description": "Icon to display for the `DrawerItem`." }, - "sortDirection": { + "active": { "required": false, "tsType": { - "name": "union", - "raw": "'ascending' | 'descending'", - "elements": [ - { - "name": "literal", - "value": "'ascending'" - }, - { - "name": "literal", - "value": "'descending'" - } - ] + "name": "boolean" }, - "description": "Direction of sorting. An arrow indicating the direction is displayed when this is given." + "description": "Whether to highlight the drawer item as active." }, - "numberOfLines": { + "disabled": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "The number of lines to show.", - "defaultValue": { - "value": "1", - "computed": false - } + "description": "Whether the item is disabled." }, "onPress": { "required": false, @@ -5146,137 +5067,81 @@ }, "description": "Function to execute on press." }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "" - }, - "textStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Text content style of the `DataTableTitle`." - }, - "maxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a text font can reach." - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/DataTable/DataTableTitle.tsx" - ], - "group": "DataTable" - }, - "Dialog/Dialog": { - "filepath": "Dialog/Dialog.tsx", - "title": "Dialog", - "description": "Dialogs inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks.\nTo render the `Dialog` above other components, you'll need to wrap it with the [`Portal`](../Portal) component.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Dialog, Portal, PaperProvider, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showDialog = () => setVisible(true);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n Alert\n \n This is simple dialog\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "dialog", - "data": { - "description": "Dialogs inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks.\nTo render the `Dialog` above other components, you'll need to wrap it with the [`Portal`](../Portal) component.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Dialog, Portal, PaperProvider, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showDialog = () => setVisible(true);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n Alert\n \n This is simple dialog\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Dialog", - "methods": [], - "statics": [], - "props": { - "dismissable": { + "background": { "required": false, "tsType": { - "name": "boolean" + "name": "PressableAndroidRippleConfig" }, - "description": "Determines whether clicking outside the dialog dismiss it.", - "defaultValue": { - "value": "true", - "computed": false - } + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, - "dismissableBackButton": { + "aria-label": { "required": false, "tsType": { - "name": "boolean" + "name": "string" }, - "description": "Determines whether clicking Android hardware back button dismiss dialog.", - "defaultValue": { - "value": "dismissable", - "computed": true - } + "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." }, - "onDismiss": { + "right": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "() => void", + "raw": "(props: { color: ColorValue }) => React.ReactNode", "signature": { - "arguments": [], + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{ color: ColorValue }", + "signature": { + "properties": [ + { + "key": "color", + "value": { + "name": "ColorValue", + "required": true + } + } + ] + } + } + } + ], "return": { - "name": "void" + "name": "ReactReactNode", + "raw": "React.ReactNode" } } }, - "description": "Callback that is called when the user dismisses the dialog." + "description": "Callback which returns a React element to display on the right side. For instance a Badge." }, - "visible": { + "labelMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Determines Whether the dialog is visible.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "Specifies the largest possible scale a label font can reach." }, - "children": { - "required": true, + "hitSlop": { + "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" }, - "description": "Content of the `Dialog`." + "description": "Sets additional distance outside of element in which a press can be detected." }, "style": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", + "name": "StyleProp", "elements": [ { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "ViewStyle" } ], - "raw": "Animated.WithAnimatedValue>" + "raw": "StyleProp" }, "description": "" }, @@ -5286,39 +5151,58 @@ "name": "ThemeProp" }, "description": "" - }, - "testID": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "testID to be used on tests." } } }, "type": "component", "dependencies": [ - "src/components/Dialog/Dialog.tsx" - ] + "src/components/Drawer/DrawerItem.tsx" + ], + "group": "Drawer" }, - "Dialog/DialogActions": { - "filepath": "Dialog/DialogActions.tsx", - "title": "Dialog.Actions", - "description": "A component to show a list of actions in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button, Dialog, Portal } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "dialog-actions", + "Drawer/DrawerSection": { + "filepath": "Drawer/DrawerSection.tsx", + "title": "Drawer.Section", + "description": "A component to group content inside a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [active, setActive] = React.useState('');\n\n return (\n \n setActive('first')}\n />\n setActive('second')}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "link": "drawer-section", "data": { - "description": "A component to show a list of actions in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Button, Dialog, Portal } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Dialog.Actions", + "description": "A component to group content inside a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [active, setActive] = React.useState('');\n\n return (\n \n setActive('first')}\n />\n setActive('second')}\n />\n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Drawer.Section", "methods": [], "statics": [], "props": { + "title": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Title to show as the header for the section." + }, "children": { "required": true, "tsType": { "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "Content of the `DialogActions`." + "description": "Content of the `Drawer.Section`." + }, + "showDivider": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether to show `Divider` at the end of the section. True by default.", + "defaultValue": { + "value": "true", + "computed": false + } + }, + "titleMaxFontSizeMultiplier": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "Specifies the largest possible scale a title font can reach." }, "style": { "required": false, @@ -5344,234 +5228,148 @@ }, "type": "component", "dependencies": [ - "src/components/Dialog/DialogActions.tsx" + "src/components/Drawer/DrawerSection.tsx" ], - "group": "Dialog" + "group": "Drawer" }, - "Dialog/DialogContent": { - "filepath": "Dialog/DialogContent.tsx", - "title": "Dialog.Content", - "description": "A component to show content in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "dialog-content", + "FAB/FAB": { + "filepath": "FAB/FAB.tsx", + "title": "FAB", + "description": "A floating action button represents the primary action on a screen.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n right: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", + "link": "fab", "data": { - "description": "A component to show content in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Dialog.Content", + "description": "A floating action button represents the primary action on a screen.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n right: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", + "displayName": "FAB", "methods": [], "statics": [], "props": { - "children": { + "icon": { "required": true, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "IconSource" }, - "description": "Content of the `DialogContent`." + "description": "Icon to display inside the FAB." }, - "style": { + "variant": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "Variant" }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Dialog/DialogContent.tsx" - ], - "group": "Dialog" - }, - "Dialog/DialogIcon": { - "filepath": "Dialog/DialogIcon.tsx", - "title": "Dialog.Icon", - "description": "@supported Available in v5.x with theme version 3\nA component to show an icon in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nconst styles = StyleSheet.create({\n title: {\n textAlign: 'center',\n },\n})\n\nexport default MyComponent;\n```", - "link": "dialog-icon", - "data": { - "description": "@supported Available in v5.x with theme version 3\nA component to show an icon in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nconst styles = StyleSheet.create({\n title: {\n textAlign: 'center',\n },\n})\n\nexport default MyComponent;\n```", - "displayName": "Dialog.Icon", - "methods": [], - "statics": [], - "props": { - "color": { + "description": "Role-color preset. Defaults to `tonalPrimary`.", + "defaultValue": { + "value": "'tonalPrimary'", + "computed": false + } + }, + "containerColor": { "required": false, "tsType": { "name": "ColorValue" }, - "description": "Custom color for action icon." + "description": "Override the container (background) color." }, - "icon": { - "required": true, + "contentColor": { + "required": false, "tsType": { - "name": "IconSource" + "name": "ColorValue" }, - "description": "Name of the icon to show." + "description": "Override the content (icon) color." }, "size": { "required": false, "tsType": { - "name": "number" + "name": "Size" }, - "description": "Optional icon size.", + "description": "Spec size. Defaults to `default`.", "defaultValue": { - "value": "24", + "value": "'default'", "computed": false } }, - "theme": { + "visible": { "required": false, "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Dialog/DialogIcon.tsx" - ], - "group": "Dialog" - }, - "Dialog/DialogScrollArea": { - "filepath": "Dialog/DialogScrollArea.tsx", - "title": "Dialog.ScrollArea", - "description": "A component to show a scrollable content in a Dialog. The component only provides appropriate styling.\nFor the scrollable content you can use `ScrollView`, `FlatList` etc. depending on your requirement.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { ScrollView } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n This is a scrollable area\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "dialog-scroll-area", - "data": { - "description": "A component to show a scrollable content in a Dialog. The component only provides appropriate styling.\nFor the scrollable content you can use `ScrollView`, `FlatList` etc. depending on your requirement.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { ScrollView } from 'react-native';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n \n \n This is a scrollable area\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Dialog.ScrollArea", - "methods": [], - "statics": [], - "props": { - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "boolean" }, - "description": "Content of the `DialogScrollArea`." + "description": "Whether the FAB is currently visible. Toggling animates the spec'd enter\nand exit (scale + alpha) on the FAB itself.", + "defaultValue": { + "value": "true", + "computed": false + } }, - "style": { + "onPress": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" } - ], - "raw": "StyleProp" + } }, - "description": "" + "description": "Function to execute on press." }, - "theme": { + "aria-label": { "required": false, "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Dialog/DialogScrollArea.tsx" - ], - "group": "Dialog" - }, - "Dialog/DialogTitle": { - "filepath": "Dialog/DialogTitle.tsx", - "title": "Dialog.Title", - "description": "A component to show a title in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "dialog-title", - "data": { - "description": "A component to show a title in a Dialog.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Dialog, Portal, Text } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const hideDialog = () => setVisible(false);\n\n return (\n \n \n This is a title\n \n This is simple dialog\n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Dialog.Title", - "methods": [], - "statics": [], - "props": { - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "string" }, - "description": "Title text for the `DialogTitle`." + "description": "Accessibility label. Falls back to nothing if unset." }, - "style": { + "aria-checked": { "required": false, "tsType": { - "name": "StyleProp", + "name": "union", + "raw": "boolean | 'mixed'", "elements": [ { - "name": "TextStyle" + "name": "boolean" + }, + { + "name": "literal", + "value": "'mixed'" } - ], - "raw": "StyleProp" + ] }, - "description": "" + "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." }, - "theme": { + "aria-selected": { "required": false, "tsType": { - "name": "ThemeProp" + "name": "boolean" }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Dialog/DialogTitle.tsx" - ], - "group": "Dialog" - }, - "Divider": { - "filepath": "Divider.tsx", - "title": "Divider", - "description": "A divider is a thin, lightweight separator that groups content in lists and page layouts.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Divider, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Lemon\n \n Mango\n \n \n);\n\nexport default MyComponent;\n```", - "link": "divider", - "data": { - "description": "A divider is a thin, lightweight separator that groups content in lists and page layouts.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Divider, Text } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Lemon\n \n Mango\n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "Divider", - "methods": [], - "statics": [], - "props": { - "leftInset": { + "description": "Indicates whether the element is selected." + }, + "aria-busy": { "required": false, "tsType": { "name": "boolean" }, - "description": "@renamed Renamed from 'inset' to 'leftInset` in v5.x\nWhether divider has a left inset." + "description": "Indicates whether the element is currently busy (e.g. loading)." }, - "horizontalInset": { + "aria-expanded": { "required": false, "tsType": { "name": "boolean" }, - "description": "@supported Available in v5.x with theme version 3\n Whether divider has a horizontal inset on both sides.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "Indicates whether the element's controlled content is expanded." }, - "bold": { + "background": { "required": false, "tsType": { - "name": "boolean" + "name": "PressableAndroidRippleConfig" }, - "description": "@supported Available in v5.x with theme version 3\n Whether divider should be bolded.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "Type of background drawable to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, "style": { "required": false, @@ -5584,7 +5382,18 @@ ], "raw": "StyleProp" }, - "description": "" + "description": "Style for positioning the FAB. The visual treatment (size, shape, color)\nis driven by `variant` and `size`." + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "TestID used for testing purposes.", + "defaultValue": { + "value": "'floating-action-button'", + "computed": false + } }, "theme": { "required": false, @@ -5592,82 +5401,105 @@ "name": "ThemeProp" }, "description": "" + }, + "ref": { + "required": false, + "tsType": { + "name": "ReactRef", + "raw": "React.Ref", + "elements": [ + { + "name": "View" + } + ] + }, + "description": "" } } }, "type": "component", "dependencies": [ - "src/components/Divider.tsx" + "src/components/FAB/FAB.tsx" ] }, - "Drawer/DrawerCollapsedItem": { - "filepath": "Drawer/DrawerCollapsedItem.tsx", - "title": "Drawer.CollapsedItem", - "description": "Note: Available in v5.x with theme version 3\n\nCollapsed component used to show an action item with an icon and optionally label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "link": "drawer-collapsed-item", - "data": { - "description": "Note: Available in v5.x with theme version 3\n\nCollapsed component used to show an action item with an icon and optionally label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "displayName": "Drawer.CollapsedItem", + "FAB/Extended": { + "filepath": "FAB/Extended.tsx", + "title": "Extended", + "description": "An extended floating action button represents the primary action on a screen\nand shows a label next to the icon. Animates between expanded (icon + label)\nand collapsed (icon only) states.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n return (\n setExpanded((v) => !v)}\n style={styles.fab}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n left: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", + "link": "extended", + "data": { + "description": "An extended floating action button represents the primary action on a screen\nand shows a label next to the icon. Animates between expanded (icon + label)\nand collapsed (icon only) states.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n return (\n setExpanded((v) => !v)}\n style={styles.fab}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n left: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", + "displayName": "Extended", "methods": [], "statics": [], "props": { + "icon": { + "required": true, + "tsType": { + "name": "IconSource" + }, + "description": "Icon to display inside the FAB." + }, "label": { - "required": false, + "required": true, "tsType": { "name": "string" }, - "description": "The label text of the item." + "description": "Label rendered next to the icon when expanded." }, - "badge": { + "variant": { "required": false, "tsType": { - "name": "union", - "raw": "string | number | boolean", - "elements": [ - { - "name": "string" - }, - { - "name": "number" - }, - { - "name": "boolean" - } - ] + "name": "Variant" }, - "description": "Badge to show on the icon, can be `true` to show a dot, `string` or `number` to show text.", + "description": "Role-color preset. Defaults to `tonalPrimary`.", "defaultValue": { - "value": "false", + "value": "'tonalPrimary'", "computed": false } }, - "disabled": { + "containerColor": { "required": false, "tsType": { - "name": "boolean" + "name": "ColorValue" }, - "description": "Whether the item is disabled." + "description": "Override the container (background) color. When set without `contentColor`,\nthe icon and label colors are derived automatically via `contentColorFor`." }, - "focusedIcon": { + "contentColor": { "required": false, "tsType": { - "name": "IconSource" + "name": "ColorValue" }, - "description": "@renamed Renamed from 'icon' to 'focusedIcon' in v5.x\nIcon to use as the focused destination icon, can be a string, an image source or a react component" + "description": "Override the content (icon + label) color." }, - "unfocusedIcon": { + "size": { "required": false, "tsType": { - "name": "IconSource" + "name": "Size" }, - "description": "@renamed Renamed from 'icon' to 'focusedIcon' in v5.x\nIcon to use as the unfocused destination icon, can be a string, an image source or a react component" + "description": "Spec size. Defaults to `default`.", + "defaultValue": { + "value": "'default'", + "computed": false + } }, - "active": { + "expanded": { + "required": true, + "tsType": { + "name": "boolean" + }, + "description": "Whether the FAB is expanded (icon + label) or collapsed (icon only). The\nwidth and label opacity animate per the MD3 Expressive spec on change." + }, + "visible": { "required": false, "tsType": { "name": "boolean" }, - "description": "Whether to highlight the drawer item as active." + "description": "Whether the FAB is currently visible. Toggling animates the spec'd enter\nand exit (scale + alpha) on the FAB itself.", + "defaultValue": { + "value": "true", + "computed": false + } }, "onPress": { "required": false, @@ -5691,6 +5523,55 @@ }, "description": "Function to execute on press." }, + "aria-label": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Accessibility label. Falls back to `label` if unset.", + "defaultValue": { + "value": "label", + "computed": true + } + }, + "aria-checked": { + "required": false, + "tsType": { + "name": "union", + "raw": "boolean | 'mixed'", + "elements": [ + { + "name": "boolean" + }, + { + "name": "literal", + "value": "'mixed'" + } + ] + }, + "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." + }, + "aria-selected": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Indicates whether the element is selected." + }, + "aria-busy": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Indicates whether the element is currently busy (e.g. loading)." + }, + "aria-expanded": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Indicates whether the element's controlled content is expanded." + }, "labelMaxFontSizeMultiplier": { "required": false, "tsType": { @@ -5698,12 +5579,12 @@ }, "description": "Specifies the largest possible scale a label font can reach." }, - "aria-label": { + "background": { "required": false, "tsType": { - "name": "string" + "name": "PressableAndroidRippleConfig" }, - "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + "description": "Type of background drawable to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, "style": { "required": false, @@ -5716,7 +5597,18 @@ ], "raw": "StyleProp" }, - "description": "" + "description": "Style for positioning the FAB. The visual treatment (size, shape, color)\nis driven by `variant` and `size`." + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "TestID used for testing purposes.", + "defaultValue": { + "value": "'extended-floating-action-button'", + "computed": false + } }, "theme": { "required": false, @@ -5725,819 +5617,189 @@ }, "description": "" }, - "testID": { + "ref": { "required": false, "tsType": { - "name": "string" + "name": "ReactRef", + "raw": "React.Ref", + "elements": [ + { + "name": "View" + } + ] }, - "description": "TestID used for testing purposes", - "defaultValue": { - "value": "'drawer-collapsed-item'", - "computed": false - } + "description": "" } } }, "type": "component", "dependencies": [ - "src/components/Drawer/DrawerCollapsedItem.tsx" - ], - "group": "Drawer" + "src/components/FAB/Extended.tsx" + ] }, - "Drawer/DrawerItem": { - "filepath": "Drawer/DrawerItem.tsx", - "title": "Drawer.Item", - "description": "A component used to show an action item with an icon and a label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "link": "drawer-item", + "FAB/Menu": { + "filepath": "FAB/Menu.tsx", + "title": "Menu", + "description": "Floating action button menu. Wraps a trigger FAB; when `expanded` is true,\nitems appear stacked above and the trigger morphs into the spec'd close\nbutton (`shape: 'full'`, 56 dp, saturated role color).\n\nNo visual backdrop and no outside-tap dismiss — that matches the MD3 spec\nand lets the user keep interacting with the content underneath. Dismiss\nvia the close button or by tapping an item.\n\n## Usage\n```tsx\nconst [open, setOpen] = React.useState(false);\n\n\n setOpen(false)}\n trigger={{ icon: 'plus', variant: 'primary', onPress: () => setOpen(true) }}\n items={[\n { icon: 'email', label: 'Send', onPress: () => {} },\n { icon: 'bell', label: 'Remind', onPress: () => {} },\n ]}\n />\n\n```", + "link": "menu", "data": { - "description": "A component used to show an action item with an icon and a label in a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "displayName": "Drawer.Item", + "description": "Floating action button menu. Wraps a trigger FAB; when `expanded` is true,\nitems appear stacked above and the trigger morphs into the spec'd close\nbutton (`shape: 'full'`, 56 dp, saturated role color).\n\nNo visual backdrop and no outside-tap dismiss — that matches the MD3 spec\nand lets the user keep interacting with the content underneath. Dismiss\nvia the close button or by tapping an item.\n\n## Usage\n```tsx\nconst [open, setOpen] = React.useState(false);\n\n\n setOpen(false)}\n trigger={{ icon: 'plus', variant: 'primary', onPress: () => setOpen(true) }}\n items={[\n { icon: 'email', label: 'Send', onPress: () => {} },\n { icon: 'bell', label: 'Remind', onPress: () => {} },\n ]}\n />\n\n```", + "displayName": "Menu", "methods": [], "statics": [], "props": { - "label": { + "expanded": { "required": true, - "tsType": { - "name": "string" - }, - "description": "The label text of the item." - }, - "icon": { - "required": false, - "tsType": { - "name": "IconSource" - }, - "description": "Icon to display for the `DrawerItem`." - }, - "active": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Whether to highlight the drawer item as active." - }, - "disabled": { - "required": false, "tsType": { "name": "boolean" }, - "description": "Whether the item is disabled." + "description": "Whether the menu is open." }, - "onPress": { - "required": false, + "onDismiss": { + "required": true, "tsType": { "name": "signature", "type": "function", - "raw": "(e: GestureResponderEvent) => void", + "raw": "() => void", "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], + "arguments": [], "return": { "name": "void" } } }, - "description": "Function to execute on press." - }, - "background": { - "required": false, - "tsType": { - "name": "PressableAndroidRippleConfig" - }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" - }, - "aria-label": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + "description": "Called when the user taps the close button or taps an item." }, - "right": { - "required": false, + "trigger": { + "required": true, "tsType": { "name": "signature", - "type": "function", - "raw": "(props: { color: ColorValue }) => React.ReactNode", + "type": "object", + "raw": "{\n /**\n * Icon displayed in the trigger FAB (and cross-faded to `closeIcon` when\n * the menu is open).\n */\n icon: IconSource;\n variant?: Variant;\n size?: Size;\n containerColor?: ColorValue;\n contentColor?: ColorValue;\n visible?: boolean;\n onPress?: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label for the trigger FAB.\n */\n 'aria-label'?: string;\n testID?: string;\n}", "signature": { - "arguments": [ + "properties": [ { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ color: ColorValue }", - "signature": { - "properties": [ - { - "key": "color", - "value": { - "name": "ColorValue", - "required": true + "key": "icon", + "value": { + "name": "IconSource", + "required": true + } + }, + { + "key": "variant", + "value": { + "name": "Variant", + "required": false + } + }, + { + "key": "size", + "value": { + "name": "Size", + "required": false + } + }, + { + "key": "containerColor", + "value": { + "name": "ColorValue", + "required": false + } + }, + { + "key": "contentColor", + "value": { + "name": "ColorValue", + "required": false + } + }, + { + "key": "visible", + "value": { + "name": "boolean", + "required": false + } + }, + { + "key": "onPress", + "value": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" } } - ] - } + ], + "return": { + "name": "void" + } + }, + "required": false + } + }, + { + "key": "aria-label", + "value": { + "name": "string", + "required": false + } + }, + { + "key": "testID", + "value": { + "name": "string", + "required": false } } - ], - "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - } + ] } }, - "description": "Callback which returns a React element to display on the right side. For instance a Badge." - }, - "labelMaxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a label font can reach." - }, - "hitSlop": { - "required": false, - "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" - }, - "description": "Sets additional distance outside of element in which a press can be detected." + "description": "Trigger FAB configuration. The menu renders a morphing FAB that\nanimates between the trigger appearance and the spec'd close button." }, - "style": { + "alignment": { "required": false, "tsType": { - "name": "StyleProp", + "name": "union", + "raw": "'start' | 'center' | 'end'", "elements": [ { - "name": "ViewStyle" + "name": "literal", + "value": "'start'" + }, + { + "name": "literal", + "value": "'center'" + }, + { + "name": "literal", + "value": "'end'" } - ], - "raw": "StyleProp" - }, - "description": "" - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Drawer/DrawerItem.tsx" - ], - "group": "Drawer" - }, - "Drawer/DrawerSection": { - "filepath": "Drawer/DrawerSection.tsx", - "title": "Drawer.Section", - "description": "A component to group content inside a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [active, setActive] = React.useState('');\n\n return (\n \n setActive('first')}\n />\n setActive('second')}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "link": "drawer-section", - "data": { - "description": "A component to group content inside a navigation drawer.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Drawer } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [active, setActive] = React.useState('');\n\n return (\n \n setActive('first')}\n />\n setActive('second')}\n />\n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Drawer.Section", - "methods": [], - "statics": [], - "props": { - "title": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Title to show as the header for the section." - }, - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Content of the `Drawer.Section`." - }, - "showDivider": { - "required": false, - "tsType": { - "name": "boolean" + ] }, - "description": "Whether to show `Divider` at the end of the section. True by default.", + "description": "Horizontal side the menu sits on. Default `'end'`.", "defaultValue": { - "value": "true", + "value": "'end'", "computed": false } }, - "titleMaxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a title font can reach." - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "" - }, - "theme": { + "closeIcon": { "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Drawer/DrawerSection.tsx" - ], - "group": "Drawer" - }, - "FAB/FAB": { - "filepath": "FAB/FAB.tsx", - "title": "FAB", - "description": "A floating action button represents the primary action on a screen.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n right: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", - "link": "fab", - "data": { - "description": "A floating action button represents the primary action on a screen.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n right: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", - "displayName": "FAB", - "methods": [], - "statics": [], - "props": { - "icon": { - "required": true, "tsType": { "name": "IconSource" }, - "description": "Icon to display inside the FAB." - }, - "variant": { - "required": false, - "tsType": { - "name": "Variant" - }, - "description": "Role-color preset. Defaults to `tonalPrimary`.", + "description": "Icon used by the close button when the menu is expanded. Default\n`'close'`.", "defaultValue": { - "value": "'tonalPrimary'", + "value": "'close'", "computed": false } }, - "containerColor": { - "required": false, - "tsType": { - "name": "ColorValue" - }, - "description": "Override the container (background) color." - }, - "contentColor": { - "required": false, - "tsType": { - "name": "ColorValue" - }, - "description": "Override the content (icon) color." - }, - "size": { - "required": false, - "tsType": { - "name": "Size" - }, - "description": "Spec size. Defaults to `default`.", - "defaultValue": { - "value": "'default'", - "computed": false - } - }, - "visible": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Whether the FAB is currently visible. Toggling animates the spec'd enter\nand exit (scale + alpha) on the FAB itself.", - "defaultValue": { - "value": "true", - "computed": false - } - }, - "onPress": { - "required": false, - "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } - }, - "description": "Function to execute on press." - }, - "aria-label": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Accessibility label. Falls back to nothing if unset." - }, - "aria-checked": { - "required": false, - "tsType": { - "name": "union", - "raw": "boolean | 'mixed'", - "elements": [ - { - "name": "boolean" - }, - { - "name": "literal", - "value": "'mixed'" - } - ] - }, - "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." - }, - "aria-selected": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is selected." - }, - "aria-busy": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is currently busy (e.g. loading)." - }, - "aria-expanded": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element's controlled content is expanded." - }, - "background": { - "required": false, - "tsType": { - "name": "PressableAndroidRippleConfig" - }, - "description": "Type of background drawable to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style for positioning the FAB. The visual treatment (size, shape, color)\nis driven by `variant` and `size`." - }, - "testID": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "TestID used for testing purposes.", - "defaultValue": { - "value": "'floating-action-button'", - "computed": false - } - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - }, - "ref": { - "required": false, - "tsType": { - "name": "ReactRef", - "raw": "React.Ref", - "elements": [ - { - "name": "View" - } - ] - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/FAB/FAB.tsx" - ] - }, - "FAB/Extended": { - "filepath": "FAB/Extended.tsx", - "title": "Extended", - "description": "An extended floating action button represents the primary action on a screen\nand shows a label next to the icon. Animates between expanded (icon + label)\nand collapsed (icon only) states.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n return (\n setExpanded((v) => !v)}\n style={styles.fab}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n left: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", - "link": "extended", - "data": { - "description": "An extended floating action button represents the primary action on a screen\nand shows a label next to the icon. Animates between expanded (icon + label)\nand collapsed (icon only) states.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { StyleSheet } from 'react-native';\nimport { FAB } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n return (\n setExpanded((v) => !v)}\n style={styles.fab}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n margin: 16,\n left: 0,\n bottom: 0,\n },\n});\n\nexport default MyComponent;\n```", - "displayName": "Extended", - "methods": [], - "statics": [], - "props": { - "icon": { - "required": true, - "tsType": { - "name": "IconSource" - }, - "description": "Icon to display inside the FAB." - }, - "label": { - "required": true, - "tsType": { - "name": "string" - }, - "description": "Label rendered next to the icon when expanded." - }, - "variant": { - "required": false, - "tsType": { - "name": "Variant" - }, - "description": "Role-color preset. Defaults to `tonalPrimary`.", - "defaultValue": { - "value": "'tonalPrimary'", - "computed": false - } - }, - "containerColor": { - "required": false, - "tsType": { - "name": "ColorValue" - }, - "description": "Override the container (background) color. When set without `contentColor`,\nthe icon and label colors are derived automatically via `contentColorFor`." - }, - "contentColor": { - "required": false, - "tsType": { - "name": "ColorValue" - }, - "description": "Override the content (icon + label) color." - }, - "size": { - "required": false, - "tsType": { - "name": "Size" - }, - "description": "Spec size. Defaults to `default`.", - "defaultValue": { - "value": "'default'", - "computed": false - } - }, - "expanded": { - "required": true, - "tsType": { - "name": "boolean" - }, - "description": "Whether the FAB is expanded (icon + label) or collapsed (icon only). The\nwidth and label opacity animate per the MD3 Expressive spec on change." - }, - "visible": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Whether the FAB is currently visible. Toggling animates the spec'd enter\nand exit (scale + alpha) on the FAB itself.", - "defaultValue": { - "value": "true", - "computed": false - } - }, - "onPress": { - "required": false, - "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } - }, - "description": "Function to execute on press." - }, - "aria-label": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Accessibility label. Falls back to `label` if unset.", - "defaultValue": { - "value": "label", - "computed": true - } - }, - "aria-checked": { - "required": false, - "tsType": { - "name": "union", - "raw": "boolean | 'mixed'", - "elements": [ - { - "name": "boolean" - }, - { - "name": "literal", - "value": "'mixed'" - } - ] - }, - "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." - }, - "aria-selected": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is selected." - }, - "aria-busy": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is currently busy (e.g. loading)." - }, - "aria-expanded": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element's controlled content is expanded." - }, - "labelMaxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a label font can reach." - }, - "background": { - "required": false, - "tsType": { - "name": "PressableAndroidRippleConfig" - }, - "description": "Type of background drawable to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style for positioning the FAB. The visual treatment (size, shape, color)\nis driven by `variant` and `size`." - }, - "testID": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "TestID used for testing purposes.", - "defaultValue": { - "value": "'extended-floating-action-button'", - "computed": false - } - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - }, - "ref": { - "required": false, - "tsType": { - "name": "ReactRef", - "raw": "React.Ref", - "elements": [ - { - "name": "View" - } - ] - }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/FAB/Extended.tsx" - ] - }, - "FAB/Menu": { - "filepath": "FAB/Menu.tsx", - "title": "Menu", - "description": "Floating action button menu. Wraps a trigger FAB; when `expanded` is true,\nitems appear stacked above and the trigger morphs into the spec'd close\nbutton (`shape: 'full'`, 56 dp, saturated role color).\n\nNo visual backdrop and no outside-tap dismiss — that matches the MD3 spec\nand lets the user keep interacting with the content underneath. Dismiss\nvia the close button or by tapping an item.\n\n## Usage\n```tsx\nconst [open, setOpen] = React.useState(false);\n\n\n setOpen(false)}\n trigger={{ icon: 'plus', variant: 'primary', onPress: () => setOpen(true) }}\n items={[\n { icon: 'email', label: 'Send', onPress: () => {} },\n { icon: 'bell', label: 'Remind', onPress: () => {} },\n ]}\n />\n\n```", - "link": "menu", - "data": { - "description": "Floating action button menu. Wraps a trigger FAB; when `expanded` is true,\nitems appear stacked above and the trigger morphs into the spec'd close\nbutton (`shape: 'full'`, 56 dp, saturated role color).\n\nNo visual backdrop and no outside-tap dismiss — that matches the MD3 spec\nand lets the user keep interacting with the content underneath. Dismiss\nvia the close button or by tapping an item.\n\n## Usage\n```tsx\nconst [open, setOpen] = React.useState(false);\n\n\n setOpen(false)}\n trigger={{ icon: 'plus', variant: 'primary', onPress: () => setOpen(true) }}\n items={[\n { icon: 'email', label: 'Send', onPress: () => {} },\n { icon: 'bell', label: 'Remind', onPress: () => {} },\n ]}\n />\n\n```", - "displayName": "Menu", - "methods": [], - "statics": [], - "props": { - "expanded": { - "required": true, - "tsType": { - "name": "boolean" - }, - "description": "Whether the menu is open." - }, - "onDismiss": { - "required": true, - "tsType": { - "name": "signature", - "type": "function", - "raw": "() => void", - "signature": { - "arguments": [], - "return": { - "name": "void" - } - } - }, - "description": "Called when the user taps the close button or taps an item." - }, - "trigger": { - "required": true, - "tsType": { - "name": "signature", - "type": "object", - "raw": "{\n /**\n * Icon displayed in the trigger FAB (and cross-faded to `closeIcon` when\n * the menu is open).\n */\n icon: IconSource;\n variant?: Variant;\n size?: Size;\n containerColor?: ColorValue;\n contentColor?: ColorValue;\n visible?: boolean;\n onPress?: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label for the trigger FAB.\n */\n 'aria-label'?: string;\n testID?: string;\n}", - "signature": { - "properties": [ - { - "key": "icon", - "value": { - "name": "IconSource", - "required": true - } - }, - { - "key": "variant", - "value": { - "name": "Variant", - "required": false - } - }, - { - "key": "size", - "value": { - "name": "Size", - "required": false - } - }, - { - "key": "containerColor", - "value": { - "name": "ColorValue", - "required": false - } - }, - { - "key": "contentColor", - "value": { - "name": "ColorValue", - "required": false - } - }, - { - "key": "visible", - "value": { - "name": "boolean", - "required": false - } - }, - { - "key": "onPress", - "value": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - }, - "required": false - } - }, - { - "key": "aria-label", - "value": { - "name": "string", - "required": false - } - }, - { - "key": "testID", - "value": { - "name": "string", - "required": false - } - } - ] - } - }, - "description": "Trigger FAB configuration. The menu renders a morphing FAB that\nanimates between the trigger appearance and the spec'd close button." - }, - "alignment": { - "required": false, - "tsType": { - "name": "union", - "raw": "'start' | 'center' | 'end'", - "elements": [ - { - "name": "literal", - "value": "'start'" - }, - { - "name": "literal", - "value": "'center'" - }, - { - "name": "literal", - "value": "'end'" - } - ] - }, - "description": "Horizontal side the menu sits on. Default `'end'`.", - "defaultValue": { - "value": "'end'", - "computed": false - } - }, - "closeIcon": { - "required": false, - "tsType": { - "name": "IconSource" - }, - "description": "Icon used by the close button when the menu is expanded. Default\n`'close'`.", - "defaultValue": { - "value": "'close'", - "computed": false - } - }, - "items": { - "required": true, + "items": { + "required": true, "tsType": { "name": "union", "raw": "| [T, T]\n| [T, T, T]\n| [T, T, T, T]\n| [T, T, T, T, T]\n| [T, T, T, T, T, T]", @@ -6846,13 +6108,131 @@ } ] } - } - ] - }, - { - "name": "tuple", - "raw": "[T, T, T, T]", - "elements": [ + } + ] + }, + { + "name": "tuple", + "raw": "[T, T, T, T]", + "elements": [ + { + "name": "signature", + "type": "object", + "raw": "{\n /**\n * Optional icon for the item.\n */\n icon?: IconSource;\n /**\n * Mandatory label.\n */\n label: string;\n /**\n * Called when the item is pressed. The menu is dismissed automatically\n * after `onPress` runs.\n */\n onPress: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label. Falls back to `label`.\n */\n 'aria-label'?: string;\n testID?: string;\n}", + "signature": { + "properties": [ + { + "key": "icon", + "value": { + "name": "IconSource", + "required": false + } + }, + { + "key": "label", + "value": { + "name": "string", + "required": true + } + }, + { + "key": "onPress", + "value": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" + } + }, + "required": true + } + }, + { + "key": "aria-label", + "value": { + "name": "string", + "required": false + } + }, + { + "key": "testID", + "value": { + "name": "string", + "required": false + } + } + ] + } + }, + { + "name": "signature", + "type": "object", + "raw": "{\n /**\n * Optional icon for the item.\n */\n icon?: IconSource;\n /**\n * Mandatory label.\n */\n label: string;\n /**\n * Called when the item is pressed. The menu is dismissed automatically\n * after `onPress` runs.\n */\n onPress: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label. Falls back to `label`.\n */\n 'aria-label'?: string;\n testID?: string;\n}", + "signature": { + "properties": [ + { + "key": "icon", + "value": { + "name": "IconSource", + "required": false + } + }, + { + "key": "label", + "value": { + "name": "string", + "required": true + } + }, + { + "key": "onPress", + "value": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" + } + }, + "required": true + } + }, + { + "key": "aria-label", + "value": { + "name": "string", + "required": false + } + }, + { + "key": "testID", + "value": { + "name": "string", + "required": false + } + } + ] + } + }, { "name": "signature", "type": "object", @@ -6970,7 +6350,13 @@ } ] } - }, + } + ] + }, + { + "name": "tuple", + "raw": "[T, T, T, T, T]", + "elements": [ { "name": "signature", "type": "object", @@ -7088,13 +6474,7 @@ } ] } - } - ] - }, - { - "name": "tuple", - "raw": "[T, T, T, T, T]", - "elements": [ + }, { "name": "signature", "type": "object", @@ -7271,7 +6651,13 @@ } ] } - }, + } + ] + }, + { + "name": "tuple", + "raw": "[T, T, T, T, T, T]", + "elements": [ { "name": "signature", "type": "object", @@ -7389,13 +6775,7 @@ } ] } - } - ] - }, - { - "name": "tuple", - "raw": "[T, T, T, T, T, T]", - "elements": [ + }, { "name": "signature", "type": "object", @@ -7631,141 +7011,473 @@ } ] } - }, + } + ] + } + ] + }, + "description": "Menu items. Spec calls for 2 to 6 items." + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "", + "defaultValue": { + "value": "'floating-action-button-menu'", + "computed": false + } + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/FAB/Menu.tsx" + ] + }, + "IconButton/IconButton": { + "filepath": "IconButton/IconButton.tsx", + "title": "IconButton", + "description": "An icon button is a button which displays only an icon without a label.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { IconButton, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "link": "icon-button", + "data": { + "description": "An icon button is a button which displays only an icon without a label.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { IconButton, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "displayName": "IconButton", + "methods": [], + "statics": [], + "props": { + "icon": { + "required": true, + "tsType": { + "name": "IconSource" + }, + "description": "Icon to display." + }, + "mode": { + "required": false, + "tsType": { + "name": "union", + "raw": "'outlined' | 'contained' | 'contained-tonal'", + "elements": [ + { + "name": "literal", + "value": "'outlined'" + }, + { + "name": "literal", + "value": "'contained'" + }, + { + "name": "literal", + "value": "'contained-tonal'" + } + ] + }, + "description": "@supported Available in v5.x with theme version 3\nMode of the icon button. By default there is no specified mode - only pressable icon will be rendered." + }, + "iconColor": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "@renamed Renamed from 'color' to 'iconColor' in v5.x\nColor of the icon." + }, + "containerColor": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "Background color of the icon container." + }, + "selected": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether icon button is selected. A selected button receives alternative combination of icon and container colors.", + "defaultValue": { + "value": "false", + "computed": false + } + }, + "size": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "Size of the icon.", + "defaultValue": { + "value": "24", + "computed": false + } + }, + "disabled": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch." + }, + "animated": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether an icon change is animated.", + "defaultValue": { + "value": "false", + "computed": false + } + }, + "aria-label": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + }, + "contentStyle": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "Style of button's inner content.\nUse this prop to apply custom height and width or to set a custom padding`." + }, + "onPress": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" + } + } + }, + "description": "Function to execute on press." + }, + "style": { + "required": false, + "tsType": { + "name": "Animated.WithAnimatedValue", + "elements": [ + { + "name": "StyleProp", + "elements": [ { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + } + ], + "raw": "Animated.WithAnimatedValue>" + }, + "description": "" + }, + "ref": { + "required": false, + "tsType": { + "name": "ReactRef", + "raw": "React.Ref", + "elements": [ + { + "name": "View" + } + ] + }, + "description": "" + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "TestID used for testing purposes", + "defaultValue": { + "value": "'icon-button'", + "computed": false + } + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + }, + "loading": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether to show a loading indicator.", + "defaultValue": { + "value": "false", + "computed": false + } + } + } + }, + "type": "component", + "dependencies": [ + "src/components/IconButton/IconButton.tsx" + ] + }, + "Icon": { + "filepath": "Icon.tsx", + "title": "Icon", + "description": "An icon component which renders icon from vector library.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Icon, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "link": "icon", + "data": { + "description": "An icon component which renders icon from vector library.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Icon, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", + "displayName": "Icon", + "methods": [], + "statics": [], + "props": { + "size": { + "required": true, + "tsType": { + "name": "number" + }, + "description": "Size of icon." + }, + "allowFontScaling": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "" + }, + "source": { + "required": true, + "tsType": { + "name": "any" + }, + "description": "Icon to display." + }, + "color": { + "required": false, + "tsType": { + "name": "ColorValue" + }, + "description": "Color of the icon." + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "TestID used for testing purposes" + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/Icon.tsx" + ] + }, + "List/ListAccordion": { + "filepath": "List/ListAccordion.tsx", + "title": "List.Accordion", + "description": "A component used to display an expandable list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n const handlePress = () => setExpanded(!expanded);\n\n return (\n \n }>\n \n \n \n\n }\n expanded={expanded}\n onPress={handlePress}>\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "list-accordion", + "data": { + "description": "A component used to display an expandable list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n const handlePress = () => setExpanded(!expanded);\n\n return (\n \n }>\n \n \n \n\n }\n expanded={expanded}\n onPress={handlePress}>\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "List.Accordion", + "methods": [], + "statics": [], + "props": { + "title": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Title text for the list accordion." + }, + "description": { + "required": false, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Description text for the list accordion." + }, + "left": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(props: { color: ColorValue; style: Style }) => React.ReactNode", + "signature": { + "arguments": [ + { + "name": "props", + "type": { "name": "signature", "type": "object", - "raw": "{\n /**\n * Optional icon for the item.\n */\n icon?: IconSource;\n /**\n * Mandatory label.\n */\n label: string;\n /**\n * Called when the item is pressed. The menu is dismissed automatically\n * after `onPress` runs.\n */\n onPress: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label. Falls back to `label`.\n */\n 'aria-label'?: string;\n testID?: string;\n}", + "raw": "{ color: ColorValue; style: Style }", "signature": { "properties": [ { - "key": "icon", - "value": { - "name": "IconSource", - "required": false - } - }, - { - "key": "label", + "key": "color", "value": { - "name": "string", + "name": "ColorValue", "required": true } }, { - "key": "onPress", + "key": "style", "value": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - }, + "name": "Style", "required": true } - }, - { - "key": "aria-label", - "value": { - "name": "string", - "required": false - } - }, - { - "key": "testID", - "value": { - "name": "string", - "required": false - } } ] } - }, - { + } + } + ], + "return": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + } + } + }, + "description": "Callback which returns a React element to display on the left side." + }, + "right": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(props: { isExpanded: boolean }) => React.ReactNode", + "signature": { + "arguments": [ + { + "name": "props", + "type": { "name": "signature", "type": "object", - "raw": "{\n /**\n * Optional icon for the item.\n */\n icon?: IconSource;\n /**\n * Mandatory label.\n */\n label: string;\n /**\n * Called when the item is pressed. The menu is dismissed automatically\n * after `onPress` runs.\n */\n onPress: (e: GestureResponderEvent) => void;\n /**\n * Accessibility label. Falls back to `label`.\n */\n 'aria-label'?: string;\n testID?: string;\n}", + "raw": "{ isExpanded: boolean }", "signature": { "properties": [ { - "key": "icon", - "value": { - "name": "IconSource", - "required": false - } - }, - { - "key": "label", - "value": { - "name": "string", - "required": true - } - }, - { - "key": "onPress", + "key": "isExpanded", "value": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - }, + "name": "boolean", "required": true } - }, - { - "key": "aria-label", - "value": { - "name": "string", - "required": false - } - }, - { - "key": "testID", - "value": { - "name": "string", - "required": false - } } ] } } - ] + } + ], + "return": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + } + } + }, + "description": "Callback which returns a React element to display on the right side." + }, + "expanded": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether the accordion is expanded\nIf this prop is provided, the accordion will behave as a \"controlled component\".\nYou'll need to update this prop when you want to toggle the component or on `onPress`." + }, + "onPress": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" } - ] + } }, - "description": "Menu items. Spec calls for 2 to 6 items." + "description": "Function to execute on press." }, - "testID": { + "onLongPress": { "required": false, "tsType": { - "name": "string" + "name": "signature", + "type": "function", + "raw": "(e: GestureResponderEvent) => void", + "signature": { + "arguments": [ + { + "name": "e", + "type": { + "name": "GestureResponderEvent" + } + } + ], + "return": { + "name": "void" + } + } }, - "description": "", - "defaultValue": { - "value": "'floating-action-button-menu'", - "computed": false - } + "description": "Function to execute on long press." + }, + "delayLongPress": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." + }, + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Content of the section." }, "theme": { "required": false, @@ -7773,140 +7485,205 @@ "name": "ThemeProp" }, "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/FAB/Menu.tsx" - ] - }, - "IconButton/IconButton": { - "filepath": "IconButton/IconButton.tsx", - "title": "IconButton", - "description": "An icon button is a button which displays only an icon without a label.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { IconButton, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "link": "icon-button", - "data": { - "description": "An icon button is a button which displays only an icon without a label.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { IconButton, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n console.log('Pressed')}\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "displayName": "IconButton", - "methods": [], - "statics": [], - "props": { - "icon": { - "required": true, + }, + "background": { + "required": false, "tsType": { - "name": "IconSource" + "name": "PressableAndroidRippleConfig" }, - "description": "Icon to display." + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, - "mode": { + "style": { "required": false, "tsType": { - "name": "union", - "raw": "'outlined' | 'contained' | 'contained-tonal'", + "name": "StyleProp", "elements": [ { - "name": "literal", - "value": "'outlined'" - }, + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "Style that is passed to the root TouchableRipple container." + }, + "containerStyle": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ { - "name": "literal", - "value": "'contained'" - }, + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + }, + "description": "Style that is passed to the outermost container that wraps the entire content, including left and right items and both title and description." + }, + "contentStyle": { + "required": false, + "tsType": { + "name": "StyleProp", + "elements": [ { - "name": "literal", - "value": "'contained-tonal'" + "name": "ViewStyle" } - ] + ], + "raw": "StyleProp" }, - "description": "@supported Available in v5.x with theme version 3\nMode of the icon button. By default there is no specified mode - only pressable icon will be rendered." + "description": "Style that is passed to the content container, which wraps the title and description." }, - "iconColor": { + "titleStyle": { "required": false, "tsType": { - "name": "ColorValue" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "@renamed Renamed from 'color' to 'iconColor' in v5.x\nColor of the icon." + "description": "Style that is passed to Title element." }, - "containerColor": { + "descriptionStyle": { "required": false, "tsType": { - "name": "ColorValue" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "Background color of the icon container." + "description": "Style that is passed to Description element." }, - "selected": { + "titleNumberOfLines": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether icon button is selected. A selected button receives alternative combination of icon and container colors.", + "description": "Truncate Title text such that the total number of lines does not\nexceed this number.", "defaultValue": { - "value": "false", + "value": "1", "computed": false } }, - "size": { + "descriptionNumberOfLines": { "required": false, "tsType": { "name": "number" }, - "description": "Size of the icon.", + "description": "Truncate Description text such that the total number of lines does not\nexceed this number.", "defaultValue": { - "value": "24", + "value": "2", "computed": false } }, - "disabled": { + "titleMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch." + "description": "Specifies the largest possible scale a title font can reach." }, - "animated": { + "descriptionMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Whether an icon change is animated.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "Specifies the largest possible scale a description font can reach." + }, + "id": { + "required": false, + "tsType": { + "name": "union", + "raw": "string | number", + "elements": [ + { + "name": "string" + }, + { + "name": "number" + } + ] + }, + "description": "Id is used for distinguishing specific accordion when using List.AccordionGroup. Property is required when using List.AccordionGroup and has no impact on behavior when using standalone List.Accordion." + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "TestID used for testing purposes" }, "aria-label": { "required": false, "tsType": { "name": "string" }, - "description": "Accessibility label for the button. This is read by the screen reader when the user taps the button." + "description": "Accessibility label for the TouchableRipple. This is read by the screen reader when the user taps the touchable." }, - "contentStyle": { + "pointerEvents": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "ViewProps['pointerEvents']", + "raw": "ViewProps['pointerEvents']" }, - "description": "Style of button's inner content.\nUse this prop to apply custom height and width or to set a custom padding`." + "description": "`pointerEvents` passed to the `View` container", + "defaultValue": { + "value": "'none'", + "computed": false + } }, - "onPress": { + "hitSlop": { + "required": false, + "tsType": { + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" + }, + "description": "Amount of space between the touchable area and the edge of the component.\nThis can be used to enlarge the touchable area beyond the visible component." + } + } + }, + "type": "component", + "dependencies": [ + "src/components/List/ListAccordion.tsx" + ], + "group": "List" + }, + "List/ListAccordionGroup": { + "filepath": "List/ListAccordionGroup.tsx", + "title": "List.AccordionGroup", + "description": "List.AccordionGroup allows to control a group of List Accordions. `id` prop for List.Accordion is required in order for group to work.\nList.AccordionGroup can be a controlled or uncontrolled component. The example shows the uncontrolled version.\nAt most one Accordion can be expanded at a given time.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View, Text } from 'react-native';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n \n \n \n List.Accordion can be wrapped because implementation uses React.Context.\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "link": "list-accordion-group", + "data": { + "description": "List.AccordionGroup allows to control a group of List Accordions. `id` prop for List.Accordion is required in order for group to work.\nList.AccordionGroup can be a controlled or uncontrolled component. The example shows the uncontrolled version.\nAt most one Accordion can be expanded at a given time.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View, Text } from 'react-native';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n \n \n \n List.Accordion can be wrapped because implementation uses React.Context.\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "List.AccordionGroup", + "methods": [], + "statics": [], + "props": { + "onAccordionPress": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(e: GestureResponderEvent) => void", + "raw": "(expandedId: string | number) => void", "signature": { "arguments": [ { - "name": "e", + "name": "expandedId", "type": { - "name": "GestureResponderEvent" + "name": "union", + "raw": "string | number", + "elements": [ + { + "name": "string" + }, + { + "name": "number" + } + ] } } ], @@ -7915,121 +7692,77 @@ } } }, - "description": "Function to execute on press." + "description": "Function to execute on selection change." }, - "style": { + "expandedId": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", + "name": "union", + "raw": "string | number", "elements": [ { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - } - ], - "raw": "Animated.WithAnimatedValue>" - }, - "description": "" - }, - "ref": { - "required": false, - "tsType": { - "name": "ReactRef", - "raw": "React.Ref", - "elements": [ + "name": "string" + }, { - "name": "View" + "name": "number" } ] }, - "description": "" - }, - "testID": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "TestID used for testing purposes", - "defaultValue": { - "value": "'icon-button'", - "computed": false - } - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" + "description": "Id of the currently expanded list accordion" }, - "loading": { - "required": false, + "children": { + "required": true, "tsType": { - "name": "boolean" + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Whether to show a loading indicator.", - "defaultValue": { - "value": "false", - "computed": false - } + "description": "React elements containing list accordions" } } }, "type": "component", "dependencies": [ - "src/components/IconButton/IconButton.tsx" - ] + "src/components/List/ListAccordionGroup.tsx" + ], + "group": "List" }, - "Icon": { - "filepath": "Icon.tsx", - "title": "Icon", - "description": "An icon component which renders icon from vector library.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Icon, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "link": "icon", + "List/ListIcon": { + "filepath": "List/ListIcon.tsx", + "title": "List.Icon", + "description": "A component to show an icon in a list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n <>\n \n \n \n \n);\n\nexport default MyComponent;\n```", + "link": "list-icon", "data": { - "description": "An icon component which renders icon from vector library.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Icon, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n);\n\nexport default MyComponent;\n```", - "displayName": "Icon", + "description": "A component to show an icon in a list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n <>\n \n \n \n \n);\n\nexport default MyComponent;\n```", + "displayName": "List.Icon", "methods": [], "statics": [], "props": { - "size": { - "required": true, - "tsType": { - "name": "number" - }, - "description": "Size of icon." - }, - "allowFontScaling": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "" - }, - "source": { + "icon": { "required": true, "tsType": { - "name": "any" + "name": "IconSource" }, - "description": "Icon to display." + "description": "Icon to show." }, "color": { "required": false, "tsType": { "name": "ColorValue" }, - "description": "Color of the icon." + "description": "Color for the icon." }, - "testID": { + "style": { "required": false, "tsType": { - "name": "string" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "TestID used for testing purposes" + "description": "" }, "theme": { "required": false, @@ -8042,35 +7775,54 @@ }, "type": "component", "dependencies": [ - "src/components/Icon.tsx" - ] + "src/components/List/ListIcon.tsx" + ], + "group": "List" }, - "List/ListAccordion": { - "filepath": "List/ListAccordion.tsx", - "title": "List.Accordion", - "description": "A component used to display an expandable list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n const handlePress = () => setExpanded(!expanded);\n\n return (\n \n }>\n \n \n \n\n }\n expanded={expanded}\n onPress={handlePress}>\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "list-accordion", + "List/ListItem": { + "filepath": "List/ListItem.tsx", + "title": "List.Item", + "description": "A component to show tiles inside a List.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "link": "list-item", "data": { - "description": "A component used to display an expandable list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [expanded, setExpanded] = React.useState(true);\n\n const handlePress = () => setExpanded(!expanded);\n\n return (\n \n }>\n \n \n \n\n }\n expanded={expanded}\n onPress={handlePress}>\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "List.Accordion", + "description": "A component to show tiles inside a List.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", + "displayName": "List.Item", "methods": [], "statics": [], "props": { "title": { "required": true, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "union", + "raw": "| React.ReactNode\n| ((props: {\n selectable: boolean;\n ellipsizeMode: EllipsizeProp | undefined;\n color: ColorValue;\n fontSize: number;\n }) => React.ReactNode)", + "elements": [ + { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + { + "name": "unknown" + } + ] }, - "description": "Title text for the list accordion." + "description": "Title text for the list item." }, "description": { "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "union", + "raw": "| React.ReactNode\n| ((props: {\n selectable: boolean;\n ellipsizeMode: EllipsizeProp | undefined;\n color: ColorValue;\n fontSize: number;\n }) => React.ReactNode)", + "elements": [ + { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + { + "name": "unknown" + } + ] }, - "description": "Description text for the list accordion." + "description": "Description text for the list item or callback which returns a React element to display the description." }, "left": { "required": false, @@ -8120,7 +7872,7 @@ "tsType": { "name": "signature", "type": "function", - "raw": "(props: { isExpanded: boolean }) => React.ReactNode", + "raw": "(props: { color: ColorValue; style?: Style }) => React.ReactNode", "signature": { "arguments": [ { @@ -8128,15 +7880,22 @@ "type": { "name": "signature", "type": "object", - "raw": "{ isExpanded: boolean }", + "raw": "{ color: ColorValue; style?: Style }", "signature": { "properties": [ { - "key": "isExpanded", + "key": "color", "value": { - "name": "boolean", + "name": "ColorValue", "required": true } + }, + { + "key": "style", + "value": { + "name": "Style", + "required": false + } } ] } @@ -8151,13 +7910,6 @@ }, "description": "Callback which returns a React element to display on the right side." }, - "expanded": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Whether the accordion is expanded\nIf this prop is provided, the accordion will behave as a \"controlled component\".\nYou'll need to update this prop when you want to toggle the component or on `onPress`." - }, "onPress": { "required": false, "tsType": { @@ -8180,43 +7932,6 @@ }, "description": "Function to execute on press." }, - "onLongPress": { - "required": false, - "tsType": { - "name": "signature", - "type": "function", - "raw": "(e: GestureResponderEvent) => void", - "signature": { - "arguments": [ - { - "name": "e", - "type": { - "name": "GestureResponderEvent" - } - } - ], - "return": { - "name": "void" - } - } - }, - "description": "Function to execute on long press." - }, - "delayLongPress": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "The number of milliseconds a user must touch the element before executing `onLongPress`." - }, - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Content of the section." - }, "theme": { "required": false, "tsType": { @@ -8224,25 +7939,31 @@ }, "description": "" }, - "background": { + "style": { "required": false, "tsType": { - "name": "PressableAndroidRippleConfig" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + "description": "Style that is passed to the root TouchableRipple container." }, - "style": { + "ref": { "required": false, "tsType": { - "name": "StyleProp", + "name": "ReactRef", + "raw": "React.Ref", "elements": [ { - "name": "ViewStyle" + "name": "View" } - ], - "raw": "StyleProp" + ] }, - "description": "Style that is passed to the root TouchableRipple container." + "description": "" }, "containerStyle": { "required": false, @@ -8318,6 +8039,20 @@ "computed": false } }, + "titleEllipsizeMode": { + "required": false, + "tsType": { + "name": "EllipsizeProp" + }, + "description": "Ellipsize Mode for the Title. One of `'head'`, `'middle'`, `'tail'`, `'clip'`.\n\nSee [`ellipsizeMode`](https://reactnative.dev/docs/text#ellipsizemode)" + }, + "descriptionEllipsizeMode": { + "required": false, + "tsType": { + "name": "EllipsizeProp" + }, + "description": "Ellipsize Mode for the Description. One of `'head'`, `'middle'`, `'tail'`, `'clip'`.\n\nSee [`ellipsizeMode`](https://reactnative.dev/docs/text#ellipsizemode)" + }, "titleMaxFontSizeMultiplier": { "required": false, "tsType": { @@ -8332,121 +8067,239 @@ }, "description": "Specifies the largest possible scale a description font can reach." }, - "id": { + "testID": { "required": false, "tsType": { - "name": "union", - "raw": "string | number", + "name": "string" + }, + "description": "TestID used for testing purposes" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/List/ListItem.tsx" + ], + "group": "List" + }, + "List/ListSection": { + "filepath": "List/ListSection.tsx", + "title": "List.Section", + "description": "A component used to group list items.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Some title\n } />\n }\n />\n \n);\n\nexport default MyComponent;\n```", + "link": "list-section", + "data": { + "description": "A component used to group list items.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Some title\n } />\n }\n />\n \n);\n\nexport default MyComponent;\n```", + "displayName": "List.Section", + "methods": [], + "statics": [], + "props": { + "title": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "Title text for the section." + }, + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Content of the section." + }, + "theme": { + "required": false, + "tsType": { + "name": "ThemeProp" + }, + "description": "" + }, + "titleStyle": { + "required": false, + "tsType": { + "name": "StyleProp", "elements": [ { - "name": "string" - }, - { - "name": "number" + "name": "TextStyle" } - ] + ], + "raw": "StyleProp" }, - "description": "Id is used for distinguishing specific accordion when using List.AccordionGroup. Property is required when using List.AccordionGroup and has no impact on behavior when using standalone List.Accordion." + "description": "Style that is passed to Title element." }, - "testID": { + "style": { "required": false, "tsType": { - "name": "string" + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" }, - "description": "TestID used for testing purposes" - }, - "aria-label": { + "description": "" + } + } + }, + "type": "component", + "dependencies": [ + "src/components/List/ListSection.tsx" + ], + "group": "List" + }, + "List/ListSubheader": { + "filepath": "List/ListSubheader.tsx", + "title": "List.Subheader", + "description": "A component used to display a header in lists.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => My List Title;\n\nexport default MyComponent;\n```", + "link": "list-subheader", + "data": { + "description": "A component used to display a header in lists.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => My List Title;\n\nexport default MyComponent;\n```", + "displayName": "List.Subheader", + "methods": [], + "statics": [], + "props": { + "theme": { "required": false, "tsType": { - "name": "string" + "name": "ThemeProp" }, - "description": "Accessibility label for the TouchableRipple. This is read by the screen reader when the user taps the touchable." + "description": "" }, - "pointerEvents": { + "style": { "required": false, "tsType": { - "name": "ViewProps['pointerEvents']", - "raw": "ViewProps['pointerEvents']" + "name": "StyleProp", + "elements": [ + { + "name": "TextStyle" + } + ], + "raw": "StyleProp" }, - "description": "`pointerEvents` passed to the `View` container", - "defaultValue": { - "value": "'none'", - "computed": false - } + "description": "Style that is passed to Text element." }, - "hitSlop": { + "maxFontSizeMultiplier": { "required": false, "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" + "name": "number" }, - "description": "Amount of space between the touchable area and the edge of the component.\nThis can be used to enlarge the touchable area beyond the visible component." + "description": "Specifies the largest possible scale a text font can reach." } } }, "type": "component", "dependencies": [ - "src/components/List/ListAccordion.tsx" + "src/components/List/ListSubheader.tsx" ], "group": "List" }, - "List/ListAccordionGroup": { - "filepath": "List/ListAccordionGroup.tsx", - "title": "List.AccordionGroup", - "description": "List.AccordionGroup allows to control a group of List Accordions. `id` prop for List.Accordion is required in order for group to work.\nList.AccordionGroup can be a controlled or uncontrolled component. The example shows the uncontrolled version.\nAt most one Accordion can be expanded at a given time.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View, Text } from 'react-native';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n \n \n \n List.Accordion can be wrapped because implementation uses React.Context.\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "link": "list-accordion-group", + "Menu/Menu": { + "filepath": "Menu/Menu.tsx", + "title": "Menu", + "description": "Menus display a list of choices on temporary elevated surfaces. Their placement varies based on the element that opens them.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Menu, Divider, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const openMenu = () => setVisible(true);\n\n const closeMenu = () => setVisible(false);\n\n return (\n \n \n Show menu}>\n {}} title=\"Item 1\" />\n {}} title=\"Item 2\" />\n \n {}} title=\"Item 3\" />\n \n \n \n );\n};\n\nexport default MyComponent;\n```\n\n### Note\nWhen using `Menu` within a React Native's `Modal` component, you need to wrap all\n`Modal` contents within a `PaperProvider` in order for the menu to show. This\nwrapping is not necessary if you use Paper's `Modal` instead.", + "link": "menu", "data": { - "description": "List.AccordionGroup allows to control a group of List Accordions. `id` prop for List.Accordion is required in order for group to work.\nList.AccordionGroup can be a controlled or uncontrolled component. The example shows the uncontrolled version.\nAt most one Accordion can be expanded at a given time.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View, Text } from 'react-native';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n \n \n \n \n \n \n \n \n List.Accordion can be wrapped because implementation uses React.Context.\n \n \n \n \n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "List.AccordionGroup", + "description": "Menus display a list of choices on temporary elevated surfaces. Their placement varies based on the element that opens them.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Menu, Divider, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const openMenu = () => setVisible(true);\n\n const closeMenu = () => setVisible(false);\n\n return (\n \n \n Show menu}>\n {}} title=\"Item 1\" />\n {}} title=\"Item 2\" />\n \n {}} title=\"Item 3\" />\n \n \n \n );\n};\n\nexport default MyComponent;\n```\n\n### Note\nWhen using `Menu` within a React Native's `Modal` component, you need to wrap all\n`Modal` contents within a `PaperProvider` in order for the menu to show. This\nwrapping is not necessary if you use Paper's `Modal` instead.", + "displayName": "Menu", "methods": [], "statics": [], "props": { - "onAccordionPress": { - "required": false, + "visible": { + "required": true, "tsType": { - "name": "signature", - "type": "function", - "raw": "(expandedId: string | number) => void", - "signature": { - "arguments": [ - { - "name": "expandedId", - "type": { - "name": "union", - "raw": "string | number", - "elements": [ - { - "name": "string" - }, - { - "name": "number" + "name": "boolean" + }, + "description": "Whether the Menu is currently visible." + }, + "anchor": { + "required": true, + "tsType": { + "name": "union", + "raw": "React.ReactNode | { x: number; y: number }", + "elements": [ + { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + { + "name": "signature", + "type": "object", + "raw": "{ x: number; y: number }", + "signature": { + "properties": [ + { + "key": "x", + "value": { + "name": "number", + "required": true } - ] - } + }, + { + "key": "y", + "value": { + "name": "number", + "required": true + } + } + ] } - ], + } + ] + }, + "description": "The anchor to open the menu from. In most cases, it will be a button that opens the menu." + }, + "anchorPosition": { + "required": false, + "tsType": { + "name": "union", + "raw": "'top' | 'bottom'", + "elements": [ + { + "name": "literal", + "value": "'top'" + }, + { + "name": "literal", + "value": "'bottom'" + } + ] + }, + "description": "Whether the menu should open at the top of the anchor or at its bottom.\nApplied only when anchor is a node, not an x/y position." + }, + "statusBarHeight": { + "required": false, + "tsType": { + "name": "number" + }, + "description": "Extra margin to add at the top of the menu to account for translucent status bar on Android.\nIf you are using Expo, we assume translucent status bar and set a height for status bar automatically.\nPass `0` or a custom value to and customize it.\nThis is automatically handled on iOS." + }, + "onDismiss": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], "return": { "name": "void" } } }, - "description": "Function to execute on selection change." + "description": "Callback called when Menu is dismissed. The `visible` prop needs to be updated when this is called." }, - "expandedId": { + "overlayAccessibilityLabel": { "required": false, "tsType": { - "name": "union", - "raw": "string | number", - "elements": [ - { - "name": "string" - }, - { - "name": "number" - } - ] + "name": "string" }, - "description": "Id of the currently expanded list accordion" + "description": "Accessibility label for the overlay. This is read by the screen reader when the user taps outside the menu.", + "defaultValue": { + "value": "'Close menu'", + "computed": false + } }, "children": { "required": true, @@ -8454,40 +8307,26 @@ "name": "ReactReactNode", "raw": "React.ReactNode" }, - "description": "React elements containing list accordions" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/List/ListAccordionGroup.tsx" - ], - "group": "List" - }, - "List/ListIcon": { - "filepath": "List/ListIcon.tsx", - "title": "List.Icon", - "description": "A component to show an icon in a list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n <>\n \n \n \n \n);\n\nexport default MyComponent;\n```", - "link": "list-icon", - "data": { - "description": "A component to show an icon in a list item.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n <>\n \n \n \n \n);\n\nexport default MyComponent;\n```", - "displayName": "List.Icon", - "methods": [], - "statics": [], - "props": { - "icon": { - "required": true, - "tsType": { - "name": "IconSource" - }, - "description": "Icon to show." + "description": "Content of the `Menu`." }, - "color": { + "contentStyle": { "required": false, "tsType": { - "name": "ColorValue" + "name": "Animated.WithAnimatedValue", + "elements": [ + { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + } + ], + "raw": "Animated.WithAnimatedValue>" }, - "description": "Color for the icon." + "description": "Style of menu's inner content." }, "style": { "required": false, @@ -8502,151 +8341,125 @@ }, "description": "" }, + "elevation": { + "required": false, + "tsType": { + "name": "Elevation" + }, + "description": "Elevation level of the menu's content. Shadow styles are calculated based on this value. Default `backgroundColor` is taken from the corresponding `theme.colors.elevation` property. By default equals `2`.\n@supported Available in v5.x with theme version 3", + "defaultValue": { + "value": "2", + "computed": false + } + }, + "mode": { + "required": false, + "tsType": { + "name": "union", + "raw": "'flat' | 'elevated'", + "elements": [ + { + "name": "literal", + "value": "'flat'" + }, + { + "name": "literal", + "value": "'elevated'" + } + ] + }, + "description": "Mode of the menu's content.\n- `elevated` - Surface with a shadow and background color corresponding to set `elevation` value.\n- `flat` - Surface without a shadow, with the background color corresponding to set `elevation` value.\n\n@supported Available in v5.x with theme version 3", + "defaultValue": { + "value": "'elevated'", + "computed": false + } + }, "theme": { "required": false, "tsType": { "name": "ThemeProp" }, "description": "" + }, + "keyboardShouldPersistTaps": { + "required": false, + "tsType": { + "name": "ScrollViewProps['keyboardShouldPersistTaps']", + "raw": "ScrollViewProps['keyboardShouldPersistTaps']" + }, + "description": "Inner ScrollView prop" + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "testID to be used on tests.", + "defaultValue": { + "value": "'menu'", + "computed": false + } } } }, "type": "component", "dependencies": [ - "src/components/List/ListIcon.tsx" - ], - "group": "List" + "src/components/Menu/Menu.tsx" + ] }, - "List/ListItem": { - "filepath": "List/ListItem.tsx", - "title": "List.Item", - "description": "A component to show tiles inside a List.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "link": "list-item", + "Menu/MenuItem": { + "filepath": "Menu/MenuItem.tsx", + "title": "Menu.Item", + "description": "A component to show a single list item inside a Menu.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Menu } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n {}} title=\"Redo\" />\n {}} title=\"Undo\" />\n {}} title=\"Cut\" disabled />\n {}} title=\"Copy\" disabled />\n {}} title=\"Paste\" />\n \n);\n\nexport default MyComponent;\n```", + "link": "menu-item", "data": { - "description": "A component to show tiles inside a List.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => (\n }\n />\n);\n\nexport default MyComponent;\n```\n\n@extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple", - "displayName": "List.Item", + "description": "A component to show a single list item inside a Menu.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Menu } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n {}} title=\"Redo\" />\n {}} title=\"Undo\" />\n {}} title=\"Cut\" disabled />\n {}} title=\"Copy\" disabled />\n {}} title=\"Paste\" />\n \n);\n\nexport default MyComponent;\n```", + "displayName": "Menu.Item", "methods": [], "statics": [], "props": { "title": { "required": true, "tsType": { - "name": "union", - "raw": "| React.ReactNode\n| ((props: {\n selectable: boolean;\n ellipsizeMode: EllipsizeProp | undefined;\n color: ColorValue;\n fontSize: number;\n }) => React.ReactNode)", - "elements": [ - { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - { - "name": "unknown" - } - ] + "name": "ReactReactNode", + "raw": "React.ReactNode" }, - "description": "Title text for the list item." + "description": "Title text for the `MenuItem`." }, - "description": { + "leadingIcon": { "required": false, "tsType": { - "name": "union", - "raw": "| React.ReactNode\n| ((props: {\n selectable: boolean;\n ellipsizeMode: EllipsizeProp | undefined;\n color: ColorValue;\n fontSize: number;\n }) => React.ReactNode)", - "elements": [ - { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - { - "name": "unknown" - } - ] + "name": "IconSource" }, - "description": "Description text for the list item or callback which returns a React element to display the description." + "description": "@renamed Renamed from 'icon' to 'leadingIcon' in v5.x\n\nLeading icon to display for the `MenuItem`." }, - "left": { + "trailingIcon": { "required": false, "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { color: ColorValue; style: Style }) => React.ReactNode", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ color: ColorValue; style: Style }", - "signature": { - "properties": [ - { - "key": "color", - "value": { - "name": "ColorValue", - "required": true - } - }, - { - "key": "style", - "value": { - "name": "Style", - "required": true - } - } - ] - } - } - } - ], - "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - } - } + "name": "IconSource" }, - "description": "Callback which returns a React element to display on the left side." + "description": "@supported Available in v5.x with theme version 3\n\nTrailing icon to display for the `MenuItem`." }, - "right": { - "required": false, - "tsType": { - "name": "signature", - "type": "function", - "raw": "(props: { color: ColorValue; style?: Style }) => React.ReactNode", - "signature": { - "arguments": [ - { - "name": "props", - "type": { - "name": "signature", - "type": "object", - "raw": "{ color: ColorValue; style?: Style }", - "signature": { - "properties": [ - { - "key": "color", - "value": { - "name": "ColorValue", - "required": true - } - }, - { - "key": "style", - "value": { - "name": "Style", - "required": false - } - } - ] - } - } - } - ], - "return": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - } - } + "disabled": { + "required": false, + "tsType": { + "name": "boolean" }, - "description": "Callback which returns a React element to display on the right side." + "description": "Whether the 'item' is disabled. A disabled 'item' is greyed out and `onPress` is not called on touch." + }, + "dense": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "@supported Available in v5.x with theme version 3\n\nSets min height with densed layout." + }, + "background": { + "required": false, + "tsType": { + "name": "PressableAndroidRippleConfig" + }, + "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" }, "onPress": { "required": false, @@ -8670,12 +8483,16 @@ }, "description": "Function to execute on press." }, - "theme": { + "titleMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "ThemeProp" + "name": "number" }, - "description": "" + "description": "Specifies the largest possible scale a title font can reach.", + "defaultValue": { + "value": "1.5", + "computed": false + } }, "style": { "required": false, @@ -8688,20 +8505,7 @@ ], "raw": "StyleProp" }, - "description": "Style that is passed to the root TouchableRipple container." - }, - "ref": { - "required": false, - "tsType": { - "name": "ReactRef", - "raw": "React.Ref", - "elements": [ - { - "name": "View" - } - ] - }, - "description": "" + "description": "Style that is passed to the root TouchableRipple container.\n" }, "containerStyle": { "required": false, @@ -8714,7 +8518,7 @@ ], "raw": "StyleProp" }, - "description": "Style that is passed to the outermost container that wraps the entire content, including left and right items and both title and description." + "description": "Style that is passed to the outermost container that wraps the entire content, including leading and trailing icons and title text." }, "contentStyle": { "required": false, @@ -8727,7 +8531,7 @@ ], "raw": "StyleProp" }, - "description": "Style that is passed to the content container, which wraps the title and description." + "description": "Style that is passed to the content container, which wraps the title text." }, "titleStyle": { "required": false, @@ -8740,170 +8544,187 @@ ], "raw": "StyleProp" }, - "description": "Style that is passed to Title element." + "description": "Style that is passed to the Title element." }, - "descriptionStyle": { + "theme": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "ThemeProp" }, - "description": "Style that is passed to Description element." + "description": "" }, - "titleNumberOfLines": { + "hitSlop": { "required": false, "tsType": { - "name": "number" + "name": "TouchableRippleProps['hitSlop']", + "raw": "TouchableRippleProps['hitSlop']" }, - "description": "Truncate Title text such that the total number of lines does not\nexceed this number.", - "defaultValue": { - "value": "1", - "computed": false - } + "description": "Sets additional distance outside of element in which a press can be detected." }, - "descriptionNumberOfLines": { + "testID": { "required": false, "tsType": { - "name": "number" + "name": "string" }, - "description": "Truncate Description text such that the total number of lines does not\nexceed this number.", + "description": "TestID used for testing purposes", "defaultValue": { - "value": "2", + "value": "'menu-item'", "computed": false } }, - "titleEllipsizeMode": { + "aria-label": { "required": false, "tsType": { - "name": "EllipsizeProp" + "name": "string" }, - "description": "Ellipsize Mode for the Title. One of `'head'`, `'middle'`, `'tail'`, `'clip'`.\n\nSee [`ellipsizeMode`](https://reactnative.dev/docs/text#ellipsizemode)" + "description": "Accessibility label for the Touchable. This is read by the screen reader when the user taps the component." }, - "descriptionEllipsizeMode": { + "aria-checked": { "required": false, "tsType": { - "name": "EllipsizeProp" + "name": "union", + "raw": "boolean | 'mixed'", + "elements": [ + { + "name": "boolean" + }, + { + "name": "literal", + "value": "'mixed'" + } + ] }, - "description": "Ellipsize Mode for the Description. One of `'head'`, `'middle'`, `'tail'`, `'clip'`.\n\nSee [`ellipsizeMode`](https://reactnative.dev/docs/text#ellipsizemode)" + "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." }, - "titleMaxFontSizeMultiplier": { + "aria-selected": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "Specifies the largest possible scale a title font can reach." + "description": "Indicates whether the element is selected." }, - "descriptionMaxFontSizeMultiplier": { + "aria-busy": { "required": false, "tsType": { - "name": "number" + "name": "boolean" }, - "description": "Specifies the largest possible scale a description font can reach." + "description": "Indicates whether the element is currently busy (e.g. loading)." }, - "testID": { + "aria-expanded": { "required": false, "tsType": { - "name": "string" + "name": "boolean" }, - "description": "TestID used for testing purposes" + "description": "Indicates whether the element's controlled content is expanded." } } }, "type": "component", "dependencies": [ - "src/components/List/ListItem.tsx" + "src/components/Menu/MenuItem.tsx" ], - "group": "List" + "group": "Menu" }, - "List/ListSection": { - "filepath": "List/ListSection.tsx", - "title": "List.Section", - "description": "A component used to group list items.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Some title\n } />\n }\n />\n \n);\n\nexport default MyComponent;\n```", - "link": "list-section", + "Modal": { + "filepath": "Modal.tsx", + "title": "Modal", + "description": "The Modal component is a simple way to present content above an enclosing view.\nTo render the `Modal` above other components, you'll need to wrap it with the [`Portal`](./Portal) component.\nNote that this modal is NOT accessible by default; if you need an accessible modal, please use the React Native Modal.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Modal, Portal, Text, Button, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showModal = () => setVisible(true);\n const hideModal = () => setVisible(false);\n const containerStyle = { backgroundColor: 'white', padding: 20 };\n\n return (\n \n \n \n Example Modal. Click outside this area to dismiss.\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "link": "modal", "data": { - "description": "A component used to group list items.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List, Palette } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n Some title\n } />\n }\n />\n \n);\n\nexport default MyComponent;\n```", - "displayName": "List.Section", + "description": "The Modal component is a simple way to present content above an enclosing view.\nTo render the `Modal` above other components, you'll need to wrap it with the [`Portal`](./Portal) component.\nNote that this modal is NOT accessible by default; if you need an accessible modal, please use the React Native Modal.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Modal, Portal, Text, Button, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showModal = () => setVisible(true);\n const hideModal = () => setVisible(false);\n const containerStyle = { backgroundColor: 'white', padding: 20 };\n\n return (\n \n \n \n Example Modal. Click outside this area to dismiss.\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", + "displayName": "Modal", "methods": [], "statics": [], "props": { - "title": { + "dismissable": { "required": false, "tsType": { - "name": "string" + "name": "boolean" }, - "description": "Title text for the section." + "description": "Determines whether clicking outside the modal dismisses it.", + "defaultValue": { + "value": "true", + "computed": false + } }, - "children": { - "required": true, + "dismissableBackButton": { + "required": false, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "boolean" }, - "description": "Content of the section." + "description": "Determines whether clicking Android hardware back button dismisses the dialog.", + "defaultValue": { + "value": "dismissable", + "computed": true + } }, - "theme": { + "onDismiss": { "required": false, "tsType": { - "name": "ThemeProp" + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + } }, - "description": "" + "description": "Callback that is called when the user dismisses the modal.", + "defaultValue": { + "value": "() => {}", + "computed": false + } }, - "titleStyle": { + "overlayAccessibilityLabel": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" + "name": "string" }, - "description": "Style that is passed to Title element." + "description": "Accessibility label for the overlay. This is read by the screen reader when the user taps outside the modal.", + "defaultValue": { + "value": "'Close modal'", + "computed": false + } }, - "style": { + "visible": { "required": false, "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" + "name": "boolean" }, - "description": "" - } - } - }, - "type": "component", - "dependencies": [ - "src/components/List/ListSection.tsx" - ], - "group": "List" - }, - "List/ListSubheader": { - "filepath": "List/ListSubheader.tsx", - "title": "List.Subheader", - "description": "A component used to display a header in lists.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => My List Title;\n\nexport default MyComponent;\n```", - "link": "list-subheader", - "data": { - "description": "A component used to display a header in lists.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { List } from 'react-native-paper';\n\nconst MyComponent = () => My List Title;\n\nexport default MyComponent;\n```", - "displayName": "List.Subheader", - "methods": [], - "statics": [], - "props": { - "theme": { + "description": "Determines Whether the modal is visible.", + "defaultValue": { + "value": "false", + "computed": false + } + }, + "children": { + "required": true, + "tsType": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + }, + "description": "Content of the `Modal`." + }, + "contentContainerStyle": { "required": false, "tsType": { - "name": "ThemeProp" + "name": "Animated.WithAnimatedValue", + "elements": [ + { + "name": "StyleProp", + "elements": [ + { + "name": "ViewStyle" + } + ], + "raw": "StyleProp" + } + ], + "raw": "Animated.WithAnimatedValue>" }, - "description": "" + "description": "Style for the content of the modal" }, "style": { "required": false, @@ -8911,306 +8732,683 @@ "name": "StyleProp", "elements": [ { - "name": "TextStyle" + "name": "ViewStyle" } ], - "raw": "StyleProp" + "raw": "StyleProp" }, - "description": "Style that is passed to Text element." + "description": "Style for the wrapper of the modal.\nUse this prop to change the default wrapper style or to override safe area insets with marginTop and marginBottom." }, - "maxFontSizeMultiplier": { + "theme": { "required": false, "tsType": { - "name": "number" + "name": "ThemeProp" }, - "description": "Specifies the largest possible scale a text font can reach." + "description": "" + }, + "testID": { + "required": false, + "tsType": { + "name": "string" + }, + "description": "testID to be used on tests.", + "defaultValue": { + "value": "'modal'", + "computed": false + } } } }, "type": "component", "dependencies": [ - "src/components/List/ListSubheader.tsx" - ], - "group": "List" + "src/components/Modal.tsx" + ] }, - "Menu/Menu": { - "filepath": "Menu/Menu.tsx", - "title": "Menu", - "description": "Menus display a list of choices on temporary elevated surfaces. Their placement varies based on the element that opens them.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Menu, Divider, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const openMenu = () => setVisible(true);\n\n const closeMenu = () => setVisible(false);\n\n return (\n \n \n Show menu}>\n {}} title=\"Item 1\" />\n {}} title=\"Item 2\" />\n \n {}} title=\"Item 3\" />\n \n \n \n );\n};\n\nexport default MyComponent;\n```\n\n### Note\nWhen using `Menu` within a React Native's `Modal` component, you need to wrap all\n`Modal` contents within a `PaperProvider` in order for the menu to show. This\nwrapping is not necessary if you use Paper's `Modal` instead.", - "link": "menu", + "NavigationBar/NavigationBar": { + "filepath": "NavigationBar/NavigationBar.tsx", + "title": "NavigationBar", + "description": "The Material Design 3 flexible navigation bar. It can easily be integrated\nwith [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/).\n\nSet the `variant` prop to `'horizontal'` to lay items out horizontally\n(icon beside label) in medium-width windows.\n\n## Usage\n### without React Navigation\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { NavigationBar, Text, Provider } from 'react-native-paper';\n\nfunction HomeScreen() {\n return (\n \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nexport default function MyComponent() {\n const [index, setIndex] = React.useState(0);\n\n const routes = [\n { key: 'home', title: 'Home', focusedIcon: 'home' },\n { key: 'settings', title: 'Settings', focusedIcon: 'cog' },\n ];\n\n const renderScene = ({ route }) => {\n switch (route.key) {\n case 'home':\n return ;\n case 'settings':\n return ;\n default:\n return null;\n }\n };\n\n return (\n \n {renderScene({ route: routes[index] })}\n {\n const newIndex = routes.findIndex((r) => r.key === route.key);\n if (newIndex !== -1) {\n setIndex(newIndex);\n }\n }}\n getLabelText={({ route }) => route.title}\n />\n \n );\n}\n```", + "link": "navigation-bar", "data": { - "description": "Menus display a list of choices on temporary elevated surfaces. Their placement varies based on the element that opens them.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Button, Menu, Divider, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const openMenu = () => setVisible(true);\n\n const closeMenu = () => setVisible(false);\n\n return (\n \n \n Show menu}>\n {}} title=\"Item 1\" />\n {}} title=\"Item 2\" />\n \n {}} title=\"Item 3\" />\n \n \n \n );\n};\n\nexport default MyComponent;\n```\n\n### Note\nWhen using `Menu` within a React Native's `Modal` component, you need to wrap all\n`Modal` contents within a `PaperProvider` in order for the menu to show. This\nwrapping is not necessary if you use Paper's `Modal` instead.", - "displayName": "Menu", + "description": "The Material Design 3 flexible navigation bar. It can easily be integrated\nwith [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/).\n\nSet the `variant` prop to `'horizontal'` to lay items out horizontally\n(icon beside label) in medium-width windows.\n\n## Usage\n### without React Navigation\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { NavigationBar, Text, Provider } from 'react-native-paper';\n\nfunction HomeScreen() {\n return (\n \n Home!\n \n );\n}\n\nfunction SettingsScreen() {\n return (\n \n Settings!\n \n );\n}\n\nexport default function MyComponent() {\n const [index, setIndex] = React.useState(0);\n\n const routes = [\n { key: 'home', title: 'Home', focusedIcon: 'home' },\n { key: 'settings', title: 'Settings', focusedIcon: 'cog' },\n ];\n\n const renderScene = ({ route }) => {\n switch (route.key) {\n case 'home':\n return ;\n case 'settings':\n return ;\n default:\n return null;\n }\n };\n\n return (\n \n {renderScene({ route: routes[index] })}\n {\n const newIndex = routes.findIndex((r) => r.key === route.key);\n if (newIndex !== -1) {\n setIndex(newIndex);\n }\n }}\n getLabelText={({ route }) => route.title}\n />\n \n );\n}\n```", + "displayName": "NavigationBar", "methods": [], "statics": [], "props": { - "visible": { - "required": true, + "labeled": { + "required": false, "tsType": { "name": "boolean" }, - "description": "Whether the Menu is currently visible." + "description": "Whether to show labels in tabs. When `false`, only icons will be displayed.", + "defaultValue": { + "value": "true", + "computed": false + } }, - "anchor": { - "required": true, + "variant": { + "required": false, "tsType": { "name": "union", - "raw": "React.ReactNode | { x: number; y: number }", + "raw": "'stacked' | 'horizontal'", "elements": [ { - "name": "ReactReactNode", - "raw": "React.ReactNode" + "name": "literal", + "value": "'stacked'" }, { - "name": "signature", - "type": "object", - "raw": "{ x: number; y: number }", - "signature": { - "properties": [ - { - "key": "x", - "value": { - "name": "number", - "required": true + "name": "literal", + "value": "'horizontal'" + } + ] + }, + "description": "The item layout variant of the flexible navigation bar.\n\n- `stacked` (default): the icon sits above the label.\n- `horizontal`: the icon sits beside the label and the active indicator\n hugs both. Recommended for medium-width windows (e.g. foldables and\n tablets). Has no effect when `labeled` is `false`.", + "defaultValue": { + "value": "'stacked'", + "computed": false + } + }, + "compact": { + "required": false, + "tsType": { + "name": "boolean" + }, + "description": "Whether tabs should be spread across the entire width." + }, + "navigationState": { + "required": true, + "tsType": { + "name": "signature", + "type": "object", + "raw": "{\n index: number;\n routes: Route[];\n}", + "signature": { + "properties": [ + { + "key": "index", + "value": { + "name": "number", + "required": true + } + }, + { + "key": "routes", + "value": { + "name": "Array", + "elements": [ + { + "name": "Route" } - }, - { - "key": "y", - "value": { - "name": "number", - "required": true + ], + "raw": "Route[]", + "required": true + } + } + ] + } + }, + "description": "State for the bottom navigation. The state should contain the following properties:\n\n- `index`: a number representing the index of the active route in the `routes` array\n- `routes`: an array containing a list of route objects used for rendering the tabs\n\nEach route object should contain the following properties:\n\n- `key`: a unique key to identify the route (required)\n- `title`: title of the route to use as the tab label\n- `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\n- `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\n- `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text.\n- `accessibilityLabel`: accessibility label for the tab button\n- `testID`: test id for the tab button\n\nExample:\n\n```js\n{\n index: 1,\n routes: [\n { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},\n { key: 'albums', title: 'Albums', focusedIcon: 'album' },\n { key: 'recents', title: 'Recents', focusedIcon: 'history' },\n { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },\n ]\n}\n```\n\n`NavigationBar` is a controlled component, which means the `index` needs to be updated via the `onTabPress` callback." + }, + "renderIcon": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(props: {\n route: Route;\n focused: boolean;\n color: ColorValue;\n}) => React.ReactNode", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{\n route: Route;\n focused: boolean;\n color: ColorValue;\n}", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + }, + { + "key": "focused", + "value": { + "name": "boolean", + "required": true + } + }, + { + "key": "color", + "value": { + "name": "ColorValue", + "required": true + } + } + ] + } + } + } + ], + "return": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + } + } + }, + "description": "Callback which returns a React Element to be used as tab icon." + }, + "renderLabel": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(props: {\n route: Route;\n focused: boolean;\n color: ColorValue;\n}) => React.ReactNode", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{\n route: Route;\n focused: boolean;\n color: ColorValue;\n}", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + }, + { + "key": "focused", + "value": { + "name": "boolean", + "required": true + } + }, + { + "key": "color", + "value": { + "name": "ColorValue", + "required": true + } + } + ] + } + } + } + ], + "return": { + "name": "ReactReactNode", + "raw": "React.ReactNode" + } + } + }, + "description": "Callback which React Element to be used as tab label." + }, + "renderTouchable": { + "required": false, + "tsType": { + "name": "signature", + "type": "function", + "raw": "(props: TouchableProps) => React.ReactNode", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "intersection", + "raw": "TouchableRippleProps & {\n key: string;\n route: Route;\n children: React.ReactNode;\n borderless?: boolean;\n centered?: boolean;\n rippleColor?: ColorValue;\n onHoverIn?: () => void;\n onHoverOut?: () => void;\n onFocus?: () => void;\n onBlur?: () => void;\n}", + "elements": [ + { + "name": "TouchableRippleProps" + }, + { + "name": "signature", + "type": "object", + "raw": "{\n key: string;\n route: Route;\n children: React.ReactNode;\n borderless?: boolean;\n centered?: boolean;\n rippleColor?: ColorValue;\n onHoverIn?: () => void;\n onHoverOut?: () => void;\n onFocus?: () => void;\n onBlur?: () => void;\n}", + "signature": { + "properties": [ + { + "key": "key", + "value": { + "name": "string", + "required": true + } + }, + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + }, + { + "key": "children", + "value": { + "name": "ReactReactNode", + "raw": "React.ReactNode", + "required": true + } + }, + { + "key": "borderless", + "value": { + "name": "boolean", + "required": false + } + }, + { + "key": "centered", + "value": { + "name": "boolean", + "required": false + } + }, + { + "key": "rippleColor", + "value": { + "name": "ColorValue", + "required": false + } + }, + { + "key": "onHoverIn", + "value": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + }, + "required": false + } + }, + { + "key": "onHoverOut", + "value": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + }, + "required": false + } + }, + { + "key": "onFocus", + "value": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + }, + "required": false + } + }, + { + "key": "onBlur", + "value": { + "name": "signature", + "type": "function", + "raw": "() => void", + "signature": { + "arguments": [], + "return": { + "name": "void" + } + }, + "required": false + } + } + ] + } } - } - ] + ] + } } + ], + "return": { + "name": "ReactReactNode", + "raw": "React.ReactNode" } - ] - }, - "description": "The anchor to open the menu from. In most cases, it will be a button that opens the menu." - }, - "anchorPosition": { - "required": false, - "tsType": { - "name": "union", - "raw": "'top' | 'bottom'", - "elements": [ - { - "name": "literal", - "value": "'top'" - }, - { - "name": "literal", - "value": "'bottom'" - } - ] - }, - "description": "Whether the menu should open at the top of the anchor or at its bottom.\nApplied only when anchor is a node, not an x/y position." - }, - "statusBarHeight": { - "required": false, - "tsType": { - "name": "number" + } }, - "description": "Extra margin to add at the top of the menu to account for translucent status bar on Android.\nIf you are using Expo, we assume translucent status bar and set a height for status bar automatically.\nPass `0` or a custom value to and customize it.\nThis is automatically handled on iOS." + "description": "Callback which returns a React element to be used as the touchable for the tab item.\nRenders a `TouchableRipple` on Android and `Pressable` on iOS.", + "defaultValue": { + "value": "({ key, ...props }: TouchableProps) => (\n \n)", + "computed": false + } }, - "onDismiss": { + "getAccessibilityLabel": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "() => void", + "raw": "(props: { route: Route }) => string | undefined", "signature": { - "arguments": [], + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + } + } + ], "return": { - "name": "void" + "name": "union", + "raw": "string | undefined", + "elements": [ + { + "name": "string" + }, + { + "name": "undefined" + } + ] } } }, - "description": "Callback called when Menu is dismissed. The `visible` prop needs to be updated when this is called." - }, - "overlayAccessibilityLabel": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Accessibility label for the overlay. This is read by the screen reader when the user taps outside the menu.", + "description": "Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab.\nUses `route.accessibilityLabel` by default.", "defaultValue": { - "value": "'Close menu'", + "value": "({ route }: { route: Route }) =>\nroute.accessibilityLabel", "computed": false } }, - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Content of the `Menu`." - }, - "contentStyle": { + "getBadge": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", - "elements": [ - { - "name": "StyleProp", + "name": "signature", + "type": "function", + "raw": "(props: { route: Route }) => boolean | number | string | undefined", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + } + } + ], + "return": { + "name": "union", + "raw": "boolean | number | string | undefined", "elements": [ { - "name": "ViewStyle" + "name": "boolean" + }, + { + "name": "number" + }, + { + "name": "string" + }, + { + "name": "undefined" } - ], - "raw": "StyleProp" - } - ], - "raw": "Animated.WithAnimatedValue>" - }, - "description": "Style of menu's inner content." - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" + ] } - ], - "raw": "StyleProp" + } }, - "description": "" + "description": "Get badge for the tab, uses `route.badge` by default.", + "defaultValue": { + "value": "({ route }: { route: Route }) => route.badge", + "computed": false + } }, - "elevation": { + "getLabelText": { "required": false, "tsType": { - "name": "Elevation" + "name": "signature", + "type": "function", + "raw": "(props: { route: Route }) => string | undefined", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + } + } + ], + "return": { + "name": "union", + "raw": "string | undefined", + "elements": [ + { + "name": "string" + }, + { + "name": "undefined" + } + ] + } + } }, - "description": "Elevation level of the menu's content. Shadow styles are calculated based on this value. Default `backgroundColor` is taken from the corresponding `theme.colors.elevation` property. By default equals `2`.\n@supported Available in v5.x with theme version 3", + "description": "Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component.", "defaultValue": { - "value": "2", + "value": "({ route }: { route: Route }) => route.title", "computed": false } }, - "mode": { + "getTestID": { "required": false, "tsType": { - "name": "union", - "raw": "'flat' | 'elevated'", - "elements": [ - { - "name": "literal", - "value": "'flat'" - }, - { - "name": "literal", - "value": "'elevated'" + "name": "signature", + "type": "function", + "raw": "(props: { route: Route }) => string | undefined", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + } + } + ], + "return": { + "name": "union", + "raw": "string | undefined", + "elements": [ + { + "name": "string" + }, + { + "name": "undefined" + } + ] } - ] + } }, - "description": "Mode of the menu's content.\n- `elevated` - Surface with a shadow and background color corresponding to set `elevation` value.\n- `flat` - Surface without a shadow, with the background color corresponding to set `elevation` value.\n\n@supported Available in v5.x with theme version 3", + "description": "Get the id to locate this tab button in tests, uses `route.testID` by default.", "defaultValue": { - "value": "'elevated'", + "value": "({ route }: { route: Route }) => route.testID", "computed": false } }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - }, - "keyboardShouldPersistTaps": { - "required": false, - "tsType": { - "name": "ScrollViewProps['keyboardShouldPersistTaps']", - "raw": "ScrollViewProps['keyboardShouldPersistTaps']" - }, - "description": "Inner ScrollView prop" - }, - "testID": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "testID to be used on tests.", - "defaultValue": { - "value": "'menu'", - "computed": false - } - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Menu/Menu.tsx" - ] - }, - "Menu/MenuItem": { - "filepath": "Menu/MenuItem.tsx", - "title": "Menu.Item", - "description": "A component to show a single list item inside a Menu.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Menu } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n {}} title=\"Redo\" />\n {}} title=\"Undo\" />\n {}} title=\"Cut\" disabled />\n {}} title=\"Copy\" disabled />\n {}} title=\"Paste\" />\n \n);\n\nexport default MyComponent;\n```", - "link": "menu-item", - "data": { - "description": "A component to show a single list item inside a Menu.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { View } from 'react-native';\nimport { Menu } from 'react-native-paper';\n\nconst MyComponent = () => (\n \n {}} title=\"Redo\" />\n {}} title=\"Undo\" />\n {}} title=\"Cut\" disabled />\n {}} title=\"Copy\" disabled />\n {}} title=\"Paste\" />\n \n);\n\nexport default MyComponent;\n```", - "displayName": "Menu.Item", - "methods": [], - "statics": [], - "props": { - "title": { + "onTabPress": { "required": true, "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Title text for the `MenuItem`." - }, - "leadingIcon": { - "required": false, - "tsType": { - "name": "IconSource" - }, - "description": "@renamed Renamed from 'icon' to 'leadingIcon' in v5.x\n\nLeading icon to display for the `MenuItem`." - }, - "trailingIcon": { - "required": false, - "tsType": { - "name": "IconSource" - }, - "description": "@supported Available in v5.x with theme version 3\n\nTrailing icon to display for the `MenuItem`." - }, - "disabled": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Whether the 'item' is disabled. A disabled 'item' is greyed out and `onPress` is not called on touch." - }, - "dense": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "@supported Available in v5.x with theme version 3\n\nSets min height with densed layout." - }, - "background": { - "required": false, - "tsType": { - "name": "PressableAndroidRippleConfig" + "name": "signature", + "type": "function", + "raw": "(props: { route: Route } & TabPressEvent) => void", + "signature": { + "arguments": [ + { + "name": "props", + "type": { + "name": "intersection", + "raw": "{ route: Route } & TabPressEvent", + "elements": [ + { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + }, + { + "name": "signature", + "type": "object", + "raw": "{\n defaultPrevented: boolean;\n preventDefault(): void;\n}", + "signature": { + "properties": [ + { + "key": "defaultPrevented", + "value": { + "name": "boolean", + "required": true + } + }, + { + "key": "preventDefault", + "value": { + "name": "void", + "required": true + } + } + ] + } + } + ] + } + } + ], + "return": { + "name": "void" + } + } }, - "description": "Type of background drawabale to display the feedback (Android).\nhttps://reactnative.dev/docs/pressable#rippleconfig" + "description": "Function to execute on tab press. It receives the route for the pressed tab. Use this to update the navigation state." }, - "onPress": { + "onTabLongPress": { "required": false, "tsType": { "name": "signature", "type": "function", - "raw": "(e: GestureResponderEvent) => void", + "raw": "(props: { route: Route } & TabPressEvent) => void", "signature": { "arguments": [ { - "name": "e", + "name": "props", "type": { - "name": "GestureResponderEvent" + "name": "intersection", + "raw": "{ route: Route } & TabPressEvent", + "elements": [ + { + "name": "signature", + "type": "object", + "raw": "{ route: Route }", + "signature": { + "properties": [ + { + "key": "route", + "value": { + "name": "Route", + "required": true + } + } + ] + } + }, + { + "name": "signature", + "type": "object", + "raw": "{\n defaultPrevented: boolean;\n preventDefault(): void;\n}", + "signature": { + "properties": [ + { + "key": "defaultPrevented", + "value": { + "name": "boolean", + "required": true + } + }, + { + "key": "preventDefault", + "value": { + "name": "void", + "required": true + } + } + ] + } + } + ] } } ], @@ -9219,236 +9417,89 @@ } } }, - "description": "Function to execute on press." - }, - "titleMaxFontSizeMultiplier": { - "required": false, - "tsType": { - "name": "number" - }, - "description": "Specifies the largest possible scale a title font can reach.", - "defaultValue": { - "value": "1.5", - "computed": false - } - }, - "style": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style that is passed to the root TouchableRipple container.\n" - }, - "containerStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style that is passed to the outermost container that wraps the entire content, including leading and trailing icons and title text." - }, - "contentStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "ViewStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style that is passed to the content container, which wraps the title text." - }, - "titleStyle": { - "required": false, - "tsType": { - "name": "StyleProp", - "elements": [ - { - "name": "TextStyle" - } - ], - "raw": "StyleProp" - }, - "description": "Style that is passed to the Title element." - }, - "theme": { - "required": false, - "tsType": { - "name": "ThemeProp" - }, - "description": "" - }, - "hitSlop": { - "required": false, - "tsType": { - "name": "TouchableRippleProps['hitSlop']", - "raw": "TouchableRippleProps['hitSlop']" - }, - "description": "Sets additional distance outside of element in which a press can be detected." + "description": "Function to execute on tab long press. It receives the route for the pressed tab" }, - "testID": { + "activeColor": { "required": false, "tsType": { "name": "string" }, - "description": "TestID used for testing purposes", - "defaultValue": { - "value": "'menu-item'", - "computed": false - } + "description": "Custom color for icon and label in the active tab." }, - "aria-label": { + "inactiveColor": { "required": false, "tsType": { "name": "string" }, - "description": "Accessibility label for the Touchable. This is read by the screen reader when the user taps the component." - }, - "aria-checked": { - "required": false, - "tsType": { - "name": "union", - "raw": "boolean | 'mixed'", - "elements": [ - { - "name": "boolean" - }, - { - "name": "literal", - "value": "'mixed'" - } - ] - }, - "description": "Indicates whether the element is checked. Accepts `true`, `false`,\nor `'mixed'` for an indeterminate state." - }, - "aria-selected": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is selected." - }, - "aria-busy": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element is currently busy (e.g. loading)." + "description": "Custom color for icon and label in the inactive tab." }, - "aria-expanded": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Indicates whether the element's controlled content is expanded." - } - } - }, - "type": "component", - "dependencies": [ - "src/components/Menu/MenuItem.tsx" - ], - "group": "Menu" - }, - "Modal": { - "filepath": "Modal.tsx", - "title": "Modal", - "description": "The Modal component is a simple way to present content above an enclosing view.\nTo render the `Modal` above other components, you'll need to wrap it with the [`Portal`](./Portal) component.\nNote that this modal is NOT accessible by default; if you need an accessible modal, please use the React Native Modal.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Modal, Portal, Text, Button, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showModal = () => setVisible(true);\n const hideModal = () => setVisible(false);\n const containerStyle = { backgroundColor: 'white', padding: 20 };\n\n return (\n \n \n \n Example Modal. Click outside this area to dismiss.\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "link": "modal", - "data": { - "description": "The Modal component is a simple way to present content above an enclosing view.\nTo render the `Modal` above other components, you'll need to wrap it with the [`Portal`](./Portal) component.\nNote that this modal is NOT accessible by default; if you need an accessible modal, please use the React Native Modal.\n\n## Usage\n```js\nimport * as React from 'react';\nimport { Modal, Portal, Text, Button, PaperProvider } from 'react-native-paper';\n\nconst MyComponent = () => {\n const [visible, setVisible] = React.useState(false);\n\n const showModal = () => setVisible(true);\n const hideModal = () => setVisible(false);\n const containerStyle = { backgroundColor: 'white', padding: 20 };\n\n return (\n \n \n \n Example Modal. Click outside this area to dismiss.\n \n \n \n \n );\n};\n\nexport default MyComponent;\n```", - "displayName": "Modal", - "methods": [], - "statics": [], - "props": { - "dismissable": { + "keyboardHidesNavigationBar": { "required": false, "tsType": { "name": "boolean" }, - "description": "Determines whether clicking outside the modal dismisses it.", + "description": "Whether the bottom navigation bar is hidden when keyboard is shown.\nOn Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`.", "defaultValue": { - "value": "true", + "value": "Platform.OS === 'android'", "computed": false } }, - "dismissableBackButton": { - "required": false, - "tsType": { - "name": "boolean" - }, - "description": "Determines whether clicking Android hardware back button dismisses the dialog.", - "defaultValue": { - "value": "dismissable", - "computed": true - } - }, - "onDismiss": { + "safeAreaInsets": { "required": false, "tsType": { "name": "signature", - "type": "function", - "raw": "() => void", + "type": "object", + "raw": "{\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}", "signature": { - "arguments": [], - "return": { - "name": "void" - } + "properties": [ + { + "key": "top", + "value": { + "name": "number", + "required": false + } + }, + { + "key": "right", + "value": { + "name": "number", + "required": false + } + }, + { + "key": "bottom", + "value": { + "name": "number", + "required": false + } + }, + { + "key": "left", + "value": { + "name": "number", + "required": false + } + } + ] } }, - "description": "Callback that is called when the user dismisses the modal.", - "defaultValue": { - "value": "() => {}", - "computed": false - } - }, - "overlayAccessibilityLabel": { - "required": false, - "tsType": { - "name": "string" - }, - "description": "Accessibility label for the overlay. This is read by the screen reader when the user taps outside the modal.", - "defaultValue": { - "value": "'Close modal'", - "computed": false - } + "description": "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.\nThe bottom insets for iOS is added by default. You can override the behavior with this option." }, - "visible": { + "labelMaxFontSizeMultiplier": { "required": false, "tsType": { - "name": "boolean" + "name": "number" }, - "description": "Determines Whether the modal is visible.", + "description": "Specifies the largest possible scale a label font can reach.", "defaultValue": { - "value": "false", + "value": "1", "computed": false } }, - "children": { - "required": true, - "tsType": { - "name": "ReactReactNode", - "raw": "React.ReactNode" - }, - "description": "Content of the `Modal`." - }, - "contentContainerStyle": { + "style": { "required": false, "tsType": { - "name": "Animated.WithAnimatedValue", + "name": "RNAnimated.WithAnimatedValue", "elements": [ { "name": "StyleProp", @@ -9460,11 +9511,11 @@ "raw": "StyleProp" } ], - "raw": "Animated.WithAnimatedValue>" + "raw": "RNAnimated.WithAnimatedValue>" }, - "description": "Style for the content of the modal" + "description": "" }, - "style": { + "activeIndicatorStyle": { "required": false, "tsType": { "name": "StyleProp", @@ -9475,7 +9526,7 @@ ], "raw": "StyleProp" }, - "description": "Style for the wrapper of the modal.\nUse this prop to change the default wrapper style or to override safe area insets with marginTop and marginBottom." + "description": "" }, "theme": { "required": false, @@ -9489,9 +9540,9 @@ "tsType": { "name": "string" }, - "description": "testID to be used on tests.", + "description": "TestID used for testing purposes", "defaultValue": { - "value": "'modal'", + "value": "'bottom-navigation-bar'", "computed": false } } @@ -9499,7 +9550,7 @@ }, "type": "component", "dependencies": [ - "src/components/Modal.tsx" + "src/components/NavigationBar/NavigationBar.tsx" ] }, "Portal/Portal": { diff --git a/example/src/ExampleList.tsx b/example/src/ExampleList.tsx index 53132e299f..2dc994243c 100644 --- a/example/src/ExampleList.tsx +++ b/example/src/ExampleList.tsx @@ -10,7 +10,6 @@ import AvatarExample from './Examples/AvatarExample'; import BadgeExample from './Examples/BadgeExample'; import BannerExample from './Examples/BannerExample'; import BottomNavigationBarExample from './Examples/BottomNavigationBarExample'; -import BottomNavigationExample from './Examples/BottomNavigationExample'; import ButtonExample from './Examples/ButtonExample'; import CardExample from './Examples/CardExample'; import CheckboxExample from './Examples/CheckboxExample'; @@ -27,6 +26,7 @@ import ListAccordionExampleGroup from './Examples/ListAccordionGroupExample'; import ListItemExample from './Examples/ListItemExample'; import ListSectionExample from './Examples/ListSectionExample'; import MenuExample from './Examples/MenuExample'; +import NavigationBarExample from './Examples/NavigationBarExample'; import ProgressBarExample from './Examples/ProgressBarExample'; import RadioButtonExample from './Examples/RadioButtonExample'; import RadioButtonGroupExample from './Examples/RadioButtonGroupExample'; @@ -55,7 +55,6 @@ export const mainExamples = { Badge: BadgeExample, Banner: BannerExample, BottomNavigationBarExample, - BottomNavigation: BottomNavigationExample, Button: ButtonExample, Card: CardExample, Checkbox: CheckboxExample, @@ -72,6 +71,7 @@ export const mainExamples = { ListSection: ListSectionExample, ListItem: ListItemExample, Menu: MenuExample, + NavigationBar: NavigationBarExample, Progressbar: ProgressBarExample, Radio: RadioButtonExample, RadioGroup: RadioButtonGroupExample, diff --git a/example/src/Examples/BottomNavigationBarExample.tsx b/example/src/Examples/BottomNavigationBarExample.tsx index 9fbddf7f23..4b4d98d94d 100644 --- a/example/src/Examples/BottomNavigationBarExample.tsx +++ b/example/src/Examples/BottomNavigationBarExample.tsx @@ -11,7 +11,7 @@ import { SFSymbol, MaterialSymbol, } from '@react-navigation/native'; -import { Text, BottomNavigation } from 'react-native-paper'; +import { Text, NavigationBar } from 'react-native-paper'; function HomeScreen() { return ( @@ -34,7 +34,7 @@ const BottomNavigationBarExample = createBottomTabNavigator({ headerShown: false, }, tabBar: ({ navigation, state, descriptors }) => ( - { const event = navigation.emit({ @@ -119,7 +119,7 @@ const BottomNavigationBarExample = createBottomTabNavigator({ }); export default Object.assign(BottomNavigationBarExample, { - title: 'Bottom Navigation Bar', + title: 'Navigation Bar (React Navigation)', }); const styles = StyleSheet.create({ diff --git a/example/src/Examples/BottomNavigationExample.tsx b/example/src/Examples/BottomNavigationExample.tsx deleted file mode 100644 index 8b2495fdbc..0000000000 --- a/example/src/Examples/BottomNavigationExample.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import * as React from 'react'; -import { - Dimensions, - Easing, - Image, - Platform, - StyleSheet, - View, -} from 'react-native'; - -import { useNavigation } from '@react-navigation/native'; -import { Appbar, BottomNavigation, Menu } from 'react-native-paper'; -import type { BottomNavigationRoute } from 'react-native-paper'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; - -import ScreenWrapper from '../ScreenWrapper'; - -type Route = { route: { key: string } }; - -const MORE_ICON = Platform.OS === 'ios' ? 'dots-horizontal' : 'dots-vertical'; - -const PhotoGallery = ({ route }: Route) => { - const PHOTOS = Array.from({ length: 24 }).map( - (_, i) => `https://unsplash.it/300/300/?random&__id=${route.key}${i}` - ); - - return ( - - {PHOTOS.map((uri) => ( - - - - ))} - - ); -}; - -const BottomNavigationExample = () => { - const navigation = useNavigation('BottomNavigation'); - - const insets = useSafeAreaInsets(); - const [index, setIndex] = React.useState(0); - const [menuVisible, setMenuVisible] = React.useState(false); - const [sceneAnimation, setSceneAnimation] = - React.useState< - React.ComponentProps['sceneAnimationType'] - >(); - - const [routes] = React.useState([ - { - key: 'album', - title: 'Album', - focusedIcon: 'image-album', - }, - { - key: 'library', - title: 'Library', - focusedIcon: 'inbox', - unfocusedIcon: 'inbox-outline', - badge: true, - }, - { - key: 'favorites', - title: 'Favorites', - focusedIcon: 'heart', - unfocusedIcon: 'heart-outline', - }, - { - key: 'purchased', - title: 'Purchased', - focusedIcon: 'shopping', - unfocusedIcon: 'shopping-outline', - }, - ]); - - React.useLayoutEffect(() => { - navigation.setOptions({ - headerShown: false, - }); - }, [navigation]); - - return ( - - - navigation.goBack()} /> - - setMenuVisible(false)} - anchor={ - setMenuVisible(true)} - /> - } - > - { - setSceneAnimation(undefined); - setMenuVisible(false); - }} - title="Scene animation: none" - /> - { - setSceneAnimation('shifting'); - setMenuVisible(false); - }} - title="Scene animation: shifting" - /> - { - setSceneAnimation('opacity'); - setMenuVisible(false); - }} - title="Scene animation: opacity" - /> - - - route.key !== 'album'} - /> - - ); -}; - -BottomNavigationExample.title = 'Bottom Navigation'; - -export default BottomNavigationExample; - -const styles = StyleSheet.create({ - ...Platform.select({ - web: { - content: { - // there is no 'grid' type in RN :( - display: 'grid' as 'none', - gridTemplateColumns: 'repeat(auto-fill, minmax(150px, 1fr))', - gridRowGap: '8px', - gridColumnGap: '8px', - padding: 8, - }, - item: { - width: '100%', - height: 150, - }, - }, - default: { - content: { - flexDirection: 'row', - flexWrap: 'wrap', - padding: 4, - }, - item: { - height: Dimensions.get('window').width / 2, - width: '50%', - padding: 4, - }, - }, - }), - photo: { - flex: 1, - }, - screen: { - flex: 1, - }, -}); diff --git a/example/src/Examples/NavigationBarExample.tsx b/example/src/Examples/NavigationBarExample.tsx new file mode 100644 index 0000000000..070bbc28c2 --- /dev/null +++ b/example/src/Examples/NavigationBarExample.tsx @@ -0,0 +1,108 @@ +import * as React from 'react'; +import { StyleSheet, View, useWindowDimensions } from 'react-native'; + +import { + NavigationBar, + SegmentedButtons, + Switch, + Text, +} from 'react-native-paper'; + +type VariantMode = 'auto' | 'stacked' | 'horizontal'; + +// The flexible navigation bar switches to a horizontal item arrangement in +// medium-width windows. M3 recommends ~600dp as the breakpoint, but the +// component leaves the decision to the consumer — here it is driven by +// `useWindowDimensions`. +const MEDIUM_WINDOW_WIDTH = 600; + +const routes = [ + { key: 'album', title: 'Album', focusedIcon: 'image-album', badge: 3 }, + { key: 'library', title: 'Library', focusedIcon: 'bookshelf' }, + { + key: 'favorites', + title: 'Favorites', + focusedIcon: 'heart', + unfocusedIcon: 'heart-outline', + }, + { + key: 'settings', + title: 'Settings', + focusedIcon: 'cog', + unfocusedIcon: 'cog-outline', + }, +]; + +const NavigationBarExample = () => { + const [index, setIndex] = React.useState(0); + const [labeled, setLabeled] = React.useState(true); + const [variantMode, setVariantMode] = React.useState('auto'); + + const { width } = useWindowDimensions(); + const autoVariant = width >= MEDIUM_WINDOW_WIDTH ? 'horizontal' : 'stacked'; + const variant = variantMode === 'auto' ? autoVariant : variantMode; + + return ( + + + {routes[index].title} + + + + Show labels + + + + setVariantMode(value as VariantMode)} + buttons={[ + { value: 'auto', label: `Auto (${autoVariant})` }, + { value: 'stacked', label: 'Stacked' }, + { value: 'horizontal', label: 'Horizontal' }, + ]} + /> + + + + { + const nextIndex = routes.findIndex((r) => r.key === route.key); + if (nextIndex !== -1) { + setIndex(nextIndex); + } + }} + /> + + ); +}; + +NavigationBarExample.title = 'Navigation Bar (flexible)'; + +export default NavigationBarExample; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + content: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + padding: 16, + }, + controls: { + marginTop: 32, + width: '100%', + maxWidth: 480, + gap: 24, + }, + row: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, +}); diff --git a/example/src/Examples/TeamDetails.tsx b/example/src/Examples/TeamDetails.tsx index 5970274f31..f032fdbd36 100644 --- a/example/src/Examples/TeamDetails.tsx +++ b/example/src/Examples/TeamDetails.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { - Easing, FlatList, ScrollView, StyleSheet, @@ -11,7 +10,7 @@ import { import { useNavigation, useRoute } from '@react-navigation/native'; import { Appbar, - BottomNavigation, + NavigationBar, Card, Button, Text, @@ -211,20 +210,19 @@ const ThemeBasedOnSourceColor = () => { navigation.goBack()} /> - + {routes[index].key === 'news' && } + {routes[index].key === 'results' && } + {routes[index].key === 'roster' && } + + { + const i = routes.findIndex((r) => r.key === route.key); + if (i !== -1 && i !== index) setIndex(i); + }} labelMaxFontSizeMultiplier={2} - renderScene={BottomNavigation.SceneMap({ - news: News, - results: Results, - roster: Roster, - })} - sceneAnimationEnabled - sceneAnimationType={'opacity'} - sceneAnimationEasing={Easing.ease} - getLazy={({ route }) => route.key !== 'album'} /> @@ -239,6 +237,9 @@ const styles = StyleSheet.create({ screen: { flex: 1, }, + scene: { + flex: 1, + }, winner: { fontWeight: '700', }, diff --git a/src/babel/__fixtures__/rewrite-imports/code.js b/src/babel/__fixtures__/rewrite-imports/code.js index f1253a5e08..a1028ff585 100644 --- a/src/babel/__fixtures__/rewrite-imports/code.js +++ b/src/babel/__fixtures__/rewrite-imports/code.js @@ -1,7 +1,6 @@ /* eslint-disable prettier/prettier */ import { PaperProvider, - BottomNavigation, Button, FAB, Appbar, diff --git a/src/babel/__fixtures__/rewrite-imports/output.js b/src/babel/__fixtures__/rewrite-imports/output.js index bbe342ad0d..5e04ea94dd 100644 --- a/src/babel/__fixtures__/rewrite-imports/output.js +++ b/src/babel/__fixtures__/rewrite-imports/output.js @@ -1,6 +1,5 @@ /* eslint-disable prettier/prettier */ import PaperProvider from "react-native-paper/lib/module/core/PaperProvider"; -import BottomNavigation from "react-native-paper/lib/module/components/BottomNavigation/BottomNavigation"; import Button from "react-native-paper/lib/module/components/Button/Button"; import FAB from "react-native-paper/lib/module/components/FAB"; import Appbar from "react-native-paper/lib/module/components/Appbar"; diff --git a/src/components/BottomNavigation/BottomNavigation.tsx b/src/components/BottomNavigation/BottomNavigation.tsx deleted file mode 100644 index df7e28cc76..0000000000 --- a/src/components/BottomNavigation/BottomNavigation.tsx +++ /dev/null @@ -1,628 +0,0 @@ -import * as React from 'react'; -import { Animated, Platform, StyleSheet, View } from 'react-native'; -import type { - ColorValue, - EasingFunction, - StyleProp, - ViewStyle, -} from 'react-native'; - -import useLatestCallback from 'use-latest-callback'; - -import BottomNavigationBar from './BottomNavigationBar'; -import BottomNavigationRouteScreen from './BottomNavigationRouteScreen'; -import { useInternalTheme } from '../../core/theming'; -import type { ThemeProp } from '../../types'; -import useAnimatedValueArray from '../../utils/useAnimatedValueArray'; -import type { IconSource } from '../Icon'; -import type { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple'; - -export type BaseRoute = { - key: string; - title?: string; - focusedIcon?: IconSource; - unfocusedIcon?: IconSource; - badge?: string | number | boolean; - 'aria-label'?: string; - testID?: string; - lazy?: boolean; -}; - -type NavigationState = { - index: number; - routes: Route[]; -}; - -type TabPressEvent = { - defaultPrevented: boolean; - preventDefault(): void; -}; - -type TouchableProps = TouchableRippleProps & { - key: string; - route: Route; - children: React.ReactNode; - borderless?: boolean; - centered?: boolean; - rippleColor?: ColorValue; -}; - -export type Props = { - /** - * 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. - * - * By default, this is `false` with theme version 3 and `true` when you have more than 3 tabs. - * Pass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation. - * Note that you need at least 2 tabs be able to run this animation. - */ - shifting?: boolean; - /** - * Whether to show labels in tabs. When `false`, only icons will be displayed. - */ - labeled?: boolean; - /** - * Whether tabs should be spread across the entire width. - */ - compact?: boolean; - /** - * State for the bottom navigation. The state should contain the following properties: - * - * - `index`: a number representing the index of the active route in the `routes` array - * - `routes`: an array containing a list of route objects used for rendering the tabs - * - * Each route object should contain the following properties: - * - * - `key`: a unique key to identify the route (required) - * - `title`: title of the route to use as the tab label - * - `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 - * - `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 - * - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text. - * - `aria-label`: accessibility label for the tab button - * - `testID`: test id for the tab button - * - * Example: - * - * ```js - * { - * index: 1, - * routes: [ - * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'}, - * { key: 'albums', title: 'Albums', focusedIcon: 'album' }, - * { key: 'recents', title: 'Recents', focusedIcon: 'history' }, - * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' }, - * ] - * } - * ``` - * - * `BottomNavigation` is a controlled component, which means the `index` needs to be updated via the `onIndexChange` callback. - */ - navigationState: NavigationState; - /** - * Callback which is called on tab change, receives the index of the new tab as argument. - * The navigation state needs to be updated when it's called, otherwise the change is dropped. - */ - onIndexChange: (index: number) => void; - /** - * Callback which returns a react element to render as the page for the tab. Receives an object containing the route as the argument: - * - * ```js - * renderScene = ({ route, jumpTo }) => { - * switch (route.key) { - * case 'music': - * return ; - * case 'albums': - * return ; - * } - * } - * ``` - * - * Pages are lazily rendered, which means that a page will be rendered the first time you navigate to it. - * After initial render, all the pages stay rendered to preserve their state. - * - * You need to make sure that your individual routes implement a `shouldComponentUpdate` to improve the performance. - * To make it easier to specify the components, you can use the `SceneMap` helper: - * - * ```js - * renderScene = BottomNavigation.SceneMap({ - * music: MusicRoute, - * albums: AlbumsRoute, - * }); - * ``` - * - * Specifying the components this way is easier and takes care of implementing a `shouldComponentUpdate` method. - * Each component will receive the current route and a `jumpTo` method as it's props. - * The `jumpTo` method can be used to navigate to other tabs programmatically: - * - * ```js - * this.props.jumpTo('albums') - * ``` - */ - renderScene: (props: { - route: Route; - jumpTo: (key: string) => void; - }) => React.ReactNode | null; - /** - * Callback which returns a React Element to be used as tab icon. - */ - renderIcon?: (props: { - route: Route; - focused: boolean; - color: ColorValue; - }) => React.ReactNode; - /** - * Callback which React Element to be used as tab label. - */ - renderLabel?: (props: { - route: Route; - focused: boolean; - color: ColorValue; - }) => React.ReactNode; - /** - * Callback which returns a React element to be used as the touchable for the tab item. - * Renders a `TouchableRipple` on Android and `Pressable` on iOS. - */ - renderTouchable?: (props: TouchableProps) => React.ReactNode; - /** - * Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab. - * Uses `route['aria-label']` by default. - */ - getAccessibilityLabel?: (props: { route: Route }) => string | undefined; - /** - * Get badge for the tab, uses `route.badge` by default. - */ - getBadge?: (props: { route: Route }) => boolean | number | string | undefined; - /** - * Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component. - */ - getLabelText?: (props: { route: Route }) => string | undefined; - /** - * Get lazy for the current screen. Uses true by default. - */ - getLazy?: (props: { route: Route }) => boolean | undefined; - /** - * Get the id to locate this tab button in tests, uses `route.testID` by default. - */ - getTestID?: (props: { route: Route }) => string | undefined; - /** - * Function to execute on tab press. It receives the route for the pressed tab, useful for things like scroll to top. - */ - onTabPress?: (props: { route: Route } & TabPressEvent) => void; - /** - * Function to execute on tab long press. It receives the route for the pressed tab, useful for things like custom action when longed pressed. - */ - onTabLongPress?: (props: { route: Route } & TabPressEvent) => void; - /** - * Custom color for icon and label in the active tab. - */ - activeColor?: string; - /** - * Custom color for icon and label in the inactive tab. - */ - inactiveColor?: string; - /** - * Whether animation is enabled for scenes transitions in `shifting` mode. - * By default, the scenes cross-fade during tab change when `shifting` is enabled. - * Specify `sceneAnimationEnabled` as `false` to disable the animation. - */ - sceneAnimationEnabled?: boolean; - /** - * The scene animation effect. Specify `'shifting'` for a different effect. - * By default, 'opacity' will be used. - */ - sceneAnimationType?: 'opacity' | 'shifting'; - /** - * The scene animation Easing. - */ - sceneAnimationEasing?: EasingFunction | undefined; - /** - * Whether the bottom navigation bar is hidden when keyboard is shown. - * On Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`. - */ - keyboardHidesNavigationBar?: boolean; - /** - * 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. - * The bottom insets for iOS is added by default. You can override the behavior with this option. - */ - safeAreaInsets?: { - top?: number; - right?: number; - bottom?: number; - left?: number; - }; - /** - * Style for the bottom navigation bar. You can pass a custom background color here: - * - * ```js - * barStyle={{ backgroundColor: '#694fad' }} - * ``` - */ - barStyle?: Animated.WithAnimatedValue>; - /** - * Specifies the largest possible scale a label font can reach. - */ - labelMaxFontSizeMultiplier?: number; - style?: StyleProp; - activeIndicatorStyle?: StyleProp; - /** - * @optional - */ - theme?: ThemeProp; - /** - * TestID used for testing purposes - */ - testID?: string; -}; - -const FAR_FAR_AWAY = Platform.OS === 'web' ? 0 : 9999; - -const SceneComponent = React.memo(({ component, ...rest }: any) => - React.createElement(component, rest) -); - -/** - * BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar. - * It is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar). - * - * By default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead. - * See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information. - * - * ## Usage - * ```js - * import * as React from 'react'; - * import { BottomNavigation, Text } from 'react-native-paper'; - * - * const MusicRoute = () => Music; - * - * const AlbumsRoute = () => Albums; - * - * const RecentsRoute = () => Recents; - * - * const NotificationsRoute = () => Notifications; - * - * const MyComponent = () => { - * const [index, setIndex] = React.useState(0); - * const [routes] = React.useState([ - * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'}, - * { key: 'albums', title: 'Albums', focusedIcon: 'album' }, - * { key: 'recents', title: 'Recents', focusedIcon: 'history' }, - * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' }, - * ]); - * - * const renderScene = BottomNavigation.SceneMap({ - * music: MusicRoute, - * albums: AlbumsRoute, - * recents: RecentsRoute, - * notifications: NotificationsRoute, - * }); - * - * return ( - * - * ); - * }; - * - * export default MyComponent; - * ``` - */ -const BottomNavigation = ({ - navigationState, - renderScene, - renderIcon, - renderLabel, - renderTouchable, - getLabelText, - getBadge, - getAccessibilityLabel, - getTestID, - activeColor, - inactiveColor, - keyboardHidesNavigationBar = Platform.OS === 'android', - barStyle, - labeled = true, - style, - activeIndicatorStyle, - sceneAnimationEnabled = false, - sceneAnimationType = 'opacity', - sceneAnimationEasing, - onTabPress, - onTabLongPress, - onIndexChange, - shifting: shiftingProp, - safeAreaInsets, - labelMaxFontSizeMultiplier = 1, - compact: compactProp, - testID = 'bottom-navigation', - theme: themeOverrides, - getLazy = ({ route }: { route: Route }) => route.lazy, -}: Props) => { - const theme = useInternalTheme(themeOverrides); - const { scale } = theme.animation; - const compact = compactProp ?? false; - let shifting = shiftingProp ?? false; - - if (shifting && navigationState.routes.length < 2) { - shifting = false; - console.warn( - 'BottomNavigation needs at least 2 tabs to run shifting animation' - ); - } - - const focusedKey = navigationState.routes[navigationState.index].key; - - /** - * Active state of individual tab item positions: - * -1 if they're before the active tab, 0 if they're active, 1 if they're after the active tab - */ - const tabsPositionAnims = useAnimatedValueArray( - navigationState.routes.map((_, i) => - i === navigationState.index ? 0 : i >= navigationState.index ? 1 : -1 - ) - ); - - /** - * The top offset for each tab item to position it offscreen. - * Placing items offscreen helps to save memory usage for inactive screens with removeClippedSubviews. - * We use animated values for this to prevent unnecessary re-renders. - */ - const offsetsAnims = useAnimatedValueArray( - navigationState.routes.map( - // offscreen === 1, normal === 0 - (_, i) => (i === navigationState.index ? 0 : 1) - ) - ); - - /** - * List of loaded tabs, tabs will be loaded when navigated to. - */ - const [loaded, setLoaded] = React.useState([focusedKey]); - - if (!loaded.includes(focusedKey)) { - // Set the current tab to be loaded if it was not loaded before - setLoaded((loaded) => [...loaded, focusedKey]); - } - - const animateToIndex = React.useCallback( - (index: number) => { - Animated.parallel([ - ...navigationState.routes.map((_, i) => - Animated.timing(tabsPositionAnims[i], { - toValue: i === index ? 0 : i >= index ? 1 : -1, - duration: 150 * scale, - useNativeDriver: true, - easing: sceneAnimationEasing, - }) - ), - ]).start(({ finished }) => { - if (finished) { - // Position all inactive screens offscreen to save memory usage - // Only do it when animation has finished to avoid glitches mid-transition if switching fast - offsetsAnims.forEach((offset, i) => { - if (i === index) { - offset.setValue(0); - } else { - offset.setValue(1); - } - }); - } - }); - }, - [ - navigationState.routes, - offsetsAnims, - scale, - tabsPositionAnims, - sceneAnimationEasing, - ] - ); - - React.useEffect(() => { - // Workaround for native animated bug in react-native@^0.57 - // Context: https://github.com/callstack/react-native-paper/pull/637 - animateToIndex(navigationState.index); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const prevNavigationState = React.useRef | undefined>( - undefined - ); - - React.useEffect(() => { - // Reset offsets of previous and current tabs before animation - offsetsAnims.forEach((offset, i) => { - if ( - i === navigationState.index || - i === prevNavigationState.current?.index - ) { - offset.setValue(0); - } - }); - - animateToIndex(navigationState.index); - }, [navigationState.index, animateToIndex, offsetsAnims]); - - const handleTabPress = useLatestCallback( - (event: { route: Route } & TabPressEvent) => { - onTabPress?.(event); - - if (event.defaultPrevented) { - return; - } - - const index = navigationState.routes.findIndex( - (route) => event.route.key === route.key - ); - - if (index !== navigationState.index) { - prevNavigationState.current = navigationState; - onIndexChange(index); - } - } - ); - - const jumpTo = useLatestCallback((key: string) => { - const index = navigationState.routes.findIndex( - (route) => route.key === key - ); - - prevNavigationState.current = navigationState; - onIndexChange(index); - }); - - const { routes } = navigationState; - const { colors } = theme; - - return ( - - - {routes.map((route, index) => { - if (getLazy({ route }) !== false && !loaded.includes(route.key)) { - // Don't render a screen if we've never navigated to it - return null; - } - - const focused = navigationState.index === index; - const previouslyFocused = - prevNavigationState.current?.index === index; - const countAlphaOffscreen = - sceneAnimationEnabled && (focused || previouslyFocused); - const renderToHardwareTextureAndroid = - sceneAnimationEnabled && focused; - - const opacity = sceneAnimationEnabled - ? tabsPositionAnims[index].interpolate({ - inputRange: [-1, 0, 1], - outputRange: [0, 1, 0], - }) - : focused - ? 1 - : 0; - - const offsetTarget = focused ? 0 : FAR_FAR_AWAY; - - const top = sceneAnimationEnabled - ? offsetsAnims[index].interpolate({ - inputRange: [0, 1], - outputRange: [0, offsetTarget], - }) - : offsetTarget; - - const left = - sceneAnimationType === 'shifting' - ? tabsPositionAnims[index].interpolate({ - inputRange: [-1, 0, 1], - outputRange: [-50, 0, 50], - }) - : 0; - - const zIndex = focused ? 1 : 0; - - return ( - - - {renderScene({ route, jumpTo })} - - - ); - })} - - - - ); -}; - -/** - * Function which takes a map of route keys to components. - * Pure components are used to minimize re-rendering of the pages. - * This drastically improves the animation performance. - */ -BottomNavigation.SceneMap = (scenes: { - [key: string]: React.ComponentType<{ - route: Route; - jumpTo: (key: string) => void; - }>; -}) => { - return ({ - route, - jumpTo, - }: { - route: Route; - jumpTo: (key: string) => void; - }) => ( - - ); -}; - -// @component ./BottomNavigationBar.tsx -BottomNavigation.Bar = BottomNavigationBar; - -export default BottomNavigation; - -const styles = StyleSheet.create({ - container: { - flex: 1, - overflow: 'hidden', - }, - content: { - flex: 1, - }, -}); diff --git a/src/components/BottomNavigation/BottomNavigationBar.tsx b/src/components/BottomNavigation/BottomNavigationBar.tsx deleted file mode 100644 index f25bcf0170..0000000000 --- a/src/components/BottomNavigation/BottomNavigationBar.tsx +++ /dev/null @@ -1,862 +0,0 @@ -import * as React from 'react'; -import { Animated, Platform, StyleSheet, Pressable, View } from 'react-native'; -import type { - ColorValue, - EasingFunction, - StyleProp, - ViewStyle, -} from 'react-native'; - -import { useSafeAreaInsets } from 'react-native-safe-area-context'; - -import { - getActiveTintColor, - getInactiveTintColor, - getLabelColor, -} from './utils'; -import { useInternalTheme } from '../../core/theming'; -import type { Theme, ThemeProp } from '../../types'; -import useAnimatedValue from '../../utils/useAnimatedValue'; -import useAnimatedValueArray from '../../utils/useAnimatedValueArray'; -import useIsKeyboardShown from '../../utils/useIsKeyboardShown'; -import useLayout from '../../utils/useLayout'; -import Badge from '../Badge'; -import Icon from '../Icon'; -import type { IconSource } from '../Icon'; -import Surface from '../Surface'; -import TouchableRipple from '../TouchableRipple/TouchableRipple'; -import type { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple'; -import Text from '../Typography/Text'; - -type BaseRoute = { - key: string; - title?: string; - focusedIcon?: IconSource; - unfocusedIcon?: IconSource; - badge?: string | number | boolean; - /** - * Accessibility label for the tab. This is read by the screen reader when the user focuses the tab. - */ - 'aria-label'?: string; - testID?: string; - lazy?: boolean; -}; - -type NavigationState = { - index: number; - routes: Route[]; -}; - -type TabPressEvent = { - defaultPrevented: boolean; - preventDefault(): void; -}; - -type TouchableProps = TouchableRippleProps & { - key: string; - route: Route; - children: React.ReactNode; - borderless?: boolean; - centered?: boolean; - rippleColor?: ColorValue; -}; - -export type Props = { - /** - * 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. - * - * By default, this is `false` with theme version 3 and `true` when you have more than 3 tabs. - * Pass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation. - * Note that you need at least 2 tabs be able to run this animation. - */ - shifting?: boolean; - /** - * Whether to show labels in tabs. When `false`, only icons will be displayed. - */ - labeled?: boolean; - /** - * Whether tabs should be spread across the entire width. - */ - compact?: boolean; - /** - * State for the bottom navigation. The state should contain the following properties: - * - * - `index`: a number representing the index of the active route in the `routes` array - * - `routes`: an array containing a list of route objects used for rendering the tabs - * - * Each route object should contain the following properties: - * - * - `key`: a unique key to identify the route (required) - * - `title`: title of the route to use as the tab label - * - `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 - * - `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 - * - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text. - * - `aria-label`: accessibility label for the tab button - * - `testID`: test id for the tab button - * - * Example: - * - * ```js - * { - * index: 1, - * routes: [ - * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'}, - * { key: 'albums', title: 'Albums', focusedIcon: 'album' }, - * { key: 'recents', title: 'Recents', focusedIcon: 'history' }, - * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' }, - * ] - * } - * ``` - * - * `BottomNavigation.Bar` is a controlled component, which means the `index` needs to be updated via the `onTabPress` callback. - */ - navigationState: NavigationState; - /** - * Callback which returns a React Element to be used as tab icon. - */ - renderIcon?: (props: { - route: Route; - focused: boolean; - color: ColorValue; - }) => React.ReactNode; - /** - * Callback which React Element to be used as tab label. - */ - renderLabel?: (props: { - route: Route; - focused: boolean; - color: ColorValue; - }) => React.ReactNode; - /** - * Callback which returns a React element to be used as the touchable for the tab item. - * Renders a `TouchableRipple` on Android and `Pressable` on iOS. - */ - renderTouchable?: (props: TouchableProps) => React.ReactNode; - /** - * Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab. - * Uses `route['aria-label']` by default. - */ - getAccessibilityLabel?: (props: { route: Route }) => string | undefined; - /** - * Get badge for the tab, uses `route.badge` by default. - */ - getBadge?: (props: { route: Route }) => boolean | number | string | undefined; - /** - * Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component. - */ - getLabelText?: (props: { route: Route }) => string | undefined; - /** - * Get the id to locate this tab button in tests, uses `route.testID` by default. - */ - getTestID?: (props: { route: Route }) => string | undefined; - /** - * Function to execute on tab press. It receives the route for the pressed tab. Use this to update the navigation state. - */ - onTabPress: (props: { route: Route } & TabPressEvent) => void; - /** - * Function to execute on tab long press. It receives the route for the pressed tab - */ - onTabLongPress?: (props: { route: Route } & TabPressEvent) => void; - /** - * Custom color for icon and label in the active tab. - */ - activeColor?: string; - /** - * Custom color for icon and label in the inactive tab. - */ - inactiveColor?: string; - /** - * The scene animation Easing. - */ - animationEasing?: EasingFunction | undefined; - /** - * Whether the bottom navigation bar is hidden when keyboard is shown. - * On Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`. - */ - keyboardHidesNavigationBar?: boolean; - /** - * 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. - * The bottom insets for iOS is added by default. You can override the behavior with this option. - */ - safeAreaInsets?: { - top?: number; - right?: number; - bottom?: number; - left?: number; - }; - /** - * Specifies the largest possible scale a label font can reach. - */ - labelMaxFontSizeMultiplier?: number; - style?: Animated.WithAnimatedValue>; - activeIndicatorStyle?: StyleProp; - /** - * @optional - */ - theme?: ThemeProp; - /** - * TestID used for testing purposes - */ - testID?: string; -}; - -const MIN_TAB_WIDTH = 96; -const MAX_TAB_WIDTH = 168; -const BAR_HEIGHT = 56; -const OUTLINE_WIDTH = 64; - -const Touchable = ({ - route: _0, - style, - children, - borderless, - centered, - rippleColor, - ...rest -}: TouchableProps) => - TouchableRipple.supported ? ( - - {children} - - ) : ( - - {children} - - ); - -/** - * A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/). - * - * ## Usage - * ### without React Navigation - * ```js - * import React from 'react'; - * import { useState } from 'react'; - * import { View } from 'react-native'; - * import { BottomNavigation, Text, Provider } from 'react-native-paper'; - * import MaterialCommunityIcons from '@react-native-vector-icons/material-design-icons'; - * - * function HomeScreen() { - * return ( - * - * Home! - * - * ); - * } - * - * function SettingsScreen() { - * return ( - * - * Settings! - * - * ); - * } - * - * export default function MyComponent() { - * const [index, setIndex] = useState(0); - * - * const routes = [ - * { key: 'home', title: 'Home', icon: 'home' }, - * { key: 'settings', title: 'Settings', icon: 'cog' }, - * ]; - - * const renderScene = ({ route }) => { - * switch (route.key) { - * case 'home': - * return ; - * case 'settings': - * return ; - * default: - * return null; - * } - * }; - * - * return ( - * - * {renderScene({ route: routes[index] })} - * { - * const newIndex = routes.findIndex((r) => r.key === route.key); - * if (newIndex !== -1) { - * setIndex(newIndex); - * } - * }} - * renderIcon={({ route, color }) => ( - * - * )} - * getLabelText={({ route }) => route.title} - * /> - * - * ); - * } - * ``` - */ -const BottomNavigationBar = ({ - navigationState, - renderIcon, - renderLabel, - renderTouchable = ({ key, ...props }: TouchableProps) => ( - - ), - getLabelText = ({ route }: { route: Route }) => route.title, - getBadge = ({ route }: { route: Route }) => route.badge, - getAccessibilityLabel = ({ route }: { route: Route }) => route['aria-label'], - getTestID = ({ route }: { route: Route }) => route.testID, - activeColor, - inactiveColor, - keyboardHidesNavigationBar = Platform.OS === 'android', - style, - activeIndicatorStyle, - labeled = true, - animationEasing, - onTabPress, - onTabLongPress, - shifting: shiftingProp, - safeAreaInsets, - labelMaxFontSizeMultiplier = 1, - compact: compactProp, - testID = 'bottom-navigation-bar', - theme: themeOverrides, -}: Props) => { - const theme = useInternalTheme(themeOverrides); - const { colors } = theme as Theme; - const { bottom, left, right } = useSafeAreaInsets(); - const { scale } = theme.animation; - const compact = compactProp ?? false; - let shifting = shiftingProp ?? false; - - if (shifting && navigationState.routes.length < 2) { - shifting = false; - console.warn( - 'BottomNavigation.Bar needs at least 2 tabs to run shifting animation' - ); - } - - /** - * Visibility of the navigation bar, visible state is 1 and invisible is 0. - */ - const visibleAnim = useAnimatedValue(1); - - /** - * Active state of individual tab items, active state is 1 and inactive state is 0. - */ - const tabsAnims = useAnimatedValueArray( - navigationState.routes.map( - // focused === 1, unfocused === 0 - (_, i) => (i === navigationState.index ? 1 : 0) - ) - ); - - /** - * Layout of the navigation bar. - */ - const [layout, onLayout] = useLayout(); - - /** - * Track whether the keyboard is visible to show and hide the navigation bar. - */ - const [keyboardVisible, setKeyboardVisible] = React.useState(false); - - const handleKeyboardShow = React.useCallback(() => { - setKeyboardVisible(true); - Animated.timing(visibleAnim, { - toValue: 0, - duration: 150 * scale, - useNativeDriver: true, - }).start(); - }, [scale, visibleAnim]); - - const handleKeyboardHide = React.useCallback(() => { - Animated.timing(visibleAnim, { - toValue: 1, - duration: 100 * scale, - useNativeDriver: true, - }).start(() => { - setKeyboardVisible(false); - }); - }, [scale, visibleAnim]); - - const animateToIndex = React.useCallback( - (index: number) => { - Animated.parallel( - navigationState.routes.map((_, i) => - Animated.timing(tabsAnims[i], { - toValue: i === index ? 1 : 0, - duration: 150 * scale, - useNativeDriver: true, - easing: animationEasing, - }) - ) - ).start(() => { - // Workaround a bug in native animations where this is reset after first animation - tabsAnims.map((tab, i) => tab.setValue(i === index ? 1 : 0)); - }); - }, - [scale, navigationState.routes, tabsAnims, animationEasing] - ); - - React.useEffect(() => { - // Workaround for native animated bug in react-native@^0.57 - // Context: https://github.com/callstack/react-native-paper/pull/637 - animateToIndex(navigationState.index); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useIsKeyboardShown({ - onShow: handleKeyboardShow, - onHide: handleKeyboardHide, - }); - - React.useEffect(() => { - animateToIndex(navigationState.index); - }, [navigationState.index, animateToIndex]); - - const eventForIndex = (index: number) => { - const event = { - route: navigationState.routes[index], - defaultPrevented: false, - preventDefault: () => { - event.defaultPrevented = true; - }, - }; - - return event; - }; - - const { routes } = navigationState; - - const { backgroundColor: customBackground } = (StyleSheet.flatten(style) || - {}) as { - elevation?: number; - backgroundColor?: ColorValue; - }; - - const backgroundColor = customBackground || colors.surfaceContainer; - - const activeTintColor = getActiveTintColor({ - activeColor, - theme, - }); - - const inactiveTintColor = getInactiveTintColor({ - inactiveColor, - theme, - }); - - const maxTabWidth = routes.length > 3 ? MIN_TAB_WIDTH : MAX_TAB_WIDTH; - const maxTabBarWidth = maxTabWidth * routes.length; - - const insets = { - left: safeAreaInsets?.left ?? left, - right: safeAreaInsets?.right ?? right, - bottom: safeAreaInsets?.bottom ?? bottom, - }; - - return ( - - ); -}; - -BottomNavigationBar.displayName = 'BottomNavigation.Bar'; - -export default BottomNavigationBar; - -const styles = StyleSheet.create({ - bar: { - left: 0, - right: 0, - bottom: 0, - }, - barContent: { - alignItems: 'center', - overflow: 'hidden', - }, - items: { - flexDirection: 'row', - ...(Platform.OS === 'web' - ? { - width: '100%', - } - : null), - }, - item: { - flex: 1, - // Top padding is 6 and bottom padding is 10 - // The extra 4dp bottom padding is offset by label's height - paddingVertical: 6, - }, - v3Item: { - paddingVertical: 0, - }, - iconContainer: { - height: 24, - width: 24, - marginTop: 2, - marginHorizontal: 12, - alignSelf: 'center', - }, - v3IconContainer: { - height: 32, - width: 32, - marginBottom: 4, - marginTop: 0, - justifyContent: 'center', - }, - iconWrapper: { - ...StyleSheet.absoluteFill, - alignItems: 'center', - }, - v3IconWrapper: { - top: 4, - }, - labelContainer: { - height: 16, - paddingBottom: 2, - }, - labelWrapper: { - ...StyleSheet.absoluteFill, - }, - // eslint-disable-next-line react-native/no-color-literals - label: { - fontSize: 12, - height: BAR_HEIGHT, - textAlign: 'center', - backgroundColor: 'transparent', - ...(Platform.OS === 'web' - ? { - whiteSpace: 'nowrap', - alignSelf: 'center', - } - : null), - }, - badgeContainer: { - position: 'absolute', - left: 0, - }, - v3TouchableContainer: { - paddingTop: 12, - paddingBottom: 16, - }, - v3NoLabelContainer: { - height: 80, - justifyContent: 'center', - alignItems: 'center', - }, - outline: { - width: OUTLINE_WIDTH, - height: OUTLINE_WIDTH / 2, - borderRadius: OUTLINE_WIDTH / 4, - alignSelf: 'center', - }, -}); diff --git a/src/components/BottomNavigation/BottomNavigationRouteScreen.tsx b/src/components/BottomNavigation/BottomNavigationRouteScreen.tsx deleted file mode 100644 index 5773e2e1fd..0000000000 --- a/src/components/BottomNavigation/BottomNavigationRouteScreen.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import type { ReactNode } from 'react'; -import { Animated, Platform, View } from 'react-native'; -import type { ViewProps } from 'react-native'; - -interface Props extends ViewProps { - visibility?: 0 | 1 | Animated.AnimatedInterpolation; - index: number; -} - -class BottomNavigationRouteScreen extends React.Component { - render(): ReactNode { - const { style, index, children, visibility, ...rest } = this.props; - - // On Web, the unfocused tab screens can still be clicked since they are transparent, but still there - // Hiding them with `display: none` makes sure that they won't receive clicks - // We only set it on Web since on native, react-native-pager-view's breaks due to layout changing - const display = - Platform.OS === 'web' ? (visibility === 0 ? 'none' : 'flex') : undefined; - - return ( - - {children} - - ); - } -} - -export default Animated.createAnimatedComponent(BottomNavigationRouteScreen); diff --git a/src/components/NavigationBar/NavigationBar.tsx b/src/components/NavigationBar/NavigationBar.tsx new file mode 100644 index 0000000000..ae84a4b367 --- /dev/null +++ b/src/components/NavigationBar/NavigationBar.tsx @@ -0,0 +1,887 @@ +import * as React from 'react'; +import { Platform, StyleSheet, Pressable, View } from 'react-native'; +import type { + Animated as RNAnimated, + ColorValue, + StyleProp, + TextStyle, + ViewStyle, +} from 'react-native'; + +import Animated, { + Easing, + ReduceMotion, + runOnJS, + useAnimatedStyle, + useSharedValue, + withSpring, + withTiming, +} from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + +import { + BAR_HEIGHT, + colorRoles, + ICON_LABEL_GAP, + ICON_SIZE, + INDICATOR_BORDER_RADIUS, + INDICATOR_HEIGHT, + INDICATOR_WIDTH, + MAX_TAB_WIDTH, + MIN_TAB_WIDTH, + NO_LABEL_BAR_HEIGHT, +} from './tokens'; +import { + getActiveTintColor, + getInactiveTintColor, + getLabelColor, +} from './utils'; +import { useInternalTheme } from '../../core/theming'; +import { useReduceMotion } from '../../theme/accessibility/ReduceMotionContext'; +import { toRawSpring } from '../../theme/tokens/sys/motion'; +import { getStateLayer } from '../../theme/utils/state'; +import type { Theme, ThemeProp } from '../../types'; +import useIsKeyboardShown from '../../utils/useIsKeyboardShown'; +import useLayout from '../../utils/useLayout'; +import Badge from '../Badge'; +import Icon from '../Icon'; +import type { IconSource } from '../Icon'; +import Surface from '../Surface'; +import TouchableRipple from '../TouchableRipple/TouchableRipple'; +import type { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple'; +import Text from '../Typography/Text'; + +export type BaseRoute = { + key: string; + title?: string; + focusedIcon?: IconSource; + unfocusedIcon?: IconSource; + badge?: string | number | boolean; + accessibilityLabel?: string; + testID?: string; + lazy?: boolean; +}; + +type NavigationState = { + index: number; + routes: Route[]; +}; + +type TabPressEvent = { + defaultPrevented: boolean; + preventDefault(): void; +}; + +type TouchableProps = TouchableRippleProps & { + key: string; + route: Route; + children: React.ReactNode; + borderless?: boolean; + centered?: boolean; + rippleColor?: ColorValue; + onHoverIn?: () => void; + onHoverOut?: () => void; + onFocus?: () => void; + onBlur?: () => void; +}; + +export type Props = { + /** + * Whether to show labels in tabs. When `false`, only icons will be displayed. + */ + labeled?: boolean; + /** + * The item layout variant of the flexible navigation bar. + * + * - `stacked` (default): the icon sits above the label. + * - `horizontal`: the icon sits beside the label and the active indicator + * hugs both. Recommended for medium-width windows (e.g. foldables and + * tablets). Has no effect when `labeled` is `false`. + */ + variant?: 'stacked' | 'horizontal'; + /** + * Whether tabs should be spread across the entire width. + */ + compact?: boolean; + /** + * State for the bottom navigation. The state should contain the following properties: + * + * - `index`: a number representing the index of the active route in the `routes` array + * - `routes`: an array containing a list of route objects used for rendering the tabs + * + * Each route object should contain the following properties: + * + * - `key`: a unique key to identify the route (required) + * - `title`: title of the route to use as the tab label + * - `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 + * - `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 + * - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text. + * - `accessibilityLabel`: accessibility label for the tab button + * - `testID`: test id for the tab button + * + * Example: + * + * ```js + * { + * index: 1, + * routes: [ + * { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'}, + * { key: 'albums', title: 'Albums', focusedIcon: 'album' }, + * { key: 'recents', title: 'Recents', focusedIcon: 'history' }, + * { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' }, + * ] + * } + * ``` + * + * `NavigationBar` is a controlled component, which means the `index` needs to be updated via the `onTabPress` callback. + */ + navigationState: NavigationState; + /** + * Callback which returns a React Element to be used as tab icon. + */ + renderIcon?: (props: { + route: Route; + focused: boolean; + color: ColorValue; + }) => React.ReactNode; + /** + * Callback which React Element to be used as tab label. + */ + renderLabel?: (props: { + route: Route; + focused: boolean; + color: ColorValue; + }) => React.ReactNode; + /** + * Callback which returns a React element to be used as the touchable for the tab item. + * Renders a `TouchableRipple` on Android and `Pressable` on iOS. + */ + renderTouchable?: (props: TouchableProps) => React.ReactNode; + /** + * Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab. + * Uses `route.accessibilityLabel` by default. + */ + getAccessibilityLabel?: (props: { route: Route }) => string | undefined; + /** + * Get badge for the tab, uses `route.badge` by default. + */ + getBadge?: (props: { route: Route }) => boolean | number | string | undefined; + /** + * Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component. + */ + getLabelText?: (props: { route: Route }) => string | undefined; + /** + * Get the id to locate this tab button in tests, uses `route.testID` by default. + */ + getTestID?: (props: { route: Route }) => string | undefined; + /** + * Function to execute on tab press. It receives the route for the pressed tab. Use this to update the navigation state. + */ + onTabPress: (props: { route: Route } & TabPressEvent) => void; + /** + * Function to execute on tab long press. It receives the route for the pressed tab + */ + onTabLongPress?: (props: { route: Route } & TabPressEvent) => void; + /** + * Custom color for icon and label in the active tab. + */ + activeColor?: string; + /** + * Custom color for icon and label in the inactive tab. + */ + inactiveColor?: string; + /** + * Whether the bottom navigation bar is hidden when keyboard is shown. + * On Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`. + */ + keyboardHidesNavigationBar?: boolean; + /** + * 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. + * The bottom insets for iOS is added by default. You can override the behavior with this option. + */ + safeAreaInsets?: { + top?: number; + right?: number; + bottom?: number; + left?: number; + }; + /** + * Specifies the largest possible scale a label font can reach. + */ + labelMaxFontSizeMultiplier?: number; + style?: RNAnimated.WithAnimatedValue>; + activeIndicatorStyle?: StyleProp; + /** + * @optional + */ + theme?: ThemeProp; + /** + * TestID used for testing purposes + */ + testID?: string; +}; + +const Touchable = ({ + route: _0, + style, + children, + borderless, + centered, + rippleColor, + ...rest +}: TouchableProps) => + TouchableRipple.supported ? ( + + {children} + + ) : ( + + {children} + + ); + +type ItemProps = { + route: Route; + focused: boolean; + labeled: boolean; + variant: 'stacked' | 'horizontal'; + activeTintColor: ColorValue; + inactiveTintColor: ColorValue; + activeColor?: string; + inactiveColor?: string; + renderIcon?: Props['renderIcon']; + renderLabel?: Props['renderLabel']; + renderTouchable: NonNullable['renderTouchable']>; + getLabelText: NonNullable['getLabelText']>; + getBadge: NonNullable['getBadge']>; + getTestID: NonNullable['getTestID']>; + getAccessibilityLabel: NonNullable['getAccessibilityLabel']>; + onPress: () => void; + onLongPress: () => void; + activeIndicatorStyle?: StyleProp; + labelMaxFontSizeMultiplier?: number; + theme: Theme; +}; + +const NavigationBarItem = ({ + route, + focused, + labeled, + variant, + activeTintColor, + inactiveTintColor, + activeColor, + inactiveColor, + renderIcon, + renderLabel, + renderTouchable, + getLabelText, + getBadge, + getTestID, + getAccessibilityLabel, + onPress, + onLongPress, + activeIndicatorStyle, + labelMaxFontSizeMultiplier = 1, + theme, +}: ItemProps) => { + const { colors } = theme; + + const [hovered, setHovered] = React.useState(false); + const [keyboardFocused, setKeyboardFocused] = React.useState(false); + const [pressed, setPressed] = React.useState(false); + + const reduceMotion = useReduceMotion(); + const reanimatedReduceMotion = reduceMotion + ? ReduceMotion.Always + : ReduceMotion.Never; + + // Selection progress for the active indicator: 1 when focused, 0 otherwise. + // Each item springs its own progress from its `focused` prop, so there's no + // shared animation array to keep in sync. + const progress = useSharedValue(focused ? 1 : 0); + const isFirstRender = React.useRef(true); + + React.useEffect(() => { + if (isFirstRender.current) { + isFirstRender.current = false; + return; + } + progress.value = withSpring(focused ? 1 : 0, { + ...toRawSpring(theme.motion.spring.fast.spatial), + reduceMotion: reanimatedReduceMotion, + }); + }, [focused, progress, theme.motion, reanimatedReduceMotion]); + + // The active indicator is always mounted and cross-fades via opacity (the + // stacked layout also scales it horizontally 0.5 → 1, the horizontal layout + // scales it 0.8 → 1). + const stackedIndicatorAnimatedStyle = useAnimatedStyle(() => ({ + opacity: progress.value, + transform: [{ scaleX: 0.5 + progress.value * 0.5 }], + })); + const horizontalIndicatorAnimatedStyle = useAnimatedStyle(() => ({ + opacity: progress.value, + transform: [{ scale: 0.8 + progress.value * 0.2 }], + })); + + const iconColor = focused ? activeTintColor : inactiveTintColor; + const labelColor = getLabelColor({ + tintColor: iconColor, + hasColor: Boolean(focused ? activeColor : inactiveColor), + focused, + theme, + }); + + const badge = getBadge({ route }); + const badgeStyle = { + top: typeof badge === 'boolean' ? 4 : 2, + right: + badge != null && typeof badge !== 'boolean' + ? String(badge).length * -2 + : 0, + }; + + const font = theme.fonts.labelMedium; + + // MD3 state layer: visible on hover (8%) and focus/press (10%). Active items + // use the on-secondary-container role, inactive the on-surface-variant role. + const stateLayerRole = focused + ? colorRoles.activeIcon + : colorRoles.inactiveIcon; + const stateLayer = pressed + ? getStateLayer(theme, stateLayerRole, 'pressed') + : keyboardFocused + ? getStateLayer(theme, stateLayerRole, 'focused') + : hovered + ? getStateLayer(theme, stateLayerRole, 'hovered') + : null; + const stateLayerColor = stateLayer + ? { backgroundColor: stateLayer.color, opacity: stateLayer.opacity } + : null; + + const itemTestID = getTestID({ route }); + const indicatorTestID = itemTestID + ? `${itemTestID}-active-indicator` + : undefined; + const stateLayerTestID = itemTestID ? `${itemTestID}-state-layer` : undefined; + + // The horizontal arrangement places the label beside the icon and only + // applies when labels are shown; otherwise it falls back to stacked icon-only. + const horizontal = variant === 'horizontal' && labeled; + + // Item pieces shared across both layouts. The active/inactive distinction is + // a plain color swap (no cross-fade), so a single icon and label suffice. + const icon = renderIcon ? ( + renderIcon({ route, focused, color: iconColor }) + ) : ( + + ); + + const tabBadge = ( + + {typeof badge === 'boolean' ? ( + + ) : ( + {badge} + )} + + ); + + const renderTabLabel = (labelStyle: StyleProp) => + renderLabel ? ( + renderLabel({ route, focused, color: labelColor }) + ) : ( + + {getLabelText({ route })} + + ); + + const stackedContent = ( + + + + + + + {icon} + {tabBadge} + + {labeled ? ( + + {renderTabLabel(styles.label)} + + ) : null} + + ); + + const horizontalContent = ( + + + + + + {icon} + {tabBadge} + + {renderTabLabel(styles.horizontalLabel)} + + + ); + + return renderTouchable({ + key: route.key, + route, + borderless: true, + centered: true, + rippleColor: 'transparent', + onPress, + onLongPress, + onPressIn: () => setPressed(true), + onPressOut: () => setPressed(false), + onHoverIn: () => setHovered(true), + onHoverOut: () => setHovered(false), + onFocus: () => setKeyboardFocused(true), + onBlur: () => setKeyboardFocused(false), + testID: itemTestID, + accessibilityLabel: getAccessibilityLabel({ route }), + accessibilityRole: Platform.OS === 'ios' ? 'button' : 'tab', + accessibilityState: { selected: focused }, + style: styles.item, + children: horizontal ? horizontalContent : stackedContent, + }); +}; + +/** + * The Material Design 3 flexible navigation bar. It can easily be integrated + * with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/). + * + * Set the `variant` prop to `'horizontal'` to lay items out horizontally + * (icon beside label) in medium-width windows. + * + * ## Usage + * ### without React Navigation + * ```js + * import * as React from 'react'; + * import { View } from 'react-native'; + * import { NavigationBar, Text, Provider } from 'react-native-paper'; + * + * function HomeScreen() { + * return ( + * + * Home! + * + * ); + * } + * + * function SettingsScreen() { + * return ( + * + * Settings! + * + * ); + * } + * + * export default function MyComponent() { + * const [index, setIndex] = React.useState(0); + * + * const routes = [ + * { key: 'home', title: 'Home', focusedIcon: 'home' }, + * { key: 'settings', title: 'Settings', focusedIcon: 'cog' }, + * ]; + * + * const renderScene = ({ route }) => { + * switch (route.key) { + * case 'home': + * return ; + * case 'settings': + * return ; + * default: + * return null; + * } + * }; + * + * return ( + * + * {renderScene({ route: routes[index] })} + * { + * const newIndex = routes.findIndex((r) => r.key === route.key); + * if (newIndex !== -1) { + * setIndex(newIndex); + * } + * }} + * getLabelText={({ route }) => route.title} + * /> + * + * ); + * } + * ``` + */ +const NavigationBar = ({ + navigationState, + renderIcon, + renderLabel, + renderTouchable = ({ key, ...props }: TouchableProps) => ( + + ), + getLabelText = ({ route }: { route: Route }) => route.title, + getBadge = ({ route }: { route: Route }) => route.badge, + getAccessibilityLabel = ({ route }: { route: Route }) => + route.accessibilityLabel, + getTestID = ({ route }: { route: Route }) => route.testID, + activeColor, + inactiveColor, + keyboardHidesNavigationBar = Platform.OS === 'android', + style, + activeIndicatorStyle, + labeled = true, + variant = 'stacked', + onTabPress, + onTabLongPress, + safeAreaInsets, + labelMaxFontSizeMultiplier = 1, + compact: compactProp, + testID = 'bottom-navigation-bar', + theme: themeOverrides, +}: Props) => { + const theme = useInternalTheme(themeOverrides); + const { colors, motion } = theme as Theme; + const { bottom, left, right } = useSafeAreaInsets(); + const compact = compactProp ?? false; + + const reduceMotion = useReduceMotion(); + const reanimatedReduceMotion = reduceMotion + ? ReduceMotion.Always + : ReduceMotion.Never; + + /** + * Visibility of the navigation bar, visible state is 1 and invisible is 0. + */ + const visible = useSharedValue(1); + + /** + * Layout of the navigation bar. + */ + const [layout, onLayout] = useLayout(); + + /** + * Track whether the keyboard is visible to show and hide the navigation bar. + */ + const [keyboardVisible, setKeyboardVisible] = React.useState(false); + + const handleKeyboardShow = React.useCallback(() => { + setKeyboardVisible(true); + visible.value = withTiming(0, { + // The bar slides out, so accelerate (exit). + duration: motion.duration.short3, + easing: Easing.bezier(...motion.easing.standardAccelerate), + reduceMotion: reanimatedReduceMotion, + }); + }, [motion, reanimatedReduceMotion, visible]); + + const handleKeyboardHide = React.useCallback(() => { + visible.value = withTiming( + 1, + { + // The bar slides back in, so decelerate (enter). + duration: motion.duration.short2, + easing: Easing.bezier(...motion.easing.standardDecelerate), + reduceMotion: reanimatedReduceMotion, + }, + (finished) => { + if (finished) { + runOnJS(setKeyboardVisible)(false); + } + } + ); + }, [motion, reanimatedReduceMotion, visible]); + + // Slide the bar down by its own height when the keyboard hides it. + const barAnimatedStyle = useAnimatedStyle(() => ({ + transform: [{ translateY: (1 - visible.value) * layout.height }], + })); + + useIsKeyboardShown({ + onShow: handleKeyboardShow, + onHide: handleKeyboardHide, + }); + + const eventForIndex = (index: number) => { + const event = { + route: navigationState.routes[index], + defaultPrevented: false, + preventDefault: () => { + event.defaultPrevented = true; + }, + }; + + return event; + }; + + const { routes } = navigationState; + + const { backgroundColor: customBackground } = (StyleSheet.flatten(style) || + {}) as { + elevation?: number; + backgroundColor?: ColorValue; + }; + + const backgroundColor = customBackground || colors.surfaceContainer; + + const activeTintColor = getActiveTintColor({ + activeColor, + theme, + }); + + const inactiveTintColor = getInactiveTintColor({ + inactiveColor, + theme, + }); + + const maxTabWidth = routes.length > 3 ? MIN_TAB_WIDTH : MAX_TAB_WIDTH; + const maxTabBarWidth = maxTabWidth * routes.length; + + const insets = { + left: safeAreaInsets?.left ?? left, + right: safeAreaInsets?.right ?? right, + bottom: safeAreaInsets?.bottom ?? bottom, + }; + + return ( + + + + + {routes.map((route, index) => { + const focused = navigationState.index === index; + + return ( + onTabPress(eventForIndex(index))} + onLongPress={() => onTabLongPress?.(eventForIndex(index))} + activeIndicatorStyle={activeIndicatorStyle} + labelMaxFontSizeMultiplier={labelMaxFontSizeMultiplier} + theme={theme as Theme} + /> + ); + })} + + + + + ); +}; + +NavigationBar.displayName = 'NavigationBar'; + +export default NavigationBar; + +const styles = StyleSheet.create({ + bar: { + left: 0, + right: 0, + bottom: 0, + }, + absolute: { + position: 'absolute', + }, + barContent: { + alignItems: 'center', + overflow: 'hidden', + }, + items: { + flexDirection: 'row', + ...(Platform.OS === 'web' + ? { + width: '100%', + } + : null), + }, + item: { + flex: 1, + paddingVertical: 0, + }, + iconContainer: { + height: INDICATOR_HEIGHT, + width: INDICATOR_HEIGHT, + marginTop: 0, + marginBottom: ICON_LABEL_GAP, + marginHorizontal: 12, + alignSelf: 'center', + justifyContent: 'center', + }, + iconWrapper: { + ...StyleSheet.absoluteFill, + top: 4, + alignItems: 'center', + }, + labelContainer: { + height: 16, + paddingBottom: 2, + }, + // eslint-disable-next-line react-native/no-color-literals + label: { + fontSize: 12, + textAlign: 'center', + backgroundColor: 'transparent', + ...(Platform.OS === 'web' + ? { + whiteSpace: 'nowrap', + alignSelf: 'center', + } + : null), + }, + badgeContainer: { + position: 'absolute', + left: 0, + }, + stackedContainer: { + height: BAR_HEIGHT, + justifyContent: 'center', + }, + noLabelContainer: { + height: NO_LABEL_BAR_HEIGHT, + justifyContent: 'center', + alignItems: 'center', + }, + stackedIndicator: { + width: INDICATOR_WIDTH, + height: INDICATOR_HEIGHT, + borderRadius: INDICATOR_BORDER_RADIUS, + alignSelf: 'center', + }, + stateLayerWrapper: { + ...StyleSheet.absoluteFill, + alignItems: 'center', + justifyContent: 'center', + }, + stateLayer: { + width: INDICATOR_WIDTH, + height: INDICATOR_HEIGHT, + borderRadius: INDICATOR_BORDER_RADIUS, + }, + horizontalContainer: { + height: BAR_HEIGHT, + justifyContent: 'center', + alignItems: 'center', + }, + horizontalItem: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + height: INDICATOR_HEIGHT, + paddingHorizontal: 16, + }, + horizontalIndicator: { + borderRadius: INDICATOR_BORDER_RADIUS, + }, + horizontalLabel: { + marginLeft: ICON_LABEL_GAP, + textAlign: 'center', + ...(Platform.OS === 'web' + ? { + whiteSpace: 'nowrap', + } + : null), + }, +}); diff --git a/src/components/NavigationBar/index.tsx b/src/components/NavigationBar/index.tsx new file mode 100644 index 0000000000..3567b88e01 --- /dev/null +++ b/src/components/NavigationBar/index.tsx @@ -0,0 +1,2 @@ +export { default } from './NavigationBar'; +export type { Props, BaseRoute } from './NavigationBar'; diff --git a/src/components/NavigationBar/tokens.ts b/src/components/NavigationBar/tokens.ts new file mode 100644 index 0000000000..cdcca922b3 --- /dev/null +++ b/src/components/NavigationBar/tokens.ts @@ -0,0 +1,39 @@ +import type { ColorRole, TypescaleKey } from '../../theme/types'; + +/** + * Resolved M3 "flexible navigation bar" spec values. + * @see https://m3.material.io/components/navigation-bar/specs + */ + +// Container heights (dp). The flexible navigation bar is shorter than the +// original navigation bar (which was 80dp). +export const BAR_HEIGHT = 64; +export const NO_LABEL_BAR_HEIGHT = 64; + +// Active indicator / state-layer pill (dp). Matches the M3 `large` corner (16). +export const INDICATOR_WIDTH = 64; +export const INDICATOR_HEIGHT = 32; +export const INDICATOR_BORDER_RADIUS = 16; + +// Icon + spacing (dp). +export const ICON_SIZE = 24; +export const ICON_LABEL_GAP = 4; + +// Tab width clamps used by the `compact` layout (dp). +export const MIN_TAB_WIDTH = 96; +export const MAX_TAB_WIDTH = 168; + +export const LABEL_TYPESCALE: TypescaleKey = 'labelMedium'; + +/** + * Color roles per the M3 spec. `activeLabel` is `secondary` (changed from + * `onSurface` in Material 3 / Compose Material3 1.4.0). + */ +export const colorRoles = { + container: 'surfaceContainer', + activeIcon: 'onSecondaryContainer', + activeIndicator: 'secondaryContainer', + activeLabel: 'secondary', + inactiveIcon: 'onSurfaceVariant', + inactiveLabel: 'onSurfaceVariant', +} as const satisfies Record; diff --git a/src/components/BottomNavigation/utils.ts b/src/components/NavigationBar/utils.ts similarity index 76% rename from src/components/BottomNavigation/utils.ts rename to src/components/NavigationBar/utils.ts index ede88105e4..3e10c84f5e 100644 --- a/src/components/BottomNavigation/utils.ts +++ b/src/components/NavigationBar/utils.ts @@ -1,5 +1,6 @@ import type { ColorValue } from 'react-native'; +import { colorRoles } from './tokens'; import type { InternalTheme, Theme } from '../../types'; export const getActiveTintColor = ({ @@ -13,7 +14,7 @@ export const getActiveTintColor = ({ return activeColor; } - return (theme as Theme).colors.onSecondaryContainer; + return (theme as Theme).colors[colorRoles.activeIcon]; }; export const getInactiveTintColor = ({ @@ -27,7 +28,7 @@ export const getInactiveTintColor = ({ return inactiveColor; } - return (theme as Theme).colors.onSurfaceVariant; + return (theme as Theme).colors[colorRoles.inactiveIcon]; }; export const getLabelColor = ({ @@ -46,8 +47,5 @@ export const getLabelColor = ({ return tintColor; } - if (focused) { - return colors.onSurface; - } - return colors.onSurfaceVariant; + return colors[focused ? colorRoles.activeLabel : colorRoles.inactiveLabel]; }; diff --git a/src/components/__tests__/BottomNavigation.test.tsx b/src/components/__tests__/BottomNavigation.test.tsx deleted file mode 100644 index 21e495742a..0000000000 --- a/src/components/__tests__/BottomNavigation.test.tsx +++ /dev/null @@ -1,653 +0,0 @@ -import { Animated, Easing, Platform, StyleSheet, Text } from 'react-native'; - -import { describe, expect, it, jest } from '@jest/globals'; -import { act, fireEvent, userEvent } from '@testing-library/react-native'; - -import { getTheme } from '../../core/theming'; -import { render, screen } from '../../test-utils'; -import { Palette } from '../../theme/tokens'; -import BottomNavigation from '../BottomNavigation/BottomNavigation'; -import BottomNavigationRouteScreen from '../BottomNavigation/BottomNavigationRouteScreen'; -import { - getActiveTintColor, - getInactiveTintColor, - getLabelColor, -} from '../BottomNavigation/utils'; -import Icon from '../Icon'; - -const styles = StyleSheet.create({ - backgroundColor: { - backgroundColor: Palette.error60, - }, -}); - -const icons = ['magnify', 'camera', 'inbox', 'heart', 'shopping-music']; - -const createState = (index: number, length: number) => ({ - index, - routes: Array.from({ length }, (_, i) => ({ - key: `key-${i}`, - focusedIcon: icons[i], - unfocusedIcon: undefined, - title: `Route: ${i}`, - })), -}); - -const renderScene = ({ route }: { route: { title: string } }) => ( - {route.title} -); - -const getTab = (index: number) => - screen.getAllByRole(Platform.OS === 'ios' ? 'button' : 'tab')[index]; - -const layoutNavigationBar = async () => { - await fireEvent(screen.getByTestId('bottom-navigation-bar'), 'layout', { - nativeEvent: { - layout: { height: 56, width: 360 }, - }, - }); -}; - -it('renders shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('renders bottom navigation with scene animation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -// eslint-disable-next-line jest/no-disabled-tests -it.skip('sceneAnimationEnabled matches animation requirements', async () => { - const ease = Easing.ease; - - await render( - - ); - - // Simulate the button press - await userEvent.press(screen.getAllByRole('button')[1]); - - // Expect the calls to Animated.parallel - expect(Animated.parallel).toHaveBeenCalledTimes(2); - - // Expect the first call to Animated.parallel - expect(Animated.parallel).toHaveBeenCalledWith( - expect.arrayContaining([ - expect.objectContaining({ - // ripple - config: expect.objectContaining({ toValue: 1, duration: 400 }), - }), - ]) - ); - - // Expect the second call to Animated.parallel - expect(Animated.parallel).toHaveBeenCalledWith( - expect.arrayContaining([ - expect.objectContaining({ - // previous position anims, shifting to the left - config: expect.objectContaining({ - toValue: -1, - duration: 150, - easing: ease, - }), - }), - expect.objectContaining({ - // active page visibility - config: expect.objectContaining({ - toValue: 1, - duration: 150, - easing: ease, - }), - }), - expect.objectContaining({ - // next position anims, shifting to the right - config: expect.objectContaining({ - toValue: 1, - duration: 150, - easing: ease, - }), - }), - ]) - ); -}); - -it('calls onIndexChange', async () => { - const onIndexChange = jest.fn(); - await render( - - ); - - await layoutNavigationBar(); - - // pressing same index as active navigation state does not call onIndexChange - await userEvent.press(getTab(0)); - expect(onIndexChange).not.toHaveBeenCalled(); - - await userEvent.press(getTab(1)); - expect(onIndexChange).toHaveBeenCalledTimes(1); -}); - -it('calls onTabPress', async () => { - const onTabPress = jest.fn(); - const onIndexChange = jest.fn(); - - await render( - - ); - - await layoutNavigationBar(); - - await userEvent.press(getTab(1)); - expect(onTabPress).toHaveBeenCalled(); - expect(onTabPress).toHaveBeenCalledTimes(1); - expect(onTabPress).toHaveBeenLastCalledWith( - expect.objectContaining({ - route: expect.objectContaining({ - key: 'key-1', - }), - defaultPrevented: expect.any(Boolean), - preventDefault: expect.any(Function), - }) - ); -}); - -it('calls onTabLongPress', async () => { - const onTabLongPress = jest.fn(); - const onIndexChange = jest.fn(); - - await render( - - ); - - await layoutNavigationBar(); - - await userEvent.longPress(getTab(2)); - expect(onTabLongPress).toHaveBeenCalled(); - expect(onTabLongPress).toHaveBeenCalledTimes(1); - expect(onTabLongPress).toHaveBeenLastCalledWith( - expect.objectContaining({ - route: expect.objectContaining({ - key: 'key-2', - }), - defaultPrevented: expect.any(Boolean), - preventDefault: expect.any(Function), - }) - ); -}); - -it('renders non-shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('does not crash when shifting is true and the number of tabs in the navigationState is less than 2', async () => { - jest.spyOn(console, 'warn').mockImplementation(() => {}); - - await render( - - ); - - expect(console.warn).toHaveBeenCalledWith( - 'BottomNavigation needs at least 2 tabs to run shifting animation' - ); - - jest.restoreAllMocks(); -}); - -it('renders custom icon and label in shifting bottom navigation', async () => { - const tree = ( - await render( - ( - - )} - renderLabel={({ route, color }) => ( - - {route.title} - - )} - /> - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('renders custom icon and label in non-shifting bottom navigation', async () => { - const tree = ( - await render( - ( - - )} - renderLabel={({ route, color }) => ( - - {route.title} - - )} - /> - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('renders custom icon and label with custom colors in shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('renders custom icon and label with custom colors in non-shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('hides labels in shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('hides labels in non-shifting bottom navigation', async () => { - const tree = ( - await render( - - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); - -it('should have appropriate display style according to the visibility on web', async () => { - const originalPlatform = Platform.OS; - Platform.OS = 'web'; - - const { rerender } = await render( - - ); - - const wrapper = screen.getByTestId('RouteScreen: 0'); - - expect(wrapper).toHaveStyle({ display: 'flex' }); - - await rerender(); - expect(wrapper).toHaveStyle({ display: 'none' }); - - Platform.OS = originalPlatform; -}); - -it('should have labelMaxFontSizeMultiplier passed to label', async () => { - const labelMaxFontSizeMultiplier = 2; - await render( - - ); - - const label = screen.getAllByText('Route: 0').find( - // eslint-disable-next-line no-restricted-syntax -- TODO: replace TestInstance props access with a user-visible assertion. - (item) => item.props.maxFontSizeMultiplier === labelMaxFontSizeMultiplier - ); - - expect(label).toBeTruthy(); -}); - -it('renders custom background color passed to barStyle property', async () => { - await render( - - ); - - const wrapper = screen.getByTestId('bottom-navigation-bar-content'); - expect(wrapper).toHaveStyle({ backgroundColor: Palette.error60 }); -}); - -it('renders a single tab', async () => { - await render( - - ); - - expect(screen.getByTestId('bottom-navigation')).toBeOnTheScreen(); -}); - -it('renders bottom navigation with getLazy', async () => { - const view = await render( - route.key === 'key-2'} - /> - ); - - expect(view).toMatchSnapshot(); - - expect(screen.queryByTestId('RouteScreen: 2')).not.toBeOnTheScreen(); -}); - -it('applies maxTabBarWidth styling if compact prop is truthy', async () => { - await render( - route.key === 'key-2'} - shifting={false} - testID="bottom-navigation" - compact - /> - ); - - expect( - screen.getByTestId('bottom-navigation-bar-content-wrapper') - ).toHaveStyle({ - maxWidth: 480, - }); -}); - -it('does not apply maxTabBarWidth styling if compact prop is falsy', async () => { - await render( - route.key === 'key-2'} - shifting={false} - testID="bottom-navigation" - compact={false} - /> - ); - - expect( - screen.getByTestId('bottom-navigation-bar-content-wrapper') - ).not.toHaveStyle({ - maxWidth: 480, - }); -}); - -it('renders bar content when shifting is enabled', async () => { - await render( - route.key === 'key-2'} - testID="bottom-navigation" - shifting - /> - ); - - expect(screen.getByTestId('bottom-navigation-bar-content')).toBeOnTheScreen(); -}); - -it('does not render legacy ripple overlay when shifting is disabled', async () => { - await render( - route.key === 'key-2'} - testID="bottom-navigation" - shifting={false} - /> - ); - - expect( - screen.queryByTestId('bottom-navigation-bar-content-ripple') - ).not.toBeOnTheScreen(); -}); - -describe('getActiveTintColor', () => { - it.each` - activeColor | expected - ${'#FBF7DB'} | ${'#FBF7DB'} - ${undefined} | ${Palette.secondary10} - `( - 'returns $expected when activeColor: $activeColor', - ({ activeColor, expected }) => { - const theme = getTheme(false); - const result = getActiveTintColor({ activeColor, theme }); - expect(result).toBe(expected); - } - ); -}); - -describe('getInactiveTintColor', () => { - it.each` - inactiveColor | expected - ${'#853D4B'} | ${'#853D4B'} - ${undefined} | ${Palette.neutralVariant30} - `( - 'returns $expected when inactiveColor: $inactiveColor', - ({ inactiveColor, expected }) => { - const theme = getTheme(false); - const result = getInactiveTintColor({ - inactiveColor, - theme, - }); - expect(result).toBe(expected); - } - ); -}); - -describe('getLabelColor', () => { - it.each([ - { tintColor: '#FBF7DB', focused: true, expected: '#FBF7DB' }, - { tintColor: '#853D4B', focused: true, expected: '#853D4B' }, - { tintColor: undefined, focused: true, expected: Palette.neutral10 }, - { - tintColor: undefined, - focused: false, - expected: Palette.neutralVariant30, - }, - ])( - 'returns $expected when tintColor: $tintColor, focused: $focused', - ({ tintColor, focused, expected }) => { - const theme = getTheme(false); - const result = getLabelColor({ - tintColor: tintColor ?? '', - hasColor: Boolean(tintColor), - focused, - theme, - }); - expect(result).toBe(expected); - } - ); -}); - -it('barStyle animated value changes correctly', async () => { - const value = new Animated.Value(1); - await render( - {}} - renderScene={renderScene} - testID={'bottom-navigation'} - barStyle={[{ transform: [{ scale: value }] }]} - /> - ); - expect(screen.getByTestId('bottom-navigation-bar-outer-layer')).toHaveStyle({ - transform: [{ scale: 1 }], - }); - - Animated.timing(value, { - toValue: 1.5, - useNativeDriver: false, - duration: 200, - }).start(); - - await act(() => { - jest.advanceTimersByTime(200); - }); - expect(screen.getByTestId('bottom-navigation-bar-outer-layer')).toHaveStyle({ - transform: [{ scale: 1.5 }], - }); -}); - -it("allows customizing Route's type via generics", async () => { - type CustomRoute = { - key: string; - customPropertyName: string; - }; - - type CustomState = { - index: number; - routes: CustomRoute[]; - }; - - const state: CustomState = { - index: 0, - routes: [ - { key: 'a', customPropertyName: 'First' }, - { key: 'b', customPropertyName: 'Second' }, - ], - }; - - const tree = ( - await render( - route.customPropertyName} - renderScene={({ route }) => {route.customPropertyName}} - /> - ) - ).toJSON(); - - expect(tree).toMatchSnapshot(); -}); diff --git a/src/components/__tests__/NavigationBar.test.tsx b/src/components/__tests__/NavigationBar.test.tsx new file mode 100644 index 0000000000..18a4431fd5 --- /dev/null +++ b/src/components/__tests__/NavigationBar.test.tsx @@ -0,0 +1,221 @@ +import { describe, expect, it, jest } from '@jest/globals'; +import { fireEvent } from '@testing-library/react-native'; + +import { getTheme } from '../../core/theming'; +import { render, screen } from '../../test-utils'; +import { Palette } from '../../theme/tokens'; +import NavigationBar from '../NavigationBar/NavigationBar'; +import { + getActiveTintColor, + getInactiveTintColor, + getLabelColor, +} from '../NavigationBar/utils'; + +const icons = ['magnify', 'camera', 'inbox', 'heart', 'shopping-music']; + +const createState = (index: number, length: number) => ({ + index, + routes: Array.from({ length }, (_, i) => ({ + key: `key-${i}`, + focusedIcon: icons[i], + unfocusedIcon: undefined, + title: `Route: ${i}`, + })), +}); + +it('renders tab labels when labeled', async () => { + await render( + + ); + + // Each tab renders a single label (no cross-fade layers). + expect(screen.getAllByText('Alpha').length).toBeGreaterThan(0); + expect(screen.getAllByText('Beta').length).toBeGreaterThan(0); +}); + +it('renders the horizontal (flexible) variant', async () => { + const tree = ( + await render( + + ) + ).toJSON(); + + expect(tree).toMatchSnapshot(); +}); + +it('falls back to icon-only when horizontal is combined with labeled=false', async () => { + await render( + + ); + + // `horizontal` is a no-op without labels, so no label text is rendered. + expect(screen.queryByText('Route: 0')).toBeNull(); + expect(screen.queryByText('Route: 1')).toBeNull(); +}); + +it('renders MD3 state layers on hover, focus and press', async () => { + const navigationState = { + index: 0, + routes: [ + { key: 'a', title: 'Route: 0', focusedIcon: 'magnify', testID: 'tab-a' }, + { key: 'b', title: 'Route: 1', focusedIcon: 'camera', testID: 'tab-b' }, + ], + }; + + await render( + + ); + + const stateLayer = () => screen.getByTestId('tab-b-state-layer'); + + // Idle: no visible state layer. + expect(stateLayer()).toHaveStyle({ opacity: undefined }); + + // Hovered: 8% state layer. + await fireEvent(screen.getByTestId('tab-b'), 'hoverIn'); + expect(stateLayer()).toHaveStyle({ opacity: 0.08 }); + await fireEvent(screen.getByTestId('tab-b'), 'hoverOut'); + expect(stateLayer()).toHaveStyle({ opacity: undefined }); + + // Focused: 10% state layer. + await fireEvent(screen.getByTestId('tab-b'), 'focus'); + expect(stateLayer()).toHaveStyle({ opacity: 0.1 }); + await fireEvent(screen.getByTestId('tab-b'), 'blur'); + + // Pressed: 10% state layer. + await fireEvent(screen.getByTestId('tab-b'), 'pressIn'); + expect(stateLayer()).toHaveStyle({ opacity: 0.1 }); + await fireEvent(screen.getByTestId('tab-b'), 'pressOut'); + expect(stateLayer()).toHaveStyle({ opacity: undefined }); +}); + +it('colors the focused tab label with secondary and others with onSurfaceVariant', async () => { + const navigationState = { + index: 0, + routes: [ + { key: 'a', title: 'Alpha', focusedIcon: 'magnify' }, + { key: 'b', title: 'Beta', focusedIcon: 'camera' }, + ], + }; + + await render( + + ); + + expect(screen.getAllByText('Alpha').at(-1)).toHaveStyle({ + color: getTheme().colors.secondary, + }); + expect(screen.getAllByText('Beta').at(-1)).toHaveStyle({ + color: getTheme().colors.onSurfaceVariant, + }); +}); + +it('renders the active indicator with the secondaryContainer color', async () => { + const navigationState = { + index: 0, + routes: [ + { key: 'a', title: 'Alpha', focusedIcon: 'magnify', testID: 'tab-a' }, + { key: 'b', title: 'Beta', focusedIcon: 'camera', testID: 'tab-b' }, + ], + }; + + await render( + + ); + + expect(screen.getByTestId('tab-a-active-indicator')).toHaveStyle({ + backgroundColor: getTheme().colors.secondaryContainer, + }); +}); + +it('renders a badge for routes that define one', async () => { + const navigationState = { + index: 0, + routes: [ + { key: 'a', title: 'Alpha', focusedIcon: 'magnify', badge: 3 }, + { key: 'b', title: 'Beta', focusedIcon: 'camera' }, + ], + }; + + await render( + + ); + + expect(screen.getByText('3')).toBeTruthy(); +}); + +describe('getActiveTintColor', () => { + it.each` + activeColor | expected + ${'#FBF7DB'} | ${'#FBF7DB'} + ${undefined} | ${Palette.secondary10} + `( + 'returns $expected when activeColor: $activeColor', + ({ activeColor, expected }) => { + const theme = getTheme(false); + const result = getActiveTintColor({ activeColor, theme }); + expect(result).toBe(expected); + } + ); +}); + +describe('getInactiveTintColor', () => { + it.each` + inactiveColor | expected + ${'#853D4B'} | ${'#853D4B'} + ${undefined} | ${Palette.neutralVariant30} + `( + 'returns $expected when inactiveColor: $inactiveColor', + ({ inactiveColor, expected }) => { + const theme = getTheme(false); + const result = getInactiveTintColor({ + inactiveColor, + theme, + }); + expect(result).toBe(expected); + } + ); +}); + +describe('getLabelColor', () => { + it.each([ + { tintColor: '#FBF7DB', focused: true, expected: '#FBF7DB' }, + { tintColor: '#853D4B', focused: true, expected: '#853D4B' }, + { tintColor: undefined, focused: true, expected: Palette.secondary40 }, + { + tintColor: undefined, + focused: false, + expected: Palette.neutralVariant30, + }, + ])( + 'returns $expected when tintColor: $tintColor, focused: $focused', + ({ tintColor, focused, expected }) => { + const theme = getTheme(false); + const result = getLabelColor({ + tintColor: tintColor ?? '', + hasColor: Boolean(tintColor), + focused, + theme, + }); + expect(result).toBe(expected); + } + ); +}); diff --git a/src/components/__tests__/__snapshots__/BottomNavigation.test.tsx.snap b/src/components/__tests__/__snapshots__/BottomNavigation.test.tsx.snap deleted file mode 100644 index 33855bb467..0000000000 --- a/src/components/__tests__/__snapshots__/BottomNavigation.test.tsx.snap +++ /dev/null @@ -1,12157 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`allows customizing Route's type via generics 1`] = ` - - - - - - First - - - - - - - - - - - - - - - - - - - - - - First - - - - - First - - - - - - - - - - - - - - - - - - Second - - - - - Second - - - - - - - - - - -`; - -exports[`hides labels in non-shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - - - - -`; - -exports[`hides labels in shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - - - - -`; - -exports[`renders bottom navigation with getLazy 1`] = ` - - - - - - Route: 0 - - - - - - - Route: 1 - - - - - - - Route: 3 - - - - - - - Route: 4 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - Route: 2 - - - - - - - - - - - heart - - - - - heart - - - - - - - - - - Route: 3 - - - - - Route: 3 - - - - - - - - - - - shopping-music - - - - - shopping-music - - - - - - - - - - Route: 4 - - - - - Route: 4 - - - - - - - - - - -`; - -exports[`renders bottom navigation with scene animation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - - - - - - - heart - - - - - heart - - - - - - - - - - Route: 3 - - - - - - - - - - - shopping-music - - - - - shopping-music - - - - - - - - - - Route: 4 - - - - - - - - - - -`; - -exports[`renders custom icon and label in non-shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - - - - - - - - Route: 0 - - - - - Route: 0 - - - - - - - - - - - - - - - - - - Route: 1 - - - - - Route: 1 - - - - - - - - - - - - - - - - - - Route: 2 - - - - - Route: 2 - - - - - - - - - - -`; - -exports[`renders custom icon and label in shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - - - - - - - - Route: 0 - - - - - - - - - - - - - - - - - - Route: 1 - - - - - - - - - - - - - - - - - - Route: 2 - - - - - - - - - - - - - - - - - - Route: 3 - - - - - - - - - - - - - - - - - - Route: 4 - - - - - - - - - - -`; - -exports[`renders custom icon and label with custom colors in non-shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - Route: 2 - - - - - - - - - - -`; - -exports[`renders custom icon and label with custom colors in shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - - - - - - -`; - -exports[`renders non-shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - Route: 2 - - - - - - - - - - -`; - -exports[`renders shifting bottom navigation 1`] = ` - - - - - - Route: 0 - - - - - - - - - - - - - - - magnify - - - - - magnify - - - - - - - - - - Route: 0 - - - - - - - - - - - camera - - - - - camera - - - - - - - - - - Route: 1 - - - - - - - - - - - inbox - - - - - inbox - - - - - - - - - - Route: 2 - - - - - - - - - - - heart - - - - - heart - - - - - - - - - - Route: 3 - - - - - - - - - - - shopping-music - - - - - shopping-music - - - - - - - - - - Route: 4 - - - - - - - - - - -`; diff --git a/src/components/__tests__/__snapshots__/NavigationBar.test.tsx.snap b/src/components/__tests__/__snapshots__/NavigationBar.test.tsx.snap new file mode 100644 index 0000000000..34b6835173 --- /dev/null +++ b/src/components/__tests__/__snapshots__/NavigationBar.test.tsx.snap @@ -0,0 +1,750 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders the horizontal (flexible) variant 1`] = ` + + + + + + + + + + + + + magnify + + + + + + + Route: 0 + + + + + + + + + + + + camera + + + + + + + Route: 1 + + + + + + + + + + + + inbox + + + + + + + Route: 2 + + + + + + + + + +`; diff --git a/src/index.tsx b/src/index.tsx index 8863e2fa20..3b580962c3 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -24,7 +24,6 @@ export { Avatar, List, Drawer }; export { default as Badge } from './components/Badge'; export { default as ActivityIndicator } from './components/ActivityIndicator'; export { default as Banner } from './components/Banner'; -export { default as BottomNavigation } from './components/BottomNavigation/BottomNavigation'; export { default as Button } from './components/Button/Button'; export { default as Card } from './components/Card/Card'; export { default as Checkbox } from './components/Checkbox'; @@ -37,6 +36,7 @@ export { default as Icon } from './components/Icon'; export { default as IconButton } from './components/IconButton/IconButton'; export { default as Menu } from './components/Menu/Menu'; export { default as Modal } from './components/Modal'; +export { default as NavigationBar } from './components/NavigationBar'; export { default as Portal } from './components/Portal/Portal'; export { default as ProgressBar } from './components/ProgressBar'; export { default as RadioButton } from './components/RadioButton'; @@ -65,10 +65,6 @@ export type { Props as AvatarImageProps } from './components/Avatar/AvatarImage' export type { Props as AvatarTextProps } from './components/Avatar/AvatarText'; export type { Props as BadgeProps } from './components/Badge'; export type { Props as BannerProps } from './components/Banner'; -export type { - Props as BottomNavigationProps, - BaseRoute as BottomNavigationRoute, -} from './components/BottomNavigation/BottomNavigation'; export type { Props as ButtonProps } from './components/Button/Button'; export type { Props as CardProps } from './components/Card/Card'; export type { Props as CardActionsProps } from './components/Card/CardActions'; @@ -115,6 +111,10 @@ export type { Props as ListSubheaderProps } from './components/List/ListSubheade export type { Props as MenuProps } from './components/Menu/Menu'; export type { Props as MenuItemProps } from './components/Menu/MenuItem'; export type { Props as ModalProps } from './components/Modal'; +export type { + Props as NavigationBarProps, + BaseRoute as NavigationBarRoute, +} from './components/NavigationBar'; export type { Props as PortalProps } from './components/Portal/Portal'; export type { Props as PortalHostProps } from './components/Portal/PortalHost'; export type { Props as ProgressBarProps } from './components/ProgressBar';