Merge pull request #2773 from husayt/patch-1

initial version of storybook+nuxt demo
This commit is contained in:
Sébastien Chopin 2018-02-06 12:29:11 +01:00 committed by GitHub
commit fcd3f06767
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1257 additions and 0 deletions

View File

@ -0,0 +1,5 @@
import '@storybook/addon-knobs/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-viewport/register';

View File

@ -0,0 +1,24 @@
import "vuetify/dist/vuetify.css";
import { configure } from "@storybook/vue";
import Vue from "vue";
import Vuex from "vuex";
import Vuetify from "vuetify";
import MyButton from "../components/Button.vue";
Vue.use(Vuex);
Vue.use(Vuetify);
Vue.component("my-button", MyButton);
//function loadStories() {
// require("../src/stories");
//}
// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /.story.js$/);
function loadStories() {
req.keys().forEach((filename) => req(filename));
}
configure(loadStories, module);

View File

@ -0,0 +1,15 @@
const webpack = require('webpack')
const path = require('path')
const nxtConf = require('../nuxt.config')
module.exports = (sBaseConfig, configType, defaultConfig) => {
const srcDir = `../${nxtConf.srcDir||''}`
const rootDir = `../${nxtConf.rootDir||''}`
Object.assign(defaultConfig.resolve.alias, {
'~~': path.resolve(__dirname, rootDir),
'~': path.resolve(__dirname, srcDir)
})
return defaultConfig
}

View File

