Table
Tableは、データを行と列で構造化して表示する際に使用されるコンポーネントです。
データを比較・分析しやすくするために設計されており、ヘッダー、行、列などの要素を含みます。
<script lang="ts">
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';
let headItems = ['テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド'];
let dataItems = [
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
];
let colspan = $derived(headItems.length - 1);
</script>
<Table class="min-w-xl">
<thead>
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each headItems as item}
<TableHead size="small">{item}</TableHead>
{/each}
</tr>
</thead>
<tbody>
{#each dataItems as data}
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each data as item}
<TableData size="small">{item}</TableData>
{/each}
</tr>
{/each}
</tbody>
<tfoot>
<tr class="bg-base-container-muted/10">
<TableData size="small" {colspan}>合計</TableData>
<TableData size="small">テーブルデータ</TableData>
</tr>
</tfoot>
</Table>
プロパティ
Tableは、以下のプロパティをサポートしています。
TableHead.TableHeadProps
| 名前 | 型 | デフォルト値 | 説明 |
|---|---|---|---|
size |
boolean |
medium |
thのサイズを指定します。small, medium, large のいずれかを選択できます。 |
TableData.TableDataProps
| 名前 | 型 | デフォルト値 | 説明 |
|---|---|---|---|
size |
boolean |
medium |
tdのサイズを指定します。small, medium, large のいずれかを選択できます。 |
インストールの手順
以下のコンポーネントのコードを、使いたいプロジェクトにコピー&ペーストします。
パスは実際のプロジェクトの構成にあわせて更新します。
atoms/Table.svelte
<!--
@component
## 概要
- tableタグと同様に表形式のデータを表示するための汎用的なテーブルコンポーネントです
## 機能
- tableタグと同様に行・列で構造化されたデータを表示可能です
- 任意のテーブル要素(`<thead>`, `<tbody>`, `<tr>` など)を自由に記述可能です
## Usage
```svelte
<Table>
<tr>などを自由に記載
</Table>
```
-->
<script module lang="ts">
import type { Snippet } from 'svelte';
import type { ClassValue, HTMLTableAttributes } from 'svelte/elements';
export interface TableProps extends HTMLTableAttributes {
/** クラス */
class?: ClassValue;
children?: Snippet<[]>;
}
</script>
<script lang="ts">
let { class: className, children, ...tableAttributes }: TableProps = $props();
</script>
<table class={className} {...tableAttributes}>
{@render children?.()}
</table>
atoms/TableHead.svelte
<!--
@component
## 概要
- thタグのように、テーブルのヘッダーセルを表す汎用的なコンポーネントです
## 機能
- thタグとして動作し、テーブルのヘッダーセルとして使用できます
## Props
- size: セルのサイズを指定できます
## Usage
```svelte
<Table>
<tbody>
<tr>
<TableHead size="s">テーブルデータ</TableHead>
</tr>
</tbody>
</Table>
```
-->
<script module lang="ts">
import type { Snippet } from 'svelte';
import type { ClassValue, HTMLThAttributes } from 'svelte/elements';
import { cva, type VariantProps } from 'class-variance-authority';
export const tableHeadVariants = cva('px-4 py-1 text-left font-medium text-base-foreground-muted text-sm/tight transition-colors', {
variants: {
/** セルのサイズ */
size: {
small: ['h-12'],
medium: ['h-18'],
large: ['h-24'],
},
},
defaultVariants: {
size: 'medium',
},
});
export type TableVariants = VariantProps<typeof tableHeadVariants>;
export interface TableHeadProps extends TableVariants, HTMLThAttributes {
/** クラス */
class?: ClassValue;
children?: Snippet<[]>;
}
</script>
<script lang="ts">
let { size, children, class: className, ...thAttributes }: TableHeadProps = $props();
let thVariantClass = $derived(tableHeadVariants({ size, class: className }));
</script>
<th class={thVariantClass} {...thAttributes}>
{@render children?.()}
</th>
atoms/TableData.svelte
<!--
@component
## 概要
- tdタグのようにテーブルのセルを表す汎用的なコンポーネントです
## 機能
- tdタグのように機能し、内容をスロットで柔軟に挿入できます
- セルのサイズを指定したり複数列にまたがるセルを指定するためのPropsが追加されています(詳細はPropsセクションを参照)
## Props
- size: セルのサイズを指定できます
## Usage
```svelte
<Table>
<tbody>
<tr>
<TableData size="s">テーブルデータ</TableData>
</tr>
</tbody>
</Table>
```
-->
<script module lang="ts">
import type { Snippet } from 'svelte';
import type { ClassValue, HTMLTdAttributes } from 'svelte/elements';
import { cva, type VariantProps } from 'class-variance-authority';
export const tableDateVariants = cva('px-4 py-1 text-base-foreground-default text-sm/normal transition-colors', {
variants: {
/** セルのサイズ */
size: {
small: ['h-12'],
medium: ['h-18'],
large: ['h-24'],
},
},
defaultVariants: {
size: 'medium',
},
});
export type TableVariants = VariantProps<typeof tableDateVariants>;
export interface TableDataProps extends TableVariants, HTMLTdAttributes {
/** クラス */
class?: ClassValue;
children?: Snippet<[]>;
}
</script>
<script lang="ts">
let { size, class: className, children, ...tdAttributes }: TableDataProps = $props();
let tdVariantClass = $derived(tableDateVariants({ size, class: className }));
</script>
<td class={tdVariantClass} {...tdAttributes}>
{@render children?.()}
</td>
使い方
<script lang="ts">
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';
let headItems = ['テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド'];
let dataItems = [
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
];
let colspan = $derived(headItems.length - 1);
</script>
<Table class="min-w-xl">
<thead>
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each headItems as item}
<TableHead size="small">{item}</TableHead>
{/each}
</tr>
</thead>
<tbody>
{#each dataItems as data}
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each data as item}
<TableData size="small">{item}</TableData>
{/each}
</tr>
{/each}
</tbody>
<tfoot>
<tr class="bg-base-container-muted/10">
<TableData size="small" {colspan}>合計</TableData>
<TableData size="small">テーブルデータ</TableData>
</tr>
</tfoot>
</Table>
サンプル
Default
特に操作が行われていない、デフォルトの状態です。
<script lang="ts">
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';
let headItems = ['テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド'];
let dataItems = [
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
['テーブルデータ', 'テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
];
let colspan = $derived(headItems.length - 1);
</script>
<Table class="min-w-xl">
<thead>
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each headItems as item}
<TableHead size="small">{item}</TableHead>
{/each}
</tr>
</thead>
<tbody>
{#each dataItems as data}
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each data as item}
<TableData size="small">{item}</TableData>
{/each}
</tr>
{/each}
</tbody>
<tfoot>
<tr class="bg-base-container-muted/10">
<TableData size="small" {colspan}>合計</TableData>
<TableData size="small">テーブルデータ</TableData>
</tr>
</tfoot>
</Table>
UseComponent
セル内にボタンやアイコンなどの他のコンポーネントを配置して、よりリッチなテーブルを作成することも可能です。
<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';
let headItems = ['テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド', 'テーブルヘッド'];
let dataItems = [
{
actionLabel: 'ボタン',
items: ['テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
},
{
actionLabel: 'ボタン',
items: ['テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
},
{
actionLabel: 'ボタン',
items: ['テーブルデータ', 'テーブルデータ', 'テーブルデータ'],
},
];
let colspan = $derived(headItems.length - 1);
</script>
<Table class="min-w-xl">
<thead>
<tr class="transition-colors hover:bg-base-container-accent/40">
{#each headItems as item}
<TableHead size="small">{item}</TableHead>
{/each}
</tr>
</thead>
<tbody>
{#each dataItems as data}
<tr class="transition-colors hover:bg-base-container-accent/40">
<TableData size="small">
<Button size="small" class="font-normal">{data.actionLabel}</Button>
</TableData>
{#each data.items as item}
<TableData size="small">{item}</TableData>
{/each}
</tr>
{/each}
</tbody>
<tfoot>
<tr class="bg-base-container-muted/10">
<TableData size="small" {colspan}>合計</TableData>
<TableData size="small">テーブルデータ</TableData>
</tr>
</tfoot>
</Table>