All right.
So now that we've got most of our functionality done, the next step is to tidy things up and try to make
the appearance of our app look a little bit better. Now
the end result that we're aiming for after all of our styling et cetera, is something like this.
We've got icons in place,
we've got expanding features for our inputs,
notice how this button also has a hover effect, and also in our background, we've got a little pattern
going on as well.
And in order to create these effects, we're going to be using some pre-built components by adding some
dependencies.
And even if you're working on your own local copy or on a previous version of the app, I recommend to
use this starting project, or to download a fresh copy if you're working on your local environment.
And the reason being is that in the styles.css we've got a couple of changes and in the CreateArea,
I've added a className to our form.
So if you don't have the same one you might end up with weird looking UI that doesn't look the same
as the video.
So I recommend starting with the same sandbox and just forking a copy of it.
So go ahead and fork
the starting project. And the first thing that we're going to add is something called Material UI.
So go ahead and click on the Add Dependency button, and search for Material UI,
and we're going to need the core component as well as the icons component.
So let's click on both of these,
material-ui/icons and material-ui/core.
Now if you're doing this locally then you can install both of these using npm.
And if you go over to the documentation for these pages you'll see how to do that
exactly.
Now MATERIAL - UI are basically React components that have been pre-built so that we can simply just customize
and get hold of some of the functionality, as well as modify some of the appearance so that we can create
our own apps much faster using Google's design concept which is called Material Design.
Now to start with let's go ahead and go to the components list and we're going to get hold of some icons.
So remember how we already installed material-ui/icons and also material-ui/core, then we
can simply just import the icons and go ahead and use them.
So if you take a look at the code here, it's as simple as importing an icon say for example the
DeleteForeverIcon from material-ui/icons/DeleteForever and then you get to simply use it as just
any other React component.
So let's try that out on our site.
The first thing I want to do is to simply change the DELETE button here from just the words DELETE which
is added inside this button to use an actual delete icon that comes from this Material-UI library.
We can find the full list of icons in their search page, and I'm going to search for something to do
with delete.
So I think this will trash bin looks pretty good.
So that's the one that I want to use and I'm going to go ahead and just copy this line of code.
Now going back over to my Note.jsx I can paste in this import statement and I can now use it
instead of my hardcoded text.
So I'm going to add a <DeleteIcon /> which is a self-closing tag.
And now if I create a new note, you'll see that it has a little trash bin.
This is just how easy it is to actually use these components. And the benefit of using React Components
over other things such as Bootstrap, or Fav icons is that in React, we have our JavaScript,
CSS, and HTML pretty much all combined into one in each of these components.
So we can even add components that actually have functionality that we didn't even have to code up.
For example, I want to change this Add button so that instead of saying the word Add, I want to use an
Add icon from Material Icons.
See if you can pause the video and find an appropriate add icon that you can replace this word add with.
Pause the video now and give that a go.
All right.
So let's try and search for something.
Now I'm just going to choose this very simple add icon here and I'm going to copy the import statement
and add it to my CreateArea.
So now instead of this word Add, I'm going to use the AddIcon component.
And now when this refreshes, you can see we've got a big add sign in here.
Now if I had just used the plus sign you can see how it's very, very tiny.
But instead I'm using the icon which should scale up.
Now notice how in the final version this add is a lot fancier, namely, when I roll over it
it actually changes color, but also when I actually click to expand this area it actually pops up with
a little animation.
So how can we do this? Well instead of using our own button which is a standard HTML button, we can
use it something called a Floating Action button that comes from the material ui package.
So if you go ahead and look through the inputs and buttons section you can see there's lots of different
types of buttons.
And the one that we want are these Circular Floating Action Buttons.
And in order to use it all we have to do is to import the floating action button which is called a Fab,
and let's go ahead and drop it into our CreateArea component. And now instead of using a button, I'm
simply going to change this component to a Fab.
So it was lowercase a and b an uppercase F which we imported here.
And you'll notice that there shouldn't be all that much change here other than the fact that when you
hover over it's suddenly changing color.
And this is because now instead of using our own buttons we're using a Fab component from the Material-UI
library.
Now if in your case you don't actually see a yellow icon that's positioned here,
then it might be that you've actually got a different stylesheet to me.
Remember in the beginning of the lesson I recommended to actually fork the starting version of this
project, and it's because there were a couple of changes in the style sheets and in the CreateApp where
I added a class name to the form.
So if you're seeing a grey button instead and it's positioned out of place then just simply go ahead and
copy this style sheet from these starting project and then go into the CreateArea and update the form
so that you apply the class name to the form.
And this way we can actually apply the same styling to everything inside the form just as before.
But if you started out with the starting project then you shouldn't have any problems at all with the
styling. Go down on the Material-UI component,
you'll see a section which talks about the floating action button animating onto the screen as an expanding
piece of material.
And we can do this,
they say, using a zoom transition.
So if we take a peek at the code you can see that all that they've done is just wrapped that Fab inside
a Zoom component.
So if we search for a Zoom component,
then we can learn how to use it.
So first let's go ahead and import it and put it at the top. And then we can go ahead and simply use
it with this in, prop.
And this is a true or false boolean,
so if it's true, the component will transition in, if it's false then it won't.
So let's go ahead and apply our Zoom component here,
and place the closing tag around our Fab, and then we'll add that prop in to make it true.
Now whenever you refresh the app you can see that the Fab actually will zoom in and in an animated way.
But it would be so much better if we can actually change our app so that we have the content input showing
by default
but when we click in the content input then do we actually show our title input and also let the button
zoom in. So this is something that we could do with conditional rendering and you already have enough
skills to be able to create this effect where the title input only shows if a particular state is set
to true, and the button also only zooms in when that state is set to true.
So there's a couple of things that you have to think about in order to complete this challenge.
Firstly, is that our content area is a textarea and to begin with we want it to be a little bit smaller
than it is. So we can set this depending on the number of rows.
So if we start out with a single row,
then it becomes very small, but once it's expanded we wanted to take up three rows.
Now the other thing to think about is we want to get rid of this input area when this CreateArea is
not expanded.
And only when it should expand do we actually insert the input back in.
So you'll have to conditionally check for some sort of state and render this input depending on that.
The final thing is we're going to also make this zoom in, conditionally.
So to start off we won't have the Fab, and then only when it's zoomed in
do we set this to true
and we actually render the Fab. So have to think about some of those things and take a look at this
behavior of expansion.
So starting out with just the text area, a single line and then when you click on it, it shows the title
input and the Fab zooms in. Pause the video and see if you can complete this challenge using what you know
about conditional rendering.
All right.
So to solve this challenge the first thing we need to do is something that holds the state of whether
if I CreateArea is expanded.
So let's create a const and I'll call it isExpanded and I'll provide a function called,
setExpanded and set that to useState.
Now to begin with,
I want my isExpanded const to be set to false because I don't want it to be expanded and it's only
when the textArea gets clicked on,
so let's add an onClick here,
then do we actually want to expand that area.
So I'll call a method called expand, and I'll define that method just below here.
Now when this method is called, we're going to set the expanded to true.
So let's call
setExpanded and pass in true as the value.
Now when we click on the textarea, isExpanded becomes true and we can now listen for that in order
to render the input.
So let's cut this out and add a set of curly braces.
If the isExpanded is true, then we'll render the input,
otherwise we'll render nothing.
Now alternatively, you can use the syntax where we just have the double ampersand and it does exactly
the same thing, showing the input only when we click on this textarea.
Now the second thing we mentioned, is that we want to change this rows to 1 to start off with and only
turn it to 3 when it's expanded. so let's check for isExpanded.
If it's true then we'll render 3 rows
and if it's false will render 1 row.
So now it starts out being very compact
and when we click on it it expands.
The final thing to address is our Fab button.
We only want it to show up and zoom in when it shows up only when it's expanded.
So instead of hard coding this is true, we're going to again use that isExpanded property.
So now we click on it and everything shows up like so. Did you manage to get that? If not be sure to review
the section on rendering components conditionally. Now at the very last icon
I want to add is to my keeper title up here.
So I want to use the highlight component that looks like this,
and so I'm just going to copy that and paste it into my header and use it inside this h1.
So let's go ahead and add it in here as a highlight icon, and now we should be able to see the icon
alongside our title like so. The very final thing that you might notice that's different between this
version and our version is it's actually got a background image. To achieve this effect
you can use a website called transparenttextures.com and you can scroll through all of these textures to
find one that you like. And the one that I decided upon was this sort of boxy looking one that looks
like this.
It's called cubes and it's made by Sander Ottens.
And in order to use it, we can simply click on it and now we have that pattern saved as a URL.
If we go ahead and copy this entire URL where we set our background image then we can go into the
CSS and go ahead and add it to the body.
So in addition to having a background, it's also got a background-image with a particular URL
and then let's just make sure we cap the end with a semicolon.
And once we hit Save on our styles.css and refresh then you'll see that background image show up.
So now we have functionality as well as style. Now
you might notice that if you add a couple of notes and you go ahead and refresh the page, your notes
will disappear.
And the reason is because React as we mentioned is a front-end library.
It's responsible for creating these components, creating the functionality and the styling but it's not
responsible for saving your data.
So if you do want these things to be persisted, then you'll have to review what you learned in our backend
modules with Node, and with MongoDB if you wanted to be able to have a backend to your frontend
application. I hope you enjoyed building this project with me and you'll use what you've learned about
React in order to build even more awesome projects of your own.
I would love to see whatever it is that you build and congratulate you on your work.
So if you create something,
be sure to let me know either via Twitter @yu_angela or in the Q&A section of the
lessons.