Skip to content

Commit

Permalink
[framework] add ember support
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielcsapo committed Sep 27, 2018
1 parent 55ac6f9 commit 5dc9150
Show file tree
Hide file tree
Showing 61 changed files with 3,032 additions and 67 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ docs/public
storybook-static
built-storybooks
lib/cli/test
examples/ember-cli
*.bundle.js
*.js.map

Expand Down
1 change: 1 addition & 0 deletions addons/centered/ember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/ember');
23 changes: 23 additions & 0 deletions addons/centered/src/ember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { document } from 'global';
import styles from './styles';

function stylesToString(_styles) {
return Object.keys(_styles)
.map(key => `${key}:${_styles[key]}`)
.join(';');
}

export default function(storyFn) {
const { template, context } = storyFn();

const boundingDocument = document.createElement('div');
boundingDocument.innerHTML = `<div style="${stylesToString(styles.style)}">
<div id="component" style="${stylesToString(styles.innerStyle)}"></div>
</div>`;

return {
template,
context,
boundingDocument,
};
}
1 change: 1 addition & 0 deletions addons/storyshots/storyshots-core/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
settings: {
'import/core-modules': [
'@storybook/angular',
'@storybook/ember',
'@storybook/html',
'@storybook/react',
'@storybook/react-native',
Expand Down
29 changes: 29 additions & 0 deletions addons/storyshots/storyshots-core/src/frameworks/ember/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import global from 'global';
import configure from '../configure';

function test(options) {
return options.framework === 'ember';
}

function load(options) {
global.STORYBOOK_ENV = 'ember';

const { configPath, config } = options;
const storybook = require.requireActual('@storybook/ember');

configure({ configPath, config, storybook });

return {
framework: 'ember',
renderTree: require.requireActual('./renderTree').default,
renderShallowTree: () => {
throw new Error('Shallow renderer is not supported for HTML');
},
storybook,
};
}

export default {
load,
test,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { document, Node } from 'global';

function getRenderedTree(story, context) {
const component = story.render(context);

if (component instanceof Node) {
return component;
}

const section = document.createElement('section');
section.innerHTML = component;

if (section.childElementCount > 1) {
return section;
}

return section.firstChild;
}

export default getRenderedTree;
30 changes: 30 additions & 0 deletions app/ember/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Storybook for Ember

Storybook for Ember is a UI development environment for your Ember components.
With it, you can visualize different states of your UI components and develop them interactively.

![Storybook Screenshot](https://github.com/storybooks/storybook/blob/master/media/storybook-intro.gif)

Storybook runs outside of your app.
So you can develop UI components in isolation without worrying about app specific dependencies and requirements.

## Getting Started

```sh
npm i -g @storybook/cli
cd my-ember-app
getstorybook
```

For more information visit: [storybook.js.org](https://storybook.js.org)

* * *

Storybook also comes with a lot of [addons](https://storybook.js.org/addons/introduction) and a great API to customize as you wish.
You can also build a [static version](https://storybook.js.org/basics/exporting-storybook) of your storybook and deploy it anywhere you want.

## Docs

- [Basics](https://storybook.js.org/basics/introduction)
- [Configurations](https://storybook.js.org/configurations/default-config)
- [Addons](https://storybook.js.org/addons/introduction)
4 changes: 4 additions & 0 deletions app/ember/bin/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node

process.env.NODE_ENV = process.env.NODE_ENV || 'production';
require('../dist/server/build');
3 changes: 3 additions & 0 deletions app/ember/bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../dist/server');
38 changes: 38 additions & 0 deletions app/ember/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@storybook/ember",
"version": "4.0.0-alpha.23",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybooks/storybook/tree/master/app/ember",
"bugs": {
"url": "https://github.com/storybooks/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT",
"main": "dist/client/index.js",
"jsnext:main": "src/client/index.js",
"bin": {
"build-storybook": "./bin/build.js",
"start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js"
},
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@babel/runtime": "^7.0.0",
"@ember/test-helpers": "^0.7.25",
"@storybook/core": "4.0.0-alpha.23",
"babel-plugin-ember-modules-api-polyfill": "^2.4.0",
"babel-plugin-htmlbars-inline-precompile": "^1.0.0",
"common-tags": "^1.8.0",
"ember-cli-htmlbars-inline-precompile": "^1.0.3",
"ember-source": "^3.4.0",
"global": "^4.3.2"
},
"peerDependencies": {
"babel-loader": "^7.0.0 || ^8.0.0 || ^8.0.0-beta.6"
}
}
9 changes: 9 additions & 0 deletions app/ember/src/client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {
storiesOf,
setAddon,
addDecorator,
addParameters,
configure,
getStorybook,
forceReRender,
} from './preview';
3 changes: 3 additions & 0 deletions app/ember/src/client/preview/globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { window } from 'global';

window.STORYBOOK_ENV = 'ember';
18 changes: 18 additions & 0 deletions app/ember/src/client/preview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { start } from '@storybook/core/client';

import './globals';
import render from './render';

const { clientApi, configApi, forceReRender } = start(render);

export const {
storiesOf,
setAddon,
addDecorator,
addParameters,
clearDecorators,
getStorybook,
} = clientApi;

export const { configure } = configApi;
export { forceReRender };
91 changes: 91 additions & 0 deletions app/ember/src/client/preview/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* eslint-disable no-undef */
import { window, document } from 'global';
import { stripIndents } from 'common-tags';
import { getApplicationConfig } from './utils';

const config = getApplicationConfig();

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

const app = window.require(`${config.APP.name}/app`).default.create({
autoboot: false,
rootElement: rootEl,
});

let appInstance;

function render(options, el) {
const { template, context = {}, boundingDocument } = options;

if (!appInstance) {
app
.boot()
.then(() => {
const appInstancePrivate = app.buildInstance();
return appInstancePrivate.boot().then(() => {
appInstance = appInstancePrivate;

return appInstance;
});
})
.then(builtAppInstance => {
builtAppInstance.register(
'component:story-mode',
Ember.Component.extend({
layout: template || options,
...context,
})
);
const component = builtAppInstance.lookup('component:story-mode');

if (boundingDocument) {
component.appendTo(boundingDocument.querySelector('#component'));

el.append(boundingDocument);
} else {
component.appendTo(el);
}
});
} else {
$(appInstance.rootElement).empty();

appInstance.unregister('component:story-mode');

appInstance.register(
'component:story-mode',
Ember.Component.extend({
layout: template || options,
...context,
})
);
const component = appInstance.lookup('component:story-mode');

if (boundingDocument) {
component.appendTo(boundingDocument.querySelector('#component'));

el.append(boundingDocument);
} else {
component.appendTo(el);
}
}
}

export default function renderMain({ story, selectedKind, selectedStory, showMain, showError }) {
const element = story();

if (!element) {
showError({
title: `Expecting a Ember element from the story: "${selectedStory}" of "${selectedKind}".`,
description: stripIndents`
Did you forget to return the Ember element from the story?
Use "() => hbs('{{component}}')" or "() => { return {
template: hbs\`{{component}}\`
} }" when defining the story.
`,
});
return;
}

showMain();
render(element, rootEl);
}
21 changes: 21 additions & 0 deletions app/ember/src/client/preview/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { document } from 'global';

/**
* gets the application config from meta tag
* @return {Object} config object
*/
export function getApplicationConfig() {
let config = {};
const metas = document.getElementsByTagName('meta');

for (let i = 0; i < metas.length; i += 1) {
if (
metas[i].getAttribute('name') &&
metas[i].getAttribute('name').indexOf('config/environment') > -1
) {
config = JSON.parse(decodeURIComponent(metas[i].getAttribute('content')));
}
}

return config;
}
4 changes: 4 additions & 0 deletions app/ember/src/server/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { buildStatic } from '@storybook/core/server';
import options from './options';

buildStatic(options);
18 changes: 18 additions & 0 deletions app/ember/src/server/framework-preset-babel-ember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { precompile } from 'ember-source/dist/ember-template-compiler';

export function babel(config) {
// Ensure plugins are defined or fallback to an array to avoid empty values.
const babelConfigPlugins = config.plugins || [];

const extraPlugins = [
[require.resolve('babel-plugin-htmlbars-inline-precompile'), { precompile }],
[require.resolve('babel-plugin-ember-modules-api-polyfill')],
];

// If `babelConfigPlugins` is not an `Array`, calling `concat` will inject it
// as a single value, if it is an `Array` it will be spreaded.
return {
...config,
plugins: [].concat(babelConfigPlugins, extraPlugins),
};
}
5 changes: 5 additions & 0 deletions app/ember/src/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { buildDev } from '@storybook/core/server';

import options from './options';

buildDev(options);
7 changes: 7 additions & 0 deletions app/ember/src/server/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import packageJson from '../../package.json';

export default {
packageJson,
defaultConfigName: 'ember-cli',
frameworkPresets: [require.resolve('./framework-preset-babel-ember.js')],
};
9 changes: 9 additions & 0 deletions examples/ember-cli/.ember-cli
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.

Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": false
}
16 changes: 16 additions & 0 deletions examples/ember-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules

# testing
coverage

# production
build

# misc
.DS_Store
.env
npm-debug.log
tmp
9 changes: 9 additions & 0 deletions examples/ember-cli/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '@storybook/addon-a11y/register';
import '@storybook/addon-storysource/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-viewport/register';
import '@storybook/addon-options/register';
import '@storybook/addon-backgrounds/register';

0 comments on commit 5dc9150

Please sign in to comment.