-
Notifications
You must be signed in to change notification settings - Fork 5
MOAMOA FE Design System
airman5573 edited this page Sep 22, 2022
·
17 revisions
모아모아의 디자인 시스템을 정립합니다.
flex와 관련된 props를 받습니다.
ex) alignItems, justifyContens 등
grid와 관련된 props를 받습니다.
ex) columns, columnGap, rows, rowGap 등
Flex와 Grid는 mediaQuery속성을 객체로 받습니다.
const Wrapper = (children, width, height, padding, margin, border ... 등의 다양한 props) => <div>{children}</div>
;
공통 컴포넌트는 자주 사용될것들로 지정합니다.
컴포넌트 개발시 props만 잘 주면 다른곳에서도 쓸 수 있을것 같을때 공통 컴포넌트로 승격시킵니다.
예를들어 컴포넌트는 아래와 같이 작성합니다.
import Button from '@components/button';
// Props를 맨 위에 둡니다
export type StudyListProps = {
children?: React.ReactNode;
variant?: 'primary' | 'secondary';
onAddButtonClick: React.MouseEventHandler<HTMLButtonElement>;
onRemoveButtonClick: React.MouseEventHandler<HTMLButtonElement>;
};
// Component는 화살표 함수로 표현하고, React.FC<Props>로 타입을 명시합니다
// - return type을 더 쉽게 강제할 수 있기 때문입니다
// - PropsWithChildren을 쓰지 않은 이유는, children이 optional로 고정되어 있기 때문입니다
// 반면 React.FC는 개발자가 사용시에 직접 컨트롤 할 수 있어 더 안정적입니다
const StudyList: React.FC<StudyListProps> = ({
children,
variant,
onAddButtonClick: handleAddButtonClick,
onRemoveButtonClick: handleRemoveButtonClick,
}) => {
return (
<Self>
<List>
<Item>리팩토링 스터디</Item>
<Item>프론트 스터디</Item>
<Item>자바 스터디</Item>
</List>
<AddButton onClick={handleAddButtonClick}>추가하기</AddButton>
<RemoveButton onClick={handleRemoveButtonClick}>삭제하기</RemoveButton>
</Self>
);
};
export default StudyList;
// styled component는 component에 같이 둡니다.
// 응집성 + 캡슐화를 위해서 필요합니다.
// 응집성 -> 위에서 바로 사용하는 컴포넌트들을 바로 아래쪽에 둡니다.
// 캡슐화 -> 이 컴포넌트에서만 사용하는 하위컴포넌트(Self, StudyList, AddStudyButton ..)들은 외부에 노출하지 않습니다.
// Self를 다른 컴포넌트에서 상속받아 사용하고 싶다면, (사용하는쪽에서 이곳의) Component를 import해서 상속 받으면 됩니다.
// 가장 바깥 컴포넌트는 Self로 명명합니다.
// 원래라면 S.StudyList라고 하는데 S를 빼고 싶은데 빼면 컴포넌트와 이름이 같아지기 때문에 Self로 명명했습니다.
const Self = styled.div`
${({ theme }) => css`
padding: ${theme.s10}; // 사이즈는 2px단위로 입력하기 때문에 theme을 활용합니다
max-width: ${theme.s250};
border: ${theme.s1} solid ${theme.color.black}; // color도 theme에서 가져옵니다
`}
`;
const List = styled.ul`
${({ theme }) => css`
padding: ${theme.s5};
margin-bottom: ${theme.s10};
`}
`;
const Item = styled.li`
${({ theme }) => css`
padding: ${theme.s2};
border-bottom: ${theme.s1};
`}
`;
type AddButtonProps = {
children: React.ReactNode;
onClick: React.MouseEventHandler<HTMLButtonElement>;
};
type RemoveButtonProps = AddButtonProps;
// 공통 컴포넌트는 이렇게 도메인에 대한 정보를 입혀서 활용합니다.
const AddButton = ({ children, onClick }: AddButtonProps) => (
<Button width={100} height={50}>
{children}
</Button>
);
// Button Props가 못받는 특수한 경우들은 상속을 받아 사용합니다
const RemoveButton = ({ children, onClick }: RemoveButtonProps) => styled.button(Button)`
transition: opacity ease 0.3s;
hover: {
opacity: 0.8;
}
`;
// Button Props의 기본 props를 넣어주면서 추가적인 CSS를 넣어주는 경우
const OpenButton = ({ children, onClick }: RemoveButtonProps) => () => {
const Component = () => <Button onClick={onClick} width={100}>{children}</Button>;
return styled(Component)`
transition: opacity ease 0.3s;
hover: {
opacity: 0.8;
}
`;
};
2px 단위로 작성합니다.