@ -0,0 +1,10 @@
## Storybook demo for Nuxt
Deo showcasing [Storybook](https://storybook.js.org/) usage with Nuxt.js, [Vuetify](https://vuetifyjs.com) and [Vue-Charts](http://vue-chartjs.org/)
### Features
* supports '~' and '~~' Nuxt.js aliases
* contains storybase.js with helper classes
* integrates most of addons
* real life examples with Vuetify and Vue-Charts

View File

@ -0,0 +1,30 @@
<template>
<button class="wr-button" :style="{color: color, borderColor: color}" @click="handleClick" :class="{rounded: rounded}"><slot></slot>!</button>
</template>
<script>
export default {
props: {
rounded: Boolean,
handleClick: {
default: () => () => null
},
color: {
default: '#42b983'
}
}
}
</script>
<style>
.rounded {
border-radius: 10px;
}
.wr-button {
border: 3px solid;
padding: 10px 20px;
background-color: white;
outline: none;
}
</style>

View File

@ -0,0 +1,82 @@
<template>
<v-app id="inspire" dark>
<v-navigation-drawer
clipped
fixed
v-model="drawer"
app
>
<v-list dense>
<v-list-group v-for="item in items" :value="item.active" v-bind:key="item.title">
<v-list-tile slot="item" @click="">
<v-list-tile-action>
<v-icon>{{ item.action }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action>
<v-icon v-if="item.items">keyboard_arrow_down</v-icon>
</v-list-tile-action>
</v-list-tile>
<v-list-tile v-for="subItem in item.items" v-bind:key="subItem.title" @click="">
<v-list-tile-content>
<v-list-tile-title>{{ subItem.title }}</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action>
<v-icon>{{ subItem.action }}</v-icon>
</v-list-tile-action>
</v-list-tile>
</v-list-group>
</v-list>
</v-navigation-drawer>
<v-toolbar app fixed clipped-left>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
<v-content>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
<v-flex xs12>
<v-card dark color="primary">
<v-card-text class="px-0"><slot/></v-card-text>
</v-card>
</v-flex>
</v-layout></v-container>
<v-container fluid fill-height>
<v-layout justify-center align-center>
<v-tooltip right>
<v-btn icon large :href="source" target="_blank" slot="activator">
<v-icon large>code</v-icon>
</v-btn>
<span>Source</span>
</v-tooltip>
</v-layout>
</v-container>
</v-content>
<v-footer app fixed>
<span>&copy; 2017</span>
</v-footer>
</v-app>
</template>
<script>
export default {
name: 'layout',
data: () => ({
drawer: null
}),
props: {
items: Array,
source: String
}
}
</script>
<style type="text/css">
@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons");
</style>

View File

@ -0,0 +1,9 @@
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: ['data', 'options'],
mounted() {
this.renderChart(this.data, this.options)
}
}

View File

@ -0,0 +1,79 @@
<template>
<div class="VueToNuxtLogo">
<div class="Triangle Triangle--two"></div>
<div class="Triangle Triangle--one"></div>
<div class="Triangle Triangle--three"></div>
<div class="Triangle Triangle--four"></div>
</div>
</template>
<style>
.VueToNuxtLogo {
display: inline-block;
animation: turn 2s linear forwards 1s;
transform: rotateX(180deg);
position: relative;
overflow: hidden;
height: 180px;
width: 245px;
}
.Triangle {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
.Triangle--one {
border-left: 105px solid transparent;
border-right: 105px solid transparent;
border-bottom: 180px solid #41B883;
}
.Triangle--two {
top: 30px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 87.5px solid transparent;
border-right: 87.5px solid transparent;
border-bottom: 150px solid #3B8070;
}
.Triangle--three {
top: 60px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #35495E;
}
.Triangle--four {
top: 120px;
left: 70px;
animation: godown 0.5s linear forwards 3s;
border-left: 35px solid transparent;
border-right: 35px solid transparent;
border-bottom: 60px solid #fff;
}
@keyframes turn {
100% {
transform: rotateX(0deg);
}
}
@keyframes godown {
100% {
top: 180px;
}
}
@keyframes goright {
100% {
left: 70px;
}
}
</style>

View File

@ -0,0 +1,7 @@
# COMPONENTS
**This directory is not required, you can delete it if you don't want to use it.**
The components directory contains your Vue.js Components.
_Nuxt.js doesn't supercharge these components._

View File

@ -0,0 +1,16 @@
<template>
<img class="VuetifyLogo" alt="Vuetify Logo" src="data:image/png;base64,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">
</template>
<style>
.VuetifyLogo {
width: 180px;
transform: rotateY(560deg);
animation: turn 3.5s ease-out forwards 1s;
}
@keyframes turn {
100% {
transform: rotateY(0deg);
}
}
</style>

View File

@ -0,0 +1,110 @@
<template>
<v-app>
<v-container fluid>
<div class="main">
<h1>Welcome to STORYBOOK</h1>
<p>
This is a UI component dev environment for your app.
</p>
<p>The repo for this project exists here
<a class="link"
href="https://github.com/white-rabbit-japan/vuetify-storyboard-boilerplate"
target="_blank"
rel="noopener noreferrer">
vuetify-storyboard-boilerplate
</a>
</p>
<p>
We've added some basic stories inside the
<code class="code">src/stories</code>
directory.
A story is a single state of one or more UI components. You can have as many stories as you want.
(Basically a story is like a visual test case.)
</p>
<p>
See these sample
<a class="link" @click.prevent="showApp" role="button" tabIndex="0">stories</a>
for a component called
<code class="code">Button</code> .
</p>
<p>
Just like that, you can add your own components as stories.
You can also edit those components and see changes right away.
(Try editing the
<code class="code">Button</code> component located at
<code class="code">src/stories/Button.js</code>.)
</p>
<p>
This is just one thing you can do with Storybook.
Have a look at the
<a class="link" href="https://github.com/storybooks/storybook" target="_blank" rel="noopener noreferrer">
Storybook
</a>
repo for more information.
</p>
<p class="note">
<b>NOTE:</b>
Have a look at the
<code class="code">.storybook/webpack.config.js</code>
to add webpack loaders and plugins you are using in this project.
</p>
</div>
</v-container>
</v-app>
</template>
<script>
export default {
name: 'welcome',
props: {
showApp: {
type: Function,
default: () => console.log('Welcome to storybook!') // eslint-disable-line
}
}
}
</script>
<style>
.main {
margin: 15px;
max-width: 600px;
line-height: 1.4;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans,
sans-serif;
}
.logo {
width: 200px;
}
.link {
color: #1474f3;
text-decoration: none;
border-bottom: 1px solid #1474f3;
padding-bottom: 2px;
}
.code {
font-size: 15px;
font-weight: 600;
padding: 2px 5px;
border: 1px solid #eae9e9;
border-radius: 4px;
background-color: #f3f2f2;
color: #3a3a3a;
}
.note {
opacity: 0.5;
}
</style>

View File

@ -0,0 +1,100 @@
<template>
<v-app dark>
<v-navigation-drawer
:mini-variant="miniVariant"
:clipped="clipped"
v-model="drawer"
fixed
app
>
<v-list>
<v-list-tile
router
:to="item.to"
:key="i"
v-for="(item, i) in items"
exact
>
<v-list-tile-action>
<v-icon v-html="item.icon"></v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title v-text="item.title"></v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar fixed app :clipped-left="clipped">
<v-toolbar-side-icon @click="drawer = !drawer"></v-toolbar-side-icon>
<v-btn
icon
@click.stop="miniVariant = !miniVariant"
>
<v-icon v-html="miniVariant ? 'chevron_right' : 'chevron_left'"></v-icon>
</v-btn>
<v-btn
icon
@click.stop="clipped = !clipped"
>
<v-icon>web</v-icon>
</v-btn>
<v-btn
icon
@click.stop="fixed = !fixed"
>
<v-icon>remove</v-icon>
</v-btn>
<v-toolbar-title v-text="title"></v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
icon
@click.stop="rightDrawer = !rightDrawer"
>
<v-icon>menu</v-icon>
</v-btn>
</v-toolbar>
<v-content>
<v-container>
<nuxt />
</v-container>
</v-content>
<v-navigation-drawer
temporary
:right="right"
v-model="rightDrawer"
fixed
>
<v-list>
<v-list-tile @click.native="right = !right">
<v-list-tile-action>
<v-icon light>compare_arrows</v-icon>
</v-list-tile-action>
<v-list-tile-title>Switch drawer (click me)</v-list-tile-title>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-footer :fixed="fixed" app>
<span>&copy; 2017</span>
</v-footer>
</v-app>
</template>
<script>
export default {
data() {
return {
clipped: false,
drawer: true,
fixed: false,
items: [
{ icon: 'apps', title: 'Welcome', to: '/' },
{ icon: 'bubble_chart', title: 'Inspire', to: '/inspire' }
],
miniVariant: false,
right: true,
rightDrawer: false,
title: 'Vuetify.js'
}
}
}
</script>

View File

@ -0,0 +1,55 @@
const pkg = require('./package')
module.exports = {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: pkg.name,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' }
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#3B8070' },
/*
** Global CSS
*/
css: [
'vuetify/src/stylus/main.styl'
],
/*
** Plugins to load before mounting the App
*/
plugins: [
'@/plugins/vuetify'
],
/*
** Nuxt.js modules
*/
modules: [
],
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
}
}

View File

@ -0,0 +1,33 @@
{
"name": "storybook",
"version": "1.0.0",
"description": "sample storybook setup for nuxt",
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"precommit": "yarn run lint",
"storybook": "start-storybook -p 9001 -c .storybook",
"storybookoutput": "build-storybook -c .storybook -o .out"
},
"dependencies": {
"chart.js": "^2.7.1",
"nuxt": "latest",
"vue-chartjs": "^3.1.1",
"vuetify": "1.0.0-beta.5"
},
"devDependencies": {
"@storybook/addon-actions": "^3.4.0-alpha.7",
"@storybook/addon-centered": "^3.4.0-alpha.7",
"@storybook/addon-knobs": "^3.4.0-alpha.7",
"@storybook/addon-links": "^3.4.0-alpha.7",
"@storybook/addon-notes": "^3.4.0-alpha.7",
"@storybook/addon-storyshots": "^3.4.0-alpha.7",
"@storybook/addon-viewport": "^3.4.0-alpha.7",
"@storybook/addons": "^3.4.0-alpha.7",
"@storybook/vue": "^3.4.0-alpha.7",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1"
}
}

