Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tabs] Forward aria-label* attributes to tablist #20986

Merged
merged 1 commit into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/pages/api-docs/tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ The `MuiTabs` name can be used for providing [default props](/customization/glob
| Name | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| <span class="prop-name">action</span> | <span class="prop-type">ref</span> | | Callback fired when the component mounts. This is useful when you want to trigger an action programmatically. It supports two actions: `updateIndicator()` and `updateScrollButtons()` |
| <span class="prop-name">aria-label</span> | <span class="prop-type">string</span> | | The label for the Tabs as a string. |
| <span class="prop-name">aria-labelledby</span> | <span class="prop-type">string</span> | | An id or list of ids separated by a space that label the Tabs. |
| <span class="prop-name">centered</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the tabs will be centered. This property is intended for large views. |
| <span class="prop-name">children</span> | <span class="prop-type">node</span> | | The content of the component. |
| <span class="prop-name">classes</span> | <span class="prop-type">object</span> | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. |
Expand Down
12 changes: 12 additions & 0 deletions packages/material-ui/src/Tabs/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export const styles = (theme) => ({

const Tabs = React.forwardRef(function Tabs(props, ref) {
const {
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
action,
centered = false,
children: childrenProp,
Expand Down Expand Up @@ -483,6 +485,8 @@ const Tabs = React.forwardRef(function Tabs(props, ref) {
{/* The tablist isn't interactive but the tabs are */}
{/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
<div
aria-label={ariaLabel}
aria-labelledby={ariaLabelledBy}
className={clsx(classes.flexContainer, {
[classes.flexContainerVertical]: vertical,
[classes.centered]: centered && !scrollable,
Expand Down Expand Up @@ -510,6 +514,14 @@ Tabs.propTypes = {
* that can be triggered programmatically.
*/
action: refType,
/**
* The label for the Tabs as a string.
*/
'aria-label': PropTypes.string,
/**
* An id or list of ids separated by a space that label the Tabs.
*/
'aria-labelledby': PropTypes.string,
/**
* If `true`, the tabs will be centered.
* This property is intended for large views.
Expand Down
19 changes: 18 additions & 1 deletion packages/material-ui/src/Tabs/Tabs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { expect } from 'chai';
import { spy, useFakeTimers } from 'sinon';
import consoleErrorMock from 'test/utils/consoleErrorMock';
import { createMount, getClasses } from '@material-ui/core/test-utils';
import { createClientRender, fireEvent } from 'test/utils/createClientRender';
import { createClientRender, fireEvent, screen } from 'test/utils/createClientRender';
import createServerRender from 'test/utils/createServerRender';
import describeConformance from '../test-utils/describeConformance';
import capitalize from '../utils/capitalize';
Expand Down Expand Up @@ -65,6 +65,23 @@ describe('<Tabs />', () => {
after: () => mount.cleanUp(),
}));

it('can be named via `aria-label`', () => {
render(<Tabs aria-label="string label" />);

expect(screen.getByRole('tablist')).toHaveAccessibleName('string label');
});

it('can be named via `aria-labelledby`', () => {
render(
<React.Fragment>
<h3 id="label-id">complex name</h3>
<Tabs aria-labelledby="label-id" />
</React.Fragment>,
);

expect(screen.getByRole('tablist')).toHaveAccessibleName('complex name');
});

describe('warnings', () => {
before(() => {
consoleErrorMock.spy();
Expand Down