Using or extending specified class to a component's root element with Svelte

fmgono

0 reactions 2022-12-20

Create a Button Component with Base Style

Let’s say we want to make a Button component and styling it with TailwindCSS:

// src/components/Button.svelte
<button class="py-2 px-4 flex justify-center bg-blue-500 text-blue-50">
  <slot/>
</button>

// src/index.svelte
<script>
import Button from './components/Button.svelte
</script>

<Button>fmgono.dev</Button>

and now our <Button /> component are rendered like this:

rendered button component with background blue and text white Purrfect!

Extend The Based Style Button Component

And for now on, we want to use this <Button /> component but with extending the style that already applied in that components. Let’s say we just want to make the background to be green. And because we using Tailwind for our styling, maybe we can simply to put bg-green-500 class, correct ?, and maybe we can write it like this

<Button class="bg-green-500">
 fmgono.dev
</Button>

And let’s check the result!

rendered button component with background blue and text white 😱😱😱 Why our class doesn't applied to the component style ? Let's inspect that elements... inspecting element html for button tag Hmm, did you see ? our class that we passed with `class="bg-green-50"` doesn't concat the base style, right ? We are expecting that our class will be like this, correct? `class="py-2 px-4 flex justify-center bg-blue-500 text-blue-50 bg-green-500"`

So, the first step to solve this case is, we have to get the passed props, right ? Maybe some of you thinking :

let’s define the variable props with export function!

Like this ?

<script>
// src/components/Button.svelte
export let class
</script>

do you ? Well that can’t be right, js / svelte compiler will gave us warning / error, because class is Reserved keyword in Javascript.

How about just using different name rather than class only ? something like customClass?

Well, that will work! But…maybe we will lost our autocompleted tailwind intellisense when trying to use tailwind class in our <Button /> component (if you are using VSCode and tailwind extension).

$$props For The Rescue!

Maybe we can declare a class props Luckily, Svelte already have a global property to access all passed props to our components, so we can use it like this!

<script>
// src/components/Button.svelte
export let class
</script>
<button class="py-2 px-4 flex justify-center bg-blue-500 {$$props.class}">
  <slot/>
</button>

and if we check our component, it will rendered the extending style from our passed class!

the rendered button component with green background and white text color Of course we are not limited to change the background, we also can use another style that Tailwind have, here is an example with adding font bold in our button label ``` ``` And the result is VOILA! rendered button element with green background and bold label text

Also if we inspect the element, the order also correct!

inspect element of button

See you next time!

Leave a reaction if you liked this post! 🧡