Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement preview hooks #6916

Merged
merged 23 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,13 @@ module.exports = {
],
'no-underscore-dangle': [
error,
{ allow: ['__STORYBOOK_CLIENT_API__', '__STORYBOOK_ADDONS_CHANNEL__'] },
{
allow: [
'__STORYBOOK_CLIENT_API__',
'__STORYBOOK_ADDONS_CHANNEL__',
'__STORYBOOK_STORY_STORE__',
],
},
],
'@typescript-eslint/no-var-requires': ignore,
'@typescript-eslint/camelcase': ignore,
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
node_modules
*.log
.idea
*.iml
.vscode
*.sw*
npm-shrinkwrap.json
Expand Down
2 changes: 1 addition & 1 deletion addons/actions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
"dependencies": {
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/api": "5.2.0-alpha.40",
"@storybook/client-api": "5.2.0-alpha.40",
"@storybook/components": "5.2.0-alpha.40",
"@storybook/core-events": "5.2.0-alpha.40",
"@storybook/theming": "5.2.0-alpha.40",
"core-js": "^3.0.1",
"fast-deep-equal": "^2.0.1",
"global": "^4.3.2",
"lodash": "^4.17.11",
"polished": "^3.3.1",
"prop-types": "^15.7.2",
"react": "^16.8.3",
Expand Down
28 changes: 8 additions & 20 deletions addons/actions/src/preview/withActions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
// Based on http://backbonejs.org/docs/backbone.html#section-164
import { document, Element } from 'global';
import { isEqual } from 'lodash';
Copy link
Member

@ndelangen ndelangen Jul 10, 2019

Choose a reason for hiding this comment

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

nice! This should shave off quite some bundlesize

import { addons } from '@storybook/addons';
import Events from '@storybook/core-events';
import { useEffect } from '@storybook/client-api';

import { actions } from './actions';

let lastSubscription: () => () => void;
let lastArgs: any[];

const delegateEventSplitter = /^(\S+)\s*(.*)$/;

const isIE = Element != null && !Element.prototype.matches;
Expand Down Expand Up @@ -42,24 +37,17 @@ const createHandlers = (actionsFn: (...arg: any[]) => object, ...args: any[]) =>
});
};

