DEV Community

Andrea Stagi
Andrea Stagi

Posted on

Oruga: the new kid on the block

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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.

image

To install Nes.css run

yarn add nes.css 
Enter fullscreen mode Exit fullscreen mode

(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";
Enter fullscreen mode Exit fullscreen mode

Let's start with a simple Button component from Oruga.

<o-button @click="search">Search</o-button>
Enter fullscreen mode Exit fullscreen mode

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'
  }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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'
  }
})
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

image

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 example waring, success, error in case of variants or centered, 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}`
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

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.

image

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

image

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

Latest comments (7)

Collapse
 
shanwshaw profile image
shawnshaw

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

Collapse
 
jtommy profile image
Walter Tommasi

Sure! To support Vue 3 completely is our goal :)

Collapse
 
astagi profile image
Andrea Stagi

👋 Yes we're working hard on Vue3 support to make it as more stable as possible.

Collapse
 
manutopik profile image
Emmanuel Salomon

Should be a killer combo with tailwindcss!
I'm wondering if it's easy to convert from Buefy to Oruga. Anyone did it?

Collapse
 
jtommy profile image
Walter Tommasi • Edited

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.

Collapse
 
n3m3s7s profile image
Fabio Politi

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!

Collapse
 
astagi profile image
Andrea Stagi

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....