forked from next-step/react-payments
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
288 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
### 필수 요구사항 | ||
- [x] 원시적인 형태의 Primitive UI 형태의 컴포넌트 작성 | ||
- [x] Box | ||
- [x] HStack | ||
- [x] VStack | ||
- [x] TextField | ||
- [x] Typography | ||
- [x] Button | ||
- [ ] Funnel 기반의 애플리케이션 설계 | ||
- [ ] Storybook 상호 작용 테스트 | ||
- [ ] Controlled & Uncontrolled Components를 명확하게 구분하거나 선택하여 구현 | ||
|
||
### 카드 추가 | ||
<(뒤로가기) 버튼 클릭 시, 카드 목록 페이지로 이동한다. | ||
|
||
= [ ] 카드 번호를 입력 받을 수 있다. | ||
|
||
- [ ] 카드 번호는 숫자만 입력가능하다. | ||
- [ ] 카드 번호 4자리마다 -가 삽입된다. | ||
- [ ] 카드 번호는 실시간으로 카드 UI에 반영된다. | ||
- [ ] 카드 번호는 앞 8자리만 숫자로 보여지고, 나머지 숫자는 *로 보여진다. | ||
- [ ] 만료일을 입력 받을 수 있다. | ||
|
||
- [ ] MM / YY 로 placeholder를 적용한다. | ||
- [ ] 월, 년 사이에 자동으로 /가 삽입된다. | ||
- [ ] 만료일은 실시간으로 카드 UI에 반영된다. | ||
- [ ] 월은 1이상 12이하 숫자여야 한다. | ||
- [ ] 보안코드를 입력 받을 수 있다. | ||
|
||
- [ ] 보안코드는 *으로 보여진다. | ||
- [ ] 보안코드는 숫자만 입력가능하다. | ||
- [ ] 카드 비밀번호의 앞 2자리를 입력 받을 수 있다. | ||
|
||
- [ ] 카드 비밀번호는 각 폼마다 한자리 숫자만 입력가능하다. | ||
- [ ] 카드 번호 입력 시, *으로 보여진다. | ||
- [ ] 카드 소유자 이름을 입력 받을 수 있다. | ||
|
||
- [ ] 이름은 30자리까지 입력할 수 있다. | ||
- [ ] 이름 입력 폼 위에, 현재 입력 자릿수와 최대 입력 자릿수를 실시간으로 보여준다. | ||
- [ ] 카드 추가 완료시 카드 등록 완료 페이지로 이동한다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import { AppLayout } from '@/components'; | ||
import { Button } from '@/shared/components'; | ||
import { storybookControls } from '@/shared/styles'; | ||
|
||
const meta: Meta<typeof Button> = { | ||
title: 'Primitive/Button', | ||
component: Button, | ||
parameters: { | ||
layout: 'centered', | ||
}, | ||
tags: ['autodocs'], | ||
argTypes: { | ||
...storybookControls.argTypes, | ||
type: { | ||
options: ['button', 'submit', 'reset'], | ||
}, | ||
variant: { | ||
options: ['solid', 'outline', 'ghost'], | ||
}, | ||
colorScheme: { | ||
options: ['teal', 'gray'], | ||
}, | ||
textAlign: { | ||
options: ['left', 'center', 'right'], | ||
}, | ||
}, | ||
args: { | ||
type: 'button', | ||
variant: 'solid', | ||
colorScheme: 'teal', | ||
children: 'Button', | ||
}, | ||
decorators: [ | ||
(Story) => ( | ||
<AppLayout> | ||
<Story /> | ||
</AppLayout> | ||
), | ||
], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof Button>; | ||
|
||
export const Primary: Story = { | ||
args: { | ||
variant: 'solid', | ||
}, | ||
}; | ||
|
||
export const WithVariantOutline: Story = { | ||
args: { | ||
variant: 'outline', | ||
}, | ||
}; | ||
|
||
export const WithVariantGhost: Story = { | ||
args: { | ||
variant: 'ghost', | ||
}, | ||
}; | ||
|
||
export const WithColorSchemeGray: Story = { | ||
args: { | ||
colorScheme: 'gray', | ||
}, | ||
}; | ||
|
||
export const WithDisabled: Story = { | ||
args: { | ||
disabled: true, | ||
}, | ||
}; | ||
|
||
export const WithCustomSize: Story = { | ||
args: { | ||
width: '200px', | ||
height: '50px', | ||
}, | ||
}; | ||
|
||
export const WithCustomTextAlign: Story = { | ||
args: { | ||
width: '200px', | ||
height: '50px', | ||
textAlign: 'right', | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { HTMLProps, PropsWithChildren } from 'react'; | ||
import styled from '@emotion/styled'; | ||
import type { ButtonOptionalProps } from './Button.type'; | ||
import { getButtonColor } from './Button.util'; | ||
import { styleToken } from '@/shared/styles'; | ||
import type { AsProps, StyleProps } from '@/shared/types'; | ||
|
||
type ButtonProps = PropsWithChildren<StyleProps & AsProps & HTMLProps<HTMLButtonElement> & ButtonOptionalProps>; | ||
|
||
export const Button = ({ children, type, variant, colorScheme, ...rest }: ButtonProps) => { | ||
const buttonType = type || 'button'; | ||
const buttonVariant = variant || 'solid'; | ||
const buttonColorScheme = colorScheme || 'teal'; | ||
return ( | ||
<Root type={buttonType} variant={buttonVariant} colorScheme={buttonColorScheme} {...rest}> | ||
{children} | ||
</Root> | ||
); | ||
}; | ||
|
||
const Root = styled.button<ButtonProps & Required<ButtonOptionalProps>>` | ||
width: ${({ width }) => width || 'auto'}; | ||
height: ${({ height }) => height || 'auto'}; | ||
text-align: ${({ textAlign }) => textAlign || 'center'}; | ||
padding: 10px 16px; | ||
border-radius: 4px; | ||
font-size: ${styleToken.fontSize.subtitle}; | ||
cursor: pointer; | ||
transition: | ||
background-color 0.2s, | ||
color 0.2s, | ||
border-color 0.2s; | ||
${({ variant, colorScheme }) => { | ||
const { backgroundColor, color, border } = getButtonColor(colorScheme, variant, 'default'); | ||
return ` | ||
background-color: ${backgroundColor}; | ||
color: ${color}; | ||
border: ${border}; | ||
`; | ||
}} | ||
&:hover { | ||
${({ variant, colorScheme }) => { | ||
const { backgroundColor, color, border } = getButtonColor(colorScheme, variant, 'hover'); | ||
return ` | ||
background-color: ${backgroundColor}; | ||
color: ${color}; | ||
border: ${border}; | ||
`; | ||
}} | ||
} | ||
&:disabled { | ||
opacity: 0.6; | ||
cursor: not-allowed; | ||
} | ||
`; | ||
|
||
Button.displayName = 'Button'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export type ButtonType = 'button' | 'submit' | 'reset'; | ||
export type ButtonVariant = 'solid' | 'outline' | 'ghost'; | ||
export type ButtonVariantState = 'default' | 'hover'; | ||
export type ButtonColorScheme = 'teal' | 'gray'; | ||
export type ButtonOptionalProps = { | ||
type?: ButtonType; | ||
variant?: ButtonVariant; | ||
colorScheme?: ButtonColorScheme; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import type { ButtonVariant, ButtonVariantState, ButtonColorScheme } from './Button.type'; | ||
import { styleToken } from '@/shared/styles'; | ||
|
||
export const buttonColorMap = { | ||
teal: { | ||
solid: { | ||
default: { | ||
backgroundColor: styleToken.color.teal200, | ||
color: styleToken.color.white, | ||
border: 'unset', | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.teal100, | ||
color: styleToken.color.white, | ||
border: 'unset', | ||
}, | ||
}, | ||
outline: { | ||
default: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.teal200, | ||
border: `1px solid ${styleToken.color.teal200}`, | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.teal200, | ||
border: `1px solid ${styleToken.color.teal200}`, | ||
}, | ||
}, | ||
ghost: { | ||
default: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.teal200, | ||
border: 'unset', | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.teal200, | ||
border: 'unset', | ||
}, | ||
}, | ||
}, | ||
gray: { | ||
solid: { | ||
default: { | ||
backgroundColor: styleToken.color.gray400, | ||
color: styleToken.color.white, | ||
border: 'unset', | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.gray300, | ||
color: styleToken.color.white, | ||
border: 'unset', | ||
}, | ||
}, | ||
outline: { | ||
default: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.gray400, | ||
border: `1px solid ${styleToken.color.gray400}`, | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.gray400, | ||
border: `1px solid ${styleToken.color.gray400}`, | ||
}, | ||
}, | ||
ghost: { | ||
default: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.gray400, | ||
border: 'unset', | ||
}, | ||
hover: { | ||
backgroundColor: styleToken.color.white, | ||
color: styleToken.color.gray400, | ||
border: 'unset', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export const getButtonColor = (colorScheme: ButtonColorScheme, variant: ButtonVariant, state: ButtonVariantState) => { | ||
const colorInfo = buttonColorMap[colorScheme][variant]; | ||
return colorInfo[state]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './Button'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters