Search code examples
javascriptwebpackstorybook

How to customize theme in Vuetify using Storybook 6?


I want to customize themes in Vuetify using Storybook 6 and I am using @socheatsok78/storybook-addon-vuetify package https://storybook.js.org/addons/@socheatsok78/storybook-addon-vuetify

I did exactly what documentation says but theme is still not working at all. I want to configure vuetify with custom properties and with my own color palette.

preview.js

import '!style-loader!css-loader!sass-loader!./main.scss';
import {
  withVuetify,
  withThemeProvider,
} from '@socheatsok78/storybook-addon-vuetify/dist/decorators';
import minifyTheme from 'minify-css-string';

export const globalTypes = {
  theme: {
    dark: false,
    options: {
      customProperties: true,
      minifyTheme,
    },
    themes: {
      light: {
        primary: '#007BBF',
        secondary: '#008574',
      },
      dark: {
        primary: '#f099aa',
      },
    },
  },
};

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};

export const decorators = [withThemeProvider, withVuetify];

main.js

const path = require('path');

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-docs',
    '@storybook/addon-essentials',
    '@storybook/preset-scss',
    '@socheatsok78/storybook-addon-vuetify',
  ],
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader',
        {
          loader: 'sass-resources-loader',
          options: {
            resources: path.resolve(__dirname, 'main.scss'),
          },
        },
      ],
      sideEffects: true,
      include: path.resolve(__dirname, '../'),
    });
    return config;
  },
};

Solution

  • Ok I fixed the theme, you can find an tutorial how to do this and with all working code down below. I found a great explanation here:

    https://morphatic.com/2020/09/30/configuring-storybook-6-for-vue-2-vuetify-2-3/

    preview.html

    import '!style-loader!css-loader!sass-loader!./main.scss';
    import { withVuetify } from '@socheatsok78/storybook-addon-vuetify/dist/decorators';
    import vuetify from './vuetify';
    
    import Vue from 'vue';
    
    export const parameters = {
      actions: { argTypesRegex: '^on[A-Z].*' },
      controls: {
        matchers: {
          color: /(background|color)$/i,
          date: /Date$/,
        },
      },
    };
    
    export const decorators = [
      (story, context) => {
        const wrapped = story(context);
    
        return Vue.extend({
          vuetify,
          components: { wrapped },
          template: `
            <v-app>
              <v-container fluid>
                <wrapped/>
              </v-container>
            </v-app>
        `,
        });
      },
      withVuetify,
    ];
    

    main.js

    I removed one line from addons

    '@socheatsok78/storybook-addon-vuetify',

    vuetify.js

    import Vue from 'vue';
    import Vuetify from 'vuetify';
    import minifyTheme from 'minify-css-string';
    import theme from './theme';
    import LRU from 'lru-cache';
    
    const themeCache = new LRU({
      max: 10,
      maxAge: 1000 * 60 * 60, // 1 hour
    });
    
    Vue.use(Vuetify);
    
    export default new Vuetify({
      theme: {
        options: {
          customProperties: true,
          minifyTheme,
          themeCache,
        },
        themes: {
          light: theme,
        },
      },
    });
    

    theme.js

    export default {
      // ... other colors
      primary: '#007BBF',
    };
    

    Theme works perfect now, only variables are not loaded correctly and I don't know how to solve this, you can read about it in the article comments