Skip to content

Commit

Permalink
Addon-docs: Basic skeleton, UI viewMode handling (#7107)
Browse files Browse the repository at this point in the history
Addon-docs: Basic skeleton, UI viewMode handling
  • Loading branch information
shilman authored Jun 18, 2019
2 parents f8b551e + 5d5c678 commit da7b6bd
Show file tree
Hide file tree
Showing 20 changed files with 159 additions and 103 deletions.
3 changes: 3 additions & 0 deletions addons/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Storybook Docs

Living documentation for your components.
39 changes: 39 additions & 0 deletions addons/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@storybook/addon-docs",
"version": "5.2.0-alpha.23",
"description": "Superior documentation for your components",
"keywords": [
"addon",
"notes",
"storybook"
],
"homepage": "https://github.com/storybookjs/storybook/tree/master/addons/docs",
"bugs": {
"url": "https://github.com/storybookjs/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybookjs/storybook.git",
"directory": "addons/docs"
},
"license": "MIT",
"main": "dist/public_api.js",
"types": "dist/public_api.d.ts",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-alpha.23",
"@storybook/api": "5.2.0-alpha.23"
},
"devDependencies": {
"@types/util-deprecate": "^1.0.0",
"@types/webpack-env": "^1.13.7"
},
"peerDependencies": {
"react": "*"
},
"publishConfig": {
"access": "public"
}
}
1 change: 1 addition & 0 deletions addons/docs/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('./dist/register.js');
Empty file added addons/docs/src/public_api.ts
Empty file.
12 changes: 12 additions & 0 deletions addons/docs/src/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import addons, { types } from '@storybook/addons';
import { ADDON_ID, PANEL_ID } from './shared';

