Skip to content
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

[FE] 이벤트 홈 화면 새로운 플로우로 교체 (참여자 별 정산, 전체 지출 내역), Dropdown 컴포넌트 구현 #582

Merged
merged 25 commits into from
Sep 24, 2024

Conversation

jinhokim98
Copy link
Contributor

@jinhokim98 jinhokim98 commented Sep 21, 2024

issue

구현 사항

Tabs 디자인 변경

이전 디자인
image

수정된 디자인
image

탭을 최신 디자인에 맞게 변경했습니다.

사용자가 더 관심이 많은 참여자 별 정산이 먼저 보이도록 설정

행동대장 링크를 타고 들어온 사람은 전체 지출 내역보다는 내가 얼마를 내야할지 더 관심이 많았습니다. 그래서 사용자가 더 관심있는 데이터를 먼저 보여주도록 했습니다.

지출내역 안에 검색창이 들어가도록 변경

이전 디자인
image

새로운 디자인
image

입금 확인 컴포넌트 적용 완료

image

Flex 컴포넌트 다른 스타일 확장할 수 있도록 설정

otherStyle 옵션을 추가했어요 React.CSSProperties 타입으로 React에서 인라인으로 css를 넣어주는 속성 그대로 사용하도록 했어요.

아래와 같이 사용하면 됩니다.

<Flex
      flexDirection="column"
      width="100%"
      backgroundColor="white"
      padding="0.5rem 1rem"
      paddingInline="0.5rem"
      gap="0.5rem"
      height="100%"
      otherStyle={{borderRadius: '1rem'}}
    >

초대 버튼 색상 변경

image

지출 내역이 없을 때 fallback 컴포넌트 구현

image

이 fallback은 참여자만 볼 수 있습니다.

관리 페이지의 dropdown 구현

image

사용방식은 탭 컴포넌트와 비슷해요!
Title의 dropdown prop에 Tabs와 Tab과 비슷한 구조로 넣으면 됩니다!

<Title
        title={eventName}
        amount={totalExpenseAmount}
        dropdown={
          <Dropdown>
            <DropdownButton text="전체 참여자 관리" />
            <DropdownButton text="계좌번호 입력하기" />
          </Dropdown>
        }
      />

탭 컴포넌트 Indicator width 이슈

두 가지 이슈가 있었습니다

  • 실제 tab width에 indicator가 꽉 차지 않음
  • 0에서 실제 tab width로 값이 바뀌며 생기는 indicator가 채워지는 현상
  1. 실제 tab width에 indicator가 꽉 차지 않음
    tab width에 indicator가 채워지지 않던 이유는 명확히는 모르겠어요. 초기 값에서 8px정도 적게 되고 resize가 일어났을 때 그때서야 바로 채워지더라구요. 현재의 방식은 ref.current.offsetWidth를 통해서 값을 가져오는 방식이었습니다.

그래서 방식을 바꿨어요. ResizeObserver를 사용하는 방식으로 바꿨습니다.
ResizeObserver는 특정 요소 자체의 크기 변화를 감지하는 옵저버입니다.

https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
https://duknock.tistory.com/8

초기에 컴포넌트가 랜더링되고 요소의 크기가 변했으니 observer callback이 실행됩니다.
그 때 현재의 tabRef와 entry target이 동일할 때 entry의 width 값을 가져옴으로써 정확한 width를 가져올 수 있습니다.

if (entry.target === tabRef.current) {
  setTabWidth(entry.contentRect.width);
}
  1. 0에서 실제 tab width로 값이 바뀌며 생기는 indicator가 채워지는 현상

기존에는 이런 현상이 있었습니다.

2024-09-24-11-56-18.mp4

탭을 이동할 때마다 indicator가 채워지는 현상이 부자연스러웠고 이를 수정하기 위해 tab width가 0일 때는 indicator를 랜더링하지 않는 방향으로 수정했습니다.

2024-09-24-11-56-52.mp4

중점적으로 리뷰받고 싶은 부분(선택)

위 Flex 확장 방식 괜찮은가요?

🫡 참고사항

행동 디자인 토큰으로 z-index를 추가했습니다. 정해진 z-index 값만 사용하기 위해서입니다~

@jinhokim98 jinhokim98 added this to the lev4 milestone Sep 21, 2024
@jinhokim98 jinhokim98 self-assigned this Sep 21, 2024
@jinhokim98 jinhokim98 changed the title [FE] 이벤트 홈 화면 새로운 플로우로 교체 (참여자 별 정산, 전체 지출 내역) [FE] 이벤트 홈 화면 새로운 플로우로 교체 (참여자 별 정산, 전체 지출 내역), Dropdown 컴포넌트 구현 Sep 23, 2024
Copy link

Copy link
Contributor

