Tips for integrating Appbar and BottomNavigation in React Native Paper

The BottomNavigation is a great choice for mobile navigation, but for the web version, I have a different preference inspired by Instagram:

https://i.sstatic.net/9XTlb.png

Navbar.tsx:

import React from 'react'
import {Appbar, BottomNavigation} from 'react-native-paper'

type NavbarProps = React.ComponentProps<typeof Appbar> &
  React.ComponentProps<typeof BottomNavigation>

export const Navbar: React.FC<NavbarProps> = (props: NavbarProps) => {
  return (
    <Appbar {...props}>
      {props.children}
      <BottomNavigation {...props} />
    </Appbar>
  )
}

Example of usage:

const App = () => {
  const colorScheme = Appearance.getColorScheme()
  const isDarkTheme = colorScheme === 'dark'
  const theme = isDarkTheme ? CombinedDarkTheme : CombinedDefaultTheme

  const [searchQuery, setSearchQuery] = React.useState('')
  const onChangeSearch = (query: React.SetStateAction<string>) => {
    setSearchQuery(query)
  }

  const [index, setIndex] = React.useState(0)
  const [routes] = React.useState([
    {key: 'home', icon: 'home'},
    {key: 'map', icon: 'compass'},
    {key: 'post', icon: 'plus-box'},
    {key: 'chat', icon: 'forum'},
    {key: 'profile', icon: 'account'},
  ])

  const renderScene = BottomNavigation.SceneMap({
    home: HomeScreen,
    map: MapScreen,
    post: PostScreen,
    chat: ChatScreen,
    profile: ProfileScreen,
  })

  return (
    <PaperProvider theme={theme}>
      <React.Fragment>
        <style type="text/css">{`
          @font-face {
            font-family: 'MaterialCommunityIcons';
            src: url('fonts/MaterialCommunityIcons.ttf') format('truetype');
          }
        `}</style>
        <Navbar
          style={styles.navbar}
          labeled={false}
          navigationState={{index, routes}}
          onIndexChange={setIndex}
          renderScene={renderScene}
          activeColor="#f50057">
          <Navbar.Content title="My cool navbar" />
          <Navbar.Search
            theme={theme}
            placeholder="Search..."
            value={searchQuery}
            onChangeText={onChangeSearch}
          />
        </Navbar>
      </React.Fragment>
    </PaperProvider>
  )
}

This implementation provides the desired navigation bar, but there is an issue with rendering scenes. The scenes are drawn inside the Appbar with zero height, which is expected.

https://i.sstatic.net/EfsOq.jpg

When examining the source code of BottomNavigation, it renders BottomNavigationRouteScreen with icons below the bar.

How can I enhance BottomNavigation to include a title and search input at the start of the navigation bar and then render BottomNavigationRouteScreen below the bar?

P.S. Omitted code related to Navbar.Content and Navbar.Search as they are not relevant to the issue.
P.P.S. I am relatively new to React.js and React Native.

Answer №1

After many tries to integrate Navbar into my application, I have come to realize that there is a simpler approach. I decided to modify the React Native Paper repository directly to include the Navbar feature: here.
This customized Navbar is derived from the BottomNavigation source code. Although it may not be ideal, it serves its purpose well for my application. I believe there are more efficient ways to enhance the default Appbar, incorporate a new Toolbar, and introduce a TabBar similar to Android native components. This would greatly increase the flexibility of the Appbar for customization.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Turning a JSON string into interpolation within an Angular application

I received a JSON response that looks like this: { someText: "Order in {000} 12pm PST for early shipping"; cutofftime : "10000000" } What is the most effective way to replace the '{000}' with the dynamic value stored in &quo ...

Guide on obtaining the total value from a JSON Array in Angular 2 using TypeScript

