일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- test
- javascript
- Chakra
- Gin
- typescript
- React
- go
- css
- 티스토리챌린지
- tanstackquery
- backend
- ReactHooks
- component
- JavaSpring
- Redux
- satisfiles
- java
- JPA
- hook
- frontend
- springboot
- storybook
- 오블완
- designpatterns
- react-hook-form
- Spring
- RTK
- golang
- 웹애플리케이션서버
- Today
- Total
bkdragon's log
CSS 프레임워크로 atomic design pattern 적용하기 본문
팀프로젝트에서 atomic design pattern을 적용해 진행하고 있다. CSS 프레임워크를 사용하여 atomic design pattern을 적용한 경험을 공유하려고 한다. css 프레임워크는 Chakra ui를 사용했다.
CRA로 앱을 설치할 때 Charka ui도 함께 설치할 수 있다.
npx create-react-app my-app --template @chakra-ui/typescript
atomic pattern
atomic pattern은 화학적 관점에서 영감을 얻은 디자인 시스템이다.
출처 : https://atomicdesign.bradfrost.com/chapter-2/#the-part-and-the-whole
각 단계를 간략하게 설명하면 다음과 같다.
- Atoms(원자) : 분해할 수 없는 최소 단위의 컴포넌트 (ex. Button, Input)
- Molecules(분자) : 두개 이상의 Atoms를 결합하여 한가지 일을 하는 컴포넌트 (ex. SearchBar, Item)
- Organisms(유기체) : Atoms + Molecules 를 조합해서 서비스에서 표현될 수 있는 명확한 영역을 가지는 컴포넌트 ( ex. Header, Contents, Section)
- Templates : 비어있는 페이지
- Pages : 페이지!
Molecules와 Organisms
분자와 유기체의 구분이 애매할 수 있다. 내 생각에 분자는 UI/UX 요소에 가까운 개념이고 유기체는 Layout에 가까운 개념이다. 그리고 분자는 재사용하기 좋고 유기체는 재사용보다는 완성된 형태를 띈다.
몇가지 예를 들어보면,
- Input : 단순하게 Input만 있다면 Atoms이지만 Button과 함께 짝일 이뤄 어떠한 작업을 하게 된다면 Molecules
- Item : 특정 Item을 보여주는 Layout (table 형태가 될수도, flex, grid 형태가 될수도 있는) 임으로 Organisms 다만 style을 props를 통해 넘겨줄 수 있어서 재사용성을 높게 만든다면 Molecules로도 볼 수 있을 것 같다. 그리고 이부분은 CSS 프레임워크가 쉽게 해준다.
- ItemList : Organisms가 모여있으니 Organisms
- Form : Form 자체는 양식 제출이라는 작업에 중점이 있으니 Molecules로 생각할 수 있지만 LoginForm 과 같이 어떤 목적을 위해 완성된 형태가 필요해지면 Organisms
나라면 이렇게 판단할 것 같다. 근데 사실 이건 팀에서 정하기 마련이다.
컴포넌트 재사용성 UP
위에 특정 Item을 보여주는 컴포넌트를 Organisms로 해석했지만 스타일을 유동적으로 하여 Molecules도 볼 수 있을 것 같다고 언급을 했다.
import { BoxProps , Box} from '@chakra-ui/react';
const Item : React.FC<BoxProps> = (props) => {
return (
<Box {...props}></Box>
)
}
이런 상태를 말한 것이였다. BoxProps를 Props의 타입으로 지정함으로 Item 컴포넌트를 사용할 때 스타일을 직접 지정해서 변경할 수 있다. 이러면 grid 형태이든 flex 형태이든 자유롭게 스타일링이 가능하다. 이렇게 사용한다면 Molecules로 볼 수 있을 것 같다는 말이였다. 이 방법으로 Atoms의 재사용성도 높힐 수 있다.
근데 보여주려는 요소마다 내부 내용이 변하기에 이렇게 사용하긴 쉽진 않을 것 같다.
Templates와 Pages
템플릿은 비어있는 페이지이다. 그래서 처음에 생각했던 것은 페이지에서 템플릿으로 데이터를 Props로 보내는 형태를 생각했다. 마치 Container-Presenter 패턴처럼 말이다. 데이터 뿐만 아니라 스타일링과 관련된 것도 전부 넘겨지는 (다만 기본값은 가지고 있는) 형태로 작성을 했더니..
return (
<AppTemplate
main={{
advice: {
style: {},
advice: data?.advice,
id: data?.slip_id,
handleChangeAdvice: () => refetchAdviceData(),
},
form: {
button: {
children: '등록',
type: 'submit',
},
form: {
handleSubmit,
},
input: {
type: 'text',
placeholder: '할 일',
width: 300,
},
},
completes,
todos: {
item: todos,
handler: {
handleCheckBox,
handleDelete: handleComplete,
},
},
}}
nav={{}}
/>
);
};
페이지 컴포넌트의 jsx 부분이 이런 식으로 작성이 되었다. 너무 복잡해보여서 좋지 않다고 생각된다.
그래서 Organisms를 좀 더 활용하기로 했다. Organisms 부터는 재사용하기 어려운 특성도 있고 유기체의 뜻을 보니 “생활 기능을 가지고 있는 조직체” 였다! 이러면 핸들링 함수나 데이터를 가지고 있는게 이상하지도 않다고 느껴져서 Organisms로 옮겼다.
Templates는 단순하게 현재 페이지에 필요한 요소들을 모아두는 역할을 하고 스타일만 Pages를 통해 제공받는 형태로 사용하게 됐다.
pages/index.tsx
const Index = () => {
return <MainTemplate display="flex" flexDirection="row" alinItems="center" />;
};
export default Index;
templates/mainTemplate.tsx
const MainTemplate: React.FC<Props> = (props) => {
return (
<Box {...props}>
<Header />
<ItemList />;
<Footer />
</Box>
);
};
export default MainTemplate;
organisms/ItemList.tsx
const ReservationList = () => {
const navigate = useNavigation();
const data = getData();
const onClick = (id: number) => {
navigate(`/reservation/${id}`);
};
return (
<Table display={'flex'} flexDirection={'column'}>
{data?.map((item, index) => (
<Item
key={item?.id}
index={index + 1}
onClick={onClick}
{...item}
/>
))}
</Table>
);
};
페이지는 템플릿에 스타일을 주입하고 유기체는 자체적으로 데이터와 핸들링 함수를 지닌다.
결론
CSS 프레임워크를 사용해서 재사용성이 높은 Atoms와 Molecules를 작성하고 이를 조합해 만든 Oranisms가 비지니스 로직을 담당하며 Templates는 스타일 변경이 가능한 Pages!
여기까지가 나의 결론이다. 일단 현재는 그러하고 생각이 언제든 바뀔 수 있다. 의견 중에 하나로 봐주면 좋을 것 같다. 앞서 언급했듯 팀에서 정할 문제이다
'concept' 카테고리의 다른 글
에러 헨들링에 관하여 (0) | 2024.06.14 |
---|---|
변신하는 Form (1) | 2023.10.18 |
[Redux-toolkit] 비동기 처리하기 (0) | 2023.09.01 |
flex-item (0) | 2023.08.30 |
MVVM 패턴 (0) | 2023.08.10 |