@pakxe pakxe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생 많았습니다! 이슈를 가져가준 것도 모자라 잘 만들어 주어서 너무 고마워요~!!!


const Dropdown = ({children}: DropdownProps) => {
const {isOpen, openDropdown, meetBallsRef, dropdownRef} = useDropdown();
const isDropdownOpen = isOpen && meetBallsRef.current;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

드랍다운을 여는 상황이 미트볼이 아닐 수도 있을 것 같아서 좀 더 범용적인 이름도 좋을 것 같네요 ! 😁

import {dropdownButtonStyle} from './Dropdown.style';
import {DropdownButtonProps} from './Dropdown.type';

const DropdownButton = ({text, ...buttonProps}: DropdownButtonProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

드랍다운 안에서 이 버튼들이 ul -> li처럼 li태그로 감싸진 후 버튼이나 다른 태그 안에 사용하는 것도 좋아보여요~! ul, li로 하면 아마 "아이템 3개 중 1번째" 이런 식으로 낭독기가 읽어줬던 것 같거든요.

>
<Icon iconType="meatballs" />
{isDropdownOpen && (
<section ref={dropdownRef}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시멘틱 태그를 적극적으로 활용하는 것 같아 좋아요~~ 제안이지만 ul태그도 넣는 건 어떻게 생각하시나요?!

Comment on lines +1 to +7
export type DropdownButtonProps = React.HTMLAttributes<HTMLButtonElement> & {
text: string;
};

export type DropdownProps = {
children: React.ReactElement<DropdownButtonProps>[];
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

타입 굿굿 ~~ 👍

Comment on lines +17 to +18
(dropdownRef.current && dropdownRef.current.contains(targetNode)) ||
(meetBallsRef.current && meetBallsRef.current.contains(targetNode))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이걸 함수로 분리해도 좋을 것 같아요! 무엇을 의미하는지 더 빠르게 알 수 있을 것 같아요 😁

const {steps} = useRequestGetSteps();
const {totalExpenseAmount} = useTotalExpenseAmountStore();

return (
<div style={{paddingBottom: '2rem'}}>
<div css={receiptStyle}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인라인 css를 없애주셨군요! 좋아요좋아요

Comment on lines 28 to 34
if (reports.length <= 0) {
return <BillEmptyFallback />;
}

return (
<Flex flexDirection="column" gap="0.5rem" paddingInline="0.5rem">
{reports.length > 0 ? (
<>
<Input inputType="search" value={name} onChange={changeName} placeholder="참여자 이름" />
{matchedReports.length !== 0 && <ExpenseList expenseList={expenseListProp} />}
</>
) : (
<Flex width="100%" justifyContent="center">
<Text size="body" textColor="gray" style={{paddingTop: '1rem'}}>
지금은 참여자가 한 명도 없어요. :(
</Text>
</Flex>
)}
<Flex flexDirection="column" gap="0.5rem">
<ExpenseList name={name} onSearch={changeName} placeholder="이름 검색" expenseList={expenseListProp} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뭔가 if문으로 위에 동떨어져 있으니까 이게 렌더링 대상이라는게 잘 인지되지 않을 수도 있을 것 같기도 해요.. 저만 그런걸 수도 ..!! 혹시 아래의 return문 안에 이걸 넣지 않은 이유가 있을까요?

@@ -5,6 +5,7 @@ import {Theme} from '@theme/theme.type';
import {GlobalStyle} from '@theme/GlobalStyle';
import {COLORS} from '@token/colors';
import {TYPOGRAPHY} from '@token/typography';
import {ZINDEX} from '@token/zIndex';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Z_INDEX는 어떤가요?!

Comment on lines +41 to +50
{inputType === 'input' && value && hasFocus && (
<IconButton tabIndex={-1} variants="none" onMouseDown={handleClickDelete}>
<Icon iconType="inputDelete" />
</IconButton>
)}
{inputType === 'search' && (
<IconButton tabIndex={-1} variants="none">
<Icon iconType="search" />
</IconButton>
)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

분기문이 늘어나니 드는 생각이 <Input.Search />이런 식으로 만든다면 각 컴포넌트를 따로 만들게 되니까 읽기 더 좋을 것 같기도 하네요 😆

@@ -17,4 +17,6 @@ export interface FlexProps {
backgroundColor?: FlexBackgroundColor;
theme?: Theme;
minHeight?: string;

otherStyle?: React.CSSProperties;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가해줘서 고맙숩니다 !~~~!!

Copy link

@jinhokim98 jinhokim98 merged commit 396ff78 into fe-dev Sep 24, 2024
2 checks passed
@jinhokim98 jinhokim98 deleted the feature/#578 branch September 24, 2024 07:33
@Todari Todari added this to the v2.0.0 milestone Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: ✅ Done
3 participants