arielsalminen / vue-design-system

An open source tool for building UI Design Systems with Vue.js
https://vueds.com
MIT License
2.17k stars 223 forks source link

Request for Documentation: Option to build a Vue Design System upon Vuetify/existing framework #187

Open barclayd opened 5 years ago

barclayd commented 5 years ago

Thank you for this brilliant Vue Design System.

Being keen to create a Design System upon modification of Vuetify components, I followed this thread to gain an understanding as to whether it was possible/how to achieve it: https://github.com/viljamis/vue-design-system/issues/102

After a few hours of tinkering, it became clear that Vuetify could be implemented exceedingly easily within the Design System by modifying:

  1. docs/docs.helper.js (to wrap the documentation)
/**
 * This is Vue Design System’s JS helper file for docs.
 * You can add more things if/when needed.
 */
import Vue from 'vue';
import Vuetify from 'vuetify';
import statusLabels from './utils/statusLabels';
import activeNav from './utils/activeNav';
import filterSearch from './utils/filterSearch';
import 'codemirror/mode/jsx/jsx';
import 'vuetify/dist/vuetify.min.css';

Vue.config.productionTip = false;
Vue.mixin(statusLabels);
Vue.use(Vuetify, {
  theme: {
    primary: '#5656ca',
    secondary: '#424242',
    accent: '#82B1FF',
    error: '#FF5252',
    info: '#2196F3',
    success: '#4CAF50',
    warning: '#FFC107',
  },
});

document.addEventListener('DOMContentLoaded', () => {
  filterSearch.methods.init();
  activeNav.methods.init();
});

window.addEventListener('hashchange', () => {
  filterSearch.methods.init();
  activeNav.methods.init();
});
  1. src/main.js (to wrap template)
// Vue Design System: The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import App from '@/App';
import router from '@/router';
import Meta from 'vue-meta';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';

// Vue Design System: Auto importing components globally
import DesignSystem from '@/system';

Vue.use(Vuetify);
Vue.use(DesignSystem);
Vue.use(Meta);

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
});

I think this is quite a common issue and so documentation on supporting Vuetify will no doubt help save a lot of time for others interested in achieving something similar.

Thank you @viljamis for all your hard work on this brilliant project!

barclayd commented 5 years ago

In addition to this, in order to complete the set up for Vuetify, Material Icons and Roboto Google font should be included as links in the header of both the docs.config.js and also the index.html like so:

  1. config/docs.config.js
const path = require('path');
const baseConfig = require('../build/webpack.base.conf.js');
const merge = require('webpack-merge');
const packageConfig = require('../package.json');
const chalk = require('chalk');
const vueLoader = require('vue-loader');

