Skip to content

Commit

Permalink
Merge pull request #1142 from Shopify/navigation-badge-support-jsx
Browse files Browse the repository at this point in the history
[Navigation] badge accepts react element
  • Loading branch information
CameronGorrie authored Mar 11, 2019
2 parents 15e0980 + b35d656 commit 6ac6319
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
2 changes: 2 additions & 0 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f

### Enhancements

- Updated `Navigation` badge prop to accept a react node ([#1142](https://github.com/Shopify/polaris-react/pull/1142))

### Bug fixes

- Fixed unnecessary height on `TextField` due to unhandled carriage returns ([#901](https://github.com/Shopify/polaris-react/pull/901))
Expand Down
39 changes: 26 additions & 13 deletions src/components/Navigation/components/Item/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface SecondaryAction {
export interface Props extends ItemURLDetails {
icon?: IconProps['source'];
iconBody?: string;
badge?: string | null;
badge?: React.ReactNode;
label: string;
disabled?: boolean;
accessibilityLabel?: string;
Expand Down Expand Up @@ -90,16 +90,16 @@ export class BaseItem extends React.Component<CombinedProps, State> {
url,
icon,
label,
badge,
subNavigationItems = [],
secondaryAction,
disabled,
onClick,
accessibilityLabel,
iconBody,
selected: selectedOverride,
badge,
new: isNew,
polaris: {intl},
selected: selectedOverride,
} = this.props;

const {location, onNavigationDismiss} = this.context;
Expand All @@ -116,15 +116,6 @@ export class BaseItem extends React.Component<CombinedProps, State> {
</span>
) : null;

const badgeMarkup =
badge || isNew ? (
<div className={styles.Badge}>
<Badge status="new" size="small">
{badge || intl.translate('Polaris.Badge.STATUS_LABELS.new')}
</Badge>
</div>
) : null;

const iconMarkup = iconBody ? (
<div className={styles.Icon}>
<Icon source={iconBody} />
Expand All @@ -137,14 +128,36 @@ export class BaseItem extends React.Component<CombinedProps, State> {
)
);

let badgeMarkup: React.ReactNode = null;
if (isNew) {
badgeMarkup = (
<Badge status="new" size="small">
{intl.translate('Polaris.Badge.STATUS_LABELS.new')}
</Badge>
);
} else if (typeof badge === 'string') {
badgeMarkup = (
<Badge status="new" size="small">
{badge}
</Badge>
);
} else {
badgeMarkup = badge;
}

const wrappedBadgeMarkup =
badgeMarkup == null ? null : (
<div className={styles.Badge}>{badgeMarkup}</div>
);

const itemContentMarkup = (
<React.Fragment>
{iconMarkup}
<span className={styles.Text}>
{label}
{indicatorMarkup}
</span>
{badgeMarkup}
{wrappedBadgeMarkup}
</React.Fragment>
);

Expand Down
28 changes: 28 additions & 0 deletions src/components/Navigation/components/Item/tests/Item.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,34 @@ describe('<Nav.Item />', () => {
const link = item.find(UnstyledLink);
expect(link.exists()).toBe(true);
});

it('renders a small badge with new status if the prop is provided with a string', () => {
const item = mountWithAppProvider(<Item label="some label" badge="1" />);

expect(item.find(Badge).props()).toMatchObject({
status: 'new',
size: 'small',
children: '1',
});
});

it('renders a badge if the prop is provided with an element', () => {
const item = mountWithAppProvider(
<Item label="some label" badge={<Badge>Custom badge</Badge>} />,
);

expect(item.find(Badge).text()).toContain('Custom badge');
});

it('renders a single new badge even if a badge prop is also provided', () => {
const item = mountWithAppProvider(
<Item label="some label" badge={<Badge>Custom badge</Badge>} new />,
);
const badge = item.find(Badge);

expect(badge).toHaveLength(1);
expect(badge.text()).toContain('New');
});
});

describe('with SubNavigationItems', () => {
Expand Down

0 comments on commit 6ac6319

Please sign in to comment.