Tabs
Tabsは、関連するコンテンツをグループ化し、タブを切り替えることで表示内容を変更できるコンポーネントです。
<script lang="ts">
import Tabs from '$lib/components/ui/atoms/Tabs.svelte';
let tabs = [
{ id: 1, label: 'タブテキスト' },
{ id: 2, label: 'タブテキスト' },
{ id: 3, label: 'タブテキスト' },
];
</script>
<Tabs {tabs} />
プロパティ
Tabsは、以下のプロパティをサポートしています。
| 名前 | 型 | デフォルト値 | 説明 |
|---|---|---|---|
tabs |
TabsItem[] |
タブ項目の配列を渡します。 | |
currentTabId |
number | string |
現在選択されているタブのIDを指します。 |
TabsItem
TabsItemは、タブ内の情報を表すオブジェクトです。
| 名前 | 型 | デフォルト値 | 説明 |
|---|---|---|---|
id |
number | string |
タブ項目のidです。 | |
label |
string |
タブの項目名です。 | |
disabled |
boolean |
false |
タブを無効化します。操作できません。 |
インストールの手順
以下のコンポーネントのコードを、使いたいプロジェクトにコピー&ペーストします。
パスは実際のプロジェクトの構成にあわせて更新してください。
atoms/Tabs.svelte
<!--
@component
## 概要
- タブ形式のナビゲーションUIを提供するコンポーネントです
## 機能
- tabsに指定した配列からタブを動的に生成します
## Props
- tabs: タブ項目の配列
- currentTabId: 現在選択されているタブのID
## Usage
```svelte
<Tabs {tabs} />
```
-->
<script module lang="ts">
import type { ClassValue } from 'svelte/elements';
import { cva, type VariantProps } from 'class-variance-authority';
export const tabsVariants = cva('relative px-3 py-1.5 leading-normal text-sm font-medium outline-primary transition-colors cursor-pointer hover:bg-base-container-accent/90 focus-visible:outline-[0.125rem] focus-visible:outline-offset-[0.125rem]', {
variants: {
/** 現在のタブかどうか */
current: {
true: ['text-base-foreground-default'],
false: ['text-base-foreground-muted'],
},
/** 操作できるかどうか */
disabled: {
true: ['opacity-50 pointer-events-none'],
false: [],
},
},
});
export type TabsVariants = VariantProps<typeof tabsVariants>;
export interface TabsProps extends TabsVariants {
/** クラス */
class?: ClassValue;
/** タブ項目の配列 */
tabs: TabsItem[];
/** タブが選択されたときのハンドラ */
onChange?: (tab: TabsItem) => void;
/** 現在選択されているタブのID */
currentTabId?: number | string;
}
export interface TabsItem {
/** タブ項目のID */
id: number | string;
/** タブの項目名 */
label: string;
/** 操作できるかどうか */
disabled?: boolean;
}
</script>
<script lang="ts">
import { quintOut } from 'svelte/easing';
import { crossfade } from 'svelte/transition';
let { class: className, tabs, onChange, currentTabId = tabs[0].id }: TabsProps = $props();
const [send, receive] = crossfade({
duration: 300,
easing: quintOut,
});
function onChangeTab(tab: TabsItem) {
if (tab.disabled) return;
currentTabId = tab.id;
onChange?.(tab);
}
</script>
<div class={[className, 'flex items-center']}>
{#each tabs as tab}
<button class={tabsVariants({ current: currentTabId === tab.id, disabled: tab.disabled })} disabled={tab.disabled} onclick={() => onChangeTab(tab)}>
{tab.label}
{#if currentTabId === tab.id}
<span class="absolute bottom-0 left-0 w-full h-0.5 bg-primary" in:receive={{ key: 'floating' }} out:send={{ key: 'floating' }}></span>
{/if}
</button>
{/each}
</div>
使い方
<script lang="ts">
import Tabs from '$lib/components/ui/atoms/Tabs.svelte';
let tabs = [
{ id: 1, label: 'タブテキスト' },
{ id: 2, label: 'タブテキスト' },
{ id: 3, label: 'タブテキスト' },
];
</script>
<Tabs {tabs} />
サンプル
Default
特に操作が行われていない、デフォルトの状態です。
<script lang="ts">
import Tabs from '$lib/components/ui/atoms/Tabs.svelte';
let tabs = [
{ id: 1, label: 'タブテキスト' },
{ id: 2, label: 'タブテキスト' },
{ id: 3, label: 'タブテキスト' },
];
</script>
<Tabs {tabs} />
Current
currentTabIdを指定することで、任意のタブを選択状態にすることも可能です。
<script lang="ts">
import Tabs from '$lib/components/ui/atoms/Tabs.svelte';
let tabs = [
{ id: 1, label: 'タブテキスト' },
{ id: 2, label: 'タブテキスト' },
{ id: 3, label: 'タブテキスト' },
];
</script>
<Tabs {tabs} currentTabId={tabs[1].id} />
Disabled
利用不可の状態です。
<script lang="ts">
import Tabs from '$lib/components/ui/atoms/Tabs.svelte';
let tabs = [
{ id: 1, label: 'タブテキスト', disabled: false },
{ id: 2, label: 'タブテキスト', disabled: true },
{ id: 3, label: 'タブテキスト', disabled: false },
];
</script>
<Tabs {tabs} />