Merge branch 'addmarkosupport' of github.com:nm123github/storybook into addmarkosupport

This commit is contained in:
Neville Mehta 2018-05-19 19:19:59 -07:00
commit 77c9b80197
177 changed files with 6467 additions and 7361 deletions

View File

@ -1,10 +1,13 @@
{ {
"presets": ["env", "stage-0", "react"], "presets": ["env", "stage-0", "react"],
"plugins": [ "env": {
"babel-plugin-macros", "plugins": [
["transform-runtime", { "emotion",
"polyfill": false, "babel-plugin-macros",
"regenerator": true ["transform-runtime", {
}] "polyfill": false,
] "regenerator": true
}]
]
}
} }

View File

@ -14,13 +14,13 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/storybooks/storybook.git" "url": "git+https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -31,10 +31,10 @@
"@storybook/core-events": "4.0.0-alpha.7", "@storybook/core-events": "4.0.0-alpha.7",
"axe-core": "^3.0.2", "axe-core": "^3.0.2",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"prop-types": "^15.6.1" "prop-types": "^15.6.1",
"react-emotion": "^9.1.3"
}, },
"peerDependencies": { "peerDependencies": {
"react": "*", "react": "*",

View File

@ -1,19 +1,20 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import addons from '@storybook/addons'; import addons from '@storybook/addons';
import styled from 'react-emotion';
import { CHECK_EVENT_ID } from '../shared'; import { CHECK_EVENT_ID } from '../shared';
import Tabs from './Tabs'; import Tabs from './Tabs';
import Report from './Report'; import Report from './Report';
const styles = { const Passes = styled('span')({
passes: { color: '#0D6731',
color: '#0D6731', });
},
violations: { const Violations = styled('span')({
color: '#AC2300', color: '#AC2300',
}, });
};
class Panel extends Component { class Panel extends Component {
constructor(props, ...args) { constructor(props, ...args) {
@ -49,11 +50,11 @@ class Panel extends Component {
<Tabs <Tabs
tabs={[ tabs={[
{ {
label: <span style={styles.violations}>{violations.length} Violations</span>, label: <Violations>{violations.length} Violations</Violations>,
panel: <Report passes={false} items={violations} empty="No a11y violations found." />, panel: <Report passes={false} items={violations} empty="No a11y violations found." />,
}, },
{ {
label: <span style={styles.passes}>{passes.length} Passes</span>, label: <Passes>{passes.length} Passes</Passes>,
panel: <Report passes items={passes} empty="No a11y check passed" />, panel: <Report passes items={passes} empty="No a11y check passed" />,
}, },
]} ]}

View File

@ -1,20 +1,20 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
import Rules from './Rules'; import Rules from './Rules';
const styles = { const Item = styled('li')({
element: { fontWeight: 600,
fontWeight: 600, });
}, const ItemTitle = styled('span')({
target: { borderBottom: '1px solid rgb(130, 130, 130)',
borderBottom: '1px solid rgb(130, 130, 130)', width: '100%',
width: '100%', display: 'inline-block',
display: 'inline-block', paddingBottom: '4px',
paddingBottom: '4px', marginBottom: '4px',
marginBottom: '4px', });
},
};
function Element({ element, passes }) { function Element({ element, passes }) {
const { any, all, none } = element; const { any, all, none } = element;
@ -22,10 +22,10 @@ function Element({ element, passes }) {
const rules = [...any, ...all, ...none]; const rules = [...any, ...all, ...none];
return ( return (
<li style={styles.element}> <Item>
<span style={styles.target}>{element.target[0]}</span> <ItemTitle>{element.target[0]}</ItemTitle>
<Rules rules={rules} passes={passes} /> <Rules rules={rules} passes={passes} />
</li> </Item>
); );
} }
Element.propTypes = { Element.propTypes = {
@ -38,13 +38,12 @@ Element.propTypes = {
}; };
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
function Elements({ elements, passes }) { const Elements = ({ elements, passes }) => (
return ( <ol>
<ol style={styles.element}> {elements.map((element, index) => <Element passes={passes} element={element} key={index} />)}
{elements.map((element, index) => <Element passes={passes} element={element} key={index} />)} </ol>
</ol> );
);
}
Elements.propTypes = { Elements.propTypes = {
elements: PropTypes.arrayOf( elements: PropTypes.arrayOf(
PropTypes.shape({ PropTypes.shape({

View File

@ -1,31 +1,31 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const styles = { import styled from 'react-emotion';
info: {
backgroundColor: 'rgb(234, 234, 234)', const Wrapper = styled('div')({
padding: '12px', backgroundColor: 'rgb(234, 234, 234)',
marginBottom: '10px', padding: '12px',
}, marginBottom: '10px',
help: { });
margin: '0 0 12px', const Help = styled('p')({
}, margin: '0 0 12px',
helpUrl: { });
marginTop: '12px', const Link = styled('a')({
textDecoration: 'underline', marginTop: '12px',
color: 'rgb(130, 130, 130)', textDecoration: 'underline',
display: 'block', color: 'rgb(130, 130, 130)',
}, display: 'block',
}; });
function Info({ item }) { function Info({ item }) {
return ( return (
<div style={styles.info}> <Wrapper>
<p style={styles.help}>{item.help}</p> <Help>{item.help}</Help>
<a style={styles.helpUrl} href={item.helpUrl} target="_blank"> <Link href={item.helpUrl} target="_blank">
More info... More info...
</a> </Link>
</div> </Wrapper>
); );
} }

View File

@ -1,24 +1,25 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
import Info from './Info'; import Info from './Info';
import Tags from './Tags'; import Tags from './Tags';
import Elements from './Elements'; import Elements from './Elements';
const styles = { const Wrapper = styled('div')({
item: { padding: '0 14px',
padding: '0 14px', cursor: 'pointer',
cursor: 'pointer', borderBottom: '1px solid rgb(234, 234, 234)',
borderBottom: '1px solid rgb(234, 234, 234)', });
},
headerBar: { const HeaderBar = styled('button')({
padding: '12px 0px', padding: '12px 0px',
display: 'block', display: 'block',
width: '100%', width: '100%',
border: 0, border: 0,
background: 'none', background: 'none',
}, });
};
class Item extends Component { class Item extends Component {
static propTypes = { static propTypes = {
@ -30,13 +31,9 @@ class Item extends Component {
passes: PropTypes.bool.isRequired, passes: PropTypes.bool.isRequired,
}; };
constructor() { state = {
super(); open: false,
};
this.state = {
open: false,
};
}
onToggle = () => onToggle = () =>
this.setState(prevState => ({ this.setState(prevState => ({
@ -48,14 +45,12 @@ class Item extends Component {
const { open } = this.state; const { open } = this.state;
return ( return (
<div style={styles.item}> <Wrapper>
<button style={styles.headerBar} onClick={() => this.onToggle()}> <HeaderBar onClick={this.onToggle}>{item.description}</HeaderBar>
{item.description}
</button>
{open && <Info item={item} />} {open && <Info item={item} />}
{open && <Elements elements={item.nodes} passes={passes} />} {open && <Elements elements={item.nodes} passes={passes} />}
{open && <Tags tags={item.tags} />} {open && <Tags tags={item.tags} />}
</div> </Wrapper>
); );
} }
} }

View File

@ -1,6 +1,6 @@
import glamorous from 'glamorous'; import styled from 'react-emotion';
const RerunButton = glamorous.button({ const RerunButton = styled('button')({
position: 'absolute', position: 'absolute',
bottom: 0, bottom: 0,
right: 0, right: 0,

View File

@ -1,6 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
const impactColors = { const impactColors = {
minor: '#f1c40f', minor: '#f1c40f',
moderate: '#e67e22', moderate: '#e67e22',
@ -9,52 +11,45 @@ const impactColors = {
success: '#2ecc71', success: '#2ecc71',
}; };
const styles = { const List = styled('div')({
rules: { display: 'flex',
display: 'flex', flexDirection: 'column',
flexDirection: 'column', padding: '4px',
padding: '4px', fontWeight: '400',
fontWeight: '400', });
},
rule: {
display: 'flex',
flexDirection: 'row',
marginBottom: '6px',
},
status: {
height: '16px',
width: '16px',
borderRadius: '8px',
fontSize: '10px',
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
color: '#fff',
textAlign: 'center',
flex: '0 0 16px',
},
message: {
paddingLeft: '6px',
},
};
function Rule({ rule, passes }) { const Item = styled('div')({
const color = passes ? impactColors.success : impactColors[rule.impact]; display: 'flex',
flexDirection: 'row',
marginBottom: '6px',
});
return ( const Message = styled('div')({
<div style={styles.rule}> paddingLeft: '6px',
<div });
style={{
...styles.status, const Status = styled('div')(({ passes, impact }) => ({
backgroundColor: color, height: '16px',
}} width: '16px',
> borderRadius: '8px',
{passes ? '✔' : '✘'} fontSize: '10px',
</div> display: 'inline-flex',
<span style={styles.message}>{rule.message}</span> justifyContent: 'center',
</div> alignItems: 'center',
); color: '#fff',
} textAlign: 'center',
flex: '0 0 16px',
backgroundColor: passes ? impactColors.success : impactColors[impact],
}));
const Rule = ({ rule, passes }) => (
<Item>
<Status passes={passes || undefined} impact={rule.impact}>
{passes ? '✔' : '✘'}
</Status>
<Message>{rule.message}</Message>
</Item>
);
Rule.propTypes = { Rule.propTypes = {
rule: PropTypes.shape({ rule: PropTypes.shape({
@ -66,9 +61,7 @@ Rule.propTypes = {
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
function Rules({ rules, passes }) { function Rules({ rules, passes }) {
return ( return (
<div style={styles.rules}> <List>{rules.map((rule, index) => <Rule passes={passes} rule={rule} key={index} />)}</List>
{rules.map((rule, index) => <Rule passes={passes} rule={rule} key={index} />)}
</div>
); );
} }
Rules.propTypes = { Rules.propTypes = {

View File

@ -1,32 +1,25 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const styles = { import styled from 'react-emotion';
tags: {
display: 'flex', const Wrapper = styled('div')({
flexWrap: 'wrap', display: 'flex',
margin: '12px 0', flexWrap: 'wrap',
}, margin: '12px 0',
tag: { });
margin: '0 6px',
padding: '5px', const Item = styled('div')({
border: '1px solid rgb(234, 234, 234)', margin: '0 6px',
borderRadius: '2px', padding: '5px',
color: 'rgb(130, 130, 130)', border: '1px solid rgb(234, 234, 234)',
fontSize: '12px', borderRadius: '2px',
}, color: 'rgb(130, 130, 130)',
}; fontSize: '12px',
});
function Tags({ tags }) { function Tags({ tags }) {
return ( return <Wrapper>{tags.map(tag => <Item key={tag}>{tag}</Item>)}</Wrapper>;
<div style={styles.tags}>
{tags.map(tag => (
<div key={tag} style={styles.tag}>
{tag}
</div>
))}
</div>
);
} }
Tags.propTypes = { Tags.propTypes = {
tags: PropTypes.arrayOf(PropTypes.node).isRequired, tags: PropTypes.arrayOf(PropTypes.node).isRequired,

View File

@ -1,26 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import addons from '@storybook/addons'; import addons from '@storybook/addons';
import { Placeholder } from '@storybook/components';
import { RERUN_EVENT_ID } from '../../shared'; import { RERUN_EVENT_ID } from '../../shared';
import RerunButton from './RerunButton'; import RerunButton from './RerunButton';
import Item from './Item'; import Item from './Item';
const styles = {
container: {
fontSize: '12px',
},
empty: {
fontSize: '11px',
padding: '20px 12px',
width: '100%',
display: 'block',
textAlign: 'center',
textTransform: 'uppercase',
},
};
function onRerunClick() { function onRerunClick() {
const channel = addons.getChannel(); const channel = addons.getChannel();
channel.emit(RERUN_EVENT_ID); channel.emit(RERUN_EVENT_ID);
@ -29,11 +16,9 @@ function onRerunClick() {
const Report = ({ items, empty, passes }) => ( const Report = ({ items, empty, passes }) => (
<div> <div>
{items.length ? ( {items.length ? (
<div style={styles.container}> items.map(item => <Item passes={passes} item={item} key={item.id} />)
{items.map(item => <Item passes={passes} item={item} key={item.id} />)}
</div>
) : ( ) : (
<span style={styles.empty}>{empty}</span> <Placeholder>{empty}</Placeholder>
)} )}
<RerunButton onClick={onRerunClick}>Re-run tests</RerunButton> <RerunButton onClick={onRerunClick}>Re-run tests</RerunButton>
</div> </div>

View File

@ -1,19 +1,28 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { baseFonts } from '@storybook/components';
const styles = { import styled from 'react-emotion';
container: {
width: '100%', const Container = styled('div')({
position: 'relative', width: '100%',
...baseFonts, position: 'relative',
}, });
tabs: {
borderBottom: '1px solid rgb(234, 234, 234)', const List = styled('div')({
flexWrap: 'wrap', borderBottom: '1px solid rgb(234, 234, 234)',
display: 'flex', flexWrap: 'wrap',
}, display: 'flex',
tab: { });
const Item = styled('button')(
({ active }) =>
active
? {
opacity: 1,
fontWeight: 600,
}
: {},
{
color: 'rgb(68, 68, 68)', color: 'rgb(68, 68, 68)',
fontSize: '11px', fontSize: '11px',
textDecoration: 'none', textDecoration: 'none',
@ -26,70 +35,40 @@ const styles = {
border: 'none', border: 'none',
background: 'none', background: 'none',
flex: 1, flex: 1,
}, }
tabActive: { );
opacity: 1,
fontWeight: 600,
},
};
const tabStyle = active => ({
...styles.tab,
...(active ? styles.tabActive : undefined),
});
class Tabs extends Component { class Tabs extends Component {
constructor(props) { state = {
super(props); active: 0,
};
this.state = { onToggle = index => {
active: 0,
};
this.onToggle = this.onToggle.bind(this);
this.renderPanel = this.renderPanel.bind(this);
this.renderTabs = this.renderTabs.bind(this);
}
onToggle(index) {
this.setState({ this.setState({
active: index, active: index,
}); });
} };
renderPanel() {
const { tabs } = this.props;
const { active } = this.state;
return <div style={styles.panel}>{tabs[active].panel}</div>;
}
renderTabs() {
const { tabs } = this.props;
const { active } = this.state;
/* eslint-disable react/no-array-index-key */
return (
<div style={styles.tabs}>
{tabs.map((tab, index) => (
<button
key={index}
style={tabStyle(active === index)}
onClick={() => this.onToggle(index)}
>
{tab.label}
</button>
))}
</div>
);
}
render() { render() {
const { tabs } = this.props;
const { active } = this.state;
return ( return (
<div style={styles.container}> <Container>
{this.renderTabs()} <List>
{this.renderPanel()} {tabs.map((tab, index) => (
</div> <Item
// eslint-disable-next-line react/no-array-index-key
key={index}
active={active === index ? true : undefined}
onClick={() => this.onToggle(index)}
>
{tab.label}
</Item>
))}
</List>
<div>{tabs[active].panel}</div>
</Container>
); );
} }
} }

View File

@ -9,13 +9,13 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -25,12 +25,12 @@
"@storybook/core-events": "4.0.0-alpha.7", "@storybook/core-events": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"make-error": "^1.3.4", "make-error": "^1.3.4",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-emotion": "^9.1.3",
"react-inspector": "^2.3.0", "react-inspector": "^2.3.0",
"uuid": "^3.2.1" "uuid": "^3.2.1"
}, },

View File

@ -37,7 +37,8 @@ class ActionLogger extends Component {
ActionLogger.propTypes = { ActionLogger.propTypes = {
onClear: PropTypes.func, onClear: PropTypes.func,
actions: PropTypes.array, // eslint-disable-line react/forbid-prop-types // eslint-disable-next-line react/forbid-prop-types
actions: PropTypes.array,
}; };
ActionLogger.defaultProps = { ActionLogger.defaultProps = {
onClear: () => {}, onClear: () => {},

View File

@ -1,7 +1,7 @@
import glamorous from 'glamorous'; import styled from 'react-emotion';
import { Button as BaseButton } from '@storybook/components'; import { Button as BaseButton } from '@storybook/components';
export const Actions = glamorous.pre({ export const Actions = styled('pre')({
flex: 1, flex: 1,
margin: 0, margin: 0,
padding: '8px 2px 20px 0', padding: '8px 2px 20px 0',
@ -9,7 +9,7 @@ export const Actions = glamorous.pre({
color: '#666', color: '#666',
}); });
export const Action = glamorous.div({ export const Action = styled('div')({
display: 'flex', display: 'flex',
padding: '3px 3px 3px 0', padding: '3px 3px 3px 0',
borderLeft: '5px solid white', borderLeft: '5px solid white',
@ -18,7 +18,7 @@ export const Action = glamorous.div({
alignItems: 'start', alignItems: 'start',
}); });
export const Button = glamorous(BaseButton)({ export const Button = styled(BaseButton)({
position: 'absolute', position: 'absolute',
bottom: 0, bottom: 0,
right: 0, right: 0,
@ -26,10 +26,11 @@ export const Button = glamorous(BaseButton)({
textTransform: 'uppercase', textTransform: 'uppercase',
letterSpacing: 1, letterSpacing: 1,
paddingTop: 5, paddingTop: 5,
paddingBootom: 5, paddingBottom: 5,
border: '0 none',
}); });
export const Counter = glamorous.div({ export const Counter = styled('div')({
margin: '0 5px 0 5px', margin: '0 5px 0 5px',
backgroundColor: '#777777', backgroundColor: '#777777',
color: '#ffffff', color: '#ffffff',
@ -37,16 +38,16 @@ export const Counter = glamorous.div({
borderRadius: '20px', borderRadius: '20px',
}); });
export const Countwrap = glamorous.div({ export const Countwrap = styled('div')({
paddingBottom: 2, paddingBottom: 2,
}); });
export const InspectorContainer = glamorous.div({ export const InspectorContainer = styled('div')({
flex: 1, flex: 1,
padding: '0 0 0 5px', padding: '0 0 0 5px',
}); });
export const Wrapper = glamorous.div({ export const Wrapper = styled('div')({
flex: 1, flex: 1,
display: 'flex', display: 'flex',
position: 'relative', position: 'relative',

View File

@ -65,7 +65,8 @@ export default class ActionLogger extends React.Component {
} }
ActionLogger.propTypes = { ActionLogger.propTypes = {
channel: PropTypes.object, // eslint-disable-line react/forbid-prop-types // eslint-disable-next-line react/forbid-prop-types
channel: PropTypes.object,
api: PropTypes.shape({ api: PropTypes.shape({
onStory: PropTypes.func.isRequired, onStory: PropTypes.func.isRequired,
}).isRequired, }).isRequired,

View File

@ -12,14 +12,14 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"author": "jbaxleyiii",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"author": "jbaxleyiii",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -27,8 +27,10 @@
"@storybook/addons": "4.0.0-alpha.7", "@storybook/addons": "4.0.0-alpha.7",
"@storybook/core-events": "4.0.0-alpha.7", "@storybook/core-events": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"emotion": "^9.1.3",
"global": "^4.3.2", "global": "^4.3.2",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-emotion": "^9.1.3",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {

View File

@ -3,17 +3,39 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import addons from '@storybook/addons'; import addons from '@storybook/addons';
import styled from 'react-emotion';
import Events from './events'; import Events from './events';
import Swatch from './Swatch'; import Swatch from './Swatch';
const storybookIframe = 'storybook-preview-iframe'; const Wrapper = styled('div')({
padding: 20,
});
const Title = styled('h5')({
fontSize: 16,
});
const Pre = styled('pre')({
padding: '30px',
display: 'block',
background: 'rgba(19,19,19,0.9)',
color: 'rgba(255,255,255,0.95)',
marginTop: '15px',
lineHeight: '1.75em',
});
const List = styled('div')({
display: 'inline-block',
padding: 15,
});
const Item = styled('div')({
display: 'inline-block',
padding: 5,
});
const storybookIframe = 'storybook-preview-iframe';
const style = { const style = {
font: {
fontFamily:
"-apple-system,'.SFNSText-Regular', 'San Francisco', Roboto, 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif",
fontSize: '14px',
},
iframe: { iframe: {
transition: 'background 0.25s ease-in-out', transition: 'background 0.25s ease-in-out',
}, },
@ -37,27 +59,18 @@ storiesOf("First Component", module)
`.trim(); `.trim();
const Instructions = () => ( const Instructions = () => (
<div style={Object.assign({ padding: '20px' }, style.font)}> <Wrapper>
<h5 style={{ fontSize: '16px' }}>Setup Instructions</h5> <Title>Setup Instructions</Title>
<p> <p>
Please add the background decorator definition to your story. The background decorate accepts Please add the background decorator definition to your story. The background decorate accepts
an array of items, which should include a name for your color (preferably the css class name) an array of items, which should include a name for your color (preferably the css class name)
and the corresponding color / image value. and the corresponding color / image value.
</p> </p>
<p>Below is an example of how to add the background decorator to your story definition.</p> <p>Below is an example of how to add the background decorator to your story definition.</p>
<pre <Pre>
style={{
padding: '30px',
display: 'block',
background: 'rgba(19,19,19,0.9)',
color: 'rgba(255,255,255,0.95)',
marginTop: '15px',
lineHeight: '1.75em',
}}
>
<code>{instructionsHtml}</code> <code>{instructionsHtml}</code>
</pre> </Pre>
</div> </Wrapper>
); );
export default class BackgroundPanel extends Component { export default class BackgroundPanel extends Component {
@ -125,13 +138,13 @@ export default class BackgroundPanel extends Component {
if (!hasDefault) backgrounds.push(defaultBackground); if (!hasDefault) backgrounds.push(defaultBackground);
return ( return (
<div style={{ display: 'inline-block', padding: '15px' }}> <List>
{backgrounds.map(({ value, name }) => ( {backgrounds.map(({ value, name }) => (
<div key={`${name} ${value}`} style={{ display: 'inline-block', padding: '5px' }}> <Item key={`${name} ${value}`}>
<Swatch value={value} name={name} setBackground={this.setBackgroundFromSwatch} /> <Swatch value={value} name={name} setBackground={this.setBackgroundFromSwatch} />
</div> </Item>
))} ))}
</div> </List>
); );
} }
} }

View File

@ -1,60 +1,56 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const style = { import styled from 'react-emotion';
swatches: {
backgroundColor: '#fff', const Button = styled('button')({
textAlign: 'center', listStyle: 'none',
padding: '0', backgroundColor: '#fff',
border: '1px solid rgba(0,0,0,0.1)', textAlign: 'center',
borderRadius: '4px', border: '1px solid rgba(0,0,0,0.1)',
cursor: 'pointer', borderRadius: 4,
display: 'inline-block', cursor: 'pointer',
width: '175px', display: 'inline-block',
verticalAlign: 'top', width: 175,
wordWrap: 'break-word', verticalAlign: 'top',
}, wordWrap: 'break-word',
swatch: { padding: 0,
height: '80px', });
borderRadius: '4px 4px 0 0', const Block = styled('div')(({ bg }) => ({
transition: 'opacity 0.25s ease-in-out', height: 80,
borderBottom: '1px solid rgba(0,0,0,0.1)', borderRadius: '4px 4px 0 0',
}, transition: 'opacity 0.25s ease-in-out',
listStyle: { listStyle: 'none' }, borderBottom: '1px solid rgba(0,0,0,0.1)',
pushBottom: { marginBottom: '10px' }, background: bg,
pushLeft: { marginLeft: '10px' }, backgroundSize: 'cover',
soft: { paddingLeft: '10px', paddingRight: '10px' }, backgroundPosition: 'center',
hard: { padding: '0' }, }));
flush: { margin: '0' },
font: { const Box = styled('div')({
fontFamily: listStyle: 'none',
"-apple-system, '.SFNSText-Regular', 'San Francisco', Roboto, 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif", paddingLeft: 10,
fontSize: '14px', paddingRight: 10,
wordBreak: 'break-word', });
},
}; const Name = styled('h4')({
float: 'left',
fontWeight: 'bold',
});
const Value = styled('h4')({
float: 'right',
fontWeight: 'normal',
});
const Swatch = ({ name, value, setBackground }) => ( const Swatch = ({ name, value, setBackground }) => (
<button <Button onClick={() => setBackground(value)} onMouseDown={event => event.preventDefault()}>
style={Object.assign({}, style.swatches, style.listStyle, style.hard)} <Block bg={value} />
onClick={() => setBackground(value)} <Box>
// Prevent focusing on mousedown <Name>{name}:</Name>
onMouseDown={event => event.preventDefault()} <Value>
>
<div
style={Object.assign({}, style.swatch, {
background: value,
backgroundSize: 'cover',
backgroundPosition: 'center',
})}
/>
<div style={Object.assign({}, style.listStyle, style.soft)}>
<h4 style={Object.assign({ float: 'left', fontWeight: 'bold' }, style.font)}>{name}:</h4>
<h4 style={Object.assign({ float: 'right', fontWeight: 'normal' }, style.font)}>
<em>{value}</em> <em>{value}</em>
</h4> </Value>
</div> </Box>
</button> </Button>
); );
Swatch.propTypes = { Swatch.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,

View File

@ -21,12 +21,9 @@ describe('Swatch', () => {
}); });
it('should render the value of the swatch and set it to be the background', () => { it('should render the value of the swatch and set it to be the background', () => {
const markup = shallow( const result = shallow(<Swatch value="bar" name="foo" setBackground={mockedSetBackround} />);
<Swatch value="bar" name="foo" setBackground={mockedSetBackround} />
).html();
expect(markup.match(/background:bar/gim)).toHaveLength(1); expect(result).toMatchSnapshot();
expect(markup.match(/bar/gim)).toHaveLength(2);
}); });
it('should emit message on click', () => { it('should emit message on click', () => {

View File

@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Swatch should render the value of the swatch and set it to be the background 1`] = `
<Styled(button)
onClick={[Function]}
onMouseDown={[Function]}
>
<Styled(div)
bg="bar"
/>
<Styled(div)>
<Styled(h4)>
foo
:
</Styled(h4)>
<Styled(h4)>
<em>
bar
</em>
</Styled(h4)>
</Styled(div)>
</Styled(button)>
`;

View File

@ -8,13 +8,13 @@
"react", "react",
"storybook" "storybook"
], ],
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git@github.com:storybooks/storybook.git" "url": "git@github.com:storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -22,8 +22,10 @@
"@storybook/addons": "4.0.0-alpha.7", "@storybook/addons": "4.0.0-alpha.7",
"@storybook/core-events": "4.0.0-alpha.7", "@storybook/core-events": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"emotion": "^9.1.3",
"format-json": "^1.0.3", "format-json": "^1.0.3",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-emotion": "^9.1.3",
"react-lifecycles-compat": "^3.0.4", "react-lifecycles-compat": "^3.0.4",
"react-textarea-autosize": "^6.1.0", "react-textarea-autosize": "^6.1.0",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"

View File

@ -1,41 +1,14 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { polyfill } from 'react-lifecycles-compat';
import json from 'format-json';
import Textarea from 'react-textarea-autosize';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { polyfill } from 'react-lifecycles-compat';
const styles = { import styled from 'react-emotion';
label: { import json from 'format-json';
display: 'table-cell',
boxSizing: 'border-box', import Textarea from 'react-textarea-autosize';
verticalAlign: 'top',
paddingRight: '5px', const StyledTextarea = styled(Textarea)(
paddingTop: '7px', {
textAlign: 'right',
width: '100px',
fontSize: '12px',
color: 'rgb(68, 68, 68)',
fontWeight: '600',
},
button: {
display: 'table-cell',
textTransform: 'uppercase',
letterSpacing: '3.5px',
fontSize: 12,
fontWeight: 'bolder',
color: 'rgb(130, 130, 130)',
border: '1px solid rgb(193, 193, 193)',
textAlign: 'center',
borderRadius: 2,
padding: 5,
cursor: 'pointer',
paddingLeft: 8,
margin: '0 0 0 5px',
backgroundColor: 'inherit',
verticalAlign: 'top',
outline: 0,
},
textArea: {
flex: '1 0 0', flex: '1 0 0',
boxSizing: 'border-box', boxSizing: 'border-box',
margin: '0 0 0 5px', margin: '0 0 0 5px',
@ -50,28 +23,66 @@ const styles = {
minHeight: '32px', minHeight: '32px',
resize: 'vertical', resize: 'vertical',
}, },
item: { ({ shown }) =>
display: 'flex', shown
padding: '5px', ? {}
alignItems: 'flex-start', : {
boxSizing: 'border-box', display: 'none',
width: '100%', },
}, ({ failed }) =>
hidden: { failed
display: 'none', ? {
}, border: '1px solid #fadddd',
failed: { backgroundColor: '#fff5f5',
border: '1px solid #fadddd', }
backgroundColor: '#fff5f5', : {}
}, );
};
const Button = styled('button')({
display: 'table-cell',
textTransform: 'uppercase',
letterSpacing: '3.5px',
fontSize: 12,
fontWeight: 'bolder',
color: 'rgb(130, 130, 130)',
border: '1px solid rgb(193, 193, 193)',
textAlign: 'center',
borderRadius: 2,
padding: 5,
cursor: 'pointer',
paddingLeft: 8,
margin: '0 0 0 5px',
backgroundColor: 'inherit',
verticalAlign: 'top',
outline: 0,
});
const Label = styled('label')({
display: 'table-cell',
boxSizing: 'border-box',
verticalAlign: 'top',
paddingRight: 5,
paddingTop: 7,
textAlign: 'right',
width: 100,
fontWeight: '600',
});
const Wrapper = styled('div')({
display: 'flex',
padding: 5,
alignItems: 'flex-start',
boxSizing: 'border-box',
width: '100%',
});
class Item extends Component { class Item extends Component {
static propTypes = { static propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
onEmit: PropTypes.func.isRequired, onEmit: PropTypes.func.isRequired,
payload: PropTypes.any, // eslint-disable-line react/forbid-prop-types, react/no-unused-prop-types // eslint-disable-next-line react/forbid-prop-types, react/no-unused-prop-types
payload: PropTypes.any,
}; };
static defaultProps = { static defaultProps = {
@ -136,45 +147,34 @@ class Item extends Component {
const { title, name } = this.props; const { title, name } = this.props;
const { failed, isTextAreaShowed } = this.state; const { failed, isTextAreaShowed } = this.state;
const extraStyle = {};
Object.assign(extraStyle, isTextAreaShowed ? {} : { ...styles.hidden });
Object.assign(extraStyle, failed ? { ...styles.failed } : {});
return ( return (
<div style={styles.item}> <Wrapper>
<label htmlFor={`addon-event-${name}`} style={styles.label}> <Label htmlFor={`addon-event-${name}`}>{title}</Label>
{title} <Button onClick={this.onEmitClick} disabled={failed} title="Submit event">
</label> <span role="img" aria-label="emit">
<button
style={styles.button}
onClick={this.onEmitClick}
disabled={failed}
title="Submit event"
>
<span role="img" aria-label="loudspeaker">
📢 📢
</span> </span>
</button> </Button>
<Textarea <StyledTextarea
id={`addon-event-${name}`} shown={isTextAreaShowed}
style={{ ...styles.textArea, ...extraStyle }} failed={failed}
value={this.state.payloadString} value={this.state.payloadString}
onChange={this.onChange} onChange={this.onChange}
/> />
{isTextAreaShowed ? ( {isTextAreaShowed ? (
<button style={styles.button} onClick={this.onToggleEditClick} title="Close editing"> <Button onClick={this.onToggleEditClick} title="Close editing">
<span role="img" aria-label="cross"> <span role="img" aria-label="close">
</span> </span>
</button> </Button>
) : ( ) : (
<button style={styles.button} onClick={this.onToggleEditClick} title="Edit event payload"> <Button onClick={this.onToggleEditClick} title="Edit event payload">
<span role="img" aria-label="pencil"> <span role="img" aria-label="edit">
</span> </span>
</button> </Button>
)} )}
</div> </Wrapper>
); );
} }
} }

View File

@ -1,25 +1,16 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
// import addons from '@storybook/addons';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { EVENTS } from '../constants'; import styled from 'react-emotion';
import { EVENTS } from '../constants';
import Event from './Event'; import Event from './Event';
const styles = { const Wrapper = styled('div')({
wrapper: { width: '100%',
fontFamily: ` boxSizing: 'border-box',
-apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", padding: '10px',
"Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif });
`,
fontSize: 14,
width: '100%',
boxSizing: 'border-box',
padding: '10px',
color: 'rgb(51, 51, 51)',
overflow: 'auto',
},
};
export default class Events extends Component { export default class Events extends Component {
static propTypes = { static propTypes = {
@ -53,9 +44,9 @@ export default class Events extends Component {
render() { render() {
const { events } = this.state; const { events } = this.state;
return ( return (
<div style={styles.wrapper}> <Wrapper>
{events.map(event => <Event key={event.name} {...event} onEmit={this.onEmit} />)} {events.map(event => <Event key={event.name} {...event} onEmit={this.onEmit} />)}
</div> </Wrapper>
); );
} }
} }

View File

@ -9,13 +9,13 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -2,13 +2,13 @@
"name": "@storybook/addon-info", "name": "@storybook/addon-info",
"version": "4.0.0-alpha.7", "version": "4.0.0-alpha.7",
"description": "A Storybook addon to show additional information for your stories.", "description": "A Storybook addon to show additional information for your stories.",
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -17,13 +17,13 @@
"@storybook/components": "4.0.0-alpha.7", "@storybook/components": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"core-js": "2.5.6", "core-js": "2.5.6",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"marksy": "^6.0.3", "marksy": "^6.0.3",
"nested-object-assign": "^1.0.1", "nested-object-assign": "^1.0.1",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-addons-create-fragment": "^15.5.3", "react-addons-create-fragment": "^15.5.3",
"react-emotion": "^9.1.3",
"react-lifecycles-compat": "^3.0.4", "react-lifecycles-compat": "^3.0.4",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
}, },

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,9 @@ import PropVal from './PropVal';
import PrettyPropType from './types/PrettyPropType'; import PrettyPropType from './types/PrettyPropType';
export const multiLineText = input => { export const multiLineText = input => {
if (!input) return input; if (!input) {
return input;
}
const text = String(input); const text = String(input);
const arrayOfText = text.split(/\r?\n|\r/g); const arrayOfText = text.split(/\r?\n|\r/g);
const isSingleLine = arrayOfText.length < 2; const isSingleLine = arrayOfText.length < 2;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import { mount } from 'enzyme'; import { shallow } from 'enzyme';
import PropTable, { multiLineText } from './PropTable'; import PropTable, { multiLineText } from './PropTable';
@ -28,13 +28,13 @@ describe('PropTable', () => {
}; };
it('should include all propTypes by default', () => { it('should include all propTypes by default', () => {
const wrapper = mount(<PropTable {...propTableProps} />); const wrapper = shallow(<PropTable {...propTableProps} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it('should exclude excluded propTypes', () => { it('should exclude excluded propTypes', () => {
const props = { ...propTableProps, excludedPropTypes: ['foo'] }; const props = { ...propTableProps, excludedPropTypes: ['foo'] };
const wrapper = mount(<PropTable {...props} />); const wrapper = shallow(<PropTable {...props} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withTheme } from 'glamorous';
import createFragment from 'react-addons-create-fragment'; import createFragment from 'react-addons-create-fragment';
const getValueStyles = (codeColors = {}) => ({ const getValueStyles = (codeColors = {}) => ({
@ -282,4 +281,4 @@ PropVal.propTypes = {
}), }),
}; };
export default withTheme(PropVal); export default PropVal;

View File

@ -5,7 +5,6 @@ import { polyfill } from 'react-lifecycles-compat';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import global from 'global'; import global from 'global';
import { baseFonts } from '@storybook/components'; import { baseFonts } from '@storybook/components';
import { ThemeProvider } from 'glamorous';
import marksy from 'marksy'; import marksy from 'marksy';
@ -364,11 +363,8 @@ class Story extends React.Component {
} }
render() { render() {
return ( // <ThemeProvider theme={this.state.stylesheet}></ThemeProvider>
<ThemeProvider theme={this.state.stylesheet}> return this.props.showInline ? this._renderInline() : this._renderOverlay();
{this.props.showInline ? this._renderInline() : this._renderOverlay()}
</ThemeProvider>
);
} }
} }

View File

@ -1,34 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PropTable multiLineText should exclude excluded propTypes 1`] = ` exports[`PropTable multiLineText should exclude excluded propTypes 1`] = `
<PropTable <small>
excludedPropTypes={ No propTypes defined!
Array [ </small>
"foo",
]
}
maxPropArrayLength={5}
maxPropObjectKeys={5}
maxPropStringLength={5}
propDefinitions={
Array [
Object {
"defaultValue": undefined,
"description": "",
"propType": Object {
"name": "string",
},
"property": "foo",
"required": false,
},
]
}
type={[Function]}
>
<small>
No propTypes defined!
</small>
</PropTable>
`; `;
exports[`PropTable multiLineText should have 2 br tags for 3 lines of text 1`] = ` exports[`PropTable multiLineText should have 2 br tags for 3 lines of text 1`] = `
@ -51,142 +26,73 @@ Array [
`; `;
exports[`PropTable multiLineText should include all propTypes by default 1`] = ` exports[`PropTable multiLineText should include all propTypes by default 1`] = `
<PropTable <Table>
excludedPropTypes={Array []} <thead>
maxPropArrayLength={5} <tr>
maxPropObjectKeys={5} <Th
maxPropStringLength={5} bordered={true}
propDefinitions={ >
Array [ property
Object { </Th>
"defaultValue": undefined, <Th
"description": "", bordered={true}
"propType": Object { >
"name": "string", propType
}, </Th>
"property": "foo", <Th
"required": false, bordered={true}
}, >
] required
} </Th>
type={[Function]} <Th
> bordered={true}
<glamorous(table)> >
<table default
className="css-1ytzlk7" </Th>
<Th
bordered={true}
>
description
</Th>
</tr>
</thead>
<tbody>
<tr
key="foo"
> >
<thead> <Td
<tr> bordered={true}
<glamorous(th) code={true}
bordered={true} >
> foo
<th </Td>
className="css-d52hbj" <Td
> bordered={true}
property code={true}
</th> >
</glamorous(th)> <PrettyPropType
<glamorous(th) depth={1}
bordered={true} propType={
> Object {
<th "name": "string",
className="css-d52hbj" }
> }
propType />
</th> </Td>
</glamorous(th)> <Td
<glamorous(th) bordered={true}
bordered={true} >
> -
<th </Td>
className="css-d52hbj" <Td
> bordered={true}
required >
</th> -
</glamorous(th)> </Td>
<glamorous(th) <Td
bordered={true} bordered={true}
> />
<th </tr>
className="css-d52hbj" </tbody>
> </Table>
default
</th>
</glamorous(th)>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
description
</th>
</glamorous(th)>
</tr>
</thead>
<tbody>
<tr
key="foo"
>
<glamorous(td)
bordered={true}
code={true}
>
<td
className="css-1ygfcef"
>
foo
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
code={true}
>
<td
className="css-1ygfcef"
>
<PrettyPropType
depth={1}
propType={
Object {
"name": "string",
}
}
>
<span>
string
</span>
</PrettyPropType>
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
>
-
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
>
-
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
/>
</glamorous(td)>
</tr>
</tbody>
</table>
</glamorous(table)>
</PropTable>
`; `;

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous, { withTheme } from 'glamorous'; import styled from 'react-emotion';
const Button = glamorous.button( const Button = styled('button')(
{ {
overflow: 'hidden', overflow: 'hidden',
border: '1px solid #eee', border: '1px solid #eee',
@ -26,7 +26,7 @@ const Button = glamorous.button(
props => props.styles props => props.styles
); );
const ContentWrapper = glamorous.div( const ContentWrapper = styled('div')(
{ {
transition: 'transform .2s ease', transition: 'transform .2s ease',
height: 16, height: 16,
@ -65,4 +65,4 @@ CopyButton.defaultProps = {
theme: {}, theme: {},
}; };
export default withTheme(CopyButton); export default CopyButton;

View File

@ -1,13 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous, { withTheme } from 'glamorous'; import styled from 'react-emotion';
import CopyButton from './copyButton'; import CopyButton from './copyButton';
import copy from './copy'; import copy from './copy';
const TOGGLE_TIMEOUT = 1800; const TOGGLE_TIMEOUT = 1800;
const StyledPre = glamorous.pre( const StyledPre = styled('pre')(
{ {
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
@ -72,4 +72,4 @@ Pre.defaultProps = {
theme: {}, theme: {},
}; };
export default withTheme(Pre); export default Pre;

View File

@ -13,14 +13,14 @@
], ],
"homepage": "https://storybook.js.org", "homepage": "https://storybook.js.org",
"bugs": "https://github.com/storybooks/storybook", "bugs": "https://github.com/storybooks/storybook",
"license": "MIT",
"author": "Renaud Tertrais <renaud.tertrais@gmail.com> (https://github.com/renaudtertrais)",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/storybooks/storybook" "url": "git+https://github.com/storybooks/storybook"
}, },
"license": "MIT",
"author": "Renaud Tertrais <renaud.tertrais@gmail.com> (https://github.com/renaudtertrais)",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -28,10 +28,10 @@
"@storybook/addons": "4.0.0-alpha.7", "@storybook/addons": "4.0.0-alpha.7",
"@storybook/components": "4.0.0-alpha.7", "@storybook/components": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"prop-types": "^15.6.1" "prop-types": "^15.6.1",
"react-emotion": "^9.1.3"
}, },
"peerDependencies": { "peerDependencies": {
"react": "*" "react": "*"

View File

@ -1,8 +1,8 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous from 'glamorous'; import styled from 'react-emotion';
const Indicator = glamorous.div( const Indicator = styled('div')(
({ color, size }) => ({ ({ color, size }) => ({
boxSizing: 'border-box', boxSizing: 'border-box',
padding: `0 ${size / 2}px`, padding: `0 ${size / 2}px`,

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous from 'glamorous'; import styled from 'react-emotion';
import { baseFonts } from '@storybook/components'; import { baseFonts } from '@storybook/components';
@ -9,32 +9,32 @@ import Result, { FailedResult } from './Result';
import provideJestResult from '../hoc/provideJestResult'; import provideJestResult from '../hoc/provideJestResult';
import colors from '../colors'; import colors from '../colors';
const List = glamorous.ul({ const List = styled('ul')({
listStyle: 'none', listStyle: 'none',
fontSize: 14, fontSize: 14,
padding: 0, padding: 0,
margin: '10px 0', margin: '10px 0',
}); });
const Item = glamorous.li({ const Item = styled('li')({
display: 'block', display: 'block',
margin: '10px 0', margin: '10px 0',
padding: 0, padding: 0,
}); });
const NoTests = glamorous.div({ const NoTests = styled('div')({
padding: '10px 20px', padding: '10px 20px',
flex: 1, flex: 1,
...baseFonts, ...baseFonts,
}); });
const FileTitle = glamorous.h2({ const FileTitle = styled('h2')({
margin: 0, margin: 0,
fontWeight: 500, fontWeight: 500,
fontSize: 18, fontSize: 18,
}); });
const SuiteHead = glamorous.div({ const SuiteHead = styled('div')({
display: 'flex', display: 'flex',
alignItems: 'baseline', alignItems: 'baseline',
justifyContent: 'space-between', justifyContent: 'space-between',
@ -42,7 +42,7 @@ const SuiteHead = glamorous.div({
paddingTop: 10, paddingTop: 10,
}); });
const SuiteTotals = glamorous(({ successNumber, failedNumber, result, className }) => ( const SuiteTotals = styled(({ successNumber, failedNumber, result, className }) => (
<div className={className}> <div className={className}>
{successNumber > 0 && <div style={{ color: colors.success }}>{successNumber} passed</div>} {successNumber > 0 && <div style={{ color: colors.success }}>{successNumber} passed</div>}
{failedNumber > 0 && <div style={{ color: colors.error }}>{failedNumber} failed</div>} {failedNumber > 0 && <div style={{ color: colors.error }}>{failedNumber} failed</div>}
@ -62,7 +62,7 @@ const SuiteTotals = glamorous(({ successNumber, failedNumber, result, className
}, },
}); });
const SuiteProgress = glamorous(({ successNumber, result, className }) => ( const SuiteProgress = styled(({ successNumber, result, className }) => (
<div className={className} role="progressbar"> <div className={className} role="progressbar">
<span style={{ width: `${successNumber / result.assertionResults.length * 100}%` }}> <span style={{ width: `${successNumber / result.assertionResults.length * 100}%` }}>
{`${successNumber / result.assertionResults.length * 100}%`} {`${successNumber / result.assertionResults.length * 100}%`}
@ -89,12 +89,12 @@ const SuiteProgress = glamorous(({ successNumber, result, className }) => (
}, },
})); }));
const SuiteTitle = glamorous.div({ const SuiteTitle = styled('div')({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
}); });
const Content = glamorous(({ tests, className }) => ( const Content = styled(({ tests, className }) => (
<div className={className}> <div className={className}>
{tests.map(({ name, result }) => { {tests.map(({ name, result }) => {
if (!result) { if (!result) {

View File

@ -1,17 +1,17 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous from 'glamorous'; import styled from 'react-emotion';
import provideJestResult from '../hoc/provideJestResult'; import provideJestResult from '../hoc/provideJestResult';
import Indicator from './Indicator'; import Indicator from './Indicator';
import colors from '../colors'; import colors from '../colors';
const Wrapper = glamorous.div({ const Wrapper = styled('div')({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
}); });
const PanelName = glamorous.div({ const PanelName = styled('div')({
paddingLeft: 5, paddingLeft: 5,
}); });

View File

@ -1,34 +1,34 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous from 'glamorous'; import styled from 'react-emotion';
import { monoFonts } from '@storybook/components'; import { monoFonts } from '@storybook/components';
import Indicator from './Indicator'; import Indicator from './Indicator';
import colors from '../colors'; import colors from '../colors';
const Pre = glamorous.pre({ const Pre = styled('pre')({
margin: 0, margin: 0,
...monoFonts, ...monoFonts,
}); });
const FlexContainer = glamorous.div` const FlexContainer = styled('div')({
display: flex; display: 'flex',
align-items: center; alignItems: 'center',
`; });
/* eslint no-control-regex:0 */ /* eslint no-control-regex:0 */
const patterns = [/^\x08+/, /^\x1b\[[012]?K/, /^\x1b\[?[\d;]{0,3}/]; const patterns = [/^\x08+/, /^\x1b\[[012]?K/, /^\x1b\[?[\d;]{0,3}/];
const Positive = glamorous.strong({ const Positive = styled('strong')({
color: colors.success, color: colors.success,
fontWeight: 500, fontWeight: 500,
}); });
const Negative = glamorous.strong({ const Negative = styled('strong')({
color: colors.error, color: colors.error,
fontWeight: 500, fontWeight: 500,
}); });
const StackTrace = glamorous(({ trace, className }) => ( const StackTrace = styled(({ trace, className }) => (
<details className={className}> <details className={className}>
<summary>Callstack</summary> <summary>Callstack</summary>
{trace {trace
@ -42,11 +42,11 @@ const StackTrace = glamorous(({ trace, className }) => (
background: 'silver', background: 'silver',
padding: 10, padding: 10,
}); });
const Main = glamorous(({ msg, className }) => <section className={className}>{msg}</section>)({ const Main = styled(({ msg, className }) => <section className={className}>{msg}</section>)({
padding: 10, padding: 10,
borderBottom: '1px solid silver', borderBottom: '1px solid silver',
}); });
const Sub = glamorous(({ msg, className }) => ( const Sub = styled(({ msg, className }) => (
<section className={className}> <section className={className}>
{msg {msg
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.trim() !== '')) .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.trim() !== ''))
@ -59,7 +59,6 @@ const Sub = glamorous(({ msg, className }) => (
return item.replace(/^[\s\n]*/, ''); return item.replace(/^[\s\n]*/, '');
} }
case typeof item === 'string' && index === list.length - 1: { case typeof item === 'string' && index === list.length - 1: {
debugger; //eslint-disable-line
return item.replace(/[\s\n]*$/, ''); return item.replace(/[\s\n]*$/, '');
} }
default: { default: {
@ -89,7 +88,6 @@ const createSubgroup = (acc, item, i, list) => {
// start or stop extraction // start or stop extraction
if (acc.startTrigger(item)) { if (acc.startTrigger(item)) {
// debugger; //eslint-disable-line
acc.mode = 'inject'; acc.mode = 'inject';
acc.injectionPoint = i; acc.injectionPoint = i;
} }
@ -188,18 +186,18 @@ Message.propTypes = {
msg: PropTypes.string.isRequired, msg: PropTypes.string.isRequired,
}; };
const Head = glamorous.header({ const Head = styled('header')({
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'flex-start', alignItems: 'flex-start',
}); });
const Title = glamorous.h3({ const Title = styled('h3')({
padding: '10px 10px 0 10px', padding: '10px 10px 0 10px',
margin: 0, margin: 0,
}); });
export const FailedResult = glamorous(({ fullName, title, status, failureMessages, className }) => ( export const FailedResult = styled(({ fullName, title, status, failureMessages, className }) => (
<div className={className}> <div className={className}>
<Head> <Head>
<FlexContainer> <FlexContainer>

View File

@ -2,13 +2,13 @@
"name": "@storybook/addon-knobs", "name": "@storybook/addon-knobs",
"version": "4.0.0-alpha.7", "version": "4.0.0-alpha.7",
"description": "Storybook Addon Prop Editor Component", "description": "Storybook Addon Prop Editor Component",
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -26,6 +26,7 @@
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-color": "^2.14.1", "react-color": "^2.14.1",
"react-datetime": "^2.14.0", "react-datetime": "^2.14.0",
"react-emotion": "^9.1.3",
"react-lifecycles-compat": "^3.0.4", "react-lifecycles-compat": "^3.0.4",
"react-textarea-autosize": "^6.1.0", "react-textarea-autosize": "^6.1.0",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"

View File

@ -1,71 +1,50 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { baseFonts } from '@storybook/components'; import styled from 'react-emotion';
const styles = { import { Placeholder } from '@storybook/components';
empty: {
flex: 1,
display: 'flex',
...baseFonts,
fontSize: 11,
letterSpacing: '1px',
textTransform: 'uppercase',
alignItems: 'center',
justifyContent: 'center',
},
wrapper: { const Wrapper = styled('div')({
flex: '1 1 auto', flex: '1 1 auto',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
background: 'white', background: 'white',
borderRadius: 4, borderRadius: 4,
border: 'solid 1px rgb(236, 236, 236)', border: 'solid 1px rgb(236, 236, 236)',
width: '100%', width: '100%',
}, });
tabbar: { const Bar = styled('div')({
display: 'flex', display: 'flex',
flexWrap: 'wrap', flexWrap: 'wrap',
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
borderBottom: 'solid 1px #eaeaea', borderBottom: 'solid 1px #eaeaea',
}, });
content: { const Content = styled('div')({
flex: '1 1 0', flex: '1 1 0',
display: 'flex', display: 'flex',
overflow: 'auto', overflow: 'auto',
}, });
tablink: { const Tab = styled('button')(({ active }) => ({
...baseFonts, fontSize: 11,
fontSize: 11, letterSpacing: '1px',
letterSpacing: '1px', padding: '10px 15px',
padding: '10px 15px', textTransform: 'uppercase',
textTransform: 'uppercase', transition: 'opacity 0.3s',
transition: 'opacity 0.3s', opacity: active ? 1 : 0.5,
opacity: 0.5, maxHeight: 60,
maxHeight: 60, overflow: 'hidden',
overflow: 'hidden', cursor: 'pointer',
cursor: 'pointer', background: 'transparent',
background: 'transparent', border: 'none',
border: 'none', }));
},
activetab: {
opacity: 1,
},
};
class GroupTabs extends Component { class GroupTabs extends Component {
renderTab(name, group) { renderTab(name, group) {
let tabStyle = styles.tablink;
if (this.props.selectedGroup === name) {
tabStyle = Object.assign({}, styles.tablink, styles.activetab);
}
const onClick = e => { const onClick = e => {
e.preventDefault(); e.preventDefault();
this.props.onGroupSelect(name); this.props.onGroupSelect(name);
@ -77,51 +56,40 @@ class GroupTabs extends Component {
} }
return ( return (
<button type="button" key={name} style={tabStyle} onClick={onClick} role="tab"> <Tab
type="button"
key={name}
onClick={onClick}
role="tab"
active={this.props.selectedGroup === name}
>
{title} {title}
</button> </Tab>
); );
} }
renderTabs() {
return Object.keys(this.props.groups).map(name => {
const group = this.props.groups[name];
return this.renderTab(name, group);
});
}
renderGroups() {
return Object.keys(this.props.groups)
.sort()
.map(name => {
const groupStyle = { display: 'none' };
const group = this.props.groups[name];
if (name === this.props.selectedGroup) {
Object.assign(groupStyle, { flex: 1, display: 'flex' });
}
return (
<div key={name} style={groupStyle}>
{group.render()}
</div>
);
});
}
renderEmpty() {
return <div style={styles.empty}>no groups available</div>;
}
render() { render() {
if (!this.props.groups || !Object.keys(this.props.groups).length) { const entries = this.props.groups ? Object.entries(this.props.groups) : null;
return this.renderEmpty();
} return entries && entries.length ? (
return ( <Wrapper>
<div style={styles.wrapper}> <Bar role="tablist">{entries.map(([key, value]) => this.renderTab(key, value))}</Bar>
<div style={styles.tabbar} role="tablist"> <Content>
{this.renderTabs()} {entries.map(([key, value]) => {
</div> const groupStyle = { display: 'none' };
<div style={styles.content}>{this.renderGroups()}</div> if (key === this.props.selectedGroup) {
</div> Object.assign(groupStyle, { flex: 1, display: 'flex' });
}
return (
<div key={key} style={groupStyle}>
{value.render()}
</div>
);
})}
</Content>
</Wrapper>
) : (
<Placeholder>no groups available</Placeholder>
); );
} }
} }
@ -133,7 +101,8 @@ GroupTabs.defaultProps = {
}; };
GroupTabs.propTypes = { GroupTabs.propTypes = {
groups: PropTypes.object, // eslint-disable-line react/forbid-prop-types // eslint-disable-next-line react/forbid-prop-types
groups: PropTypes.object,
onGroupSelect: PropTypes.func, onGroupSelect: PropTypes.func,
selectedGroup: PropTypes.string, selectedGroup: PropTypes.string,
}; };

View File

@ -1,6 +1,9 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
import { Placeholder } from '@storybook/components';
import GroupTabs from './GroupTabs'; import GroupTabs from './GroupTabs';
import PropForm from './PropForm'; import PropForm from './PropForm';
import Types from './types'; import Types from './types';
@ -9,40 +12,29 @@ const getTimestamp = () => +new Date();
const DEFAULT_GROUP_ID = 'ALL'; const DEFAULT_GROUP_ID = 'ALL';
const styles = { const PanelWrapper = styled('div')({
panelWrapper: { width: '100%',
width: '100%', });
},
panel: { const PanelInner = styled('div')({
padding: '5px', padding: '5px',
width: 'auto', width: 'auto',
position: 'relative', position: 'relative',
}, });
noKnobs: {
fontFamily: ` const ResetButton = styled('button')({
-apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", position: 'absolute',
"Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif bottom: 11,
`, right: 10,
display: 'inline', border: 'none',
width: '100%', borderTop: 'solid 1px rgba(0, 0, 0, 0.2)',
textAlign: 'center', borderLeft: 'solid 1px rgba(0, 0, 0, 0.2)',
color: 'rgb(190, 190, 190)', background: 'rgba(255, 255, 255, 0.5)',
padding: '10px', padding: '5px 10px',
}, borderRadius: '4px 0 0 0',
resetButton: { color: 'rgba(0, 0, 0, 0.5)',
position: 'absolute', outline: 'none',
bottom: 11, });
right: 10,
border: 'none',
borderTop: 'solid 1px rgba(0, 0, 0, 0.2)',
borderLeft: 'solid 1px rgba(0, 0, 0, 0.2)',
background: 'rgba(255, 255, 255, 0.5)',
padding: '5px 10px',
borderRadius: '4px 0 0 0',
color: 'rgba(0, 0, 0, 0.5)',
outline: 'none',
},
};
export default class Panel extends React.Component { export default class Panel extends React.Component {
constructor(props) { constructor(props) {
@ -172,11 +164,11 @@ export default class Panel extends React.Component {
knobsArray = knobsArray.map(key => knobs[key]); knobsArray = knobsArray.map(key => knobs[key]);
if (knobsArray.length === 0) { if (knobsArray.length === 0) {
return <div style={styles.noKnobs}>NO KNOBS</div>; return <Placeholder>NO KNOBS</Placeholder>;
} }
return ( return (
<div style={styles.panelWrapper}> <PanelWrapper>
{groupIds.length > 0 && ( {groupIds.length > 0 && (
<GroupTabs <GroupTabs
groups={groups} groups={groups}
@ -184,17 +176,15 @@ export default class Panel extends React.Component {
selectedGroup={this.state.groupId} selectedGroup={this.state.groupId}
/> />
)} )}
<div style={styles.panel}> <PanelInner>
<PropForm <PropForm
knobs={knobsArray} knobs={knobsArray}
onFieldChange={this.handleChange} onFieldChange={this.handleChange}
onFieldClick={this.handleClick} onFieldClick={this.handleClick}
/> />
</div> </PanelInner>
<button style={styles.resetButton} onClick={this.reset}> <ResetButton onClick={this.reset}>RESET</ResetButton>
RESET </PanelWrapper>
</button>
</div>
); );
} }
} }

View File

@ -1,49 +1,32 @@
/* eslint-disable no-underscore-dangle */
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import styled from 'react-emotion';
import TypeMap from './types'; import TypeMap from './types';
const InvalidType = () => <span>Invalid Type</span>; const InvalidType = () => <span>Invalid Type</span>;
const stylesheet = { const Field = styled('div')({
field: { display: 'table-row',
display: 'table-row', padding: '5px',
padding: '5px', });
}, const Label = styled('label')({
label: { display: 'table-cell',
display: 'table-cell', boxSizing: 'border-box',
boxSizing: 'border-box', verticalAlign: 'top',
verticalAlign: 'top', paddingRight: 5,
paddingRight: 5, paddingTop: 5,
paddingTop: 5, textAlign: 'right',
textAlign: 'right', width: 80,
width: 80, fontSize: 12,
fontSize: 12, color: 'rgb(68, 68, 68)',
color: 'rgb(68, 68, 68)', fontWeight: 600,
fontWeight: 600, });
},
};
stylesheet.textarea = {
...stylesheet.input,
height: '100px',
};
stylesheet.checkbox = {
...stylesheet.input,
width: 'auto',
};
export default class PropField extends React.Component { export default class PropField extends React.Component {
constructor(props) { onChange = e => {
super(props);
this._onChange = this.onChange.bind(this);
}
onChange(e) {
this.props.onChange(e.target.value); this.props.onChange(e.target.value);
} };
render() { render() {
const { onChange, onClick, knob } = this.props; const { onChange, onClick, knob } = this.props;
@ -51,12 +34,10 @@ export default class PropField extends React.Component {
const InputType = TypeMap[knob.type] || InvalidType; const InputType = TypeMap[knob.type] || InvalidType;
return ( return (
<div style={stylesheet.field}> <Field>
<label htmlFor={knob.name} style={stylesheet.label}> <Label htmlFor={knob.name}>{!knob.hideLabel && `${knob.name}`}</Label>
{!knob.hideLabel && `${knob.name}`}
</label>
<InputType knob={knob} onChange={onChange} onClick={onClick} /> <InputType knob={knob} onChange={onChange} onClick={onClick} />
</div> </Field>
); );
} }
} }

View File

@ -1,23 +1,17 @@
/* eslint no-underscore-dangle: 0 */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
import PropField from './PropField'; import PropField from './PropField';
const stylesheet = { const Form = styled('form')({
propForm: { display: 'table',
fontFamily: ` boxSizing: 'border-box',
-apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", width: '100%',
"Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif borderCollapse: 'separate',
`, borderSpacing: '5px',
display: 'table', });
boxSizing: 'border-box',
width: '100%',
borderCollapse: 'separate',
borderSpacing: '5px',
},
};
export default class propForm extends React.Component { export default class propForm extends React.Component {
makeChangeHandler(name, type) { makeChangeHandler(name, type) {
@ -31,7 +25,7 @@ export default class propForm extends React.Component {
const { knobs } = this.props; const { knobs } = this.props;
return ( return (
<form style={stylesheet.propForm}> <Form>
{knobs.map(knob => { {knobs.map(knob => {
const changeHandler = this.makeChangeHandler(knob.name, knob.type); const changeHandler = this.makeChangeHandler(knob.name, knob.type);
return ( return (
@ -46,7 +40,7 @@ export default class propForm extends React.Component {
/> />
); );
})} })}
</form> </Form>
); );
} }
} }

View File

@ -30,6 +30,7 @@ describe('GroupTabs', () => {
test('should set onGroupSelected as onClick handlers of tabs', () => { test('should set onGroupSelected as onClick handlers of tabs', () => {
const groups = { const groups = {
test1: { test1: {
title: 'test 1',
render() { render() {
return <div>TEST 1</div>; return <div>TEST 1</div>;
}, },
@ -40,7 +41,10 @@ describe('GroupTabs', () => {
const wrapper = shallow( const wrapper = shallow(
<GroupTabs groups={groups} onGroupSelect={onGroupSelect} selectedGroup="test1" /> <GroupTabs groups={groups} onGroupSelect={onGroupSelect} selectedGroup="test1" />
); );
wrapper.find('button').simulate('click', { preventDefault }); wrapper
.find('Styled(button)')
.dive()
.simulate('click', { preventDefault });
expect(onGroupSelect).toHaveBeenCalled(); expect(onGroupSelect).toHaveBeenCalled();
expect(preventDefault).toHaveBeenCalled(); expect(preventDefault).toHaveBeenCalled();

View File

@ -1,22 +1,24 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import Textarea from 'react-textarea-autosize'; import styled from 'react-emotion';
import Textarea from 'react-textarea-autosize';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
const styles = { const StyledTextarea = styled(Textarea)({
display: 'table-cell', display: 'table-cell',
boxSizing: 'border-box', boxSizing: 'border-box',
verticalAlign: 'middle', verticalAlign: 'middle',
height: '26px', height: '26px',
width: '100%', width: '100%',
maxWidth: '100%',
outline: 'none', outline: 'none',
border: '1px solid #f7f4f4', border: '1px solid #f7f4f4',
borderRadius: 2, borderRadius: 2,
fontSize: 11, fontSize: 11,
padding: '5px', padding: '5px',
color: '#555', color: '#555',
}; });
function formatArray(value, separator) { function formatArray(value, separator) {
if (value === '') { if (value === '') {
@ -36,6 +38,10 @@ class ArrayType extends React.Component {
this.onChange = debounce(this.props.onChange, 200); this.onChange = debounce(this.props.onChange, 200);
} }
componentWillUnmount() {
this.onChange.cancel();
}
handleChange = e => { handleChange = e => {
const { knob } = this.props; const { knob } = this.props;
const { value } = e.target; const { value } = e.target;
@ -49,7 +55,7 @@ class ArrayType extends React.Component {
const { knob } = this.props; const { knob } = this.props;
const { value } = this.state; const { value } = this.state;
return <Textarea id={knob.name} style={styles} value={value} onChange={this.handleChange} />; return <StyledTextarea id={knob.name} value={value} onChange={this.handleChange} />;
} }
} }

View File

@ -1,7 +1,9 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
const styles = { import styled from 'react-emotion';
const Input = styled('input')({
display: 'table-cell', display: 'table-cell',
boxSizing: 'border-box', boxSizing: 'border-box',
verticalAlign: 'top', verticalAlign: 'top',
@ -10,19 +12,18 @@ const styles = {
border: '1px solid #ececec', border: '1px solid #ececec',
fontSize: '12px', fontSize: '12px',
color: '#555', color: '#555',
}; });
class BooleanType extends React.Component { class BooleanType extends React.Component {
render() { render() {
const { knob, onChange } = this.props; const { knob, onChange } = this.props;
return ( return (
<input <Input
id={knob.name} id={knob.name}
ref={c => { ref={c => {
this.input = c; this.input = c;
}} }}
style={styles}
type="checkbox" type="checkbox"
onChange={() => onChange(this.input.checked)} onChange={() => onChange(this.input.checked)}
checked={knob.value} checked={knob.value}

View File

@ -1,28 +1,17 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
const styles = { import styled from 'react-emotion';
height: '26px',
};
class ButtonType extends React.Component { const Button = styled('button')({
render() { height: '26px',
const { knob, onClick } = this.props; });
return (
<button const ButtonType = ({ knob, onClick }) => (
type="button" <Button type="button" id={knob.name} onClick={() => onClick(knob)}>
id={knob.name} {knob.name}
ref={c => { </Button>
this.input = c; );
}}
style={styles}
onClick={() => onClick(knob)}
>
{knob.name}
</button>
);
}
}
ButtonType.defaultProps = { ButtonType.defaultProps = {
knob: {}, knob: {},

View File

@ -2,32 +2,29 @@ import { document } from 'global';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { SketchPicker } from 'react-color'; import { SketchPicker } from 'react-color';
import styled from 'react-emotion';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
const conditionalRender = (condition, positive, negative) => (condition ? positive() : negative()); const SwatchButton = styled('button')({
background: '#fff',
const styles = { borderRadius: '1px',
swatch: { border: '1px solid rgb(247, 244, 244)',
background: '#fff', display: 'inline-block',
borderRadius: '1px', cursor: 'pointer',
border: '1px solid rgb(247, 244, 244)', width: '100%',
display: 'inline-block', padding: 0,
cursor: 'pointer', });
width: '100%', const Swatch = styled('div')({
padding: 0, width: 'auto',
}, height: '20px',
popover: { borderRadius: '2px',
position: 'absolute', margin: 5,
zIndex: '2', });
}, const Popover = styled('div')({
cover: { position: 'absolute',
position: 'fixed', zIndex: '2',
top: '0px', });
right: '0px',
bottom: '0px',
left: '0px',
},
};
class ColorType extends React.Component { class ColorType extends React.Component {
constructor(props, context) { constructor(props, context) {
@ -46,6 +43,7 @@ class ColorType extends React.Component {
} }
componentWillUnmount() { componentWillUnmount() {
document.removeEventListener('mousedown', this.handleWindowMouseDown); document.removeEventListener('mousedown', this.handleWindowMouseDown);
this.onChange.cancel();
} }
handleWindowMouseDown = e => { handleWindowMouseDown = e => {
@ -75,31 +73,23 @@ class ColorType extends React.Component {
const { knob } = this.props; const { knob } = this.props;
const { displayColorPicker, value } = this.state; const { displayColorPicker, value } = this.state;
const colorStyle = { const colorStyle = {
width: 'auto',
height: '20px',
borderRadius: '2px',
margin: 5,
background: knob.value, background: knob.value,
}; };
return ( return (
<div id={knob.name}> <div id={knob.name}>
<button type="button" style={styles.swatch} onClick={this.handleClick}> <SwatchButton type="button" onClick={this.handleClick}>
<div style={colorStyle} /> <Swatch style={colorStyle} />
</button> </SwatchButton>
{conditionalRender( {displayColorPicker ? (
displayColorPicker, <Popover
() => ( innerRef={e => {
<div this.popover = e;
style={styles.popover} }}
ref={e => { >
this.popover = e; <SketchPicker color={value} onChange={this.handleChange} />
}} </Popover>
> ) : null}
<SketchPicker color={value} onChange={this.handleChange} />
</div>
),
() => null
)}
</div> </div>
); );
} }

View File

@ -2,6 +2,23 @@ import { FileReader } from 'global';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import styled from 'react-emotion';
const Input = styled('input')({
display: 'table-cell',
boxSizing: 'border-box',
verticalAlign: 'middle',
height: '26px',
width: '100%',
maxWidth: '100%',
outline: 'none',
border: '1px solid #f7f4f4',
borderRadius: 2,
fontSize: 11,
padding: '5px',
color: '#555',
});
function fileReaderPromise(file) { function fileReaderPromise(file) {
return new Promise(resolve => { return new Promise(resolve => {
const fileReader = new FileReader(); const fileReader = new FileReader();
@ -11,7 +28,7 @@ function fileReaderPromise(file) {
} }
const FilesType = ({ knob, onChange }) => ( const FilesType = ({ knob, onChange }) => (
<input <Input
id={knob.name} id={knob.name}
type="file" type="file"
multiple multiple

View File

@ -1,39 +1,41 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import styled from 'react-emotion';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
const styles = { const base = {
common: { boxSizing: 'border-box',
boxSizing: 'border-box', height: '25px',
height: '25px', outline: 'none',
outline: 'none', border: '1px solid #f7f4f4',
border: '1px solid #f7f4f4', borderRadius: 2,
borderRadius: 2, fontSize: 11,
fontSize: 11, padding: '5px',
padding: '5px', color: '#444',
color: '#444',
},
normal: {
display: 'table-cell',
width: '100%',
verticalAlign: 'middle',
},
range: {
flexGrow: 1,
},
rangeLabel: {
paddingLeft: 5,
paddingRight: 5,
fontSize: 12,
whiteSpace: 'nowrap',
},
rangeWrapper: {
display: 'flex',
alignItems: 'center',
width: '100%',
},
}; };
const TextInput = styled('input')(base, {
display: 'table-cell',
width: '100%',
verticalAlign: 'middle',
});
const RangeInput = styled('input')(base, {
display: 'table-cell',
flexGrow: 1,
});
const RangeLabel = styled('span')({
paddingLeft: 5,
paddingRight: 5,
fontSize: 12,
whiteSpace: 'nowrap',
});
const RangeWrapper = styled('div')({
display: 'flex',
alignItems: 'center',
width: '100%',
});
class NumberType extends React.Component { class NumberType extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -45,6 +47,10 @@ class NumberType extends React.Component {
this.onChange = debounce(props.onChange, 400); this.onChange = debounce(props.onChange, 400);
} }
componentWillUnmount() {
this.onChange.cancel();
}
handleChange = event => { handleChange = event => {
const { value } = event.target; const { value } = event.target;
@ -59,14 +65,27 @@ class NumberType extends React.Component {
this.onChange(parsedValue); this.onChange(parsedValue);
}; };
renderNormal() { render() {
const { knob } = this.props; const { knob } = this.props;
const { value } = this.state; const { value } = this.state;
return ( return knob.range ? (
<input <RangeWrapper>
<RangeLabel>{knob.min}</RangeLabel>
<RangeInput
id={knob.name}
value={value}
type="range"
min={knob.min}
max={knob.max}
step={knob.step}
onChange={this.handleChange}
/>
<RangeLabel>{`${value} / ${knob.max}`}</RangeLabel>
</RangeWrapper>
) : (
<TextInput
id={knob.name} id={knob.name}
style={{ ...styles.common, ...styles.normal }}
value={value} value={value}
type="number" type="number"
min={knob.min} min={knob.min}
@ -76,34 +95,6 @@ class NumberType extends React.Component {
/> />
); );
} }
renderRange() {
const { knob } = this.props;
const { value } = this.state;
return (
<div style={styles.rangeWrapper}>
<span style={styles.rangeLabel}>{knob.min}</span>
<input
id={knob.name}
style={{ ...styles.common, ...styles.range }}
value={value}
type="range"
min={knob.min}
max={knob.max}
step={knob.step}
onChange={this.handleChange}
/>
<span style={styles.rangeLabel}>{`${value} / ${knob.max}`}</span>
</div>
);
}
render() {
const { knob } = this.props;
return knob.range ? this.renderRange() : this.renderNormal();
}
} }
NumberType.defaultProps = { NumberType.defaultProps = {

View File

@ -1,9 +1,11 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React, { Component } from 'react';
import styled from 'react-emotion';
import Textarea from 'react-textarea-autosize'; import Textarea from 'react-textarea-autosize';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
const styles = { const StyledTextarea = styled(Textarea)({
display: 'table-cell', display: 'table-cell',
boxSizing: 'border-box', boxSizing: 'border-box',
verticalAlign: 'middle', verticalAlign: 'middle',
@ -15,9 +17,9 @@ const styles = {
padding: '5px', padding: '5px',
color: '#555', color: '#555',
fontFamily: 'monospace', fontFamily: 'monospace',
}; });
class ObjectType extends React.Component { class ObjectType extends Component {
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
@ -37,6 +39,10 @@ class ObjectType extends React.Component {
this.onChange = debounce(props.onChange, 200); this.onChange = debounce(props.onChange, 200);
} }
componentWillUnmount() {
this.onChange.cancel();
}
handleChange = e => { handleChange = e => {
const { value } = e.target; const { value } = e.target;
@ -66,9 +72,9 @@ class ObjectType extends React.Component {
} }
return ( return (
<Textarea <StyledTextarea
id={knob.name} id={knob.name}
style={{ ...styles, ...extraStyle }} style={extraStyle}
value={value} value={value}
onChange={this.handleChange} onChange={this.handleChange}
/> />

View File

@ -1,9 +1,8 @@
/* eslint no-underscore-dangle: 0 */
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import styled from 'react-emotion';
const styles = { const Select = styled('select')({
display: 'table-cell', display: 'table-cell',
boxSizing: 'border-box', boxSizing: 'border-box',
verticalAlign: 'middle', verticalAlign: 'middle',
@ -15,7 +14,7 @@ const styles = {
fontSize: 11, fontSize: 11,
padding: '5px', padding: '5px',
color: '#555', color: '#555',
}; });
class SelectType extends React.Component { class SelectType extends React.Component {
renderOptionList({ options }) { renderOptionList({ options }) {
@ -35,14 +34,9 @@ class SelectType extends React.Component {
const { knob, onChange } = this.props; const { knob, onChange } = this.props;
return ( return (
<select <Select id={knob.name} value={knob.value} onChange={e => onChange(e.target.value)}>
id={knob.name}
style={styles}
value={knob.value}
onChange={e => onChange(e.target.value)}
>
{this.renderOptionList(knob)} {this.renderOptionList(knob)}
</select> </Select>
); );
} }
} }

View File

@ -1,21 +1,24 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import styled from 'react-emotion';
import Textarea from 'react-textarea-autosize'; import Textarea from 'react-textarea-autosize';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
const styles = { const StyledTextarea = styled(Textarea)({
display: 'table-cell', display: 'table-cell',
boxSizing: 'border-box', boxSizing: 'border-box',
verticalAlign: 'middle', verticalAlign: 'middle',
height: '26px', height: '26px',
width: '100%', width: '100%',
maxWidth: '100%',
outline: 'none', outline: 'none',
border: '1px solid #f7f4f4', border: '1px solid #f7f4f4',
borderRadius: 2, borderRadius: 2,
fontSize: 11, fontSize: 11,
padding: '5px', padding: '5px',
color: '#555', color: '#555',
}; });
class TextType extends React.Component { class TextType extends React.Component {
constructor(props, context) { constructor(props, context) {
@ -28,6 +31,10 @@ class TextType extends React.Component {
this.onChange = debounce(props.onChange, 200); this.onChange = debounce(props.onChange, 200);
} }
componentWillUnmount() {
this.onChange.cancel();
}
handleChange = event => { handleChange = event => {
const { value } = event.target; const { value } = event.target;
@ -40,7 +47,7 @@ class TextType extends React.Component {
const { knob } = this.props; const { knob } = this.props;
const { value } = this.state; const { value } = this.state;
return <Textarea id={knob.name} style={styles} value={value} onChange={this.handleChange} />; return <StyledTextarea id={knob.name} value={value} onChange={this.handleChange} />;
} }
} }

View File

@ -9,13 +9,13 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -7,21 +7,23 @@
"notes", "notes",
"storybook" "storybook"
], ],
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
"dependencies": { "dependencies": {
"@storybook/addons": "4.0.0-alpha.7", "@storybook/addons": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"emotion": "^9.1.3",
"marked": "^0.3.19", "marked": "^0.3.19",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-emotion": "^9.1.3",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -7,9 +7,8 @@ export class WithNotes extends React.Component {
const { children, notes } = this.props; const { children, notes } = this.props;
const channel = addons.getChannel(); const channel = addons.getChannel();
// send the notes to the channel.
channel.emit('storybook/notes/add_notes', notes); channel.emit('storybook/notes/add_notes', notes);
// return children elements.
return children; return children;
} }
} }

View File

@ -1,18 +1,14 @@
/* eslint-disable react/no-danger */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import addons from '@storybook/addons'; import addons from '@storybook/addons';
const styles = { import styled from 'react-emotion';
notesPanel: {
margin: 10, const Panel = styled('div')({
fontFamily: 'Arial', padding: 10,
fontSize: 14, boxSizing: 'border-box',
color: '#444', width: '100%',
width: '100%', });
overflow: 'auto',
},
};
export class Notes extends React.Component { export class Notes extends React.Component {
constructor(...args) { constructor(...args) {
@ -51,17 +47,15 @@ export class Notes extends React.Component {
const { text } = this.state; const { text } = this.state;
const textAfterFormatted = text ? text.trim().replace(/\n/g, '<br />') : ''; const textAfterFormatted = text ? text.trim().replace(/\n/g, '<br />') : '';
return ( return <Panel dangerouslySetInnerHTML={{ __html: textAfterFormatted }} />;
<div style={styles.notesPanel}>
<div dangerouslySetInnerHTML={{ __html: textAfterFormatted }} />
</div>
);
} }
} }
Notes.propTypes = { Notes.propTypes = {
channel: PropTypes.object, // eslint-disable-line react/forbid-prop-types // eslint-disable-next-line react/forbid-prop-types
api: PropTypes.object, // eslint-disable-line react/forbid-prop-types channel: PropTypes.object,
// eslint-disable-next-line react/forbid-prop-types
api: PropTypes.object,
}; };
Notes.defaultProps = { Notes.defaultProps = {
channel: {}, channel: {},

View File

@ -9,12 +9,12 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "preview.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "preview.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -2,13 +2,13 @@
"name": "@storybook/addon-storyshots", "name": "@storybook/addon-storyshots",
"version": "4.0.0-alpha.7", "version": "4.0.0-alpha.7",
"description": "StoryShots is a Jest Snapshot Testing Addon for Storybook.", "description": "StoryShots is a Jest Snapshot Testing Addon for Storybook.",
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"build-storybook": "build-storybook", "build-storybook": "build-storybook",
"example": "jest storyshot.test", "example": "jest storyshot.test",

View File

@ -1,114 +1,178 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Another Button with some emoji 1`] = ` exports[`Storyshots Another Button with some emoji 1`] = `
.emotion-0 {
border: 1px solid #eee;
border-radius: 3px;
background-color: #FFFFFF;
cursor: pointer;
font-size: 15px;
padding: 3px 10px;
margin: 10px;
}
<Button <Button
onClick={[Function]} onClick={[Function]}
> >
<Component <button
className="css-1yjiefr" className="emotion-0"
onClick={[Function]} onClick={[Function]}
> >
<button <span
className="css-1yjiefr" aria-label="so cool"
onClick={[Function]} role="img"
> >
<span 😀 😎 👍 💯
aria-label="so cool" </span>
role="img" </button>
>
😀 😎 👍 💯
</span>
</button>
</Component>
</Button> </Button>
`; `;
exports[`Storyshots Another Button with text 1`] = ` exports[`Storyshots Another Button with text 1`] = `
.emotion-0 {
border: 1px solid #eee;
border-radius: 3px;
background-color: #FFFFFF;
cursor: pointer;
font-size: 15px;
padding: 3px 10px;
margin: 10px;
}
<Button <Button
onClick={[Function]} onClick={[Function]}
> >
<Component <button
className="css-1yjiefr" className="emotion-0"
onClick={[Function]} onClick={[Function]}
> >
<button Hello Button
className="css-1yjiefr" </button>
onClick={[Function]}
>
Hello Button
</button>
</Component>
</Button> </Button>
`; `;
exports[`Storyshots Button with some emoji 1`] = ` exports[`Storyshots Button with some emoji 1`] = `
.emotion-0 {
border: 1px solid #eee;
border-radius: 3px;
background-color: #FFFFFF;
cursor: pointer;
font-size: 15px;
padding: 3px 10px;
margin: 10px;
}
<Button <Button
onClick={[Function]} onClick={[Function]}
> >
<Component <button
className="css-1yjiefr" className="emotion-0"
onClick={[Function]} onClick={[Function]}
> >
<button <span
className="css-1yjiefr" aria-label="so cool"
onClick={[Function]} role="img"
> >
<span 😀 😎 👍 💯
aria-label="so cool" </span>
role="img" </button>
>
😀 😎 👍 💯
</span>
</button>
</Component>
</Button> </Button>
`; `;
exports[`Storyshots Button with text 1`] = ` exports[`Storyshots Button with text 1`] = `
.emotion-0 {
border: 1px solid #eee;
border-radius: 3px;
background-color: #FFFFFF;
cursor: pointer;
font-size: 15px;
padding: 3px 10px;
margin: 10px;
}
<Button <Button
onClick={[Function]} onClick={[Function]}
> >
<Component <button
className="css-1yjiefr" className="emotion-0"
onClick={[Function]} onClick={[Function]}
> >
<button Hello Button
className="css-1yjiefr" </button>
onClick={[Function]}
>
Hello Button
</button>
</Component>
</Button> </Button>
`; `;
exports[`Storyshots Welcome to Storybook 1`] = ` exports[`Storyshots Welcome to Storybook 1`] = `
.emotion-9 {
margin: 15px;
max-width: 600px;
line-height: 1.4;
font-family: "Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;
}
.emotion-1 {
font-size: 15px;
font-weight: 600;
padding: 2px 5px;
border: 1px solid #eae9e9;
border-radius: 4px;
background-color: #f3f2f2;
color: #3a3a3a;
}
.emotion-2 {
color: #1474f3;
-webkit-text-decoration: none;
text-decoration: none;
border-bottom: 1px solid #1474f3;
padding-bottom: 2px;
border-top: none;
border-right: none;
border-left: none;
background-color: transparent;
padding: 0;
cursor: pointer;
font: inherit;
}
.emotion-6 {
color: #1474f3;
-webkit-text-decoration: none;
text-decoration: none;
border-bottom: 1px solid #1474f3;
padding-bottom: 2px;
}
.emotion-8 {
opacity: 0.5;
}
<Welcome <Welcome
showApp={[Function]} showApp={[Function]}
> >
<glamorous(article)> <Styled(article)>
<article <article
className="css-1fqbdip" className="emotion-9"
> >
<glamorous(h1)> <Styled(h1)>
<h1 <h1
className="css-nil" className="emotion-0"
> >
Welcome to storybook Welcome to storybook
</h1> </h1>
</glamorous(h1)> </Styled(h1)>
<p> <p>
This is a UI component dev environment for your app. This is a UI component dev environment for your app.
</p> </p>
<p> <p>
We've added some basic stories inside the We've added some basic stories inside the
<glamorous(code)> <Styled(code)>
<code <code
className="css-mteq83" className="emotion-1"
> >
src/stories src/stories
</code> </code>
</glamorous(code)> </Styled(code)>
directory. directory.
<br /> <br />
A story is a single state of one or more UI components. You can have as many stories as you want. A story is a single state of one or more UI components. You can have as many stories as you want.
@ -117,25 +181,25 @@ exports[`Storyshots Welcome to Storybook 1`] = `
</p> </p>
<p> <p>
See these sample See these sample
<glamorous(glamorous(glamorous(a))) <Styled(button)
onClick={[Function]} onClick={[Function]}
> >
<button <button
className="css-1opliz7" className="emotion-2"
onClick={[Function]} onClick={[Function]}
> >
stories stories
</button> </button>
</glamorous(glamorous(glamorous(a)))> </Styled(button)>
for a component called for a component called
<glamorous(code)> <Styled(code)>
<code <code
className="css-mteq83" className="emotion-1"
> >
Button Button
</code> </code>
</glamorous(code)> </Styled(code)>
. .
</p> </p>
<p> <p>
@ -144,22 +208,22 @@ exports[`Storyshots Welcome to Storybook 1`] = `
You can also edit those components and see changes right away. You can also edit those components and see changes right away.
<br /> <br />
(Try editing the (Try editing the
<glamorous(code)> <Styled(code)>
<code <code
className="css-mteq83" className="emotion-1"
> >
Button Button
</code> </code>
</glamorous(code)> </Styled(code)>
stories located at stories located at
<glamorous(code)> <Styled(code)>
<code <code
className="css-mteq83" className="emotion-1"
> >
src/stories/index.js src/stories/index.js
</code> </code>
</glamorous(code)> </Styled(code)>
.) .)
</p> </p>
<p> <p>
@ -167,43 +231,43 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
Have a look at the Have a look at the
<glamorous(a) <Styled(a)
href="https://storybook.js.org/basics/writing-stories" href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
> >
<a <a
className="css-ca0824" className="emotion-6"
href="https://storybook.js.org/basics/writing-stories" href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
> >
Writing Stories Writing Stories
</a> </a>
</glamorous(a)> </Styled(a)>
section in our documentation. section in our documentation.
</p> </p>
<glamorous(p)> <Styled(p)>
<p <p
className="css-bwdon3" className="emotion-8"
> >
<b> <b>
NOTE: NOTE:
</b> </b>
<br /> <br />
Have a look at the Have a look at the
<glamorous(code)> <Styled(code)>
<code <code
className="css-mteq83" className="emotion-1"
> >
.storybook/webpack.config.js .storybook/webpack.config.js
</code> </code>
</glamorous(code)> </Styled(code)>
to add webpack loaders and plugins you are using in this project. to add webpack loaders and plugins you are using in this project.
</p> </p>
</glamorous(p)> </Styled(p)>
</article> </article>
</glamorous(article)> </Styled(article)>
</Welcome> </Welcome>
`; `;

View File

@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Another Button with some emoji 1`] = ` exports[`Storyshots Another Button with some emoji 1`] = `
<Unknown <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
<span <span
@ -11,21 +11,21 @@ exports[`Storyshots Another Button with some emoji 1`] = `
> >
😀 😎 👍 💯 😀 😎 👍 💯
</span> </span>
</Unknown> </button>
`; `;
exports[`Storyshots Another Button with text 1`] = ` exports[`Storyshots Another Button with text 1`] = `
<Unknown <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
Hello Button Hello Button
</Unknown> </button>
`; `;
exports[`Storyshots Button with some emoji 1`] = ` exports[`Storyshots Button with some emoji 1`] = `
<Unknown <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
<span <span
@ -34,31 +34,31 @@ exports[`Storyshots Button with some emoji 1`] = `
> >
😀 😎 👍 💯 😀 😎 👍 💯
</span> </span>
</Unknown> </button>
`; `;
exports[`Storyshots Button with text 1`] = ` exports[`Storyshots Button with text 1`] = `
<Unknown <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
Hello Button Hello Button
</Unknown> </button>
`; `;
exports[`Storyshots Welcome to Storybook 1`] = ` exports[`Storyshots Welcome to Storybook 1`] = `
<glamorous(article)> <Styled(article)>
<glamorous(h1)> <Styled(h1)>
Welcome to storybook Welcome to storybook
</glamorous(h1)> </Styled(h1)>
<p> <p>
This is a UI component dev environment for your app. This is a UI component dev environment for your app.
</p> </p>
<p> <p>
We've added some basic stories inside the We've added some basic stories inside the
<glamorous(code)> <Styled(code)>
src/stories src/stories
</glamorous(code)> </Styled(code)>
directory. directory.
<br /> <br />
A story is a single state of one or more UI components. You can have as many stories as you want. A story is a single state of one or more UI components. You can have as many stories as you want.
@ -67,16 +67,16 @@ exports[`Storyshots Welcome to Storybook 1`] = `
</p> </p>
<p> <p>
See these sample See these sample
<glamorous(glamorous(glamorous(a))) <Styled(button)
onClick={[Function]} onClick={[Function]}
> >
stories stories
</glamorous(glamorous(glamorous(a)))> </Styled(button)>
for a component called for a component called
<glamorous(code)> <Styled(code)>
Button Button
</glamorous(code)> </Styled(code)>
. .
</p> </p>
<p> <p>
@ -85,14 +85,14 @@ exports[`Storyshots Welcome to Storybook 1`] = `
You can also edit those components and see changes right away. You can also edit those components and see changes right away.
<br /> <br />
(Try editing the (Try editing the
<glamorous(code)> <Styled(code)>
Button Button
</glamorous(code)> </Styled(code)>
stories located at stories located at
<glamorous(code)> <Styled(code)>
src/stories/index.js src/stories/index.js
</glamorous(code)> </Styled(code)>
.) .)
</p> </p>
<p> <p>
@ -100,26 +100,26 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
Have a look at the Have a look at the
<glamorous(a) <Styled(a)
href="https://storybook.js.org/basics/writing-stories" href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
> >
Writing Stories Writing Stories
</glamorous(a)> </Styled(a)>
section in our documentation. section in our documentation.
</p> </p>
<glamorous(p)> <Styled(p)>
<b> <b>
NOTE: NOTE:
</b> </b>
<br /> <br />
Have a look at the Have a look at the
<glamorous(code)> <Styled(code)>
.storybook/webpack.config.js .storybook/webpack.config.js
</glamorous(code)> </Styled(code)>
to add webpack loaders and plugins you are using in this project. to add webpack loaders and plugins you are using in this project.
</glamorous(p)> </Styled(p)>
</glamorous(article)> </Styled(article)>
`; `;

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Another Button with some emoji 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":{\\"type\\":\\"span\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"role\\":\\"img\\",\\"aria-label\\":\\"so cool\\",\\"children\\":\\"😀 😎 👍 💯\\"},\\"_owner\\":null,\\"_store\\":{}},\\"className\\":\\"css-1yjiefr\\"},\\"_owner\\":null,\\"_store\\":{}}"`; exports[`Storyshots Another Button with some emoji 1`] = `"{\\"type\\":\\"button\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":{\\"type\\":\\"span\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"role\\":\\"img\\",\\"aria-label\\":\\"so cool\\",\\"children\\":\\"😀 😎 👍 💯\\"},\\"_owner\\":null,\\"_store\\":{}},\\"className\\":\\"css-1qwzad5\\"},\\"_owner\\":null,\\"_store\\":{}}"`;
exports[`Storyshots Another Button with text 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Hello Button\\",\\"className\\":\\"css-1yjiefr\\"},\\"_owner\\":null,\\"_store\\":{}}"`; exports[`Storyshots Another Button with text 1`] = `"{\\"type\\":\\"button\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Hello Button\\",\\"className\\":\\"css-1qwzad5\\"},\\"_owner\\":null,\\"_store\\":{}}"`;
exports[`Storyshots Button with some emoji 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":{\\"type\\":\\"span\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"role\\":\\"img\\",\\"aria-label\\":\\"so cool\\",\\"children\\":\\"😀 😎 👍 💯\\"},\\"_owner\\":null,\\"_store\\":{}},\\"className\\":\\"css-1yjiefr\\"},\\"_owner\\":null,\\"_store\\":{}}"`; exports[`Storyshots Button with some emoji 1`] = `"{\\"type\\":\\"button\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":{\\"type\\":\\"span\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"role\\":\\"img\\",\\"aria-label\\":\\"so cool\\",\\"children\\":\\"😀 😎 👍 💯\\"},\\"_owner\\":null,\\"_store\\":{}},\\"className\\":\\"css-1qwzad5\\"},\\"_owner\\":null,\\"_store\\":{}}"`;
exports[`Storyshots Button with text 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Hello Button\\",\\"className\\":\\"css-1yjiefr\\"},\\"_owner\\":null,\\"_store\\":{}}"`; exports[`Storyshots Button with text 1`] = `"{\\"type\\":\\"button\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Hello Button\\",\\"className\\":\\"css-1qwzad5\\"},\\"_owner\\":null,\\"_store\\":{}}"`;
exports[`Storyshots Welcome to Storybook 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Welcome to storybook\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"This is a UI component dev environment for your app.\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"We've added some basic stories inside the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"src/stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" directory.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"A story is a single state of one or more UI components. You can have as many stories as you want.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"(Basically a story is like a visual test case.)\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"See these sample \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" for a component called\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Button\\"},\\"_owner\\":null,\\"_store\\":{}},\\".\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"Just like that, you can add your own components as stories.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"You can also edit those components and see changes right away.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"(Try editing the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Button\\"},\\"_owner\\":null,\\"_store\\":{}},\\" stories located at\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"src/stories/index.js\\"},\\"_owner\\":null,\\"_store\\":{}},\\".)\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"Usually we create stories with smaller UI components in the app.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"Have a look at the\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"href\\":\\"https://storybook.js.org/basics/writing-stories\\",\\"target\\":\\"_blank\\",\\"rel\\":\\"noopener noreferrer\\",\\"children\\":\\"Writing Stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" \\",\\"section in our documentation.\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[{\\"type\\":\\"b\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"NOTE:\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"Have a look at the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\".storybook/webpack.config.js\\"},\\"_owner\\":null,\\"_store\\":{}},\\" to add webpack loaders and plugins you are using in this project.\\"]},\\"_owner\\":null,\\"_store\\":{}}]},\\"_owner\\":null,\\"_store\\":{}}"`; exports[`Storyshots Welcome to Storybook 1`] = `"{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Welcome to storybook\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"This is a UI component dev environment for your app.\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"We've added some basic stories inside the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"src/stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" directory.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"A story is a single state of one or more UI components. You can have as many stories as you want.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"(Basically a story is like a visual test case.)\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"See these sample \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" for a component called\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Button\\"},\\"_owner\\":null,\\"_store\\":{}},\\".\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"Just like that, you can add your own components as stories.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"You can also edit those components and see changes right away.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"(Try editing the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"Button\\"},\\"_owner\\":null,\\"_store\\":{}},\\" stories located at\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"src/stories/index.js\\"},\\"_owner\\":null,\\"_store\\":{}},\\".)\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"p\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[\\"Usually we create stories with smaller UI components in the app.\\",{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"Have a look at the\\",\\" \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"href\\":\\"https://storybook.js.org/basics/writing-stories\\",\\"target\\":\\"_blank\\",\\"rel\\":\\"noopener noreferrer\\",\\"children\\":\\"Writing Stories\\"},\\"_owner\\":null,\\"_store\\":{}},\\" \\",\\"section in our documentation.\\"]},\\"_owner\\":null,\\"_store\\":{}},{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":[{\\"type\\":\\"b\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\"NOTE:\\"},\\"_owner\\":null,\\"_store\\":{}},{\\"type\\":\\"br\\",\\"key\\":null,\\"ref\\":null,\\"props\\":{},\\"_owner\\":null,\\"_store\\":{}},\\"Have a look at the \\",{\\"key\\":null,\\"ref\\":null,\\"props\\":{\\"children\\":\\".storybook/webpack.config.js\\"},\\"_owner\\":null,\\"_store\\":{}},\\" to add webpack loaders and plugins you are using in this project.\\"]},\\"_owner\\":null,\\"_store\\":{}}]},\\"_owner\\":null,\\"_store\\":{}}"`;

View File

@ -2,7 +2,7 @@
exports[`Storyshots Another Button with some emoji 1`] = ` exports[`Storyshots Another Button with some emoji 1`] = `
<button <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
<span <span
@ -16,7 +16,7 @@ exports[`Storyshots Another Button with some emoji 1`] = `
exports[`Storyshots Another Button with text 1`] = ` exports[`Storyshots Another Button with text 1`] = `
<button <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
Hello Button Hello Button

View File

@ -2,7 +2,7 @@
exports[`Storyshots Button with some emoji 1`] = ` exports[`Storyshots Button with some emoji 1`] = `
<button <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
<span <span
@ -16,7 +16,7 @@ exports[`Storyshots Button with some emoji 1`] = `
exports[`Storyshots Button with text 1`] = ` exports[`Storyshots Button with text 1`] = `
<button <button
className="css-1yjiefr" className="css-1qwzad5"
onClick={[Function]} onClick={[Function]}
> >
Hello Button Hello Button

View File

@ -2,10 +2,10 @@
exports[`Storyshots Welcome to Storybook 1`] = ` exports[`Storyshots Welcome to Storybook 1`] = `
<article <article
className="css-1fqbdip" className="css-3qkdq7"
> >
<h1 <h1
className="css-nil" className="css-0"
> >
Welcome to storybook Welcome to storybook
</h1> </h1>
@ -15,7 +15,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p> <p>
We've added some basic stories inside the We've added some basic stories inside the
<code <code
className="css-mteq83" className="css-1rxzob2"
> >
src/stories src/stories
</code> </code>
@ -28,7 +28,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p> <p>
See these sample See these sample
<button <button
className="css-1opliz7" className="css-1otf2jm"
onClick={[Function]} onClick={[Function]}
> >
stories stories
@ -36,7 +36,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
for a component called for a component called
<code <code
className="css-mteq83" className="css-1rxzob2"
> >
Button Button
</code> </code>
@ -49,14 +49,14 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
(Try editing the (Try editing the
<code <code
className="css-mteq83" className="css-1rxzob2"
> >
Button Button
</code> </code>
stories located at stories located at
<code <code
className="css-mteq83" className="css-1rxzob2"
> >
src/stories/index.js src/stories/index.js
</code> </code>
@ -68,7 +68,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
Have a look at the Have a look at the
<a <a
className="css-ca0824" className="css-4d3lbr"
href="https://storybook.js.org/basics/writing-stories" href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
@ -79,7 +79,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
section in our documentation. section in our documentation.
</p> </p>
<p <p
className="css-bwdon3" className="css-1tzeee1"
> >
<b> <b>
NOTE: NOTE:
@ -87,7 +87,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
Have a look at the Have a look at the
<code <code
className="css-mteq83" className="css-1rxzob2"
> >
.storybook/webpack.config.js .storybook/webpack.config.js
</code> </code>

View File

@ -9,13 +9,13 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/storybooks/storybook.git" "url": "https://github.com/storybooks/storybook.git"
}, },
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -1,12 +1,33 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { RoutedLink } from '@storybook/components'; import { RoutedLink, monoFonts } from '@storybook/components';
import jsx from 'react-syntax-highlighter/languages/prism/jsx'; import jsx from 'react-syntax-highlighter/languages/prism/jsx';
import { darcula } from 'react-syntax-highlighter/styles/prism'; import { darcula } from 'react-syntax-highlighter/styles/prism';
import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light'; import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light';
import { createElement } from 'react-syntax-highlighter'; import { createElement } from 'react-syntax-highlighter';
import { EVENT_ID } from './'; import { EVENT_ID } from './';
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',
},
};
registerLanguage('jsx', jsx); registerLanguage('jsx', jsx);
const styles = { const styles = {
@ -41,15 +62,7 @@ export default class StoryPanel extends Component {
: []; : [];
} }
constructor(props) { state = { source: '// Here will be dragons 🐉' };
super(props);
this.state = { source: '// Here will be dragons 🐉' };
this.setSelectedStoryRef = this.setSelectedStoryRef.bind(this);
this.lineRenderer = this.lineRenderer.bind(this);
this.clickOnStory = this.clickOnStory.bind(this);
}
componentDidMount() { componentDidMount() {
const { channel } = this.props; const { channel } = this.props;
@ -72,20 +85,20 @@ export default class StoryPanel extends Component {
} }
} }
setSelectedStoryRef(ref) { setSelectedStoryRef = ref => {
this.selectedStoryRef = ref; this.selectedStoryRef = ref;
} };
clickOnStory(kind, story) { clickOnStory = (kind, story) => {
const { api } = this.props; const { api } = this.props;
if (kind && story) { if (kind && story) {
api.selectStory(kind, story); api.selectStory(kind, story);
} }
} };
createPart(rows, stylesheet, useInlineStyles) { createPart = (rows, stylesheet, useInlineStyles) =>
return rows.map((node, i) => rows.map((node, i) =>
createElement({ createElement({
node, node,
stylesheet, stylesheet,
@ -93,7 +106,6 @@ export default class StoryPanel extends Component {
key: `code-segement${i}`, key: `code-segement${i}`,
}) })
); );
}
createStoryPart(rows, stylesheet, useInlineStyles, location, kindStory) { createStoryPart(rows, stylesheet, useInlineStyles, location, kindStory) {
const { currentLocation } = this.state; const { currentLocation } = this.state;
@ -154,7 +166,7 @@ export default class StoryPanel extends Component {
return parts; return parts;
} }
lineRenderer({ rows, stylesheet, useInlineStyles }) { lineRenderer = ({ rows, stylesheet, useInlineStyles }) => {
const { locationsMap, locationsKeys } = this.state; const { locationsMap, locationsKeys } = this.state;
if (!locationsMap || !locationsKeys.length) { if (!locationsMap || !locationsKeys.length) {
@ -163,15 +175,15 @@ export default class StoryPanel extends Component {
const parts = this.createParts(rows, stylesheet, useInlineStyles); const parts = this.createParts(rows, stylesheet, useInlineStyles);
return <span>{parts.map(part => part)}</span>; return <span>{parts}</span>;
} };
render() { render() {
return ( return (
<SyntaxHighlighter <SyntaxHighlighter
language="jsx" language="jsx"
showLineNumbers="true" showLineNumbers="true"
style={darcula} style={highlighterTheme}
renderer={this.lineRenderer} renderer={this.lineRenderer}
customStyle={styles.panel} customStyle={styles.panel}
> >

View File

@ -15,9 +15,11 @@
"@storybook/components": "4.0.0-alpha.7", "@storybook/components": "4.0.0-alpha.7",
"@storybook/core-events": "4.0.0-alpha.7", "@storybook/core-events": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"emotion": "^9.1.3",
"global": "^4.3.2", "global": "^4.3.2",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-emotion": "^9.1.3",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -1,9 +1,10 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { baseFonts } from '@storybook/components';
import { document } from 'global'; import { document } from 'global';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
import styled from 'react-emotion';
import { resetViewport, viewportsTransformer } from './viewportInfo'; import { resetViewport, viewportsTransformer } from './viewportInfo';
import { SelectViewport } from './SelectViewport'; import { SelectViewport } from './SelectViewport';
import { RotateViewport } from './RotateViewport'; import { RotateViewport } from './RotateViewport';
@ -16,15 +17,14 @@ import {
DEFAULT_VIEWPORT, DEFAULT_VIEWPORT,
} from '../../shared'; } from '../../shared';
import * as styles from './styles'; import { Button } from './styles';
const storybookIframe = 'storybook-preview-iframe'; const storybookIframe = 'storybook-preview-iframe';
const containerStyles = { const Container = styled('div')({
padding: 15, padding: 15,
width: '100%', width: '100%',
boxSizing: 'border-box', boxSizing: 'border-box',
...baseFonts, });
};
const getDefaultViewport = (viewports, candidateViewport) => const getDefaultViewport = (viewports, candidateViewport) =>
candidateViewport in viewports ? candidateViewport : Object.keys(viewports)[0]; candidateViewport in viewports ? candidateViewport : Object.keys(viewports)[0];
@ -170,11 +170,6 @@ export class Panel extends Component {
this.iframe.style.height = viewport.styles.width; this.iframe.style.height = viewport.styles.width;
this.iframe.style.width = viewport.styles.height; this.iframe.style.width = viewport.styles.height;
} }
// Always make parent's height equals iframe
if (this.iframe.parentElement) {
this.iframe.parentElement.style.height = this.iframe.style.height;
}
}; };
render() { render() {
@ -187,17 +182,9 @@ export class Panel extends Component {
} = this.state; } = this.state;
const disableDefault = viewport === storyDefaultViewport; const disableDefault = viewport === storyDefaultViewport;
const disabledStyles = disableDefault ? styles.disabled : {};
const buttonStyles = {
...styles.button,
...disabledStyles,
marginTop: 30,
padding: 20,
};
return ( return (
<div style={containerStyles}> <Container>
<SelectViewport <SelectViewport
viewports={viewports} viewports={viewports}
defaultViewport={storyDefaultViewport} defaultViewport={storyDefaultViewport}
@ -211,14 +198,10 @@ export class Panel extends Component {
active={isLandscape} active={isLandscape}
/> />
<button <Button onClick={() => this.changeViewport(storyDefaultViewport)} disabled={disableDefault}>
style={buttonStyles}
onClick={() => this.changeViewport(storyDefaultViewport)}
disabled={disableDefault}
>
Reset Viewport Reset Viewport
</button> </Button>
</div> </Container>
); );
} }
} }

View File

@ -1,24 +1,16 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as styles from './styles';
export function RotateViewport({ active, ...props }) { import { Label, Row, Button } from './styles';
const disabledStyles = props.disabled ? styles.disabled : {};
const actionStyles = { export const RotateViewport = ({ active, ...props }) => (
...styles.action, <Row>
...disabledStyles, <Label htmlFor="rotate">Rotate</Label>
}; <Button id="rotate" {...props}>
return ( {active ? 'Vertical' : 'Landscape'}
<div style={styles.row}> </Button>
<label htmlFor="rotate" style={styles.label}> </Row>
Rotate );
</label>
<button id="rotate" {...props} style={actionStyles}>
{active ? 'Vertical' : 'Landscape'}
</button>
</div>
);
}
RotateViewport.propTypes = { RotateViewport.propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,

View File

@ -1,25 +1,20 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as styles from './styles'; import { Label, Row, Select } from './styles';
export function SelectViewport({ viewports, defaultViewport, activeViewport, onChange }) { export function SelectViewport({ viewports, defaultViewport, activeViewport, onChange }) {
return ( return (
<div style={styles.row}> <Row>
<label htmlFor="device" style={styles.label}> <Label htmlFor="device">Device</Label>
Device <Select id="device" value={activeViewport} onChange={onChange}>
</label> {Object.entries(viewports).map(([key, { name }]) => (
<select style={styles.action} id="device" value={activeViewport} onChange={onChange}> <option value={key} key={key}>
{Object.keys(viewports).map(key => { {key === defaultViewport ? `(Default) ${name}` : name}
const { name } = viewports[key]; </option>
return ( ))}
<option value={key} key={key}> </Select>
{key === defaultViewport ? `(Default) ${name}` : name} </Row>
</option>
);
})}
</select>
</div>
); );
} }

View File

@ -1,30 +1,36 @@
export const row = { import styled from 'react-emotion';
export const Row = styled('div')({
width: '100%', width: '100%',
display: 'flex', display: 'flex',
marginBottom: 15, marginBottom: 15,
}; });
export const label = { export const Label = styled('label')({
width: 80, width: 80,
marginRight: 15, marginRight: 15,
}; });
const actionColor = 'rgb(247, 247, 247)'; const actionColor = 'rgb(247, 247, 247)';
export const button = { const basebutton = {
color: 'rgb(85, 85, 85)', color: 'rgb(85, 85, 85)',
width: '100%', width: '100%',
border: `1px solid ${actionColor}`, border: `1px solid ${actionColor}`,
backgroundColor: actionColor, backgroundColor: actionColor,
borderRadius: 3, borderRadius: 4,
padding: 10,
}; };
export const disabled = { export const Button = styled('button')(
opacity: '0.5', basebutton,
cursor: 'not-allowed', ({ disabled }) =>
}; disabled
? {
opacity: '0.5',
cursor: 'not-allowed',
}
: {}
);
export const action = { export const Select = styled('select')(basebutton);
...button,
height: 30,
};

View File

@ -4,7 +4,6 @@ import { document } from 'global';
import { Panel } from '../Panel'; import { Panel } from '../Panel';
import { resetViewport, viewportsTransformer } from '../viewportInfo'; import { resetViewport, viewportsTransformer } from '../viewportInfo';
import * as styles from '../styles';
import { DEFAULT_VIEWPORT, INITIAL_VIEWPORTS } from '../../../shared'; import { DEFAULT_VIEWPORT, INITIAL_VIEWPORTS } from '../../../shared';
const initialViewportAt = index => Object.keys(INITIAL_VIEWPORTS)[index]; const initialViewportAt = index => Object.keys(INITIAL_VIEWPORTS)[index];
@ -320,109 +319,100 @@ describe('Viewport/Panel', () => {
}); });
}); });
describe('render', () => { describe('reset button', () => {
describe('reset button', () => { let resetBtn;
let resetBtn;
beforeEach(() => {
subject.instance().changeViewport = jest.fn();
resetBtn = subject.find('Styled(button)');
});
it('enables the reset button if not default', () => {
subject.setState({ viewport: 'responsive' });
resetBtn = subject.find('Styled(button)');
expect(resetBtn).toHaveProp('disabled', true);
subject.setState({ viewport: 'iphone6' });
resetBtn = subject.find('Styled(button)');
expect(resetBtn).toHaveProp('disabled', false);
});
it('toggles the landscape on click', () => {
resetBtn.simulate('click');
expect(subject.instance().changeViewport).toHaveBeenCalledWith(DEFAULT_VIEWPORT);
});
});
describe('SelectViewport', () => {
let select;
beforeEach(() => {
select = subject.find('SelectViewport');
subject.instance().changeViewport = jest.fn();
});
it('passes the activeViewport', () => {
expect(select.props()).toEqual(
expect.objectContaining({
activeViewport: DEFAULT_VIEWPORT,
})
);
});
it('passes the defaultViewport', () => {
expect(select.props()).toEqual(
expect.objectContaining({
defaultViewport: DEFAULT_VIEWPORT,
})
);
});
it('passes the INITIAL_VIEWPORTS', () => {
expect(select.props()).toEqual(
expect.objectContaining({
viewports: transformedInitialViewports,
})
);
});
it('onChange it updates the viewport', () => {
const e = { target: { value: 'iphone6' } };
select.simulate('change', e);
expect(subject.instance().changeViewport).toHaveBeenCalledWith(e.target.value);
});
});
describe('RotateView', () => {
let toggle;
beforeEach(() => {
toggle = subject.find('RotateViewport');
jest.spyOn(subject.instance(), 'toggleLandscape');
subject.instance().forceUpdate();
});
it('passes the active prop based on the state of the panel', () => {
expect(toggle.props().active).toEqual(subject.state('isLandscape'));
});
describe('is on the default viewport', () => {
beforeEach(() => { beforeEach(() => {
subject.instance().changeViewport = jest.fn(); subject.setState({ viewport: DEFAULT_VIEWPORT });
resetBtn = subject.find('button');
}); });
it('styles the reset button as disabled if viewport is default', () => { it('sets the disabled property', () => {
expect(resetBtn.props().style).toEqual(expect.objectContaining(styles.disabled)); expect(toggle.props().disabled).toEqual(true);
}); });
});
it('enabels the reset button if not default', () => { describe('is on a non-default viewport', () => {
beforeEach(() => {
subject.setState({ viewport: 'iphone6' }); subject.setState({ viewport: 'iphone6' });
// Find updated button
resetBtn = subject.find('button');
expect(resetBtn.props().style).toEqual({
...styles.button,
marginTop: 30,
padding: 20,
});
});
it('toggles the landscape on click', () => {
resetBtn.simulate('click');
expect(subject.instance().changeViewport).toHaveBeenCalledWith(DEFAULT_VIEWPORT);
});
});
describe('SelectViewport', () => {
let select;
beforeEach(() => {
select = subject.find('SelectViewport');
subject.instance().changeViewport = jest.fn();
});
it('passes the activeViewport', () => {
expect(select.props()).toEqual(
expect.objectContaining({
activeViewport: DEFAULT_VIEWPORT,
})
);
});
it('passes the defaultViewport', () => {
expect(select.props()).toEqual(
expect.objectContaining({
defaultViewport: DEFAULT_VIEWPORT,
})
);
});
it('passes the INITIAL_VIEWPORTS', () => {
expect(select.props()).toEqual(
expect.objectContaining({
viewports: transformedInitialViewports,
})
);
});
it('onChange it updates the viewport', () => {
const e = { target: { value: 'iphone6' } };
select.simulate('change', e);
expect(subject.instance().changeViewport).toHaveBeenCalledWith(e.target.value);
});
});
describe('RotateView', () => {
let toggle;
beforeEach(() => {
toggle = subject.find('RotateViewport'); toggle = subject.find('RotateViewport');
jest.spyOn(subject.instance(), 'toggleLandscape');
subject.instance().forceUpdate();
}); });
it('passes the active prop based on the state of the panel', () => { it('the disabled property is false', () => {
expect(toggle.props().active).toEqual(subject.state('isLandscape')); expect(toggle.props().disabled).toEqual(false);
});
describe('is on the default viewport', () => {
beforeEach(() => {
subject.setState({ viewport: DEFAULT_VIEWPORT });
});
it('sets the disabled property', () => {
expect(toggle.props().disabled).toEqual(true);
});
});
describe('is on a non-default viewport', () => {
beforeEach(() => {
subject.setState({ viewport: 'iphone6' });
toggle = subject.find('RotateViewport');
});
it('the disabled property is false', () => {
expect(toggle.props().disabled).toEqual(false);
});
}); });
}); });
}); });

View File

@ -1,91 +1,51 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { RotateViewport } from '../RotateViewport'; import { RotateViewport } from '../RotateViewport';
import * as styles from '../styles';
const setup = addition => {
const props = {
onClick: jest.fn(),
disabled: false,
...addition,
};
const result = shallow(<RotateViewport {...props} />);
return { result, props };
};
describe('Viewport/RotateViewport', () => { describe('Viewport/RotateViewport', () => {
let subject; it('renders correctly', () => {
let props; const { result } = setup();
expect(result).toMatchSnapshot();
beforeEach(() => {
props = {
onClick: jest.fn(),
};
subject = shallow(<RotateViewport {...props} />);
}); });
it('has a label', () => { it('has a click handler set via props', () => {
expect(subject.find('label').text()).toEqual('Rotate'); const { result, props } = setup();
const button = result.find('Styled(button)');
expect(button).toHaveProp('onClick');
button.simulate('click');
expect(props.onClick).toHaveBeenCalled();
}); });
describe('button', () => { it('renders the correctly if not-disabled', () => {
let btn; const { result } = setup({ disabled: false });
expect(result.find('Styled(button)')).toHaveProp('disabled', false);
});
beforeEach(() => { it('renders the correctly if disabled', () => {
btn = subject.find('button'); const { result } = setup({ disabled: true });
}); expect(result.find('Styled(button)')).toHaveProp('disabled', true);
});
it('has a click handler set via props', () => { it('renders the correctly if not-active', () => {
// note, this shouldn't trigger if disabled, but enzyme doesn't care const { result } = setup({ active: false });
btn.simulate('click'); expect(result.html()).toContain('Landscape');
expect(props.onClick).toHaveBeenCalled(); });
});
it('renders the the action styles on the button', () => { it('renders the correctly if active', () => {
expect(btn.props().style).toEqual(expect.objectContaining(styles.action)); const { result } = setup({ active: true });
}); expect(result.html()).toContain('Vertical');
describe('is active', () => {
beforeEach(() => {
subject.setProps({ active: true });
btn = subject.find('button');
});
it('renders the correct text', () => {
expect(btn.text()).toEqual('Vertical');
});
});
describe('is inactive', () => {
beforeEach(() => {
subject.setProps({ active: false });
btn = subject.find('button');
});
it('renders the correct text', () => {
expect(btn.text()).toEqual('Landscape');
});
});
describe('is disabled', () => {
beforeEach(() => {
subject.setProps({ disabled: true });
btn = subject.find('button');
});
it('renders the disabled styles', () => {
expect(btn.props().style).toEqual(expect.objectContaining(styles.disabled));
});
it('sets the disabled property on the button', () => {
expect(btn.props().disabled).toEqual(true);
});
});
describe('is enabled', () => {
beforeEach(() => {
subject.setProps({ disabled: false });
btn = subject.find('button');
});
it('renders the disabled styles', () => {
expect(btn.props().style).not.toEqual(expect.objectContaining(styles.disabled));
});
it('does not set the disabled property on the button', () => {
expect(btn.props().disabled).toEqual(false);
});
});
}); });
}); });

View File

@ -2,56 +2,43 @@ import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { SelectViewport } from '../SelectViewport'; import { SelectViewport } from '../SelectViewport';
import { INITIAL_VIEWPORTS, DEFAULT_VIEWPORT } from '../../../shared'; import { INITIAL_VIEWPORTS, DEFAULT_VIEWPORT } from '../../../shared';
import * as styles from '../styles';
const setup = () => {
const props = {
onChange: jest.fn(),
activeViewport: DEFAULT_VIEWPORT,
viewports: INITIAL_VIEWPORTS,
defaultViewport: DEFAULT_VIEWPORT,
};
return { props, result: shallow(<SelectViewport {...props} />) };
};
describe('Viewport/SelectViewport', () => { describe('Viewport/SelectViewport', () => {
let subject; it('is correctly rendered', () => {
let props; const { result } = setup();
expect(result).toMatchSnapshot();
beforeEach(() => {
props = {
onChange: jest.fn(),
activeViewport: DEFAULT_VIEWPORT,
viewports: INITIAL_VIEWPORTS,
defaultViewport: DEFAULT_VIEWPORT,
};
subject = shallow(<SelectViewport {...props} />);
}); });
describe('label', () => { it('has a default option first', () => {
let label; const { result } = setup();
beforeEach(() => { expect(result.find('Styled(select)').props().value).toEqual(DEFAULT_VIEWPORT);
label = subject.find('label');
});
it('is correctly styled', () => {
expect(label.props().style).toEqual(styles.label);
});
}); });
describe('select', () => { it('has at least 1 option', () => {
it('has a default option first', () => { const viewportKeys = Object.keys(INITIAL_VIEWPORTS);
const firstOption = subject.find('option').first(); expect(viewportKeys.length).toBeGreaterThan(0);
expect(firstOption.props().value).toEqual(DEFAULT_VIEWPORT); });
});
describe('dynamic options', () => { const viewportKeys = Object.keys(INITIAL_VIEWPORTS);
const viewportKeys = Object.keys(INITIAL_VIEWPORTS); const { result } = setup();
it('has at least 1 option', () => { viewportKeys.forEach(key => {
expect(viewportKeys.length).toBeGreaterThan(0); const { name } = INITIAL_VIEWPORTS[key];
}); const expectedText = key === DEFAULT_VIEWPORT ? `(Default) ${name}` : name;
viewportKeys.forEach(key => { it(`renders an option for ${name}`, () => {
let option; const option = result.find(`option[value="${key}"]`);
const { name } = INITIAL_VIEWPORTS[key]; expect(option.text()).toEqual(expectedText);
const expectedText = key === DEFAULT_VIEWPORT ? `(Default) ${name}` : name;
it(`renders an option for ${name}`, () => {
option = subject.find(`option[value="${key}"]`);
expect(option.text()).toEqual(expectedText);
});
});
}); });
}); });
}); });

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Viewport/RotateViewport renders correctly 1`] = `
<Styled(div)>
<Styled(label)
htmlFor="rotate"
>
Rotate
</Styled(label)>
<Styled(button)
disabled={false}
id="rotate"
onClick={[MockFunction]}
>
Landscape
</Styled(button)>
</Styled(div)>
`;

View File

@ -0,0 +1,65 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Viewport/SelectViewport is correctly rendered 1`] = `
<Styled(div)>
<Styled(label)
htmlFor="device"
>
Device
</Styled(label)>
<Styled(select)
id="device"
onChange={[MockFunction]}
value="responsive"
>
<option
key="responsive"
value="responsive"
>
(Default) Responsive
</option>
<option
key="iphone5"
value="iphone5"
>
iPhone 5
</option>
<option
key="iphone6"
value="iphone6"
>
iPhone 6
</option>
<option
key="iphone6p"
value="iphone6p"
>
iPhone 6 Plus
</option>
<option
key="ipad"
value="ipad"
>
iPad
</option>
<option
key="galaxys5"
value="galaxys5"
>
Galaxy S5
</option>
<option
key="nexus5x"
value="nexus5x"
>
Nexus 5X
</option>
<option
key="nexus6p"
value="nexus6p"
>
Nexus 6P
</option>
</Styled(select)>
</Styled(div)>
`;

View File

@ -1,7 +1,5 @@
export const configuredStyles = { export const configuredStyles = {
border: '1px solid #728099',
display: 'flex', display: 'flex',
margin: '0 auto',
boxShadow: 'rgba(0,0,0,0.2) 0px 0px 60px 12px', boxShadow: 'rgba(0,0,0,0.2) 0px 0px 60px 12px',
}; };
@ -12,7 +10,6 @@ export const resetViewport = {
height: '100%', height: '100%',
border: 'none', border: 'none',
display: 'block', display: 'block',
margin: '0',
boxShadow: 'none', boxShadow: 'none',
}, },
}; };

View File

@ -12,7 +12,6 @@ export const INITIAL_VIEWPORTS = {
height: '100%', height: '100%',
border: 'none', border: 'none',
display: 'block', display: 'block',
margin: '0',
boxShadow: 'none', boxShadow: 'none',
}, },
type: 'desktop', type: 'desktop',

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"jsnext:main": "src/client/index.js", "jsnext:main": "src/client/index.js",
@ -14,10 +18,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"bin": { "bin": {
@ -13,10 +17,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"jsnext:main": "src/client/index.js", "jsnext:main": "src/client/index.js",
@ -14,10 +18,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -41,14 +41,14 @@
"common-tags": "^1.7.2", "common-tags": "^1.7.2",
"core-js": "^2.5.4", "core-js": "^2.5.4",
"dotenv-webpack": "^1.5.5", "dotenv-webpack": "^1.5.5",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"lodash.flattendeep": "^4.4.0", "lodash.flattendeep": "^4.4.0",
"marko-loader": "^1.3.3", "marko-loader": "^1.3.3",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"react-emotion": "^9.1.3",
"webpack": "^4.8.3", "webpack": "^4.8.3",
"webpack-hot-middleware": "^2.22.2" "webpack-hot-middleware": "^2.22.2"
}, },

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"jsnext:main": "src/client/index.js", "jsnext:main": "src/client/index.js",
@ -14,10 +18,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"bin": { "bin": {
@ -13,10 +17,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -11,16 +11,16 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"jsnext:main": "src/index.js", "jsnext:main": "src/index.js",
"bin": { "bin": {
"storybook": "dist/bin/storybook.js" "storybook": "dist/bin/storybook.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"jsnext:main": "src/client/index.js", "jsnext:main": "src/client/index.js",
@ -14,10 +18,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },
@ -39,13 +39,13 @@
"common-tags": "^1.7.2", "common-tags": "^1.7.2",
"core-js": "^2.5.6", "core-js": "^2.5.6",
"dotenv-webpack": "^1.5.5", "dotenv-webpack": "^1.5.5",
"glamor": "^2.20.40", "emotion": "^9.1.3",
"glamorous": "^4.13.0",
"global": "^4.3.2", "global": "^4.3.2",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"lodash.flattendeep": "^4.4.0", "lodash.flattendeep": "^4.4.0",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"react-emotion": "^9.1.3",
"webpack": "^4.8.3", "webpack": "^4.8.3",
"webpack-hot-middleware": "^2.22.2" "webpack-hot-middleware": "^2.22.2"
}, },

View File

@ -1,8 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import styled from 'react-emotion';
import glamorous from 'glamorous';
const Button = glamorous(({ children, ...rest }) => <button {...rest}>{children}</button>)({ const Button = styled('button')({
border: '1px solid #eee', border: '1px solid #eee',
borderRadius: 3, borderRadius: 3,
backgroundColor: '#FFFFFF', backgroundColor: '#FFFFFF',

View File

@ -1,21 +1,21 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import glamorous from 'glamorous'; import styled from 'react-emotion';
const Main = glamorous.article({ const Main = styled('article')({
margin: 15, margin: 15,
maxWidth: 600, maxWidth: 600,
lineHeight: 1.4, lineHeight: 1.4,
fontFamily: '"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif', fontFamily: '"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif',
}); });
const Title = glamorous.h1({}); const Title = styled('h1')({});
const Note = glamorous.p({ const Note = styled('p')({
opacity: 0.5, opacity: 0.5,
}); });
const InlineCode = glamorous.code({ const InlineCode = styled('code')({
fontSize: 15, fontSize: 15,
fontWeight: 600, fontWeight: 600,
padding: '2px 5px', padding: '2px 5px',
@ -25,14 +25,14 @@ const InlineCode = glamorous.code({
color: '#3a3a3a', color: '#3a3a3a',
}); });
const Link = glamorous.a({ const Link = styled('a')({
color: '#1474f3', color: '#1474f3',
textDecoration: 'none', textDecoration: 'none',
borderBottom: '1px solid #1474f3', borderBottom: '1px solid #1474f3',
paddingBottom: 2, paddingBottom: 2,
}); });
const NavButton = glamorous(Link.withComponent('button'))({ const NavButton = styled(Link.withComponent('button'))({
borderTop: 'none', borderTop: 'none',
borderRight: 'none', borderRight: 'none',
borderLeft: 'none', borderLeft: 'none',

View File

@ -6,6 +6,10 @@
"bugs": { "bugs": {
"url": "https://github.com/storybooks/storybook/issues" "url": "https://github.com/storybooks/storybook/issues"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT", "license": "MIT",
"main": "dist/client/index.js", "main": "dist/client/index.js",
"jsnext:main": "src/client/index.js", "jsnext:main": "src/client/index.js",
@ -14,10 +18,6 @@
"start-storybook": "./bin/index.js", "start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js" "storybook-server": "./bin/index.js"
}, },
"repository": {
"type": "git",
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": { "scripts": {
"prepare": "node ../../scripts/prepare.js" "prepare": "node ../../scripts/prepare.js"
}, },

View File

@ -20,7 +20,8 @@ const Examples = ({ items }) => (
</div> </div>
); );
Examples.propTypes = { Examples.propTypes = {
items: PropTypes.array, // eslint-disable-line react/forbid-prop-types // eslint-disable-next-line react/forbid-prop-types
items: PropTypes.array,
}; };
Examples.defaultProps = { Examples.defaultProps = {
items: [], items: [],

View File

@ -9,12 +9,33 @@
"e2e": "ng e2e", "e2e": "ng e2e",
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
"storybook:prebuild": "npm run test:generate-output",
"storybook": "npm run storybook:prebuild && start-storybook -p 9008 -s src/assets", "storybook": "npm run storybook:prebuild && start-storybook -p 9008 -s src/assets",
"storybook:prebuild": "npm run test:generate-output",
"test": "jest", "test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage", "test:coverage": "jest --coverage",
"test:generate-output": "jest --json --outputFile=addon-jest.testresults.json || true" "test:generate-output": "jest --json --outputFile=addon-jest.testresults.json || true",
"test:watch": "jest --watch"
},
"jest": {
"coveragePathIgnorePatterns": [
"/jest-config/",
"/node_modules/"
],
"preset": "jest-preset-angular",
"setupTestFrameworkScriptFile": "./jest-config/setup.ts",
"snapshotSerializers": [
"<rootDir>/../../node_modules/jest-preset-angular/AngularSnapshotSerializer.js",
"<rootDir>/../../node_modules/jest-preset-angular/HTMLCommentSerializer.js"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/build/",
"/storybook-static/",
"angularshots.test.js"
],
"transform": {
"^.+\\.(ts|js|html)$": "<rootDir>/../../node_modules/jest-preset-angular/preprocessor.js"
}
}, },
"dependencies": { "dependencies": {
"@angular/common": "^5.2.10", "@angular/common": "^5.2.10",
@ -55,26 +76,5 @@
"protractor": "~5.3.2", "protractor": "~5.3.2",
"ts-node": "~6.0.3", "ts-node": "~6.0.3",
"typescript": "^2.8.3" "typescript": "^2.8.3"
},
"jest": {
"preset": "jest-preset-angular",
"transform": {
"^.+\\.(ts|js|html)$": "<rootDir>/../../node_modules/jest-preset-angular/preprocessor.js"
},
"testPathIgnorePatterns": [
"/node_modules/",
"/build/",
"/storybook-static/",
"angularshots.test.js"
],
"coveragePathIgnorePatterns": [
"/jest-config/",
"/node_modules/"
],
"snapshotSerializers": [
"<rootDir>/../../node_modules/jest-preset-angular/AngularSnapshotSerializer.js",
"<rootDir>/../../node_modules/jest-preset-angular/HTMLCommentSerializer.js"
],
"setupTestFrameworkScriptFile": "./jest-config/setup.ts"
} }
} }

View File

@ -92,7 +92,7 @@ exports[`Storyshots Button addons composition 1`] = `
Story Source Story Source
</h1> </h1>
<pre <pre
class="css-4akams" class="css-r8d96o"
> >
<div> <div>
<div> <div>
@ -181,10 +181,10 @@ exports[`Storyshots Button addons composition 1`] = `
</div> </div>
</div> </div>
<button <button
class="css-gydez8" class="css-zvhq5i"
> >
<div <div
class="css-kv47nt" class="css-lvl6aa"
> >
<div <div
style="margin-bottom:6px" style="margin-bottom:6px"
@ -296,7 +296,7 @@ exports[`Storyshots Button with new info 1`] = `
Story Source Story Source
</h1> </h1>
<pre <pre
class="css-4akams" class="css-r8d96o"
> >
<div> <div>
<div> <div>
@ -385,10 +385,10 @@ exports[`Storyshots Button with new info 1`] = `
</div> </div>
</div> </div>
<button <button
class="css-gydez8" class="css-zvhq5i"
> >
<div <div
class="css-kv47nt" class="css-lvl6aa"
> >
<div <div
style="margin-bottom:6px" style="margin-bottom:6px"
@ -415,32 +415,32 @@ exports[`Storyshots Button with new info 1`] = `
"Container" Component "Container" Component
</h2> </h2>
<table <table
class="css-1ytzlk7" class="css-1uhv8nx"
> >
<thead> <thead>
<tr> <tr>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
property property
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
propType propType
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
required required
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
default default
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
description description
</th> </th>
@ -449,47 +449,47 @@ exports[`Storyshots Button with new info 1`] = `
<tbody> <tbody>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
children children
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
yes yes
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
isAmazing isAmazing
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#a11" style="color:#a11"
@ -498,27 +498,27 @@ exports[`Storyshots Button with new info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
age age
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#666" style="color:#666"
@ -555,27 +555,27 @@ exports[`Storyshots Button with new info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
title title
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#22a;word-break:break-word" style="color:#22a;word-break:break-word"
@ -584,7 +584,7 @@ exports[`Storyshots Button with new info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
</tbody> </tbody>
@ -609,7 +609,7 @@ exports[`Storyshots Button with new info 1`] = `
exports[`Storyshots Button with notes 1`] = ` exports[`Storyshots Button with notes 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Check my notes in the notes panel Check my notes in the notes panel
</button> </button>
@ -617,7 +617,7 @@ exports[`Storyshots Button with notes 1`] = `
exports[`Storyshots Button with some emoji 1`] = ` exports[`Storyshots Button with some emoji 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
<span <span
aria-label="so cool" aria-label="so cool"
@ -703,7 +703,7 @@ exports[`Storyshots Button with some info 1`] = `
Story Source Story Source
</h1> </h1>
<pre <pre
class="css-4akams" class="css-r8d96o"
> >
<div> <div>
<div> <div>
@ -785,10 +785,10 @@ exports[`Storyshots Button with some info 1`] = `
</div> </div>
</div> </div>
<button <button
class="css-gydez8" class="css-zvhq5i"
> >
<div <div
class="css-kv47nt" class="css-lvl6aa"
> >
<div <div
style="margin-bottom:6px" style="margin-bottom:6px"
@ -815,32 +815,32 @@ exports[`Storyshots Button with some info 1`] = `
"Container" Component "Container" Component
</h2> </h2>
<table <table
class="css-1ytzlk7" class="css-1uhv8nx"
> >
<thead> <thead>
<tr> <tr>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
property property
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
propType propType
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
required required
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
default default
</th> </th>
<th <th
class="css-d52hbj" class="css-11b5gui"
> >
description description
</th> </th>
@ -849,47 +849,47 @@ exports[`Storyshots Button with some info 1`] = `
<tbody> <tbody>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
children children
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
yes yes
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
isAmazing isAmazing
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#a11" style="color:#a11"
@ -898,27 +898,27 @@ exports[`Storyshots Button with some info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
age age
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#666" style="color:#666"
@ -955,27 +955,27 @@ exports[`Storyshots Button with some info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
<tr> <tr>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
title title
</td> </td>
<td <td
class="css-1ygfcef" class="css-1qcb1f7"
> >
<span /> <span />
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
- -
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
> >
<span <span
style="color:#22a;word-break:break-word" style="color:#22a;word-break:break-word"
@ -984,7 +984,7 @@ exports[`Storyshots Button with some info 1`] = `
</span> </span>
</td> </td>
<td <td
class="css-d52hbj" class="css-11b5gui"
/> />
</tr> </tr>
</tbody> </tbody>
@ -1009,7 +1009,7 @@ exports[`Storyshots Button with some info 1`] = `
exports[`Storyshots Button with text 1`] = ` exports[`Storyshots Button with text 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Hello Button Hello Button
</button> </button>
@ -1029,7 +1029,7 @@ exports[`Storyshots Some really long story kind description with text 1`] = `
style="margin:auto" style="margin:auto"
> >
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Hello Button Hello Button
</button> </button>

View File

@ -2,10 +2,10 @@
exports[`Storyshots Welcome to Storybook 1`] = ` exports[`Storyshots Welcome to Storybook 1`] = `
<article <article
class="css-1fqbdip" class="css-3qkdq7"
> >
<h1 <h1
class="css-nil" class="css-0"
> >
Welcome to storybook Welcome to storybook
</h1> </h1>
@ -15,7 +15,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p> <p>
We've added some basic stories inside the We've added some basic stories inside the
<code <code
class="css-mteq83" class="css-1rxzob2"
> >
src/stories src/stories
</code> </code>
@ -28,13 +28,13 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p> <p>
See these sample See these sample
<button <button
class="css-1opliz7" class="css-1otf2jm"
> >
stories stories
</button> </button>
for a component called for a component called
<code <code
class="css-mteq83" class="css-1rxzob2"
> >
Button Button
</code> </code>
@ -47,13 +47,13 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
(Try editing the (Try editing the
<code <code
class="css-mteq83" class="css-1rxzob2"
> >
Button Button
</code> </code>
stories located at stories located at
<code <code
class="css-mteq83" class="css-1rxzob2"
> >
src/stories/index.js src/stories/index.js
</code> </code>
@ -64,7 +64,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
Have a look at the Have a look at the
<a <a
class="css-ca0824" class="css-4d3lbr"
href="https://storybook.js.org/basics/writing-stories" href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
@ -74,7 +74,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
section in our documentation. section in our documentation.
</p> </p>
<p <p
class="css-bwdon3" class="css-1tzeee1"
> >
<b> <b>
NOTE: NOTE:
@ -82,7 +82,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<br /> <br />
Have a look at the Have a look at the
<code <code
class="css-mteq83" class="css-1rxzob2"
> >
.storybook/webpack.config.js .storybook/webpack.config.js
</code> </code>

View File

@ -1,17 +1,17 @@
{ {
"name": "html-kitchen-sink", "name": "html-kitchen-sink",
"version": "4.0.0-alpha.7", "version": "4.0.0-alpha.7",
"description": "",
"main": "index.js",
"private": true, "private": true,
"scripts": { "description": "",
"generate-addon-jest-testresults": "jest --config=tests/addon-jest.config.json --json --outputFile=stories/addon-jest.testresults.json",
"storybook": "start-storybook -p 9006",
"build-storybook": "build-storybook"
},
"keywords": [], "keywords": [],
"author": "",
"license": "ISC", "license": "ISC",
"author": "",
"main": "index.js",
"scripts": {
"build-storybook": "build-storybook",
"generate-addon-jest-testresults": "jest --config=tests/addon-jest.config.json --json --outputFile=stories/addon-jest.testresults.json",
"storybook": "start-storybook -p 9006"
},
"devDependencies": { "devDependencies": {
"@storybook/addon-a11y": "4.0.0-alpha.7", "@storybook/addon-a11y": "4.0.0-alpha.7",
"@storybook/addon-actions": "4.0.0-alpha.7", "@storybook/addon-actions": "4.0.0-alpha.7",

View File

@ -1,12 +1,44 @@
{ {
"name": "marko-cli", "name": "marko-cli",
"version": "4.0.0-alpha.7", "version": "4.0.0-alpha.7",
"private": true,
"description": "Demo of how to build an app using marko-starter", "description": "Demo of how to build an app using marko-starter",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/marko-js-samples/marko-starter-demo" "url": "https://github.com/marko-js-samples/marko-starter-demo"
}, },
"license": "MIT", "license": "MIT",
"scripts": {
"build": "NODE_ENV=production marko-starter build",
"build-storybook": "build-storybook",
"lint": "eslint src/",
"serve-static": "NODE_ENV=production marko-starter serve-static",
"start": "marko-starter server",
"storybook": "start-storybook -p 9005",
"test": "npm run lint",
"prettier": "prettier src/**/*.{js,css,less} *.js --write"
},
"eslintConfig": {
"env": {
"browser": true,
"node": true
},
"extends": [
"eslint:recommended",
"prettier"
],
"rules": {
"no-console": "off"
}
},
"eslintIgnore": [
"*.marko.js"
],
"dependencies": {
"marko": "^4",
"marko-widgets": "^7",
"marko-starter": "^1.0.0"
},
"devDependencies": { "devDependencies": {
"@storybook/addon-actions": "4.0.0-alpha.7", "@storybook/addon-actions": "4.0.0-alpha.7",
"@storybook/addon-knobs": "4.0.0-alpha.7", "@storybook/addon-knobs": "4.0.0-alpha.7",
@ -20,37 +52,5 @@
"eslint-plugin-prettier": "^2.1.2", "eslint-plugin-prettier": "^2.1.2",
"prettier": "^1.5.2", "prettier": "^1.5.2",
"webpack": "^4.8.3" "webpack": "^4.8.3"
}, }
"dependencies": {
"marko": "^4",
"marko-widgets": "^7",
"marko-starter": "^1.0.0"
},
"scripts": {
"start": "marko-starter server",
"build-storybook": "build-storybook",
"storybook": "start-storybook -p 9005",
"build": "NODE_ENV=production marko-starter build",
"serve-static": "NODE_ENV=production marko-starter serve-static",
"lint": "eslint src/",
"test": "npm run lint",
"prettier": "prettier src/**/*.{js,css,less} *.js --write"
},
"eslintConfig": {
"extends": [
"eslint:recommended",
"prettier"
],
"rules": {
"no-console": "off"
},
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": [
"*.marko.js"
],
"private": true
} }

View File

@ -1,6 +1,10 @@
import { configure } from '@storybook/react'; import React from 'react';
import { ThemeProvider } from 'emotion-theming';
import { configure, addDecorator } from '@storybook/react';
import { themes } from '@storybook/components';
import { setOptions } from '@storybook/addon-options'; import { setOptions } from '@storybook/addon-options';
import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import 'react-chromatic/storybook-addon'; import 'react-chromatic/storybook-addon';
import addHeadWarning from './head-warning'; import addHeadWarning from './head-warning';
import extraViewports from './extra-viewports.json'; import extraViewports from './extra-viewports.json';
@ -13,6 +17,12 @@ setOptions({
hierarchyRootSeparator: /\|/, hierarchyRootSeparator: /\|/,
}); });
addDecorator(Story => (
<ThemeProvider theme={themes.normal}>
<Story />
</ThemeProvider>
));
configureViewport({ configureViewport({
viewports: { viewports: {
...INITIAL_VIEWPORTS, ...INITIAL_VIEWPORTS,

View File

@ -5,10 +5,10 @@
"scripts": { "scripts": {
"build-storybook": "build-storybook -c ./ -s built-storybooks", "build-storybook": "build-storybook -c ./ -s built-storybooks",
"chromatic": "chromatic test --storybook-addon --exit-zero-on-changes --app-code ab7m45tp9p", "chromatic": "chromatic test --storybook-addon --exit-zero-on-changes --app-code ab7m45tp9p",
"do-image-snapshots": "../../node_modules/.bin/jest --projects=./image-snapshots",
"generate-addon-jest-testresults": "jest --config=tests/addon-jest.config.json --json --outputFile=stories/addon-jest.testresults.json", "generate-addon-jest-testresults": "jest --config=tests/addon-jest.config.json --json --outputFile=stories/addon-jest.testresults.json",
"graphql": "node ./graphql-server/index.js", "graphql": "node ./graphql-server/index.js",
"image-snapshots": "yarn run build-storybook && yarn run do-image-snapshots", "image-snapshots": "yarn run build-storybook && yarn run do-image-snapshots",
"do-image-snapshots": "../../node_modules/.bin/jest --projects=./image-snapshots",
"storybook": "start-storybook -p 9011 -c ./ -s built-storybooks" "storybook": "start-storybook -p 9011 -c ./ -s built-storybooks"
}, },
"devDependencies": { "devDependencies": {
@ -34,6 +34,8 @@
"@storybook/react": "4.0.0-alpha.7", "@storybook/react": "4.0.0-alpha.7",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"cors": "^2.8.4", "cors": "^2.8.4",
"emotion": "^9.1.3",
"emotion-theming": "^9.1.2",
"enzyme-to-json": "^3.3.3", "enzyme-to-json": "^3.3.3",
"eventemitter3": "^3.1.0", "eventemitter3": "^3.1.0",
"express": "^4.16.3", "express": "^4.16.3",
@ -46,6 +48,7 @@
"react": "^16.3.2", "react": "^16.3.2",
"react-chromatic": "^0.8.3", "react-chromatic": "^0.8.3",
"react-dom": "^16.3.2", "react-dom": "^16.3.2",
"react-emotion": "^9.1.3",
"uuid": "^3.2.1", "uuid": "^3.2.1",
"webpack": "^4.8.3" "webpack": "^4.8.3"
} }

View File

@ -1,26 +1,21 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import json from 'format-json'; import json from 'format-json';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'react-emotion';
import EventEmitter from 'eventemitter3'; import EventEmitter from 'eventemitter3';
import uuid from 'uuid/v4'; import uuid from 'uuid/v4';
const styles = { const Wrapper = styled('div')({
wrapper: { padding: 20,
padding: 20, });
fontFamily: ` const Title = styled('h1')({
-apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", margin: 0,
"Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif });
`, const Item = () => ({
color: 'rgb(51, 51, 51)', listStyle: 'none',
}, marginBottom: 10,
title: { });
margin: 0,
},
item: {
listStyle: 'none',
marginBottom: 10,
},
};
export default class Logger extends Component { export default class Logger extends Component {
static LOG_EVENT = 'Logger:log'; static LOG_EVENT = 'Logger:log';
@ -57,21 +52,21 @@ export default class Logger extends Component {
const { title } = this.props; const { title } = this.props;
return ( return (
<div style={styles.wrapper}> <Wrapper>
<h1 style={styles.title}>{title}</h1> <Title>{title}</Title>
<dl> <dl>
{events.map(({ id, name, payload }) => ( {events.map(({ id, name, payload }) => (
<div style={styles.item} key={id}> <Item key={id}>
<dt> <dt>
<b>Event name:</b> {name} <b>Event name:</b> {name}
</dt> </dt>
<dd> <dd>
<b>Event payload:</b> {json.plain(payload)} <b>Event payload:</b> {json.plain(payload)}
</dd> </dd>
</div> </Item>
))} ))}
</dl> </dl>
</div> </Wrapper>
); );
} }
} }

View File

@ -3,102 +3,102 @@
exports[`Storyshots Addons|Actions All types 1`] = ` exports[`Storyshots Addons|Actions All types 1`] = `
<div> <div>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Array Array
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Boolean Boolean
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Empty Object Empty Object
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
File File
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Function A Function A
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Bound Function A Bound Function A
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Infinity Infinity
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
-Infinity -Infinity
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
NaN NaN
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
null null
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Number Number
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Multiple Multiple
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Plain Object Plain Object
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Object (depth: 2) Object (depth: 2)
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
RegExp RegExp
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
String String
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Symbol Symbol
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
SyntheticEvent SyntheticEvent
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
undefined undefined
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Window Window
</button> </button>
@ -107,7 +107,7 @@ exports[`Storyshots Addons|Actions All types 1`] = `
exports[`Storyshots Addons|Actions Circular Payload 1`] = ` exports[`Storyshots Addons|Actions Circular Payload 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Circular Payload Circular Payload
</button> </button>
@ -115,7 +115,7 @@ exports[`Storyshots Addons|Actions Circular Payload 1`] = `
exports[`Storyshots Addons|Actions Decorated Action (deprecated) 1`] = ` exports[`Storyshots Addons|Actions Decorated Action (deprecated) 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Native Event Native Event
</button> </button>
@ -123,7 +123,7 @@ exports[`Storyshots Addons|Actions Decorated Action (deprecated) 1`] = `
exports[`Storyshots Addons|Actions Decorated action + config 1`] = ` exports[`Storyshots Addons|Actions Decorated action + config 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Moving away from this story will persist the action logger Moving away from this story will persist the action logger
</button> </button>
@ -131,7 +131,7 @@ exports[`Storyshots Addons|Actions Decorated action + config 1`] = `
exports[`Storyshots Addons|Actions Decorated action 1`] = ` exports[`Storyshots Addons|Actions Decorated action 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Native Event Native Event
</button> </button>
@ -139,7 +139,7 @@ exports[`Storyshots Addons|Actions Decorated action 1`] = `
exports[`Storyshots Addons|Actions Decorated actions + config 1`] = ` exports[`Storyshots Addons|Actions Decorated actions + config 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Moving away from this story will persist the action logger Moving away from this story will persist the action logger
</button> </button>
@ -147,7 +147,7 @@ exports[`Storyshots Addons|Actions Decorated actions + config 1`] = `
exports[`Storyshots Addons|Actions Decorated actions 1`] = ` exports[`Storyshots Addons|Actions Decorated actions 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Native Event Native Event
</button> </button>
@ -155,7 +155,7 @@ exports[`Storyshots Addons|Actions Decorated actions 1`] = `
exports[`Storyshots Addons|Actions Function Name 1`] = ` exports[`Storyshots Addons|Actions Function Name 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Action.name: fnName Action.name: fnName
</button> </button>
@ -163,7 +163,7 @@ exports[`Storyshots Addons|Actions Function Name 1`] = `
exports[`Storyshots Addons|Actions Hello World 1`] = ` exports[`Storyshots Addons|Actions Hello World 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Hello World Hello World
</button> </button>
@ -172,12 +172,12 @@ exports[`Storyshots Addons|Actions Hello World 1`] = `
exports[`Storyshots Addons|Actions Limit Action Output 1`] = ` exports[`Storyshots Addons|Actions Limit Action Output 1`] = `
<div> <div>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
False False
</button> </button>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
True True
</button> </button>
@ -186,7 +186,7 @@ exports[`Storyshots Addons|Actions Limit Action Output 1`] = `
exports[`Storyshots Addons|Actions Multiple actions + config 1`] = ` exports[`Storyshots Addons|Actions Multiple actions + config 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Moving away from this story will persist the action logger Moving away from this story will persist the action logger
</button> </button>
@ -194,7 +194,7 @@ exports[`Storyshots Addons|Actions Multiple actions + config 1`] = `
exports[`Storyshots Addons|Actions Multiple actions 1`] = ` exports[`Storyshots Addons|Actions Multiple actions 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Hello World Hello World
</button> </button>
@ -202,7 +202,7 @@ exports[`Storyshots Addons|Actions Multiple actions 1`] = `
exports[`Storyshots Addons|Actions Multiple actions, object + config 1`] = ` exports[`Storyshots Addons|Actions Multiple actions, object + config 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Moving away from this story will persist the action logger Moving away from this story will persist the action logger
</button> </button>
@ -210,7 +210,7 @@ exports[`Storyshots Addons|Actions Multiple actions, object + config 1`] = `
exports[`Storyshots Addons|Actions Multiple actions, object 1`] = ` exports[`Storyshots Addons|Actions Multiple actions, object 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Hello World Hello World
</button> </button>
@ -222,7 +222,7 @@ exports[`Storyshots Addons|Actions Persisting the action logger 1`] = `
Moving away from this story will persist the action logger Moving away from this story will persist the action logger
</p> </p>
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Object (configured clearOnStoryChange: false) Object (configured clearOnStoryChange: false)
</button> </button>
@ -231,7 +231,7 @@ exports[`Storyshots Addons|Actions Persisting the action logger 1`] = `
exports[`Storyshots Addons|Actions Reserved keyword as name 1`] = ` exports[`Storyshots Addons|Actions Reserved keyword as name 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Delete Delete
</button> </button>
@ -239,7 +239,7 @@ exports[`Storyshots Addons|Actions Reserved keyword as name 1`] = `
exports[`Storyshots Addons|Actions configureActionsDepth 1`] = ` exports[`Storyshots Addons|Actions configureActionsDepth 1`] = `
<button <button
class="css-1yjiefr" class="css-1qwzad5"
> >
Object (configured depth: 2) Object (configured depth: 2)
</button> </button>

View File

@ -2,11 +2,10 @@
exports[`Storyshots Addons|Events Logger 1`] = ` exports[`Storyshots Addons|Events Logger 1`] = `
<div <div
style="padding:20px;font-family:-apple-system, \\".SFNSText-Regular\\", \\"San Francisco\\", \\"Roboto\\", class="css-1ruxp1v"
\\"Segoe UI\\", \\"Helvetica Neue\\", \\"Lucida Grande\\", sans-serif;color:rgb(51, 51, 51)"
> >
<h1 <h1
style="margin:0" class="css-1uk1gs8"
> >
Logger Logger
</h1> </h1>
@ -16,11 +15,10 @@ exports[`Storyshots Addons|Events Logger 1`] = `
exports[`Storyshots Addons|Events/WithEvents (deprecated) Logger 1`] = ` exports[`Storyshots Addons|Events/WithEvents (deprecated) Logger 1`] = `
<div <div
style="padding:20px;font-family:-apple-system, \\".SFNSText-Regular\\", \\"San Francisco\\", \\"Roboto\\", class="css-1ruxp1v"
\\"Segoe UI\\", \\"Helvetica Neue\\", \\"Lucida Grande\\", sans-serif;color:rgb(51, 51, 51)"
> >
<h1 <h1
style="margin:0" class="css-1uk1gs8"
> >
Logger Logger
</h1> </h1>

Some files were not shown because too many files have changed in this diff Show More