일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- UI컴포넌트설계 고민
- 컴파운드패턴 연습
- 오랜만의회고
- nextjs13
- css-in-js 버그
- State
- 2번째
- RSC
- 유사이터럴객체의차이
- react-naver-map
- 함수형업데이트
- styled-component
- WIL
- props
- Promise
- prop 'className' did not match
- redux
- RCC
- 설치 및 구조파악
- 프로젝트회고
- 항해99
- 두번째포스팅
- 이미지로딩실패
- getElements
- 언어학습2일차
- 트러블슈팅
- useState
- react
- thunk정리
- til
- Today
- Total
코딩을 박터지게 죽을때까지
MIL - 사이드 프로젝트 회고 3 : UI 컴포넌트 설계 본문
프로젝트 초반에,
디자인이 자꾸 바뀌고 기획도 계속 바뀌는데, 동적스타일링을 평소대로 하다가,
색다르게 해보고 싶어져서 컴파운드 패턴을 활용하기로 했다.
모든 CSS 요소를 쪼개서, 컴파운드 패턴의 요소로 넣는다.
각 요소는 컴포넌트의 객체로 구성하여 자동완성 기능을 활용하자.
라는 방향이었다. 좀 특이한 경험이긴 하다.
장점은
1. 새로운 디자인이 생기면 아무 컴포넌트나 하나 복붙하고, 부분만 수정하여 바로 만들어낸다(생산성 향상)
2. 휴먼에러가 적다.
단점은
1. hover 같은 스타일을 지정하기가 너무 귀찮다.
디자이너가 hover를 거의 안넣긴 했는데,
이러한 방식으로 구현하니 간간히 hover가 들어갈 때 너무 귀찮았다.
const Refresh = ({ onClick, children }: InternalJSX) => {
return (
<Wrapper onClick={onClick}>
<BtnMediumLength.Default>
<BtnSize.Medium>
<BtnBg.White>
<BtnPosition.Center>
<BtnText.Medium>
<BtnTextColor.Gray>
{children}
</BtnTextColor.Gray>
</BtnText.Medium>
</BtnPosition.Center>
</BtnBg.White>
</BtnSize.Medium>
</BtnMediumLength.Default>
</Wrapper>
);
};
const Wrapper = styled(BtnRadius.Rounded)`
&:hover > ${BtnMediumLength.Default} {
> ${BtnSize.Medium} {
> ${BtnBg.White} {
background-color: ${colorSet.primary_01};
> ${BtnPosition.Center} {
> ${BtnText.Medium} {
> ${BtnTextColor.Gray} {
color: white;
}
}
}
}
}
}
`;
이와 같은 방식으로 해야했는데, 모든 버튼에 hover가 들어갔다면 매우 귀찮았을 것이다.
저렇게 직계 자식을 하나하나 거치지 않으면 내가 의도한 대로 hover가 작동하지 않는다.
처음에는 모든 하위 컴포넌트에서 style 요소를 inherit으로 전달하여
제일 바깥의 요소가 hover가 되면 제일 안쪽 요소, 즉 텍스트 까지 hover가 되는 것을 기대했다.
그러나 버튼의 윤곽부분에 마우스를 올리면, 커서가 있는 위치까지만 hover가 되고 버튼 텍스트는 그대로였다.
그러다보니 위와 같이 hover를 정의하게 된 것이다.
프로젝트가 끝난 지금, 다시 한번 새로운 방식을 고민하고 있다.
위에 적어둔 저 컴파운드 패턴과 유사한 것이 아니라,
일반적으로 내가 그동안 사용했던 라이브러리별 동적스타일링 방식 말고..
어떻게 하면 귀찮음과 속도저하를 더 빨리 줄일수 있을까.....
보통 그러지 않을까 싶긴한데,
나같은 경우에는 tailwind를 쓰든, 이모션을 쓰든, 스타일드컴포넌트를 쓰든..
다 똑같다.
시멘틱 태그가 유지보수 시, 관심사 파악에 매우 도움된다는 생각을 가지고 있어서,
시멘틱 태그의 사용목적으로 보통 as라는 프롭을 두고, 태그명을 지정하여 현업에서 사용중이다.
Chakra UI같은 경우에는 아예 as라는 프롭을 자체적으로 제공하더라.
아래 같은 경우같이 Flex를 정의한다치고, 내가 스타일링할때 자주 애용하는 것들을 기본값 넣고,
그때그때 필요한 스타일은 etc라는 prop에 정의하도록 구성한다.
export const HFlex = styled.div<{
width?: string | null,
height?: string | null,
gap?: string | null,
etc?: string | null
}>`
display: flex;
flex-direction: row;
align-items: center;
box-sizing: border-box;
width : ${({ width }) => width ? width : '100%'};
height : ${({ height }) => height ? height : '100%'};
gap : ${({ gap }) => gap ? gap : null};
${({ etc }) => etc};
`;
나는 display:flex인 경우,
즉 정렬 목적으로 이러한 컴포넌트를 네개 정도 만들고 프로젝트 내에서 재사용한다.
컴포넌트 props의 마지막에 etc라는 prop을 받는데,
미리 지정한 스타일 이외에, 사용처마다 필요한 기타사항이 있을 경우
etc라는 이름으로 style을 넘겨주며 사용했다.
이틀전에 이것저것 다른 기술들을 좀 둘러보다 보니,
emotion도 이와 비슷하게 <button css={~~} /> 식으로 스타일을 먹이는 방식이라는 것을 발견했다.
그래서 이 부분에 착안해서, styled-components로 생산성을 높이는 방식을 고안하고 있고,
현재까지의 진행상황은 아래와 같다.
function App() {
return (
<div className="App">
<Buttons.Default>기존 방식</Buttons.Default><br /><br />
<Custom.Button css={btn.default}>새로운 방식</Custom.Button><br />
<Custom.Span css={typo.HEADING_1 + `color:${color.RED}`}>타이핑</Custom.Span>
</div>
);
}
Custom.Button이 지금 새롭게 고안하는 방식이다.
Custom 객체는 아래와 같이 구성된다.
HTML Element에 따라 추가가 될 것이고, 기본으로 버튼과 span만 넣어봤다.
css라는 prop을 받아서 스타일을 정의하는 빈 컴포넌트다.
그럼 css에 들어갈 내용들을 살펴보면,
이와 같이 구성된다. 조금 정신사나워 보이기는하는데..
그 다음으로 fw 라는 객체가 정의된 파일은 아래와 같이 구성되어있다.
figma에서 디자이너가 만들어 둔 클래스를 바탕으로 이와같이 미리 데이터를 다 셋팅하고,
실제 사용하는 컴포넌트에서는 자동완성을 통해서 빠르게 ui를 사용한다.
새로운 디자인이 추가되면, 해당 사항들에 대해서 각각의 스타일을 갱신하여 조합한다.
이렇게 하면, 생산성도 챙기고, hover에 대한 정의도 간편하게 할 수 있다.
반쯤 재미로 맨 위에 적어두었던 컴파운드패턴 활용의 아쉬운점은, 좀 복잡한 느낌이다.
그래서... "모든 css 요소를 쪼개는 게 조금 오바인가.." 하는 생각을 하게 되는데,
디자이너가 미래에 어떻게 작업을 할지 알 수 없기에 저정도가 한계더라.
따라서, 미래에 예외적인 상황을 만나서 고민할 바에야
처음부터 그냥 이렇게 다 쪼개버리는게 속 시원할 거같아서 아직 판단이 잘 서지 않는다.
'React' 카테고리의 다른 글
NextJS - 3 CSS-in-JS 사용 관련 버그 (0) | 2023.07.18 |
---|---|
NextJS 공부 - 1 (1) | 2023.05.23 |
MIL - 사이드 프로젝트 회고 2 : 서비스 기획 전반 (0) | 2023.05.21 |
MIL - 사이드 프로젝트 회고 1 : 전반적인 협업흐름 (0) | 2023.05.20 |
react-naver-maps 사용 중에 발견한 이상현상 (0) | 2023.03.29 |