View File

@ -0,0 +1,43 @@
<template>
<v-layout column justify-center align-center>
<v-flex xs12 sm8 md6>
<div class="text-xs-center">
<logo/>
<vuetify-logo/>
</div>
<v-card>
<v-card-title class="headline">Welcome to the Vuetify + Nuxt.js template</v-card-title>
<v-card-text>
<p>Vuetify is a progressive Material Design component framework for Vue.js. It was designed to empower developers to create amazing applications.</p>
<p>For more information on Vuetify, check out the <a href="https://vuetifyjs.com" target="_blank">documentation</a>.</p>
<p>If you have questions, please join the official <a href="https://chat.vuetifyjs.com/" target="_blank" title="chat">discord</a>.</p>
<p>Find a bug? Report it on the github <a href="https://github.com/vuetifyjs/vuetify/issues" target="_blank" title="contribute">issue board</a>.</p>
<p>Thank you for developing with Vuetify and I look forward to bringing more exciting features in the future.</p>
<div class="text-xs-right">
<em><small>&mdash; John Leider</small></em>
</div>
<hr class="my-3">
<a href="https://nuxtjs.org/" target="_blank">Nuxt Documentation</a>
<br>
<a href="https://github.com/nuxt/nuxt.js" target="_blank">Nuxt GitHub</a>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" flat nuxt to="/inspire">Continue</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</template>
<script>
import Logo from '~/components/Logo.vue'
import VuetifyLogo from '~/components/VuetifyLogo.vue'
export default {
components: {
Logo,
VuetifyLogo
}
}
</script>

