Card
Cardは、コンテンツを整理し、視覚的にグループ化するためのコンポーネントです。
<script lang="ts">
import Card from '$lib/components/ui/atoms/Card.svelte';
</script>
<Card>
<div class="flex items-center justify-center w-56 h-48">
<p class="leading-normal text-sm text-base-foreground-muted">ここに要素が入ります。</p>
</div>
</Card>
インストールの手順
以下のコンポーネントのコードを、使いたいプロジェクトにコピー&ペーストします。
パスは実際のプロジェクトの構成にあわせて更新します。
atoms/Card.svelte
<!--
@component
## 概要
- 情報をグループ化して表示するためのコンポーネントです
## 機能
- 枠線でグループ化して表示することができます
- 任意のコンテンツを配置できます
## Usage
```svelte
<Card>
<p>カードの中身</p>
</Card>
```
-->
<script module lang="ts">
import type { Snippet } from 'svelte';
import type { ClassValue } from 'svelte/elements';
import { cva, type VariantProps } from 'class-variance-authority';
export const cardVariants = cva('flex flex-col gap-6 p-6 border border-base-stroke-default rounded-lg shadow-xs');
export type CardVariants = VariantProps<typeof cardVariants>;
export interface CardProps extends CardVariants {
/** クラス */
class?: ClassValue;
children?: Snippet<[]>;
}
</script>
<script lang="ts">
let { class: className, children }: CardProps = $props();
let cardVariantsClass = $derived(cardVariants({ class: className }));
</script>
<div class={cardVariantsClass}>
{@render children?.()}
</div>
使い方
<script lang="ts">
import Card from '$lib/components/ui/atoms/Card.svelte';
</script>
<Card>
<img class="w-full h-auto rounded-md" src="/images/sample.png" alt="">
<div>
<h2 class="leading-tight text-2xl font-semibold mb-2">タイトル</h2>
<p class="leading-normal text-sm text-base-foreground-muted">ここに補足文が入ります。</p>
</div>
</Card>
サンプル
Image
画像を使ったサンプルです。
<script lang="ts">
import Card from '$lib/components/ui/atoms/Card.svelte';
</script>
<Card>
<img class="w-full h-auto rounded-md" src="/images/sample.png" alt="">
<div>
<h2 class="leading-tight text-2xl font-semibold mb-2">タイトル</h2>
<p class="leading-normal text-sm text-base-foreground-muted">ここに補足文が入ります。</p>
</div>
</Card>
Form
入力要素を使ったサンプルです。
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
import Checkbox from '$lib/components/ui/atoms/Checkbox.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Label from '$lib/components/ui/atoms/Label.svelte';
import Select from '$lib/components/ui/atoms/Select.svelte';
let options = [
{ label: '選択肢1', value: 'item1' },
{ label: '選択肢2', value: 'item2' },
{ label: '選択肢3', value: 'item3' },
];
let value = $state('');
let group = $state([]);
</script>
<Card>
<form class="flex flex-col gap-6" onsubmit={(e) => e.preventDefault()}>
<div class="leading-tight text-2xl font-semibold w-80">タイトル</div>
<div class="flex flex-col gap-4">
<div>
<Label class="mb-1.5" for="input">ラベル</Label>
<p class="text-base-foreground-muted mb-2">ここに補足文が入ります。</p>
<Input id="input" placeholder="プレースホルダー" />
</div>
<div>
<Label class="mb-1.5" for="select">ラベル</Label>
<Select id="select" {options} placeholder="プレースホルダー" bind:value={value} />
</div>
<div>
<Label class="mb-1.5">ラベル</Label>
<p class="text-base-foreground-muted mb-2">ここに補足文が入ります。</p>
<div class="grid gap-2">
<Label class="!flex items-center gap-2">
<Checkbox value="item1" bind:group />選択肢1
</Label>
<Label class="!flex items-center gap-2">
<Checkbox value="item2" bind:group />選択肢2
</Label>
<Label class="!flex items-center gap-2">
<Checkbox value="item3" bind:group />選択肢3
</Label>
</div>
</div>
</div>
<div class="flex justify-end w-full gap-2">
<Button variant="secondary" tone="solid" size="small">ボタン</Button>
<Button variant="primary" tone="solid" size="small">ボタン</Button>
</div>
</form>
</Card>
List
リストを使ったサンプルです。
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
let infoCards = Array(3).fill({
img: '/images/sample.png',
label: 'ラベル',
description: 'ここに補足文が入ります。',
});
</script>
<Card>
<form class="flex flex-col gap-6" onsubmit={(e) => e.preventDefault()}>
<div class="w-80">
<h2 class="leading-tight text-2xl font-semibold mb-2">タイトル</h2>
<p class="leading-normal text-sm text-base-foreground-muted font-regular">ここに補足文が入ります。</p>
</div>
<div>
{#each infoCards as infoCard}
<div class="flex items-center gap-2 mb-4 last:mb-0">
<img class="w-10 h-10 rounded-full" src={infoCard.img} alt="">
<div>
<p class="leading-tight text-base-foreground-default text-sm font-medium">{infoCard.label}</p>
<p class="leading-normal text-base-foreground-muted text-sm font-regular">{infoCard.description}</p>
</div>
</div>
{/each}
</div>
<div class="w-full flex justify-end gap-2">
<Button variant="secondary" tone="solid" size="small">ボタン</Button>
<Button variant="primary" tone="solid" size="small">ボタン</Button>
</div>
</form>
</Card>