Merge branch 'next' into separate-manager-preview-p5

This commit is contained in:
Norbert de Langen 2018-11-27 19:30:37 +01:00
commit 006429301a
No known key found for this signature in database
GPG Key ID: 976651DA156C2825
27 changed files with 541 additions and 113 deletions

View File

@ -15,6 +15,7 @@
|[links](addons/links) |+|+|+|+|+|+|+| |+|+|+|
|[notes](addons/notes) |+|+*|+|+|+|+|+| |+|+|+|
|[options](addons/options) |+|+|+|+|+|+|+| |+|+|+|
|[cssresources](addons/cssresources) |+| |+|+|+|+|+|+|+|+|+|
|[storyshots](addons/storyshots) |+|+|+|+| | |+| |+|+| |
|[storysource](addons/storysource) |+| |+|+|+|+|+|+|+|+|+|
|[viewport](addons/viewport) |+| |+|+|+|+|+|+|+|+|+|

View File

@ -110,6 +110,7 @@ For additional help, join us [in our Discord](https://discord.gg/sMFvFsG) or [Sl
| [actions](addons/actions/) | Log actions as users interact with components in the Storybook UI |
| [backgrounds](addons/backgrounds/) | Let users choose backgrounds in the Storybook UI |
| [centered](addons/centered/) | Center the alignment of your components within the Storybook UI |
| [cssresources](addons/cssresources/) | Dynamically add/remove css resources to the component iframe |
| [events](addons/events/) | Interactively fire events to components that respond to EventEmitter |
| [graphql](addons/graphql/) | Query a GraphQL server within Storybook stories |
| [google-analytics](addons/google-analytics) | Reports google analytics on stories |

View File

@ -0,0 +1,63 @@
# Storybook Addon Cssresources
Storybook Addon Cssresources to switch between css resources at runtime for your story [Storybook](https://storybook.js.org).
[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)
![Storybook Addon Cssresources Demo](docs/demo.gif)
## Installation
```sh
yarn add -D @storybook/addon-cssresources
```
## Configuration
Then create a file called `addons.js` in your storybook config.
Add following content to it:
```js
import '@storybook/addon-cssresources/register';
```
## Usage
You need add the all the css resources at compile time using the `withCssResources` decorator. They can be added globally or per story. You can then choose which ones to load from the cssresources addon ui:
```js
// Import from @storybook/X where X is your framework
import { configure, addDecorator, storiesOf } from '@storybook/react';
import { withCssResources } from '@storybook/addon-cssresources';
// global
addDecorator(
withCssResources({
cssresources: [{
name: `bluetheme`,
code: `<style>body { background-color: lightblue; }</style>`,
picked: false,
},
],
})
);
// per story
storiesOf('Addons|Cssresources', module)
.addDecorator(
withCssResources({
cssresources: [{
name: `fontawesome`,
code: `<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"></link>`,
picked: true,
}, {
name: `whitetheme`,
code: `<style>.fa { color: #fff }</style>`,
picked: true,
},
],
})
)
.add('Camera Icon', () => <i className="fa fa-camera-retro"> Camera Icon</i>);
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 MiB

View File

@ -0,0 +1,39 @@
{
"name": "@storybook/addon-cssresources",
"version": "4.1.0-alpha.8",
"description": "A storybook addon to switch between css resources at runtime for your story",
"keywords": [
"addon",
"cssresources",
"react",
"storybook"
],
"homepage": "https://storybook.js.org",
"bugs": {
"url": "https://github.com/storybooks/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT",
"author": "nm123github",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@emotion/styled": "0.10.6",
"@storybook/addons": "4.1.0-alpha.8",
"@storybook/components": "4.1.0-alpha.8",
"@storybook/core-events": "4.1.0-alpha.8",
"global": "^4.3.2",
"prop-types": "^15.6.2",
"react-syntax-highlighter": "^10.0.0",
"util-deprecate": "^1.0.2"
},
"peerDependencies": {
"react": "*"
}
}

View File

@ -0,0 +1 @@
require('./dist/register.js');

View File

