266 lines
8.6 KiB
TypeScript
266 lines
8.6 KiB
TypeScript
import type { Meta, StoryObj } from '@storybook/react'
|
|
import { useState } from 'react'
|
|
import { Table } from './Table'
|
|
|
|
const meta = {
|
|
title: 'Components/Table',
|
|
component: Table,
|
|
args: {
|
|
children: null
|
|
},
|
|
argTypes: {
|
|
isLayoutFixed: { control: 'boolean' },
|
|
isFullHeight: { control: 'boolean' },
|
|
isHoverable: { control: 'boolean' },
|
|
isClickable: { control: 'boolean' },
|
|
},
|
|
} satisfies Meta<typeof Table>
|
|
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
const sampleData = [
|
|
{ id: 1, name: '홍길동', email: 'hong@example.com', role: '관리자' },
|
|
{ id: 2, name: '김철수', email: 'kim@example.com', role: '사용자' },
|
|
{ id: 3, name: '이영희', email: 'lee@example.com', role: '사용자' },
|
|
{ id: 4, name: '박민수', email: 'park@example.com', role: '편집자' },
|
|
{ id: 5, name: '최지은', email: 'choi@example.com', role: '사용자' },
|
|
]
|
|
|
|
export const Default: Story = {
|
|
render: () => (
|
|
<div className="h-80">
|
|
<Table>
|
|
<Table.Caption>
|
|
<Table.CaptionLeft>
|
|
<Table.Total count={sampleData.length} />
|
|
</Table.CaptionLeft>
|
|
</Table.Caption>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col width={100} />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center">ID</Table.HeaderCell>
|
|
<Table.HeaderCell>이름</Table.HeaderCell>
|
|
<Table.HeaderCell>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell align="center">역할</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
{sampleData.map((row) => (
|
|
<Table.Row key={row.id}>
|
|
<Table.Cell align="center">{row.id}</Table.Cell>
|
|
<Table.Cell>{row.name}</Table.Cell>
|
|
<Table.Cell>{row.email}</Table.Cell>
|
|
<Table.Cell align="center">{row.role}</Table.Cell>
|
|
</Table.Row>
|
|
))}
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
),
|
|
}
|
|
|
|
export const Empty: Story = {
|
|
render: () => (
|
|
<div className="h-60">
|
|
<Table>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col width={100} />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center">ID</Table.HeaderCell>
|
|
<Table.HeaderCell>이름</Table.HeaderCell>
|
|
<Table.HeaderCell>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell align="center">역할</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
<Table.Empty colSpan={4} />
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
),
|
|
}
|
|
|
|
export const Loading: Story = {
|
|
render: () => (
|
|
<div className="h-60">
|
|
<Table>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col width={100} />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center">ID</Table.HeaderCell>
|
|
<Table.HeaderCell>이름</Table.HeaderCell>
|
|
<Table.HeaderCell>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell align="center">역할</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
<Table.Loading colSpan={4} />
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
),
|
|
}
|
|
|
|
export const Selectable: Story = {
|
|
render: function Render() {
|
|
const [selectedId, setSelectedId] = useState<number | null>(null)
|
|
return (
|
|
<div className="h-80">
|
|
<Table>
|
|
<Table.Caption>
|
|
<Table.CaptionLeft>
|
|
<Table.Total count={sampleData.length} />
|
|
{selectedId && (
|
|
<span className="text-sm text-primary">선택: {selectedId}</span>
|
|
)}
|
|
</Table.CaptionLeft>
|
|
</Table.Caption>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col width={100} />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center">ID</Table.HeaderCell>
|
|
<Table.HeaderCell>이름</Table.HeaderCell>
|
|
<Table.HeaderCell>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell align="center">역할</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
{sampleData.map((row) => (
|
|
<Table.Row
|
|
key={row.id}
|
|
isSelected={selectedId === row.id}
|
|
onClick={() => setSelectedId(row.id)}
|
|
>
|
|
<Table.Cell align="center">{row.id}</Table.Cell>
|
|
<Table.Cell>{row.name}</Table.Cell>
|
|
<Table.Cell>{row.email}</Table.Cell>
|
|
<Table.Cell align="center">{row.role}</Table.Cell>
|
|
</Table.Row>
|
|
))}
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
)
|
|
},
|
|
}
|
|
|
|
export const GroupedHeader: Story = {
|
|
render: () => (
|
|
<div className="h-80">
|
|
<Table>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center" rowSpan={2}>ID</Table.HeaderCell>
|
|
<Table.HeaderCell rowSpan={2}>이름</Table.HeaderCell>
|
|
<Table.HeaderCell align="center" colSpan={2} isGroupTitle>연락처</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell isGroupChild>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell isGroupChild>전화번호</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
<Table.Row>
|
|
<Table.Cell align="center">1</Table.Cell>
|
|
<Table.Cell>홍길동</Table.Cell>
|
|
<Table.Cell>hong@example.com</Table.Cell>
|
|
<Table.Cell>010-1234-5678</Table.Cell>
|
|
</Table.Row>
|
|
<Table.Row>
|
|
<Table.Cell align="center">2</Table.Cell>
|
|
<Table.Cell>김철수</Table.Cell>
|
|
<Table.Cell>kim@example.com</Table.Cell>
|
|
<Table.Cell>010-9876-5432</Table.Cell>
|
|
</Table.Row>
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
),
|
|
}
|
|
|
|
export const ManyRows: Story = {
|
|
render: () => {
|
|
const manyData = Array.from({ length: 50 }, (_, i) => ({
|
|
id: i + 1,
|
|
name: `사용자 ${i + 1}`,
|
|
email: `user${i + 1}@example.com`,
|
|
role: i % 3 === 0 ? '관리자' : '사용자',
|
|
}))
|
|
|
|
return (
|
|
<div className="h-96">
|
|
<Table>
|
|
<Table.Caption>
|
|
<Table.CaptionLeft>
|
|
<Table.Total count={manyData.length} />
|
|
</Table.CaptionLeft>
|
|
</Table.Caption>
|
|
<Table.Container>
|
|
<Table.Colgroup>
|
|
<Table.Col width={60} />
|
|
<Table.Col width={120} />
|
|
<Table.Col />
|
|
<Table.Col width={100} />
|
|
</Table.Colgroup>
|
|
<Table.Header>
|
|
<Table.HeaderRow>
|
|
<Table.HeaderCell align="center">ID</Table.HeaderCell>
|
|
<Table.HeaderCell>이름</Table.HeaderCell>
|
|
<Table.HeaderCell>이메일</Table.HeaderCell>
|
|
<Table.HeaderCell align="center">역할</Table.HeaderCell>
|
|
</Table.HeaderRow>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
{manyData.map((row) => (
|
|
<Table.Row key={row.id}>
|
|
<Table.Cell align="center">{row.id}</Table.Cell>
|
|
<Table.Cell>{row.name}</Table.Cell>
|
|
<Table.Cell>{row.email}</Table.Cell>
|
|
<Table.Cell align="center">{row.role}</Table.Cell>
|
|
</Table.Row>
|
|
))}
|
|
</Table.Body>
|
|
</Table.Container>
|
|
</Table>
|
|
</div>
|
|
)
|
|
},
|
|
}
|