0

The BottomNavigation is a great navigator for mobile devices but for web version I would prefer to have a something as below (inspired by Instagram):

Screenshot

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 code gives me the bar that I need but it doesn't render a scene. To be more precise, it draws the scene, but inside the Appbar and with zero height, which is logical.

Screenshot 2

If to look at source code of BottomNavigation, it renders BottomNavigationRouteScreen and below its bar with icons.

How can I extend BottomNavigation to add the title and search (just some nested views) at the beginning of the bar from BottomNavigation and render BottomNavigationRouteScreen below the bar?

P.S. I didn't post a code related to Navbar.Content and Navbar.Search because of it doesn't play any role in my problem.
P.P.S. I am a noobie in React.js and React Native.

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123

1 Answers1

0

After several attempts to implement Navbar in my app, I've realised there is much easier way. I forked React Native Paper repository and implemented Navbar in their library directly: here.
This Navbar is based on BottomNavigation source code and I can't call this solution perfect but it works for my app. There is a smarter way to redesign a built-in Appbar, introduce new Toolbar and TabBar as it was made in Android native components. It would make Appbar much more flexible for setting.

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123