Skip to content

Commit 59bc860

Browse files
committed
chore(storybook): move storybook files to @vuetify namespace.
1 parent 126e8a2 commit 59bc860

File tree

14 files changed

+339
-0
lines changed

14 files changed

+339
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const fs = require('fs')
2+
3+
module.exports = api => {
4+
api.render('./template')
5+
6+
api.extendPackage({
7+
scripts: {
8+
'serve:storybook': 'start-storybook -p 6006',
9+
'build:storybook': 'build-storybook',
10+
},
11+
devDependencies: {
12+
'@babel/preset-react': '^7.6.3',
13+
'@mdi/font': '^4.5.95',
14+
'@storybook/addon-a11y': '^5.2',
15+
'@storybook/addon-actions': '^5.2',
16+
'@storybook/addon-knobs': '^5.2',
17+
'@storybook/addon-notes': '^5.2',
18+
'@storybook/addon-viewport': '^5.2',
19+
'@storybook/addons': '^5.2',
20+
'@storybook/vue': '^5.2',
21+
'babel-preset-vue': '^2.0.2',
22+
'prism-react-renderer': '^0.1.7',
23+
'js-beautify': '^1.11.0',
24+
prismjs: '^1.17.1',
25+
'vue-storybook': '^1.1.0',
26+
},
27+
})
28+
29+
api.onCreateComplete(() => {
30+
const path = api.resolve('./babel.config.js')
31+
const config = fs.existsSync(path) ? require(path) : {}
32+
33+
config.presets = config.presets || []
34+
35+
// Add presets to config
36+
for (let preset of ['env', 'react']) {
37+
preset = `@babel/preset-${preset}`
38+
39+
if (config.presets.includes(preset)) continue
40+
41+
config.presets.push(preset)
42+
}
43+
44+
fs.writeFileSync(path, api.genJSConfig(config))
45+
})
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Utilities
2+
import addons, { makeDecorator } from '@storybook/addons'
3+
import beautify from 'js-beautify'
4+
import { EVENT_ID } from './register'
5+
6+
const withTemplate = makeDecorator({
7+
name: 'withTemplate',
8+
wrapper: (storyFn, context) => {
9+
const story = storyFn(context)
10+
11+
const template = story.options &&
12+
story.options.STORYBOOK_WRAPS &&
13+
story.options.STORYBOOK_WRAPS.options &&
14+
(story.options.STORYBOOK_WRAPS.options.template || null)
15+
16+
const channel = addons.getChannel()
17+
channel.emit(EVENT_ID, { markup: beautify.html(template, { indent_size: 2 }) })
18+
19+
return story
20+
},
21+
})
22+
23+
export default withTemplate
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import withTemplate from './decorator'
2+
3+
export { withTemplate }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { createElement } from 'react'
2+
import Highlight, { defaultProps } from 'prism-react-renderer'
3+
import './styles.css'
4+
5+
import addons, { types } from '@storybook/addons'
6+
7+
const ADDON_ID = 'show-vue-markup'
8+
const PANEL_ID = `${ADDON_ID}/panel`
9+
export const EVENT_ID = `${ADDON_ID}/markup`
10+
11+
class MarkupPanel extends React.Component {
12+
state = { markup: '' }
13+
14+
componentDidMount () {
15+
const { channel } = this.props
16+
17+
channel.on(EVENT_ID, this.onStoryChange)
18+
}
19+
20+
componentWillUnmount () {
21+
const { channel } = this.props
22+
23+
channel.off(EVENT_ID, this.onStoryChange)
24+
}
25+
26+
onStoryChange = ({ markup }) => {
27+
this.setState({ markup })
28+
}
29+
30+
render () {
31+
const { markup } = this.state
32+
const { active } = this.props
33+
34+
return active ? createElement(Highlight, {
35+
...defaultProps,
36+
code: markup,
37+
language: 'html',
38+
children: ({ className, style, tokens, getLineProps, getTokenProps }) => {
39+
return createElement('pre', {
40+
className,
41+
style,
42+
}, tokens.map((line, i) => createElement('div', {
43+
...getLineProps({ line, key: i }),
44+
}, line.map((token, key) => createElement('span', {
45+
...getTokenProps({ token, key }),
46+
})))))
47+
},
48+
}) : null
49+
}
50+
}
51+
52+
addons.register(ADDON_ID, () => {
53+
const channel = addons.getChannel()
54+
55+
addons.add(PANEL_ID, {
56+
type: types.PANEL,
57+
title: 'Markup',
58+
render: ({ active, key }) => createElement(MarkupPanel, { active, key, channel }),
59+
})
60+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pre.prism-code {
2+
font-size: 18px;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Imports
2+
import Vue from 'vue'
3+
import Vuetify from 'vuetify'
4+
import { makeDecorator } from '@storybook/addons'
5+
6+
// Utilities
7+
import deepmerge from 'deepmerge'
8+
9+
// Vuetify
10+
import 'vuetify/dist/vuetify.min.css'
11+
import '@mdi/font/css/materialdesignicons.min.css'
12+
13+
Vue.use(Vuetify)
14+
15+
export default makeDecorator({
16+
name: 'withVuetify',
17+
parameterName: 'vuetify',
18+
wrapper: (storyFn, context, { parameters = {} }) => {
19+
// Reduce to one new URL?
20+
const searchParams = new URL(window.location).searchParams
21+
const dark = searchParams.get('eyes-variation') === 'dark'
22+
const rtl = searchParams.get('eyes-variation') === 'rtl'
23+
const vuetify = new Vuetify(deepmerge({
24+
rtl,
25+
theme: { dark },
26+
}, parameters))
27+
const WrappedComponent = storyFn(context)
28+
29+
return Vue.extend({
30+
vuetify,
31+
components: { WrappedComponent },
32+
template: `
33+
<v-app>
34+
<v-container fluid>
35+
<wrapped-component />
36+
</v-container>
37+
</v-app>
38+
`,
39+
})
40+
},
41+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import withVuetify from './decorator'
2+
3+
export { withVuetify }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import './addon-show-vue-markup/register'
2+
import '@storybook/addon-knobs/register'
3+
import '@storybook/addon-actions/register'
4+
import '@storybook/addon-notes/register'
5+
import '@storybook/addon-a11y/register'
6+
import '@storybook/addon-viewport/register'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Imports
2+
import { configure, addDecorator } from '@storybook/vue'
3+
import { withA11y } from '@storybook/addon-a11y'
4+
import { withKnobs } from '@storybook/addon-knobs'
5+
import { withTemplate } from '~storybook/addon-show-vue-markup'
6+
import { withVuetify } from '~storybook/addon-vuetify'
7+
8+
addDecorator(withA11y)
9+
addDecorator(withKnobs)
10+
addDecorator(withTemplate)
11+
addDecorator(withVuetify)
12+
13+
configure(require.context('./stories', true, /\.stories\.js$/), module)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Utilities
2+
import { storyFactory } from '../util/helpers'
3+
import { text, boolean } from '@storybook/addon-knobs'
4+
5+
export default { title: 'BaseCard' }
6+
7+
function genComponent (name) {
8+
return {
9+
name,
10+
11+
render (h) {
12+
return h('div', this.$slots.default)
13+
},
14+
}
15+
}
16+
17+
const story = storyFactory({
18+
BaseBtn: genComponent('BaseBtn'),
19+
BaseCard: genComponent('BaseCard'),
20+
})
21+
22+
export const asDefault = () => story({
23+
props: {
24+
actions: {
25+
default: boolean('Actions', false),
26+
},
27+
cardText: {
28+
default: text('Card text', 'Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Donec sodales sagittis magna. Vestibulum dapibus nunc ac augue. Donec sodales sagittis magna. Duis vel nibh at velit scelerisque suscipit.'),
29+
},
30+
divider: {
31+
default: boolean('Divider', false),
32+
},
33+
text: {
34+
default: boolean('Text', true),
35+
},
36+
title: {
37+
default: boolean('Show title', true),
38+
},
39+
titleText: {
40+
default: text('Title text', 'Card title'),
41+
},
42+
},
43+
template: `
44+
<base-card>
45+
<v-card-title v-if="title">{{ titleText }}</v-card-title>
46+
47+
<v-card-text v-if="text">{{ cardText }}</v-card-text>
48+
49+
<v-divider v-if="divider"></v-divider>
50+
51+
<v-card-actions v-if="actions">
52+
<v-btn text>Cancel</v-btn>
53+
54+
<v-spacer></v-spacer>
55+
56+
<base-btn depressed>Accept</base-btn>
57+
</v-card-actions>
58+
</base-card>
59+
`,
60+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Returns a function to generate stories
2+
export const storyFactory = (components) => {
3+
return opts => {
4+
// If user supplied a string,
5+
// create an object with it
6+
if (typeof opts === 'string') {
7+
opts = { template: opts }
8+
}
9+
10+
return {
11+
components,
12+
...opts,
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const path = require('path')
2+
3+
module.exports = async ({ config }) => {
4+
config.resolve.alias['~storybook'] = path.resolve(__dirname)
5+
6+
config.module.rules.push({
7+
resourceQuery: /blockType=story/,
8+
loader: 'vue-storybook',
9+
})
10+
11+
config.module.rules.push({
12+
test: /\.s(a|c)ss$/,
13+
use: ['style-loader', 'css-loader', 'sass-loader'],
14+
include: path.resolve(__dirname, '../'),
15+
})
16+
17+
return config
18+
}

packages/@vuetify/storybook/index.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// const fs = require('fs')
2+
// const path = require('path')
3+
// const kebabCase = require('lodash/kebabCase')
4+
5+
module.exports = api => {
6+
// if (!api.hasPlugin('vuetify-cli')) return
7+
8+
// const component = api.service.commands['make:component']
9+
10+
// // If user removed or modified
11+
// // the script to a new name.
12+
// if (!component) return
13+
14+
// const serveFn = component.fn
15+
16+
// component.fn = async (...args) => {
17+
// const { name, rootDir, type } = await serveFn(...args)
18+
// let file
19+
20+
// if (type.indexOf('../') === 0) {
21+
// const split = type.split('/')
22+
23+
// split.shift()
24+
25+
// file = `${split.join('/')}${name}`
26+
// } else {
27+
// file = `components/${type ? `${type}/` : ''}${name}/${name}`
28+
// }
29+
30+
// const template =
31+
// fs.readFileSync(path.resolve(__dirname, './generator/template/template.stories.js'), 'utf-8')
32+
// .replace(/ComponentName/g, name)
33+
// .replace(/ComponentPath/g, file)
34+
// .replace(/component-template/g, kebabCase(name))
35+
36+
// const dirName = kebabCase(name)
37+
38+
// fs.writeFileSync(`${rootDir}/.storybook/stories/${dirName}.stories.js`, template, 'utf-8')
39+
// }
40+
}

packages/@vuetify/storybook/yarn.lock

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
lodash@^4.17.15:
6+
version "4.17.15"
7+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
8+
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==

0 commit comments

Comments
 (0)