Skip to content

Commit f58b9eb

Browse files
Change Breadcrumbs to accept single breadcrumb instead of array
1 parent 1441b7a commit f58b9eb

File tree

9 files changed

+77
-108
lines changed

9 files changed

+77
-108
lines changed

.changeset/afraid-scissors-work.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/polaris': major
3+
---
4+
5+
Change breadcrumbs from an array to a single breadcrumb since only one is supported.

polaris-react/playground/DetailsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ export function DetailsPage() {
547547
const actualPageMarkup = (
548548
<Page
549549
fullWidth
550-
breadcrumbs={[{content: 'Products', url: '/products/31'}]}
550+
breadcrumb={{content: 'Products', url: '/products/31'}}
551551
title={title}
552552
titleMetadata={<Badge status="success">Success badge</Badge>}
553553
primaryAction={{

polaris-react/src/components/Breadcrumbs/Breadcrumbs.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,11 @@ import {Text} from '../Text';
1010
import styles from './Breadcrumbs.scss';
1111

1212
export interface BreadcrumbsProps {
13-
/** Collection of breadcrumbs */
14-
breadcrumbs: (CallbackAction | LinkAction)[];
13+
/** Breadcrumb link */
14+
breadcrumb: CallbackAction | LinkAction;
1515
}
1616

17-
export function Breadcrumbs({breadcrumbs}: BreadcrumbsProps) {
18-
const breadcrumb = breadcrumbs[breadcrumbs.length - 1];
19-
if (breadcrumb == null) {
20-
return null;
21-
}
22-
17+
export function Breadcrumbs({breadcrumb}: BreadcrumbsProps) {
2318
const {content} = breadcrumb;
2419

2520
const contentMarkup = (

polaris-react/src/components/Breadcrumbs/tests/Breadcrumbs.test.tsx

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,25 @@ import {Text} from '../../Text';
88
describe('<Breadcrumbs />', () => {
99
describe('url', () => {
1010
it('uses <a> tags when passed a LinkAction', () => {
11-
const linkBreadcrumbs: LinkAction[] = [
12-
{
13-
content: 'Products',
14-
url: 'https://www.shopify.com',
15-
},
16-
];
17-
11+
const linkBreadcrumb: LinkAction = {
12+
content: 'Products',
13+
url: 'https://www.shopify.com',
14+
};
1815
const breadcrumbs = mountWithApp(
19-
<Breadcrumbs breadcrumbs={linkBreadcrumbs} />,
16+
<Breadcrumbs breadcrumb={linkBreadcrumb} />,
2017
);
2118

2219
expect(breadcrumbs).toContainReactComponentTimes('a', 1);
2320
});
2421

2522
it('passes the accessibilityLabel through to <a> tag', () => {
26-
const linkBreadcrumbs: LinkAction[] = [
27-
{
28-
content: 'Products',
29-
url: 'https://shopify.com',
30-
accessibilityLabel: 'Go to Products',
31-
},
32-
];
33-
23+
const linkBreadcrumb: LinkAction = {
24+
content: 'Products',
25+
url: 'https://shopify.com',
26+
accessibilityLabel: 'Go to Products',
27+
};
3428
const breadcrumbs = mountWithApp(
35-
<Breadcrumbs breadcrumbs={linkBreadcrumbs} />,
29+
<Breadcrumbs breadcrumb={linkBreadcrumb} />,
3630
);
3731

3832
expect(breadcrumbs).toContainReactComponent('a', {
@@ -43,31 +37,25 @@ describe('<Breadcrumbs />', () => {
4337

4438
describe('onAction()', () => {
4539
it('uses <button> tags when passed a CallbackAction', () => {
46-
const callbackBreadcrumbs: CallbackAction[] = [
47-
{
48-
content: 'Products',
49-
onAction: noop,
50-
},
51-
];
52-
40+
const callbackBreadcrumb: CallbackAction = {
41+
content: 'Products',
42+
onAction: noop,
43+
};
5344
const breadcrumbs = mountWithApp(
54-
<Breadcrumbs breadcrumbs={callbackBreadcrumbs} />,
45+
<Breadcrumbs breadcrumb={callbackBreadcrumb} />,
5546
);
5647

5748
expect(breadcrumbs).toContainReactComponentTimes('button', 1);
5849
});
5950

6051
it('passes accessibilityLabel through to <button> tag', () => {
61-
const callbackBreadcrumbs: CallbackAction[] = [
62-
{
63-
content: 'Products',
64-
onAction: noop,
65-
accessibilityLabel: 'Go to Products',
66-
},
67-
];
68-
52+
const callbackBreadcrumb: CallbackAction = {
53+
content: 'Products',
54+
onAction: noop,
55+
accessibilityLabel: 'Go to Products',
56+
};
6957
const breadcrumbs = mountWithApp(
70-
<Breadcrumbs breadcrumbs={callbackBreadcrumbs} />,
58+
<Breadcrumbs breadcrumb={callbackBreadcrumb} />,
7159
);
7260

7361
expect(breadcrumbs).toContainReactComponent('button', {
@@ -77,43 +65,32 @@ describe('<Breadcrumbs />', () => {
7765

7866
it('triggers the callback function when clicked', () => {
7967
const spy = jest.fn();
80-
const callbackBreadcrumbs: CallbackAction[] = [
81-
{
82-
content: 'Products',
83-
onAction: spy,
84-
},
85-
];
86-
68+
const callbackBreadcrumb: CallbackAction = {
69+
content: 'Products',
70+
onAction: spy,
71+
};
8772
const breadcrumbs = mountWithApp(
88-
<Breadcrumbs breadcrumbs={callbackBreadcrumbs} />,
73+
<Breadcrumbs breadcrumb={callbackBreadcrumb} />,
8974
);
9075

9176
breadcrumbs.find('button')!.trigger('onClick');
9277
expect(spy).toHaveBeenCalled();
9378
});
9479
});
9580

96-
const linkBreadcrumbs: LinkAction[] = [
97-
{
98-
content: 'Products',
99-
url: 'https://www.shopify.com',
100-
},
101-
];
81+
const linkBreadcrumb: LinkAction = {
82+
content: 'Products',
83+
url: 'https://www.shopify.com',
84+
};
10285

10386
it('renders breadcrumb content as a visually hidden label when the new design language is enabled', () => {
104-
const wrapper = mountWithApp(<Breadcrumbs breadcrumbs={linkBreadcrumbs} />);
87+
const wrapper = mountWithApp(<Breadcrumbs breadcrumb={linkBreadcrumb} />);
10588

10689
expect(wrapper).toContainReactComponent(Text, {
10790
children: 'Products',
10891
visuallyHidden: true,
10992
});
11093
});
111-
112-
it('renders nothing when empty', () => {
113-
const wrapper = mountWithApp(<Breadcrumbs breadcrumbs={[]} />);
114-
115-
expect(wrapper.html()).toBe('');
116-
});
11794
});
11895

11996
function noop() {}

polaris-react/src/components/Page/Page.stories.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default {
1010
export function Default() {
1111
return (
1212
<Page
13-
breadcrumbs={[{content: 'Products', url: '/products'}]}
13+
breadcrumb={{content: 'Products', url: '/products'}}
1414
title="3/4 inch Leather pet collar"
1515
titleMetadata={<Badge status="success">Paid</Badge>}
1616
subtitle="Perfect for any pet"
@@ -30,7 +30,6 @@ export function Default() {
3030
actionGroups={[
3131
{
3232
title: 'Promote',
33-
accessibilityLabel: 'Action group label',
3433
actions: [
3534
{
3635
content: 'Share on Facebook',
@@ -55,7 +54,7 @@ export function Default() {
5554
export function WithCustomPrimaryAction() {
5655
return (
5756
<Page
58-
breadcrumbs={[{content: 'Settings', url: '/settings'}]}
57+
breadcrumb={{content: 'Settings', url: '/settings'}}
5958
title="General"
6059
primaryAction={
6160
<Button
@@ -79,7 +78,7 @@ export function WithCustomPrimaryAction() {
7978
export function WithoutPrimaryActionInHeader() {
8079
return (
8180
<Page
82-
breadcrumbs={[{content: 'Orders', url: '/orders'}]}
81+
breadcrumb={{content: 'Orders', url: '/orders'}}
8382
title="#1085"
8483
secondaryActions={[
8584
{content: 'Print'},
@@ -159,7 +158,7 @@ export function WithToolTipAction() {
159158
export function WithSubtitle() {
160159
return (
161160
<Page
162-
breadcrumbs={[{content: 'Products', url: '/products'}]}
161+
breadcrumb={{content: 'Products', url: '/products'}}
163162
title="Invoice"
164163
subtitle="Statement period: May 3, 2019 to June 2, 2019"
165164
secondaryActions={[{content: 'Download', icon: ArrowDownMinor}]}
@@ -195,7 +194,7 @@ export function WithExternalLink() {
195194
export function WithoutPagination() {
196195
return (
197196
<Page
198-
breadcrumbs={[{content: 'Settings', url: '/settings'}]}
197+
breadcrumb={{content: 'Settings', url: '/settings'}}
199198
title="General"
200199
primaryAction={{content: 'Save'}}
201200
>
@@ -228,7 +227,7 @@ export function NarrowWidth() {
228227
return (
229228
<Page
230229
narrowWidth
231-
breadcrumbs={[{content: 'Orders', url: '/orders'}]}
230+
breadcrumb={{content: 'Orders', url: '/orders'}}
232231
title="Add payment method"
233232
primaryAction={{content: 'Save', disabled: true}}
234233
>
@@ -282,7 +281,7 @@ export function WithActionGroups() {
282281
export function WithContentAfterTitle() {
283282
return (
284283
<Page
285-
breadcrumbs={[{content: 'Products', url: '/products'}]}
284+
breadcrumb={{content: 'Products', url: '/products'}}
286285
title="Jar With Lock-Lid"
287286
titleMetadata={<Badge status="attention">Verified</Badge>}
288287
primaryAction={{content: 'Save', disabled: true}}
@@ -305,7 +304,7 @@ export function WithContentAfterTitle() {
305304
export function WithDivider() {
306305
return (
307306
<Page
308-
breadcrumbs={[{content: 'Settings', url: '/settings'}]}
307+
breadcrumb={{content: 'Settings', url: '/settings'}}
309308
title="General"
310309
divider
311310
>

polaris-react/src/components/Page/Page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function Page({
4040
rest.secondaryActions.length > 0) ||
4141
isReactElement(rest.secondaryActions))) ||
4242
(rest.actionGroups != null && rest.actionGroups.length > 0) ||
43-
(rest.breadcrumbs != null && rest.breadcrumbs.length > 0);
43+
rest.breadcrumb != null;
4444

4545
const contentClassName = classNames(
4646
!hasHeaderContent && styles.Content,

polaris-react/src/components/Page/components/Header/Header.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ export interface HeaderProps extends TitleProps {
4747
primaryAction?: PrimaryAction | React.ReactNode;
4848
/** Page-level pagination */
4949
pagination?: PaginationProps;
50-
/** Collection of breadcrumbs */
51-
breadcrumbs?: BreadcrumbsProps['breadcrumbs'];
50+
/** Breadcrumb link */
51+
breadcrumb?: BreadcrumbsProps['breadcrumb'];
5252
/** Collection of secondary page-level actions */
5353
secondaryActions?: MenuActionDescriptor[] | React.ReactNode;
5454
/** Collection of page-level groups of secondary actions */
@@ -74,7 +74,7 @@ export function Header({
7474
primaryAction,
7575
pagination,
7676
additionalNavigation,
77-
breadcrumbs = [],
77+
breadcrumb,
7878
secondaryActions = [],
7979
actionGroups = [],
8080
compactTitle = false,
@@ -97,12 +97,11 @@ export function Header({
9797
isReactElement(secondaryActions)) &&
9898
!actionGroups.length;
9999

100-
const breadcrumbMarkup =
101-
breadcrumbs.length > 0 ? (
102-
<div className={styles.BreadcrumbWrapper}>
103-
<Breadcrumbs breadcrumbs={breadcrumbs} />
104-
</div>
105-
) : null;
100+
const breadcrumbMarkup = breadcrumb ? (
101+
<div className={styles.BreadcrumbWrapper}>
102+
<Breadcrumbs breadcrumb={breadcrumb} />
103+
</div>
104+
) : null;
106105

107106
const paginationMarkup =
108107
pagination && !isNavigationCollapsed ? (
@@ -178,7 +177,7 @@ export function Header({
178177
navigationMarkup && styles.hasNavigation,
179178
actionMenuMarkup && styles.hasActionMenu,
180179
isNavigationCollapsed && styles.mobileView,
181-
!breadcrumbs.length && styles.noBreadcrumbs,
180+
!breadcrumb && styles.noBreadcrumbs,
182181
title && title.length < LONG_TITLE && styles.mediumTitle,
183182
title && title.length > LONG_TITLE && styles.longTitle,
184183
);

polaris-react/src/components/Page/components/Header/tests/Header.test.tsx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,17 @@ describe('<Header />', () => {
4747
});
4848

4949
describe('breadcrumbs', () => {
50-
const breadcrumbs: LinkAction[] = [
51-
{
52-
content: 'Products',
53-
url: 'https://www.google.com',
54-
},
55-
];
50+
const breadcrumb: LinkAction = {
51+
content: 'Products',
52+
url: 'https://www.google.com',
53+
};
5654

5755
it('get passed into Breadcrumbs', () => {
5856
const header = mountWithApp(
59-
<Header {...mockProps} breadcrumbs={breadcrumbs} />,
57+
<Header {...mockProps} breadcrumb={breadcrumb} />,
6058
);
6159
expect(header).toContainReactComponent(Breadcrumbs, {
62-
breadcrumbs,
60+
breadcrumb,
6361
});
6462
});
6563
});
@@ -291,12 +289,10 @@ describe('<Header />', () => {
291289
{content: 'mock content 2'},
292290
];
293291

294-
const breadcrumbs: LinkAction[] = [
295-
{
296-
content: 'Products',
297-
url: 'https://www.google.com',
298-
},
299-
];
292+
const breadcrumb: LinkAction = {
293+
content: 'Products',
294+
url: 'https://www.google.com',
295+
};
300296

301297
it('does not render primary and secondary action wrapper divs', () => {
302298
const header = mountWithApp(
@@ -341,7 +337,7 @@ describe('<Header />', () => {
341337

342338
it('renders a default mobile layout', () => {
343339
const header = mountWithApp(
344-
<Header title="mmmmmmmmm" breadcrumbs={breadcrumbs} />,
340+
<Header title="mmmmmmmmm" breadcrumb={breadcrumb} />,
345341
{
346342
mediaQuery: {isNavigationCollapsed: true},
347343
},

polaris-react/src/components/Page/tests/Page.test.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,26 +234,24 @@ describe('<Page />', () => {
234234
});
235235

236236
describe('breadcrumbs', () => {
237-
const breadcrumbs = [
238-
{
239-
content: 'Products',
240-
onAction: noop,
241-
},
242-
];
237+
const breadcrumb = {
238+
content: 'Products',
239+
onAction: noop,
240+
};
243241

244242
it('renders a <Header /> when defined', () => {
245243
const page = mountWithApp(
246-
<Page {...mockProps} breadcrumbs={breadcrumbs} />,
244+
<Page {...mockProps} breadcrumb={breadcrumb} />,
247245
);
248246
expect(page).toContainReactComponent(Header);
249247
});
250248

251249
it('gets passed into the <Header />', () => {
252250
const page = mountWithApp(
253-
<Page {...mockProps} breadcrumbs={breadcrumbs} />,
251+
<Page {...mockProps} breadcrumb={breadcrumb} />,
254252
);
255253
expect(page).toContainReactComponent(Header, {
256-
breadcrumbs,
254+
breadcrumb,
257255
});
258256
});
259257
});

0 commit comments

Comments
 (0)