This commit is contained in:
Norbert de Langen 2017-11-12 00:19:51 +01:00
parent 90f1711a2e
commit 88a8f00f00
No known key found for this signature in database
GPG Key ID: 976651DA156C2825
14 changed files with 81 additions and 147 deletions

View File

@ -1,2 +1,3 @@
const manager = require('./dist/register');
manager.init();

View File

@ -7,7 +7,7 @@ class A11yManager {
wrapStory(channel, storyFn, context) {
const props = { context, storyFn, channel };
return (<WrapStory {...props} />);
return <WrapStory {...props} />;
}
}

View File

@ -12,7 +12,7 @@ const styles = {
violations: {
color: '#e74c3c',
},
}
};
class Panel extends Component {
constructor(props, ...args) {
@ -38,7 +38,7 @@ class Panel extends Component {
this.setState({
passes,
violations,
})
});
}
render() {
@ -46,35 +46,18 @@ class Panel extends Component {
return (
<Tabs
tabs={[{
label: (
<span style={styles.violations}>
Violations
</span>
),
panel: (
<Report
passes={false}
items={violations}
empty="No a11y violations found."
/>
)
}, {
label: (
<span style={styles.passes}>
Passes
</span>
),
panel: (
<Report
passes
items={passes}
empty="No a11y check passed"
/>
)
}]}
tabs={[
{
label: <span style={styles.violations}>Violations</span>,
panel: <Report passes={false} items={violations} empty="No a11y violations found." />,
},
{
label: <span style={styles.passes}>Passes</span>,
panel: <Report passes items={passes} empty="No a11y check passed" />,
},
]}
/>
)
);
return <div>{this.state.text}</div>;
}

View File

@ -12,8 +12,8 @@ const styles = {
display: 'inline-block',
paddingBottom: '4px',
marginBottom: '4px',
}
}
},
};
function Element({ element, passes }) {
const { any, all, none } = element;
@ -22,27 +22,16 @@ function Element({ element, passes }) {
return (
<li style={styles.element}>
<span style={styles.target}>
{element.target[0]}
</span>
<Rules
rules={rules}
passes={passes}
/>
<span style={styles.target}>{element.target[0]}</span>
<Rules rules={rules} passes={passes} />
</li>
)
);
}
function Elements({ elements, passes }) {
return (
<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>
);
}

View File

@ -16,23 +16,17 @@ const styles = {
color: 'rgb(130, 130, 130)',
display: 'block',
},
}
};
function Info({ item }) {
return (
<div style={styles.info}>
<p style={styles.help}>
{item.help}
</p>
<a
style={styles.helpUrl}
href={item.helpUrl}
target="_blank"
>
<p style={styles.help}>{item.help}</p>
<a style={styles.helpUrl} href={item.helpUrl} target="_blank">
More info...
</a>
</div>
)
);
}
Info.propTypes = {

View File

@ -16,25 +16,26 @@ const styles = {
display: 'block',
width: '100%',
},
}
};
class Item extends Component {
static propTypes = {
item: PropTypes.object,
passes: PropTypes.bool,
}
};
constructor() {
super();
this.state = {
open: false,
}
};
}
onToggle = () => this.setState((prevState) => ({
open: !prevState.open,
}))
onToggle = () =>
this.setState(prevState => ({
open: !prevState.open,
}));
render() {
const { item, passes } = this.props;
@ -42,22 +43,14 @@ class Item extends Component {
return (
<div style={styles.item}>
<div
style={styles.headerBar}
onClick={() => this.onToggle()}
>
<div style={styles.headerBar} onClick={() => this.onToggle()}>
{item.description}
</div>
{ open && (<Info item={item} />) }
{ open && (
<Elements
elements={item.nodes}
passes={passes}
/>
) }
{ open && (<Tags tags={item.tags} />) }
{open && <Info item={item} />}
{open && <Elements elements={item.nodes} passes={passes} />}
{open && <Tags tags={item.tags} />}
</div>
)
);
}
}

View File

@ -34,14 +34,11 @@ const styles = {
},
message: {
paddingLeft: '6px',
}
}
},
};
function Rule({ rule, passes }) {
const color = ( passes ?
impactColors.success :
impactColors[rule.impact]
)
const color = passes ? impactColors.success : impactColors[rule.impact];
return (
<div style={styles.rule}>
@ -51,27 +48,19 @@ function Rule({ rule, passes }) {
backgroundColor: color,
}}
>
{ passes ? '✔' : '✘' }
{passes ? '✔' : '✘'}
</div>
<span style={styles.message}>
{rule.message}
</span>
<span style={styles.message}>{rule.message}</span>
</div>
)
);
}
function Rules({ rules, passes }) {
return (
<div style={styles.rules}>
{rules.map((rule, index) => (
<Rule
passes={passes}
rule={rule}
key={index}
/>
))}
{rules.map((rule, index) => <Rule passes={passes} rule={rule} key={index} />)}
</div>
)
);
}
export default Rules;

