An Introduction to Using Grommet UI with React, Part 1
Make your react apps beautiful and responsive, fast
There are many great ways to style your React applications, from classic CSS/SASS stylesheets, CSS-in-JS(such as styled components), and CSS libraries such as Tailwind or Bulma. There are also UI libraries, which provide pre-styled components for you to build your application with. Material UI, React Bootstrap, and Semantic UI are among the most popular, but lately I have really enjoyed using Grommet. Grommet is a wide library of components which brags some big name users such as Netflix and Boeing. Grommet has great theme tooling and specializes in accessible, mobile-friendly applications. In part 1 of this article I will walk though setting up a new react app using Grommet!
Table of Contents
Setting up
Create-React-App
This tutorial will be utilizing Create-React-App(CRA). Instructions for getting started with CRA can be found here. We will also be using npm as our package manager, but feel free to use the package manager of your choice.
create-react-app grommet-tutorial
cd grommet-tutorial
rm -rf yarn.lock
rm -rf node_modules
npm install
Clean Up
Next, for the purposes of this tutorial, we will clean up some of the unnecessary files. From the ‘src’ directory, remove the following files:
- src/App.css
- src/App.test.js
- src/index.css
- src/logo.svg
You can copy and paste the following command to delete them all at once:
# working directory: grommet-tutorial
rm -rf src/App.css && rm -rf src/App.test.js && rm -rf src/index.css && rm -rf src/logo.svg
Inside src/index.js
, remove the import of index.css
. Inside src/App.js
, remove the import of the logo and App.css
. Don’t forget to delete the <img>
tag containing the logo as well.
Add Grommet
Next, we are going to add grommet and the accompanying icons pack to our project:
npm install grommet grommet-icons --save
Now we will import Grommet at the top of App.js
like so:
import { Grommet } from 'grommet'
Your App.js
file should now look like this:
import React from 'react'
import { Grommet } from 'grommet'
function App() {
return (
<div className='App'>
<header className='App-header'>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className='App-link' href='https://reactjs.org' target='_blank' rel='noopener noreferrer'>
Learn React
</a>
</header>
</div>
)
}
export default App
Adding Your First Components
The first thing we need to do to start using Grommet is to wrap the entire app in the Grommet
component we imported at the end of the last step. Once we do, we can utilize any of the grommet components inside. To do this, lets replace the main app div with Grommet
:
function App() {
return (
<Grommet>
// ...
</Grommet>
)
Next, lets import a couple themes for us to use! Grommet comes with a few out of the box, but you can also create your own custom themes. Go ahead and import the standard light and dark themes, and add one to your Grommet
component:
import { grommet, dark } from 'grommet/themes'
// ...
function App() {
return (
<Grommet theme={dark}>
// ...
</Grommet>
)
}
If you are using dark
, you may notice that it doesn’t extend to the edges of the screen. To fix this, lets add the prop full
to Grommet
, like so:
function App() {
return (
<Grommet theme={dark} full>
// ...
</Grommet>
)
}
Viola! Modifying components is as simple as passing in props. We dive into this more in a bit.
The next component we will use is called Box
, and it is essentially a div with benefits. Box
has Flexbox built in, and comes default as a flex column. Let’s go ahead and replace the <header>
tag with a Box
. With any new component, we will need to import it before we can use it:
import { Grommet, Box } from 'grommet'
// ...
function App() {
return (
<Grommet theme={grommet}>
<Box>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className='App-link' href='https://reactjs.org' target='_blank' rel='noopener noreferrer'>
Learn React
</a>
</Box>
</Grommet>
)
}
You shouldn’t see a big change yet, so lets modify the box a little bit to make things look better. Just like earlier, all we need to do is pass in values as props! Lets say we want to center all of our content on the page. We can fo this by passing in three props. First, fill
, which defaults to true. This will cause the Box
to fill up all available space on the page. Next, we want to add justify
and align
, and set them both to true. align
will center the content on the x-axis, or left-to-right, and justify
will center on the y-axis, or vertically. Your component should now look like this:
<Box
fill
align='center'
justify='center'
>
//...
</Box>
And with that, all of our content is centered! We are now ready build our next custom component, a nav bar.
Building a Nav Bar
Above the App
function, lets create a new function called NavBar. NavBar will return a Box
, styled as a nav bar. If you are familiar with CSS, many of the props will be familiar to CSS properties, and usually the value passed will be the same as CSS.
// ...
const NavBar = () => {
return (
<Box
tag='header' // sets the HTML tag Box is rendered as to header
direction='row' // sets the flex direction to row
align='center'
justify='between' // spreads out the content of the box
background='brand' // sets the background to the brand, or main, color of the theme.
pad= // sets the padding, or space around all content within the box
elevation='medium' // how high above the background this element will seem. Gives a box shadow.
{...props} // spreads any children elements passed in as props
/>
)
}
function App() {
return (
<Grommet theme={light} full>
<NavBar></NavBar>
<Box fill align='center' justify='center'>
// ...
</Box>
</Grommet>
)
}
Now that you have written your custom NavBar component, lets add some content to it! Lets import two new Grommet components, Heading
and Button
, and well as Menu
from the icon pack. We can the add these as children to NavBar
:
import { grommet as light, dark } from 'grommet/themes'
import { Menu } from 'grommet-icons'
// ...
function App() {
return (
<Grommet theme={light} full>
<NavBar>
<Heading
level='3' // sets the type of header (h1, h2, etc)
>
Grommet Tutorial
</Heading>
<Button
icon={<Menu />} // sets an icon as the button
onClick={() => {}} // handles a callback function on click
/>
</NavBar>
// ...
</Grommet>
)
}
And just like that, you should have a beautiful header at the top of the page. The Menu button doesn’t have any functionality yet, but we will be adding that in part 2!
Congrats!
That concludes part 1 of this article! In part two, we will look at integrating React state to make our user interface more dynamic, as well as optimizing our site for mobile. Thank you so much for reading, and I hope to see you in part 2!