-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feat: 공통 Header를 구현합니다. #19
base: main
Are you sure you want to change the base?
Conversation
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.
prop 네이밍은 다양한 프로젝트의 header 인터페이스를 참고해서 가장 general하게 사용되는 이름으로 네이밍해보았는데, 너무 길다는 생각이 든다면 언제든 더 나은 네이밍을 추천해주셔도 좋습니다!!
저는 직관적이고 좋은 것 같습니다!
고생 많으셨어용 ~~ ✨👍
src/common/components/Header.tsx
Outdated
const LeftElement = styled.div` | ||
position: absolute; | ||
left: 1.5rem; | ||
`; | ||
|
||
const CenterElement = styled.div` | ||
margin: 0 auto; | ||
`; | ||
|
||
const RightElement = styled.div` | ||
position: absolute; | ||
right: 1.5rem; | ||
`; |
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 LeftElement = styled.div` | |
position: absolute; | |
left: 1.5rem; | |
`; | |
const CenterElement = styled.div` | |
margin: 0 auto; | |
`; | |
const RightElement = styled.div` | |
position: absolute; | |
right: 1.5rem; | |
`; | |
const LeftElement = styled.div({ | |
position: absolute; | |
left: 1.5rem; | |
}); |
회의 때 얘기 나눈 것처럼 string tagged template 말고 object 사용하면 좋을 것 같아요~!
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.
수정해두었습니다!! (626a4dd)
src/common/components/Header.tsx
Outdated
|
||
const HeaderWrapper = styled.header({ | ||
position: "sticky", | ||
zIndex: 999, |
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.
요런 공통 컴포넌트에서 쓰이는 z-index 값들은 다른 요소들의 z-index 와 영향을 미칠 수 있으니까
export const HEADER_Z_INDEX = 999
이런식으로 하나 상수 파일 안에서 z-index들 관리해도 좋을 것 같아요!
그래서 헤더보다 낮은 z index를 줘야할 때 예를 들면
zIndex : HEADER_Z_INDEX - 1
이런식으로 관리하면 유용하더라구용
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.
zIndex를 상수로 관리하는 의견에 동의해요!
다른 곳에서도 zIndex를 사용하는 곳이 있을수 있어서, 아예 글로벌로 스케일을 정해두고 사용해도 좋을것 같습니다!
// ex. common style 파일에 다음과 같이 zIndex 스케일을 정해두고, 사용시에는 z-index: ${zIndicies.global1};의 형태로 사용가능해요 !
export const zIndicies = {
global1: 900,
global2: 800,
page1: 80,
page2: 70,
page3: 60,
component1: 30,
component2: 20,
component3: 10,
negative: -10,
};
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.
상수로 관리하는 거 좋은 것 같아요!! 좋은 의견 감사해요🙏🏻
글로벌 스케일 방식 괜찮아보이는데 저희가 디자인 시스템이 없다 보니 따로 elevating guide 같은게 없어서 글로벌 스케일을 정확히 어떤 수치로 나누어 정의해야할지 조금은 모호한 부분이 있네요...
// src/constants/zIndex.ts
export const Z_INDEX = {
MODAL: 1000,
DROPDOWN: 100,
HEADER: 10,
} as const;
임의로 이렇게 구현해서 사용하는 방식으로 변경해보았어요. (0252fdc)
다음 프론트 회의 때 글로벌 스케일에 대한 부분도 같이 논의해보고 싶어요!! 🙌🏻
src/common/components/Header.tsx
Outdated
const LeftElement = styled.div` | ||
position: absolute; | ||
left: 1.5rem; | ||
`; |
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.
여기랑 RightElement에 height: "100%" 주는거 어떨까요?
여기서 줘야 leftElement 전달할 때 height 100% 사용이 가능해서요!
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.
여기에 height: 100%를 지정하지 않은 이유는 HeaderWrapper에서 각 Element를 flex align center로 중앙정렬을 해뒀기 때문이에요!!
height: 100%를 지정하게 되면 결국 자동 중앙정렬의 효과가 사라질테고, 그렇다고 각 Element에서 중앙정렬을 각각 알아서 주어야 하는 것은 반복적이고 비효율적인 작업이라고 생각했어요!! 또 Header가 현재 항상 고정된 높이를 가지기 때문에 저희가 자식 Element의 높이로 % 단위를 사용할 일이 있을까 싶기도 하구요!!
어떻게 생각하시나요?? 👀
src/common/components/Header.tsx
Outdated
return ( | ||
<HeaderWrapper aria-label="페이지 헤더"> | ||
<LeftElement>{leftElement}</LeftElement> | ||
<CenterElement>{centerElement}</CenterElement> |
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.
<CenterElement>{centerElement}</CenterElement> | |
<CenterElement as={typeof centerElement === 'string' ? 'h1' : 'div'}>{centerElement}</CenterElement> |
이렇게 지정해주면 어떨까용?
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.
오홍 emotion/styled
에서 as prop 지원하는거 첨 알았네요...! 이거 넘 좋네요 🚀🚀
3f2f03e에서 반영 완료했습니다~!
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.
src/common/components/Header.tsx
Outdated
|
||
const HeaderWrapper = styled.header({ | ||
position: "sticky", | ||
zIndex: 999, |
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.
zIndex를 상수로 관리하는 의견에 동의해요!
다른 곳에서도 zIndex를 사용하는 곳이 있을수 있어서, 아예 글로벌로 스케일을 정해두고 사용해도 좋을것 같습니다!
// ex. common style 파일에 다음과 같이 zIndex 스케일을 정해두고, 사용시에는 z-index: ${zIndicies.global1};의 형태로 사용가능해요 !
export const zIndicies = {
global1: 900,
global2: 800,
page1: 80,
page2: 70,
page3: 60,
component1: 30,
component2: 20,
component3: 10,
negative: -10,
};
src/common/components/Header.tsx
Outdated
leftElement?: ReactNode; | ||
centerElement: ReactNode; | ||
rightElement?: ReactNode; |
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.
공통컴포넌트인만큼 타입 범위를 보다 명확히 좁혀줘도 좋을것 같아요!
leftElement?: ReactNode; | |
centerElement: ReactNode; | |
rightElement?: ReactNode; | |
leftElement?: ReactElement | string ; | |
centerElement: ReactElement | string; | |
rightElement?: ReactElement | string; |
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.
두 타입 이외에 다른 타입 들어올 일 없을 것 같아서 훨 좋아보이네요!!!
9efe246에서 반영해두었습니당 😃
안녕하세요, 익숙한 이름들이 보이는 레포라 슬쩍 와서 코멘트 남기고 갑니다..
새벽에 과제하다가 머리 안돌아가서 기웃거려 봅니다 그럼 파이팅~~ |
@Brokyeom 좋은 리뷰 감사합니다 🙌🏻🙌🏻
Addon이라는 이름도 좋아보여요!! 그런데 Addon이라는 네이밍 특성상 optional한 감이 좀 있어서, required prop인 CenterElement에 적용하기에는 조금 어색하다고 느껴져요. 보통 필수 Element는 어떻게 네이밍을 하는 편인지 궁금해요!!
저는 emotion의 css prop이 runtime에 스타일이 적용되는 것으로 이해하고 있어요!! 빌드타임에 컴파일 전<div
css={{
color: "red",
}}
>
안녕
</div> 컴파일 후jsx('div', {
className: css({
color: 'red'
})
}, '안녕') 실제 |
close #7
☑️ 완료 태스크
🔎 PR 내용
Interface 설계
와이어프레임을 확인해보면 Header의 중앙 Element는 항상 존재하기 때문에 required prop으로 지정했고, left, right Element는 존재하지 않을 가능성도 있기 때문에 optional prop으로 지정했어요.
Element 배치 설계
처음에는 좌우 padding을 주고
display: flex
,justify-content: space-between
으로 배치하려고 했으나, left, right Element가 optional prop이므로, 존재하지 않게 되면 위치가 다 깨져버리는 문제가 있었어요. 그래서 optional prop이 존재하지 않는 경우도 올바른 위치를 보장하기 위해 각각 Header 내에서 절대적인 위치를 잡아주었어요. 중앙 Element는margin: 0 auto
로 중앙정렬, 좌측, 우측 Element는position: absolute
로 각각 Header 내부 좌측 우측에 고정시켜주었어요. 그 결과 optional prop이 존재하지 않는 경우도 올바른 위치를 보장하게 됩니다!!좌측 Element X
우측 Element X
좌, 우측 Element X
웹 접근성 향상을 위한 aria-label
웹 접근성 향상을 위해 다음과 같이 "페이지 헤더"라는 aria-label을 추가했어요.
Header 상단 고정
Header를 상단고정하기 위해 처음에는
position: fixed
를 사용했어요. 그러다보니 문서 흐름을 벗어나버려서 page body 부분이 Header 밑으로 깔리게 되는 문제가 있었어요.이를 해결하기 위해 페이지 공통 레이아웃의 Outlet 부분이 Header의 높이만큼 상단 margin을 갖게 하여 body 부분이 가려지지 않도록 해주었어요. 해결은 되었지만 좋은 방법이라는 생각이 들지 않았어요. 만약 Header의 height이 변경되면 그때마다 Outlet 영역의 상단 margin도 항상 sync를 맞춰주어야 하기 때문에 유지보수 측면에서 좋지 못하다고 생각했기 때문이에요. 더 나은 방법을 고민하던 중에 서현이가 알려준 대로
position: sticky
를 사용하니 별도로 상단 margin을 주지 않고도 해결되었어요.position: sticky
는 초기에 relative처럼 동작해요. 그러다가 부모 스크롤 영역 안에서 지정해준 position에 도달하면 fixed처럼 고정되는데, 이때position: fixed
처럼 문서 흐름에서 벗어나서 독립적인 레이어에서 동작하는게 아니라, 문서 흐름을 유지하면서 지정한 위치에 고정돼요. 그래서 고정이 되면서도 page body를 가리지 않게 되는 원리입니다!!🙋🏻♂️ 논의가 필요한 점
HeaderWrapper가 flex 속성까지 담당하는 방법과 HeaderWrapper 자식 컴포넌트로 Flex 컴포넌트를 위치시켜 Flex 컴포넌트에게
flex
에 관련된 속성을 위임하는 방법 중 고민했는데, depth 증가 +align="center"
를 위해 Flex 컴포넌트가 HeaderWrapper의 높이를 상속받아야 하는 것이 불필요하다고 생각해서 HeaderWrapper에서 flex 속성까지 담당하는 방법을 선택했어요. 연서 PR에서도 논의되었던 부분과 같은 결의 내용 같은데, 다음 회의때 결정될 것 같은 부분이라 임시로 이 방법을 택했다고 봐주시면 감사하겠습니다🙏🏻prop 네이밍은 다양한 프로젝트의 header 인터페이스를 참고해서 가장 general하게 사용되는 이름으로 네이밍해보았는데, 너무 길다는 생각이 든다면 언제든 더 나은 네이밍을 추천해주셔도 좋습니다!!
📷 스크린샷