Skip to content

Commit

Permalink
feat: add badge component (#76)
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas.J.Han <[email protected]>
  • Loading branch information
lukasjhan authored Aug 10, 2024
1 parent eff39f6 commit 7fbbfdb
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 1 deletion.
87 changes: 87 additions & 0 deletions packages/core/lib/components/Badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import { Label } from './Label';
import { Color } from '../colors/color.type';

export type BadgeProps = {
label: string;
variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger';
size?: 'x-small' | 'small' | 'medium' | 'large';
appearance?: 'fill' | 'stroke';
className?: string;
};

const variantStyles: Record<
NonNullable<BadgeProps['variant']>,
{
fill: { style: string; color: Color };
stroke: { style: string; color: Color };
}
> = {
default: {
fill: { style: 'bg-gray-10', color: 'gray-70' },
stroke: { style: 'bg-transparent border border-gray-30', color: 'gray-70' },
},
primary: {
fill: { style: 'bg-primary-10', color: 'primary-70' },
stroke: {
style: 'bg-transparent border border-primary-30',
color: 'primary-70',
},
},
success: {
fill: { style: 'bg-success-10', color: 'success-70' },
stroke: {
style: 'bg-transparent border border-success-30',
color: 'success-70',
},
},
warning: {
fill: { style: 'bg-warning-10', color: 'warning-70' },
stroke: {
style: 'bg-transparent border border-warning-30',
color: 'warning-70',
},
},
danger: {
fill: { style: 'bg-danger-10', color: 'danger-70' },
stroke: {
style: 'bg-transparent border border-danger-30',
color: 'danger-70',
},
},
};

const sizeStyles: Record<
NonNullable<BadgeProps['size']>,
{ padding: string; fontSize: 'xs' | 's' | 'm' | 'l' }
> = {
'x-small': { padding: 'px-3 py-1', fontSize: 'xs' },
small: { padding: 'px-3 py-1', fontSize: 's' },
medium: { padding: 'px-4 py-2', fontSize: 'm' },
large: { padding: 'px-4 py-2', fontSize: 'l' },
};

export const Badge: React.FC<BadgeProps> = ({
label,
variant = 'default',
size = 'small',
appearance = 'fill',
className = '',
}) => {
const variantStyle = variantStyles[variant][appearance];
const { padding, fontSize } = sizeStyles[size];

const { style, color } = variantStyle;

return (
<span
className={`inline-flex items-center justify-center rounded-2 ${style} ${padding} ${className}`}
role="status"
aria-label={label}
>
<Label color={color} size={fontSize}>
{label}
</Label>
</span>
);
};
3 changes: 2 additions & 1 deletion packages/core/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Button } from './components/Button';
import { LinkButton } from './components/LinkButton';
import { Tag } from './components/Tag';
import { Spinner } from './components/Spinner';
import { Badge } from './components/Badge';

export { Display, Heading, Title, Body, Detail, Label, Link, colors };
export { Button, LinkButton, Tag, Spinner };
export { Button, LinkButton, Tag, Spinner, Badge };
105 changes: 105 additions & 0 deletions stories/core/Badge.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { Badge } from '../../packages/core/lib';

const meta = {
title: 'Components/Badge',
component: Badge,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
control: {
type: 'select',
options: ['default', 'primary', 'success', 'warning', 'error'],
},
},
size: {
control: {
type: 'select',
options: ['x-small', 'small', 'medium', 'large'],
},
},
},
} satisfies Meta<typeof Badge>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
label: 'default',
},
};

export const Primary: Story = {
args: {
label: 'primary',
variant: 'primary',
},
};

export const Success: Story = {
args: {
label: 'success',
variant: 'success',
},
};

export const Warning: Story = {
args: {
label: 'warning',
variant: 'warning',
},
};

export const Error: Story = {
args: {
label: 'danger',
variant: 'danger',
},
};

export const xSmall: Story = {
args: {
label: 'x-small',
size: 'x-small',
},
};

export const Small: Story = {
args: {
label: 'small',
size: 'small',
},
};

export const Medium: Story = {
args: {
label: 'medium',
size: 'medium',
},
};

export const Large: Story = {
args: {
label: 'large',
size: 'large',
},
};

export const Fill: Story = {
args: {
label: 'fill',
appearance: 'fill',
},
};

export const Stroke: Story = {
args: {
label: 'stroke',
appearance: 'stroke',
},
};

0 comments on commit 7fbbfdb

Please sign in to comment.