Skip to content

Commit

Permalink
Merge branch 'release/3.3' into (#1736)-Ability-to-force-redender-a-s…
Browse files Browse the repository at this point in the history
…tory
  • Loading branch information
ndelangen authored Dec 21, 2017
2 parents 50774cb + 4d59b5f commit 6d80f69
Show file tree
Hide file tree
Showing 46 changed files with 1,658 additions and 919 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = {
singleQuote: true,
},
],
'no-debugger': process.env.NODE_ENV === 'production' ? error : ignore,
quotes: [warn, 'single', { avoidEscape: true }],
'class-methods-use-this': ignore,
'arrow-parens': [warn, 'as-needed'],
Expand Down
174 changes: 174 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion addons/a11y/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"dependencies": {
"@storybook/components": "^3.3.0-alpha.4",
"axe-core": "^2.0.7",
"axe-core": "^2.6.0",
"prop-types": "^15.6.0"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion addons/graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"dependencies": {
"global": "^4.3.2",
"graphiql": "^0.11.10",
"graphql": "^0.11.7",
"graphql": "^0.12.3",
"prop-types": "^15.6.0"
},
"peerDependencies": {
Expand Down
33 changes: 32 additions & 1 deletion addons/info/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ import { withInfo } from '@storybook/addon-info';
storiesOf('Component', module)
.add('simple info',
withInfo({
styles: {
header: {
h1: {
color: 'red'
}
}
},
text: 'String or React Element with docs about my component', // Warning! This option's name will be likely renamed to "summary" in 3.3 release. Follow this PR #1501 for details
// other possible options see in Global options section below
})(() =>
Expand All @@ -67,6 +74,30 @@ storiesOf('Component', module)
)
```

The `styles` prop can also accept a function. The default stylesheet is passed as argument:

```js
import { withInfo } from '@storybook/addon-info';

storiesOf('Component', module)
.add('custom info styles using a function',
withInfo({
styles: stylesheet => ({
...stylesheet,
header: {
...stylesheet.header,
h1: {
...stylesheet.header.h1,
color: 'red'
}
}
})
})(() =>
<Component>Click the "?" mark at top-right to view the info.</Component>
)
)
```

## Usage as decorator

It is possible to add infos by default to all components by using a global or story decorator. The drawback is you won't be able to display a distinct info message per story.
Expand Down Expand Up @@ -100,7 +131,7 @@ setDefaults({
source: true, // Displays the source of story Component
propTables: [/* Components used in story */], // displays Prop Tables with this components
propTablesExclude: [], // Exclude Components from being shown in Prop Tables section
styles: {}, // Overrides styles of addon
styles: {}, // Overrides styles of addon. The object should follow this shape: https://github.com/storybooks/storybook/blob/master/addons/info/src/components/Story.js#L19. This prop can also accept a function which has the default stylesheet passed as an argument.
components: {}, // Overrides components used to display markdown
maxPropsIntoLine: 1, // Max props to display per line in source code
maxPropObjectKeys: 10, // Displays the first 10 characters of the prop name
Expand Down
1 change: 1 addition & 0 deletions addons/info/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@storybook/components": "^3.3.0-alpha.4",
"babel-runtime": "^6.26.0",
"global": "^4.3.2",
"nested-object-assign": "^1.0.1",
"marksy": "^6.0.1",
"prop-types": "^15.6.0",
"react-addons-create-fragment": "^15.5.3",
Expand Down
4 changes: 2 additions & 2 deletions addons/info/src/components/Story.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export default class Story extends React.Component {
super(...args);
this.state = {
open: false,
stylesheet: this.props.styles(JSON.parse(JSON.stringify(stylesheet))),
stylesheet: this.props.styles(stylesheet),
};
this.marksy = marksy({
createElement,
Expand All @@ -115,7 +115,7 @@ export default class Story extends React.Component {

componentWillReceiveProps(nextProps) {
this.setState({
stylesheet: nextProps.styles(JSON.parse(JSON.stringify(stylesheet))),
stylesheet: nextProps.styles(stylesheet),
});
}

Expand Down
6 changes: 5 additions & 1 deletion addons/info/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import deprecate from 'util-deprecate';
import nestedObjectAssign from 'nested-object-assign';
import logger from '@storybook/client-logger';
import Story from './components/Story';
import PropTable from './components/PropTable';
Expand Down Expand Up @@ -65,10 +66,13 @@ function addInfo(storyFn, context, infoOptions) {
showInline: Boolean(options.inline),
showHeader: Boolean(options.header),
showSource: Boolean(options.source),
styles:
typeof options.styles === 'function'
? options.styles
: s => nestedObjectAssign({}, s, options.styles),
propTables: options.propTables,
propTablesExclude: options.propTablesExclude,
PropTable: makeTableComponent(options.TableComponent),
styles: typeof options.styles === 'function' ? options.styles : s => s,
components,
maxPropObjectKeys: options.maxPropObjectKeys,
maxPropArrayLength: options.maxPropArrayLength,
Expand Down
6 changes: 3 additions & 3 deletions addons/knobs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
"storybook": "start-storybook -p 9010"
},
"dependencies": {
"@angular/core": "^5.0.0-beta.7",
"babel-runtime": "^6.26.0",
"deep-equal": "^1.0.1",
"global": "^4.3.2",
"insert-css": "^2.0.0",
"lodash.debounce": "^4.0.8",
"moment": "^2.19.4",
"moment": "^2.20.1",
"prop-types": "^15.6.0",
"react-color": "^2.11.4",
"react-datetime": "^2.11.1",
Expand All @@ -30,10 +29,11 @@
"devDependencies": {
"raw-loader": "^0.5.1",
"style-loader": "^0.19.1",
"vue": "^2.5.11"
"vue": "^2.5.12"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0-alpha.4",
"@angular/core": "=>4.0.0",
"react": "*",
"react-dom": "*"
}
Expand Down
39 changes: 22 additions & 17 deletions addons/knobs/src/angular/helpers.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
/* eslint no-underscore-dangle: 0 */

import { Component, SimpleChange, ChangeDetectorRef } from '@angular/core';
import { getParameters, getAnnotations, getPropMetadata } from './utils';

const getComponentMetadata = ({ component, props = {} }) => {
const getComponentMetadata = ({ component, props = {}, pipes = [] }) => {
if (!component || typeof component !== 'function') throw new Error('No valid component provided');

const componentMeta = component.__annotations__[0] || component.annotations[0];
const propsMeta = component.__prop__metadata__ || component.propMetadata || {};
const paramsMetadata = component.__parameters__ || component.parameters || [];
const componentMeta = getAnnotations(component)[0] || {};
const propsMeta = getPropMetadata(component);
const paramsMetadata = getParameters(component);

return {
component,
props,
pipes,
componentMeta,
propsMeta,
params: paramsMetadata,
};
};

const getAnnotatedComponent = ({ componentMeta, component, params, knobStore, channel }) => {
const NewComponent = function NewComponent(cd, ...args) {
const KnobWrapperComponent = function KnobWrapperComponent(cd, ...args) {
component.call(this, ...args);
this.cd = cd;
this.knobChanged = this.knobChanged.bind(this);
this.setPaneKnobs = this.setPaneKnobs.bind(this);
};
NewComponent.prototype = Object.create(component.prototype);
NewComponent.__annotations__ = [new Component(componentMeta)];
NewComponent.__parameters__ = [[ChangeDetectorRef], ...params];

NewComponent.prototype.constructor = NewComponent;
NewComponent.prototype.ngOnInit = function onInit() {
KnobWrapperComponent.prototype = Object.create(component.prototype);
KnobWrapperComponent.__annotations__ = [new Component(componentMeta)];
KnobWrapperComponent.__parameters__ = [[ChangeDetectorRef], ...params];

KnobWrapperComponent.prototype.constructor = KnobWrapperComponent;
KnobWrapperComponent.prototype.ngOnInit = function onInit() {
if (component.prototype.ngOnInit) {
component.prototype.ngOnInit();
}
Expand All @@ -40,7 +44,7 @@ const getAnnotatedComponent = ({ componentMeta, component, params, knobStore, ch
this.setPaneKnobs();
};

NewComponent.prototype.ngOnDestroy = function onDestroy() {
KnobWrapperComponent.prototype.ngOnDestroy = function onDestroy() {
if (component.prototype.ngOnDestroy) {
component.prototype.ngOnDestroy();
}
Expand All @@ -50,20 +54,20 @@ const getAnnotatedComponent = ({ componentMeta, component, params, knobStore, ch
knobStore.unsubscribe(this.setPaneKnobs);
};

NewComponent.prototype.ngOnChanges = function onChanges(changes) {
KnobWrapperComponent.prototype.ngOnChanges = function onChanges(changes) {
if (component.prototype.ngOnChanges) {
component.prototype.ngOnChanges(changes);
}
};

NewComponent.prototype.setPaneKnobs = function setPaneKnobs(timestamp = +new Date()) {
KnobWrapperComponent.prototype.setPaneKnobs = function setPaneKnobs(timestamp = +new Date()) {
channel.emit('addon:knobs:setKnobs', {
knobs: knobStore.getAll(),
timestamp,
});
};

NewComponent.prototype.knobChanged = function knobChanged(change) {
KnobWrapperComponent.prototype.knobChanged = function knobChanged(change) {
const { name, value } = change;
const knobOptions = knobStore.get(name);
const oldValue = knobOptions.value;
Expand All @@ -77,12 +81,12 @@ const getAnnotatedComponent = ({ componentMeta, component, params, knobStore, ch
});
};

NewComponent.prototype.knobClicked = function knobClicked(clicked) {
KnobWrapperComponent.prototype.knobClicked = function knobClicked(clicked) {
const knobOptions = knobStore.get(clicked.name);
knobOptions.callback();
};

return NewComponent;
return KnobWrapperComponent;
};

const resetKnobs = (knobStore, channel) => {
Expand All @@ -95,7 +99,7 @@ const resetKnobs = (knobStore, channel) => {

export function prepareComponent({ getStory, context, channel, knobStore }) {
resetKnobs(knobStore, channel);
const { component, componentMeta, props, propsMeta, params } = getComponentMetadata(
const { component, componentMeta, props, pipes, propsMeta, params } = getComponentMetadata(
getStory(context)
);

Expand All @@ -112,6 +116,7 @@ export function prepareComponent({ getStory, context, channel, knobStore }) {
return {
component: AnnotatedComponent,
props,
pipes,
propsMeta,
};
}
31 changes: 31 additions & 0 deletions addons/knobs/src/angular/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable no-param-reassign */
/* globals window */

function getMeta(component, [name1, name2], defaultValue) {
if (!name2) {
name2 = name1;
name1 = `__${name1}__`;
}

if (component[name1]) {
return component[name1];
}

if (component[name2]) {
return component[name2];
}

return window.Reflect.getMetadata(name2, component) || defaultValue;
}

export function getAnnotations(component) {
return getMeta(component, ['annotations'], []);
}

export function getPropMetadata(component) {
return getMeta(component, ['__prop__metadata__', 'propMetadata'], {});
}

export function getParameters(component) {
return getMeta(component, ['parameters'], []);
}
2 changes: 1 addition & 1 deletion addons/storyshots/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"example": "jest storyshot.test"
},
"dependencies": {
"@storybook/channels": "^3.2.17",
"@storybook/channels": "^3.3.0-alpha.4",
"babel-core": "^6.26.0",
"babel-runtime": "^6.26.0",
"glob": "^7.1.2",
Expand Down
15 changes: 9 additions & 6 deletions app/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,10 @@
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": {
"dev": "DEV_BUILD=1 nodemon -e js,ts --watch ./src --exec 'npm run prepublish'",
"dev": "cross-env DEV_BUILD=1 nodemon -e js,ts --watch ./src --exec \"yarn prepare\"",
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@angular/common": "^5.0.0-beta.7",
"@angular/compiler": "^5.0.0-beta.7",
"@angular/core": "^5.0.0-beta.7",
"@angular/platform-browser": "^5.0.0-beta.7",
"@angular/platform-browser-dynamic": "^5.0.0-beta.7",
"@storybook/addon-actions": "^3.3.0-alpha.4",
"@storybook/addon-links": "^3.3.0-alpha.4",
"@storybook/addons": "^3.3.0-alpha.4",
Expand All @@ -50,6 +45,7 @@
"configstore": "^3.1.0",
"core-js": "^2.4.1",
"css-loader": "^0.28.1",
"cross-env": "^5.1.1",
"express": "^4.15.3",
"file-loader": "^0.11.1",
"find-cache-dir": "^1.0.0",
Expand Down Expand Up @@ -90,5 +86,12 @@
"mock-fs": "^4.3.0",
"nodemon": "^1.12.0",
"typescript": "^2.4.0"
},
"peerDependencies": {
"@angular/common": "=>4.0.0",
"@angular/compiler": "=>4.0.0",
"@angular/core": "=>4.0.0",
"@angular/platform-browser": "=>4.0.0",
"@angular/platform-browser-dynamic": "=>4.0.0"
}
}
3 changes: 2 additions & 1 deletion app/angular/src/client/preview/angular/app.token.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { InjectionToken } from "@angular/core";
import { InjectionToken, PipeTransform } from "@angular/core";

export const STORY = new InjectionToken<Data>("story");

export type Data = {
component: any;
props: object;
propsMeta: object;
pipes: PipeTransform[];
}
12 changes: 10 additions & 2 deletions app/angular/src/client/preview/angular/components/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
ViewChild,
ViewContainerRef,
ComponentFactoryResolver,
OnDestroy
OnDestroy,
EventEmitter
} from "@angular/core";
import { STORY, Data } from "../app.token";

Expand Down Expand Up @@ -41,7 +42,14 @@ export class AppComponent implements AfterViewInit, OnDestroy {
const instance = this.target.createComponent(compFactory).instance;

Object.keys(propsMeta).map(key => {
(<any>instance)[key] = props[key];
const value = (<any>props)[key];
const property = (<any>instance)[key];

if (!(property instanceof EventEmitter)) {
(<any>instance)[key] = (<any>props)[key];
} else if (typeof value === 'function') {
property.subscribe((<any>props)[key]);
}
});
}
}
Loading

0 comments on commit 6d80f69

Please sign in to comment.