Posted on • Originally published atrailsdesigner.com
Multiple component variants with Tailwind
This article was originally published onRails Designer
One thing vanilla CSS does really well is extensibility. A good, and common, example of this is a button. With plain CSS you can build a basebtn
class and then a modifierbtn-primary
(orbtn--primary
to be BEM-like).
With Tailwind this is less easy to do, unless you use some sort of component system, likeViewComponent. Let's build just that today, so in your app you can writerender ButtonComponent.new.with_content "Save"
orrender ButtonComponent.new(variant: "danger").with_content "Delete"
. No dependencies needed, only what Rails gives you.
Let's set up the basics:
classButtonComponent<ApplicationComponentdefinitialize(variant:"primary")@variant=variantenddefcalltag.buttoncontent,class:classesendprivatedefclasses"inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-blue-500 rounded-sm"endend
That's your typical button component. Let's make use of the@variant
variable now.
classButtonComponent<ApplicationComponentdefinitialize(variant:"primary")@variant=variant.inquiryend# …privatedefclassesclass_names("inline-flex items-center px-3 py-2 text-sm font-medium rounded-sm",{"text-white bg-blue-500":@variant.primary?})endend
Firstinquiry
is called on the@variant
variable. I've writtenthis article on inquiry, so be sure to check it out for all the details. Than in theclasses
method, I am usingclass_names
. For theclass_names helper I've also written a separate article.
Theclasses
method is where everything comes together. You can see how clean having multiple variants is when the list is extended:
defclassesclass_names("inline-flex items-center px-3 py-2 text-sm font-medium rounded-sm",{"text-white bg-blue-500":@variant.primary?,"text-white bg-gray-600":@variant.secondary?,"text-white bg-green-600":@variant.success?,"text-white bg-red-600":@variant.danger?,"text-yellow-950 bg-yellow-500":@variant.warning?,"text-white bg-cyan-500":@variant.info?,"text-gray-900 bg-gray-50":@variant.light?,"text-white bg-gray-900":@variant.dark?,"text-blue-500 bg-transparent":@variant.text?})end
This is how they all look:
Next steps
If you want to use this component in your app, there are a few things you might want to add like:
- a
type
variable, so you can use this a submit-button in forms; - any other options, eg.
@options = options
, then using the double-splat (**options
) when passing it to the button element.
Simple and easy, right?
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse