Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dony] Table 컴포넌트 구현 #7

Merged
merged 18 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/playground-react/constants/icons.tsx
@@ -0,0 +1,16 @@
export const SortingIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="17"
height="14"
viewBox="0 0 17 14"
>
<path
id="다각형_3"
data-name="다각형 3"
d="M7.645,1.408a1,1,0,0,1,1.71,0l6.723,11.073A1,1,0,0,1,15.223,14H1.777a1,1,0,0,1-.855-1.519Z"
transform="translate(17 14) rotate(180)"
fill="#007aff"
/>
</svg>
);
30 changes: 30 additions & 0 deletions packages/playground-react/constants/mock.ts
@@ -0,0 +1,30 @@
export const noticeList = [
{
id: 1,
title: '스터디 가입전 해당 공지사항을 숙지해주세요.',
writer: '파크',
date: 1669750385300,
view: 101,
},
{
id: 2,
title: '스터디 전체 공지 드립니다.',
writer: '도니',
date: 1662476400000,
view: 110,
},
{
id: 3,
title: '스터디 전체 공지 드립니다.',
writer: '햄디',
date: 1662476400000,
view: 9,
},
{
id: 4,
title: '스터디 전체 공지 드립니다.',
writer: '제이미',
date: 1668750300553,
view: 9,
},
];
11 changes: 11 additions & 0 deletions packages/playground-react/helpers/table/index.ts
@@ -0,0 +1,11 @@
export const getDateForm = (date: number) => {
const dateArray = [
new Date(date).getFullYear(),
new Date(date).getMonth() + 1,
new Date(date).getDate(),
];

return dateArray
.map((number) => (number < 10 ? `0${number}` : number))
.join('.');
};
33 changes: 33 additions & 0 deletions packages/playground-react/pages/table/basic-table.tsx
@@ -0,0 +1,33 @@
import { BasicTable, Text } from '@cos-ui/react';

import { noticeList } from '@constants/mock';
import { getDateForm } from '@helpers/table';

const BasicTablePage = () => (
<BasicTable caption="test" columnsWidth={['10rem', '*', '12rem', '10rem']}>
{noticeList.map(({ id, title, writer, date, view }) => (
<BasicTable.Row key={id}>
<BasicTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{writer}
</Text>
</BasicTable.BodyCell>
<BasicTable.BodyCell>
<Text ellipsis>{title}</Text>
</BasicTable.BodyCell>
<BasicTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{getDateForm(date)}
</Text>
</BasicTable.BodyCell>
<BasicTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{view}
</Text>
</BasicTable.BodyCell>
</BasicTable.Row>
))}
</BasicTable>
);

export default BasicTablePage;
81 changes: 81 additions & 0 deletions packages/playground-react/pages/table/column-table.tsx
@@ -0,0 +1,81 @@
import { ColumnTable, Text, FlexBox } from '@cos-ui/react';

import { SortingIcon } from '@constants/icons';
import { noticeList } from '@constants/mock';
import { getDateForm } from '@helpers/table';

const sortingValues = {
writer: noticeList.map(({ writer }) => writer),
date: noticeList.map(({ date }) => date),
view: noticeList.map(({ view }) => view),
};

const ColumnTablePage = () => (
<ColumnTable
caption="공지사항"
columnsWidth={['8.5rem', '*', '12rem', '12rem', '12rem']}
sortingValues={sortingValues}
>
<ColumnTable.Row>
<ColumnTable.HeadCell>번호</ColumnTable.HeadCell>
<ColumnTable.HeadCell>
<Text as="div" sx={{ textAlign: 'left' }}>
제목
</Text>
</ColumnTable.HeadCell>
<ColumnTable.HeadCell name="writer">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
작성자
<SortingIcon />
</FlexBox>
</ColumnTable.HeadCell>
<ColumnTable.HeadCell name="date">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
날짜
<SortingIcon />
</FlexBox>
</ColumnTable.HeadCell>
<ColumnTable.HeadCell name="view">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
조회수
<SortingIcon />
</FlexBox>
</ColumnTable.HeadCell>
</ColumnTable.Row>
{noticeList.map(({ id, title, writer, date, view }) => (
<ColumnTable.Row key={id}>
<ColumnTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{id}
</Text>
</ColumnTable.BodyCell>
<ColumnTable.BodyCell>
<Text ellipsis>{title}</Text>
</ColumnTable.BodyCell>
<ColumnTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{writer}
</Text>
</ColumnTable.BodyCell>
<ColumnTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{getDateForm(date)}
</Text>
</ColumnTable.BodyCell>
<ColumnTable.BodyCell>
<Text sx={{ textAlign: 'center' }} ellipsis>
{view}
</Text>
</ColumnTable.BodyCell>
</ColumnTable.Row>
))}
</ColumnTable>
);

export default ColumnTablePage;
83 changes: 83 additions & 0 deletions packages/playground-react/pages/table/row-table.tsx
@@ -0,0 +1,83 @@
import { RowTable, Text, FlexBox } from '@cos-ui/react';

