Extracting a Component0:00
So, we have two templates and a layout, and everything appears to be working okay, except that the templates essentially have the same markup. The content is of course different, the colors are obviously different, and if programming has taught us anything, it's that when we have any kind of repetition at all, that is an opportunity to extract that out into something that can be reused. And we can do that by creating a component. So a component is, well, it is a component. It is a set of markup that we define, and that we can reuse throughout our project. So if we open up the Explorer, there is this components folder, and that is where our components live.
Creating Notification Component0:45
So if we open up the Explorer, there is this components folder, and that is where our components live. So let's create a new file. And we'll just call it Notification, because that's essentially what we are going to create, a component for notification emails. It's going to have this same overall markup, but of course, it's going to be generic so that we can supply whatever content that we need for it to display. So the first thing I'm going to do is take out all of the markup from our invoice approval template, and I'm going to paste it inside of Notification. And of course, whenever I save everything, then we see nothing in the browser, but that's
template, and I'm going to paste it inside of Notification. And of course, whenever I save everything, then we see nothing in the browser, but that's to be expected, because our invoice approval template no longer has any markup or content. So that means we want to be able to refer to that Notification component, and we do so a lot like we do with the layout page. We start with X-, followed by a dash, and then the name of the component file. So our file is Notification.html. So the tag is going to be X-Notification. And voila, we see our Notification component being used. And that's all well and good, but now we need to supply the necessary information to make
Adding Props and Variables1:52
And voila, we see our Notification component being used. And that's all well and good, but now we need to supply the necessary information to make this a reusable component. So let's start by going to our Notification component, and at the very top, we are going to add a script element that has an attribute called props. Then we will want a module.exports statement to where we export an object. And then the properties that we define here are going to be variables that we can use inside of our markup here. So for example, the headerBackgroundColor is blue. So what we could do then is define a bgColor property, and we could set that value to bgBlue900.
So for example, the header background color is blue. So what we could do then is define a bgColor property, and we could set that value to bgBlue900. And then inside of our markup, we can get rid of that CSS class, and we can use a pair of curly braces, and then use bgColor there. Notice that nothing changes in the browser because, well, we're using the same color. But let's say that's not blue, but we want slaked. And so there we can see the obvious change occur inside of the browser. Now, that's all well and good, but that is still something that's hard-coded inside of the component. We need to be able to provide content to a component so that it can use that data.
inside of the component. We need to be able to provide content to a component so that it can use that data however it needs to. So what we want to do then is pass what's called a prop. And if you are familiar with Vue or React or those kinds of frameworks, then this is going to be very familiar to you. A prop is really just a parameter. You can think of a component as a function. Functions have parameters that you pass values to. Well, a component has props.
Functions have parameters that you pass values to. Well, a component has props. A prop is something that has a name, and you pass a value to that prop. So in the case of our invoice approval notification, the background color is going to be the value that we want, which will be bg-blue-900. The prop name is going to be bgColor. And then we just need to refer to that prop up here inside of our script element. So we could do something like this. We could say that this slightColor is going to be our default.
So we could do something like this. We could say that this slight color is going to be our default. But if we are given a BG color as a prop, then we want to use that value instead. So that in this case, we passed blue to the BG color prop. That value is then being used for the BG color variable inside of our component. And then if we omit that BG color prop, then the slate color will be used. So that's perfect. I like that functionality. Now, you might be tempted to do something like this, to use props.
I like that functionality. Now, you might be tempted to do something like this, to use props. And then your prop name directly inside of your HTML. Well, that's not gonna work. So this props object is only available inside of our script element. If there's a prop value that we want to use, we have to essentially assign that to a variable that we can then use inside of our markup. Now, notice that the pageTitle is still working just fine. So even though we are inside of a component, we still have access to that page variable.
So even though we are inside of a component, we still have access to that page variable. So therefore, we are still pulling in the title from the front matter on our invoice approval template. Now, we have the header sorted out, but what about the content? Because we essentially have two pieces of content here. We have what I'm going to refer to as the message. So username approved the invoice, that's the message of this notification. And then we have some content, which in this particular case is a link. But I could see cases where we wouldn't want a link,
Passing Body Content5:30
And then we have some content, which in this particular case is a link. But I could see cases where we wouldn't want a link, we would want some other kind of content. So the content portion can be different for a variety of different cases. So what we could do is something like this. We could supply that content as the body of the component inside of our template. So that we still have this x-notification element, but inside of it, we have the content that we would want to display. And then inside of our component, we could display that content by using the content element.
And then inside of our component, we could display that content by using the content element. Just like we did inside of the layout. And so this way, whatever is going to be using this notification component, well, it could supply whatever content that it needed. And we can see that the content is gone now. So we are at least displaying the content dynamically, but I want to take this a step further. And I want to say that if we have a message, then I want that message to always have this same styling.
Using Named Slots6:24
And I want to say that if we have a message, then I want that message to always have this same styling. And that could be a little rough, because that would mean we would need to remember this exact styling all of the time. So what we could do is something like this. We can still keep this content here. But for our message, we will use what's called a slot. So that inside of our component, we will still have this <p> element. But instead of this text here for the content, we will have a slot that will have a name.
But instead of this text here for the content, we will have a slot that will have a name. And we can just call that message. And so inside of our template, we could say that we want to fill that message slot with the content of username approved the invoice. And so if we inspect this, we should see that <p> element wrapping around that text. There it is, <p class="margin-bottom-16">. So everything is working okay. The only issue with this approach, however, is what if we decide that we don't need a message?
The only issue with this approach, however, is what if we decide that we don't need a message? And so we don't include that. And that's fine, the P element isn't displayed, but that P element is still being rendered in the browser. So what we could do inside of our component is check to see if we have a value for the slot for the message. So we can use the if element. We'll have a condition that's going to use this slots magic variable. And we'll just check if there's a message and if it is filled.
We'll have a condition that's going to use this slots magic variable. And we'll just check if there's a message and if it is filled. And if so, then we will display that <p> element and the slot content inside of it. So if we look inside of the inspector, we can now see that that <p> element is no longer being rendered in the browser. Now we just have the content of this <p> element that has the link. But in this case, we want that message. So we will have the fill message elements and username approved the invoice. And so now we have a notification component that we can use for
Applying Component to Template8:16
So we will have the fill message elements and username approved the invoice. And so now we have a notification component that we can use for a variety of cases. And for the most part, we can supply whatever content that we need. The only thing that we need to do now is open up the document approval template and make that use our new notification component. So let's take out the table, we'll replace it with our notification component. The BG color here is going to be amber. I guess we need to open this up in the browser, so let's do that. But let's first of all omit BG color just so
I guess we need to open this up in the browser, so let's do that. But let's first of all omit BG color just so that we can see that everything is working okay. And then for our message, we'll say username approved the document. But let's say in this case, we don't need a link for the document. All we need is that message. So if we save it, we can see this template now uses our notification component. Let's add the appropriate BG color, and we will be good to go. And in the next episode, we will look at more of these utility elements.
And in the next episode, we will look at more of these utility elements.
