Back to blog

Vuetify in Storybook

Get the most out of Vuetify in Storybook with out of the box Vite support

loading
Shaun Evening
โ€” @Integrayshaun
Last updated:
โš ๏ธ
A few things have changed since the full release of Storybook 7.0. For a more up-to-date guide to integrating Vuetify in Storybook, check out our recipe in the integration catalog

App design can be complex, with many options for fonts, typography, spacing and colors. Vuetify simplifies this by offering pre-designed themeable components for a cohesive look, based on Google's Material Design guidelines.

Storybook is a frontend workbench for building UIs in isolation. By combining Storybook and Vuetify, you can build UIs faster without all the grunt work. As of Storybook 7.0, this is even easier with out of the box Vite support. This post will show you how to integrate these two tools to create a powerful and flexible development environment for building user interfaces with Vuetify.

In this post, we will explain how to

  • ๐Ÿ”Œ Setup Vuetify with Storybook
  • ๐Ÿงฑ Use Vuetify in your components
  • ๐ŸŽจ Switch Vuetify themes in a click

If youโ€™d like to see the example code of this recipe, check out the example repository on GitHub. Let's get started!

A completed example of Vuetify working in Storybook with a theme switcher

Register Vuetify in Storybook

To get started, you'll need to add Vuetifyโ€™s fontloader and plugin to your Storybook configuration. To do this, add the following to your .storybook/preview.js file:

// .storybook/preview.js
import { setup } from "@storybook/vue3";
import { registerPlugins } from "../src/plugins";

setup((app) => {
  // Registers your app's plugins into Storybook
  registerPlugins(app);
});

Here registerPlugins loads Vuetifyโ€™s fonts and registers all of its components with Storybookโ€™s Vue app.

Using Vuetify Components

Letโ€™s update some of our example components to use Vuetify instead. Weโ€™ll use the Button component in ./src/stories/button.vue.

The storybook example button story

Currently, itโ€™s not looking very Vuetiful so letโ€™s make some changes. Replace the contents of ./src/stories/Button.vue with the following code:

<template>
  <v-btn type="button" color="primary" @click="onClick" :variant="variant" :size="size">{{ label }}</v-btn>
</template>

<script>
  import { reactive, computed } from 'vue';

  export default {
    name: 'my-button',
    props: {
      label: {
        type: String,
        required: true,
      },
      primary: {
        type: Boolean,
        default: false,
      },
      size: {
        type: String,
        validator: function (value) {
          return ['small', 'large'].indexOf(value) !== -1;
        },
      },
      backgroundColor: {
        type: String,
      },
    },
    emits: ['click'],
    setup(props, { emit }) {
      props = reactive(props);
      return {
        onClick() {
          emit('click');
        },
        variant: computed(() => props.primary ? 'flat' : 'outlined'),
      }
    },
  };
</script>

Now looking back at Storybook, our button is now the Vuetify button. It even changed in the page-level stories.

Updating the button component to use the Vuetify button and seeing the button update in Storybook

Add a theme switcher tool using globalTypes

Vuetify comes out of the box with a light and dark theme but you can override them and add more. To get the most out of your stories, you should have a way to toggle between all of your themes.

Switching from Vuetify's light theme to dark theme using a Storybook theme switcher

To add a theme switcher, declare a global variable named theme in .storybook/preview.js and give it a list of supported themes to choose from.

// .storybook/preview.js
export const globalTypes = {
  theme: {
    name: "Theme",
    description: "Global theme for components",
    toolbar: {
      icon: "paintbrush",
      // Array of plain string values or MenuItem shape (see below)
      items: [
        { value: "light", title: "Light", left: "๐ŸŒž" },
        { value: "dark", title: "Dark", left: "๐ŸŒ›" },
      ],
      // Change title based on selected value
      dynamicTitle: true,
    },
  },
};

This code will create a new toolbar dropdown to select your desired theme for your stories.

Add a withVuetifyTheme decorator

There needs to be a way to tell Vuetify to use the theme selected in the toolbar. This can be done using a decorator.

Below I created a new file in .storybook called withVuetifyTheme.decorator.js that will take our global theme value and update Vuetifyโ€™s current theme.

// .storybook/withVeutifyTheme.decorator.js
import { useTheme } from "vuetify";

export const DEFAULT_THEME = "light";

export const withVuetifyTheme = (story, context) => {
  const globalTheme = context.globals.theme || DEFAULT_THEME;

  return {
    components: { story },
    setup() {
      const theme = useTheme();

      theme.global.name.value = globalTheme;

      return {
        theme,
      };
    },
    template: `<story />`,
  };
};

Now give this decorator to Storybook to wrap our stories in. To do this, add the decorator to the decorator array in .storybook/preview.js

// .storybook/preview.js
import { setup } from "@storybook/vue3";
import { registerPlugins } from "../src/plugins";
import { withVuetifyTheme } from "./withVuetifyTheme.decorator";

setup((app) => {
  // Registers your app's plugins into Storybook
  registerPlugins(app);
});

/* snipped for brevity */

export const decorators = [withVuetifyTheme];

Wrapping up

Vuetify offers a large collection of readymade Material Design components to make building Vuetiful UIs a breeze. In just a few steps, you can setup Vuetify in Storybook to create a powerful development environment.

Get involved

If you use Vuetify at work, we'd love your help making an addon that automatically applies the configuration above. Join the maintainers in Discord to get involved, or jump into addon docs.

Join the Storybook mailing list

Get the latest news, updates and releases

6,655 developers and counting

Weโ€™re hiring!

Join the team behind Storybook and Chromatic. Build tools that are used in production by 100s of thousands of developers. Remote-first.

View jobs

Popular posts

Component Story Format 3 is here

Next gen story format to make you more productive
loading
Michael Shilman

Improved type safety in Storybook 7

CSF3 syntax combined with TypeScript satisfies gives you stricter types and an improved developer experience
loading
Kasper Peulen

Storybook Ecosystem CI

Protecting Storybook users from package upgrade headaches
loading
Michael Shilman
Join the community
6,655 developers and counting
WhyWhy StorybookComponent-driven UI
DocsGuidesTutorialsChangelogTelemetry
CommunityAddonsGet involvedBlog
ShowcaseExploreProjectsComponent glossary
Open source software
Storybook

Maintained by
Chromatic
Special thanks to Netlify and CircleCI