View File

@ -0,0 +1,15 @@
<template>
<v-layout>
<v-flex text-xs-center>
<img src="/v.png" alt="Vuetify.js" class="mb-5">
<blockquote class="blockquote">
&#8220;First, solve the problem. Then, write the code.&#8221;
<footer>
<small>
<em>&mdash;John Johnson</em>
</small>
</footer>
</blockquote>
</v-flex>
</v-layout>
</template>

View File

@ -0,0 +1,15 @@
import Vue from 'vue'
import Vuetify from 'vuetify'
import colors from 'vuetify/es5/util/colors'
Vue.use(Vuetify, {
theme: {
primary: '#121212', // a color that is not in the material colors palette
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber,
error: colors.deepOrange.accent4,
success: colors.green.accent3
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,10 @@
# STORE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Vuex Store files.
Vuex Store option is implemented in the Nuxt.js framework.
Creating a file in this directory activate the option in the framework automatically.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).

View File

@ -0,0 +1,92 @@
import {
nStoriesOfWithDefault,
action,
boolean,
text,
color,
array
} from './storybase.js'
import LineChart from '~/components/LineChart'
nStoriesOfWithDefault({ LineChart })
.add('with some data', () => ({
components: { LineChart },
template: `
<div>
<line-chart :data="{
labels: [1,2,3],
datasets: [
{
label: 'Sample',
backgroundColor: 'green',
data: ['1','2','3']
}
]
}" :options="{ maintainAspectRatio: false, responsive:true}"/>
</div>`
}))
.add('with knobs demo', () => {
const maintainAspectRatio = boolean('Aspect Ratio', false)
const responsive = boolean('Responsive', true)
const title = text('Title', 'Sample chart')
const myColor = color('Background Color', 'darkred')
const defaultValue = array('Values', [1, 2, 3, 6, 3, 8])
const defaultLabel = array('Labels', [
"'a'",
"'b'",
"'c'",
"'d'",
"'e'",
"'f'"
])
return {
components: { LineChart },
methods: { onResize: action('resized') },
template: `
<div style="position: relative; height:40vh; width:80vw">
<line-chart :data="{
labels: [${defaultLabel}],
datasets: [
{
label: '${title}',
backgroundColor: '${myColor}',
data: [${defaultValue}]
}
]
}" :options="{ maintainAspectRatio: ${maintainAspectRatio}, responsive:${responsive}, onResize }"/>
</div>
`
}
})
.addVT('with Vuetify', () => {
const data = { "'a'": 1, "'b'": 2, "'c'": 3 }
return `
<line-chart :data="{
labels: [${Object.keys(data)}],
datasets: [
{
label: 'list 1',
backgroundColor: '#41b883',
data: [${Object.values(data)}]
}
]
}" :options="{ maintainAspectRatio: false, responsive:true}"/>
`
})
.addVT(
'with Vuetify2',
`<line-chart :data="{
labels: [1,2,3],
datasets: [
{
label: 'list 2',
backgroundColor: '#41b883',
data: ['1','2','3']
}
]
}" :options="{ maintainAspectRatio: false, responsive:true}"/>
`
)

View File

@ -0,0 +1,45 @@
import {
nStoriesOf,
// action,
// boolean,
// text,
// color,
// array,
object
} from './storybase.js'
import Logo from '~/components/Logo.vue'
// nStoriesOf({ Logo }, "Logo 1")
// .addDecorator(story => (
// <div style={{textAlign: 'center'}}>
// {story()}
// </div>
// ))
// .add("with some data", () => ({
// components: { Logo },
// template: `
// <logo :data="{ } "/>`
// }))
nStoriesOf({ Logo }, 'Logo ')
.add('with some data', () => ({
components: { Logo },
template: `
<v-app dark style="min-width:400px">
<v-container fill-height>
<v-flex xs12>
<logo :data="{ } "/>
</v-flex>
</v-container></v-app>`
}))
.addVT('with App layout', '<logo :data="{ } "/>')
.addVT('with a knob', () => {
let data = JSON.stringify(
object('Data', {
name: 'Apple',
count: 132
})
)
return `<logo :data='${data}' />`
})

View File

@ -0,0 +1,14 @@
import { storiesOf } from '@storybook/vue'
import MyButton from '~/components/Button.vue'
import Centered from '@storybook/addon-centered'
storiesOf('Button', module)
.addDecorator(Centered)
.add('rounded button', () => ({
template: '<my-button :rounded="true"> 👍 A Button with rounded edges</my-button>'
}))
.add('normal button', () => ({
components: { MyButton },
template: '<my-button :rounded="false">A Button with square edges</my-button>'
}))

View File

@ -0,0 +1,15 @@
import { storiesOf } from '@storybook/vue'
// import { action } from '@storybook/addon-actions'
import { linkTo } from '@storybook/addon-links'
import Welcome from '~/components/Welcome.vue'
storiesOf('Welcome', module).add('to Storybook', () => ({
render: h => h(Welcome)
}))
.add('with Link To Button', () => ({
components: { Welcome },
template: '<div align=center><welcome :showApp="action" /></div>',
methods: { action: linkTo('Button') }
}))

View File

@ -0,0 +1,236 @@
/* eslint-disable react/react-in-jsx-scope */
import Vuex from 'vuex'
import { storiesOf } from '@storybook/vue'
import { action } from '@storybook/addon-actions'
import { linkTo } from '@storybook/addon-links'
import { withNotes } from '@storybook/addon-notes'
import {
withKnobs,
text,
number,
boolean,
array,
select,
color,
date,
button
} from '@storybook/addon-knobs/vue'
import MyButton from '~/components/Button.vue'
// storiesOf('App', module).add('App', () => ({
// render: h => h(App),
// }));
storiesOf('Features/Method for rendering Vue', module)
.add('render', () => ({
render: h => h('div', ['renders a div with some text in it..'])
}))
.add('render + component', () => ({
render(h) {
return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton'])
}
}))
.add('template', () => ({
template: `
<div>
<h1>A template</h1>
<p>rendered in vue in storybook</p>
</div>`
}))
.add('template + component', () => ({
components: { MyButton },
template: '<my-button>MyButton rendered in a template</my-button>'
}))
.add('template + methods', () => ({
components: { MyButton },
template: `
<p>
<em>Clicking the button will navigate to another story using the 'addon-links'</em><br/>
<my-button :rounded="true" :handle-click="action">MyButton rendered in a template + props & methods</my-button>
</p>`,
methods: {
action: linkTo('Button')
}
}))
.add('JSX', () => ({
components: { MyButton },
render() {
return <my-button>MyButton rendered with JSX</my-button>
}
}))
.add('vuex + actions', () => ({
components: { MyButton },
template: '<my-button :handle-click="log">with vuex: {{ $store.state.count }}</my-button>',
store: new Vuex.Store({
state: { count: 0 },
mutations: {
increment(state) {
state.count += 1; // eslint-disable-line
action('vuex state')(state)
}
}
}),
methods: {
log() {
this.$store.commit('increment')
}
}
}))
.add('whatever you want', () => ({
components: { MyButton },
template:
'<my-button :handle-click="log">with awesomeness: {{ $store.state.count }}</my-button>',
store: new Vuex.Store({
state: { count: 0 },
mutations: {
increment(state) {
state.count += 1; // eslint-disable-line
action('vuex state')(state)
}
}
}),
methods: {
log() {
this.$store.commit('increment')
}
}
}))
.add('pre-registered component', () => ({
/* By pre-registering component in config.js,
* the need to register all components with each story is removed.
* You'll only need the template */
template: `
<p>
<em>This component was pre-registered in .storybook/config.js</em><br/>
<my-button>MyButton rendered in a template</my-button>
</p>`
}))
storiesOf('Features/Decorator for Vue', module)
.addDecorator(story => {
// Decorated with story function
const WrapButton = story()
return {
components: { WrapButton },
template: '<div :style="{ border: borderStyle }"><wrap-button/></div>',
data() {
return { borderStyle: 'medium solid red' }
}
}
})
.addDecorator(() => ({
// Decorated with `story` component
template: '<div :style="{ border: borderStyle }"><story/></div>',
data() {
return {
borderStyle: 'medium solid blue'
}
}
}))
.add('template', () => ({
template: '<my-button>MyButton with template</my-button>'
}))
.add('render', () => ({
render(h) {
return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton'])
}
}))
storiesOf('Features/Addon Actions', module)
.add('Action only', () => ({
template: '<my-button :handle-click="log">Click me to log the action</my-button>',
methods: {
log: action('log1')
}
}))
.add('Action and method', () => ({
template: '<my-button :handle-click="log">Click me to log the action</my-button>',
methods: {
log: e => {
e.preventDefault()
action('log2')(e.target)
}
}
}))
storiesOf('Features/Addon Notes', module)
.add(
'Simple note',
withNotes({ text: 'My notes on some bold text' })(() => ({
template:
'<p><strong>Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.</strong></p>'
}))
)
.add(
'Note with HTML',
withNotes({
text: `
<h2>My notes on emojies</h2>
<em>It's not all that important to be honest, but..</em>
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
`
})(() => ({
template: '<p>🤔😳😯😮<br/>😄😩😓😱<br/>🤓😑😶😊</p>'
}))
)
storiesOf('Features/ Addon Knobs', module)
.addDecorator(withKnobs)
.add('Simple', () => {
const name = text('Name', 'John Doe')
const age = number('Age', 44)
const content = `I am ${name} and I'm ${age} years old.`
return {
template: `<div>${content}</div>`
}
})
.add('All knobs', () => {
const name = text('Name', 'Jane')
const stock = number('Stock', 20, {
range: true,
min: 0,
max: 30,
step: 5
})
const fruits = {
apples: 'Apple',
bananas: 'Banana',
cherries: 'Cherry'
}
const fruit = select('Fruit', fruits, 'apple')
const price = number('Price', 2.25)
const colour = color('Border', 'deeppink')
const today = date('Today', new Date('Jan 20 2017'))
const items = array('Items', ['Laptop', 'Book', 'Whiskey'])
const nice = boolean('Nice', true)
const stockMessage = stock
? `I have a stock of ${stock} ${fruit}, costing &dollar;${price} each.`
: `I'm out of ${fruit}${nice ? ', Sorry!' : '.'}`
const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'
button('Arbitrary action', action('You clicked it!'))
return {
template: `
<div style="border:2px dotted ${colour}; padding: 8px 22px; border-radius: 8px">
<h1>My name is ${name},</h1>
<h3>today is ${new Date(today).toLocaleDateString()}</h3>
<p>${stockMessage}</p>
<p>Also, I have:</p>
<ul>
${items.map(item => `<li key=${item}>${item}</li>`).join('')}
</ul>
<p>${salutation}</p>
</div>
`
}
})
/* eslint-enable react/react-in-jsx-scope */

View File

@ -0,0 +1,84 @@
import { storiesOf } from '@storybook/vue'
import { action } from '@storybook/addon-actions'
import {
withKnobs,
text,
number,
boolean,
array,
select,
color,
date,
object,
button
} from '@storybook/addon-knobs/vue'
// import { withSmartKnobs } from "storybook-addon-smart-knobs"
// import { withInfo } from "@storybook/addon-info"
import centered from '@storybook/addon-centered'
import { linkTo } from '@storybook/addon-links'
/**
* Template function for Vuetify
* @param {*} cmp component inside object {cmp}
* @param {*} cmpStr template string or function returning on
*/
const vtmp = (cmp, cmpStr) => ({
components: cmp,
template: `
<v-app style="min-width:400px">
<v-container fluid fill-height>
<v-flex xs12>${cmpStr instanceof Function ? cmpStr() : cmpStr}</v-flex>
</v-container>
</v-app>
`
})
/**
* Richer aLternative to storiesOf
* @param {*} cmp
* @param {*} name
* @param {*} params
*/
const nStoriesOf = (cmp, name = Object.keys(cmp)[0], params = {}) => {
let x = storiesOf(name, module)
.addDecorator(centered)
.addDecorator(withKnobs)
if (params.withDefault) {
x.add('Default', () => ({
render: h => h(Object.values(cmp)[0])
}))
}
x.addVT = (title, cmpStr) => {
x.add(title, () => vtmp(cmp, cmpStr))
return x
}
return x
}
/**
* Stories of which just works
* @param {*} cmp
* @param {*} name
*/
const nStoriesOfWithDefault = (cmp, name = Object.keys(cmp)[0]) =>
nStoriesOf(cmp, name, { withDefault: 'withDefault' })
export {
nStoriesOf,
nStoriesOfWithDefault,
action,
linkTo,
withKnobs,
text,
number,
object,
boolean,
array,
select,
color,
date,
button,
vtmp
}

View File

@ -0,0 +1,113 @@
import { storiesOf } from '@storybook/vue'
// import { linkTo } from '@storybook/addon-links'
import VuetifyLogo from '~/components/VuetifyLogo.vue'
// import Layout from '~/components/Layout.vue'
import Centered from '@storybook/addon-centered'
storiesOf('Vuetify/Logo', module)
.addDecorator(Centered)
.add('Logo', () => ({
render: h => h(VuetifyLogo)
}))
const menuItems = [
{
action: 'local_activity',
title: 'Attractions',
items: [{ title: 'List Item' }]
},
{
action: 'restaurant',
title: 'Dining',
active: true,
items: [
{ title: 'Breakfast & brunch' },
{ title: 'New American' },
{ title: 'Sushi' }
]
},
{
action: 'school',
title: 'Education',
items: [{ title: 'List Item' }]
},
{
action: 'directions_run',
title: 'Family',
items: [{ title: 'List Item' }]
},
{
action: 'healing',
title: 'Health',
items: [{ title: 'List Item' }]
},
{
action: 'content_cut',
title: 'Office',
items: [{ title: 'List Item' }]
},
{
action: 'local_offer',
title: 'Promotions',
items: [{ title: 'List Item' }]
}
]
const menuItemsAlt = [
{
action: 'inbox',
title: 'Mailbox'
},
{
action: 'note',
title: 'My Address'
},
{
action: 'assignment',
title: 'In Progress',
active: true,
items: [
{ title: 'Consolidation' },
{ title: 'Repacking' },
{ title: 'Shipping' }
]
},
{
action: 'playlist_add_check',
title: 'Registration'
},
{
action: 'account_circle',
title: 'Account'
},
{
action: 'view_headline',
title: 'Shipped'
}
]
storiesOf('Vuetify/V-Btn', module)
.add('Square Button', () => ({
components: {},
data() {
return {
items: menuItems
}
},
template:
'<v-btn color="success">Success</v-btn>'
}))
.add('with rounded button', () => ({
components: {},
data() {
return {
items: menuItemsAlt
}
},
template:
`<v-btn color="warning" large round dark>
Rounded button
</v-btn>`
}))