2026.05.27 リリースしました

確認する

Pricing

Pricing は、料金プランをカードで並べて表示するサンプルです。

pricing/default is coming soon.

インストールの手順

以下のコードを、使いたいプロジェクトにコピー&ペーストします。
パスは実際のプロジェクトの構成にあわせて更新します。

pricing/default is coming soon.

PricingCard

atoms/PricingCard.svelte
        <!--
@component
## 概要
- 料金プランの情報をカード形式で表示するためのコンポーネントです
- mostPopular を true にすることで、強調スタイルで表示できます

## 機能
- プラン名・価格・機能リスト・ラベルリストなどをカードにまとめて表示します
- 見た目を変更するためのいくつかのスタイル用Propsが追加されています(詳細はPropsセクションを参照)

## Props
- plan: プランデータをオブジェクトとして指定します
  - name: プラン名を指定します
  - description: プランの説明文を指定します
  - price: 価格を指定します(例: ¥980)
  - caption: 価格の補足テキストを指定します(例: 1ユーザーあたり月額)
  - mostPopular: true にするとプライマリカラーのボーダーとシャドウで強調スタイルになります
  - features: 機能リストを指定します(enabled が false のものはグレーアウトされます)
  - labels: ラベルリストを指定します
- button: CTAボタンを描画する snippet を指定します

## Usage
```svelte
<PricingCard {plan}>
  {#snippet button()}
    <Button class="w-full" variant="primary" tone="solid" size="small">このプランではじめる</Button>
  {/snippet}
</PricingCard>
```
-->

<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 pricingCardVariants = cva('flex flex-col overflow-hidden rounded-lg border bg-surface', {
    variants: {
      /** 強調スタイルにするか */
      mostPopular: {
        true: 'border-primary shadow-md',
        false: 'border-border',
      },
    },
    defaultVariants: {
      mostPopular: false,
    },
  });

  export type PricingCardVariants = VariantProps<typeof pricingCardVariants>;

  export interface PricingCardFeature {
    /** 機能名 */
    label: string;
    /** このプランに含まれるか(false の場合グレーアウト) */
    enabled?: boolean;
  }

  export interface PricingCardLabel {
    /** 項目名 */
    label: string;
    /** 値 */
    value: string;
  }

  export interface PricingCardPlan {
    /** プラン名 */
    name: string;
    /** プランの説明文 */
    description?: string;
    /** 価格表示(例: ¥980) */
    price: string;
    /** 価格の補足テキスト(例: 1ユーザーあたり月額) */
    caption?: string;
    /** 強調スタイルにするか */
    mostPopular?: boolean;
    /** 機能リスト */
    features?: PricingCardFeature[];
    /** ラベルリスト */
    labels?: PricingCardLabel[];
  }

  export interface PricingCardProps {
    /** クラス */
    class?: ClassValue;
    /** プランデータ */
    plan: PricingCardPlan;
    /** CTAボタン */
    button?: Snippet<[]>;
  }
</script>

<script lang="ts">
  import Separator from '$lib/components/ui/atoms/Separator.svelte';
  import Check from '@lucide/svelte/icons/check';

  let { class: className, plan, button }: PricingCardProps = $props();

  let cardClass = $derived(pricingCardVariants({ mostPopular: plan.mostPopular, class: className }));
</script>

<div class={cardClass} data-rabee-ui="pricing-card">
  <div class="flex flex-col items-center gap-3 px-6 pb-3 pt-5 text-center">
    <div class="flex flex-col w-full">
      <p class="text-lg/tight font-semibold text-foreground">{plan.name}</p>
      {#if plan.description}
        <p class="text-sm text-muted-foreground">{plan.description}</p>
      {/if}
    </div>
    <div class="flex flex-col w-full">
      <p class="text-3xl/tight font-semibold text-foreground">{plan.price}</p>
      {#if plan.caption}
        <p class="text-sm text-muted-foreground">{plan.caption}</p>
      {/if}
    </div>
    {#if button}
      {@render button()}
    {/if}
  </div>
  {#if plan.labels?.length || plan.features?.length}
    <Separator />
    <div class="flex flex-1 flex-col gap-4 p-6">
      {#if plan.labels?.length}
        <div class="flex flex-col gap-1">
          {#each plan.labels as { label, value }}
            <div class="flex items-center">
              <span class="w-1/2 text-sm text-muted-foreground">{label}</span>
              <span class="w-1/2 text-sm text-foreground">{value}</span>
            </div>
          {/each}
        </div>
      {/if}
      {#if plan.features?.length}
        <div class="flex flex-col gap-1">
          {#each plan.features as feature}
            <div class={['flex items-start gap-1 py-1', feature.enabled === false && 'opacity-50']}>
              <Check class={['mt-0.5 shrink-0', feature.enabled !== false ? 'text-primary' : 'text-foreground']} size="1rem" />
              <span class={['text-sm', feature.enabled !== false ? 'text-primary' : 'text-foreground']}>{feature.label}</span>
            </div>
          {/each}
        </div>
      {/if}
    </div>
  {/if}
</div>

      

依存コンポーネント

Pricing を使うときは、以下のコンポーネントもダウンロードが必要です。