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

Storybook for HTML snippets #3475

Merged
merged 62 commits into from
May 7, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
7a879b8
Add storybook for HTML snippets
Hypnosphi Apr 22, 2018
b155f65
Add docs
Hypnosphi Apr 22, 2018
64708c4
Add netlify context
Hypnosphi Apr 22, 2018
1a4adc7
Update Live examples section
Hypnosphi Apr 22, 2018
2652127
Add acceptance story
Hypnosphi Apr 22, 2018
099dd2c
Update storyshots
Hypnosphi Apr 22, 2018
9be6965
Merge branch 'master' into html
Hypnosphi Apr 22, 2018
4753936
Add CI build type
Hypnosphi Apr 22, 2018
cc5426e
TeamCity: fix syntax error
Hypnosphi Apr 22, 2018
167ec7d
TeamCity: temporary add only HTML dependency
Hypnosphi Apr 22, 2018
51559e0
Merge branch 'master' into html
Hypnosphi Apr 22, 2018
9243827
TeamCity: depend on HTML build
Hypnosphi Apr 22, 2018
1b76ab2
Revert "TeamCity: depend on HTML build"
Hypnosphi Apr 22, 2018
bc130ff
Merge branch 'master' into html
Hypnosphi Apr 22, 2018
46da4e3
Add StorySource addon
igor-dv Apr 23, 2018
17ae506
Add Viewport addon
igor-dv Apr 23, 2018
625ddbe
Add Options addon
igor-dv Apr 23, 2018
5163d52
TeamCity: make unmerged apps builds noop
Hypnosphi Apr 23, 2018
51cae39
Don't run chromatic twice
Hypnosphi Apr 23, 2018
fcaf79e
Merge branch 'master' into html
Hypnosphi Apr 23, 2018
35b91bd
TeamCity: enable HTML build
Hypnosphi Apr 23, 2018
17bf3be
Introduce subscriptionsStore
Hypnosphi Apr 23, 2018
931dadf
Add Centered addon
igor-dv Apr 24, 2018
c24e5ee
Add Notes addon
igor-dv Apr 24, 2018
f868afd
Add Storyshots addon
igor-dv Apr 24, 2018
e3c8db4
Remove unneeded statement
igor-dv Apr 24, 2018
902a0cb
Reuse divs in Centered addon
igor-dv Apr 25, 2018
a37f096
Update snapshot + allow returning multiple children for storyshots
igor-dv Apr 25, 2018
20cace2
Add multiple nodes example
igor-dv Apr 25, 2018
715f2d8
Merge branch 'master' into html
Hypnosphi Apr 25, 2018
e42a800
Merge branch 'master' into html
Hypnosphi Apr 25, 2018
322be35
Add Knobs addon
igor-dv Apr 25, 2018
4f7f2eb
window => global
Hypnosphi Apr 25, 2018
ea48bae
Update knobs example
igor-dv Apr 25, 2018
805ef36
Simplify knobs registration for HTML app
igor-dv Apr 25, 2018
8b21185
Few fixes + more knobs examples
igor-dv Apr 25, 2018
6e17afc
Merge remote-tracking branch 'origin/master' into html
Hypnosphi Apr 25, 2018
9a919ff
Integrate changes from #3487
Hypnosphi Apr 25, 2018
8e8ba81
Merge remote-tracking branch 'origin/master' into html
Hypnosphi Apr 30, 2018
f5df963
Update version
Hypnosphi Apr 30, 2018
486f278
Fix missed "mithrils"
Hypnosphi Apr 30, 2018
81d3e5b
Merge branch 'master' into html
Hypnosphi Apr 30, 2018
944873d
Merge remote-tracking branch 'origin/master' into html
Hypnosphi May 1, 2018
61f1291
Integrate changes from #3472
Hypnosphi May 1, 2018
8603038
Merge remote-tracking branch 'origin/master' into html
Hypnosphi May 1, 2018
51eeaa0
Merge branch 'postmessage-same-sender' into html
Hypnosphi May 1, 2018
60c96ae
Use force re-render event in knobs
Hypnosphi May 1, 2018
0a5a468
Make welcome story default
Hypnosphi May 1, 2018
61f3232
Introduce "register subscription" event, move declarative links decor…
Hypnosphi May 1, 2018
c12de16
Update snapshots
igor-dv May 2, 2018
4a86624
Merge branch 'master' into html
Hypnosphi May 2, 2018
6df6a3c
Integrate changes from #3520
Hypnosphi May 2, 2018
100985b
withActions decorator
Hypnosphi May 2, 2018
0ad1dd9
Fix for RN
Hypnosphi May 2, 2018
adcbc00
Commit storyshot
Hypnosphi May 2, 2018
6d661af
Addon-a11y support
Hypnosphi May 2, 2018
3851174
Addon-backgrouns support
Hypnosphi May 2, 2018
71f72f0
Commit storyshot
Hypnosphi May 3, 2018
bf86c0c
Addon-events support
Hypnosphi May 3, 2018
8bf5af8
Addon-jest support
Hypnosphi May 4, 2018
3605b76
Commit storyshots
Hypnosphi May 5, 2018
10fa1dc
Refer to html guide in slow start guide
Hypnosphi May 5, 2018
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ For additional help, join us [in our Slack](https://now-examples-slackin-rrirkqo
- [React Native](app/react-native)
- [Vue](app/vue)
- [Angular](app/angular)
- [Polymer](app/polymer) <sup>release candidate</sup>
- [Polymer](app/polymer)
- [Mithril](app/mithril) <sup>alpha</sup>
- [HTML](app/html) <sup>alpha</sup>

### Sub Projects

Expand Down
3 changes: 3 additions & 0 deletions app/html/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
docs
src
.babelrc
26 changes: 26 additions & 0 deletions app/html/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Storybook for HTML <sup>alpha</sup>

* * *

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

![Storybook Screenshot](https://github.com/storybooks/storybook/blob/master/app/html/docs/demo.png)

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-app
getstorybook --html
```

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.
3 changes: 3 additions & 0 deletions app/html/bin/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

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

require('../dist/server');
Binary file added app/html/docs/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions app/html/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "@storybook/html",
"version": "4.0.0-alpha.3",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"homepage": "https://github.com/storybooks/storybook/tree/master/apps/html",
"bugs": {
"url": "https://github.com/storybooks/storybook/issues"
},
"license": "MIT",
"main": "dist/client/index.js",
"bin": {
"build-storybook": "./bin/build.js",
"start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js"
},
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/core": "4.0.0-alpha.3",
"@storybook/react-dev-utils": "^5.0.0",
"airbnb-js-shims": "^1.4.1",
"babel-loader": "^7.1.4",
"babel-plugin-macros": "^2.2.0",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.0",
"babel-preset-minify": "^0.4.0",
"babel-preset-stage-0": "^6.24.1",
"babel-runtime": "^6.26.0",
"case-sensitive-paths-webpack-plugin": "^2.1.2",
"common-tags": "^1.4.0",
"core-js": "^2.5.5",
"dotenv-webpack": "^1.5.5",
"global": "^4.3.2",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.6.0",
"webpack-hot-middleware": "^2.22.1"
},
"peerDependencies": {
"babel-core": "^6.26.0 || ^7.0.0-0",
"babel-runtime": ">=6.0.0"
},
"devDependencies": {
"html-loader": "^0.5.5",
"markdown-loader": "^2.0.2"
}
}
8 changes: 8 additions & 0 deletions app/html/src/client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export {
storiesOf,
setAddon,
addDecorator,
addParameters,
configure,
getStorybook,
} from './preview';
17 changes: 17 additions & 0 deletions app/html/src/client/preview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { start } from '@storybook/core/client';

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 };
25 changes: 25 additions & 0 deletions app/html/src/client/preview/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { document, Node } from 'global';
import { stripIndents } from 'common-tags';

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

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

if (typeof component === 'string') {
rootElement.innerHTML = component;
} else if (component instanceof Node) {
rootElement.innerHTML = '';
rootElement.appendChild(component);
} else {
showError({
message: `Expecting an HTML snippet or DOM node from the story: "${selectedStory}" of "${selectedKind}".`,
stack: stripIndents`
Did you forget to return the HTML snippet from the story?
Use "() => <your snippet or node>" or when defining the story.
`,
});
return;
}
showMain();
}
12 changes: 12 additions & 0 deletions app/html/src/server/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { buildStatic } from '@storybook/core/server';
import path from 'path';
import packageJson from '../../package.json';
import getBaseConfig from './config/webpack.config.prod';
import loadConfig from './config';

buildStatic({
packageJson,
getBaseConfig,
loadConfig,
defaultFavIcon: path.resolve(__dirname, 'public/favicon.ico'),
});
8 changes: 8 additions & 0 deletions app/html/src/server/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { configLoaderCreator } from '@storybook/core/server';
import defaultConfig from './config/babel';

const configLoader = configLoaderCreator({
defaultBabelConfig: defaultConfig,
});

export default configLoader;
28 changes: 28 additions & 0 deletions app/html/src/server/config/babel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
// Don't try to find .babelrc because we want to force this configuration.
babelrc: false,
presets: [
[
require.resolve('babel-preset-env'),
{
targets: {
browsers: ['last 2 versions', 'safari >= 7'],
},
modules: process.env.NODE_ENV === 'test' ? 'commonjs' : false,
},
],
require.resolve('babel-preset-stage-0'),
],
plugins: [
require.resolve('babel-plugin-macros'),
require.resolve('babel-plugin-transform-regenerator'),
[
require.resolve('babel-plugin-transform-runtime'),
{
helpers: true,
polyfill: true,
regenerator: true,
},
],
],
};
33 changes: 33 additions & 0 deletions app/html/src/server/config/babel.prod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
// Don't try to find .babelrc because we want to force this configuration.
babelrc: false,
presets: [
[
require.resolve('babel-preset-env'),
{
targets: {
browsers: ['last 2 versions', 'safari >= 7'],
},
modules: false,
},
],
require.resolve('babel-preset-stage-0'),
[
require.resolve('babel-preset-minify'),
{
mangle: false,
},
],
],
plugins: [
require.resolve('babel-plugin-transform-regenerator'),
[
require.resolve('babel-plugin-transform-runtime'),
{
helpers: true,
polyfill: true,
regenerator: true,
},
],
],
};
4 changes: 4 additions & 0 deletions app/html/src/server/config/globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { window } from 'global';

window.STORYBOOK_REACT_CLASSES = {};
window.STORYBOOK_ENV = 'HTML';
3 changes: 3 additions & 0 deletions app/html/src/server/config/polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'core-js/es6/symbol';
import 'core-js/fn/array/iterator';
import 'airbnb-js-shims';
35 changes: 35 additions & 0 deletions app/html/src/server/config/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import path from 'path';

export const includePaths = [path.resolve('./')];

export const excludePaths = [path.resolve('node_modules')];

export const nodeModulesPaths = path.resolve('./node_modules');

export const nodePaths = (process.env.NODE_PATH || '')
.split(process.platform === 'win32' ? ';' : ':')
.filter(Boolean)
.map(p => path.resolve('./', p));

// Load environment variables starts with STORYBOOK_ to the client side.
export function loadEnv(options = {}) {
const defaultNodeEnv = options.production ? 'production' : 'development';
const env = {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || defaultNodeEnv),
// This is to support CRA's public folder feature.
// In production we set this to dot(.) to allow the browser to access these assests
// even when deployed inside a subpath. (like in GitHub pages)
// In development this is just empty as we always serves from the root.
PUBLIC_URL: JSON.stringify(options.production ? '.' : ''),
};

Object.keys(process.env)
.filter(name => /^STORYBOOK_/.test(name))
.forEach(name => {
env[name] = JSON.stringify(process.env[name]);
});

return {
'process.env': env,
};
}
109 changes: 109 additions & 0 deletions app/html/src/server/config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import path from 'path';
import webpack from 'webpack';
import Dotenv from 'dotenv-webpack';
import InterpolateHtmlPlugin from '@storybook/react-dev-utils/InterpolateHtmlPlugin';
import WatchMissingNodeModulesPlugin from '@storybook/react-dev-utils/WatchMissingNodeModulesPlugin';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import {
managerPath,
getPreviewHeadHtml,
getManagerHeadHtml,
indexHtmlPath,
iframeHtmlPath,
} from '@storybook/core/server';

import { includePaths, excludePaths, nodeModulesPaths, loadEnv, nodePaths } from './utils';
import babelLoaderConfig from './babel';
import { version } from '../../../package.json';

export default function(configDir) {
const config = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: {
manager: [require.resolve('./polyfills'), managerPath],
preview: [
require.resolve('./polyfills'),
require.resolve('./globals'),
`${require.resolve('webpack-hot-middleware/client')}?reload=true`,
],
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'static/[name].bundle.js',
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
chunks: ['manager'],
chunksSortMode: 'none',
data: {
managerHead: getManagerHeadHtml(configDir),
version,
},
template: indexHtmlPath,
}),
new HtmlWebpackPlugin({
filename: 'iframe.html',
excludeChunks: ['manager'],
chunksSortMode: 'none',
data: {
previewHead: getPreviewHeadHtml(configDir),
},
template: iframeHtmlPath,
}),
new InterpolateHtmlPlugin(process.env),
new webpack.DefinePlugin(loadEnv()),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new WatchMissingNodeModulesPlugin(nodeModulesPaths),
new webpack.ProgressPlugin(),
new Dotenv({ silent: true }),
],
module: {
rules: [
{
test: /\.js$/,
loader: require.resolve('babel-loader'),
query: babelLoaderConfig,
include: includePaths,
exclude: excludePaths,
},
{
test: /\.html$/,
use: [
{
loader: require.resolve('html-loader'),
},
],
},
{
test: /\.md$/,
use: [
{
loader: require.resolve('html-loader'),
},
{
loader: require.resolve('markdown-loader'),
},
],
},
],
},
resolve: {
// Since we ship with json-loader always, it's better to move extensions to here
// from the default config.
extensions: ['.js', '.json'],
// Add support to NODE_PATH. With this we could avoid relative path imports.
// Based on this CRA feature: https://github.com/facebookincubator/create-react-app/issues/253
modules: ['node_modules'].concat(nodePaths),
},
performance: {
hints: false,
},
};

return config;
}
Loading