addons.register(ADDON_ID, api => {
addons.add(PANEL_ID, {
type: types.TAB,
title: 'Docs',
route: ({ storyId }) => `/docs/${storyId}`,
match: ({ viewMode }) => viewMode === 'docs',
render: () => null,
});
});
3 changes: 3 additions & 0 deletions addons/docs/src/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const ADDON_ID = 'storybook/docs';
export const PANEL_ID = `${ADDON_ID}/panel`;
export const PARAM_KEY = `docs`;
9 changes: 9 additions & 0 deletions addons/docs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"types": ["webpack-env"]
},
"include": ["src/**/*"],
"exclude": ["src/**.test.ts"]
}
1 change: 1 addition & 0 deletions examples/official-storybook/addons.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@storybook/addon-storysource/register';
import '@storybook/addon-design-assets/register';
import '@storybook/addon-docs/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-events/register';
Expand Down
1 change: 1 addition & 0 deletions examples/official-storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@storybook/addon-contexts": "5.2.0-alpha.23",
"@storybook/addon-cssresources": "5.2.0-alpha.23",
"@storybook/addon-design-assets": "5.2.0-alpha.23",
"@storybook/addon-docs": "5.2.0-alpha.23",
"@storybook/addon-events": "5.2.0-alpha.23",
"@storybook/addon-graphql": "5.2.0-alpha.23",
"@storybook/addon-info": "5.2.0-alpha.23",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Addons|Docs default 1`] = `
<div>
Click the docs tab to see the docs
</div>
`;
8 changes: 8 additions & 0 deletions examples/official-storybook/stories/addon-docs.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

storiesOf('Addons|Docs', module)
.addParameters({
docs: () => <div>Hello docs</div>,
})
.add('default', () => <div>Click the docs tab to see the docs</div>);
4 changes: 2 additions & 2 deletions lib/client-api/src/story_store.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export default class StoryStore extends EventEmitter {
);
}

setSelection = ({ storyId }) => {
this._selection = { storyId };
setSelection = ({ storyId, viewMode }) => {
this._selection = { storyId, viewMode };
setTimeout(() => this.emit(Events.STORY_RENDER), 1);
};

Expand Down
79 changes: 45 additions & 34 deletions lib/core/src/client/preview/start.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';

import addons from '@storybook/addons';
import { navigator, window, document } from 'global';
import createChannel from '@storybook/channel-postmessage';
Expand Down Expand Up @@ -119,52 +122,60 @@ export default function start(render, { decorateStory } = {}) {
let previousKind = '';
let previousStory = '';
let previousRevision = -1;
let previousViewMode = '';

const renderMain = forceRender => {
const revision = storyStore.getRevision();
const { storyId } = storyStore.getSelection();

const { storyId, viewMode } = storyStore.getSelection();
const data = storyStore.fromId(storyId);

const { kind, name, getDecorated, id } = data || {};
const { kind, name, getDecorated, id, parameters } = data || {};

const renderContext = {
...context,
...data,
selectedKind: kind,
selectedStory: name,
parameters,
forceRender,
};

if (getDecorated) {
// Render story only if selectedKind or selectedStory have changed.
// However, we DO want the story to re-render if the store itself has changed
// (which happens at the moment when HMR occurs)
if (
!forceRender &&
revision === previousRevision &&
kind === previousKind &&
previousStory === name
) {
addons.getChannel().emit(Events.STORY_UNCHANGED, id);
return;
}

if (!forceRender && previousKind && previousStory) {
addons.getChannel().emit(Events.STORY_CHANGED, id);
}
// Render story only if selectedKind or selectedStory have changed.
// However, we DO want the story to re-render if the store itself has changed
// (which happens at the moment when HMR occurs)
if (
!forceRender &&
revision === previousRevision &&
viewMode === previousViewMode &&
kind === previousKind &&
name === previousStory
) {
addons.getChannel().emit(Events.STORY_UNCHANGED, id);
return;
}

previousRevision = revision;
previousKind = kind;
previousStory = name;
if (!forceRender && previousKind && previousStory) {
addons.getChannel().emit(Events.STORY_CHANGED, id);
}

render(renderContext);
addons.getChannel().emit(Events.STORY_RENDERED, id);
} else {
showNopreview();
addons.getChannel().emit(Events.STORY_MISSING, id);
if (viewMode === 'docs') {
const NoDocs = () => <div style={{ fontFamily: 'sans-serif' }}>No docs found</div>;
const StoryDocs = (parameters && parameters.docs) || NoDocs;
ReactDOM.render(<StoryDocs context={renderContext} />, document.getElementById('root'));
} else if (!viewMode || viewMode === 'story') {
if (getDecorated) {
render(renderContext);
addons.getChannel().emit(Events.STORY_RENDERED, id);
} else {
showNopreview();
addons.getChannel().emit(Events.STORY_MISSING, id);
}
}

previousRevision = revision;
previousKind = kind;
previousStory = name;
previousViewMode = viewMode;

if (!forceRender) {
document.documentElement.scrollTop = 0;
}
Expand All @@ -191,7 +202,7 @@ export default function start(render, { decorateStory } = {}) {
);

channel.on(Events.FORCE_RE_RENDER, forceReRender);
channel.on(Events.SET_CURRENT_STORY, ({ storyId: inputStoryId, name, kind }) => {
channel.on(Events.SET_CURRENT_STORY, ({ storyId: inputStoryId, name, kind, viewMode }) => {
let storyId = inputStoryId;
// For backwards compatibility
if (!storyId) {
Expand All @@ -201,8 +212,8 @@ export default function start(render, { decorateStory } = {}) {
storyId = deprecatedToId(kind, name);
}

storyStore.setSelection({ storyId });
setPath({ storyId });
storyStore.setSelection({ storyId, viewMode });
setPath({ storyId, viewMode });
});

// Handle keyboard shortcuts
Expand All @@ -218,8 +229,8 @@ export default function start(render, { decorateStory } = {}) {
}

storyStore.on(Events.STORY_INIT, () => {
const { storyId } = initializePath();
storyStore.setSelection({ storyId });
const { storyId, viewMode } = initializePath();
storyStore.setSelection({ storyId, viewMode });
});

storyStore.on(Events.STORY_RENDER, renderUI);
Expand Down
12 changes: 8 additions & 4 deletions lib/core/src/client/preview/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ export function pathToId(path) {
return match[1];
}

export const setPath = ({ storyId }) => {
export const setPath = ({ storyId, viewMode }) => {
const { path, selectedKind, selectedStory, ...rest } = qs.parse(document.location.search, {
ignoreQueryPrefix: true,
});
const newPath = `${document.location.pathname}?${qs.stringify({ ...rest, id: storyId })}`;
const newPath = `${document.location.pathname}?${qs.stringify({
...rest,
id: storyId,
viewMode,
})}`;
history.replaceState({}, '', newPath);
};

Expand All @@ -28,11 +32,11 @@ export const parseQueryParameters = search => {

export const initializePath = () => {
const query = qs.parse(document.location.search, { ignoreQueryPrefix: true });
let { id: storyId } = query;
let { id: storyId, viewMode } = query; // eslint-disable-line prefer-const
if (!storyId) {
storyId = getIdFromLegacyQuery(query);
if (storyId) {
setPath({ storyId });
setPath({ storyId, viewMode });
}
}
return { storyId };
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const App = React.memo(({ viewMode, layout, size: { width, height } }) => {
);
});
App.propTypes = {
viewMode: PropTypes.oneOf(['story', 'info']),
viewMode: PropTypes.oneOf(['story', 'info', 'docs']),
layout: PropTypes.shape({}).isRequired,
size: PropTypes.shape({
width: PropTypes.number,
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/components/layout/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ Layout.propTypes = {
showPanel: PropTypes.bool.isRequired,
panelPosition: PropTypes.string.isRequired,
}).isRequired,
viewMode: PropTypes.oneOf(['story', 'info']),
viewMode: PropTypes.oneOf(['story', 'info', 'docs']),
theme: PropTypes.shape({}).isRequired,
};
Layout.defaultProps = {
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/components/layout/desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Desktop.propTypes = {
panelPosition: PropTypes.string.isRequired,
isToolshown: PropTypes.bool.isRequired,
}).isRequired,
viewMode: PropTypes.oneOf(['story', 'info']),
viewMode: PropTypes.oneOf(['story', 'info', 'docs']),
};
Desktop.defaultProps = {
viewMode: undefined,
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/components/layout/mobile.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Mobile.propTypes = {
render: PropTypes.func.isRequired,
})
).isRequired,
viewMode: PropTypes.oneOf(['story', 'info']),
viewMode: PropTypes.oneOf(['story', 'info', 'docs']),
options: PropTypes.shape({
initialActive: PropTypes.number,
}).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ Array [
allowfullscreen=""
id="storybook-preview-iframe"
scrolling="yes"
src="http://example.com?id=string"
src="http://example.com?id=string&viewMode=story"
title="string"
/>
</div>
Expand Down Expand Up @@ -403,7 +403,7 @@ Array [
margin-left: 0;
}

.emotion-2 {
.emotion-0 {
white-space: normal;
display: -webkit-inline-box;
display: -webkit-inline-flex;
Expand Down Expand Up @@ -439,51 +439,6 @@ Array [
border-bottom-color: transparent;
}

.emotion-2:empty {
display: none;
}

.emotion-2:focus {
outline: 0 none;
border-bottom-color: #1EA7FD;
}

.emotion-0 {
white-space: normal;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
overflow: hidden;
vertical-align: top;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-align: center;
-webkit-text-decoration: none;
text-decoration: none;
padding: 0 15px;
text-transform: capitalize;
-webkit-transition: color 0.2s linear,border-bottom-color 0.2s linear;
transition: color 0.2s linear,border-bottom-color 0.2s linear;
height: 40px;
line-height: 12px;
cursor: pointer;
background: transparent;
border: 0 solid transparent;
border-top: 3px solid transparent;
border-bottom: 3px solid transparent;
font-weight: bold;
font-size: 13px;
color: #1EA7FD;
border-bottom-color: #1EA7FD;
}

.emotion-0:empty {
display: none;
}
Expand Down Expand Up @@ -644,7 +599,7 @@ Array [
href="/?path=/info/string"
>
<button
class="emotion-2"
class="emotion-0"
>
Notes
</button>
Expand Down Expand Up @@ -835,7 +790,7 @@ Array [
allowfullscreen=""
id="storybook-preview-iframe"
scrolling="yes"
src="http://example.com?id=string"
src="http://example.com?id=string&viewMode=story"
title="string"
/>
</div>
Expand Down
Loading

1 comment on commit da7b6bd

@vercel
Copy link

@vercel vercel bot commented on da7b6bd Jun 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.