Table
データをテーブル形式で表示するコンポーネント。ソート機能と行選択機能をサポートします。
基本的な使い方
Preview
Name | Email | Role |
|---|---|---|
| Alice | alice@example.com | Admin |
| Bob | bob@example.com | User |
| Charlie | charlie@example.com | User |
ソート機能
コールバックベースの設計により、親コンポーネントでソート状態を管理できます。
Preview
ソート機能の実装例(インタラクティブデモは実装アプリケーション側で確認してください)
行選択
useTable フックを使用して行選択機能を実装できます。
import { Table, useTable } from '@codeconnect-llc/design-system'
export function SelectableTable() { const { selectedRows, toggleRowSelection } = useTable()
const columns = [ { key: 'name', label: 'Name' }, { key: 'email', label: 'Email' }, ]
const data = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }, ]
return ( <Table> <Table.Head columns={columns} /> <Table.Body columns={columns} data={data} rowKey={(row) => row.id} onRowClick={(row) => toggleRowSelection(row.id)} selectedRows={selectedRows} /> </Table> )}カスタムレンダリング
render 関数を使用してセルの内容をカスタマイズできます。
const columns = [ { key: 'name', label: 'Name' }, { key: 'status', label: 'Status', render: (value) => ( <Badge variant={value === 'active' ? 'success' : 'default'}> {value} </Badge> ), },]Props
Table
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 追加のCSSクラス |
children | ReactNode | - | Table.Head, Table.Body などのサブコンポーネント |
Table.Head
| Prop | Type | Default | Description |
|---|---|---|---|
columns | TableColumn<T>[] | - | カラム定義の配列 |
className | string | - | 追加のCSSクラス |
Table.Body
| Prop | Type | Default | Description |
|---|---|---|---|
columns | TableColumn<T>[] | - | カラム定義の配列 |
data | T[] | - | 表示するデータの配列 |
rowKey | (row: T, index: number) => string | number | - | 行の一意なキーを生成する関数 |
onRowClick | (row: T, index: number) => void | - | 行クリック時のコールバック |
selectedRows | Set<string | number> | - | 選択中の行のキーのセット |
className | string | - | 追加のCSSクラス |
TableColumn
| Prop | Type | Default | Description |
|---|---|---|---|
key | keyof T | - | データオブジェクトのキー |
label | ReactNode | - | カラムのラベル |
onSort | () => void | - | ソートコールバック(指定するとソートアイコンが表示される) |
sortDirection | 'asc' | 'desc' | - | ソート方向 |
render | (value: T[keyof T], row: T) => ReactNode | - | カスタムレンダリング関数 |
className | string | - | カラムに適用するCSSクラス |
useTable
行選択機能を提供するカスタムフック。
戻り値:
| Property | Type | Description |
|---|---|---|
selectedRows | Set<string | number> | 選択中の行のキーのセット |
toggleRowSelection | (key: string | number) => void | 行の選択状態を切り替える |
toggleAllRows | (allKeys: (string | number)[]) => void | すべての行の選択状態を切り替える |
clearSelection | () => void | 選択をクリア |
isRowSelected | (key: string | number) => boolean | 行が選択されているか確認 |
アクセシビリティ
- セマンティックな
<table>,<thead>,<tbody>要素を使用 - ソート可能なカラムはクリック可能であることを視覚的に示す
- 選択可能な行は
data-state属性で状態を管理 - キーボードナビゲーション対応
設計思想
Tableコンポーネントは状態を持たない設計になっています。ソート状態や選択状態は親コンポーネントで管理し、コールバックとプロパティを通じて制御します。これにより、柔軟性とテスト容易性を確保しています。
使用例
import { Table, useTable } from '@codeconnect-llc/design-system'import { useState } from 'react'
interface User { id: number name: string email: string role: string}
export function UserTable() { const [sortKey, setSortKey] = useState<keyof User>('name') const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc') const { selectedRows, toggleRowSelection } = useTable()
const users: User[] = [ { id: 1, name: 'Alice', email: 'alice@example.com', role: 'Admin' }, { id: 2, name: 'Bob', email: 'bob@example.com', role: 'User' }, { id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'User' }, ]
const handleSort = (key: keyof User) => { if (sortKey === key) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc') } else { setSortKey(key) setSortDirection('asc') } }
const sortedUsers = [...users].sort((a, b) => { const aVal = a[sortKey] const bVal = b[sortKey] const order = sortDirection === 'asc' ? 1 : -1 return aVal > bVal ? order : -order })
const columns = [ { key: 'name' as keyof User, label: 'Name', onSort: () => handleSort('name'), sortDirection: sortKey === 'name' ? sortDirection : undefined, }, { key: 'email' as keyof User, label: 'Email', onSort: () => handleSort('email'), sortDirection: sortKey === 'email' ? sortDirection : undefined, }, { key: 'role' as keyof User, label: 'Role', }, ]
return ( <Table> <Table.Caption>User List</Table.Caption> <Table.Head columns={columns} /> <Table.Body columns={columns} data={sortedUsers} rowKey={(row) => row.id} onRowClick={(row) => toggleRowSelection(row.id)} selectedRows={selectedRows} /> </Table> )}