アクション付きデータテーブルActionDataTableExperimental
行選択、一括操作、行操作を組み合わせたデータテーブルです。
プレビュー
1 - 10 / 全300件
1 / 30
0選択中
| 行操作 | |||||
|---|---|---|---|---|---|
| 春の新生活バナー | 青井 花 | 公開中 | 2026-05-28 | ||
| アプリ訴求 LP | 田中 空 | 下書き | 2026-05-27 | ||
| 法人向け資料広告 | 山本 優 | 公開中 | 2026-05-26 | ||
| 旧キャンペーン素材 | 小林 真央 | 保管済み | 2026-05-25 | ||
| 展示会フォロー | 中村 蓮 | 下書き | 2026-05-24 | ||
| 採用サイト告知 | 佐藤 葵 | 公開中 | 2026-05-23 | ||
| 店舗向け予約導線 | 伊藤 陽 | 公開中 | 2026-05-22 | ||
| 夏季キャンペーン | 高橋 澪 | 下書き | 2026-05-21 | ||
| 資料請求リターゲティング | 渡辺 凛 | 公開中 | 2026-05-20 | ||
| 法人向けメール施策 | 加藤 蒼 | 保管済み | 2026-05-19 |
状態とバリエーション
選択と一括操作
行を選択すると一括操作が有効になり、未選択時は理由をツールチップで説明します。
1 - 10 / 全300件
1 / 30
0選択中
| 行操作 | |||||
|---|---|---|---|---|---|
| 春の新生活バナー | 青井 花 | 公開中 | 2026-05-28 | ||
| アプリ訴求 LP | 田中 空 | 下書き | 2026-05-27 | ||
| 法人向け資料広告 | 山本 優 | 公開中 | 2026-05-26 | ||
| 旧キャンペーン素材 | 小林 真央 | 保管済み | 2026-05-25 | ||
| 展示会フォロー | 中村 蓮 | 下書き | 2026-05-24 | ||
| 採用サイト告知 | 佐藤 葵 | 公開中 | 2026-05-23 | ||
| 店舗向け予約導線 | 伊藤 陽 | 公開中 | 2026-05-22 | ||
| 夏季キャンペーン | 高橋 澪 | 下書き | 2026-05-21 | ||
| 資料請求リターゲティング | 渡辺 凛 | 公開中 | 2026-05-20 | ||
| 法人向けメール施策 | 加藤 蒼 | 保管済み | 2026-05-19 |
行操作
各行の操作は右端に固定し、無効な行操作は理由をツールチップで表示します。
1 - 10 / 全300件
1 / 30
0選択中
| 行操作 | |||||
|---|---|---|---|---|---|
| 春の新生活バナー | 青井 花 | 公開中 | 2026-05-28 | ||
| アプリ訴求 LP | 田中 空 | 下書き | 2026-05-27 | ||
| 法人向け資料広告 | 山本 優 | 公開中 | 2026-05-26 | ||
| 旧キャンペーン素材 | 小林 真央 | 保管済み | 2026-05-25 | ||
| 展示会フォロー | 中村 蓮 | 下書き | 2026-05-24 | ||
| 採用サイト告知 | 佐藤 葵 | 公開中 | 2026-05-23 | ||
| 店舗向け予約導線 | 伊藤 陽 | 公開中 | 2026-05-22 | ||
| 夏季キャンペーン | 高橋 澪 | 下書き | 2026-05-21 | ||
| 資料請求リターゲティング | 渡辺 凛 | 公開中 | 2026-05-20 | ||
| 法人向けメール施策 | 加藤 蒼 | 保管済み | 2026-05-19 |
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| columns | ColumnDef<TData, TValue>[] | - | 表示列です。選択列と行操作列は ActionDataTable が追加します。 |
| data | TData[] | - | 表示する行データです。 |
| getRowId | (row: TData, index: number) => string | - | 選択状態を維持するための安定した行 ID を返します。 |
| getRowLabel | (row: TData, index: number) => string | - | 行選択チェックボックスのアクセシブル名に使うラベルです。 |
| enableSelection | boolean | true | 行選択列を表示するかどうかです。 |
| rowActions | ActionDataTableRowAction<TData>[] | - | 各行の右端に表示する操作です。無効理由はツールチップで説明します。 |
| bulkActions | ActionDataTableBulkAction<TData>[] | - | 選択行に対して実行する一括操作です。 |
| labels | ActionDataTableLabels | - | DataTable の文言に加えて、選択・一括操作・行操作の文言を差し替えます。 |
使い方
"use client"
import * as React from "react"
import type { ColumnDef } from "@tanstack/react-table"
import { IconArchive, IconPencil, IconTrash } from "@tabler/icons-react"
import { ActionDataTable, Badge, type ActionDataTableLabels } from "@gunjo/ui"
type Campaign = {
id: string
name: string
owner: string
status: "active" | "draft" | "archived"
updatedAt: string
}
const campaigns: Campaign[] = [
{ id: "c-001", name: "春の新生活バナー", owner: "青井 花", status: "active", updatedAt: "2026-05-12" },
{ id: "c-002", name: "アプリ訴求 LP", owner: "田中 空", status: "draft", updatedAt: "2026-05-10" },
{ id: "c-003", name: "法人向け資料広告", owner: "山本 優", status: "active", updatedAt: "2026-05-08" },
{ id: "c-004", name: "旧キャンペーン素材", owner: "小林 真央", status: "archived", updatedAt: "2026-04-28" },
{ id: "c-005", name: "展示会フォロー", owner: "中村 蓮", status: "draft", updatedAt: "2026-04-25" },
]
const statusLabels: Record<Campaign["status"], string> = {
active: "公開中",
draft: "下書き",
archived: "保管済み",
}
const statusVariants: Record<Campaign["status"], "default" | "secondary" | "outline"> = {
active: "default",
draft: "secondary",
archived: "outline",
}
const columns: ColumnDef<Campaign>[] = [
{
accessorKey: "name",
header: "キャンペーン",
size: 280,
cell: ({ row }) => <span className="font-medium">{row.original.name}</span>,
},
{ accessorKey: "owner", header: "担当者", size: 128 },
{
accessorKey: "status",
header: "状態",
size: 112,
cell: ({ row }) => {
const status = row.original.status
return <Badge variant={statusVariants[status]}>{statusLabels[status]}</Badge>
},
},
{ accessorKey: "updatedAt", header: "更新日", size: 120 },
]
const labels: ActionDataTableLabels = {
filterPlaceholder: "キャンペーン名で絞り込み...",
noResults: "該当するキャンペーンがありません。",
previous: "前へ",
next: "次へ",
rowsPerPage: "表示件数",
selectedRows: (count) => count + "件を選択中",
selectedRowsLabel: "選択中",
selectAllRows: "すべての行を選択します",
selectRow: (label) => label + "を選択します",
selectAllRowsSelected: "すべての選択を外します",
selectRowSelected: (label) => label + "の選択を外します",
clearSelection: "選択を解除",
actions: "行操作",
bulkActions: "一括操作",
bulkActionPlaceholder: "一括操作",
disabledAction: "行を選択すると操作できます",
}
export function CampaignTable() {
const [rows, setRows] = React.useState(campaigns)
const archiveRows = (selectedRows: Campaign[]) => {
const selectedIds = new Set(selectedRows.map((row) => row.id))
setRows((current) =>
current.map((row) =>
selectedIds.has(row.id)
? { ...row, status: "archived", updatedAt: "2026-05-22" }
: row
)
)
}
const deleteRows = (selectedRows: Campaign[]) => {
const selectedIds = new Set(selectedRows.map((row) => row.id))
setRows((current) => current.filter((row) => !selectedIds.has(row.id)))
}
return (
<ActionDataTable
columns={columns}
data={rows}
filter={{ columnId: "name", placeholder: labels.filterPlaceholder }}
labels={labels}
getRowId={(row) => row.id}
getRowLabel={(row) => row.name}
rowActions={[
{
id: "edit",
label: "編集",
icon: IconPencil,
onSelect: (row) => window.alert(row.name + "を編集します"),
},
{
id: "archive",
label: "保管",
icon: IconArchive,
disabled: (row) => row.status === "archived",
disabledReason: "すでに保管済みです",
onSelect: (row) => archiveRows([row]),
},
{
id: "delete",
label: "削除",
icon: IconTrash,
variant: "destructive",
disabled: (row) => row.status === "archived",
disabledReason: "保管済みの行はこの画面から削除できません",
onSelect: (row) => deleteRows([row]),
},
]}
bulkActions={[
{
id: "archive",
label: "保管",
icon: IconArchive,
disabledReason: "行を選択すると保管できます",
onSelect: archiveRows,
},
{
id: "delete",
label: "削除",
icon: IconTrash,
variant: "destructive",
disabledReason: "行を選択すると削除できます",
onSelect: deleteRows,
},
]}
/>
)
}