-
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?
Conversation
|
|
constantly-dev
left a comment
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.
수고하셨습니다! 코멘트 확인해주세요~
| const style = createButtonVariant(theme, rounded, size, variant); | ||
| const { finalIntent, finalShape } = useResolvedProps({ intent, shape, theme, rounded }); | ||
| const isFloating = variant === 'floating'; | ||
| const scrollDirection = isFloating ? useScrollDirection() : null; |
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.
hook은 조건에 따라 호출되는 것이 아닌 최상위에서 호출이 되어야 할 것 같아요! 차라리 일단 무조건 값을 return 받고 값으로 분기처리 해야 할 것 같아요.
const scrollDirection = useScrollDirection();
const finalDirection = isFloating ? scrollDirection : null; 근데 이렇게 하면 useScrollDirection에서 useEffect 내부 이벤트 리스너 등 로직을 isFloating이 false일 때도 불필요하게 실행이 되니, useScrollDirection에 enabled 파라미터를 뚫어서 isFloating에 따라 useEffect에 early return으로 실행 분기를 내부적으로 추가하면 어떨까요?
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.
가장 최선은 디자이너와 논의하여 FloatingButton 정도의 별도 컴포넌트를 만드는 것이라고 봐요.. 하나의 베리언트가 이렇게 많은 파생 분기 코드들을 만들어내니, 자연스럽게 분리를 고려하기 좋은 타이밍이라고 생각합니다.
그게 안된다면 차선책으로 진혁님이 말씀해주신 것들 챙기면 좋을 것 같네요
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.
저도 이부분에 대해서 동의합니다!
| } | ||
|
|
||
| export const useResolvedProps = ({ intent, shape, theme, rounded }: UseResolvedProps) => { | ||
| const finalIntent = React.useMemo(() => { |
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.
useMemo만 import 시켜도 될 것 같습니다
| rounded?: 'md' | 'lg'; | ||
| } | ||
|
|
||
| export const useResolvedProps = ({ intent, shape, theme, rounded }: UseResolvedProps) => { |
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.
button 컴포넌트 interface가 변경되면서 useResolvedProps로 이전 interface의 호환성을 가져가기 위함이 맞을까요?
물론 개인적인 생각이지만 호환성을 위해서는 필요하지만 이렇게 진행하게 되면 결국 레거시가 또 추가되는 느낌이 들어서..! 이후에 각 팀에서 interface 최신화해주고, 없애는 것은 어떨까요?
| useEffect(() => { | ||
| let lastScrollY = window.pageYOffset; | ||
| const updateScrollDirection = () => { | ||
| const scrollY = window.pageYOffset; | ||
| const direction = scrollY > lastScrollY ? 'down' : 'up'; | ||
| setScrollDirection(direction); | ||
| lastScrollY = scrollY > 0 ? scrollY : 0; | ||
| }; | ||
| window.addEventListener('scroll', updateScrollDirection); | ||
| return () => { | ||
| window.removeEventListener('scroll', updateScrollDirection); | ||
| }; | ||
| }, [scrollDirection]); |
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.
현재 코드상으로는 scrollDirection가 의존에 추가되어 있어 스크롤 할 때마다 useEffect 전체 로직이 실행되니까, 이벤트 리스너 로직도 계속 실행이 될 것 같아요.
scrollDirection가 의존성 배열에 안 들어가도 될 것 같은데 어떻게 생각하시나요?
| const [scrollDirection, setScrollDirection] = useState<'up' | 'down' | null>(null); | ||
|
|
||
| useEffect(() => { | ||
| let lastScrollY = window.pageYOffset; |
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.
클로저로 구현된 거 같은데 맞을까요?? 지금도 잘 작동할 것 같고 useRef를 사용해도 동일하게 작동하겠네요!
| sizeTheme: ButtonSizeTheme, | ||
| variant: 'fill' | 'outlined', | ||
| variant: ButtonVariant, | ||
| isExpanded: boolean, |
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.
피그마랑 동일하게 isExtended로 통일하는 것은 어떨까요?
| isExpanded: boolean, | |
| isExtended: boolean, |
아래 분기 처리된 string 값도 extended 같아서!
padding:
variant === 'floating'
? isExpanded
? 'floating-extended'
: 'floating-default'
: variant === 'text'
? 'text'
: sizeTheme,| const { finalIntent, finalShape } = useResolvedProps({ intent, shape, theme, rounded }); | ||
| const isFloating = variant === 'floating'; | ||
| const scrollDirection = isFloating ? useScrollDirection() : null; | ||
| const [isExpanded, setIsExpanded] = useState(false); |
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.
| RightIcon, | ||
| variant = 'fill', | ||
| shape = 'rect', | ||
| intent = 'primary', |
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는 어떤 의미인가요?
constantly-dev
left a comment
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.
👀
| padding: | ||
| variant === 'floating' | ||
| ? isExpanded | ||
| ? 'floating-extended' | ||
| : 'floating-default' | ||
| : variant === 'text' | ||
| ? 'text' | ||
| : sizeTheme, |
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.
Do not nest ternary expressions.
eslint(no-nested-ternary)
eslint error가 뜨긴하네요!
| }, | ||
| borderRadius: radiusTheme === 'lg' ? 'max' : sizeTheme, | ||
| padding: sizeTheme, | ||
| borderRadius: variant === 'text' || variant === 'floating' ? variant : radiusTheme === 'pill' ? 'max' : sizeTheme, |
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.
조금 복잡한 조건은 차라리 이름 붙여서 분리해주면 좋을 것 같아요!
| interface UseResolvedProps { | ||
| intent: ButtonIntent; | ||
| shape: ButtonShape; | ||
| theme?: ButtonColorTheme; | ||
| rounded?: 'md' | 'lg'; | ||
| } |
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.
| interface UseResolvedProps { | |
| intent: ButtonIntent; | |
| shape: ButtonShape; | |
| theme?: ButtonColorTheme; | |
| rounded?: 'md' | 'lg'; | |
| } | |
| type UseResolvedProps = Pick<ButtonProps, pick_union> |
새로 작성하지 않는게 좋을 것 같아요
| const style = createButtonVariant(theme, rounded, size, variant); | ||
| const { finalIntent, finalShape } = useResolvedProps({ intent, shape, theme, rounded }); | ||
| const isFloating = variant === 'floating'; | ||
| const scrollDirection = isFloating ? useScrollDirection() : null; |
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.
가장 최선은 디자이너와 논의하여 FloatingButton 정도의 별도 컴포넌트를 만드는 것이라고 봐요.. 하나의 베리언트가 이렇게 많은 파생 분기 코드들을 만들어내니, 자연스럽게 분리를 고려하기 좋은 타이밍이라고 생각합니다.
그게 안된다면 차선책으로 진혁님이 말씀해주신 것들 챙기면 좋을 것 같네요

변경사항
링크
시급한 정도
🏃♂️ 보통 : 최대한 빠르게 리뷰 부탁드립니다.
기타 사항