Theming

All components created with VueTypescript can be customized using the theming system. This not only allows you to customize the styles, but also the value of the props. All of it being dynamic, so you can add or modify your themes at runtime, dynamically.

Overview

The theming of a component works in two phases:

  1. the component exposes css variables and props,
  2. the end user define themes and variants, each containing a set of overrides of what is exposed,
  3. when the component is used, every variant matching its current state will apply its overrides.

By default, when you create a component, the theming is disabled. To enable it, add @Themeable decorator on the class:

import { Component, Themeable } from "@banquette/vue-typescript";

@Themeable()
@Component()
class MyComponent {

}

The theme then opens the ability for the user to mutate the component on:

  • the styles by overriding css variables or by adding custom rules,
  • the props by replacing the default value defined in the component.

TIP

All the options of @Themeable are discussed in depth in the dedicated section.


Then, with the component "themeable", you can define a theme using the VueThemes class. It's a static class that you can use anywhere in your project:

import { VueThemes } from "@banquette/vue-typescript";
import { ThemeWildcard } from "@banquette/vue-typescript/theme/constant";

// We define a theme for all components named "my-component".
VueThemes.Define('my-component', {
    // The key is the name of the theme for which we will define variants. 
    '*': [
        // Then we define a list of variants, each having a "match" selector
        // and a set of rules to apply.
        {
            match: 'danger',
            cssVars: {
                backgroundColor: 'red'
            }
        }
    ],
    dark: [
        ...
    ]
});

Then the variants will apply depending on the current theme and on the state of the component:

<my-component>I'm NOT red</my-component>
<my-component variant="red">I'm red!</my-component>

TIP

The theme or its variants can be created and mutated whenever you want, the components will change in real time automatically.

Basic example

Let's take an example with a button on which we want to customize the background color.

First we create the component:

    Everything is static for the moment. To make the background configurable, we have to make several changes:

    1) Create a variable for the color

    button {
        [...]
        background: var(--bg-color, #1a87d1);
    }
    

    2) Expose it to the outside world

    // We make the component customizable.
    @Themeable({
        css: {
            vars: {
                // "backgroundColor" is the name of the variable for the outside.
                backgroundColor: 'bg-color'
            }
        }
    })
    @Component('my-button')
    export default class Button {
    }
    

    3) We bind the theme with the template

    <button v-bt-bind-theme>
        <slot></slot>
    </button>
    

    WARNING

    This directive is part of VueTypescript and is mandatory for the theming to work. You should always put it on the root element of your template.

    This is required so the attributes that condition the theme's css rules can be assigned before the component is rendered. This way there is no frame rendered without the theme being applied.

    Then, after adding a red theme (that you can see in the Theme.ts tab below), here is the result: