SW 엘리스 2차 프로젝트에서 Style 코드에 관해 고민했던 지점들
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
fontSize: {
title: string;
subTitle: string;
small: string;
};
colors: {
main: string;
emphasis: string;
cancel: string;
button: string;
sub: string;
background: string;
innerContainer: string;
container: string;
gray: string;
lightGray: string;
};
font: {
color: {
black: string;
darkGray: string;
white: string;
description: string;
subTitle: string;
};
size: {
normal: string;
containerTitle: string;
};
};
}
}
모듈을 바탕으로 theme의 프로퍼티들을 정의한다.
import { DefaultTheme } from 'styled-components';
const theme: DefaultTheme = {
fontSize: {
title: '18px',
subTitle: '14px',
small: '10px',
},
colors: {
main: '#E59A59',
emphasis: '#712E1E',
cancel: '#A82A1E',
button: '#E59A59',
sub: '#FFD5AF',
background: '#FFFAF5',
innerContainer: '#f7f7f7',
container: '#FCF3EB',
gray: '#888870',
lightGray: '#C9CACC',
},
font: {
color: {
black: '#1E1F21',
darkGray: '#303030',
white: '#ffffff',
description: '#5e5f61',
subTitle: '#424140',
},
size: {
normal: '14px',
containerTitle: '18px',
},
},
};
export default theme;
color: ${({ theme }) => theme.colors.main};
export const FlexContainer = styled.div`
display: flex;
align-items: center;
justify-content: space-around;
`; // 공용 FlexContainer
export const ContentContainer = styled(FlexContainer)`
flex-direction: column;
width: 60vw;
justify-content: flex-start;
margin-bottom: 70px;
`; // 컴포넌트 확장
type MenuCardProps = {
width: string;
padding?: string;
margin?: string;
flex?: string;
};
export const MenuCard = styled(Card)<MenuCardProps>`
width: ${(props) => props.width};
padding: ${(props) => props.padding};
margin: ${(props) => props.margin};
font-size: ${({ theme }) => theme.fontSize.subTitle};
flex: ${(props) => props.flex};
p {
margin-bottom: 20px;
}
`; //재사용가능한 컴포넌트 정의
//Content.tsx
import * as S from '../styles/contentStyle'; // style코드를 import
return (
<S.ContentContainer>
<S.TitleContainer>
<S.Title>
{shop.name}({shop.category})
</S.Title>
{!gathering && !isJoined && (
<S.LikeButton
variant="contained"
onClick={handleClick}
sx={{
fontSize: '20px',
marginRight: '30px',
}}>{`모임 생성`}</S.LikeButton>
)}
{gathering && !isJoined && (
<S.LikeButton
variant="contained"
onClick={() => clickJoinButton(currentParty?.partyId as number)}
sx={{
fontSize: '20px',
marginRight: '30px',
}}>{`모임 참여`}</S.LikeButton>
)}
{isJoined && <p>참여중</p>}
</S.TitleContainer>
<S.MenuContainer>
<S.MenuCard width={'20vw'} padding="20px" margin="20px" flex="2">
<p className="description">{shop.description}</p>
<p>{`거리 : 걸어서 ${shop.distance}분 거리`}</p>
<S.ATag href={`${BASE_URL}${shop.address}`} target="_blank" rel="noreferrer">
지도 보기
</S.ATag>
</S.MenuCard>
<S.SelectContainer>
<SelectTags type={'모집인원'} value={partyLimit} setValue={setpartyLimit} />
</S.SelectContainer>
</S.MenuContainer>
</S.ContentContainer>
);
ref)