@ -0,0 +1,147 @@
import { document, DOMParser } from 'global';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { monoFonts } from '@storybook/components';
import styled from '@emotion/styled';
import css from 'react-syntax-highlighter/dist/esm/languages/prism/css';
import { darcula } from 'react-syntax-highlighter/dist/esm/styles/prism';
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light';
SyntaxHighlighter.registerLanguage('css', css);
const storybookIframe = 'storybook-preview-iframe';
const addedElAttr = 'addedbycssresourcesaddon';
// Taken from StoryPanel.js
const highlighterTheme = {
...darcula,
'pre[class*="language-"]': {
...darcula['pre[class*="language-"]'],
margin: 'auto',
width: 'auto',
height: 'auto',
minHeight: '100%',
overflow: 'hidden',
boxSizing: 'border-box',
display: 'flex',
fontFamily: monoFonts.fontFamily,
fontSize: 'inherit',
},
'code[class*="language-"]': {
...darcula['code[class*="language-"]'],
margin: 0,
fontFamily: 'inherit',
},
};
const PanelWrapper = styled.div({
position: 'absolute',
top: '10px',
left: '10px',
fontFamily: monoFonts.fontFamily,
});
export default class CssResourcePanel extends Component {
constructor(props) {
super(props);
this.state = { cssresources: `` };
this.onAddCssresources = this.onAddCssresources.bind(this);
this.parser = new DOMParser();
}
componentDidMount() {
const { channel } = this.props;
this.iframe = document.getElementById(storybookIframe);
if (!this.iframe) {
throw new Error('Cannot find Storybook iframe');
}
channel.on('storybook/resources/add_cssresources', this.onAddCssresources);
}
componentWillUnmount() {
const { channel } = this.props;
channel.removeListener('storybook/resources/add_cssresources', this.onAddCssresources);
}
onAddCssresources(cssresources) {
this.loadCssresources(cssresources.filter(res => res.picked));
this.setState(prevState => ({ ...prevState, cssresources }));
}
handleChange(i, { target }) {
const { channel } = this.props;
const { cssresources = [] } = this.state;
cssresources[i].picked = target.checked;
channel.emit('storybook/resources/add_cssresources', cssresources);
}
loadCssresources(cssresources) {
// remove previously added elements!
this.iframe.contentDocument.head.querySelectorAll(`[${addedElAttr}]`).forEach(eL => {
if (eL) {
eL.parentNode.removeChild(eL);
}
});
// add new elements!
const str = cssresources.map(res => res.code).join('');
const parsedHtml = this.parser.parseFromString(str, 'text/html');
const elements = parsedHtml.querySelectorAll('head > *');
elements.forEach(eL => {
// add addedElAttr to css elements
eL.setAttribute(addedElAttr, '');
this.iframe.contentDocument.head.appendChild(eL);
});
}
render() {
const { cssresources = [] } = this.state;
const { active } = this.props;
if (!active) {
return null;
}
return (
<PanelWrapper className="addon-cssresources-container">
{cssresources &&
cssresources.map(({ name, code, picked }, i) => (
<div key={name} style={{ padding: 10 }}>
<div style={{ fontSize: '1.1em', marginBottom: 10 }}>
<input
id={`cssresource${i}`}
style={{ fontSize: '1.5em' }}
type="checkbox"
checked={picked}
onChange={this.handleChange.bind(this, i)}
/>
<label htmlFor={`cssresource${i}`}>#{name}</label>
</div>
<SyntaxHighlighter
language="css"
style={highlighterTheme}
customStyle={{ opacity: picked ? 1 : 0.5 }}
>
{code}
</SyntaxHighlighter>
</div>
))}
</PanelWrapper>
);
}
}
CssResourcePanel.propTypes = {
active: PropTypes.bool.isRequired,
channel: PropTypes.shape({
on: PropTypes.func,
emit: PropTypes.func,
removeListener: PropTypes.func,
}).isRequired,
api: PropTypes.shape({
onStory: PropTypes.func,
getQueryParam: PropTypes.func,
setQueryParams: PropTypes.func,
}).isRequired,
};

View File

@ -0,0 +1,23 @@
import addons, { makeDecorator } from '@storybook/addons';
export const withCssResources = makeDecorator({
name: 'withCssResources',
parameterName: 'cssresources',
skipIfNoParametersOrOptions: true,
allowDeprecatedUsage: false,
wrapper: (getStory, context, { options, parameters }) => {
const channel = addons.getChannel();
const storyOptions = parameters || options;
if (!Array.isArray(storyOptions) && !Array.isArray(storyOptions.cssresources)) {
throw new Error('The `cssresources` parameter needs to be an Array');
}
channel.emit(
'storybook/resources/add_cssresources',
Array.isArray(storyOptions) ? storyOptions : storyOptions.cssresources
);
return getStory(context);
},
});