View File

@ -13,17 +13,14 @@ const styles = {
borderRadius: '2px',
color: 'rgb(130, 130, 130)',
fontSize: '12px',
}
}
},
};
function Tags({ tags }) {
return (
<div style={styles.tags}>
{tags.map((tag) => (
<div
key={tag}
style={styles.tag}
>
{tags.map(tag => (
<div key={tag} style={styles.tag}>
{tag}
</div>
))}

View File

@ -5,41 +5,37 @@ import Item from './Item';
const styles = {
container: {
fontFamily: '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
fontFamily:
'-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
fontSize: '12px',
},
empty: {
fontFamily: '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
fontFamily:
'-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
fontSize: '11px',
padding: '20px 12px',
width: '100%',
display: 'block',
textAlign: 'center',
textTransform: 'uppercase',
}
}
},
};
function Report({ items, empty, passes }) {
if (items.length) {
return (
<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>
);
}
return (<span style={styles.empty}>{empty}</span>)
return <span style={styles.empty}>{empty}</span>;
}
Report.propTypes = {
items: PropTypes.array,
empty: PropTypes.string,
}
};
export default Report;

View File

@ -11,7 +11,8 @@ const styles = {
display: 'flex',
},
tab: {
fontFamily: '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
fontFamily:
'-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
color: 'rgb(68, 68, 68)',
fontSize: '11px',
textDecoration: 'none',
@ -25,8 +26,8 @@ const styles = {
tabActive: {
opacity: 1,
fontWeight: 600,
}
}
},
};
class Tabs extends Component {
constructor(props) {
@ -34,7 +35,7 @@ class Tabs extends Component {
this.state = {
active: 0,
}
};
this.onToggle = this.onToggle.bind(this);
this.renderPanel = this.renderPanel.bind(this);
@ -44,18 +45,14 @@ class Tabs extends Component {
onToggle(index) {
this.setState({
active: index,
})
});
}
renderPanel() {
const { tabs } = this.props;
const { active } = this.state;
return (
<div style={styles.panel}>
{tabs[active].panel}
</div>
)
return <div style={styles.panel}>{tabs[active].panel}</div>;
}
renderTabs() {
@ -69,15 +66,15 @@ class Tabs extends Component {
key={index}
style={{
...styles.tab,
...(index === active ? styles.tabActive : undefined)
...(index === active ? styles.tabActive : undefined),
}}
onClick={() => this.onToggle(index)}
>
{ tab.label }
{tab.label}
</div>
))}
</div>
)
);
}
render() {
@ -93,10 +90,12 @@ class Tabs extends Component {
}
Tabs.propTypes = {
tabs: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.node,
panel: PropTypes.node,
})),
tabs: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.node,
panel: PropTypes.node,
})
),
};
export default Tabs;

View File

@ -8,14 +8,14 @@ class WrapStory extends Component {
context: PropTypes.object,
storyFn: PropTypes.func,
channel: PropTypes.object,
}
};
componentDidMount() {
const { channel } = this.props;
const wrapper = findDOMNode(this);
if (wrapper !== null) {
axe.a11yCheck(wrapper, {}, (results) => {
axe.a11yCheck(wrapper, {}, results => {
channel.emit('addon:a11y:check', results);
});
}

View File

@ -1,7 +1,7 @@
import addons from '@storybook/addons';
import A11yManager from './A11yManager';
import * as shared from './shared'
import * as shared from './shared';
const manager = new A11yManager();
@ -10,7 +10,4 @@ function checkA11y(storyFn, context) {
return manager.wrapStory(channel, storyFn, context);
}
export {
checkA11y,
shared,
};
export { checkA11y, shared };

View File

@ -10,9 +10,9 @@ function init() {
title: 'Accessibility',
render() {
return <Panel />;
}
},
});
});
}
export { init }
export { init };

View File

@ -3,8 +3,4 @@ const ADDON_ID = 'jbovenschen/storybook-addon-a11y';
const PANEL_ID = `${ADDON_ID}/addon-panel`;
const EVENT_ID = `${ADDON_ID}/addon-event`;
export {
ADDON_ID,
PANEL_ID,
EVENT_ID,
}
export { ADDON_ID, PANEL_ID, EVENT_ID };