# PricingTable

`PricingTable` コンポーネントは、サブスクリプションプランと価格オプションを構造化されたレスポンシブなテーブルに表示するために設計された、柔軟な UI 要素です。ユーザーは請求サイクル（例：月次、年次）の切り替え、希望通貨の選択、そしてプランの選択を行って次に進むことができます。

このコンポーネントは、価格プランの表示を詳細に制御する必要があるカスタムチェックアウトフローの構築に最適です。チェックアウトプロセス全体を処理する、より統合されたソリューションをお求めの場合は、高レベルの [`CheckoutTable`](./components-checkout-checkout-table.md) コンポーネントの使用を検討してください。

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `table` | `TPricingTableExpanded` | - | **必須**。価格表データを含むオブジェクトで、アイテム（プラン）のリスト、通貨情報、その他の詳細が含まれます。 |
| `onSelect` | `(priceId: string, currencyId: string) => void` | - | **必須**。ユーザーがプランのアクションボタンをクリックしたときにトリガーされるコールバック関数です。選択された `priceId` と `currencyId` を受け取ります。 |
| `alignItems` | `'center' \| 'left'` | `'center'` | テーブルヘッダーのコンテンツ（請求サイクルと通貨セレクター）の水平方向の配置を制御します。 |
| `mode` | `'checkout' \| 'select'` | `'checkout'` | アクションボタンの動作とテキストを決定します。`'checkout'` モードは支払いを開始するためのもので、`'select'` モードはより大きなフォーム内でプランを選択するためのものです。 |
| `interval` | `string` | `''` | 最初に選択される請求期間を設定します。フォーマットは通常 `interval-interval_count` です（例：`month-1`、`year-1`）。 |
| `hideCurrency` | `boolean` | `false` | `true` の場合、複数の通貨が利用可能であっても、通貨セレクターのドロップダウンは非表示になります。 |

## 使用例

`PricingTable` を使用するには、`PaymentProvider` でラップする必要があります。このコンポーネントには、製品データを含む `table` オブジェクトと、ユーザーの選択を管理するための `onSelect` ハンドラーが必要です。

```tsx Integration Example icon=lucide:code
import { PaymentProvider } from '@blocklet/payment-react';
import { PricingTable } from '@blocklet/payment-react/components/ui';
import type { TPricingTableExpanded } from '@blocklet/payment-types';

// 実際のアプリケーションでは、このデータを支払いサービスから取得します。
const pricingTableData: TPricingTableExpanded = {
  id: 'pt_123',
  livemode: false,
  currency: { id: 'usd', symbol: '$' },
  items: [
    {
      price_id: 'price_basic_monthly',
      product: {
        name: 'Basic Plan',
        description: 'For individuals and small teams.',
        unit_label: 'user',
        features: [{ name: '5 Projects' }, { name: '10GB Storage' }, { name: 'Basic Support' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '1000', // セント単位
        recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '1000' }],
      },
      is_highlight: false,
    },
    {
      price_id: 'price_pro_monthly',
      product: {
        name: 'Pro Plan',
        description: 'For growing businesses.',
        unit_label: 'user',
        features: [{ name: 'Unlimited Projects' }, { name: '100GB Storage' }, { name: 'Priority Support' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '2500',
        recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '2500' }],
      },
      is_highlight: true,
      highlight_text: 'Popular',
    },
    {
      price_id: 'price_basic_yearly',
      product: {
        name: 'Basic Plan',
        description: 'For individuals and small teams.',
        unit_label: 'user',
        features: [{ name: '5 Projects' }, { name: '10GB Storage' }, { name: 'Basic Support' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '10000',
        recurring: { interval: 'year', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '10000' }],
      },
      is_highlight: false,
    },
    {
      price_id: 'price_pro_yearly',
      product: {
        name: 'Pro Plan',
        description: 'For growing businesses.',
        unit_label: 'user',
        features: [{ name: 'Unlimited Projects' }, { name: '100GB Storage' }, { name: 'Priority Support' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '25000',
        recurring: { interval: 'year', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '25000' }],
      },
      is_highlight: true,
      highlight_text: 'Popular',
    },
  ],
};

function MyPricingPage() {
  const { session, connect } = useSessionContext();

  const handlePlanSelect = async (priceId: string, currencyId: string) => {
    console.log(`Plan selected: ${priceId}, Currency: ${currencyId}`);
    // ここでは、通常チェックアウトページに移動するか、支払いモーダルを開きます。
    // 例：`router.push(\"/checkout?price_id=${priceId}&currency_id=${currencyId}\")`
    alert(`Selected Price ID: ${priceId}`);
  };

  return (
    <PaymentProvider session={session} connect={connect}>
      <div style={{ maxWidth: 800, margin: 'auto' }}>
        <PricingTable table={pricingTableData} onSelect={handlePlanSelect} />
      </div>
    </PaymentProvider>
  );
}

export default MyPricingPage;
```

## 使用シナリオ

### モード：`checkout` vs. `select`

`mode` プロップは、さまざまなユースケースに合わせてコールトゥアクションボタンを変更します。

-   **`mode='checkout'` (デフォルト):** ボタンのテキストはコンテキストに応じて、「Subscribe」や「Start Trial」などのラベルを表示します。このモードは、ユーザーのクリックが直ちに支払いまたはチェックアウトプロセスを開始する場合に使用します。

-   **`mode='select'`:** ボタンのテキストは「Select」または「Selected」と表示されます。これは、価格表がより大きなフォームや複数ステップのプロセスの一部である場合に便利です。`onSelect` コールバックを使用して、選択されたプランでアプリケーションの状態を更新でき、UI は現在どのプランが選択されているかを視覚的に示します。

### `onSelect` の処理

`onSelect` コールバックは、ユーザーインタラクションを処理するための中心的なメカニズムです。これは選択されたプランの `priceId` と `currencyId` を受け取る非同期関数です。アプリケーションのロジックはここに記述します。一般的なアクションは次のとおりです：

-   選択したプランをアプリケーションの状態に保存する。
-   ユーザーを専用のチェックアウトページにリダイレクトし、`priceId` を URL パラメータとして渡す。
-   `priceId` を使用して支払いサービスのバックエンドでチェックアウトセッションを作成し、支払いフォームを開く。