const actionsSubscription = (...args: any[]) => {
if (!isEqual(args, lastArgs)) {
lastArgs = args;
// @ts-ignore
const handlers = createHandlers(...args);
lastSubscription = () => {
export const createDecorator = (actionsFn: any) => (...args: any[]) => (storyFn: () => any) => {
useEffect(() => {
if (root != null) {
const handlers = createHandlers(actionsFn, ...args);
handlers.forEach(({ eventName, handler }) => root.addEventListener(eventName, handler));
return () =>
handlers.forEach(({ eventName, handler }) => root.removeEventListener(eventName, handler));
};
}
return lastSubscription;
};
}
return undefined;
}, [root, actionsFn, args]);

export const createDecorator = (actionsFn: any) => (...args: any[]) => (storyFn: () => any) => {
if (root != null) {
addons.getChannel().emit(Events.REGISTER_SUBSCRIPTION, actionsSubscription(actionsFn, ...args));
}
return storyFn();
};

Expand Down
2 changes: 1 addition & 1 deletion addons/docs/src/lib/getPropDefs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-underscore-dangle,react/forbid-foreign-prop-types */

import PropTypes from 'prop-types';
import { PropDef } from '@storybook/components';
Expand Down
1 change: 1 addition & 0 deletions addons/events/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/api": "5.2.0-alpha.40",
"@storybook/client-api": "5.2.0-alpha.40",
"@storybook/core-events": "5.2.0-alpha.40",
"@storybook/theming": "5.2.0-alpha.40",
"core-js": "^3.0.1",
Expand Down
37 changes: 37 additions & 0 deletions addons/events/src/deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// TODO remove in 6.0
import addons from '@storybook/addons';
import CoreEvents from '@storybook/core-events';
import deprecate from 'util-deprecate';

import { EVENTS } from './constants';

let prevEvents;
let currentEmit;

const onEmit = event => {
currentEmit(event.name, event.payload);
};

const subscription = () => {
const channel = addons.getChannel();
channel.on(EVENTS.EMIT, onEmit);
return () => {
prevEvents = null;
addons.getChannel().emit(EVENTS.ADD, []);
channel.removeListener(EVENTS.EMIT, onEmit);
};
};

const addEvents = ({ emit, events }) => {
if (prevEvents !== events) {
addons.getChannel().emit(EVENTS.ADD, events);
prevEvents = events;
}
currentEmit = emit;
addons.getChannel().emit(CoreEvents.REGISTER_SUBSCRIPTION, subscription);
};

export const WithEvents = deprecate(({ children, ...options }) => {
addEvents(options);
return children;
}, `<WithEvents> usage is deprecated, use .addDecorator(withEvents({emit, events})) instead`);
5 changes: 3 additions & 2 deletions addons/knobs/src/registerKnobs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import addons from '@storybook/addons';
import { STORY_CHANGED, FORCE_RE_RENDER, REGISTER_SUBSCRIPTION } from '@storybook/core-events';
import { useEffect } from '@storybook/client-api';
import { STORY_CHANGED, FORCE_RE_RENDER } from '@storybook/core-events';
import debounce from 'lodash/debounce';

import KnobManager from './KnobManager';
Expand Down Expand Up @@ -85,5 +86,5 @@ function connectCallbacks() {
}

export function registerKnobs() {
addons.getChannel().emit(REGISTER_SUBSCRIPTION, connectCallbacks);
useEffect(connectCallbacks, []);
}
1 change: 1 addition & 0 deletions addons/ondevice-notes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/client-logger": "5.2.0-alpha.40",
"core-js": "^3.0.1",
"prop-types": "^15.7.2",
"react-native-simple-markdown": "^1.1.0"
Expand Down
4 changes: 3 additions & 1 deletion addons/ondevice-notes/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { logger } from '@storybook/client-logger';

// eslint-disable-next-line no-undef
if (__DEV__) {
console.log("import '@storybook/addon-ondevice-notes/register' to register the notes addon");
logger.log("import '@storybook/addon-ondevice-notes/register' to register the notes addon");
}
2 changes: 1 addition & 1 deletion addons/storyshots/storyshots-puppeteer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"puppeteer": "^1.12.2"
},
"peerDependencies": {
"@storybook/addon-storyshots": "5.2.0-alpha.37",
"@storybook/addon-storyshots": "5.2.0-alpha.40",
"puppeteer": "^1.12.2"
},
"publishConfig": {
Expand Down
4 changes: 2 additions & 2 deletions app/react-native/src/preview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class Preview {
constructor() {
this._addons = {};
this._decorators = [];
this._stories = new StoryStore({});
this._stories = new StoryStore({ channel: null });
this._clientApi = new ClientApi({ storyStore: this._stories });
}

Expand Down Expand Up @@ -211,7 +211,7 @@ export default class Preview {
_selectStory(story: any) {
const channel = addons.getChannel();

this._stories.setSelection({ storyId: story.id });
this._stories.setSelection({ storyId: story.id, viewMode: 'story' }, null);
channel.emit(Events.SELECT_STORY, story);
}

Expand Down
12 changes: 12 additions & 0 deletions dev-kits/addon-decorator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# example addon: decorator

This addon exposes a function users can use to wrap their storyFn with. This is called a decorator in storybook's terminology.

A decorator can perform analysis on the storyFn, detect how long it takes to render, detect side-effects, and have access to the storyContext.

It's also possible to wrap the results with some additional html/jsx or provide additional data to the storyFn.

Uses include:
- do side-effects detection
- wrap story with additional html
- add data to storyFn
35 changes: 35 additions & 0 deletions dev-kits/addon-decorator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@storybook/addon-decorator",
"version": "5.2.0-alpha.40",
"description": "decorator addon for storybook",
"keywords": [
"devkit",
"addon",
"storybook",
"decorator"
],
"homepage": "https://github.com/storybookjs/storybook/tree/master/addons/actions",
"bugs": {
"url": "https://github.com/storybookjs/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybookjs/storybook.git",
"directory": "addons/actions"
},
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/client-api": "5.2.0-alpha.40",
"global": "^3.0.1",
"core-js": "^3.0.1"
},
"publishConfig": {
"access": "public"
}
}
1 change: 1 addition & 0 deletions dev-kits/addon-decorator/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ADDON_ID = 'storybook/decorator';
21 changes: 21 additions & 0 deletions dev-kits/addon-decorator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-disable no-console */
import { document } from 'global';
import { useEffect } from '@storybook/client-api';

const root = document && document.getElementById('root');

export const createDecorator = () => (options: any) => (storyFn: () => any) => {
Copy link
Member

Choose a reason for hiding this comment

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

@ndelangen @Hypnosphi StoryContext?

useEffect(() => {
if (root != null) {
console.log('story was rendered');
return () => {
console.log('story was removed');
};
}
return undefined;
}, [root, options]);

return storyFn();
};

export const withDecorator = createDecorator();
3 changes: 3 additions & 0 deletions dev-kits/addon-decorator/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// TODO: following packages need definition files or a TS migration
declare module 'global';
declare module 'react-inspector';
13 changes: 13 additions & 0 deletions dev-kits/addon-decorator/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"types": ["webpack-env"]
},
"include": [
"src/**/*"
],
"exclude": [
"src/__tests__/**/*"
]
}
2 changes: 1 addition & 1 deletion dev-kits/addon-parameter/src/register.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Fragment, useMemo } from 'react';
import React, { useMemo } from 'react';

