Skip to content

Commit

Permalink
Merge pull request #24 from Myongji-Graduate/implement-button-atom-co…
Browse files Browse the repository at this point in the history
…mponent/#19

Implement button atom component/#19
  • Loading branch information
gahyuun authored Feb 18, 2024
2 parents e6421ca + 1d6594e commit b19a151
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 129 deletions.
10 changes: 10 additions & 0 deletions .storybook/preview-body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/static/pretendard-dynamic-subset.min.css"
/>

<style>
* {
font-family: 'Pretendard';
}
</style>
1 change: 1 addition & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Preview } from '@storybook/react';
import '../app/globals.css';

const preview: Preview = {
parameters: {
Expand Down
14 changes: 9 additions & 5 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
}
}

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb));
}

@layer utilities {
.text-balance {
text-wrap: balance;
}
}

*,
a {
font-family: 'Pretendard';
}

a:-webkit-any-link {
text-decoration: none;
}
11 changes: 7 additions & 4 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
Expand All @@ -16,7 +13,13 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<head>
<link
href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/static/pretendard.css"
rel="stylesheet"
/>
</head>
<body>{children}</body>
</html>
);
}
90 changes: 90 additions & 0 deletions app/ui/view/atom/button/button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './button';

const meta = {
title: 'ui/view/atom/Button',
component: Button,
tags: ['autodocs'],
parameters: {
componentSubtitle: 'Button은 사용자가 한 번의 탭으로 작업을 수행하고 선택할 수 있는 컴포넌트입니다.',
docs: {
description: {
component: `
- variant값으로 "primary" | "secondary" | "text" | "delete" 중 하나를 선택할 수 있습니다.\n
- size값으로 "lg" | "md" | "sm" | "xs" | "default" 중 하나를 선택할 수 있습니다.\n
- label 값으로 button 태그에 존재하는 text를 의미하고 필수적으로 할당해야 합니다
`,
},
},
},
argTypes: {
variant: {
description: 'Button의 Variant를 설정합니다.',
table: {
type: { summary: 'ButtonVariant' },
defaultValue: { summary: 'primary' },
},
options: ['primary', 'secondary', 'text', 'delete'],
control: {
type: 'radio',
},
},
size: {
description: 'Button의 size를 설정합니다.',
table: {
type: { summary: 'ButtonSize' },
defaultValue: { summary: 'md' },
},
options: ['lg', 'md', 'sm', 'xs', 'default'],
control: {
type: 'radio',
},
},
label: {
description: 'Button의 label을 설정합니다',
table: {
type: { summary: 'ButtonLabel' },
defaultValue: { summary: '' },
},
},
},
} satisfies Meta<typeof Button>;

export default meta;

export const PrimaryButton: StoryObj<typeof Button> = {
args: {
size: 'md',
variant: 'primary',
label: '수강현황 자세히보기',
},
render: (args) => <Button {...args} />,
};

export const SecondaryButton: StoryObj<typeof Button> = {
args: {
size: 'xs',
variant: 'secondary',
label: '커스텀하기',
},
render: (args) => <Button {...args} />,
};

export const DeleteButton: StoryObj<typeof Button> = {
args: {
size: 'default',
variant: 'delete',
label: '삭제',
},
render: (args) => <Button {...args} />,
};

export const TextButton: StoryObj<typeof Button> = {
args: {
size: 'default',
variant: 'text',
label: '회원탈퇴하기',
},
render: (args) => <Button {...args} />,
};
37 changes: 37 additions & 0 deletions app/ui/view/atom/button/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { cva } from 'class-variance-authority';
import React from 'react';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
label: string;
variant?: 'primary' | 'secondary' | 'text' | 'delete';
size?: 'xs' | 'sm' | 'md' | 'lg' | 'default';
}

export const ButtonVariants = cva(`flex justify-center items-center`, {
variants: {
variant: {
primary: 'bg-primary rounded-[100px] text-white border-0 hover:bg-primary-hover',
secondary: 'bg-white rounded-[100px] border-solid border-[1px] border-gray hover:bg-white-hover',
text: 'font-medium text-slate-400 text-sm hover:text-slate-600',
delete: 'py-2 px-3.5 bg-[#35353559] rounded-[7px] text-white leading-5 font-medium text-[18px]',
},
size: {
default: '',
xs: 'px-5 py-3 text-lg font-medium leading-5',
sm: 'px-12 py-3.5 text-sm font-medium leading-3',
md: 'px-6 py-4 text-lg font-medium leading-3',
lg: 'px-32 py-6 text-3xl font-medium leading-9',
},
},
});

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
{ label, variant = 'primary', size = 'default', ...props },
ref,
) {
return (
<button className={ButtonVariants({ variant, size })} {...props} ref={ref}>
{label}
</button>
);
});
Loading

0 comments on commit b19a151

Please sign in to comment.