import { SortingIcon } from '@constants/icons';
import { noticeList } from '@constants/mock';
import { getDateForm } from '@helpers/table';

const sortingValues = {
writer: noticeList.map(({ writer }) => writer),
date: noticeList.map(({ date }) => date),
view: noticeList.map(({ view }) => view),
};

const RowTablePage = () => (
<RowTable
caption="공지사항"
columnsWidth={['12rem', '25%', '25%', '25%', '25%']}
sortingValues={sortingValues}
>
<RowTable.Row>
<RowTable.HeadCell>번호</RowTable.HeadCell>
{noticeList.map(({ id }) => (
<RowTable.BodyCell key={id}>
<Text ellipsis>{id}</Text>
</RowTable.BodyCell>
))}
</RowTable.Row>
<RowTable.Row>
<RowTable.HeadCell>제목</RowTable.HeadCell>
{noticeList.map(({ id, title }) => (
<RowTable.BodyCell key={id}>
<Text ellipsis>{title}</Text>
</RowTable.BodyCell>
))}
</RowTable.Row>
<RowTable.Row>
<RowTable.HeadCell name="writer">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
작성자
<SortingIcon />
</FlexBox>
</RowTable.HeadCell>
{noticeList.map(({ id, writer }) => (
<RowTable.BodyCell key={id}>
<Text ellipsis>{writer}</Text>
</RowTable.BodyCell>
))}
</RowTable.Row>
<RowTable.Row>
<RowTable.HeadCell name="date">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
날짜
<SortingIcon />
</FlexBox>
</RowTable.HeadCell>
{noticeList.map(({ id, date }) => (
<RowTable.BodyCell key={id}>
<Text ellipsis>{getDateForm(date)}</Text>
</RowTable.BodyCell>
))}
</RowTable.Row>
<RowTable.Row>
<RowTable.HeadCell name="view">
<FlexBox
sx={{ justifyContent: 'center', alignItems: 'center', gap: '1rem' }}
>
조회수
<SortingIcon />
</FlexBox>
</RowTable.HeadCell>
{noticeList.map(({ id, view }) => (
<RowTable.BodyCell key={id}>
<Text ellipsis>{view}</Text>
</RowTable.BodyCell>
))}
</RowTable.Row>
</RowTable>
);

export default RowTablePage;
18 changes: 6 additions & 12 deletions packages/playground-react/tsconfig.path.json
Expand Up @@ -2,18 +2,12 @@
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@components/*": [
"components/*"
],
"@pages/*": [
"pages/*"
],
"@styles/*": [
"styles/*"
],
"@utils/*": [
"utils/*"
]
"@components/*": ["components/*"],
"@pages/*": ["pages/*"],
"@styles/*": ["styles/*"],
"@utils/*": ["utils/*"],
"@constants/*": ["constants/*"],
"@helpers/*": ["helpers/*"]
}
}
}
58 changes: 58 additions & 0 deletions packages/primitives/src/components/Table/BasicTable.tsx
@@ -0,0 +1,58 @@
import { ReactElement, ReactNode } from 'react';

import { offscreen } from '@styles/commonStyles';

export type BasicTableProps = {
caption: string;
columnsWidth?: string[];
children: (ReactElement | ReactElement[])[];
};

const BasicTable = ({
caption,
columnsWidth,
children,
...restProps
}: BasicTableProps) => (
<table {...restProps}>
<caption css={offscreen}>{caption}</caption>
{columnsWidth && (
<colgroup>
{columnsWidth.map((width, index) => {
const pxWidth = /[0-9.]+rem/.test(width)
? `${parseFloat(width) * 10}px`
: width;
Comment on lines +21 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추후 '%, em 등의 단위도 쓸 수 있게 해주세요' 라는 요구사항이 있을 수도 있다고 생각해요
그러면 삼항연산자가 변경에 대응하기가 좋을까? 라는 생각이 들었어요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%는 사용가능합니다! em은 부모 박스의 css에 따라 상대적으로 정해지는거라 모든 부모들의 font-size를 계산해야하고 em을 width에 잘쓰지 않아서 고려해도 되지 않다고 생각했어요!
width에 자주 쓰는 px, %, rem 3가지가 가능하니 괜찮지않을까 싶습니다!

return (
// 유동적으로 변하지 않는 리스트
// eslint-disable-next-line react/no-array-index-key
<col key={index} width={pxWidth} />
);
})}
</colgroup>
)}
<tbody>{children}</tbody>
</table>
);

type RowProps = {
children: ReactElement | ReactElement[];
};

const Row = ({ children, ...restProps }: RowProps) => (
<tr {...restProps}>{children}</tr>
);

type CellProps = {
colSpan?: number;
rowSpan?: number;
children: ReactNode;
};

const Cell = ({ children, ...restProps }: CellProps) => (
<td {...restProps}>{children}</td>
);

BasicTable.Row = Row;
BasicTable.Cell = Cell;

export default BasicTable;