I received a JSON response which includes carts values with different amounts. "carts": { "value": [ { "Amt": 40 }, { "Amt": 20.25 }, ...

Issue with ReactTS Route Triggering Invalid Hook Call

My implementation of the PrivateRoute component is as follows: interface Props { path: string, exact: boolean, component: React.FC<any>; } const PrivateRoute: React.FC<Props> = ({ component, path, exact }) => { return ( ...

Angular 2+: A guide to retrieving error messages from Firebase

For my project, I've implemented Firebase as a simple backend solution. However, I've encountered an issue where Firebase expires my token after a short period of time. My goal is to detect this specific error and prompt the user to log in again. ...

Adapting imports in Typescript for seamless npm distribution

Currently, I'm facing an issue with module resolution while compiling my NPM package written in Typescript for publishing. In my project, I've been using non-relative imports to avoid the hassle of excessive ../../../. However, according to TypeS ...

Leveraging Global Variables in TypeScript with Node Express

Having issues using global variables in node express when working with typescript. Specifically, trying to use the same global array variable tokenList:tokList across multiple modules and middleware, but haven't been successful so far. Any suggestions ...

Guide on building an npm package that seamlessly allows for installation both locally and globally (-g) using webpack and typescript

As I work on developing an npm package with options for both local and global (-g) installations, I find myself puzzled by the distinctions between the src and lib directories and the purpose of the bin directory. In my previous projects, I typically util ...

Is there a way for me to maintain a consistent layout across all pages while also changing the content component based on the URL route in Next.js?

I'm currently working with Typescript and Next.js My goal is to implement a unified <Layout> for all pages on my website. The layout comprises components such as <Header>, <Footer>, <Sidenav>, and <Content>. Here is the ...

The issue lies with the Cookies.get function, as the Typescript narrowing feature does not

Struggling with types in TypeScript while trying to parse a cookie item using js-cookie: // the item 'number' contains a javascript number (ex:5) let n:number if(typeof Cookies.get('number')!== 'undefined'){ n = JSON.pars ...

Ionic 3 Local Notification spamming a particular page with excessive pushes

Recently starting out with Ionic, I encountered an issue while developing a basic app that should display a specific page by opening a Local Notification. The problem arises when I create multiple notifications – after clicking on the second notification ...

Exploring ways to interact with an API using arrays through interfaces in Angular CLI

I am currently utilizing Angular 7 and I have a REST API that provides the following data: {"Plate":"MIN123","Certifications":[{"File":"KIO","Date":"12-02-2018","Number":1},{"File":"KIO","Date":"12-02-2018","Number":1},{"File":"preventive","StartDate":"06 ...

Strategies for managing memory warnings in React Native iOS

Context: I am developing a native iOS map feature in Swift for integration into my React Native application. The map dynamically loads tiles as the user interacts with it, leading to a gradual increase in memory usage. Issue: At times, the memory usage sp ...

increase the selected date in an Angular datepicker by 10 days

I have a datepicker value in the following format: `Fri Mar 01 2021 00:00:00 GMT+0530 (India Standard Time)` My goal is to add 60 days to this date. After performing the addition, the updated value appears as: `Fri Apr 29 2021 00:00:00 GMT+0530 (India St ...

Is it possible for NodeJS to prioritize IPv6 DNS lookups as the default option?

In my work with multiple TypeScript (NodeJS 14) client applications that are all Dockerized, I primarily use axios for most HTTP requests. However, there are other tools used as well. Typically, DNS queries default to resolving IPv4 addresses, resulting i ...

The softAssert method is not available when trying to implement soft assertions within a TypeScript-based Protractor framework

Uncaught TypeError: assertion.softAssert is not a function I recently included a package called soft-assert using npm in my project. To install this package, I executed the following command: npm i soft-assert -g --save-dev Incorporated the following co ...

The specified dependency, * core-js/fn/symbol, could not be located

I am in the process of developing a Vue.js application with Vuex and have encountered some errors during the build. I attempted to resolve the issue by installing npm install --save core-js/fn/symbol, but unfortunately, it did not work as expected. https:/ ...

What is the proper method for typing unidentified exports that are to be used in TypeScript through named imports?

Currently, I am developing an NPM package that takes the process.env, transforms it, and then exports the transformed environment for easier usage. The module is structured like this: const transformedEnv = transform(process.env) module.exports = transf ...

How does using ngFor and ngModel in Angular cause a change in one select to affect others?

I am looking to implement a feature where users can create multiple select dropdowns, choose options for each one, and then aggregate these selections into an array that will be sent to a parent component. My current approach involves using an *ngFor loop ...

Storing the state of DevExtreme DataGrid in Angular

Currently, I have integrated the DevExtreme DataGrid widget into my Angular application. Here is a snippet of how my DataGrid is configured: <dx-data-grid id="gridContainer" [dataSource]="employees" [allowColumnReordering]="true" [allo ...

Converting TypeScript query string values into GUIDs

I'm currently working on a project that requires me to retrieve a string value (GUID) and convert it into a GUID. The query string format is already in GUID, but when getting the value from the query string using AngularJS and TypeScript, it returns ...