View File

@ -0,0 +1,12 @@
import React from 'react';
import addons from '@storybook/addons';
import CssResourcePanel from './CssResourcePanel';
addons.register('storybook/cssresources', api => {
const channel = addons.getChannel();
addons.addPanel('storybook/cssresources/panel', {
title: 'Cssresources',
// eslint-disable-next-line react/prop-types
render: ({ active }) => <CssResourcePanel channel={channel} api={api} active={active} />,
});
});

View File

@ -124,9 +124,11 @@ You can pass these parameters to getStorybookUI call in your storybook entry poi
initialSelection: Object (null)
-- initialize storybook with a specific story. In case a valid object is passed, it will take precedence over `shouldPersistSelection. ex: `{ kind: 'Knobs', story: 'with knobs' }`
shouldPersistSelection: Boolean (true)
-- initialize storybook with the last selected story.`
-- initialize storybook with the last selected story.
shouldDisableKeyboardAvoidingView: Boolean (false)
-- Disable KeyboardAvoidingView wrapping Storybook's view
keyboardAvoidingViewVerticalOffset: Number (0)
-- With shouldDisableKeyboardAvoidingView=true, this will set the keyboardverticaloffset (https://facebook.github.io/react-native/docs/keyboardavoidingview#keyboardverticaloffset) value for KeyboardAvoidingView wrapping Storybook's view
}
```

View File

@ -40,8 +40,8 @@ export default class OnDeviceUI extends PureComponent {
this.state = {
tabOpen,
slideBetweenAnimation: false,
selection: props.initialStory || {},
storyFn: props.initialStory ? props.initialStory.storyFn : null,
selection: {},
storyFn: null,
previewWidth: 0,
previewHeight: 0,
};
@ -50,8 +50,18 @@ export default class OnDeviceUI extends PureComponent {
this.forceRender = this.forceUpdate.bind(this);
}
componentWillMount() {
const { events } = this.props;
async componentWillMount() {
const { events, getInitialStory } = this.props;
if (getInitialStory) {
const story = await getInitialStory();
this.setState({
selection: story || {},
storyFn: story ? story.storyFn : null,
});
}
events.on(Events.SELECT_STORY, this.handleStoryChange);
events.on(Events.FORCE_RE_RENDER, this.forceRender);
}
@ -111,7 +121,14 @@ export default class OnDeviceUI extends PureComponent {
};
render() {
const { stories, events, url, isUIHidden, shouldDisableKeyboardAvoidingView } = this.props;
const {
stories,
events,
url,
isUIHidden,
shouldDisableKeyboardAvoidingView,
keyboardAvoidingViewVerticalOffset,
} = this.props;
const {
tabOpen,
slideBetweenAnimation,
@ -137,6 +154,7 @@ export default class OnDeviceUI extends PureComponent {
<KeyboardAvoidingView
enabled={!shouldDisableKeyboardAvoidingView || tabOpen !== PREVIEW}
behavior={IS_IOS ? 'padding' : null}
keyboardVerticalOffset={keyboardAvoidingViewVerticalOffset}
style={style.flex}
>
<AbsolutePositionedKeyboardAwareView
@ -194,18 +212,16 @@ OnDeviceUI.propTypes = {
url: PropTypes.string,
tabOpen: PropTypes.number,
isUIHidden: PropTypes.bool,
initialStory: PropTypes.shape({
story: PropTypes.string.isRequired,
kind: PropTypes.string.isRequired,
storyFn: PropTypes.func.isRequired,
}),
getInitialStory: PropTypes.func,
shouldDisableKeyboardAvoidingView: PropTypes.bool,
keyboardAvoidingViewVerticalOffset: PropTypes.number,
};
OnDeviceUI.defaultProps = {
url: '',
tabOpen: 0,
isUIHidden: false,
initialStory: null,
getInitialStory: null,
shouldDisableKeyboardAvoidingView: false,
keyboardAvoidingViewVerticalOffset: 0,
};

View File

@ -1,4 +1,4 @@
/* eslint-disable react/no-this-in-sfc, no-underscore-dangle */
/* eslint-disable no-underscore-dangle */
import React from 'react';
import { AsyncStorage, NativeModules } from 'react-native';
@ -46,7 +46,7 @@ export default class Preview {
let channel = null;
const onDeviceUI = params.onDeviceUI !== false;
const { initialSelection, shouldPersistSelection } = params;
// should the initial story be sent to storybookUI
// set to true if using disableWebsockets or if connection to WebsocketServer fails.
let setInitialStory = false;
@ -67,7 +67,7 @@ export default class Preview {
const port = params.port !== false ? `:${params.port || 7007}` : '';
const query = params.query || '';
const { initialSelection, secured, shouldPersistSelection } = params;
const { secured } = params;
const websocketType = secured ? 'wss' : 'ws';
const httpType = secured ? 'https' : 'http';
@ -77,6 +77,8 @@ export default class Preview {
url,
async: onDeviceUI,
onError: () => {
// We are both emitting event and telling the component to get initial story. It may happen that component is created before the error or vise versa.
// This way we handle both cases
this._setInitialStory(initialSelection, shouldPersistSelection);
setInitialStory = true;
@ -90,7 +92,7 @@ export default class Preview {
}
channel.on(Events.GET_STORIES, () => this._sendSetStories());
channel.on(Events.SET_CURRENT_STORY, d => this._selectStory(d));
channel.on(Events.SET_CURRENT_STORY, d => this._selectStoryEvent(d));
this._sendSetStories();
// If the app is started with server running, set the story as the one selected in the browser
@ -114,8 +116,13 @@ export default class Preview {
url={webUrl}
isUIOpen={params.isUIOpen}
tabOpen={params.tabOpen}
initialStory={setInitialStory ? preview._getInitialStory() : null}
getInitialStory={
setInitialStory
? preview._getInitialStory(initialSelection, shouldPersistSelection)
: null
}
shouldDisableKeyboardAvoidingView={params.shouldDisableKeyboardAvoidingView}
keyboardAvoidingViewVerticalOffset={params.keyboardAvoidingViewVerticalOffset}
/>
);
}
@ -137,8 +144,15 @@ export default class Preview {
}
_setInitialStory = async (initialSelection, shouldPersistSelection = true) => {
let story = this._getInitialStory();
const story = await this._getInitialStory(initialSelection, shouldPersistSelection)();
if (story) {
this._selectStory(story);
}
};
_getInitialStory = (initialSelection, shouldPersistSelection = true) => async () => {
let story = null;
if (initialSelection && this._checkStory(initialSelection)) {
story = initialSelection;
} else if (shouldPersistSelection) {
@ -151,11 +165,9 @@ export default class Preview {
}
if (story) {
this._selectStory(story);
this._getStory(story);
}
};
_getInitialStory = () => {
const dump = this._stories.dumpStoryBook();
const nonEmptyKind = dump.find(kind => kind.stories.length > 0);
@ -172,11 +184,16 @@ export default class Preview {
return { ...selection, storyFn };
}
_selectStory(selection) {
const channel = addons.getChannel();
channel.emit(Events.SELECT_STORY, this._getStory(selection));
_selectStoryEvent(selection) {
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(selection));
const story = this._getStory(selection);
this._selectStory(story);
}
_selectStory(story) {
const channel = addons.getChannel();
channel.emit(Events.SELECT_STORY, story);
}
_checkStory(selection) {

View File

@ -35,7 +35,7 @@
"react-dom": "^16.6.0"
},
"devDependencies": {
"svelte": "^2.15.2",
"svelte": "^2.15.3",
"svelte-loader": "^2.11.0"
},
"peerDependencies": {

View File

@ -19,8 +19,8 @@
"prepare": "npm run snyk-protect"
},
"dependencies": {
"@storybook/addon-actions": "^4.0.8",
"@storybook/addon-links": "^4.0.7",
"@storybook/addon-actions": "^4.0.9",
"@storybook/addon-links": "^4.0.9",
"@storybook/addons": "^3.4.11",
"@storybook/react": "^3.4.11",
"babel-loader": "^6.4.1",
@ -47,7 +47,7 @@
"react-router": "^4.3.1",
"react-stack-grid": "^0.7.1",
"sitemap": "^2.1.0",
"snyk": "^1.109.0"
"snyk": "^1.110.2"
},
"snyk": true
}

View File

@ -7,18 +7,29 @@ Storybook's manager UI is theme-able! You can change theme variables using [addo
## Set a theme
You can do this in an decorator, addon or in `config.js`. Changing theme at runtime is supported!
You can do this in an decorator, addon or in `.storybook/config.js`. Changing theme at runtime is supported!
First, create or modify `.storybook/addons.js` to include registering addon-options:
```js
import { setOptions } from '@storybook/addon-options';
import '@storybook/addon-options/register';
```
setOptions({
theme: {},
Then, modify `.storybook/config.js` to include your new options:
```js
import { addDecorator, configure } from '@storybook/react';
import { withOptions } from '@storybook/addon-options';
addDecorator(
withOptions({
theme: {},
})
});
```
When setting a theme, set a full theme object, the theme is replaced, not combined.
See more addon options at https://github.com/storybooks/storybook/tree/master/addons/options
## Get a theme
We have created 2 themes for you: "normal" (a light theme) and "dark" (a dark theme).
@ -26,7 +37,17 @@ We have created 2 themes for you: "normal" (a light theme) and "dark" (a dark th
You can get these themes like so:
```js
import { addDecorator, configure } from '@storybook/react';
import { withOptions } from '@storybook/addon-options';
import { themes } from '@storybook/components';
// Option defaults.
addDecorator(
withOptions({
name: 'Foo',
theme: themes.dark,
})
);
```
## Theme variables

View File

@ -147,16 +147,16 @@
react-inspector "^2.2.2"
uuid "^3.2.1"
"@storybook/addon-actions@^4.0.8":
version "4.0.8"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-4.0.8.tgz#7230a63ee98e2d61f806a7a8e1c5146daed6026e"
integrity sha512-lRwmi9icRyNiXamSY5JtRvOx1Pg3KNAMn7GZjn0saS86/9b4aq6jTLg8QpLHHSM3zckZ97SbXTyHcuP/M6LgZg==
"@storybook/addon-actions@^4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-4.0.9.tgz#6733e37641329751a7b90722f71893dc019d20b5"
integrity sha512-CRMofmt1wF8D2MLxXlm/IKSfDpNatooUliRo57jaHMa+0F+alDQbujgQJR7mAvHVN/MFQQ2Go+5PXDnfijKkHw==
dependencies:
"@emotion/core" "^0.13.1"
"@emotion/provider" "^0.11.2"
"@emotion/styled" "^0.10.6"
"@storybook/addons" "4.0.8"
"@storybook/components" "4.0.8"
"@storybook/addons" "4.0.9"
"@storybook/components" "4.0.9"
"@storybook/core-events" "4.0.8"
deep-equal "^1.0.1"
global "^4.3.2"
@ -176,14 +176,14 @@
global "^4.3.2"
prop-types "^15.6.1"
"@storybook/addon-links@^4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-4.0.7.tgz#2579707052cfc9bcb2a97d21c7363c673574ae89"
integrity sha512-1MTWD+2Qu5txSxPykk7le8gEA66Yjm+USDC1Gbq0KqSLoQ0vh2Fxd6cXE+mIUBC2IIIqDio2SjkqV0974B8JgA==
"@storybook/addon-links@^4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-4.0.9.tgz#72f594c46d70d9e7008888517765fa452c338cd6"
integrity sha512-n5KUirtb5r8YcXXV/pLjx0wf9E9YbzUfaaj76Z4hNkLegtG/9AJCXe0paFqwFXM7gi2nQR0ldWopdZqgVpV77g==
dependencies:
"@storybook/addons" "4.0.7"
"@storybook/components" "4.0.7"
"@storybook/core-events" "4.0.7"
"@storybook/addons" "4.0.9"
"@storybook/components" "4.0.9"
"@storybook/core-events" "4.0.8"
global "^4.3.2"
prop-types "^15.6.2"
@ -192,23 +192,13 @@
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-3.4.11.tgz#f3e27c46d80ad1f171888c4aad0a19a8a032d072"
integrity sha512-Uf01aZ1arcpG1prrrCrBCUYW63lDaoG+r/i3TNo1iG9ZaNc+2UHWeuiEedLfHg0fi/q7UnqMNWDiyO3AkEwwrA==
"@storybook/addons@4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-4.0.7.tgz#52a98ebfa862b34ed47368590564a9638b86d211"
integrity sha512-rfumQnFLMhpGx3nvzhW+stTFKwp5SMOso7pryEBhxxskT4f6kBuzZyaChhnSBWBwVz5bPpplWj5l0H0F2/+5bg==
dependencies:
"@storybook/channels" "4.0.7"
"@storybook/components" "4.0.7"
global "^4.3.2"
util-deprecate "^1.0.2"
"@storybook/addons@4.0.8":
version "4.0.8"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-4.0.8.tgz#841848c57406296f7b513708c15dc865f6b37fc7"
integrity sha512-rcLqzRHFPYQ5S0/NKc3Qk7klUseiq3YCAKghYjGzXPENgID6rKnqAYrlOybPgR0aUWs6koXKiIjtco9tT1UBxQ==
"@storybook/addons@4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-4.0.9.tgz#cfa18fe10ddda454dbbc3aae17562e46d04d3955"
integrity sha512-D+RsN1fNywgk46UxG6Lue+p9Egf7/DpgEJtQb6RS+UoyOF24p3FlwWMh36kpRfSSgGqFZ+a0jIKhXuRSr31UNQ==
dependencies:
"@storybook/channels" "4.0.8"
"@storybook/components" "4.0.8"
"@storybook/components" "4.0.9"
global "^4.3.2"
util-deprecate "^1.0.2"
@ -226,11 +216,6 @@
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-3.4.11.tgz#853ec40fdfa6c3ae8cff23f0cd86b77a719823f5"
integrity sha512-49A79anI04nhMsNzyk5cF8fa3+HKZkb9RLshtaqvQmM7olQxCrks6cIdE2Y1zMBuyZxX1ARhcBCFVw+PUxkJjA==
"@storybook/channels@4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-4.0.7.tgz#bb7607c9d0036cbed884c11683d7c168c2663733"
integrity sha512-XSfMaD+GKQpNtHSAZb0aMjDH59rYIvTB3je0jM67NVHneIbZrxxEcY52QZ7KP2eAP9qRw3yK89VoNo7D0APdcQ==
"@storybook/channels@4.0.8":
version "4.0.8"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-4.0.8.tgz#36d96ad714c685f144fd1f1e5394faf0e0291032"
@ -250,10 +235,10 @@
glamorous "^4.12.1"
prop-types "^15.6.1"
"@storybook/components@4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-4.0.7.tgz#f5a51b6999df7bd137a02a968d17795c836bfa5b"
integrity sha512-edQdAx+Vy6ycg6wxj5vX2DzDIcH9hikj517wKunlv78zv+82aFgHI/UZoUhaSL2dqYWOx+dO1eSza5456y7llQ==
"@storybook/components@4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-4.0.9.tgz#c5cc9f52768fd7a6078d9601cecacd0e357dc130"
integrity sha512-EoPJitDUBkNdg4UiWyrmU6IkpLmJTjJO6KD382isHXA7qCxBJQTPb2m3GXy35KKF510NtJ9H0l4k5x7yg5Wzng==
dependencies:
"@emotion/core" "^0.13.1"
"@emotion/provider" "^0.11.2"
@ -266,27 +251,6 @@
react-textarea-autosize "^7.0.4"
render-fragment "^0.1.1"
"@storybook/components@4.0.8":
version "4.0.8"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-4.0.8.tgz#0c0701e64b52538acb0d39412db476549a3d7579"
integrity sha512-6r6/B2i2sQrDPvOgzo5YgCtSCj3q4E54e6V5fkbrYhSvH7Ro8fwca6Pee0uHbKECT+N8+HzWveV0WKg20TZvIg==
dependencies:
"@emotion/core" "^0.13.1"
"@emotion/provider" "^0.11.2"
"@emotion/styled" "^0.10.6"
global "^4.3.2"
lodash "^4.17.11"
prop-types "^15.6.2"
react-inspector "^2.3.0"
react-split-pane "^0.1.84"
react-textarea-autosize "^7.0.4"
render-fragment "^0.1.1"
"@storybook/core-events@4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-4.0.7.tgz#8fb7be5dd0fba5c6928b15cd2d92ffdb0a53da6f"
integrity sha512-rirZ/dtcA22BqZoxsYGeUHdS0IQFKNerTnNcDuL7NaTD79tl1JaWYvtLot3GqxLD7/lyUh0GQIGnxqr1ouGBhQ==
"@storybook/core-events@4.0.8":
version "4.0.8"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-4.0.8.tgz#7af80f1c3eb32ae0eafe789be651c684dcfefd7b"
@ -4207,6 +4171,13 @@ dir-glob@^2.0.0:
arrify "^1.0.1"
path-type "^3.0.0"
dockerfile-ast@0.0.12:
version "0.0.12"
resolved "https://registry.yarnpkg.com/dockerfile-ast/-/dockerfile-ast-0.0.12.tgz#6f25f6ad55eeecdd297ab68b08be1b32e64b5aeb"
integrity sha512-cIV8oXkAxpIuN5XgG0TGg07nLDgrj4olkfrdT77OTA3VypscsYHBUg/FjHxW9K3oA+CyH4Th/qtoMgTVpzSobw==
dependencies:
vscode-languageserver-types "^3.5.0"
doctrine@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@ -12780,12 +12751,13 @@ snyk-config@2.2.0:
lodash "^4.17.5"
nconf "^0.10.0"
snyk-docker-plugin@1.12.2:
version "1.12.2"
resolved "https://registry.yarnpkg.com/snyk-docker-plugin/-/snyk-docker-plugin-1.12.2.tgz#1adf272b10ea47420fba5f469ae7ed4efe4e6fdd"
integrity sha512-8bEn6tDSXPtNS6d1XRM6CSRMwM0bI3N0vRzcKVMZ9E52W9sIpv2E50noYjxcMpoRFxpLWAJ4WMtamcMtLPnNeQ==
snyk-docker-plugin@1.12.3:
version "1.12.3"
resolved "https://registry.yarnpkg.com/snyk-docker-plugin/-/snyk-docker-plugin-1.12.3.tgz#a4a7c81a8e4e3c6a6cc303d4bc9aa98645274bca"
integrity sha512-ZbvaFCPCd0wxhqxjzU/iyf39tKlq2nvI9nPW32uZV3RGdHrkQH55BzCtBCF9d0dapxX+PKgae/4u2BKNw8hd9Q==
dependencies:
debug "^3"
dockerfile-ast "0.0.12"
tslib "^1"
snyk-go-plugin@1.6.0:
@ -12929,10 +12901,10 @@ snyk-try-require@1.3.1, snyk-try-require@^1.1.1, snyk-try-require@^1.3.1:
lru-cache "^4.0.0"
then-fs "^2.0.0"
snyk@^1.109.0:
version "1.109.0"
resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.109.0.tgz#74409541afc54a13b47b01adcd8609ef2e75f8f4"
integrity sha512-JobrjjeK8b/O6+Vl65rFb068U9S44YEaZmAlGDHdteDy+v9X9ajGAwYW15lC1hfnl4EHwOE6FnD0d1rD6PFdqw==
snyk@^1.110.2:
version "1.110.2"
resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.110.2.tgz#0d8366ac8880abd8b60e6c6d3dc2074fb91a45f5"
integrity sha512-SQE4sudrscd48EoRJqy5h5S6c8YBiOw0r0Se3rfg1l6ElJGgCB9je6XEzfe+UmfES06D7ueFYepiQPxTwH4Qww==
dependencies:
abbrev "^1.1.1"
ansi-escapes "^3.1.0"
@ -12950,7 +12922,7 @@ snyk@^1.109.0:
recursive-readdir "^2.2.2"
semver "^5.5.0"
snyk-config "2.2.0"
snyk-docker-plugin "1.12.2"
snyk-docker-plugin "1.12.3"
snyk-go-plugin "1.6.0"
snyk-gradle-plugin "2.1.1"
snyk-module "1.9.1"
@ -14665,6 +14637,11 @@ vm-browserify@0.0.4:
dependencies:
indexof "0.0.1"
vscode-languageserver-types@^3.5.0:
version "3.13.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4"
integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA==
walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"

View File

@ -0,0 +1,28 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>

View File

@ -5,6 +5,7 @@ import '@storybook/addon-events/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-options/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-cssresources/register';
import '@storybook/addon-backgrounds/register';
import '@storybook/addon-a11y/register';
import '@storybook/addon-jest/register';

View File

@ -4,6 +4,7 @@ import { configure, addDecorator } from '@storybook/react';
import { themes } from '@storybook/components';
import { withOptions } from '@storybook/addon-options';
import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import { withCssResources } from '@storybook/addon-cssresources';
import 'react-chromatic/storybook-addon';
import addHeadWarning from './head-warning';
@ -34,6 +35,20 @@ addDecorator(
})
);
addDecorator(
withCssResources({
cssresources: [
{
name: `bluetheme`,
code: `<style>body {
background-color: lightblue;
}</style>`,
picked: false,
},
],
})
);
addDecorator(
(story, { kind }) =>
kind === 'Core|Errors' ? (

View File

@ -20,6 +20,7 @@
"@storybook/addon-actions": "4.1.0-alpha.8",
"@storybook/addon-backgrounds": "4.1.0-alpha.8",
"@storybook/addon-centered": "4.1.0-alpha.8",
"@storybook/addon-cssresources": "4.1.0-alpha.8",
"@storybook/addon-events": "4.1.0-alpha.8",
"@storybook/addon-graphql": "4.1.0-alpha.8",
"@storybook/addon-info": "4.1.0-alpha.8",

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Addons|Cssresources Camera Icon 1`] = `
<i
class="fa fa-camera-retro"
>
Camera Icon
</i>
`;
exports[`Storyshots Addons|Cssresources Primary Large Button 1`] = `
<button
class="btn btn-lg btn-primary"
type="button"
>
Primary Large Button
</button>
`;

