Skip to content

Commit

Permalink
fix(Tabs): add ARIA attributes (#4970)
Browse files Browse the repository at this point in the history
This change adds ARIA attributes to `<Tab>` and `<TabContent>` to
better describe their relationship.

Fixes #4968.
  • Loading branch information
asudoh authored and joshblack committed Jan 23, 2020
1 parent 5717f19 commit 0add8cc
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
8 changes: 8 additions & 0 deletions packages/react/src/components/Tab/Tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const { prefix } = settings;

export default class Tab extends React.Component {
static propTypes = {
/**
* The element ID for the top-level element.
*/
id: PropTypes.string,

/**
* Specify an optional className to be added to your Tab
*/
Expand Down Expand Up @@ -104,6 +109,7 @@ export default class Tab extends React.Component {

render() {
const {
id,
className,
handleTabClick,
handleTabKeyDown,
Expand All @@ -126,12 +132,14 @@ export default class Tab extends React.Component {
});

const anchorProps = {
id,
className: `${prefix}--tabs__nav-link`,
href,
role: 'tab',
tabIndex: !disabled ? tabIndex : -1,
['aria-selected']: selected,
['aria-disabled']: disabled,
['aria-controls']: id && `${id}__panel`,
ref: e => {
this.tabAnchor = e;
},
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/TabContent/TabContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const TabContent = props => {
});
return (
<div
role="tabpanel"
{...other}
className={tabContentClasses}
selected={selected}
Expand Down
26 changes: 18 additions & 8 deletions packages/react/src/components/Tabs/Tabs-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ const TabContentRenderedOnlyWhenSelected = ({
className,
...other
}) =>
!selected ? null : (
!selected ? (
<div {...other} ciassName="bx--visually-hidden" />
) : (
<div
{...other}
className={classNames(className, `${prefix}--tab-content`)}
Expand All @@ -72,22 +74,26 @@ storiesOf('Tabs', module)
'Default',
() => (
<Tabs {...props.tabs()}>
<Tab {...props.tab()} label="Tab label 1">
<Tab id="tab-1" {...props.tab()} label="Tab label 1">
<div className="some-content">Content for first tab goes here.</div>
</Tab>
<Tab {...props.tab()} label="Tab label 2">
<Tab id="tab-2" {...props.tab()} label="Tab label 2">
<div className="some-content">Content for second tab goes here.</div>
</Tab>
<Tab {...props.tab()} label="Tab label 3" disabled>
<Tab id="tab-3" {...props.tab()} label="Tab label 3" disabled>
<div className="some-content">Content for third tab goes here.</div>
</Tab>
<Tab
id="tab-4"
{...props.tab()}
label="Tab label 4"
renderContent={TabContentRenderedOnlyWhenSelected}>
<div className="some-content">Content for fourth tab goes here.</div>
</Tab>
<Tab {...props.tab()} label={<CustomLabel text="Custom Label" />}>
<Tab
id="tab-5"
{...props.tab()}
label={<CustomLabel text="Custom Label" />}>
<div className="some-content">Content for fifth tab goes here.</div>
</Tab>
</Tabs>
Expand All @@ -105,19 +111,23 @@ storiesOf('Tabs', module)
'Container',
() => (
<Tabs type="container" {...props.tabs()}>
<Tab {...props.tab()} label="Tab label 1">
<Tab id="tab-1" {...props.tab()} label="Tab label 1">
<div className="some-content">Content for first tab goes here.</div>
</Tab>
<Tab {...props.tab()} label="Tab label 2">
<Tab id="tab-2" {...props.tab()} label="Tab label 2">
<div className="some-content">Content for second tab goes here.</div>
</Tab>
<Tab
id="tab-3"
{...props.tab()}
label="Tab label 3"
renderContent={TabContentRenderedOnlyWhenSelected}>
<div className="some-content">Content for third tab goes here.</div>
</Tab>
<Tab {...props.tab()} label={<CustomLabel text="Custom Label" />}>
<Tab
id="tab-4"
{...props.tab()}
label={<CustomLabel text="Custom Label" />}>
<div className="some-content">Content for fourth tab goes here.</div>
</Tab>
</Tabs>
Expand Down
11 changes: 9 additions & 2 deletions packages/react/src/components/Tabs/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,21 @@ export default class Tabs extends React.Component {
});

const tabContentWithProps = React.Children.map(tabsWithProps, tab => {
const { children, selected, renderContent: TabContent } = tab.props;
const {
id: tabId,
children,
selected,
renderContent: TabContent,
} = tab.props;

return (
<TabContent
id={tabId && `${tabId}__panel`}
className={tabContentClassName}
aria-hidden={!selected}
hidden={!selected}
selected={selected}>
selected={selected}
aria-labelledby={tabId}>
{children}
</TabContent>
);
Expand Down

0 comments on commit 0add8cc

Please sign in to comment.