Skip to content
This repository has been archived by the owner on Nov 5, 2020. It is now read-only.

Commit

Permalink
Merge pull request #70 from pocka/feature/docs-in-panel
Browse files Browse the repository at this point in the history
Docs in panel mode
  • Loading branch information
pocka authored Feb 2, 2019
2 parents 5392284 + 042c8be commit a45527c
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ This addon accepts [@storybook/addon-info](https://github.com/storybooks/storybo
| `wrapperComponent` | `Component` | [default wrapper](src/components/Wrapper/index.vue) | Override docs component. |
| `summary` | `string` | `''` | Summary for the story. Accepts Markdown. |
| `components` | `{ [name: string]: Component }\|null` | `null` | Display info for these components. Same type as component's `components` property. If `null` or `false`, this addon tries to use `components` property in story component then outermost tag in `template`. |
| `docsInPanel` | `boolean` | `true` | Whether to show docs in addon panel. |
| `useDocgen` | `boolean` | `true` | Whether to use result of vue-docgen-api. |

In addition to addon options, we have a component option.
Expand Down
1 change: 1 addition & 0 deletions example/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import 'storybook-addon-vue-info/lib/register'
48 changes: 46 additions & 2 deletions example/stories/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,45 @@ storiesOf('Examples/Advance usage', module)
}
}))
)
.add(
'Show docs in preview area',
withInfo({
summary: `
To show docs in preview area, turn off \`docsInPanel\` option.
\`\`\`js
withInfo({
docsInPanel: false
})
\`\`\`
This will override descriptions generated by docgen.
If you never use docsInPanel feature,
you can omit \`import 'storybook-addon-vue-info/register\` in \`.storybook/addons.js\`.
### ATTENTION!
Docs in preview wraps story component, which might cause unexpected behaviors/bugs,
especially with other addons and Vue.js plugins.
I recommend to use this only for documentation and
separate from interactive story such as one using addon-knobs
(otherwise you should set this option true).
`,
docsInPanel: false
})(() => ({
components: { BaseButton },
template: '<base-button label="I\'m a button!"/>',
}))
)
.add(
'Customize docs',
withInfo({
summary: `
To customize docs view, set your docs component to \`wrapperComponent\` option.
## Customize docs in preview
To customize docs in preview area, set your docs component to \`wrapperComponent\` option.
This addon passes two props:
Expand All @@ -185,8 +219,18 @@ storiesOf('Examples/Advance usage', module)
For more detail, please look at source code of this example
(\`example/components/customDocs/wrapper\`).
<br/>
## Customize docs in addon panel
Not supported.
It's challenging to change components in addon panel.
To avoid plugin being complex and messy, customizing addon panel is not supported.
`,
wrapperComponent: CustomWrapper
wrapperComponent: CustomWrapper,
docsInPanel: false
})(() => ({
components: { BaseButton },
template: '<base-button label="I\'m a button!"/>'
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@types/highlight.js": "^9.12.2",
"@types/jest": "^22.2.3",
"@types/marked": "^0.3.0",
"@types/react": "^16.7.22",
"@types/storybook__vue": "^3.3.0",
"autoprefixer": "^9.4.7",
"babel-loader": "^8.0.5",
Expand All @@ -65,12 +66,13 @@
"ts-jest": "^22.4.5",
"tslint": "^5.10.0",
"tslint-config-prettier": "^1.13.0",
"typescript": "^2.9.2",
"typescript": "3",
"vue": "^2.5.16",
"vue-loader": "^15.6.2"
},
"peerDependencies": {
"@storybook/vue": "*",
"react": "*",
"vue": "^2.0.0"
},
"prettier": {
Expand Down Expand Up @@ -99,11 +101,13 @@
]
},
"dependencies": {
"@storybook/addons": "^4.1.11",
"dedent": "^0.7.0",
"highlight.js": "^9.12.0",
"marked": "^0.3.19",
"querystring": "^0.2.0",
"vue-docgen-api": "^3.3.4",
"vue-template-compiler": "^2.5.16"
"vue-template-compiler": "^2.5.16",
"vuera": "^0.2.3"
}
}
28 changes: 21 additions & 7 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ import resolve from 'rollup-plugin-node-resolve'
import typescript from 'rollup-plugin-typescript2'
import vue from 'rollup-plugin-vue'

export default {
input: './src/index.ts',
output: {
file: './lib/index.js',
format: 'es'
},
const commonConfig = {
plugins: [
resolve({
only: ['parse5']
Expand Down Expand Up @@ -42,5 +37,24 @@ export default {
plugins: ['external-helpers']
})
],
external: ['vue', 'dedent', 'marked', 'highlight.js', 'vue-template-compiler']
external: ['vue', 'dedent', 'marked', 'highlight.js', 'vue-template-compiler', 'react', 'vuera', '@storybook/addons']
}

export default [
{
input: './src/index.ts',
output: {
file: './lib/index.js',
format: 'es'
},
...commonConfig
},
{
input: './src/register.tsx',
output: {
file: './lib/register.js',
format: 'es'
},
...commonConfig
}
]
7 changes: 7 additions & 0 deletions src/addon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const AddonName = 'STORYBOOK_ADDON_VUE_INFO'

export const PanelName = AddonName + '/panel'

export const Events = {
ShowDocs: AddonName + '/show_docs'
}
2 changes: 1 addition & 1 deletion src/components/Wrapper/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default {
:title="info.title"
:subtitle="info.subtitle"
/>
<x-preview> <slot /> </x-preview>
<x-preview v-if="!options.docsInPanel"> <slot /> </x-preview>
<x-summary :markdown="info.summary" />
<x-story-source
v-if="options.source"
Expand Down
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { StoryDecorator, StoryFunction } from '@storybook/vue'

import { extract } from './extract'
import { defaultOptions, InfoAddonOptions } from './options'
import { wrap } from './view'
import { transfer, wrap } from './view'

export * from './components'

Expand Down Expand Up @@ -47,6 +47,12 @@ export function withInfo(
// Extract information to display
const info = extract(storyComponent, ctx.kind, ctx.story, opts)

if (opts.docsInPanel) {
transfer(info, opts)

return storyComponent
}

// Return story component wrapped with docs
return wrap(storyComponent, info, opts)
}
Expand Down
49 changes: 49 additions & 0 deletions src/lib.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* tslint:disable:ban-types */

declare module 'vue-template-compiler' {
export interface ASTElement {
attrs?: any[]
Expand All @@ -17,3 +19,50 @@ declare module 'vue-template-compiler' {
}
export function compile(template: string): CompileResult
}

declare module 'vuera' {
import * as React from 'react'
import { AsyncComponent, Component } from 'vue'

interface Props {
component:
| Component<any, any, any, any>
| AsyncComponent<any, any, any, any>
[prop: string]: any
}

export const VueWrapper: React.SFC<Props>
}

declare module '@storybook/addons' {
import { SFC } from 'react'

export interface Api {
onStory(callback: Function): () => void
}

export interface Channel {
on(name: string, handler: Function): void
emit(name: string, payload: any): void

removeListener(name: string, handler: Function): void
}

interface Mod {
register(name: string, callback: (api: Api) => any): void

addPanel(
name: string,
options: {
title: string
render: SFC<{ active: boolean }>
}
): void

getChannel(): Channel
}

const addons: Mod

export default addons
}
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const defaultOptions: InfoAddonOptions = {
summary: '',
components: null,
wrapperComponent: DefaultWrapper,
docsInPanel: true,
useDocgen: true
}

Expand Down Expand Up @@ -40,6 +41,11 @@ export interface InfoAddonOptions {
*/
wrapperComponent: AnyComponent

/**
* Whether to show docs in panel instead of wrapping story
*/
docsInPanel: boolean

/**
* Whether to use component infomation generated by vue-docgen-api
*/
Expand Down
86 changes: 86 additions & 0 deletions src/register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as React from 'react'
import Vue, { ComponentOptions } from 'vue'
import { VueWrapper } from 'vuera'

import addons, { Api, Channel } from '@storybook/addons'

import { AddonName, PanelName, Events } from './addon'
import { InfoAddonOptions } from './options'
import { StoryInfo } from './types/info'

import Wrapper from './components/Wrapper/index.vue'

interface Props {
channel: Channel
api: Api
active: boolean
}

interface State {
/** Information of current story */
info?: StoryInfo
/** Addon options */
options?: InfoAddonOptions
}

class Info extends React.Component<Props, State> {
public state: State = {}

/** Callback to remove event handler */
private stopListen?: () => void

/**
* Callback for ShowDocs event
*/
private onShowDocs = ({ info, options }: State) => {
this.setState({ info, options })
}

public componentDidMount() {
const { channel, api } = this.props

channel.on(Events.ShowDocs, this.onShowDocs)

this.stopListen = api.onStory(() => {
// Clear panel when story changes
this.setState({
info: undefined,
options: undefined
})
})
}

public render() {
const { info, options } = this.state
const { active } = this.props

if (!active || !info || !options) {
return null
}

return (
<div>
<VueWrapper component={Wrapper} info={info} options={options} />
</div>
)
}

public componentWillUnmount() {
if (this.stopListen) {
this.stopListen()
}

const { channel } = this.props

channel.removeListener(Events.ShowDocs, this.onShowDocs)
}
}

addons.register(AddonName, api => {
addons.addPanel(PanelName, {
title: 'Info(Vue)',
render: ({ active }) => (
<Info channel={addons.getChannel()} api={api} active={active} />
)
})
})
9 changes: 9 additions & 0 deletions src/view/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Vue, { ComponentOptions } from 'vue'

import addons from '@storybook/addons'

import { Events } from '../addon'
import { InfoAddonOptions } from '../options'
import { StoryInfo } from '../types/info'

Expand All @@ -20,3 +23,9 @@ export function wrap(
}
}
}

export function transfer(info: StoryInfo, options: InfoAddonOptions): void {
const channel = addons.getChannel()

channel.emit(Events.ShowDocs, { info, options })
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"es2015",
"es2015.promise"
],
"jsx": "react",
"target": "es5",
"strict": true,
"module": "es2015",
Expand Down
Loading

0 comments on commit a45527c

Please sign in to comment.