From cefc94c2f1db64176bc63a427b3de26b7a336144 Mon Sep 17 00:00:00 2001 From: Ye-Chan Kang Date: Mon, 29 Jan 2024 19:23:27 +0900 Subject: [PATCH] feat(common): badge (#3) --- src/components/common/Badge/index.tsx | 93 ++++++++++++++++++++++++++ src/components/common/Button/index.tsx | 2 +- src/components/common/index.ts | 1 + src/stories/common/Badge.stories.tsx | 90 +++++++++++++++++++++++++ src/styles/theme.ts | 1 + 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/components/common/Badge/index.tsx create mode 100644 src/stories/common/Badge.stories.tsx diff --git a/src/components/common/Badge/index.tsx b/src/components/common/Badge/index.tsx new file mode 100644 index 0000000..3f8bffe --- /dev/null +++ b/src/components/common/Badge/index.tsx @@ -0,0 +1,93 @@ +import { Theme, css } from '@emotion/react'; +import styled from '@emotion/styled'; +import * as React from 'react'; + +import { SizeType } from '@/types/size'; + +type BadgeVariantType = 'primary' | 'secondary' | 'warning' | 'danger' | 'outline' | 'ghost'; + +const BadgeVariantStyles = ({ theme, variant }: { theme: Theme; variant: BadgeVariantType }) => { + switch (variant) { + case 'secondary': + return css` + background-color: ${theme.colors.secondary}; + `; + case 'danger': + return css` + color: ${theme.colors.white}; + background-color: ${theme.colors.danger}; + `; + case 'warning': + return css` + color: ${theme.colors.white}; + background-color: ${theme.colors.warning}; + `; + case 'outline': + return css` + background-color: transparent; + border: 1px solid ${theme.colors.gray['300']}; + &:hover { + background-color: ${theme.colors.gray['100']}; + } + `; + case 'ghost': + return css` + background-color: transparent; + `; + case 'primary': + default: + return css` + color: white; + background-color: ${theme.colors.primary}; + `; + } +}; + +const BadgeSizeStyles = ({ size }: { size: SizeType }) => { + switch (size) { + case 'sm': + return css` + padding: 0.125rem 0.5rem; + `; + case 'lg': + return css` + padding: 0.375rem 0.75rem; + `; + case 'md': + default: + return css` + padding: 0.25rem 0.625rem; + `; + } +}; + +const StyledBadge = styled.div` + font-weight: 500; + font-size: 75%; + line-height: 1rem; + border-radius: 6px; + border: 1px solid transparent; + display: inline-flex; + align-items: center; + + ${({ theme, variant }) => variant && BadgeVariantStyles({ theme, variant })} + + ${({ size }) => size && BadgeSizeStyles({ size })} +`; + +export interface BadgeVariantProps { + /* + Badge variant + */ + variant?: BadgeVariantType; + /* + Badge size + */ + size?: SizeType; +} + +export interface BadgeProps extends React.ComponentProps<'div'>, BadgeVariantProps {} + +export const Badge = ({ className, variant = 'primary', size = 'md', ...props }: BadgeProps) => { + return ; +}; diff --git a/src/components/common/Button/index.tsx b/src/components/common/Button/index.tsx index 06e4243..381a7bb 100644 --- a/src/components/common/Button/index.tsx +++ b/src/components/common/Button/index.tsx @@ -10,7 +10,7 @@ const ButtonVariantStyles = ({ theme, variant }: { theme: Theme; variant: Button switch (variant) { case 'secondary': return css` - background-color: ${theme.colors.gray['200']}; + background-color: ${theme.colors.secondary}; `; case 'danger': return css` diff --git a/src/components/common/index.ts b/src/components/common/index.ts index ba7644b..b0d6377 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -1,4 +1,5 @@ export * from './Avatar'; +export * from './Badge'; export * from './Button'; export * from './Card'; export * from './Form'; diff --git a/src/stories/common/Badge.stories.tsx b/src/stories/common/Badge.stories.tsx new file mode 100644 index 0000000..e72973b --- /dev/null +++ b/src/stories/common/Badge.stories.tsx @@ -0,0 +1,90 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import React from 'react'; + +import { Badge } from '../..'; + +const meta = { + title: 'common/Badge', + component: Badge, + tags: ['autodocs'], + argTypes: {}, + parameters: { + layout: 'centered', + componentSubtitle: 'Base Badge', + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + args: { + children: 'Badge', + }, +}; + +export const Secondary: Story = { + args: { + variant: 'secondary', + ...Primary.args, + }, +}; + +export const Danger: Story = { + args: { + variant: 'danger', + ...Primary.args, + }, +}; + +export const Warning: Story = { + args: { + variant: 'warning', + ...Primary.args, + }, +}; + +export const Outline: Story = { + args: { + variant: 'outline', + ...Primary.args, + }, +}; + +export const Ghost: Story = { + args: { + variant: 'ghost', + ...Primary.args, + }, +}; + +export const WithLink: Story = { + args: { + children: 'Link', + }, + decorators: [ + Story => { + return ( + + + + ); + }, + ], +}; + +export const WithText: Story = { + args: { + children: 'Badge', + }, + decorators: [ + Story => { + return ( +
+ WithText +
+ ); + }, + ], +}; diff --git a/src/styles/theme.ts b/src/styles/theme.ts index 80e4ab1..0a4b8a8 100644 --- a/src/styles/theme.ts +++ b/src/styles/theme.ts @@ -5,6 +5,7 @@ export const BMateColors = { white: '#FAFAFA', black: '#212121', primary: '#212121', + secondary: '#EEEEEE', gray: { 50: '#FAFAFA', 100: '#F5F5F5',