React | 반응형 테이블을 만들어보자..
테이블처럼 보이지만
<table/>
은 사용하지 않는다..
결과물
데스크탑에서는 이렇게 보이고,
모바일에서는 이렇게 되도록 만들거다.
원하는 거..
- 제목 셀은 항상 존재하고 제목 셀의 넓이는 항상 일정하다.
- 모바일에서는 제목, 내용 한 쌍이 무조건 한 열을 다 차지한다.
- 한 열에 두 개 혹은 네 개의 셀이 들어갈 수 있다.
컴포넌트 만들기..
Table
: 테이블 전체를 감싸는 divTableRow
: 한 열을 감싸는 divTableCell
: 제목 + 내용으로 이루어진 한 쌍
일단 styled-components
를 사용하기 떄문에 스타일을 정의할 파일을 하나 생성한다.
// Table.styled.js
import styled from 'styled-components';
export const StyledTable = styled.div`
`;
export const StyledTableRow = styled.div`
`;
export const StyledTh = styled.div`
`;
export const StyledTd = styled.div`
`;
Table
Table
컴포넌트는 전체 테이블 내용을 감싸는 컴포넌트 children
만 props로 받아 감싸주면 끝
// Table.js
import { StyledTable } from './Table.styled';
const Table = ({ children }) => {
return <StyledTable>{children}</StyledTable>;
};
export default Table;
css는 대충 원하는대로 해주면 된다.. display: flex; flex-dirction: column;
이 필수
//Table.styled.js
export const StyledTable = styled.div`
padding: 1rem;
background: #fff;
border-radius: 1rem;
display: flex;
flex-direction: column;
`;
TableRow
TableRow
는 한 열이 된다. 테이블 셀을 감싸주는 컴포넌트.
// TableRow.js
import { StyledTableRow } from './Table.styled';
const TableRow = ({ children }) => {
return <StyledTableRow>{children}</StyledTableRow>;
};
export default TableRow;
display: flex;
를 주어 셀들이 가로 방향으로 나열되도록 설정..
//Table.styled.js
export const StyledTableRow = styled.div`
display: flex;
flex-wrap: wrap;
`;
TableCell
TableCell
은 제목과 내용의 한 쌍으로 이루어진다.
//TableCell.js
import { StyledTh, StyledTd } from './Table.styled';
const TableCell = ({ title, value }) => {
return (
<>
<StyledTh>{title}</StyledTh>
<StyledTd>{value}</StyledTd>
</>
);
};
export default TableCell;
display: flex; align-items: center;
는 항상 내용이 세로 중심에 위치하도록 하기 위한 설정이다.
여기서 중요한건 flex: 0 0 10rem; width: 10rem;
설정..flex-basis
값을 10rem으로 주고, width
를 10rem으로 주면 항상 제목 셀의 넓이가 일정하게 유지된다.
내용 셀(StyledTd)은 flex: 1;
을 주어 제목셀 제외 남은 공간을 다 차지하도록 한다.
//Table.styled.js
export const StyledTh = styled.div`
display: flex;
align-items: center;
flex: 0 0 10rem;
width: 10rem;
color: ${({ theme }) => theme.gray};
background: #c3c7d926;
font-weight: 600;
padding: 1rem;
word-break: keep-all;
`;
export const StyledTd = styled.div`
display: flex;
align-items: center;
padding: 1rem;
flex: 1;
word-break: keep-all;
`;
모바일 css
TableCell
부분만 미디어쿼리를 사용하면 된다..flex
설정을 이용해서 셀들이 밑으로 붙도록..?
export const StyledTh = styled.div`
display: flex;
align-items: center;
flex: 0 0 10rem;
width: 10rem;
color: ${({ theme }) => theme.gray};
background: #c3c7d926;
font-weight: 600;
padding: 1rem;
word-break: keep-all;
@media (max-width: ${({ theme }) => theme.mobile}) {
padding: 0.8rem;
flex: 1 1 37%;
}
`;
export const StyledTd = styled.div`
display: flex;
align-items: center;
padding: 1rem;
flex: 1;
word-break: keep-all;
@media (max-width: ${({ theme }) => theme.mobile}) {
padding: 0.8rem;
flex: 1 1 63%;
}
`;
border설정
border
가 생각보다 까다로웠다.. 왜냐면나는바보라서...TableRow
에 fist-child
설정을 이용해서 border값을 준다. 무조건 첫 번째 열은 border-top
을 설정
export const StyledTableRow = styled.div`
display: flex;
flex-wrap: wrap;
&:first-child {
border-top: 1px solid ${({ theme }) => theme.lightGray};
}
`;
그리고 TableCell
은 이제 미디어쿼리랑도 조합해야 함..
export const StyledTh = styled.div`
/* 생략 */
border-bottom: 1px solid ${({ theme }) => theme.lightGray};
&:first-child {
border-left: 1px solid ${({ theme }) => theme.lightGray};
}
@media (max-width: ${({ theme }) => theme.mobile}) {
padding: 0.8rem;
flex: 1 1 37%;
border-left: 1px solid ${({ theme }) => theme.lightGray};
}
`;
export const StyledTd = styled.div`
/* 생략 */
border-left: 1px solid ${({ theme }) => theme.lightGray};
border-right: 1px solid ${({ theme }) => theme.lightGray};
border-bottom: 1px solid ${({ theme }) => theme.lightGray};
word-break: keep-all;
@media (max-width: ${({ theme }) => theme.mobile}) {
padding: 0.8rem;
flex: 1 1 63%;
}
`;
끝..