react-native-acoustic-connect-beta 18.0.7 → 18.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Examples/SampleUI/.bundle/config +2 -0
- package/Examples/SampleUI/.eslintrc.js +4 -0
- package/Examples/SampleUI/.prettierrc.js +7 -0
- package/Examples/SampleUI/.watchmanconfig +1 -0
- package/Examples/SampleUI/App.js +1 -0
- package/Examples/SampleUI/Gemfile +10 -0
- package/Examples/SampleUI/Gemfile.lock +121 -0
- package/Examples/SampleUI/README.md +79 -0
- package/Examples/SampleUI/__tests__/App.test.tsx +17 -0
- package/Examples/SampleUI/android/app/build.gradle +124 -0
- package/Examples/SampleUI/android/app/debug.keystore +0 -0
- package/Examples/SampleUI/android/app/proguard-rules.pro +10 -0
- package/Examples/SampleUI/android/app/src/debug/AndroidManifest.xml +9 -0
- package/Examples/SampleUI/android/app/src/main/AndroidManifest.xml +26 -0
- package/Examples/SampleUI/android/app/src/main/java/com/sampleui/MainActivity.kt +23 -0
- package/Examples/SampleUI/android/app/src/main/java/com/sampleui/MainApplication.kt +53 -0
- package/Examples/SampleUI/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/values/strings.xml +3 -0
- package/Examples/SampleUI/android/app/src/main/res/values/styles.xml +9 -0
- package/Examples/SampleUI/android/build.gradle +21 -0
- package/Examples/SampleUI/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/Examples/SampleUI/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/Examples/SampleUI/android/gradle.properties +39 -0
- package/Examples/SampleUI/android/gradlew +252 -0
- package/Examples/SampleUI/android/gradlew.bat +94 -0
- package/Examples/SampleUI/android/settings.gradle +21 -0
- package/Examples/SampleUI/app.json +51 -0
- package/Examples/SampleUI/assets/fonts/Abel-Regular.ttf +0 -0
- package/Examples/SampleUI/assets/fonts/NotoSans-Regular.ttf +0 -0
- package/Examples/SampleUI/assets/images/android-icon.png +0 -0
- package/Examples/SampleUI/assets/images/artist-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/artist-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/avatar.png +0 -0
- package/Examples/SampleUI/assets/images/beach.jpg +0 -0
- package/Examples/SampleUI/assets/images/bridge.jpg +0 -0
- package/Examples/SampleUI/assets/images/chameleon.jpg +0 -0
- package/Examples/SampleUI/assets/images/city.jpg +0 -0
- package/Examples/SampleUI/assets/images/email-icon.png +0 -0
- package/Examples/SampleUI/assets/images/favorite.png +0 -0
- package/Examples/SampleUI/assets/images/forest.jpg +0 -0
- package/Examples/SampleUI/assets/images/paper-icon.png +0 -0
- package/Examples/SampleUI/assets/images/players-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/players.jpg +0 -0
- package/Examples/SampleUI/assets/images/restaurant-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/restaurant-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/song-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/song-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/splash.png +0 -0
- package/Examples/SampleUI/assets/images/strawberries.jpg +0 -0
- package/Examples/SampleUI/assets/images/wrecked-ship.jpg +0 -0
- package/Examples/SampleUI/assets/styles/fonts.css +47 -0
- package/Examples/SampleUI/babel.config.js +22 -0
- package/Examples/SampleUI/index.js +9 -0
- package/Examples/SampleUI/ios/.xcode.env +11 -0
- package/Examples/SampleUI/ios/Podfile +58 -0
- package/Examples/SampleUI/ios/SampleUI/AppDelegate.h +7 -0
- package/Examples/SampleUI/ios/SampleUI/AppDelegate.mm +31 -0
- package/Examples/SampleUI/ios/SampleUI/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/Examples/SampleUI/ios/SampleUI/Images.xcassets/Contents.json +6 -0
- package/Examples/SampleUI/ios/SampleUI/Info.plist +52 -0
- package/Examples/SampleUI/ios/SampleUI/LaunchScreen.storyboard +47 -0
- package/Examples/SampleUI/ios/SampleUI/PrivacyInfo.xcprivacy +48 -0
- package/Examples/SampleUI/ios/SampleUI/main.m +10 -0
- package/Examples/SampleUI/ios/SampleUI.xcodeproj/project.pbxproj +785 -0
- package/Examples/SampleUI/ios/SampleUI.xcodeproj/xcshareddata/xcschemes/SampleUI.xcscheme +88 -0
- package/Examples/SampleUI/ios/SampleUI.xcworkspace/contents.xcworkspacedata +10 -0
- package/Examples/SampleUI/ios/SampleUITests/Info.plist +24 -0
- package/Examples/SampleUI/ios/SampleUITests/SampleUITests.m +66 -0
- package/Examples/SampleUI/jest.config.js +3 -0
- package/Examples/SampleUI/metro.config.js +53 -0
- package/Examples/SampleUI/package-lock.json +17033 -0
- package/Examples/SampleUI/package.json +62 -0
- package/Examples/SampleUI/src/DrawerItems.tsx +322 -0
- package/Examples/SampleUI/src/ExampleList.tsx +175 -0
- package/Examples/SampleUI/src/Examples/ActivityIndicatorExample.tsx +73 -0
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/AnimatedFABExample.tsx +220 -0
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/CustomFAB.tsx +70 -0
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/CustomFABControls.tsx +146 -0
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/index.ts +1 -0
- package/Examples/SampleUI/src/Examples/AppbarExample.tsx +263 -0
- package/Examples/SampleUI/src/Examples/AvatarExample.tsx +76 -0
- package/Examples/SampleUI/src/Examples/BadgeExample.tsx +97 -0
- package/Examples/SampleUI/src/Examples/BannerExample.tsx +152 -0
- package/Examples/SampleUI/src/Examples/BottomNavigationBarExample.tsx +94 -0
- package/Examples/SampleUI/src/Examples/BottomNavigationExample.tsx +205 -0
- package/Examples/SampleUI/src/Examples/ButtonExample.tsx +405 -0
- package/Examples/SampleUI/src/Examples/CardExample.tsx +245 -0
- package/Examples/SampleUI/src/Examples/CheckboxExample.tsx +87 -0
- package/Examples/SampleUI/src/Examples/CheckboxItemExample.tsx +72 -0
- package/Examples/SampleUI/src/Examples/ChipExample.tsx +432 -0
- package/Examples/SampleUI/src/Examples/DataTableExample.tsx +128 -0
- package/Examples/SampleUI/src/Examples/DialogExample.tsx +131 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogTextComponent.tsx +31 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithCustomColors.tsx +57 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithDismissableBackButton.tsx +38 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithIcon.tsx +42 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithLoadingIndicator.tsx +48 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithLongText.tsx +81 -0
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithRadioBtns.tsx +111 -0
- package/Examples/SampleUI/src/Examples/Dialogs/UndismissableDialog.tsx +30 -0
- package/Examples/SampleUI/src/Examples/Dialogs/index.tsx +7 -0
- package/Examples/SampleUI/src/Examples/DividerExample.tsx +30 -0
- package/Examples/SampleUI/src/Examples/FABExample.tsx +226 -0
- package/Examples/SampleUI/src/Examples/IconButtonExample.tsx +230 -0
- package/Examples/SampleUI/src/Examples/IconExample.tsx +50 -0
- package/Examples/SampleUI/src/Examples/ListAccordionExample.tsx +65 -0
- package/Examples/SampleUI/src/Examples/ListAccordionGroupExample.tsx +80 -0
- package/Examples/SampleUI/src/Examples/ListItemExample.tsx +310 -0
- package/Examples/SampleUI/src/Examples/ListSectionExample.tsx +159 -0
- package/Examples/SampleUI/src/Examples/MaterialBottomTabNavigatorExample.tsx +87 -0
- package/Examples/SampleUI/src/Examples/MenuExample.tsx +211 -0
- package/Examples/SampleUI/src/Examples/ProgressBarExample.tsx +142 -0
- package/Examples/SampleUI/src/Examples/RadioButtonExample.tsx +104 -0
- package/Examples/SampleUI/src/Examples/RadioButtonGroupExample.tsx +67 -0
- package/Examples/SampleUI/src/Examples/RadioButtonItemExample.tsx +77 -0
- package/Examples/SampleUI/src/Examples/SearchbarExample.tsx +249 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonCustomColorCheck.tsx +93 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonDefault.tsx +49 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonDisabled.tsx +47 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselect.tsx +50 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselectIcons.tsx +49 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselectRealCase.tsx +114 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonOnlyIcons.tsx +40 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonOnlyIconsWithCheck.tsx +43 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonRealCase.tsx +97 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonWithDensity.tsx +47 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonWithSelectedCheck.tsx +52 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtons/index.ts +9 -0
- package/Examples/SampleUI/src/Examples/SegmentedButtonsExample.tsx +57 -0
- package/Examples/SampleUI/src/Examples/SnackbarExample.tsx +141 -0
- package/Examples/SampleUI/src/Examples/SurfaceExample.tsx +130 -0
- package/Examples/SampleUI/src/Examples/SwitchExample.tsx +105 -0
- package/Examples/SampleUI/src/Examples/TeamDetails.tsx +291 -0
- package/Examples/SampleUI/src/Examples/TeamsList.tsx +57 -0
- package/Examples/SampleUI/src/Examples/TextExample.tsx +132 -0
- package/Examples/SampleUI/src/Examples/TextInputExample.tsx +914 -0
- package/Examples/SampleUI/src/Examples/ThemeExample.tsx +41 -0
- package/Examples/SampleUI/src/Examples/ThemingWithReactNavigation.tsx +75 -0
- package/Examples/SampleUI/src/Examples/ToggleButtonExample.tsx +128 -0
- package/Examples/SampleUI/src/Examples/TooltipExample.tsx +191 -0
- package/Examples/SampleUI/src/Examples/TouchableRippleExample.tsx +37 -0
- package/Examples/SampleUI/src/RootNavigator.tsx +86 -0
- package/Examples/SampleUI/src/ScreenWrapper.tsx +67 -0
- package/Examples/SampleUI/src/components/ActivityIndicator.tsx +254 -0
- package/Examples/SampleUI/src/components/Appbar/Appbar.tsx +364 -0
- package/Examples/SampleUI/src/components/Appbar/AppbarAction.tsx +132 -0
- package/Examples/SampleUI/src/components/Appbar/AppbarBackAction.tsx +77 -0
- package/Examples/SampleUI/src/components/Appbar/AppbarBackIcon.tsx +52 -0
- package/Examples/SampleUI/src/components/Appbar/AppbarContent.tsx +249 -0
- package/Examples/SampleUI/src/components/Appbar/AppbarHeader.tsx +174 -0
- package/Examples/SampleUI/src/components/Appbar/index.ts +22 -0
- package/Examples/SampleUI/src/components/Appbar/utils.ts +188 -0
- package/Examples/SampleUI/src/components/Avatar/Avatar.tsx +8 -0
- package/Examples/SampleUI/src/components/Avatar/AvatarIcon.tsx +87 -0
- package/Examples/SampleUI/src/components/Avatar/AvatarImage.tsx +128 -0
- package/Examples/SampleUI/src/components/Avatar/AvatarText.tsx +127 -0
- package/Examples/SampleUI/src/components/Badge.tsx +138 -0
- package/Examples/SampleUI/src/components/Banner.tsx +302 -0
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigation.tsx +643 -0
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigationBar.tsx +1039 -0
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigationRouteScreen.tsx +31 -0
- package/Examples/SampleUI/src/components/BottomNavigation/utils.ts +70 -0
- package/Examples/SampleUI/src/components/Button/Button.tsx +503 -0
- package/Examples/SampleUI/src/components/Button/utils.tsx +272 -0
- package/Examples/SampleUI/src/components/Card/Card.tsx +373 -0
- package/Examples/SampleUI/src/components/Card/CardActions.tsx +74 -0
- package/Examples/SampleUI/src/components/Card/CardContent.tsx +99 -0
- package/Examples/SampleUI/src/components/Card/CardCover.tsx +96 -0
- package/Examples/SampleUI/src/components/Card/CardTitle.tsx +236 -0
- package/Examples/SampleUI/src/components/Card/utils.tsx +110 -0
- package/Examples/SampleUI/src/components/Checkbox/Checkbox.tsx +78 -0
- package/Examples/SampleUI/src/components/Checkbox/CheckboxAndroid.tsx +180 -0
- package/Examples/SampleUI/src/components/Checkbox/CheckboxIOS.tsx +104 -0
- package/Examples/SampleUI/src/components/Checkbox/CheckboxItem.tsx +236 -0
- package/Examples/SampleUI/src/components/Checkbox/index.ts +19 -0
- package/Examples/SampleUI/src/components/Checkbox/utils.ts +183 -0
- package/Examples/SampleUI/src/components/Chip/Chip.tsx +513 -0
- package/Examples/SampleUI/src/components/Chip/helpers.tsx +322 -0
- package/Examples/SampleUI/src/components/CrossFadeIcon.tsx +140 -0
- package/Examples/SampleUI/src/components/DataTable/DataTable.tsx +138 -0
- package/Examples/SampleUI/src/components/DataTable/DataTableCell.tsx +132 -0
- package/Examples/SampleUI/src/components/DataTable/DataTableHeader.tsx +82 -0
- package/Examples/SampleUI/src/components/DataTable/DataTablePagination.tsx +407 -0
- package/Examples/SampleUI/src/components/DataTable/DataTableRow.tsx +107 -0
- package/Examples/SampleUI/src/components/DataTable/DataTableTitle.tsx +208 -0
- package/Examples/SampleUI/src/components/Dialog/Dialog.tsx +191 -0
- package/Examples/SampleUI/src/components/Dialog/DialogActions.tsx +94 -0
- package/Examples/SampleUI/src/components/Dialog/DialogContent.tsx +54 -0
- package/Examples/SampleUI/src/components/Dialog/DialogIcon.tsx +100 -0
- package/Examples/SampleUI/src/components/Dialog/DialogScrollArea.tsx +88 -0
- package/Examples/SampleUI/src/components/Dialog/DialogTitle.tsx +94 -0
- package/Examples/SampleUI/src/components/Divider.tsx +102 -0
- package/Examples/SampleUI/src/components/Drawer/Drawer.tsx +8 -0
- package/Examples/SampleUI/src/components/Drawer/DrawerCollapsedItem.tsx +282 -0
- package/Examples/SampleUI/src/components/Drawer/DrawerItem.tsx +209 -0
- package/Examples/SampleUI/src/components/Drawer/DrawerSection.tsx +138 -0
- package/Examples/SampleUI/src/components/FAB/AnimatedFAB.tsx +619 -0
- package/Examples/SampleUI/src/components/FAB/FAB.tsx +371 -0
- package/Examples/SampleUI/src/components/FAB/FABGroup.tsx +532 -0
- package/Examples/SampleUI/src/components/FAB/index.ts +13 -0
- package/Examples/SampleUI/src/components/FAB/utils.ts +474 -0
- package/Examples/SampleUI/src/components/HelperText/HelperText.tsx +168 -0
- package/Examples/SampleUI/src/components/HelperText/utils.ts +30 -0
- package/Examples/SampleUI/src/components/Icon.tsx +170 -0
- package/Examples/SampleUI/src/components/IconButton/IconButton.tsx +234 -0
- package/Examples/SampleUI/src/components/IconButton/utils.ts +190 -0
- package/Examples/SampleUI/src/components/List/List.tsx +20 -0
- package/Examples/SampleUI/src/components/List/ListAccordion.tsx +391 -0
- package/Examples/SampleUI/src/components/List/ListAccordionGroup.tsx +88 -0
- package/Examples/SampleUI/src/components/List/ListIcon.tsx +79 -0
- package/Examples/SampleUI/src/components/List/ListImage.tsx +89 -0
- package/Examples/SampleUI/src/components/List/ListItem.tsx +313 -0
- package/Examples/SampleUI/src/components/List/ListSection.tsx +87 -0
- package/Examples/SampleUI/src/components/List/ListSubheader.tsx +79 -0
- package/Examples/SampleUI/src/components/List/utils.ts +113 -0
- package/Examples/SampleUI/src/components/MaterialCommunityIcon.tsx +121 -0
- package/Examples/SampleUI/src/components/Menu/Menu.tsx +711 -0
- package/Examples/SampleUI/src/components/Menu/MenuItem.tsx +257 -0
- package/Examples/SampleUI/src/components/Menu/utils.ts +110 -0
- package/Examples/SampleUI/src/components/Modal.tsx +245 -0
- package/Examples/SampleUI/src/components/Portal/Portal.tsx +69 -0
- package/Examples/SampleUI/src/components/Portal/PortalConsumer.tsx +44 -0
- package/Examples/SampleUI/src/components/Portal/PortalHost.tsx +143 -0
- package/Examples/SampleUI/src/components/Portal/PortalManager.tsx +54 -0
- package/Examples/SampleUI/src/components/ProgressBar.tsx +292 -0
- package/Examples/SampleUI/src/components/RadioButton/RadioButton.tsx +86 -0
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonAndroid.tsx +202 -0
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonGroup.tsx +67 -0
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonIOS.tsx +130 -0
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonItem.tsx +268 -0
- package/Examples/SampleUI/src/components/RadioButton/index.ts +22 -0
- package/Examples/SampleUI/src/components/RadioButton/utils.ts +37 -0
- package/Examples/SampleUI/src/components/Searchbar.tsx +459 -0
- package/Examples/SampleUI/src/components/SegmentedButtons/SegmentedButtonItem.tsx +271 -0
- package/Examples/SampleUI/src/components/SegmentedButtons/SegmentedButtons.tsx +197 -0
- package/Examples/SampleUI/src/components/SegmentedButtons/utils.ts +179 -0
- package/Examples/SampleUI/src/components/Snackbar.tsx +430 -0
- package/Examples/SampleUI/src/components/Surface.tsx +376 -0
- package/Examples/SampleUI/src/components/Switch/Switch.tsx +108 -0
- package/Examples/SampleUI/src/components/Switch/utils.ts +113 -0
- package/Examples/SampleUI/src/components/TextInput/Addons/Outline.tsx +64 -0
- package/Examples/SampleUI/src/components/TextInput/Addons/Underline.tsx +78 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputAdornment.tsx +208 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputAffix.tsx +212 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputIcon.tsx +195 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/enums.tsx +12 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/types.tsx +11 -0
- package/Examples/SampleUI/src/components/TextInput/Adornment/utils.ts +48 -0
- package/Examples/SampleUI/src/components/TextInput/Label/InputLabel.tsx +217 -0
- package/Examples/SampleUI/src/components/TextInput/Label/LabelBackground.tsx +100 -0
- package/Examples/SampleUI/src/components/TextInput/TextInput.tsx +572 -0
- package/Examples/SampleUI/src/components/TextInput/TextInputFlat.tsx +475 -0
- package/Examples/SampleUI/src/components/TextInput/TextInputOutlined.tsx +450 -0
- package/Examples/SampleUI/src/components/TextInput/constants.tsx +48 -0
- package/Examples/SampleUI/src/components/TextInput/helpers.tsx +612 -0
- package/Examples/SampleUI/src/components/TextInput/types.tsx +155 -0
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButton.tsx +187 -0
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButtonGroup.tsx +72 -0
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButtonRow.tsx +107 -0
- package/Examples/SampleUI/src/components/ToggleButton/index.ts +16 -0
- package/Examples/SampleUI/src/components/ToggleButton/utils.ts +26 -0
- package/Examples/SampleUI/src/components/Tooltip/Tooltip.tsx +249 -0
- package/Examples/SampleUI/src/components/Tooltip/utils.ts +129 -0
- package/Examples/SampleUI/src/components/TouchableRipple/Pressable.tsx +41 -0
- package/Examples/SampleUI/src/components/TouchableRipple/TouchableRipple.native.tsx +145 -0
- package/Examples/SampleUI/src/components/TouchableRipple/TouchableRipple.tsx +317 -0
- package/Examples/SampleUI/src/components/TouchableRipple/utils.ts +66 -0
- package/Examples/SampleUI/src/components/Typography/AnimatedText.tsx +107 -0
- package/Examples/SampleUI/src/components/Typography/Text.tsx +184 -0
- package/Examples/SampleUI/src/components/Typography/types.tsx +5 -0
- package/Examples/SampleUI/src/components/Typography/v2/Caption.tsx +50 -0
- package/Examples/SampleUI/src/components/Typography/v2/Headline.tsx +52 -0
- package/Examples/SampleUI/src/components/Typography/v2/Paragraph.tsx +49 -0
- package/Examples/SampleUI/src/components/Typography/v2/StyledText.tsx +56 -0
- package/Examples/SampleUI/src/components/Typography/v2/Subheading.tsx +50 -0
- package/Examples/SampleUI/src/components/Typography/v2/Text.tsx +62 -0
- package/Examples/SampleUI/src/components/Typography/v2/Title.tsx +49 -0
- package/Examples/SampleUI/src/components/Typography/v2/index.ts +5 -0
- package/Examples/SampleUI/src/core/PaperProvider.tsx +122 -0
- package/Examples/SampleUI/src/core/SafeAreaProviderCompat.tsx +65 -0
- package/Examples/SampleUI/src/core/settings.tsx +23 -0
- package/Examples/SampleUI/src/core/theming.tsx +170 -0
- package/Examples/SampleUI/src/index.native.tsx +270 -0
- package/Examples/SampleUI/src/index.tsx +226 -0
- package/Examples/SampleUI/src/react-navigation/index.tsx +19 -0
- package/Examples/SampleUI/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx +72 -0
- package/Examples/SampleUI/src/react-navigation/types.tsx +126 -0
- package/Examples/SampleUI/src/react-navigation/views/MaterialBottomTabView.tsx +140 -0
- package/Examples/SampleUI/src/styles/__tests__/fonts.test.js +290 -0
- package/Examples/SampleUI/src/styles/fonts.tsx +143 -0
- package/Examples/SampleUI/src/styles/overlay.tsx +70 -0
- package/Examples/SampleUI/src/styles/shadow.tsx +109 -0
- package/Examples/SampleUI/src/styles/themes/index.ts +4 -0
- package/Examples/SampleUI/src/styles/themes/v2/DarkTheme.tsx +30 -0
- package/Examples/SampleUI/src/styles/themes/v2/LightTheme.tsx +30 -0
- package/Examples/SampleUI/src/styles/themes/v2/colors.tsx +277 -0
- package/Examples/SampleUI/src/styles/themes/v3/DarkTheme.tsx +66 -0
- package/Examples/SampleUI/src/styles/themes/v3/LightTheme.tsx +69 -0
- package/Examples/SampleUI/src/styles/themes/v3/tokens.tsx +230 -0
- package/Examples/SampleUI/src/utils/BackHandler/BackHandler.native.tsx +3 -0
- package/Examples/SampleUI/src/utils/BackHandler/BackHandler.tsx +11 -0
- package/Examples/SampleUI/src/utils/addEventListener.tsx +56 -0
- package/Examples/SampleUI/src/utils/forwardRef.tsx +23 -0
- package/Examples/SampleUI/src/utils/getContrastingColor.tsx +15 -0
- package/Examples/SampleUI/src/utils/hasTouchHandler.tsx +23 -0
- package/Examples/SampleUI/src/utils/roundLayoutSize.ts +2 -0
- package/Examples/SampleUI/src/utils/splitStyles.ts +60 -0
- package/Examples/SampleUI/src/utils/useAnimatedValue.tsx +9 -0
- package/Examples/SampleUI/src/utils/useAnimatedValueArray.tsx +13 -0
- package/Examples/SampleUI/src/utils/useIsKeyboardShown.tsx +55 -0
- package/Examples/SampleUI/src/utils/useLayout.tsx +29 -0
- package/Examples/SampleUI/src/utils/useLazyRef.tsx +11 -0
- package/Examples/SampleUI/tsconfig.json +3 -0
- package/Examples/SampleUI/utils/index.ts +1426 -0
- package/lib/typescript/jslib/TLTRN.d.ts +5 -5
- package/lib/typescript/jslib/TLTRN.d.ts.map +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,1039 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Animated,
|
|
4
|
+
ColorValue,
|
|
5
|
+
EasingFunction,
|
|
6
|
+
Platform,
|
|
7
|
+
StyleProp,
|
|
8
|
+
StyleSheet,
|
|
9
|
+
Pressable,
|
|
10
|
+
View,
|
|
11
|
+
ViewStyle,
|
|
12
|
+
} from 'react-native';
|
|
13
|
+
|
|
14
|
+
import color from 'color';
|
|
15
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
getActiveTintColor,
|
|
19
|
+
getInactiveTintColor,
|
|
20
|
+
getLabelColor,
|
|
21
|
+
} from './utils';
|
|
22
|
+
import { useInternalTheme } from '../../core/theming';
|
|
23
|
+
import overlay from '../../styles/overlay';
|
|
24
|
+
import { black, white } from '../../styles/themes/v2/colors';
|
|
25
|
+
import type { ThemeProp } from '../../types';
|
|
26
|
+
import useAnimatedValue from '../../utils/useAnimatedValue';
|
|
27
|
+
import useAnimatedValueArray from '../../utils/useAnimatedValueArray';
|
|
28
|
+
import useIsKeyboardShown from '../../utils/useIsKeyboardShown';
|
|
29
|
+
import useLayout from '../../utils/useLayout';
|
|
30
|
+
import Badge from '../Badge';
|
|
31
|
+
import Icon, { IconSource } from '../Icon';
|
|
32
|
+
import Surface from '../Surface';
|
|
33
|
+
import TouchableRipple from '../TouchableRipple/TouchableRipple';
|
|
34
|
+
import { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple';
|
|
35
|
+
import Text from '../Typography/Text';
|
|
36
|
+
|
|
37
|
+
type BaseRoute = {
|
|
38
|
+
key: string;
|
|
39
|
+
title?: string;
|
|
40
|
+
focusedIcon?: IconSource;
|
|
41
|
+
unfocusedIcon?: IconSource;
|
|
42
|
+
badge?: string | number | boolean;
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated In v5.x works only with theme version 2.
|
|
45
|
+
*/
|
|
46
|
+
color?: string;
|
|
47
|
+
accessibilityLabel?: string;
|
|
48
|
+
testID?: string;
|
|
49
|
+
lazy?: boolean;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type NavigationState<Route extends BaseRoute> = {
|
|
53
|
+
index: number;
|
|
54
|
+
routes: Route[];
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type TabPressEvent = {
|
|
58
|
+
defaultPrevented: boolean;
|
|
59
|
+
preventDefault(): void;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type TouchableProps<Route extends BaseRoute> = TouchableRippleProps & {
|
|
63
|
+
key: string;
|
|
64
|
+
route: Route;
|
|
65
|
+
children: React.ReactNode;
|
|
66
|
+
borderless?: boolean;
|
|
67
|
+
centered?: boolean;
|
|
68
|
+
rippleColor?: ColorValue;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type Props<Route extends BaseRoute> = {
|
|
72
|
+
/**
|
|
73
|
+
* 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.
|
|
74
|
+
*
|
|
75
|
+
* By default, this is `false` with theme version 3 and `true` when you have more than 3 tabs.
|
|
76
|
+
* Pass `shifting={false}` to explicitly disable this animation, or `shifting={true}` to always use this animation.
|
|
77
|
+
* Note that you need at least 2 tabs be able to run this animation.
|
|
78
|
+
*/
|
|
79
|
+
shifting?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Whether to show labels in tabs. When `false`, only icons will be displayed.
|
|
82
|
+
*/
|
|
83
|
+
labeled?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Whether tabs should be spread across the entire width.
|
|
86
|
+
*/
|
|
87
|
+
compact?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* State for the bottom navigation. The state should contain the following properties:
|
|
90
|
+
*
|
|
91
|
+
* - `index`: a number representing the index of the active route in the `routes` array
|
|
92
|
+
* - `routes`: an array containing a list of route objects used for rendering the tabs
|
|
93
|
+
*
|
|
94
|
+
* Each route object should contain the following properties:
|
|
95
|
+
*
|
|
96
|
+
* - `key`: a unique key to identify the route (required)
|
|
97
|
+
* - `title`: title of the route to use as the tab label
|
|
98
|
+
* - `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
|
|
99
|
+
* - `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
|
|
100
|
+
* - `color`: color to use as background color for shifting bottom navigation @deprecatedProperty In v5.x works only with theme version 2.
|
|
101
|
+
* - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text.
|
|
102
|
+
* - `accessibilityLabel`: accessibility label for the tab button
|
|
103
|
+
* - `testID`: test id for the tab button
|
|
104
|
+
*
|
|
105
|
+
* Example:
|
|
106
|
+
*
|
|
107
|
+
* ```js
|
|
108
|
+
* {
|
|
109
|
+
* index: 1,
|
|
110
|
+
* routes: [
|
|
111
|
+
* { key: 'music', title: 'Favorites', focusedIcon: 'heart', unfocusedIcon: 'heart-outline'},
|
|
112
|
+
* { key: 'albums', title: 'Albums', focusedIcon: 'album' },
|
|
113
|
+
* { key: 'recents', title: 'Recents', focusedIcon: 'history' },
|
|
114
|
+
* { key: 'notifications', title: 'Notifications', focusedIcon: 'bell', unfocusedIcon: 'bell-outline' },
|
|
115
|
+
* ]
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* `BottomNavigation.Bar` is a controlled component, which means the `index` needs to be updated via the `onTabPress` callback.
|
|
120
|
+
*/
|
|
121
|
+
navigationState: NavigationState<Route>;
|
|
122
|
+
/**
|
|
123
|
+
* Callback which returns a React Element to be used as tab icon.
|
|
124
|
+
*/
|
|
125
|
+
renderIcon?: (props: {
|
|
126
|
+
route: Route;
|
|
127
|
+
focused: boolean;
|
|
128
|
+
color: string;
|
|
129
|
+
}) => React.ReactNode;
|
|
130
|
+
/**
|
|
131
|
+
* Callback which React Element to be used as tab label.
|
|
132
|
+
*/
|
|
133
|
+
renderLabel?: (props: {
|
|
134
|
+
route: Route;
|
|
135
|
+
focused: boolean;
|
|
136
|
+
color: string;
|
|
137
|
+
}) => React.ReactNode;
|
|
138
|
+
/**
|
|
139
|
+
* Callback which returns a React element to be used as the touchable for the tab item.
|
|
140
|
+
* Renders a `TouchableRipple` on Android and `Pressable` on iOS.
|
|
141
|
+
*/
|
|
142
|
+
renderTouchable?: (props: TouchableProps<Route>) => React.ReactNode;
|
|
143
|
+
/**
|
|
144
|
+
* Get accessibility label for the tab button. This is read by the screen reader when the user taps the tab.
|
|
145
|
+
* Uses `route.accessibilityLabel` by default.
|
|
146
|
+
*/
|
|
147
|
+
getAccessibilityLabel?: (props: { route: Route }) => string | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* Get badge for the tab, uses `route.badge` by default.
|
|
150
|
+
*/
|
|
151
|
+
getBadge?: (props: { route: Route }) => boolean | number | string | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* Get color for the tab, uses `route.color` by default.
|
|
154
|
+
*/
|
|
155
|
+
getColor?: (props: { route: Route }) => string | undefined;
|
|
156
|
+
/**
|
|
157
|
+
* Get label text for the tab, uses `route.title` by default. Use `renderLabel` to replace label component.
|
|
158
|
+
*/
|
|
159
|
+
getLabelText?: (props: { route: Route }) => string | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Get the id to locate this tab button in tests, uses `route.testID` by default.
|
|
162
|
+
*/
|
|
163
|
+
getTestID?: (props: { route: Route }) => string | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Function to execute on tab press. It receives the route for the pressed tab. Use this to update the navigation state.
|
|
166
|
+
*/
|
|
167
|
+
onTabPress: (props: { route: Route } & TabPressEvent) => void;
|
|
168
|
+
/**
|
|
169
|
+
* Function to execute on tab long press. It receives the route for the pressed tab
|
|
170
|
+
*/
|
|
171
|
+
onTabLongPress?: (props: { route: Route } & TabPressEvent) => void;
|
|
172
|
+
/**
|
|
173
|
+
* Custom color for icon and label in the active tab.
|
|
174
|
+
*/
|
|
175
|
+
activeColor?: string;
|
|
176
|
+
/**
|
|
177
|
+
* Custom color for icon and label in the inactive tab.
|
|
178
|
+
*/
|
|
179
|
+
inactiveColor?: string;
|
|
180
|
+
/**
|
|
181
|
+
* The scene animation Easing.
|
|
182
|
+
*/
|
|
183
|
+
animationEasing?: EasingFunction | undefined;
|
|
184
|
+
/**
|
|
185
|
+
* Whether the bottom navigation bar is hidden when keyboard is shown.
|
|
186
|
+
* On Android, this works best when [`windowSoftInputMode`](https://developer.android.com/guide/topics/manifest/activity-element#wsoft) is set to `adjustResize`.
|
|
187
|
+
*/
|
|
188
|
+
keyboardHidesNavigationBar?: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* 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.
|
|
191
|
+
* The bottom insets for iOS is added by default. You can override the behavior with this option.
|
|
192
|
+
*/
|
|
193
|
+
safeAreaInsets?: {
|
|
194
|
+
top?: number;
|
|
195
|
+
right?: number;
|
|
196
|
+
bottom?: number;
|
|
197
|
+
left?: number;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Specifies the largest possible scale a label font can reach.
|
|
201
|
+
*/
|
|
202
|
+
labelMaxFontSizeMultiplier?: number;
|
|
203
|
+
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
|
|
204
|
+
activeIndicatorStyle?: StyleProp<ViewStyle>;
|
|
205
|
+
/**
|
|
206
|
+
* @optional
|
|
207
|
+
*/
|
|
208
|
+
theme?: ThemeProp;
|
|
209
|
+
/**
|
|
210
|
+
* TestID used for testing purposes
|
|
211
|
+
*/
|
|
212
|
+
testID?: string;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const MIN_RIPPLE_SCALE = 0.001; // Minimum scale is not 0 due to bug with animation
|
|
216
|
+
const MIN_TAB_WIDTH = 96;
|
|
217
|
+
const MAX_TAB_WIDTH = 168;
|
|
218
|
+
const BAR_HEIGHT = 56;
|
|
219
|
+
const OUTLINE_WIDTH = 64;
|
|
220
|
+
|
|
221
|
+
const Touchable = <Route extends BaseRoute>({
|
|
222
|
+
route: _0,
|
|
223
|
+
style,
|
|
224
|
+
children,
|
|
225
|
+
borderless,
|
|
226
|
+
centered,
|
|
227
|
+
rippleColor,
|
|
228
|
+
...rest
|
|
229
|
+
}: TouchableProps<Route>) =>
|
|
230
|
+
TouchableRipple.supported ? (
|
|
231
|
+
<TouchableRipple
|
|
232
|
+
{...rest}
|
|
233
|
+
disabled={rest.disabled || undefined}
|
|
234
|
+
borderless={borderless}
|
|
235
|
+
centered={centered}
|
|
236
|
+
rippleColor={rippleColor}
|
|
237
|
+
style={style}
|
|
238
|
+
>
|
|
239
|
+
{children}
|
|
240
|
+
</TouchableRipple>
|
|
241
|
+
) : (
|
|
242
|
+
<Pressable style={style} {...rest}>
|
|
243
|
+
{children}
|
|
244
|
+
</Pressable>
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/).
|
|
249
|
+
*
|
|
250
|
+
* ## Usage
|
|
251
|
+
* ```js
|
|
252
|
+
* import React from 'react';
|
|
253
|
+
* import { View, StyleSheet } from 'react-native';
|
|
254
|
+
*
|
|
255
|
+
* import { CommonActions } from '@react-navigation/native';
|
|
256
|
+
* import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
257
|
+
* import { Text, BottomNavigation } from 'react-native-paper';
|
|
258
|
+
* import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
259
|
+
*
|
|
260
|
+
* const Tab = createBottomTabNavigator();
|
|
261
|
+
*
|
|
262
|
+
* export default function MyComponent() {
|
|
263
|
+
* return (
|
|
264
|
+
* <Tab.Navigator
|
|
265
|
+
* screenOptions={{
|
|
266
|
+
* headerShown: false,
|
|
267
|
+
* }}
|
|
268
|
+
* tabBar={({ navigation, state, descriptors, insets }) => (
|
|
269
|
+
* <BottomNavigation.Bar
|
|
270
|
+
* navigationState={state}
|
|
271
|
+
* safeAreaInsets={insets}
|
|
272
|
+
* onTabPress={({ route, preventDefault }) => {
|
|
273
|
+
* const event = navigation.emit({
|
|
274
|
+
* type: 'tabPress',
|
|
275
|
+
* target: route.key,
|
|
276
|
+
* canPreventDefault: true,
|
|
277
|
+
* });
|
|
278
|
+
*
|
|
279
|
+
* if (event.defaultPrevented) {
|
|
280
|
+
* preventDefault();
|
|
281
|
+
* } else {
|
|
282
|
+
* navigation.dispatch({
|
|
283
|
+
* ...CommonActions.navigate(route.name, route.params),
|
|
284
|
+
* target: state.key,
|
|
285
|
+
* });
|
|
286
|
+
* }
|
|
287
|
+
* }}
|
|
288
|
+
* renderIcon={({ route, focused, color }) => {
|
|
289
|
+
* const { options } = descriptors[route.key];
|
|
290
|
+
* if (options.tabBarIcon) {
|
|
291
|
+
* return options.tabBarIcon({ focused, color, size: 24 });
|
|
292
|
+
* }
|
|
293
|
+
*
|
|
294
|
+
* return null;
|
|
295
|
+
* }}
|
|
296
|
+
* getLabelText={({ route }) => {
|
|
297
|
+
* const { options } = descriptors[route.key];
|
|
298
|
+
* const label =
|
|
299
|
+
* options.tabBarLabel !== undefined
|
|
300
|
+
* ? options.tabBarLabel
|
|
301
|
+
* : options.title !== undefined
|
|
302
|
+
* ? options.title
|
|
303
|
+
* : route.title;
|
|
304
|
+
*
|
|
305
|
+
* return label;
|
|
306
|
+
* }}
|
|
307
|
+
* />
|
|
308
|
+
* )}
|
|
309
|
+
* >
|
|
310
|
+
* <Tab.Screen
|
|
311
|
+
* name="Home"
|
|
312
|
+
* component={HomeScreen}
|
|
313
|
+
* options={{
|
|
314
|
+
* tabBarLabel: 'Home',
|
|
315
|
+
* tabBarIcon: ({ color, size }) => {
|
|
316
|
+
* return <Icon name="home" size={size} color={color} />;
|
|
317
|
+
* },
|
|
318
|
+
* }}
|
|
319
|
+
* />
|
|
320
|
+
* <Tab.Screen
|
|
321
|
+
* name="Settings"
|
|
322
|
+
* component={SettingsScreen}
|
|
323
|
+
* options={{
|
|
324
|
+
* tabBarLabel: 'Settings',
|
|
325
|
+
* tabBarIcon: ({ color, size }) => {
|
|
326
|
+
* return <Icon name="cog" size={size} color={color} />;
|
|
327
|
+
* },
|
|
328
|
+
* }}
|
|
329
|
+
* />
|
|
330
|
+
* </Tab.Navigator>
|
|
331
|
+
* );
|
|
332
|
+
* }
|
|
333
|
+
*
|
|
334
|
+
* function HomeScreen() {
|
|
335
|
+
* return (
|
|
336
|
+
* <View style={styles.container}>
|
|
337
|
+
* <Text variant="headlineMedium">Home!</Text>
|
|
338
|
+
* </View>
|
|
339
|
+
* );
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* function SettingsScreen() {
|
|
343
|
+
* return (
|
|
344
|
+
* <View style={styles.container}>
|
|
345
|
+
* <Text variant="headlineMedium">Settings!</Text>
|
|
346
|
+
* </View>
|
|
347
|
+
* );
|
|
348
|
+
* }
|
|
349
|
+
*
|
|
350
|
+
* const styles = StyleSheet.create({
|
|
351
|
+
* container: {
|
|
352
|
+
* flex: 1,
|
|
353
|
+
* justifyContent: 'center',
|
|
354
|
+
* alignItems: 'center',
|
|
355
|
+
* },
|
|
356
|
+
* });
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
const BottomNavigationBar = <Route extends BaseRoute>({
|
|
360
|
+
navigationState,
|
|
361
|
+
renderIcon,
|
|
362
|
+
renderLabel,
|
|
363
|
+
renderTouchable = ({ key, ...props }: TouchableProps<Route>) => (
|
|
364
|
+
<Touchable key={key} {...props} />
|
|
365
|
+
),
|
|
366
|
+
getLabelText = ({ route }: { route: Route }) => route.title,
|
|
367
|
+
getBadge = ({ route }: { route: Route }) => route.badge,
|
|
368
|
+
getColor = ({ route }: { route: Route }) => route.color,
|
|
369
|
+
getAccessibilityLabel = ({ route }: { route: Route }) =>
|
|
370
|
+
route.accessibilityLabel,
|
|
371
|
+
getTestID = ({ route }: { route: Route }) => route.testID,
|
|
372
|
+
activeColor,
|
|
373
|
+
inactiveColor,
|
|
374
|
+
keyboardHidesNavigationBar = Platform.OS === 'android',
|
|
375
|
+
style,
|
|
376
|
+
activeIndicatorStyle,
|
|
377
|
+
labeled = true,
|
|
378
|
+
animationEasing,
|
|
379
|
+
onTabPress,
|
|
380
|
+
onTabLongPress,
|
|
381
|
+
shifting: shiftingProp,
|
|
382
|
+
safeAreaInsets,
|
|
383
|
+
labelMaxFontSizeMultiplier = 1,
|
|
384
|
+
compact: compactProp,
|
|
385
|
+
testID = 'bottom-navigation-bar',
|
|
386
|
+
theme: themeOverrides,
|
|
387
|
+
}: Props<Route>) => {
|
|
388
|
+
const theme = useInternalTheme(themeOverrides);
|
|
389
|
+
const { bottom, left, right } = useSafeAreaInsets();
|
|
390
|
+
const { scale } = theme.animation;
|
|
391
|
+
const compact = compactProp ?? !theme.isV3;
|
|
392
|
+
let shifting =
|
|
393
|
+
shiftingProp ?? (theme.isV3 ? false : navigationState.routes.length > 3);
|
|
394
|
+
|
|
395
|
+
if (shifting && navigationState.routes.length < 2) {
|
|
396
|
+
shifting = false;
|
|
397
|
+
console.warn(
|
|
398
|
+
'BottomNavigation.Bar needs at least 2 tabs to run shifting animation'
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Visibility of the navigation bar, visible state is 1 and invisible is 0.
|
|
404
|
+
*/
|
|
405
|
+
const visibleAnim = useAnimatedValue(1);
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Active state of individual tab items, active state is 1 and inactive state is 0.
|
|
409
|
+
*/
|
|
410
|
+
const tabsAnims = useAnimatedValueArray(
|
|
411
|
+
navigationState.routes.map(
|
|
412
|
+
// focused === 1, unfocused === 0
|
|
413
|
+
(_, i) => (i === navigationState.index ? 1 : 0)
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Index of the currently active tab. Used for setting the background color.
|
|
419
|
+
* We don't use the color as an animated value directly, because `setValue` seems to be buggy with colors?.
|
|
420
|
+
*/
|
|
421
|
+
const indexAnim = useAnimatedValue(navigationState.index);
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Animation for the background color ripple, used to determine it's scale and opacity.
|
|
425
|
+
*/
|
|
426
|
+
const rippleAnim = useAnimatedValue(MIN_RIPPLE_SCALE);
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Layout of the navigation bar. The width is used to determine the size and position of the ripple.
|
|
430
|
+
*/
|
|
431
|
+
const [layout, onLayout] = useLayout();
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Track whether the keyboard is visible to show and hide the navigation bar.
|
|
435
|
+
*/
|
|
436
|
+
const [keyboardVisible, setKeyboardVisible] = React.useState(false);
|
|
437
|
+
|
|
438
|
+
const handleKeyboardShow = React.useCallback(() => {
|
|
439
|
+
setKeyboardVisible(true);
|
|
440
|
+
Animated.timing(visibleAnim, {
|
|
441
|
+
toValue: 0,
|
|
442
|
+
duration: 150 * scale,
|
|
443
|
+
useNativeDriver: true,
|
|
444
|
+
}).start();
|
|
445
|
+
}, [scale, visibleAnim]);
|
|
446
|
+
|
|
447
|
+
const handleKeyboardHide = React.useCallback(() => {
|
|
448
|
+
Animated.timing(visibleAnim, {
|
|
449
|
+
toValue: 1,
|
|
450
|
+
duration: 100 * scale,
|
|
451
|
+
useNativeDriver: true,
|
|
452
|
+
}).start(() => {
|
|
453
|
+
setKeyboardVisible(false);
|
|
454
|
+
});
|
|
455
|
+
}, [scale, visibleAnim]);
|
|
456
|
+
|
|
457
|
+
const animateToIndex = React.useCallback(
|
|
458
|
+
(index: number) => {
|
|
459
|
+
// Reset the ripple to avoid glitch if it's currently animating
|
|
460
|
+
rippleAnim.setValue(MIN_RIPPLE_SCALE);
|
|
461
|
+
|
|
462
|
+
Animated.parallel([
|
|
463
|
+
Animated.timing(rippleAnim, {
|
|
464
|
+
toValue: 1,
|
|
465
|
+
duration: theme.isV3 || shifting ? 400 * scale : 0,
|
|
466
|
+
useNativeDriver: true,
|
|
467
|
+
}),
|
|
468
|
+
...navigationState.routes.map((_, i) =>
|
|
469
|
+
Animated.timing(tabsAnims[i], {
|
|
470
|
+
toValue: i === index ? 1 : 0,
|
|
471
|
+
duration: theme.isV3 || shifting ? 150 * scale : 0,
|
|
472
|
+
useNativeDriver: true,
|
|
473
|
+
easing: animationEasing,
|
|
474
|
+
})
|
|
475
|
+
),
|
|
476
|
+
]).start(() => {
|
|
477
|
+
// Workaround a bug in native animations where this is reset after first animation
|
|
478
|
+
tabsAnims.map((tab, i) => tab.setValue(i === index ? 1 : 0));
|
|
479
|
+
|
|
480
|
+
// Update the index to change bar's background color and then hide the ripple
|
|
481
|
+
indexAnim.setValue(index);
|
|
482
|
+
rippleAnim.setValue(MIN_RIPPLE_SCALE);
|
|
483
|
+
});
|
|
484
|
+
},
|
|
485
|
+
[
|
|
486
|
+
rippleAnim,
|
|
487
|
+
theme.isV3,
|
|
488
|
+
shifting,
|
|
489
|
+
scale,
|
|
490
|
+
navigationState.routes,
|
|
491
|
+
tabsAnims,
|
|
492
|
+
animationEasing,
|
|
493
|
+
indexAnim,
|
|
494
|
+
]
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
React.useEffect(() => {
|
|
498
|
+
// Workaround for native animated bug in react-native@^0.57
|
|
499
|
+
// Context: https://github.com/callstack/react-native-paper/pull/637
|
|
500
|
+
animateToIndex(navigationState.index);
|
|
501
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
502
|
+
}, []);
|
|
503
|
+
|
|
504
|
+
useIsKeyboardShown({
|
|
505
|
+
onShow: handleKeyboardShow,
|
|
506
|
+
onHide: handleKeyboardHide,
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
React.useEffect(() => {
|
|
510
|
+
animateToIndex(navigationState.index);
|
|
511
|
+
}, [navigationState.index, animateToIndex]);
|
|
512
|
+
|
|
513
|
+
const eventForIndex = (index: number) => {
|
|
514
|
+
const event = {
|
|
515
|
+
route: navigationState.routes[index],
|
|
516
|
+
defaultPrevented: false,
|
|
517
|
+
preventDefault: () => {
|
|
518
|
+
event.defaultPrevented = true;
|
|
519
|
+
},
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
return event;
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
const { routes } = navigationState;
|
|
526
|
+
const { colors, dark: isDarkTheme, mode, isV3 } = theme;
|
|
527
|
+
|
|
528
|
+
const { backgroundColor: customBackground, elevation = 4 } =
|
|
529
|
+
(StyleSheet.flatten(style) || {}) as {
|
|
530
|
+
elevation?: number;
|
|
531
|
+
backgroundColor?: ColorValue;
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
const approxBackgroundColor = customBackground
|
|
535
|
+
? customBackground
|
|
536
|
+
: isDarkTheme && mode === 'adaptive'
|
|
537
|
+
? overlay(elevation, colors?.surface)
|
|
538
|
+
: colors?.primary;
|
|
539
|
+
|
|
540
|
+
const v2BackgroundColorInterpolation = shifting
|
|
541
|
+
? indexAnim.interpolate({
|
|
542
|
+
inputRange: routes.map((_, i) => i),
|
|
543
|
+
// FIXME: does outputRange support ColorValue or just strings?
|
|
544
|
+
// @ts-expect-error
|
|
545
|
+
outputRange: routes.map(
|
|
546
|
+
(route) => getColor({ route }) || approxBackgroundColor
|
|
547
|
+
),
|
|
548
|
+
})
|
|
549
|
+
: approxBackgroundColor;
|
|
550
|
+
|
|
551
|
+
const backgroundColor = isV3
|
|
552
|
+
? customBackground || theme.colors.elevation.level2
|
|
553
|
+
: shifting
|
|
554
|
+
? v2BackgroundColorInterpolation
|
|
555
|
+
: approxBackgroundColor;
|
|
556
|
+
|
|
557
|
+
const isDark =
|
|
558
|
+
typeof approxBackgroundColor === 'string'
|
|
559
|
+
? !color(approxBackgroundColor).isLight()
|
|
560
|
+
: true;
|
|
561
|
+
|
|
562
|
+
const textColor = isDark ? white : black;
|
|
563
|
+
|
|
564
|
+
const activeTintColor = getActiveTintColor({
|
|
565
|
+
activeColor,
|
|
566
|
+
defaultColor: textColor,
|
|
567
|
+
theme,
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
const inactiveTintColor = getInactiveTintColor({
|
|
571
|
+
inactiveColor,
|
|
572
|
+
defaultColor: textColor,
|
|
573
|
+
theme,
|
|
574
|
+
});
|
|
575
|
+
const touchColor = color(activeTintColor).alpha(0.12).rgb().string();
|
|
576
|
+
|
|
577
|
+
const maxTabWidth = routes.length > 3 ? MIN_TAB_WIDTH : MAX_TAB_WIDTH;
|
|
578
|
+
const maxTabBarWidth = maxTabWidth * routes.length;
|
|
579
|
+
|
|
580
|
+
const rippleSize = layout.width / 4;
|
|
581
|
+
|
|
582
|
+
const insets = {
|
|
583
|
+
left: safeAreaInsets?.left ?? left,
|
|
584
|
+
right: safeAreaInsets?.right ?? right,
|
|
585
|
+
bottom: safeAreaInsets?.bottom ?? bottom,
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
return (
|
|
589
|
+
<Surface
|
|
590
|
+
{...(theme.isV3 && { elevation: 0 })}
|
|
591
|
+
testID={testID}
|
|
592
|
+
style={[
|
|
593
|
+
!theme.isV3 && styles.elevation,
|
|
594
|
+
styles.bar,
|
|
595
|
+
keyboardHidesNavigationBar // eslint-disable-next-line react-native/no-inline-styles
|
|
596
|
+
? {
|
|
597
|
+
// When the keyboard is shown, slide down the navigation bar
|
|
598
|
+
transform: [
|
|
599
|
+
{
|
|
600
|
+
translateY: visibleAnim.interpolate({
|
|
601
|
+
inputRange: [0, 1],
|
|
602
|
+
outputRange: [layout.height, 0],
|
|
603
|
+
}),
|
|
604
|
+
},
|
|
605
|
+
],
|
|
606
|
+
// Absolutely position the navigation bar so that the content is below it
|
|
607
|
+
// This is needed to avoid gap at bottom when the navigation bar is hidden
|
|
608
|
+
position: keyboardVisible ? 'absolute' : undefined,
|
|
609
|
+
}
|
|
610
|
+
: null,
|
|
611
|
+
style,
|
|
612
|
+
]}
|
|
613
|
+
pointerEvents={
|
|
614
|
+
layout.measured
|
|
615
|
+
? keyboardHidesNavigationBar && keyboardVisible
|
|
616
|
+
? 'none'
|
|
617
|
+
: 'auto'
|
|
618
|
+
: 'none'
|
|
619
|
+
}
|
|
620
|
+
onLayout={onLayout}
|
|
621
|
+
>
|
|
622
|
+
<Animated.View
|
|
623
|
+
style={[styles.barContent, { backgroundColor }]}
|
|
624
|
+
testID={`${testID}-content`}
|
|
625
|
+
>
|
|
626
|
+
<View
|
|
627
|
+
style={[
|
|
628
|
+
styles.items,
|
|
629
|
+
{
|
|
630
|
+
marginBottom: insets.bottom,
|
|
631
|
+
marginHorizontal: Math.max(insets.left, insets.right),
|
|
632
|
+
},
|
|
633
|
+
compact && {
|
|
634
|
+
maxWidth: maxTabBarWidth,
|
|
635
|
+
},
|
|
636
|
+
]}
|
|
637
|
+
accessibilityRole={'tablist'}
|
|
638
|
+
testID={`${testID}-content-wrapper`}
|
|
639
|
+
>
|
|
640
|
+
{shifting && !isV3 ? (
|
|
641
|
+
<Animated.View
|
|
642
|
+
pointerEvents="none"
|
|
643
|
+
style={[
|
|
644
|
+
styles.ripple,
|
|
645
|
+
{
|
|
646
|
+
// Since we have a single ripple, we have to reposition it so that it appears to expand from active tab.
|
|
647
|
+
// We need to move it from the top to center of the navigation bar and from the left to the active tab.
|
|
648
|
+
top: (BAR_HEIGHT - rippleSize) / 2,
|
|
649
|
+
left:
|
|
650
|
+
(Math.min(layout.width, maxTabBarWidth) / routes.length) *
|
|
651
|
+
(navigationState.index + 0.5) -
|
|
652
|
+
rippleSize / 2,
|
|
653
|
+
height: rippleSize,
|
|
654
|
+
width: rippleSize,
|
|
655
|
+
borderRadius: rippleSize / 2,
|
|
656
|
+
backgroundColor: getColor({
|
|
657
|
+
route: routes[navigationState.index],
|
|
658
|
+
}),
|
|
659
|
+
transform: [
|
|
660
|
+
{
|
|
661
|
+
// Scale to twice the size to ensure it covers the whole navigation bar
|
|
662
|
+
scale: rippleAnim.interpolate({
|
|
663
|
+
inputRange: [0, 1],
|
|
664
|
+
outputRange: [0, 8],
|
|
665
|
+
}),
|
|
666
|
+
},
|
|
667
|
+
],
|
|
668
|
+
opacity: rippleAnim.interpolate({
|
|
669
|
+
inputRange: [0, MIN_RIPPLE_SCALE, 0.3, 1],
|
|
670
|
+
outputRange: [0, 0, 1, 1],
|
|
671
|
+
}),
|
|
672
|
+
},
|
|
673
|
+
]}
|
|
674
|
+
testID={`${testID}-content-ripple`}
|
|
675
|
+
/>
|
|
676
|
+
) : null}
|
|
677
|
+
{routes.map((route, index) => {
|
|
678
|
+
const focused = navigationState.index === index;
|
|
679
|
+
const active = tabsAnims[index];
|
|
680
|
+
|
|
681
|
+
// Scale the label up
|
|
682
|
+
const scale =
|
|
683
|
+
labeled && shifting
|
|
684
|
+
? active.interpolate({
|
|
685
|
+
inputRange: [0, 1],
|
|
686
|
+
outputRange: [0.5, 1],
|
|
687
|
+
})
|
|
688
|
+
: 1;
|
|
689
|
+
|
|
690
|
+
// Move down the icon to account for no-label in shifting and smaller label in non-shifting.
|
|
691
|
+
const translateY = labeled
|
|
692
|
+
? shifting
|
|
693
|
+
? active.interpolate({
|
|
694
|
+
inputRange: [0, 1],
|
|
695
|
+
outputRange: [7, 0],
|
|
696
|
+
})
|
|
697
|
+
: 0
|
|
698
|
+
: 7;
|
|
699
|
+
|
|
700
|
+
// We render the active icon and label on top of inactive ones and cross-fade them on change.
|
|
701
|
+
// This trick gives the illusion that we are animating between active and inactive colors.
|
|
702
|
+
// This is to ensure that we can use native driver, as colors cannot be animated with native driver.
|
|
703
|
+
const activeOpacity = active;
|
|
704
|
+
const inactiveOpacity = active.interpolate({
|
|
705
|
+
inputRange: [0, 1],
|
|
706
|
+
outputRange: [1, 0],
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
const v3ActiveOpacity = focused ? 1 : 0;
|
|
710
|
+
const v3InactiveOpacity = shifting
|
|
711
|
+
? inactiveOpacity
|
|
712
|
+
: focused
|
|
713
|
+
? 0
|
|
714
|
+
: 1;
|
|
715
|
+
|
|
716
|
+
// Scale horizontally the outline pill
|
|
717
|
+
const outlineScale = focused
|
|
718
|
+
? active.interpolate({
|
|
719
|
+
inputRange: [0, 1],
|
|
720
|
+
outputRange: [0.5, 1],
|
|
721
|
+
})
|
|
722
|
+
: 0;
|
|
723
|
+
|
|
724
|
+
const badge = getBadge({ route });
|
|
725
|
+
|
|
726
|
+
const activeLabelColor = getLabelColor({
|
|
727
|
+
tintColor: activeTintColor,
|
|
728
|
+
hasColor: Boolean(activeColor),
|
|
729
|
+
focused,
|
|
730
|
+
defaultColor: textColor,
|
|
731
|
+
theme,
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
const inactiveLabelColor = getLabelColor({
|
|
735
|
+
tintColor: inactiveTintColor,
|
|
736
|
+
hasColor: Boolean(inactiveColor),
|
|
737
|
+
focused,
|
|
738
|
+
defaultColor: textColor,
|
|
739
|
+
theme,
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
const badgeStyle = {
|
|
743
|
+
top: !isV3 ? -2 : typeof badge === 'boolean' ? 4 : 2,
|
|
744
|
+
right:
|
|
745
|
+
(badge != null && typeof badge !== 'boolean'
|
|
746
|
+
? String(badge).length * -2
|
|
747
|
+
: 0) - (!isV3 ? 2 : 0),
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
const isV3Shifting = isV3 && shifting && labeled;
|
|
751
|
+
|
|
752
|
+
const font = isV3 ? theme.fonts.labelMedium : {};
|
|
753
|
+
|
|
754
|
+
return renderTouchable({
|
|
755
|
+
key: route.key,
|
|
756
|
+
route,
|
|
757
|
+
borderless: true,
|
|
758
|
+
centered: true,
|
|
759
|
+
rippleColor: isV3 ? 'transparent' : touchColor,
|
|
760
|
+
onPress: () => onTabPress(eventForIndex(index)),
|
|
761
|
+
onLongPress: () => onTabLongPress?.(eventForIndex(index)),
|
|
762
|
+
testID: getTestID({ route }),
|
|
763
|
+
accessibilityLabel: getAccessibilityLabel({ route }),
|
|
764
|
+
accessibilityRole: Platform.OS === 'ios' ? 'button' : 'tab',
|
|
765
|
+
accessibilityState: { selected: focused },
|
|
766
|
+
style: [styles.item, isV3 && styles.v3Item],
|
|
767
|
+
children: (
|
|
768
|
+
<View
|
|
769
|
+
pointerEvents="none"
|
|
770
|
+
style={
|
|
771
|
+
isV3 &&
|
|
772
|
+
(labeled
|
|
773
|
+
? styles.v3TouchableContainer
|
|
774
|
+
: styles.v3NoLabelContainer)
|
|
775
|
+
}
|
|
776
|
+
>
|
|
777
|
+
<Animated.View
|
|
778
|
+
style={[
|
|
779
|
+
styles.iconContainer,
|
|
780
|
+
isV3 && styles.v3IconContainer,
|
|
781
|
+
(!isV3 || isV3Shifting) && {
|
|
782
|
+
transform: [{ translateY }],
|
|
783
|
+
},
|
|
784
|
+
]}
|
|
785
|
+
>
|
|
786
|
+
{isV3 && focused && (
|
|
787
|
+
<Animated.View
|
|
788
|
+
style={[
|
|
789
|
+
styles.outline,
|
|
790
|
+
{
|
|
791
|
+
transform: [
|
|
792
|
+
{
|
|
793
|
+
scaleX: outlineScale,
|
|
794
|
+
},
|
|
795
|
+
],
|
|
796
|
+
backgroundColor: theme.colors.secondaryContainer,
|
|
797
|
+
},
|
|
798
|
+
activeIndicatorStyle,
|
|
799
|
+
]}
|
|
800
|
+
/>
|
|
801
|
+
)}
|
|
802
|
+
<Animated.View
|
|
803
|
+
style={[
|
|
804
|
+
styles.iconWrapper,
|
|
805
|
+
isV3 && styles.v3IconWrapper,
|
|
806
|
+
{ opacity: isV3 ? v3ActiveOpacity : activeOpacity },
|
|
807
|
+
]}
|
|
808
|
+
>
|
|
809
|
+
{renderIcon ? (
|
|
810
|
+
renderIcon({
|
|
811
|
+
route,
|
|
812
|
+
focused: true,
|
|
813
|
+
color: activeTintColor,
|
|
814
|
+
})
|
|
815
|
+
) : (
|
|
816
|
+
<Icon
|
|
817
|
+
source={route.focusedIcon as IconSource}
|
|
818
|
+
color={activeTintColor}
|
|
819
|
+
size={24}
|
|
820
|
+
/>
|
|
821
|
+
)}
|
|
822
|
+
</Animated.View>
|
|
823
|
+
<Animated.View
|
|
824
|
+
style={[
|
|
825
|
+
styles.iconWrapper,
|
|
826
|
+
isV3 && styles.v3IconWrapper,
|
|
827
|
+
{
|
|
828
|
+
opacity: isV3 ? v3InactiveOpacity : inactiveOpacity,
|
|
829
|
+
},
|
|
830
|
+
]}
|
|
831
|
+
>
|
|
832
|
+
{renderIcon ? (
|
|
833
|
+
renderIcon({
|
|
834
|
+
route,
|
|
835
|
+
focused: false,
|
|
836
|
+
color: inactiveTintColor,
|
|
837
|
+
})
|
|
838
|
+
) : (
|
|
839
|
+
<Icon
|
|
840
|
+
source={
|
|
841
|
+
theme.isV3 && route.unfocusedIcon !== undefined
|
|
842
|
+
? route.unfocusedIcon
|
|
843
|
+
: (route.focusedIcon as IconSource)
|
|
844
|
+
}
|
|
845
|
+
color={inactiveTintColor}
|
|
846
|
+
size={24}
|
|
847
|
+
/>
|
|
848
|
+
)}
|
|
849
|
+
</Animated.View>
|
|
850
|
+
<View style={[styles.badgeContainer, badgeStyle]}>
|
|
851
|
+
{typeof badge === 'boolean' ? (
|
|
852
|
+
<Badge visible={badge} size={isV3 ? 6 : 8} />
|
|
853
|
+
) : (
|
|
854
|
+
<Badge visible={badge != null} size={16}>
|
|
855
|
+
{badge}
|
|
856
|
+
</Badge>
|
|
857
|
+
)}
|
|
858
|
+
</View>
|
|
859
|
+
</Animated.View>
|
|
860
|
+
{labeled ? (
|
|
861
|
+
<Animated.View
|
|
862
|
+
style={[
|
|
863
|
+
styles.labelContainer,
|
|
864
|
+
!isV3 && { transform: [{ scale }] },
|
|
865
|
+
]}
|
|
866
|
+
>
|
|
867
|
+
<Animated.View
|
|
868
|
+
style={[
|
|
869
|
+
styles.labelWrapper,
|
|
870
|
+
(!isV3 || isV3Shifting) && {
|
|
871
|
+
opacity: activeOpacity,
|
|
872
|
+
},
|
|
873
|
+
]}
|
|
874
|
+
>
|
|
875
|
+
{renderLabel ? (
|
|
876
|
+
renderLabel({
|
|
877
|
+
route,
|
|
878
|
+
focused: true,
|
|
879
|
+
color: activeLabelColor,
|
|
880
|
+
})
|
|
881
|
+
) : (
|
|
882
|
+
<Text
|
|
883
|
+
maxFontSizeMultiplier={labelMaxFontSizeMultiplier}
|
|
884
|
+
variant="labelMedium"
|
|
885
|
+
style={[
|
|
886
|
+
styles.label,
|
|
887
|
+
{
|
|
888
|
+
color: activeLabelColor,
|
|
889
|
+
...font,
|
|
890
|
+
},
|
|
891
|
+
]}
|
|
892
|
+
>
|
|
893
|
+
{getLabelText({ route })}
|
|
894
|
+
</Text>
|
|
895
|
+
)}
|
|
896
|
+
</Animated.View>
|
|
897
|
+
{shifting ? null : (
|
|
898
|
+
<Animated.View
|
|
899
|
+
style={[
|
|
900
|
+
styles.labelWrapper,
|
|
901
|
+
{ opacity: inactiveOpacity },
|
|
902
|
+
]}
|
|
903
|
+
>
|
|
904
|
+
{renderLabel ? (
|
|
905
|
+
renderLabel({
|
|
906
|
+
route,
|
|
907
|
+
focused: false,
|
|
908
|
+
color: inactiveLabelColor,
|
|
909
|
+
})
|
|
910
|
+
) : (
|
|
911
|
+
<Text
|
|
912
|
+
maxFontSizeMultiplier={labelMaxFontSizeMultiplier}
|
|
913
|
+
variant="labelMedium"
|
|
914
|
+
selectable={false}
|
|
915
|
+
style={[
|
|
916
|
+
styles.label,
|
|
917
|
+
{
|
|
918
|
+
color: inactiveLabelColor,
|
|
919
|
+
...font,
|
|
920
|
+
},
|
|
921
|
+
]}
|
|
922
|
+
>
|
|
923
|
+
{getLabelText({ route })}
|
|
924
|
+
</Text>
|
|
925
|
+
)}
|
|
926
|
+
</Animated.View>
|
|
927
|
+
)}
|
|
928
|
+
</Animated.View>
|
|
929
|
+
) : (
|
|
930
|
+
!isV3 && <View style={styles.labelContainer} />
|
|
931
|
+
)}
|
|
932
|
+
</View>
|
|
933
|
+
),
|
|
934
|
+
});
|
|
935
|
+
})}
|
|
936
|
+
</View>
|
|
937
|
+
</Animated.View>
|
|
938
|
+
</Surface>
|
|
939
|
+
);
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
BottomNavigationBar.displayName = 'BottomNavigation.Bar';
|
|
943
|
+
|
|
944
|
+
export default BottomNavigationBar;
|
|
945
|
+
|
|
946
|
+
const styles = StyleSheet.create({
|
|
947
|
+
bar: {
|
|
948
|
+
left: 0,
|
|
949
|
+
right: 0,
|
|
950
|
+
bottom: 0,
|
|
951
|
+
},
|
|
952
|
+
barContent: {
|
|
953
|
+
alignItems: 'center',
|
|
954
|
+
overflow: 'hidden',
|
|
955
|
+
},
|
|
956
|
+
items: {
|
|
957
|
+
flexDirection: 'row',
|
|
958
|
+
...(Platform.OS === 'web'
|
|
959
|
+
? {
|
|
960
|
+
width: '100%',
|
|
961
|
+
}
|
|
962
|
+
: null),
|
|
963
|
+
},
|
|
964
|
+
item: {
|
|
965
|
+
flex: 1,
|
|
966
|
+
// Top padding is 6 and bottom padding is 10
|
|
967
|
+
// The extra 4dp bottom padding is offset by label's height
|
|
968
|
+
paddingVertical: 6,
|
|
969
|
+
},
|
|
970
|
+
v3Item: {
|
|
971
|
+
paddingVertical: 0,
|
|
972
|
+
},
|
|
973
|
+
ripple: {
|
|
974
|
+
position: 'absolute',
|
|
975
|
+
},
|
|
976
|
+
iconContainer: {
|
|
977
|
+
height: 24,
|
|
978
|
+
width: 24,
|
|
979
|
+
marginTop: 2,
|
|
980
|
+
marginHorizontal: 12,
|
|
981
|
+
alignSelf: 'center',
|
|
982
|
+
},
|
|
983
|
+
v3IconContainer: {
|
|
984
|
+
height: 32,
|
|
985
|
+
width: 32,
|
|
986
|
+
marginBottom: 4,
|
|
987
|
+
marginTop: 0,
|
|
988
|
+
justifyContent: 'center',
|
|
989
|
+
},
|
|
990
|
+
iconWrapper: {
|
|
991
|
+
...StyleSheet.absoluteFillObject,
|
|
992
|
+
alignItems: 'center',
|
|
993
|
+
},
|
|
994
|
+
v3IconWrapper: {
|
|
995
|
+
top: 4,
|
|
996
|
+
},
|
|
997
|
+
labelContainer: {
|
|
998
|
+
height: 16,
|
|
999
|
+
paddingBottom: 2,
|
|
1000
|
+
},
|
|
1001
|
+
labelWrapper: {
|
|
1002
|
+
...StyleSheet.absoluteFillObject,
|
|
1003
|
+
},
|
|
1004
|
+
// eslint-disable-next-line react-native/no-color-literals
|
|
1005
|
+
label: {
|
|
1006
|
+
fontSize: 12,
|
|
1007
|
+
height: BAR_HEIGHT,
|
|
1008
|
+
textAlign: 'center',
|
|
1009
|
+
backgroundColor: 'transparent',
|
|
1010
|
+
...(Platform.OS === 'web'
|
|
1011
|
+
? {
|
|
1012
|
+
whiteSpace: 'nowrap',
|
|
1013
|
+
alignSelf: 'center',
|
|
1014
|
+
}
|
|
1015
|
+
: null),
|
|
1016
|
+
},
|
|
1017
|
+
badgeContainer: {
|
|
1018
|
+
position: 'absolute',
|
|
1019
|
+
left: 0,
|
|
1020
|
+
},
|
|
1021
|
+
v3TouchableContainer: {
|
|
1022
|
+
paddingTop: 12,
|
|
1023
|
+
paddingBottom: 16,
|
|
1024
|
+
},
|
|
1025
|
+
v3NoLabelContainer: {
|
|
1026
|
+
height: 80,
|
|
1027
|
+
justifyContent: 'center',
|
|
1028
|
+
alignItems: 'center',
|
|
1029
|
+
},
|
|
1030
|
+
outline: {
|
|
1031
|
+
width: OUTLINE_WIDTH,
|
|
1032
|
+
height: OUTLINE_WIDTH / 2,
|
|
1033
|
+
borderRadius: OUTLINE_WIDTH / 4,
|
|
1034
|
+
alignSelf: 'center',
|
|
1035
|
+
},
|
|
1036
|
+
elevation: {
|
|
1037
|
+
elevation: 4,
|
|
1038
|
+
},
|
|
1039
|
+
});
|