Skip to content

Commit

Permalink
#341 Reorganize Badge component to reflect Figma designs
Browse files Browse the repository at this point in the history
  • Loading branch information
Szymon Graczyk committed Jul 25, 2022
1 parent 65e3c89 commit cce8a2e
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 37 deletions.
101 changes: 89 additions & 12 deletions packages/react-components/src/components/Badge/Badge.module.scss
Original file line number Diff line number Diff line change
@@ -1,23 +1,100 @@
.badge {
background-color: var(--color-negative-default);
border-radius: 18px;
$base-class: 'badge';

@mixin dot($size) {
border-radius: $size;
height: $size;
width: $size;
}

.#{$base-class} {
align-items: center;
box-sizing: border-box;
color: var(--content-invert-default);
display: inline-block;
font-size: 10px;
display: inline-flex;
flex-direction: column;
font-size: 12px;
font-weight: 600;
height: 18px;
line-height: 18px;
min-width: 18px;
padding: 0 3px;
text-align: center;
gap: 10px;
justify-content: center;
line-height: 16px;

&__dot {
background-color: var(--content-invert-default);
margin: 0 -2px;
}

& + & {
margin-left: 4px;
}

&--large {
border-radius: 24px;
height: 24px;
min-width: 24px;
padding: 4px 8.5px;

.#{$base-class}__dot {
@include dot(10px);
}
}

&--medium {
border-radius: 20px;
height: 20px;
min-width: 20px;
padding: 2px 7px;

.#{$base-class}__dot {
@include dot(8px);
}
}

&--compact {
border-radius: 24px;
height: 18px;
min-width: 18px;
padding: 1px 6px;

.#{$base-class}__dot {
@include dot(6px);
}
}

&--primary {
background-color: var(--color-negative-default);
color: var(--content-invert-default);

&:hover {
background-color: var(--color-negative-hover);
}

.#{$base-class}__dot {
background-color: var(--content-invert-default);
}
}

&--secondary {
background-color: var(--color-action-default);
color: var(--content-invert-default);

&:hover {
background-color: var(--color-action-hover);
}

.#{$base-class}__dot {
background-color: var(--content-invert-default);
}
}

&--tertiary {
background-color: var(--surface-secondary-default);
color: var(--surface-invert-default);
color: var(--content-default);

&:hover {
background-color: var(--surface-secondary-hover);
}

.#{$base-class}__dot {
background-color: var(--content-default);
}
}
}
13 changes: 13 additions & 0 deletions packages/react-components/src/components/Badge/Badge.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,24 @@ import * as React from 'react';
import { render } from 'test-utils';

import { Badge } from './Badge';
import styles from './Badge.module.scss';

describe('Badge', () => {
it('should accept custom className', () => {
const { container } = render(<Badge className="my-custom-class" />);

expect(container.firstChild).toHaveClass('my-custom-class');
});

it('should display exclamation mark for alert type', () => {
const { container } = render(<Badge type="alert" />);

expect(container).toHaveTextContent('!');
});

it('should display dot content for dot type', () => {
const { container } = render(<Badge type="dot" />);

expect(container.querySelector(`.${styles['badge__dot']}`)).toBeVisible();
});
});
47 changes: 32 additions & 15 deletions packages/react-components/src/components/Badge/Badge.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import { Story } from '@storybook/react';
import * as React from 'react';
import { Badge as BadgeComponent, BadgeProps } from './Badge';
import { Badge, BadgeProps } from './Badge';

export default {
title: 'Components/Badge',
component: BadgeComponent,
component: Badge,
};

export const Badge = (args: BadgeProps): React.ReactElement => (
<div
style={{
display: 'inline-flex',
alignItems: 'center',
alignContent: 'center',
}}
>
<BadgeComponent {...args} />
export const Default: Story<BadgeProps> = (
args: BadgeProps
): React.ReactElement => <Badge {...args} />;

Default.storyName = 'Badge';
Default.args = {
children: '1',
};

export const Sizes = (): JSX.Element => (
<div className="spacer">
<Badge size="compact">1</Badge>
<Badge size="medium">1</Badge>
<Badge size="large">1</Badge>
</div>
);

Badge.args = {
secondary: false,
children: '7',
};
export const Kinds = (): JSX.Element => (
<div className="spacer">
<Badge kind="primary">1</Badge>
<Badge kind="secondary">1</Badge>
<Badge kind="tertiary">1</Badge>
</div>
);

export const Types = (): JSX.Element => (
<div className="spacer">
<Badge type="content">3 steps left</Badge>
<Badge type="alert" />
<Badge type="dot" />
</div>
);
31 changes: 21 additions & 10 deletions packages/react-components/src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,33 @@ import * as React from 'react';
import styles from './Badge.module.scss';
import cx from 'clsx';

const baseClass = 'badge';

export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {
secondary?: boolean;
kind?: 'primary' | 'secondary' | 'tertiary';
size?: 'large' | 'medium' | 'compact';
type?: 'content' | 'alert' | 'dot';
}

export const Badge: React.FC<BadgeProps> = ({
children,
className,
secondary = false,
kind = 'primary',
size = 'medium',
type = 'content',
}) => {
return (
<span
className={cx(styles.badge, className, {
[styles['badge--secondary']]: secondary,
})}
>
{children}
</span>
const mergedClassNames = cx(
className,
styles[baseClass],
styles[`${baseClass}--${kind}`],
styles[`${baseClass}--${size}`]
);

const content = {
['content']: children,
['alert']: '!',
['dot']: <span className={styles[`${baseClass}__dot`]} />,
}[type];

return <span className={mergedClassNames}>{content}</span>;
};

0 comments on commit cce8a2e

Please sign in to comment.