Skip to content

Commit 26105dd

Browse files
authored
Merge pull request #72 from COW-dev/feat/#68-table
[FEAT] Table 컴포넌트 제작
2 parents fd860d0 + 27a99fe commit 26105dd

File tree

9 files changed

+195
-0
lines changed

9 files changed

+195
-0
lines changed

src/shared/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export { TextArea } from './ui/TextArea';
2727
export { Tooltip } from './ui/Tooltip';
2828
export { Title1, Title2, Title3, Caption1, Body1, Body2, Body3 } from './ui/Typography';
2929
export { Header, NavigationItem, MenuContainer, Menu, MenuTrigger, MenuItem } from './ui/Header';
30+
export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/Table';
3031

3132
export { Icons, iconNames } from './ui/assets';
3233
export type { IconName } from './ui/assets';
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { Meta, StoryObj } from '@storybook/react';
2+
3+
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from './index';
4+
5+
const PrimitiveMeta = {
6+
title: 'Components/Table',
7+
component: Table,
8+
tags: ['autodocs'],
9+
parameters: {
10+
docs: {
11+
description: {
12+
component: '기본적인 Table 레이아웃 구성 요소 세트입니다. ',
13+
},
14+
},
15+
},
16+
} satisfies Meta<typeof Table>;
17+
export default PrimitiveMeta;
18+
19+
const data = [
20+
{
21+
scoreCategory: '동아리 활동 보고서',
22+
reason: '2회차 활동보고서',
23+
amount: 4.615,
24+
createdAt: '2025-03-31 15:42:26',
25+
},
26+
{
27+
scoreCategory: '동아리 활동 보고서',
28+
reason: '2회차 활동보고서',
29+
amount: 0.001,
30+
createdAt: '2025-03-31 16:02:31',
31+
},
32+
{
33+
scoreCategory: '전동대회',
34+
reason: '3월 전동대회 참여',
35+
amount: 1.0,
36+
createdAt: '2025-04-01 11:40:36',
37+
},
38+
{
39+
scoreCategory: '전동대회',
40+
reason: '4월 전동대회 참여',
41+
amount: 1.0,
42+
createdAt: '2025-04-28 19:44:04',
43+
},
44+
{
45+
scoreCategory: '동아리 활동 보고서',
46+
reason: '3회차 활동보고서',
47+
amount: 4.615,
48+
createdAt: '2025-04-30 14:56:26',
49+
},
50+
];
51+
52+
export const Basic: StoryObj<typeof PrimitiveMeta> = {
53+
render: () => (
54+
<Table>
55+
<TableHeader>
56+
<TableRow>
57+
<TableHead>날짜</TableHead>
58+
<TableHead>카테고리</TableHead>
59+
<TableHead>점수</TableHead>
60+
</TableRow>
61+
</TableHeader>
62+
<TableBody>
63+
{data.map((row, i) => (
64+
<TableRow key={i}>
65+
<TableCell>{row.createdAt}</TableCell>
66+
<TableCell>{row.scoreCategory}</TableCell>
67+
<TableCell>{row.amount.toFixed(3)}</TableCell>
68+
</TableRow>
69+
))}
70+
</TableBody>
71+
</Table>
72+
),
73+
};

src/shared/ui/Table/Table.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
export type Props = React.HTMLAttributes<HTMLTableElement> & {
6+
/**
7+
* Optional custom className for additional styling.
8+
*/
9+
className?: string;
10+
11+
/**
12+
* Table content, usually composed of `<TableHeader>`, `<TableBody>`, etc.
13+
*/
14+
children?: React.ReactNode;
15+
};
16+
export function Table({ className, children, ...props }: Props) {
17+
return (
18+
<div
19+
className={cn('no-scrollbar relative w-full overflow-auto rounded-md border border-gray-100')}
20+
>
21+
<table className={cn('w-full table-fixed border-collapse text-sm', className)} {...props}>
22+
{children}
23+
</table>
24+
</div>
25+
);
26+
}

src/shared/ui/Table/TableBody.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
export type Props = React.HTMLAttributes<HTMLTableSectionElement> & {
6+
className?: string;
7+
children?: React.ReactNode;
8+
};
9+
10+
export function TableBody({ className, children, ...props }: Props) {
11+
return (
12+
<tbody className={cn('bg-white', className)} {...props}>
13+
{children}
14+
</tbody>
15+
);
16+
}

src/shared/ui/Table/TableCell.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
import { Body2 } from '../Typography';
6+
7+
export type Props = React.TdHTMLAttributes<HTMLTableCellElement> & {
8+
className?: string;
9+
children?: React.ReactNode;
10+
};
11+
12+
export function TableCell({ className, children, ...props }: Props) {
13+
return (
14+
<td className={cn('px-4 py-2 align-middle md:px-4', className)} {...props}>
15+
<Body2 className="whitespace-pre-wrap text-gray-400" weight="normal">
16+
{children}
17+
</Body2>
18+
</td>
19+
);
20+
}

src/shared/ui/Table/TableHead.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
import { Body2 } from '../Typography';
6+
7+
export type Props = React.ThHTMLAttributes<HTMLTableCellElement> & {
8+
className?: string;
9+
children?: React.ReactNode;
10+
};
11+
12+
export function TableHead({ className, children, ...props }: Props) {
13+
return (
14+
<th
15+
className={cn('h-10 px-4 py-2 text-left align-middle whitespace-nowrap', className)}
16+
{...props}
17+
>
18+
<Body2 className="text-gray-700">{children}</Body2>
19+
</th>
20+
);
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
export type Props = React.HTMLAttributes<HTMLTableSectionElement> & {
6+
className?: string;
7+
children?: React.ReactNode;
8+
};
9+
10+
export function TableHeader({ className, children, ...props }: Props) {
11+
return (
12+
<thead className={cn('bg-gray-50', className)} {...props}>
13+
{children}
14+
</thead>
15+
);
16+
}

src/shared/ui/Table/TableRow.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@/shared/lib/core';
4+
5+
export type Props = React.HTMLAttributes<HTMLTableRowElement> & {
6+
className?: string;
7+
children?: React.ReactNode;
8+
};
9+
10+
export function TableRow({ className, children, ...props }: Props) {
11+
return (
12+
<tr className={cn('border-b border-gray-200 last:border-0', className)} {...props}>
13+
{children}
14+
</tr>
15+
);
16+
}

src/shared/ui/Table/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export { Table } from './Table';
2+
export { TableHeader } from './TableHeader';
3+
export { TableBody } from './TableBody';
4+
export { TableRow } from './TableRow';
5+
export { TableHead } from './TableHead';
6+
export { TableCell } from './TableCell';

0 commit comments

Comments
 (0)