Skip to content
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: 1 addition & 1 deletion docs/pages/api/breadcrumbs.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <span class="prop-name">component</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'nav'</span> | The component used for the root node. Either a string to use a DOM element or a component. By default, it maps the variant to a good default headline component. |
| <span class="prop-name">itemsAfterCollapse</span> | <span class="prop-type">number</span> | <span class="prop-default">1</span> | If max items is exceeded, the number of items to show after the ellipsis. |
| <span class="prop-name">itemsBeforeCollapse</span> | <span class="prop-type">number</span> | <span class="prop-default">1</span> | If max items is exceeded, the number of items to show before the ellipsis. |
| <span class="prop-name">maxItems</span> | <span class="prop-type">number</span> | <span class="prop-default">8</span> | Specifies the maximum number of breadcrumbs to display. When there are more than the maximum number, only the first and last will be shown, with an ellipsis in between. |
| <span class="prop-name">maxItems</span> | <span class="prop-type">number</span> | <span class="prop-default">8</span> | Specifies the maximum number of breadcrumbs to display. When there are more than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse` will be shown, with an ellipsis in between. |
| <span class="prop-name">separator</span> | <span class="prop-type">node</span> | <span class="prop-default">'/'</span> | Custom separator node. |

The `ref` is forwarded to the root element.
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui/src/Breadcrumbs/Breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ Breadcrumbs.propTypes = {
itemsBeforeCollapse: PropTypes.number,
/**
* Specifies the maximum number of breadcrumbs to display. When there are more
* than the maximum number, only the first and last will be shown, with an
* ellipsis in between.
* than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse`
* will be shown, with an ellipsis in between.
*/
maxItems: PropTypes.number,
/**
Expand Down
109 changes: 61 additions & 48 deletions packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import { assert } from 'chai';
import { expect } from 'chai';
import { createMount, getClasses } from '@material-ui/core/test-utils';
import describeConformance from '../test-utils/describeConformance';
import Breadcrumbs from './Breadcrumbs';
import BreadcrumbSeparator from './BreadcrumbSeparator';
import BreadcrumbCollapsed from './BreadcrumbCollapsed';
import consoleErrorMock from 'test/utils/consoleErrorMock';
import { cleanup, createClientRender } from 'test/utils/createClientRender';

describe('<Breadcrumbs />', () => {
let mount;
let classes;
const render = createClientRender({ strict: true });

before(() => {
mount = createMount({ strict: true });
Expand All @@ -20,8 +20,8 @@ describe('<Breadcrumbs />', () => {
);
});

after(() => {
mount.cleanUp();
afterEach(() => {
cleanup();
});

describeConformance(<Breadcrumbs>Conformance?</Breadcrumbs>, () => ({
Expand All @@ -30,53 +30,65 @@ describe('<Breadcrumbs />', () => {
mount,
refInstanceof: window.HTMLElement,
testComponentPropWith: 'div',
after: () => mount.cleanUp(),
}));

it('should render seperators', () => {
const wrapper = mount(
it('should render inaccessible seperators between each listitem', () => {
const { getAllByRole, getByRole } = render(
<Breadcrumbs>
<span />
<span />
<span>first</span>
<span>second</span>
</Breadcrumbs>,
);
assert.strictEqual(wrapper.find(BreadcrumbSeparator).length, 1);

expect(
getAllByRole('listitem').filter(item => !item.matches('[aria-hidden="true"]')),
).to.have.length(2);

expect(getByRole('list')).to.have.text('first/second');
});

it('should render an ellipse', () => {
const wrapper = mount(
it('should render an ellipse between `itemsAfterCollapse` and `itemsBeforeCollapse`', () => {
const { getAllByRole, getByRole } = render(
<Breadcrumbs>
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span>first</span>
<span>second</span>
<span>third</span>
<span>fourth</span>
<span>fifth</span>
<span>sixth</span>
<span>seventh</span>
<span>eighth</span>
<span>ninth</span>
</Breadcrumbs>,
);
assert.strictEqual(wrapper.find(BreadcrumbSeparator).length, 2);
assert.strictEqual(wrapper.find(BreadcrumbCollapsed).length, 1);

expect(
getAllByRole('listitem').filter(item => !item.matches('[aria-hidden="true"]')),
).to.have.length(3);
expect(getByRole('list')).to.have.text('first//ninth');
expect(getAllByRole('listitem')[2].querySelector('[data-mui-test="MoreHorizIcon"]')).to.be.ok;
});

it('should expand when `BreadcrumbCollapsed` is clicked', () => {
const wrapper = mount(
const { getAllByRole } = render(
<Breadcrumbs>
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span />
<span>first</span>
<span>second</span>
<span>third</span>
<span>fourth</span>
<span>fifth</span>
<span>sixth</span>
<span>seventh</span>
<span>eighth</span>
<span>ninth</span>
</Breadcrumbs>,
);
assert.strictEqual(wrapper.find(BreadcrumbSeparator).length, 2);
wrapper.find(BreadcrumbCollapsed).simulate('click');
assert.strictEqual(wrapper.find(BreadcrumbSeparator).length, 8);

getAllByRole('listitem')[2].click();

const items = getAllByRole('listitem').filter(item => !item.matches('[aria-hidden="true"]'));
expect(items).to.have.length(9);
});

describe('warnings', () => {
Expand All @@ -88,21 +100,22 @@ describe('<Breadcrumbs />', () => {
consoleErrorMock.reset();
});

it('should support invalid input', () => {
const wrapper = mount(
it('should warn about invalid input', () => {
const { getAllByRole, getByRole } = render(
<Breadcrumbs maxItems={3} itemsAfterCollapse={2} itemsBeforeCollapse={2}>
<span />
<span />
<span />
<span />
<span>first</span>
<span>second</span>
<span>third</span>
<span>fourth</span>
</Breadcrumbs>,
);
assert.strictEqual(wrapper.find(BreadcrumbSeparator).length, 3);
assert.strictEqual(wrapper.find(BreadcrumbCollapsed).length, 0);
assert.strictEqual(consoleErrorMock.callCount(), 2);
assert.include(
consoleErrorMock.args()[0][0],
'you have provided an invalid combination of props to the',
expect(
getAllByRole('listitem').filter(item => !item.matches('[aria-hidden="true"]')),
).to.have.length(4);
expect(getByRole('list')).to.have.text('first/second/third/fourth');
expect(consoleErrorMock.callCount()).to.equal(2); // strict mode renders twice
expect(consoleErrorMock.args()[0][0]).to.include(
'you have provided an invalid combination of props to the Breadcrumbs.\nitemsAfterCollapse={2} + itemsBeforeCollapse={2} >= maxItems={3}',
);
});
});
Expand Down