Skip to content

Commit

Permalink
Add role and aria attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjcenizal committed Apr 30, 2018
1 parent 4540cf6 commit 3cde22c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ exports[`EuiTabbedContent behavior when selected tab state isn't controlled by t
role="tablist"
>
<button
aria-controls="42-es"
aria-selected="true"
class="euiTab euiTab-isSelected"
content="[object Object]"
id="es"
role="tab"
title="Elasticsearch"
type="button"
Expand All @@ -19,10 +20,11 @@ exports[`EuiTabbedContent behavior when selected tab state isn't controlled by t
/>
</button>
<button
aria-controls="42-kibana"
aria-selected="false"
class="euiTab"
content="[object Object]"
data-test-subj="kibanaTab"
id="kibana"
role="tab"
title="Kibana"
type="button"
Expand All @@ -32,9 +34,15 @@ exports[`EuiTabbedContent behavior when selected tab state isn't controlled by t
/>
</button>
</div>
<p>
Elasticsearch content
</p>
<div
aria-labelledby="es"
id="42-es"
role="tabpanel"
>
<p>
Elasticsearch content
</p>
</div>
</div>
`;

Expand All @@ -49,9 +57,10 @@ exports[`EuiTabbedContent is rendered 1`] = `
role="tablist"
>
<button
aria-controls="42-es"
aria-selected="true"
class="euiTab euiTab-isSelected"
content="[object Object]"
id="es"
role="tab"
title="Elasticsearch"
type="button"
Expand All @@ -61,10 +70,11 @@ exports[`EuiTabbedContent is rendered 1`] = `
/>
</button>
<button
aria-controls="42-kibana"
aria-selected="false"
class="euiTab"
content="[object Object]"
data-test-subj="kibanaTab"
id="kibana"
role="tab"
title="Kibana"
type="button"
Expand All @@ -74,9 +84,15 @@ exports[`EuiTabbedContent is rendered 1`] = `
/>
</button>
</div>
<p>
Elasticsearch content
</p>
<div
aria-labelledby="es"
id="42-es"
role="tabpanel"
>
<p>
Elasticsearch content
</p>
</div>
</div>
`;

Expand All @@ -87,9 +103,10 @@ exports[`EuiTabbedContent props initialSelectedTab is rendered 1`] = `
role="tablist"
>
<button
aria-controls="42-es"
aria-selected="false"
class="euiTab"
content="[object Object]"
id="es"
role="tab"
title="Elasticsearch"
type="button"
Expand All @@ -99,10 +116,11 @@ exports[`EuiTabbedContent props initialSelectedTab is rendered 1`] = `
/>
</button>
<button
aria-controls="42-kibana"
aria-selected="true"
class="euiTab euiTab-isSelected"
content="[object Object]"
data-test-subj="kibanaTab"
id="kibana"
role="tab"
title="Kibana"
type="button"
Expand All @@ -112,9 +130,15 @@ exports[`EuiTabbedContent props initialSelectedTab is rendered 1`] = `
/>
</button>
</div>
<p>
Kibana content
</p>
<div
aria-labelledby="kibana"
id="42-kibana"
role="tabpanel"
>
<p>
Kibana content
</p>
</div>
</div>
`;

Expand All @@ -125,9 +149,10 @@ exports[`EuiTabbedContent props selectedTab is rendered 1`] = `
role="tablist"
>
<button
aria-controls="42-es"
aria-selected="false"
class="euiTab"
content="[object Object]"
id="es"
role="tab"
title="Elasticsearch"
type="button"
Expand All @@ -137,10 +162,11 @@ exports[`EuiTabbedContent props selectedTab is rendered 1`] = `
/>
</button>
<button
aria-controls="42-kibana"
aria-selected="true"
class="euiTab euiTab-isSelected"
content="[object Object]"
data-test-subj="kibanaTab"
id="kibana"
role="tab"
title="Kibana"
type="button"
Expand All @@ -150,9 +176,15 @@ exports[`EuiTabbedContent props selectedTab is rendered 1`] = `
/>
</button>
</div>
<p>
Kibana content
</p>
<div
aria-labelledby="kibana"
id="42-kibana"
role="tabpanel"
>
<p>
Kibana content
</p>
</div>
</div>
`;

Expand All @@ -163,9 +195,10 @@ exports[`EuiTabbedContent props size is rendered 1`] = `
role="tablist"
>
<button
aria-controls="42-es"
aria-selected="true"
class="euiTab euiTab-isSelected"
content="[object Object]"
id="es"
role="tab"
title="Elasticsearch"
type="button"
Expand All @@ -175,10 +208,11 @@ exports[`EuiTabbedContent props size is rendered 1`] = `
/>
</button>
<button
aria-controls="42-kibana"
aria-selected="false"
class="euiTab"
content="[object Object]"
data-test-subj="kibanaTab"
id="kibana"
role="tab"
title="Kibana"
type="button"
Expand All @@ -188,8 +222,14 @@ exports[`EuiTabbedContent props size is rendered 1`] = `
/>
</button>
</div>
<p>
Elasticsearch content
</p>
<div
aria-labelledby="es"
id="42-es"
role="tabpanel"
>
<p>
Elasticsearch content
</p>
</div>
</div>
`;
36 changes: 30 additions & 6 deletions src/components/tabs/tabbed_content/tabbed_content.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types';

import { htmlIdGenerator } from '../../../services';

import { EuiTabs, SIZES } from '../tabs';
import { EuiTab } from '../tab';

const makeId = htmlIdGenerator();

export class EuiTabbedContent extends Component {
static propTypes = {
className: PropTypes.string,
tabs: PropTypes.array.isRequired,
// We use the id to associate tabs with panels for accessibility.
tabs: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired })).isRequired,
onTabClick: PropTypes.func,
selectedTab: PropTypes.object,
initialSelectedTab: PropTypes.object,
Expand All @@ -19,6 +24,8 @@ export class EuiTabbedContent extends Component {

const { initialSelectedTab, selectedTab, tabs } = props;

this.rootId = makeId();

this.state = {
selectedTab: selectedTab || initialSelectedTab || tabs[0],
};
Expand Down Expand Up @@ -47,27 +54,44 @@ export class EuiTabbedContent extends Component {

// Allow the consumer to control tab selection.
const selectedTab = externalSelectedTab || this.state.selectedTab
const { content } = selectedTab

const {
content: selectedTabContent,
id: selectedTabId,
} = selectedTab

return (
<div className={className} {...rest}>
<EuiTabs size={size}>
{
tabs.map((tab, index) => {
const { id, name, ...tabProps } = tab
tabs.map((tab) => {
const {
id,
name,
content, // eslint-disable-line no-unused-vars
...tabProps
} = tab
const props = {
key: id !== undefined ? id : index,
key: id,
id,
...tabProps,
onClick: () => this.onTabClick(tab),
isSelected: tab === selectedTab,
'aria-controls': `${this.rootId}-${id}`,
};

return <EuiTab {...props}>{name}</EuiTab>;
})
}
</EuiTabs>

{content}
<div
role='tabpanel'
id={`${this.rootId}-${selectedTabId}`}
aria-labelledby={selectedTabId}
>
{selectedTabContent}
</div>
</div>
)
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/tabs/tabbed_content/tabbed_content.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import { requiredProps, findTestSubject } from '../../../test';

import { EuiTabbedContent } from './tabbed_content';

// Mock the htmlIdGenerator to generate predictable ids for snapshot tests
jest.mock('../../../services/accessibility/html_id_generator', () => ({
htmlIdGenerator: () => { return () => 42; },
}));

const elasticsearchTab = {
id: 'es',
title: `Elasticsearch`,
content: <p>Elasticsearch content</p>,
};

const kibanaTab = {
id: 'kibana',
title: `Kibana`,
'data-test-subj': 'kibanaTab',
content: <p>Kibana content</p>,
Expand Down

0 comments on commit 3cde22c

Please sign in to comment.