-
Notifications
You must be signed in to change notification settings - Fork 4
refactor(Button): Button 컴포넌트 variant 추가 #287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
76dbf95
7b5466b
c640708
2bd93dd
55937c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,9 @@ | ||
| import React, { type ButtonHTMLAttributes } from 'react'; | ||
| import React, { useEffect, useState, type ButtonHTMLAttributes } from 'react'; | ||
| import * as S from './style.css'; | ||
| import createButtonVariant from './utils'; | ||
| import { iconSizes } from './constants'; | ||
| import { ButtonIntent, ButtonShape, ButtonVariant } from './types'; | ||
| import { useResolvedProps, useScrollDirection } from './hooks'; | ||
|
|
||
| interface IconProps { | ||
| color?: string; | ||
|
|
@@ -13,33 +15,48 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { | |
| children?: React.ReactNode; | ||
| className?: string; | ||
| size?: 'sm' | 'md' | 'lg'; | ||
| theme?: 'white' | 'black' | 'blue' | 'red'; | ||
| rounded?: 'md' | 'lg'; | ||
| variant?: 'fill' | 'outlined'; | ||
| theme?: 'white' | 'black' | 'blue' | 'red'; // @deprecated - `intent` prop 사용 | ||
| rounded?: 'md' | 'lg'; // @deprecated - `shape` prop 사용 | ||
| variant?: ButtonVariant; | ||
| LeftIcon?: React.ComponentType<IconProps>; | ||
| RightIcon?: React.ComponentType<IconProps>; | ||
| shape?: ButtonShape; | ||
| intent?: ButtonIntent; | ||
| } | ||
|
|
||
| function Button({ | ||
| children, | ||
| className, | ||
| size = 'md', | ||
| theme = 'white', | ||
| rounded = 'md', | ||
| theme, | ||
| rounded, | ||
| LeftIcon, | ||
| RightIcon, | ||
| variant = 'fill', | ||
| shape = 'rect', | ||
| intent = 'primary', | ||
| ...buttonElementProps | ||
| }: ButtonProps) { | ||
| const style = createButtonVariant(theme, rounded, size, variant); | ||
| const { finalIntent, finalShape } = useResolvedProps({ intent, shape, theme, rounded }); | ||
| const isFloating = variant === 'floating'; | ||
| const scrollDirection = isFloating ? useScrollDirection() : null; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hook은 조건에 따라 호출되는 것이 아닌 최상위에서 호출이 되어야 할 것 같아요! 차라리 일단 무조건 값을 return 받고 값으로 분기처리 해야 할 것 같아요. const scrollDirection = useScrollDirection();
const finalDirection = isFloating ? scrollDirection : null; 근데 이렇게 하면
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 가장 최선은 디자이너와 논의하여 FloatingButton 정도의 별도 컴포넌트를 만드는 것이라고 봐요.. 하나의 베리언트가 이렇게 많은 파생 분기 코드들을 만들어내니, 자연스럽게 분리를 고려하기 좋은 타이밍이라고 생각합니다. 그게 안된다면 차선책으로 진혁님이 말씀해주신 것들 챙기면 좋을 것 같네요
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 이부분에 대해서 동의합니다! |
||
| const [isExpanded, setIsExpanded] = useState(false); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| useEffect(() => { | ||
| if (!isFloating) return; | ||
| setIsExpanded(scrollDirection === 'down'); | ||
| }, [scrollDirection, isFloating]); | ||
|
|
||
| const style = createButtonVariant(finalIntent, finalShape, size, variant, isExpanded); | ||
| const iconSize = iconSizes[size]; | ||
| return ( | ||
| <button className={`${S.root} ${style} ${className}`} type='button' {...buttonElementProps}> | ||
| {LeftIcon ? <LeftIcon height={iconSize} width={iconSize} /> : null} | ||
| <span>{children}</span> | ||
| {(!isFloating || isExpanded) && <span>{children}</span>} | ||
| {RightIcon && !LeftIcon ? <RightIcon height={iconSize} width={iconSize} /> : null} | ||
| </button> | ||
| ); | ||
| } | ||
|
|
||
| Button.displayName = 'Button'; | ||
| export default Button; | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순 궁금증인데
intent는 어떤 의미인가요?