If you're working with Vue.js you know that here are a lot of UI component libraries orbiting around the Vue.js world like Vuetify, Buefy, BootstrapVue and so on. Rather than coding and styling buttons, cards, and layouts, you can use these libraries to get access to all the necessary UI elements for creating beautiful, content-rich applications. However sometimes you want to switch to your custom design or try another UI framework that doesn't provide any ready-to-use Vue.js component. In such cases you would like to have a set of naked UI components on which you can apply your style: here's where Oruga comes into play!
Say Hi to Oruga! 👋
Oruga is a new lightweight library of UI components for Vue.js (2.x and 3.x) without any CSS framework dependency. In fact, it doesn't depend on any specific style or CSS framework and it doesn't provide any grid system or CSS utility, it just offer a set of components that you can easily customize modifying your stylesheets or integrating it with a CSS framework. It also provides a default stylesheet containing only the essential rules to display Oruga components correctly such as display
, position
, z-index
and other basic attributes.
Oruga wants you to focus only on UI/UX aspects of your application and be totally flexible to future changes without having to touch a line of JavaScript.
👉🏻 You can find useful resources and links at the end of the article!
Setup 🐛
Let's start a new project for Vue.js 2.x and install Oruga package (note that Oruga is available for Nuxt.js as well, see the documentation)
yarn add @oruga-ui/oruga
Then, import Oruga default stylesheet, the Config
component and the Button
component
import Vue from 'vue'
import {
Config, Button
} from '@oruga-ui/oruga';
import '@oruga-ui/oruga/dist/oruga.css'
Vue.use(Button)
Config
will be used for customization.
Customization
Customization is the core feature of Oruga. You can easily override existing components style appending one or more classes using the Config
component. Each component has some class properties
that you can define to extend classes of the target component. Each class property affects a specific part of the component as you can discover using the Class props inspector in Oruga documentation.
Suppose we want to style our Oruga components using a cool CSS framework like Nes.css to give our app a cool 90s style.
To install Nes.css run
yarn add nes.css
(add --ignore-engines
to the command above if you're using Node.js > 10.x)
And import it in your project
import "nes.css/css/nes.min.css";
Let's start with a simple Button component from Oruga.
<o-button @click="search">Search</o-button>
Nes.css provides nes-btn
class for buttons, so we can extend Oruga Button component using the Config object
Vue.use(Config, {
button: {
rootClass: 'nes-btn'
}
}
When you instantiate a new Oruga Button, you'll have the class nes-btn
automagically applied to your component, alongside default classes applied on that part of the component. If you wish to override default classes and use only your custom class, you can assign to rootClass
an object, with the override
attribute set to true
.
Vue.use(Config, {
button: {
rootClass: {
class: 'nes-btn',
override: true
}
}
}
Using the Class props inspector we can easily find the class name to add a class when the button is disabled (in this case disabledClass
), then we can extend our configuration overriding all the class props of o-button we need to customize
Vue.use(Config, {
button: {
override: true,
rootClass: 'nes-btn',
disabledClass: 'is-disabled'
}
})
Result
Sometimes you may need more flexibility to extend classes and decide programmatically which class to apply to our component, especially when you have to deal with variant or position classes. Many Oruga components has some classes applied when certain properties change, like position
and variant
, on the other side Nes.css provides "variant" classes like is-success
and is-warning
and "position" classes like is-centered
. For example, how can I apply the correct class in this case?
<o-button variant="warning">Warning!</o-button>
Follwing the Class prop inspector we can easily find that the Class prop we need to override is variantClass
but its values are not fixed, it could be is-warning
, is-error
, is-success
depending on variant value as you can see in the Suffixes
column
Oruga provides an easy way to help us: you can extend classes using functions! A function will receive two parameters:
- a
suffix
(that will receive for examplewaring
,success
,error
in case of variants orcentered
,right
.. in case of positions) - a
context
containing the context of the component instance.
To extend variantClass with Nes.css for Button we can simply do that
Vue.use(Config, {
button: {
rootClass: "nes-btn",
variantClass: (suffix, context) => {
return `is-${suffix}`
}
}
})
Result:
variantClass
is determined by a function that will receive "warning"
as suffix when variant property of o-button
is "warning". Using a function we can instruct Oruga to apply to our Button components a class whose name is composed by "is-" followed by the suffix value, in this case the variant. Thanks to the context
parameter, you can take more refined decisions like not applying a variant if the component is outlined (see an example here)
A Pokèmon finder with Oruga and Nes.css
Using Oruga and Nes.css I built a simple Pokèmon finder to search some statistics of my favourites Pokèmon taking advantage of the cool PokèAPI.
The app is really simple: it allows you to type Pokèmon name you want to find, press a button and then, through the API, get all the information you need and show them in a table. If the Pokèmon can't be found, the search input will turn red (variant="error") and an error message will be shown. You can play with the app on Netlify and browse the final code on GitHub
As you can see in the main.js file the final configuration for Oruga is really simple.
Useful resources
You can also play with other cool Oruga examples
Top comments (7)
the current only UI library does vue3 at production-ready quality is primevue, oruga seems the second most potential ones(all the rest options are still early in their vue3 efforts), hope to see a stable Oruga-for-vue3 soon
Sure! To support Vue 3 completely is our goal :)
👋 Yes we're working hard on Vue3 support to make it as more stable as possible.
Uoh, it looks like a brilliant idea.
I struggle in every project on this exact aspect of frontend development (Vuetify2 => Vuetify3?!?! ...coff ...coff) and the fact that is available for Vue2 AND Vue3 (my favourite frameworks) makes me very happy.
Do You know if this can be used with Vuetify2/3?
Thanks Andrea and keep up!
Thanks Fabio! Well, you could try customizing Oruga with Vuetify CSS and see if it works... I only tried to customize Oruga with Bootstrap Material css here oruga-multiframework-demo.netlify....
Should be a killer combo with tailwindcss!
I'm wondering if it's easy to convert from Buefy to Oruga. Anyone did it?
Oruga comes from Buefy so i think you'll find 95% of Buefy features in it.
About UI the full-css is very similar but the class naming doesn't follow Bulma/Buefy syntax; I don't think to be able to follow both projects so for this reason (later) I'll develop a Buefy plugin (+ how to) for Oruga in order to make it easier to migrate from it.