Skip to content

Commit

Permalink
Merge pull request #2467 from storybooks/angular-versions-support
Browse files Browse the repository at this point in the history
Angular versions support
  • Loading branch information
igor-dv authored Dec 20, 2017
2 parents cb34518 + cc32f92 commit 6c28b98
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 64 deletions.
2 changes: 1 addition & 1 deletion addons/knobs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"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",
Expand All @@ -34,6 +33,7 @@
},
"peerDependencies": {
"@storybook/addons": "^3.3.0-alpha.4",
"@angular/core": "=>4.0.0",
"react": "*",
"react-dom": "*"
}
Expand Down
33 changes: 18 additions & 15 deletions addons/knobs/src/angular/helpers.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* eslint no-underscore-dangle: 0 */

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

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,
Expand All @@ -19,18 +21,19 @@ const getComponentMetadata = ({ component, props = {}, pipes = [] }) => {
};

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 @@ -41,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 @@ -51,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 @@ -78,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 Down
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'], []);
}
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"
}
}
40 changes: 21 additions & 19 deletions app/angular/src/client/preview/angular/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,45 @@ import {
enableProdMode,
NgModule,
Component,
NgModuleRef,
ApplicationRef,
CUSTOM_ELEMENTS_SCHEMA
} from "@angular/core";

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./components/app.component";
import { ErrorComponent } from "./components/error.component";
import { NoPreviewComponent } from "./components/no-preview.component";
import { STORY } from "./app.token";
import { getAnnotations, getParameters, getPropMetadata } from './utils';

let platform = null;
let promises = [];

// Taken from https://davidwalsh.name/javascript-debounce-function
// We don't want to pull underscore

const debounce = (func, wait = 100, immediate = false) => {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};

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

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

Object.keys(propsMeta).map(key => {
propsMetadata[key] = propsMeta[key];
Expand All @@ -61,10 +60,12 @@ const getAnnotatedComponent = (meta, component, propsMeta, params) => {
const NewComponent: any = function NewComponent(...args) {
component.call(this, ...args);
};

NewComponent.prototype = Object.create(component.prototype);
NewComponent.annotations = [new Component(meta)];
NewComponent.parameters = params;
NewComponent.propsMetadata = propsMeta;

return NewComponent;
};

Expand All @@ -79,6 +80,7 @@ const getModule = (declarations, entryComponents, bootstrap, data) => {
});

const NewModule: any = function NewModule() {};

NewModule.annotations = [moduleMeta];

return NewModule;
Expand Down
28 changes: 28 additions & 0 deletions app/angular/src/client/preview/angular/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function getMeta(component, [name1, name2]: any, 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 app/angular/src/server/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default function() {
new WatchMissingNodeModulesPlugin(nodeModulesPaths),
new webpack.ProgressPlugin(),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
/angular(\\|\/)core(\\|\/)(@angular|esm5)/,
path.resolve(__dirname, '../src')
),
],
Expand Down
2 changes: 1 addition & 1 deletion app/angular/src/server/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default function() {
},
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
/angular(\\|\/)core(\\|\/)(@angular|esm5)/,
path.resolve(__dirname, '../src')
),
],
Expand Down
6 changes: 4 additions & 2 deletions examples/angular-cli/src/stories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ storiesOf('Addon Notes', module)
withNotes({ text: 'My notes on some button' })(() => ({
component: Button,
props: {
text: 'Notes on some Button'
text: 'Notes on some Button',
onClick: () => {},
}
}))
)
Expand All @@ -122,7 +123,8 @@ storiesOf('Addon Notes', module)
})(() => ({
component: Button,
props: {
text: 'Notes with HTML'
text: 'Notes with HTML',
onClick: () => {},
}
}))
);
Expand Down
18 changes: 9 additions & 9 deletions lib/cli/test/fixtures/angular-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@
},
"private": true,
"dependencies": {
"@angular/common": "^2.3.1",
"@angular/compiler": "^2.3.1",
"@angular/core": "^2.3.1",
"@angular/forms": "^2.3.1",
"@angular/http": "^2.3.1",
"@angular/platform-browser": "^2.3.1",
"@angular/platform-browser-dynamic": "^2.3.1",
"@angular/router": "^3.3.1",
"@angular/common": "4.0.0",
"@angular/compiler": "4.0.0",
"@angular/core": "4.0.0",
"@angular/forms": "4.0.0",
"@angular/http": "4.0.0",
"@angular/platform-browser": "4.0.0",
"@angular/platform-browser-dynamic": "4.0.0",
"@angular/router": "4.0.0",
"core-js": "^2.4.1",
"rxjs": "^5.0.1",
"ts-helpers": "^1.1.1",
"zone.js": "^0.7.2"
},
"devDependencies": {
"@angular/compiler-cli": "^2.3.1",
"@angular/compiler-cli": "4.0.0",
"@types/jasmine": "2.5.38",
"@types/node": "^6.0.42",
"angular-cli": "1.0.0-beta.28.3",
Expand Down
18 changes: 9 additions & 9 deletions lib/cli/test/snapshots/angular-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
},
"private": true,
"dependencies": {
"@angular/common": "^2.3.1",
"@angular/compiler": "^2.3.1",
"@angular/core": "^2.3.1",
"@angular/forms": "^2.3.1",
"@angular/http": "^2.3.1",
"@angular/platform-browser": "^2.3.1",
"@angular/platform-browser-dynamic": "^2.3.1",
"@angular/router": "^3.3.1",
"@angular/common": "4.0.0",
"@angular/compiler": "4.0.0",
"@angular/core": "4.0.0",
"@angular/forms": "4.0.0",
"@angular/http": "4.0.0",
"@angular/platform-browser": "4.0.0",
"@angular/platform-browser-dynamic": "4.0.0",
"@angular/router": "4.0.0",
"core-js": "^2.4.1",
"rxjs": "^5.0.1",
"ts-helpers": "^1.1.1",
"zone.js": "^0.7.2"
},
"devDependencies": {
"@angular/compiler-cli": "^2.3.1",
"@angular/compiler-cli": "4.0.0",
"@types/jasmine": "2.5.38",
"@types/node": "^6.0.42",
"angular-cli": "1.0.0-beta.28.3",
Expand Down
Loading

0 comments on commit 6c28b98

Please sign in to comment.