Table
대량의 데이터를 행과 열의 그리드 형식으로 정리하여 보여주는 요소입니다. 구조화된 정보를 통해 사용자가 데이터 간의 관계를 쉽게 비교하고 패턴을 파악할 수 있도록 돕습니다. 화면 너비를 확보할 수 있는 데스크톱 환경에서만 사용합니다.
대량의 데이터를 행과 열의 그리드 형식으로 정리하여 보여줍니다.
import {
Table,
TableRow,
TableHead,
TableHeadCell,
TableCell,
TableBody,
Checkbox,
ContentBadge,
} from '@wanteddev/wds';
const Demo = () => {
return (
<Table sx={{ width: '85%' }}>
<colgroup>
<col width="36px" />
<col width="auto" />
<col width="auto" />
<col width="100px" />
</colgroup>
<TableHead>
<TableRow>
<TableHeadCell>
<Checkbox size="small" />
</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<Checkbox size="small" />
</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>
<ContentBadge>
텍스트
</ContentBadge>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Checkbox size="small" />
</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>
<ContentBadge>
텍스트
</ContentBadge>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Checkbox size="small" />
</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>
<ContentBadge>
텍스트
</ContentBadge>
</TableCell>
</TableRow>
</TableBody>
</Table>
)
}
export default Demo;기본적으로 아래와 같은 구조로 사용합니다.
interaction 옵션을 통해 인터렉션을 줄 수 있습니다.
- 인터렉션 색상, opacity를 변경하고 싶을 땐
&::after스타일을 변경합니다. - interaction이 true일 때는 tabIndex를 자동으로 지정하여 키보드로 조작할 수 있게 설정합니다.
import {
Table,
TableRow,
TableHead,
TableHeadCell,
TableCell,
TableBody,
} from '@wanteddev/wds';
const Demo = () => {
return (
<Table sx={{ width: '85%' }}>
<TableHead>
<TableRow>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow interaction>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
</TableRow>
<TableRow interaction>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
</TableRow>
<TableRow interaction>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
</TableRow>
</TableBody>
</Table>
)
}
export default Demo;Pagination 컴포넌트와 함께 사용할 수 있습니다.
import {
Table,
TableRow,
TableHead,
TableHeadCell,
TableCell,
TableBody,
Pagination
} from '@wanteddev/wds';
const rows = new Array(5).fill(null)
const Demo = () => {
return (
<Table
sx={{ width: '85%' }}
pagination={(
<Pagination totalPages={1} defaultPage={1} />
)}
>
<TableHead>
<TableRow>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((_, i) => (
<TableRow key={i}>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
</TableRow>
))}
</TableBody>
</Table>
)
}
export default Demo;@tanstack/react-virtual 등을 이용하여 가상 스크롤을 적용할 수 있습니다.
가상 스크롤을 사용할 때 sticky 영역을 보존하기 위해 임의의 영역을 차지하는 TableRow를 지정해야 합니다.
import {
Table,
TableRow,
TableHead,
TableHeadCell,
TableCell,
TableBody
} from '@wanteddev/wds';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useRef } from 'react';
const rows = new Array(5000)
.fill(true)
const Demo = () => {
const ref = useRef<HTMLDivElement>(null);
const rowVirtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => ref.current,
estimateSize: () => 56,
overscan: 20,
});
const virtualRows = rowVirtualizer.getVirtualItems();
const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
const paddingBottom =
virtualRows.length > 0
? rowVirtualizer.getTotalSize() - (virtualRows?.[virtualRows.length - 1]?.end || 0)
: 0;
return (
<Table
sx={{ width: '85%' }}
sx={{
height: '400px',
['[data-radix-scroll-area-content]']: {
minHeight: `${rowVirtualizer.getTotalSize()}px`,
},
}}
viewportRef={ref}
>
<TableHead>
<TableRow>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
<TableHeadCell>제목</TableHeadCell>
</TableRow>
</TableHead>
<TableBody>
{paddingTop > 0 ? (
<TableRow>
<TableCell style={{ height: paddingTop }} />
</TableRow>
) : null}
{rowVirtualizer.getVirtualItems().map((virtualRow, index) => (
<TableRow key={virtualRow.index}>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
<TableCell>텍스트</TableCell>
</TableRow>
))}
{paddingBottom > 0 ? (
<TableRow>
<TableCell style={{ height: paddingBottom }} />
</TableRow>
) : null}
</TableBody>
</Table>
)
}
export default Demo;