import { useParameter } from '@storybook/api';
import { addons, types } from '@storybook/addons';
Expand Down
1 change: 1 addition & 0 deletions dev-kits/addon-roundtrip/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/api": "5.2.0-alpha.40",
"@storybook/client-api": "5.2.0-alpha.40",
"@storybook/client-logger": "5.2.0-alpha.40",
"@storybook/components": "5.2.0-alpha.40",
"@storybook/core-events": "5.2.0-alpha.40",
Expand Down
17 changes: 7 additions & 10 deletions dev-kits/addon-roundtrip/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { addons } from '@storybook/addons';
import { useChannel } from '@storybook/client-api';
import { EVENTS } from './constants';

const run = async () => {
const channel = await addons.ready();

channel.on(EVENTS.REQUEST, () => {
// do something in the preview context
// then report back to the manager
channel.emit(EVENTS.RESULT, ['from the preview']);
export const withRoundtrip = (storyFn: () => any) => {
const emit = useChannel({
[EVENTS.REQUEST]: () => {
emit(EVENTS.RESULT, ['from the preview']);
},
});
return storyFn();
};

run();
4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"serve": "gatsby serve"
},
"dependencies": {
"@storybook/components": "5.2.0-alpha.37",
"@storybook/theming": "5.2.0-alpha.37",
"@storybook/components": "5.2.0-alpha.40",
"@storybook/theming": "5.2.0-alpha.40",
"babel-loader": "^6.4.1",
"babel-plugin-styled-components": "^1.10.6",
"bootstrap": "^4.3.1",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/versions/next.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "5.2.0-alpha.39",
"version": "5.2.0-alpha.40",
"info": {
"plain": "### Bug Fixes\n\n* UI: Fix Sidebar input refresh on 'Enter' ([#7342](https://github.com/storybookjs/storybook/pull/7342))\n* Addon-knobs: Fix select options types to allow string[] and null ([#7356](https://github.com/storybookjs/storybook/pull/7356))\n\n### Maintenance\n\n* Typescript: Migrate @storybook/react ([#7054](https://github.com/storybookjs/storybook/pull/7054))\n* Build: delete tests & snapshots from dist ([#7358](https://github.com/storybookjs/storybook/pull/7358))"
}
Expand Down
1 change: 1 addition & 0 deletions examples/dev-kits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"storybook": "start-storybook -p 9011 -c ./"
},
"devDependencies": {
"@storybook/addon-decorator": "5.2.0-alpha.40",
"@storybook/addon-parameter": "5.2.0-alpha.40",
"@storybook/addon-roundtrip": "5.2.0-alpha.40",
"@storybook/addons": "5.2.0-alpha.40",
Expand Down
12 changes: 12 additions & 0 deletions examples/dev-kits/stories/addon-decorator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

import { withDecorator } from '@storybook/addon-decorator';
import { withRoundtrip } from '@storybook/addon-roundtrip';

storiesOf('addons|decorator', module)
.addDecorator(withRoundtrip)
.addDecorator(withDecorator())
.add('with decorator', () => (
<div>This story is wrapped with a decorator that is aware of when a story updates/changes</div>
));
2 changes: 0 additions & 2 deletions examples/dev-kits/stories/addon-roundtrip.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

import '@storybook/addon-roundtrip';

storiesOf('root|group/component', module).add('variant 1', () => <div>This is variant 1</div>);

storiesOf('addons|parameter', module)
Expand Down
3 changes: 2 additions & 1 deletion examples/html-kitchen-sink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build-storybook": "build-storybook",
"generate-addon-jest-testresults": "jest --config=tests/addon-jest.config.json --json --outputFile=stories/addon-jest.testresults.json",
"now-build": "node ../../scripts/bootstrap --core && yarn run build-storybook --quiet",
"storybook": "start-storybook -p 9006"
"storybook": "start-storybook -p 9006 --no-dll"
},
"devDependencies": {
"@storybook/addon-a11y": "5.2.0-alpha.40",
Expand All @@ -28,6 +28,7 @@
"@storybook/addon-storysource": "5.2.0-alpha.40",
"@storybook/addon-viewport": "5.2.0-alpha.40",
"@storybook/addons": "5.2.0-alpha.40",
"@storybook/client-api": "5.2.0-alpha.40",
"@storybook/core": "5.2.0-alpha.40",
"@storybook/core-events": "5.2.0-alpha.40",
"@storybook/html": "5.2.0-alpha.40",
Expand Down
Loading