module.exports = {
  /**
   * Name of your design system. Changes both page title and sidebar logo.
   */
  title: 'Vue Design System',
  /**
   * Most of the styles are defined in /docs/docs.styles.scss
   */
  version: packageConfig.version,
  theme: {
    maxWidth: '100%',
    sidebarWidth: 240,
    fontFamily: {
      base: ["'Roboto'", 'Helvetica', 'Arial', 'sans-serif'],
      monospace: ['Consolas', "'Liberation Mono'", 'Menlo', 'monospace'],
    },
  },
  renderRootJsx: path.join(__dirname, '../docs/components/Preview.js'),
  /**
   * Define a custom code highlighting theme.
   */
  editorConfig: {
    theme: 'night',
  },
  /**
   * Path to static assets directory
   */
  assetsDir: path.join(__dirname, '../src/assets'),
  /**
   * Enabling the below option will break things in Vue Design System!
   */
  skipComponentsWithoutExample: false,
  /**
   * We’re defining below JS and SCSS requires for the documentation.
   */
  require: [
    path.join(__dirname, '../docs/docs.helper.js'),
    path.join(__dirname, '../docs/docs.styles.scss'),
  ],
  /**
   * Enabling the following option splits sections into separate views.
   */
  pagePerSection: true,
  sections: [
    {
      name: 'Getting Started',
      content: '../docs/getting-started.md',
      // Needs to be loaded in somewhere as this is also shown in
      // element, Pattern & Template overviews.
      components: '../docs/components/status/**/[A-Z]*.vue',
      sectionDepth: 1,
      exampleMode: 'hide',
      usageMode: 'hide',
    },
    {
      name: 'Design Principles',
      content: '../docs/principles.md',
      sectionDepth: 1,
      exampleMode: 'hide',
      usageMode: 'hide',
    },
    {
      name: 'Voice & Tone',
      content: '../docs/voice-and-tone.md',
      sectionDepth: 1,
      exampleMode: 'hide',
      usageMode: 'hide',
    },
    {
      name: 'Design Tokens',
      content: '../docs/tokens.md',
      sectionDepth: 1,
      exampleMode: 'hide',
      usageMode: 'hide',
      components: () => [
        '../docs/components/tokens/Color.vue',
        '../docs/components/tokens/FontSize.vue',
        '../docs/components/tokens/Spacing.vue',
        '../docs/components/tokens/All.vue',
      ],
    },
    {
      name: 'Elements',
      content: '../docs/elements.md',
      components: '../src/elements/**/[A-Z]*.vue',
      exampleMode: 'expand',
      usageMode: 'expand',
      sectionDepth: 2,
    },
    {
      name: 'Patterns',
      content: '../docs/patterns.md',
      components: '../src/patterns/**/[A-Z]*.vue',
      exampleMode: 'expand',
      usageMode: 'expand',
      sectionDepth: 2,
    },
    {
      name: 'Templates',
      content: '../docs/templates.md',
      components: '../src/templates/**/[A-Z]*.vue',
      exampleMode: 'expand',
      usageMode: 'expand',
      sectionDepth: 2,
    },
    {
      name: 'Downloads',
      content: '../docs/downloads.md',
      exampleMode: 'hide',
      usageMode: 'hide',
      sectionDepth: 1,
    },
    {
      name: 'FAQ',
      content: '../docs/faq.md',
      exampleMode: 'hide',
      usageMode: 'hide',
      sectionDepth: 1,
    },
    {
      /**
       * Private components have to be loaded into the documentation as well,
       * otherwise anything using them will be broken. We’re loading them in
       * their own section, which then gets hidden in docs/docs.styles.scss
       */
      name: 'Private Components',
      exampleMode: 'hide',
      usageMode: 'hide',
      components: '../src/**/[_]*.vue',
    },
  ],
  /**
   * Custom wrapper template for the documentation.
   */
  template: {
    title: 'Example — Vue Design System',
    lang: 'en',
    trimWhitespace: true,
    head: {
      links: [
        {
          href:
            'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700',
          rel: 'stylesheet',
        },
        {
          href: 'https://fonts.googleapis.com/icon?family=Material+Icons',
          rel: 'stylesheet',
        },
      ],
      meta: [
        {
          name: 'viewport',
          content: 'width=device-width,initial-scale=1.0',
        },
        {
          name: 'format-detection',
          content: 'telephone=no',
        },
      ],
    },
  },
  /**
   * Ignore app.vue, tests, and example component.
   */
  ignore: [
    '**/App.vue',
    '**/__tests__/**',
    '**/*.test.js',
    '**/*.test.jsx',
    '**/*.spec.js',
    '**/*.spec.jsx',
    '**/ExampleComponent.vue',
  ],
  webpackConfig: merge(baseConfig, {
    module: {
      rules: [
        {
          test: /\.(css?|scss|sass)(\?.*)?$/,
          use: [
            'style-loader',
            'css-loader',
            'postcss-loader',
            'sass-loader',
            {
              loader: 'sass-resources-loader',
              options: {
                resources: [
                  path.join(__dirname, '../src/assets/tokens/tokens.scss'),
                  path.join(__dirname, '../src/assets/tokens/tokens.map.scss'),
                  path.join(__dirname, '../src/styles/styles.scss'),
                ],
              },
            },
          ],
        },
      ],
    },
  }),
  styleguideDir: '../dist/docs',
  printServerInstructions() {},
  printBuildInstructions(config) {
    console.log(
      chalk.cyan('\n  Design System Docs build finished succesfully!\n'),
    );
    console.log(
      chalk.yellow(
        '  Tip: You can now deploy the docs as a static website.\n' +
          '  Copy the build files from ' +
          `${config.styleguideDir}\n`,
      ),
    );
  },
  usageMode: 'expand',
  exampleMode: 'expand',
  styleguideDir: 'dist',
  ribbon: {
    text: 'Back to examples',
    url: 'https://vue-styleguidist.github.io/Examples.html',
  },
  /**
   * Configure docs server to redirect asset queries
   */
  // configureServer(app) {
  //   // `app` is the instance of the express server running the docs
  //   app.get("/assets/:file", (req, res) => {
  //     res.redirect(req.params.file)
  //   })
  // },
};
  1. index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>Vue Design System</title>
    <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/icon?family=Material+Icons"
    />
    <link
            href="https://fonts.googleapis.com/css?family=Roboto:400,400i,500,500i,700,900,900i&display=swap"
            rel="stylesheet"
    />
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

And that should be everything needed to set up VDS with Vuetify 😊

nicovanzyl commented 5 years ago

@barclayd Nice! This will make a great Medium post (or blog post if you have a personal blog).

barclayd commented 5 years ago

Thanks @nicovanzyl, that's a great idea 😊

escael commented 4 years ago

Hi @barclayd , it works perfectly for me, but I can't get the theme to load. Do you have a repository with a functional example? Thank you