View File

@ -0,0 +1,45 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withCssResources } from '@storybook/addon-cssresources';
storiesOf('Addons|Cssresources', module)
.addDecorator(
withCssResources({
cssresources: [
{
name: `bootstrap v4.1.3`,
code: `<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"></link>`,
picked: true,
},
{
name: `bootstrap v3.3.5`,
code: `<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"></link>`,
picked: false,
},
],
})
)
.add('Primary Large Button', () => (
<button type="button" className="btn btn-lg btn-primary">
Primary Large Button
</button>
));
storiesOf('Addons|Cssresources', module)
.addDecorator(
withCssResources({
cssresources: [
{
name: `fontawesome`,
code: `<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"></link>`,
picked: true,
},
{
name: `whitetheme`,
code: `<style>.fa { color: #fff }</style>`,
picked: true,
},
],
})
)
.add('Camera Icon', () => <i className="fa fa-camera-retro"> Camera Icon</i>);

View File

@ -185,9 +185,7 @@ exports[`Storyshots Welcome Welcome 1`] = `
href="https://storybook.js.org/basics/writing-stories"
target="_blank"
>
Writing Stories
Writing Stories
</a>
section in our documentation.

View File

@ -26,9 +26,7 @@
class="link"
href="https://storybook.js.org/basics/writing-stories"
target="_blank"
>
Writing Stories
</a>
>Writing Stories</a>
section in our documentation.
</p>
<p class="note">

View File

@ -36,7 +36,7 @@ export function buildStaticStandalone(options) {
process.exit(-1);
}
logger.info(`=> Copying static files from: ${dir}`);
shelljs.cp('-r', `${dir}/*`, outputDir);
shelljs.cp('-r', `${dir}/!(index.html)`, outputDir);
});
}

View File

@ -48,7 +48,11 @@ export function changeUrl(clientStore, usePush) {
if (!data.selectedKind) return;
const state = getUrlState(data);
history[usePush ? 'pushState' : 'replaceState'](state, '', state.url);
try {
history[usePush ? 'pushState' : 'replaceState'](state, '', state.url);
} catch (e) {
// do nothing
}
}
export function updateStore(queryParams, actions) {

View File

@ -1342,7 +1342,7 @@
"@emotion/serialize" "^0.9.1"
"@emotion/utils" "^0.8.2"
"@emotion/styled@^0.10.6":
"@emotion/styled@0.10.6", "@emotion/styled@^0.10.6":
version "0.10.6"
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-0.10.6.tgz#1f6af1d3d4bf9fdeb05a4d220046ce11ad21a7ca"
integrity sha512-DFNW8jlMjy1aYCj/PKsvBoJVZAQXzjmSCwtKXLs31qZzNPaUEPbTYSIKnMUtIiAOYsu0pUTGXM+l0a+MYNm4lA==
@ -21546,10 +21546,10 @@ svelte-loader@^2.11.0:
require-relative "^0.8.7"
svelte-dev-helper "^1.1.9"
svelte@^2.15.2:
version "2.15.2"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-2.15.2.tgz#6aaf4a10307409099ec30dd7c73f746fef32c949"
integrity sha512-l/YAQQ/ArmUTlEdspyLS7viFtKX0ZRKVmYeizAlvFoJ4vKos+7/aBD8xWxQTUd8EPh1JD95DVy7NK3h8+ITlxw==
svelte@^2.15.3:
version "2.15.3"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-2.15.3.tgz#d9ba5b48eae30f5501b3266c563add2399c67b40"
integrity sha512-0bKpXppM/YlPZ8F0mREaUYpE8Te11RvG62ttFr+n1U3G2qdr3cZzuXCnQMcVZukwAUJAjRM55OSH7FLmXnPGRA==
svg-tags@^1.0.0:
version "1.0.0"