From 6b84755a0a581c6cda70f7baf446da54f9ee7677 Mon Sep 17 00:00:00 2001 From: kyuran kim <57716832+gxxrxn@users.noreply.github.com> Date: Mon, 17 Jul 2023 19:06:55 +0900 Subject: [PATCH] =?UTF-8?q?[#359]=20Button=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20(#381)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Button 컴포넌트 작성 * feat: Button 컴포넌트 스토리 작성 * feat: 버튼 fontWeight props 추가 - 최근 검색어 버튼 스토리 작성 * fix: fontWeight 400 normal로 변경 * chore: 사용하지 않는 스토리북 Button 컴포넌트 삭제 * refactor: 버튼 props 및 스토리북 수정 * chore: story 버튼 컴포넌트 복구 * feat: 버튼 Default 스토리 추가 * refactor: Base 폴더 안으로 Button 스토리 이동 --- src/stories/Base/Button.stories.tsx | 68 +++++++++++++++++++++ src/stories/Button.stories.ts | 42 ------------- src/ui/Base/Button.tsx | 92 +++++++++++++++++++++++++++++ tailwind.config.js | 2 +- 4 files changed, 161 insertions(+), 43 deletions(-) create mode 100644 src/stories/Base/Button.stories.tsx delete mode 100644 src/stories/Button.stories.ts create mode 100644 src/ui/Base/Button.tsx diff --git a/src/stories/Base/Button.stories.tsx b/src/stories/Base/Button.stories.tsx new file mode 100644 index 00000000..a857e86b --- /dev/null +++ b/src/stories/Base/Button.stories.tsx @@ -0,0 +1,68 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import Button from '@/ui/Base/Button'; + +const meta: Meta = { + title: 'Base/Button', + component: Button, + tags: ['autodocs'], + argTypes: { + colorScheme: { control: 'select' }, + }, + args: { + size: 'medium', + fill: true, + fullRadius: false, + }, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: args => , +}; + +export const Main: Story = { + args: { + colorScheme: 'main', + }, + render: args => , +}; + +export const MainLight: Story = { + args: { + colorScheme: 'main-light', + }, + render: args => , +}; + +export const Warning: Story = { + args: { + colorScheme: 'warning', + }, + render: args => , +}; + +export const Grey: Story = { + args: { + colorScheme: 'grey', + }, + render: args => , +}; + +export const Kakao: Story = { + args: { + colorScheme: 'kakao', + }, + render: args => , +}; + +export const RecentSearch: Story = { + args: { + ...MainLight.args, + fullRadius: true, + }, + render: args => , +}; diff --git a/src/stories/Button.stories.ts b/src/stories/Button.stories.ts deleted file mode 100644 index 43fec6f6..00000000 --- a/src/stories/Button.stories.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Button } from './Button'; - -// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction -const meta: Meta = { - title: 'Example/Button', - component: Button, - tags: ['autodocs'], - argTypes: {}, -}; - -export default meta; -type Story = StoryObj; - -// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args -export const Primary: Story = { - args: { - primary: true, - label: 'Button', - }, -}; - -export const Secondary: Story = { - args: { - label: 'Button', - }, -}; - -export const Large: Story = { - args: { - size: 'large', - label: 'Button', - }, -}; - -export const Small: Story = { - args: { - size: 'small', - label: 'Button', - }, -}; diff --git a/src/ui/Base/Button.tsx b/src/ui/Base/Button.tsx new file mode 100644 index 00000000..cb0eb9a0 --- /dev/null +++ b/src/ui/Base/Button.tsx @@ -0,0 +1,92 @@ +import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; +import { useMemo } from 'react'; + +type Size = 'small' | 'medium' | 'large' | 'full'; +type ColorScheme = 'main' | 'main-light' | 'warning' | 'grey' | 'kakao'; + +type ButtonProps = PropsWithChildren<{ + size?: Size; + colorScheme?: ColorScheme; + fill?: boolean; + fullRadius?: boolean; +}> & + ComponentPropsWithoutRef<'button'>; + +const getSizeClasses = (size: Size) => { + switch (size) { + case 'small': { + return 'text-sm px-[1.2rem] py-[0.6rem]'; + } + case 'medium': { + return 'text-md px-[1.6rem] py-[0.8rem]'; + } + case 'large': { + return 'text-lg px-[2.4rem] py-[1rem]'; + } + case 'full': { + return 'text-lg px-[2.4rem] py-[1rem] w-full'; + } + default: { + // medium + return 'text-md px-[1.6rem] py-[0.8rem]'; + } + } +}; + +const getSchemeClasses = (theme: ColorScheme, isFill: boolean) => { + switch (theme) { + case 'main': { + return isFill + ? 'border-main-900 bg-main-900 text-white' + : 'border-main-900 text-main-900'; + } + case 'main-light': { + return 'border-transparent bg-main-600/[.18] text-main-900 font-normal'; + } + case 'warning': { + return isFill + ? 'border-warning-800 bg-warning-800 text-white ' + : 'border-warning-800 text-warning-800'; + } + case 'grey': { + return isFill + ? 'border-black-400 bg-black-400 text-black-500 ' + : 'border-black-400 text-black-500'; + } + case 'kakao': { + return 'border-kakao bg-kakao text-kakaotext'; + } + } +}; + +const BASE_BUTTON_CLASSES = + 'cursor-pointer border-[0.1rem] leading-none inline-block font-bold'; + +const Button = ({ + size = 'medium', + colorScheme = 'main', + fill = true, + fullRadius = false, + children, + ...props +}: ButtonProps) => { + const computedClasses = useMemo(() => { + const sizeClass = getSizeClasses(size); + const schemeClass = getSchemeClasses(colorScheme, fill); + const roundedClass = fullRadius ? 'rounded-full' : 'rounded-[5px]'; + + return [sizeClass, schemeClass, roundedClass].join(' '); + }, [size, colorScheme, fill, fullRadius]); + + return ( + + ); +}; + +export default Button; diff --git a/tailwind.config.js b/tailwind.config.js index c271dc03..5f87125f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -21,7 +21,7 @@ module.exports = { }, fontWeight: { thin: 100, - regular: 400, + normal: 400, bold: 700, }, colors: {