Or rather my friends, so now I'd like to create a custom button component so that this looks a bit better than this default button right here. And then we can reuse that button component wherever we need it in the future as well. So we can make this button customizable and we could maybe pass in some options as props maybe.
So let us first create this new component inside the shared folder and we'll call this button.svelte. Okay. So inside here we need a script because we're going to accept some props later on. We also need a style tag at the bottom because we're going to style this later on. And we also need some kind of template. Now the template itself is going to be simple, it's just going to be a button. And then inside we're going to render the slot. And remember, a slot is a way to pass data into a component. So when we use the component in the future, then we can pass in whatever we want to be inside that button's content. Now that could be icons or it could be text, or it could be even HTML. So we have this slot set up now.
Defining Customizable Props
And I'd like to accept also a few different props. Now I'm going to explain these in a second, but first let me say export let type and we'll set a default value as primary. So this right here is going to be the type of button, so it could be primary or secondary maybe. And then we can apply this as a class to the button itself and do a selector for primary and secondary and style those differently. So that's the first thing we're going to accept.
We're also going to accept a prop called flat and that is going to be a boolean, either true or false. So if it's true, it means it's going to be a flat button. If it's false, it means it should be a little bit away from the screen, so maybe apply a box shadow to it. So we could apply a conditional class of flat to the button and style that differently dependent on this. And then finally, I'm going to say export let inverse and set that equal to false. And again, a boolean, true or false. If it's inverse, what I will do is give it maybe a white background or transparent background and a border instead of a colored background. And we'll see that later on.
Binding Props and Applying Base Styles
But for now, let's do this thing first of all. So I'm going to say that the class of this is going to be equal to the type. So this is not a conditional class, we're not saying class type is equal to some kind of evaluation, we're saying the class is actually going to be the type that we get right here. So that could be primary if we pass in primary, and that's the default one as well, or it could be secondary if we pass in secondary. And we could then style primary and secondary different.
So let's do a few styles for now anyway. So I'll say first of all, the button is going to have a border of zero, and then we'll say the cursor is going to be a pointer so a little hand and a user knows they can click on it. Then a border-radius to soften the corners of six pixels, and then we'll do a padding of eight pixels top and bottom and 12 pixels left and right. And then we'll also do a font weight of bold. And then we'll do a box shadow. This gives it a bit of a 3D effect. And we'll say one pixel, two pixel, three pixel, rgba and it's going to be zero, zero, zero which is black and an alpha channel or opacity of 0.2, so a faint shadow.
Now what I'm going to do for now is import this button into the form so we can see what it looks like so far. So let me go to the form and import it at the top. So I'll say import, and it's going to be button from, and we want to go up a directory first of all, because we're currently in components. So ../ to jump out of that directory, then into shared, then /button.svelte. And now we can output that down here instead of this button. So button like so. And remember we're passing content, which will be the slot right here. So whatever we pass in between the opening and closing button tag will appear where the slot is right here. So I'm going to say Add Poll like so.
Now if I save that and preview it, we should be able to see this new button. It doesn't look great at the minute and we have this random closing angle bracket, which we'll sort in a second as well, but we are going to add styles to this as we go forward. Now let me now just go to the button and find the angle bracket, and I can't actually see it there. So let's check the form. And yep, it's right here. Okay, so save that and preview again, and that looks better.
Styling Primary and Secondary Variants
Okay, so now let's style up the primary class and also maybe a secondary class. So I'm going to say the primary is going to be a background color of, and it's going to be that red color from before, which was d91b42, like so. And then it's also going to have a text color of white. So that's the primary one.
Now, the secondary class is going to have a background of a different hash, which is 45c496, and that's a greeny color, and the color of the text is also going to be white in this case. So now if we have a type of primary, the class is primary and we're going to style it like this, and we should see a red background button with white text, which we do. And if we give this a class of secondary, which we'll do now, we're passing that as a prop. So we'll say type is equal to secondary like so. Now we're overriding that value. So type is now secondary, the class is therefore secondary, and we style it like this. So if we preview now, we can see it's green. Okay, so we're passing in options to the button.
Implementing the 'Flat' Style
Okay, so what else can we do? Well, we have this thing right here where we're saying flat is false, and we're going to output a conditional class based on this boolean. So I'm going to say class:flat={flat}. So if this boolean right here is true, then we're going to add a class of flat to this button. If this is false, then we're not going to add a class of flat. All right, so if we do have a class of flat, all we're going to do is take away the box shadow. So I'll say box-shadow is none. Now by default, flat is false, so we won't get that class applied. So it should look the same if we go to Add New Poll. But if I now say that I want flat to be true, so flat={true} on this button, now we can see that this is flat because we apply the flat class. I can open this up and inspect, and we can see this flat class right here.
Implementing the 'Inverse' Style
Awesome. Okay then, so back in the button, let's do this final thing, inverse. And we're going to do exactly the same as we did here. So class:inverse, so we're only going to apply this class of inverse if the inverse variable is true. Currently it's false, so it won't apply that class, but if it was true, it would apply that class.
Now the inverse class is basically going to reverse the colors. So instead of the background being this color, the background would be white and the text color would be this color. And also we could apply a border of this color as well. Now we need to apply different inverse classes for each one of these because the colors are different. So let's do that. I'm going to say .primary.inverse. So if we have both of those classes, then the color of the text is actually going to be this thing right here, which was the background before, and the background, oops, the background this time is going to be a white. And also we'll do a border and that is going to be two pixels solid and we're going to do that red color again. Okay, so that's the primary inverse.
Now let's do .secondary.inverse. And this time the color of the text is going to be this green color right here. So let's copy that dude and paste it right here. And we want the background again to be white this time because we're inversing those things. And then we also want a border of two pixels of the button, solid, and it's going to be this green color again. Okay, so now we shouldn't see any difference when we go to the bottom because we don't have that inverse class. But if I now say over here that inverse={true}, then it's going to inverse the colors and we should see something like this instead.
So, we have a bit of flexibility with our button. We could pass in secondary or primary and we see different styles. We can pass in inverse or flat as well. And in fact, I'm going to take this off because I don't want this to be inverse. I want it to be primary, but I don't need to explicitly say that here because the default value is primary up here. So I just want this to be flat. Save that, preview at new poll, and that looks pretty good. In fact, I think I'd like to make this green. So let's say actually that the type is going to be equal to secondary, because we're going to use the red button later on for deleting polls. So we use green for adding, red for deleting. Save that and preview again. And there we go. Wow, looks pretty good to me. So now we have our custom reusable button component, and we're going to use this later on in different components as well. Next up, we're going to add a little bit of custom form validation to our form over here when we try to submit.