Skip to content

Commit

Permalink
riot integration
Browse files Browse the repository at this point in the history
  • Loading branch information
libetl committed Aug 26, 2018
1 parent b71117d commit 30a05ba
Show file tree
Hide file tree
Showing 59 changed files with 1,709 additions and 12 deletions.
10 changes: 10 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
- examples/polymer-cli/node_modules
- examples/vue-kitchen-sink/node_modules
- examples/svelte-kitchen-sink/node_modules
- examples/riot-kitchen-sink/node_modules
- examples/marko-cli/node_modules
- addons
- app
Expand Down Expand Up @@ -71,6 +72,11 @@ jobs:
command: |
cd examples/svelte-kitchen-sink
yarn build-storybook
- run:
name: Build riot kitchen-sking
command: |
cd examples/riot-kitchen-sink
yarn build-storybook
- run:
name: Build angular-cli
command: |
Expand Down Expand Up @@ -123,6 +129,10 @@ jobs:
command: |
cd examples/svelte-kitchen-sink
yarn storybook --smoke-test
- run:
name: Run riot kitchen-sink (smoke test)
cd examples/riot-kitchen-sink
yarn storybook --smoke-test
- run:
name: Run angular-cli (smoke test)
command: |
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ For additional help, join us [in our Slack](https://now-examples-slackin-rrirkqo
- [Marko](app/marko) <sup>alpha</sup> [![Marko](https://img.shields.io/npm/dt/@storybook/marko.svg)](app/marko)
- [HTML](app/html) <sup>alpha</sup> [![HTML](https://img.shields.io/npm/dt/@storybook/html.svg)](app/html)
- [Svelte](app/svelte) <sup>alpha</sup> [![Svelte](https://img.shields.io/npm/dt/@storybook/svelte.svg)](app/svelte)
- [Riot](app/riot) <sup>alpha</sup> [![Riot](https://img.shields.io/npm/dt/@storybook/riot.svg)](app/riot)

### Sub Projects

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

* * *

Storybook for Riot is a UI development environment for the components written with riot.js.
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-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.
4 changes: 4 additions & 0 deletions app/riot/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/riot/bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../dist/server');
49 changes: 49 additions & 0 deletions app/riot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@storybook/riot",
"version": "4.0.0-alpha.18",
"description": "Storybook for riot.js: View riot snippets in isolation with Hot Reloading.",
"homepage": "https://github.com/storybooks/storybook/tree/master/app/riot",
"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",
"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-rc.2",
"@storybook/core": "4.0.0-alpha.18",
"common-tags": "^1.8.0",
"global": "^4.3.2",
"moment": "^2.22.2",
"riot": "^3.11.1",
"riot-hot-reload": "^1.0.0",
"riot-tag-loader": "^2.1.0",
"raw-loader": "^0.5.1",
"riot-compiler": "^3.5.1",
"react": "^16.4.2",
"react-dom": "^16.4.2"
},
"devDependencies": {
"cross-env": "^5.2.0",
"@babel/preset-flow": "^7.0.0-rc.2",
"@babel/preset-react": "^7.0.0-rc.2",
"@babel/runtime": "^7.0.0-rc.2",
"@babel/preset-env": "^7.0.0-rc.2",
"@babel/plugin-transform-runtime": "^7.0.0-rc.2",
"@babel/plugin-transform-modules-commonjs": "^7.0.0-rc.2"
},
"peerDependencies": {
"babel-core": "^7.0.0 || ^8.0.0 || ^8.0.0-beta.6"
}
}
9 changes: 9 additions & 0 deletions app/riot/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/riot/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 = 'riot';
18 changes: 18 additions & 0 deletions app/riot/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 };
66 changes: 66 additions & 0 deletions app/riot/src/client/preview/render-riot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export function guessRootName(stringified) {
return stringified.trim().match(/^<[^ >]+\/>$/)
? stringified.trim().replace(/[<>/]/g, '')
: stringified.substring(
stringified.indexOf('<') + 1,
Math.min(stringified.indexOf(' ', stringified.indexOf('<') + 1), stringified.indexOf('>'))
);
}

export function renderStringified(
{ tags, scenario = `<${(tags[0] || []).boundAs || guessRootName(tags[0] || '')}/>` },
{ unregister, tag2, mount, compiler } // eslint-disable-line no-unused-vars
) {
unregister('root');
unregister('div');
unregister('p');
unregister('span');
tags.forEach(oneTag => {
const rootName = oneTag.boundAs || guessRootName(oneTag);
const { content } = oneTag || {};
const sourceCode = content ? content.trim() : oneTag;
const compiled = compiler
.compile(sourceCode, {})
.replace("var riot = require('riot')", '')
.trim();
unregister(rootName);
eval(`${compiled}`.replace(/riot\.tag2/g, 'tag2')); // eslint-disable-line no-eval
});
const sourceCode = `<root>${scenario}</root>`;
eval(`${compiler.compile(sourceCode, {})}`.replace(/riot\.tag2/g, 'tag2')); // eslint-disable-line no-eval
mount('*');
}

// eslint-disable-next-line no-unused-vars
export function renderRaw(sourceCode, { unregister, mount, compiler, tag2 }) {
unregister('root');
// eslint-disable-next-line no-eval
eval(
`${compiler.compile(sourceCode.replace("var riot = require('riot')", '').trim(), {})}`.replace(
/riot.tag2/g,
'tag2'
)
);
mount('root', /riot\.tag2\s*\(\s*'([^']+)'/.exec(sourceCode)[1], {});
}

export function renderCompiledObject(component, { rootElement }) {
rootElement.appendChild((!component.length ? component : component)[0].__.root); // eslint-disable-line no-underscore-dangle
}

export function render(component, context) {
const { tags } = component || {};
if (typeof component === 'string') {
renderRaw(component, context);
return true;
}
if (Array.isArray(tags)) {
renderStringified(component, context);
return true;
}
if (component && typeof component === 'object') {
renderCompiledObject(component, context);
return true;
}
return false;
}
28 changes: 28 additions & 0 deletions app/riot/src/client/preview/render-riot.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { document } from 'global';
import { render } from './render-riot';

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

const defaultContext = {
unregister: () => {},
rootElement,
compiler: { compile: () => "riot.tag2('test', '<div></div>')" },
tag2: () => {},
mount: () => {},
};

describe('render a riot element', () => {
it('should not work with nothing', () => {
expect(render(null, { ...defaultContext })).toBe(false);
});

it('can work with some text', () => {
render({ tags: ['<div><p>some test</p></div>'] }, { ...defaultContext });
});

it('can work with raw code', () => {
render("riot.tag2('test', '<div>simple test ({ opts.value })</div>', '', '', () => {})", {
...defaultContext,
});
});
});
23 changes: 23 additions & 0 deletions app/riot/src/client/preview/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { document } from 'global';
import { stripIndents } from 'common-tags';
import { mount, unregister, tag2 } from 'riot';
import compiler from 'riot-compiler';
import { render as renderRiot } from './render-riot';

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

export default function renderMain({ story, selectedKind, selectedStory, showMain, showError }) {
showMain();
rootElement.innerHTML = '<root></root>';
const context = { unregister, mount, tag2, compiler, rootElement };
const component = story();
const rendered = renderRiot(component, context);
if (!rendered)
showError({
title: `Expecting a riot snippet or a riot component from the story: "${selectedStory}" of "${selectedKind}".`,
description: stripIndents`
Did you forget to return the component snippet from the story?
Use "() => <your snippet or node>" or when defining the story.
`,
});
}
4 changes: 4 additions & 0 deletions app/riot/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);
5 changes: 5 additions & 0 deletions app/riot/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);
8 changes: 8 additions & 0 deletions app/riot/src/server/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import packageJson from '../../package.json';

import wrapInitialConfig from './wrapInitialConfig';

export default {
packageJson,
wrapInitialConfig,
};
17 changes: 17 additions & 0 deletions app/riot/src/server/wrapInitialConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default config => ({
...config,
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.tag$/,
use: [
{
loader: require.resolve('riot-tag-loader'),
},
],
},
],
},
});
15 changes: 15 additions & 0 deletions examples/riot-kitchen-sink/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 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
8 changes: 8 additions & 0 deletions examples/riot-kitchen-sink/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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';
15 changes: 15 additions & 0 deletions examples/riot-kitchen-sink/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { configure } from '@storybook/riot';
import { setOptions } from '@storybook/addon-options';

setOptions({
hierarchyRootSeparator: /\|/,
});

function loadStories() {
require('../src/stories');

const req = require.context('../src/stories', true, /\.stories\.js$/);
req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
12 changes: 12 additions & 0 deletions examples/riot-kitchen-sink/.storybook/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('path');

module.exports = (storybookBaseConfig, configType, defaultConfig) => {
defaultConfig.module.rules.push({
test: [/\.stories\.js$/, /index\.js$/],
loaders: [require.resolve('@storybook/addon-storysource/loader')],
include: [path.resolve(__dirname, '../src')],
enforce: 'pre',
});

return defaultConfig;
};
3 changes: 3 additions & 0 deletions examples/riot-kitchen-sink/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Storybook Demo

This is a demo app to test riot.js integration with Storybook. Run `npm install` to sync Storybook module with the source code and run `npm run storybook` to start the Storybook.
11 changes: 11 additions & 0 deletions examples/riot-kitchen-sink/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>demo2</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
Loading

0 comments on commit 30a05ba

Please sign in to comment.