Skip to content

Commit

Permalink
Merge branch 'next' into addon-info-forward-ref-opt-in
Browse files Browse the repository at this point in the history
  • Loading branch information
ndelangen authored Mar 25, 2019
2 parents a121c44 + 496408c commit 5e48b8f
Show file tree
Hide file tree
Showing 37 changed files with 2,050 additions and 1,087 deletions.
5 changes: 4 additions & 1 deletion addons/a11y/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
"util-deprecate": "^1.0.2"
},
"devDependencies": {
"@types/common-tags": "^1.8.0"
"@types/common-tags": "^1.8.0",
"@types/react-redux": "^7.0.3",
"react-redux": "^6.0.1",
"redux": "^4.0.1"
},
"publishConfig": {
"access": "public"
Expand Down
108 changes: 67 additions & 41 deletions addons/a11y/src/components/A11YPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import { Tabs } from './Tabs';
import { EVENTS } from '../constants';
import { API } from '@storybook/api';

import { Provider } from 'react-redux';
import store, { clearElements } from '../redux-config';

export enum RuleType {
VIOLATION,
PASS,
INCOMPLETION,
}

const Icon = styled(Icons)(
{
height: '12px',
Expand Down Expand Up @@ -81,13 +90,14 @@ export class A11YPanel extends Component<A11YPanelProps, A11YPanelState> {
const { active } = this.props;

if (!prevProps.active && active) {
// removes all elements from the redux map in store from the previous panel
store.dispatch(clearElements(null));
this.request();
}
}

componentWillUnmount() {
const { api } = this.props;

api.off(STORY_RENDERED, this.request);
api.off(EVENTS.RESULT, this.onUpdate);
}
Expand Down Expand Up @@ -151,46 +161,62 @@ export class A11YPanel extends Component<A11YPanelProps, A11YPanelState> {

return active ? (
<Fragment>
{status === 'running' ? (
<Loader />
) : (
<ScrollArea vertical horizontal>
<Tabs
key="tabs"
tabs={[
{
label: <Violations>{violations.length} Violations</Violations>,
panel: (
<Report
name="violations"
passes={false}
items={violations}
empty="No a11y violations found."
/>
),
},
{
label: <Passes>{passes.length} Passes</Passes>,
panel: (
<Report name={'passes'} passes items={passes} empty="No a11y check passed." />
),
},
{
label: <Incomplete>{incomplete.length} Incomplete</Incomplete>,
panel: (
<Report
name="incomplete"
passes={false}
items={incomplete}
empty="No a11y incomplete found."
/>
),
},
]}
/>
</ScrollArea>
)}
<ActionBar key="actionbar" actionItems={[{ title: actionTitle, onClick: this.request }]} />
<Provider store={store}>
{status === 'running' ? (
<Loader />
) : (
<ScrollArea vertical horizontal>
<Tabs
key="tabs"
tabs={[
{
label: <Violations>{violations.length} Violations</Violations>,
panel: (
<Report
passes={false}
items={violations}
type={RuleType.VIOLATION}
empty="No a11y violations found."
/>
),
items: violations,
type: RuleType.VIOLATION,
},
{
label: <Passes>{passes.length} Passes</Passes>,
panel: (
<Report
passes
items={passes}
type={RuleType.PASS}
empty="No a11y check passed."
/>
),
items: passes,
type: RuleType.PASS,
},
{
label: <Incomplete>{incomplete.length} Incomplete</Incomplete>,
panel: (
<Report
passes={false}
items={incomplete}
type={RuleType.INCOMPLETION}
empty="No a11y incomplete found."
/>
),
items: incomplete,
type: RuleType.INCOMPLETION,
},
]}
/>
</ScrollArea>
)}
<ActionBar
key="actionbar"
actionItems={[{ title: actionTitle, onClick: this.request }]}
/>
</Provider>
</Fragment>
) : null;
}
Expand Down
36 changes: 27 additions & 9 deletions addons/a11y/src/components/Report/Elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,48 @@ import { styled } from '@storybook/theming';

import { NodeResult } from 'axe-core';
import { Rules } from './Rules';
import { RuleType } from '../A11YPanel';
import HighlightToggle from './HighlightToggle';

const Item = styled.li({
fontWeight: 600,
});
const ItemTitle = styled.span({
borderBottom: '1px solid rgb(130, 130, 130)',

const ItemTitle = styled.span(({ theme }) => ({
borderBottom: `1px solid ${theme.appBorderColor}`,
width: '100%',
display: 'inline-block',
paddingBottom: '4px',
marginBottom: '4px',
paddingBottom: '6px',
marginBottom: '6px',
}));

const HighlightToggleElement = styled.span({
fontWeight: 'normal',
float: 'right',
paddingRight: '15px',
input: { margin: 0, },
});

interface ElementProps {
element: NodeResult;
passes: boolean;
type: RuleType;
}

const Element: FunctionComponent<ElementProps> = ({ element, passes }) => {
const Element: FunctionComponent<ElementProps> = ({ element, passes, type }) => {
const { any, all, none } = element;

const rules = [...any, ...all, ...none];
const highlightToggleId = `${type}-${element.target[0]}`;
const highlightLabel = `Highlight`;

return (
<Item>
<ItemTitle>{element.target[0]}</ItemTitle>
<ItemTitle>
{element.target[0]}
<HighlightToggleElement>
<HighlightToggle toggleId={highlightToggleId} type={type} elementsToHighlight={[element]} label={highlightLabel} />
</HighlightToggleElement>
</ItemTitle>
<Rules rules={rules} passes={passes} />
</Item>
);
Expand All @@ -37,12 +54,13 @@ const Element: FunctionComponent<ElementProps> = ({ element, passes }) => {
interface ElementsProps {
elements: NodeResult[];
passes: boolean;
type: RuleType;
}

export const Elements: FunctionComponent<ElementsProps> = ({ elements, passes }) => (
export const Elements: FunctionComponent<ElementsProps> = ({ elements, passes, type }) => (
<ol>
{elements.map((element, index) => (
<Element passes={passes} element={element} key={index} />
<Element passes={passes} element={element} key={index} type={type} />
))}
</ol>
);
40 changes: 40 additions & 0 deletions addons/a11y/src/components/Report/HighlightToggle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import { ThemeProvider, themes, convert } from '@storybook/theming';
import HighlightToggle from './HighlightToggle.tsx';
import store from '../../redux-config.tsx';

function ThemedHighlightToggle(props) {
return (
<ThemeProvider theme={convert(themes.normal)}>
<HighlightToggle {...props} />
</ThemeProvider>
);
}

describe('HighlightToggle component', () => {
test('should render', () => {
// given
const wrapper = mount(
<Provider store={store}>
<ThemedHighlightToggle />
</Provider>
);

// then
expect(wrapper.exists()).toBe(true);
});

test('should match snapshot', () => {
// given
const wrapper = mount(
<Provider store={store}>
<ThemedHighlightToggle />
</Provider>
);

// then
expect(wrapper).toMatchSnapshot();
});
});
Loading

0 comments on commit 5e48b8f

Please sign in to comment.