DEV Community

Cover image for Creating a Custom Navbar with Mantine in ReactJS #2
Sam Preston
Sam Preston

Posted on • Edited on

10 2

Creating a Custom Navbar with Mantine in ReactJS #2

Intro

Welcome back (previous) to the series where I show you how to build an web application with Mantine, ReactJS with TypeScript.

Mantine is:

"A fully featured React components library"

Part 1 - Simple Theming

Mantine ships with a very useful MantineProvider this allows us to apply themes and styles globally. This is as simple as inserting it and enclosing the App component in index.tsx with it:

ReactDOM.render(
  <React.StrictMode>
    <MantineProvider>
      <App />
    </MantineProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

We'll use the default dark mode for now so we can create the application without going blind. To do this we need to use the theme prop.

ReactDOM.render(
  <React.StrictMode>
    <MantineProvider
      theme={{
        colorScheme: 'dark'
      }}
    >
      <App />
    </MantineProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

This changes the application to look like so:
Dark Mode Init

Part 2 - Navigation

With great foresight, Mantine ships with a Section component as a child of the Navbar component so this is simply used as <Navbar.Section />.

function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <Navbar.Section>Assets/Hosts</Navbar.Section>
          <Navbar.Section>Software</Navbar.Section>
          <Navbar.Section>Configurations</Navbar.Section>
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
Enter fullscreen mode Exit fullscreen mode

Ugly Navbar

This creates a very ugly un-styled look to the Navbar, lets fix that by using a Button component.

function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <Navbar.Section>
            <Button>
              Assets/Hosts
            </Button>
          </Navbar.Section>

          <Navbar.Section>
            <Button>
              Software
            </Button>
          </Navbar.Section>

          <Navbar.Section>
            <Button>
              Configurations
            </Button>
          </Navbar.Section>
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
Enter fullscreen mode Exit fullscreen mode

Unstyled Buttons Navbar

Better, however, it could be better if we styled them. To do so we can use the variant and fullWidth prop. We're going to use the subtle variant as I personally prefer it.

function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <Navbar.Section>
            <Button variant='subtle' fullWidth>
              Assets/Hosts
            </Button>
          </Navbar.Section>

          <Navbar.Section>
            <Button variant='subtle' fullWidth>
              Software
            </Button>
          </Navbar.Section>

          <Navbar.Section>
            <Button variant='subtle' fullWidth>
              Configurations
            </Button>
          </Navbar.Section>
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
Enter fullscreen mode Exit fullscreen mode

Pretty Navbar

As you can see it looks 10 times better than before, but **STILL **we are not done. I want to centre these vertically so they more accessible from anywhere on the page. To this we need to do some tricky CSS, we're also going to create a Group component to... group the buttons.

Personally, I like to do in-line CSS before moving it anywhere that way I only have to modify a single file. This is what I created:

function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <Group
            direction='column'
            spacing='lg'
            grow
            sx={{ margin: 'auto 0 auto 0' }}
          >
            <Navbar.Section>
              <Button variant='subtle' fullWidth>
                Assets/Hosts
              </Button>
            </Navbar.Section>

            <Navbar.Section>
              <Button variant='subtle' fullWidth>
                Software
              </Button>
            </Navbar.Section>

            <Navbar.Section>
              <Button variant='subtle' fullWidth>
                Configurations
              </Button>
            </Navbar.Section>
          </Group>
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
Enter fullscreen mode Exit fullscreen mode

Let me explain the Group component quickly.

<Group
  direction='column'
  spacing='lg'
  grow
  sx={{ margin: 'auto 0 auto 0' }}
>
Enter fullscreen mode Exit fullscreen mode

Final Navbar

direction is used to define if the group is in columns or rows. spacing is used to create spaces between the components, this can be customised using themes. grow allows the components to grow horizontally if direction='column' and vertically if direction='row'. sx is used to pass in-line CSS to the component, more of my reasons for my solution can be found here.

Now before we move on let's clean it all up. I'll create a new directory under src, called components/CustomNavbar, and create the CustomNavbar.tsx file. Within it I'll cut the Navbar children and paste it into CustomNavbar.tsx.

CustomNavbar.tsx

function CustomNavbar() {
  return (
    <Group
      direction='column'
      spacing='lg'
      grow
      sx={{ margin: 'auto 0 auto 0' }}
    >
      <Navbar.Section>
        <Button variant='subtle' fullWidth>
          Assets/Hosts
        </Button>
      </Navbar.Section>

      <Navbar.Section>
        <Button variant='subtle' fullWidth>
          Software
        </Button>
      </Navbar.Section>

      <Navbar.Section>
        <Button variant='subtle' fullWidth>
          Configurations
        </Button>
      </Navbar.Section>
    </Group>
  )
}
Enter fullscreen mode Exit fullscreen mode

We'll then import the new CustomNavbar component into the App.tsx file where the original code was.

App.tsx

function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <CustomNavbar />
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
Enter fullscreen mode Exit fullscreen mode

Part 3 - Further Styling

We're not going to be creating anymore Navbar components and so we'll make the CSS for this global to clean up the files. We do this by moving it to the MantineProvider component in our index.tsx.

ReactDOM.render(
  <React.StrictMode>
    <MantineProvider
      theme={{
        colorScheme: 'dark'
      }}
      styles={{
        Navbar: {
          root: { height: '100vh', width: '300px' }
        }
      }}
    >
      <App />
    </MantineProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

Because our CustomNavbar's Group component will be reused later in this project we'll leave the in-line styling and we'll come back to the CustomNavbar when we create users.

Conclusion

Thanks for joining me on the 2nd part to this series, please leave a like and comment if you have any questions, I will try to answer all questions. Come back next time to see further developments to the Navbar and how we'll create a User component.

Tiugo image

Fast, Lean, and Fully Extensible

CKEditor 5 is built for developers who value flexibility and speed. Pick the features that matter, drop the ones that don’t and enjoy a high-performance WYSIWYG that fits into your workflow

Start now

Top comments (0)

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Value this insightful article and join the thriving DEV Community. Developers of every skill level are encouraged to contribute and expand our collective knowledge.

A simple “thank you” can uplift someone’s spirits. Leave your appreciation in the comments!

On DEV, exchanging expertise lightens our path and reinforces our bonds. Enjoyed the read? A quick note of thanks to the author means a lot.

Okay