Table
Tableコンポーネントを使用したサンプルです。
ChipやButtonなどのコンポーネントと組み合わせて、さまざまなデータに適したテーブルを作成できます。
MemberManagement
メンバー一覧の表示に使うテーブルです。
table/member-management is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Table from '$lib/components/ui/atoms/Table.svelte';
import TableData from '$lib/components/ui/atoms/TableData.svelte';
import TableHead from '$lib/components/ui/atoms/TableHead.svelte';
import { MoreHorizontal } from '@lucide/svelte';
const columnItems = [
{ label: '', type: 'image', class: 'w-20' },
{ label: 'メンバー', key: 'name' },
{ label: 'メールアドレス', key: 'email' },
{ label: '権限', key: 'role' },
{ label: '', type: 'button', class: 'w-17' },
];
const members = [
{ name: '佐藤 太郎', email: 'rabeeui@example.com', role: '管理者', image: '/images/sample.png' },
{ name: '佐藤 太郎', email: 'rabeeui@example.com', role: 'メンバー', image: '/images/sample.png' },
{ name: '佐藤 太郎', email: 'rabeeui@example.com', role: 'メンバー', image: '/images/sample.png' },
{ name: '佐藤 太郎', email: 'rabeeui@example.com', role: 'メンバー', image: '/images/sample.png' },
{ name: '佐藤 太郎', email: 'rabeeui@example.com', role: 'メンバー', image: '/images/sample.png' },
];
</script>
<div class="flex flex-col justify-center w-full h-screen p-6 overflow-y-auto">
<div class="min-w-3xl border border-border bg-surface rounded-md overflow-hidden">
<Table class="w-full">
<thead class="border-b border-border">
<tr class="transition-colors hover:bg-accent/40">
{#each columnItems as item}
<TableHead class={['text-nowrap', item.class]} size="small">
{item.label}
</TableHead>
{/each}
</tr>
</thead>
<tbody class="divide-y divide-border">
{#each members as member}
<tr class="transition-colors hover:bg-accent/40">
{#each columnItems as item}
<TableData class={[item.class]}>
{#if item.type === 'image'}
<img class="size-12 rounded-full object-cover" src={member.image} alt={member.name} />
{:else if item.type === 'button'}
<Button size="small" variant="secondary" tone="ghost" isSquare>
<MoreHorizontal size="1rem" />
</Button>
{:else if item.key}
{member[item.key]}
{/if}
</TableData>
{/each}
</tr>
{/each}
</tbody>
</Table>
</div>
</div>
依存コンポーネント
上記のサンプルを使うときは、以下のコンポーネントもダウンロードが必要です。
DataTable
様々なデータの表示に使うテーブルです。
table/data-table is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Pagination from '$lib/components/ui/atoms/Pagination.svelte';
import Table from '$lib/components/ui/atoms/Table.svelte';
import TableData from '$lib/components/ui/atoms/TableData.svelte';
import TableHead from '$lib/components/ui/atoms/TableHead.svelte';
import { ArrowUpDownIcon, Pencil, Plus, Search } from '@lucide/svelte';
let headItems = ['ID', '画像', '名前', '価格', '在庫数', 'ステータス', '編集'];
let allDataItems = Array.from({ length: 50 }, (_, i) => {
const id = String(i + 1).padStart(3, '0');
const name = `アイテム${i + 1}`;
const status = i % 3 === 2 ? '非公開' : '公開';
return [id, '/images/sample.png', name, '1,000円', '10', status, ''];
});
let currentPage = $state(1);
const ROWS_LENGTH = 5;
let tableRows = $derived.by(() => {
return allDataItems.slice(
(currentPage - 1) * ROWS_LENGTH,
currentPage * ROWS_LENGTH,
);
});
function handleChangePage(page: number) {
currentPage = page;
}
function handleSearchSubmit(event: Event) {
event.preventDefault();
}
</script>
<div class="flex flex-col justify-center min-w-3xl w-full h-screen p-6 bg-surface overflow-y-auto">
<form class="flex flex-col" onsubmit={handleSearchSubmit}>
<div class="w-80 font-semibold leading-tight text-xl mb-1">アイテム一覧</div>
<div class="flex flex-col mb-4">
<p class="text-muted-foreground text-sm mb-2">ショップで販売するアイテムを登録・編集・削除できます。</p>
<div class="flex">
<Input id="text" class="w-full" inputClass="!w-80" placeholder="ID・名前で検索">
{#snippet startContent()}
<Search class="text-muted-foreground pointer-events-none" size="1rem" />
{/snippet}
</Input>
<Button class="break-keep">
<Plus size="1rem" />
アイテム登録
</Button>
</div>
</div>
</form>
<Table class="min-w-3xl">
<thead class="border-b border-border">
<tr class="break-keep transition-colors hover:bg-accent/40">
{#each headItems as item, index}
{#if index === 5}
<TableHead class="text-nowrap transition-colors cursor-pointer hover:bg-accent/90" size="small">
<div class="flex items-center gap-2">
{item}
<ArrowUpDownIcon class="text-muted-foreground" size="1rem" />
</div>
</TableHead>
{:else}
<TableHead class={`text-nowrap ${index === 2 ? 'w-2/3' : 'w-1/6'}`} size="small">
<div class="flex items-center gap-2">
{item}
</div>
</TableHead>
{/if}
{/each}
</tr>
</thead>
<tbody class="border-b border-border divide-border divide-y">
{#each tableRows as tableRow}
<tr class="break-keep transition-colors hover:bg-accent/40">
{#each tableRow as column, index}
<TableData>
{#if index === 1}
<img class="w-12 rounded-md" src={column} alt="" />
{:else if index === tableRow.length - 1}
<Button size="medium" variant="secondary" tone="ghost" isSquare>
<Pencil size="1rem" />
</Button>
{:else}
{column}
{/if}
</TableData>
{/each}
</tr>
{/each}
</tbody>
</Table>
<div class="flex items-center justify-between p-4 bg-muted/10 border-b border-border">
<div class="text-muted-foreground text-sm">
キャプション
</div>
<Pagination class="!gap-0" maxPage={Math.ceil(allDataItems.length / ROWS_LENGTH)} {currentPage} onChangePage={handleChangePage} />
</div>
</div>
依存コンポーネント
上記のサンプルを使うときは、以下のコンポーネントもダウンロードが必要です。
FormListTable
フォーム一覧の表示に使うテーブルです。
table/form-list-table is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Chip from '$lib/components/ui/atoms/Chip.svelte';
import Table from '$lib/components/ui/atoms/Table.svelte';
import TableData from '$lib/components/ui/atoms/TableData.svelte';
import TableHead from '$lib/components/ui/atoms/TableHead.svelte';
import { Pencil } from '@lucide/svelte';
const columnItems = [
{ label: 'タイトル', key: 'title', class: 'w-2/3' },
{ label: '公開状態', key: 'status', type: 'chip' },
{ label: '作成日', key: 'date' },
{ label: '回答数', key: 'count' },
{ label: '', type: 'button' },
{ label: '', type: 'icon' },
];
const dataItems = [
{ title: 'フォームのタイトル', status: 'チップ', date: '2026/01/01', count: '100' },
{ title: 'フォームのタイトル', status: 'チップ', date: '2026/01/01', count: '100' },
{ title: 'フォームのタイトル', status: 'チップ', date: '2026/01/01', count: '100' },
{ title: 'フォームのタイトル', status: 'チップ', date: '2026/01/01', count: '100' },
{ title: 'フォームのタイトル', status: 'チップ', date: '2026/01/01', count: '100' },
];
</script>
<div class="flex flex-col justify-center w-full h-screen p-6 overflow-y-auto">
<div class="min-w-3xl border border-border bg-surface rounded-md overflow-hidden">
<Table>
<thead class="border-b border-border">
<tr class="transition-colors hover:bg-accent/40">
{#each columnItems as item}
<TableHead class={['text-nowrap', item.class]} size="small">{item.label}</TableHead>
{/each}
</tr>
</thead>
<tbody>
{#each dataItems as data}
<tr class="transition-colors hover:bg-accent/40">
{#each columnItems as item}
<TableData size="small">
{#if item.type === 'chip' && item.key}
<Chip class="shrink-0 text-nowrap" tone="filled">
{data[item.key]}
</Chip>
{:else if item.type === 'button'}
<Button class="text-nowrap" size="small" variant="secondary" tone="solid">回答一覧</Button>
{:else if item.type === 'icon'}
<Button size="small" variant="secondary" tone="ghost" isSquare>
<Pencil size="1rem" />
</Button>
{:else if item.key}
{data[item.key]}
{/if}
</TableData>
{/each}
</tr>
{/each}
</tbody>
</Table>
</div>
</div>
依存コンポーネント
上記のサンプルを使うときは、以下のコンポーネントもダウンロードが必要です。