Oruga - UI components library without CSS framework dependency
Tags: vue, ux, css, javascript
Published: 2020-07-20 16:15:32

During my work on [Buefy](https://buefy.org) (thanks to all community :wink:) I realized that to be bounded to a CSS Framework might be limiting for a UI components library that it isn't only a simple wrapper. Then I tried to use the current codebase in some way to be CSS frameworkless and so was born the idea called Oruga :tada:

[Oruga](https://oruga.io) is a lightweight library of UI components for Vue.js without CSS framework dependency.

> Oruga UI is like a caterpillar, minimal and yet functional. It's in your hands turning it into a butterfly (🐛) => 🦋

Nice, but what does it mean? :open_mouth:

The main idea behind Oruga is to be a UI components library CSS framework agnostic. It doesn't depend on Bootstrap, Bulma,  Material, TailwindCSS, etc but it offers an easy way to integrate with one of them.

All components are individually importable (tree shaking) and they aren't a simple wrapper of native elements but they add new and custom features.

Oruga allows to customize a component in 4 different ways:

* using CSS variables
* using SASS/SCSS variables
* adding new classes on the base theme or oruga-lite theme
* overriding all classes

but you can mix them, for example adding new classes and using CSS variables!

In the following examples, I'll show you how to customize the component **o-dropdown** in 3 different ways without losing any functional features of the component itself.

#CSS Variables

It is a very simple way to customize the default style of a component by CSS stylesheet or dynamically by Javascript.

```css
<style>
:root {
  --oruga-dropdown-menu-width: 300px;
  --oruga-dropdown-menu-box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1),
    0 0 0 1px rgba(10, 10, 10, 0.02);
}
</style>
```

{% codesandbox oruga-css-var-0kibe %}

All dropdown variables are listed [here](https://oruga.io/components/dropdown.html#style).

#SASS/SCSS Variables

It allows making static themes choosing the default values of style attributes for each component and to customize the final CSS bundle with all Oruga features (css-vars, css-vars prefix name, whitelist, etc.)

The base config is available [here](https://oruga.io/components/#base-style)

#Adding new classes (+ oruga-lite)

Oruga offers a minimal style that tries to cover the style of a single component but sometimes might be not easy add/override a default style; for this reason, you can import *oruga-lite.css*, a lite stylesheet that doesn't contain any styles attributes (background, color, padding, width, etc).

The example shows the integration between Oruga and [TailwindCSS](https://tailwindcss.com/).

Note: *the example uses TailwindCSS because of its popularity but it works with custom classes (own company design system) or other CSS frameworks/libraries.*
Note 2: *All single classes (bg-blue, text-white, ...) could be wrapped into a one custom class for each component prop, it was only an example choice*

```javascript
import Oruga from "@oruga-ui/oruga";
import "@oruga-ui/oruga/dist/oruga-lite.css";

Vue.use(Oruga, {
  // ...
  dropdown: {
    menuClass: "m-0 bg-white shadow-lg min-w-0  rounded-sm",
    backgroundClass: "bg-gray-900 bg-opacity-75",
    itemClass: "px-2 py-2",
    itemActiveClass: "bg-blue-500 text-white"
  },
  // ...
});
```

{% codesandbox oruga-lite-tailwindcss-59j1n %}

As you can see the mobile feature (*dropdown content (items) are shown into a modal on mobile*) is always available and it follows the custom style added.

In alternative, you can add a custom style to a single component instance, for example:

```html
<o-dropdown menu-class="m-0 bg-white shadow-lg min-w-0  rounded-sm" ...> ...
  <o-dropdown-item item-class="px-2 py-2">...</o-dropdown-item>
</o-dropdown>
```

#Overriding 

In this case, you have full power and you can customize all parts of the component (of course it's about what Oruga allows :smiley:)

Setting the field `override` to true, the component won't use any default classes but it will apply all custom classes defined as below:

```javascript
import Oruga from "@oruga-ui/oruga";

Vue.use(Oruga, {
  // ...
  dropdown: {
    override: true,
    rootClass: "inline-flex relative",
    menuClass:
      "tail-dropdown-menu m-0 bg-white shadow-lg min-w-0 rounded-sm",
    backgroundClass: "tail-dropdown-background",
    itemClass: "relative block no-underline cursor-pointer px-2 py-2",
    itemActiveClass: "bg-blue-500 text-white",
    mobileClass: "tail-dropdown-mobile"
  },
  // ...
});
```

{% codesandbox oruga-tailwindcss-zct93 %}

Here we have the same result as above but looking in the code the added classes are not about styles (background, color) but they must provide the structural style attributes (position, display, etc). 
For example, I had to add `tail-dropdown-menu` to `menu-class` field in order to show the dropdown menu in the correct position of the window and relative to the trigger button.

```css
.tail-dropdown-menu {
  top: 100%;
  min-width: 12em;
  position: absolute;
  left: 0;
}
```

It's better to evaluate to use oruga-lite stylesheet before in order to really take care only of pure style part; anyway, all depend on project/ui needs.

If you’re interested and you don't want to write new components (simple and complex) from scratch it could be a good idea give a try to Oruga :wink: