Creating a Custom Navbar with Mantine in ReactJS #2
Tags: javascript, webdev, tutorial, react
Published: 2022-02-20 04:02:17

## Intro
Welcome back ([previous](https://dev.to/samp_reston/building-an-application-with-mantine-in-reactjs-ts-3f43)) 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](https://mantine.dev/theming/mantine-provider/) 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:

```javascript
ReactDOM.render(
  <React.StrictMode>
    <MantineProvider>
      <App />
    </MantineProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

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.

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

This changes the application to look like so:
![Dark Mode Init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ilp4hnsaquvl2ymutcw7.png)
 
## 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 />`.

```typescript
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>
  );
}
```

![Ugly Navbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v34nkeq1kzaq2go2639z.png)

This creates a very ugly un-styled look to the Navbar, lets fix that by using a [Button](https://mantine.dev/core/button/) component.

```typescript
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>
  );
}
```

![Unstyled Buttons Navbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp89esh190ililxosilz.png)

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.

```typescript
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>
  );
}
```

![Pretty Navbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s287luq4v53nyo99pecj.png)

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](https://mantine.dev/core/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:
```typescript
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>
  );
}
```
Let me explain the Group component quickly. 
```typescript
<Group
  direction='column'
  spacing='lg'
  grow
  sx={{ margin: 'auto 0 auto 0' }}
>
```
![Final Navbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jptud7tlent9cv9vsntm.png)
 
`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](https://www.w3schools.com/cssref/pr_margin.asp).

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_**
```typescript
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>
  )
}
```
We'll then import the new CustomNavbar component into the App.tsx file where the original code was.

**_App.tsx_**
```typescript
function App() {
  return (
    <AppShell
      navbar={
        <Navbar
          width={{ base: 300 }}
          height='100vh'
        >
          <CustomNavbar />
        </Navbar>
      }
    >
      {/* Your application here */}
    </AppShell>
  );
}
```

## 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`.
```typescript
ReactDOM.render(
  <React.StrictMode>
    <MantineProvider
      theme={{
        colorScheme: 'dark'
      }}
      styles={{
        Navbar: {
          root: { height: '100vh', width: '300px' }
        }
      }}
    >
      <App />
    </MantineProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

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.