# PricingTable

The `PricingTable` component is a flexible UI element designed to display subscription plans and pricing options in a structured, responsive table. It allows users to toggle between billing cycles (e.g., monthly, yearly), select their preferred currency, and choose a plan to proceed with.

This component is ideal for building custom checkout flows where you need granular control over the presentation of pricing plans. For a more integrated solution that handles the entire checkout process, consider using the higher-level [`CheckoutTable`](./components-checkout-checkout-table.md) component.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `table` | `TPricingTableExpanded` | - | **Required**. An object containing the pricing table data, including a list of items (plans), currency information, and other details. |
| `onSelect` | `(priceId: string, currencyId: string) => void` | - | **Required**. A callback function that is triggered when a user clicks the action button for a plan. It receives the selected `priceId` and `currencyId`. |
| `alignItems` | `'center' \| 'left'` | `'center'` | Controls the horizontal alignment of the table's header content (billing cycle and currency selectors). |
| `mode` | `'checkout' \| 'select'` | `'checkout'` | Determines the behavior and text of the action button. `'checkout'` mode is for initiating a payment, while `'select'` mode is for selecting a plan within a larger form. |
| `interval` | `string` | `''` | Sets the initially selected billing interval. The format is typically `interval-interval_count` (e.g., `month-1`, `year-1`). |
| `hideCurrency` | `boolean` | `false` | If `true`, the currency selector dropdown will be hidden, even if multiple currencies are available. |

## Usage Example

To use the `PricingTable`, you must wrap it in a `PaymentProvider`. The component requires a `table` object with your product data and an `onSelect` handler to manage user selections.

```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';

// In a real application, you would fetch this data from your payment service.
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', // in cents
        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}`);
    // Here, you would typically navigate to a checkout page or open a payment modal.
    // For example: `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;
```

## Usage Scenarios

### Mode: `checkout` vs. `select`

The `mode` prop changes the call-to-action button to fit different use cases.

-   **`mode='checkout'` (Default):** The button text will be context-aware, showing labels like "Subscribe" or "Start Trial". This mode is intended for when the user's click should immediately initiate the payment or checkout process.

-   **`mode='select'`:** The button text will show "Select" or "Selected". This is useful when the pricing table is part of a larger form or multi-step process. The `onSelect` callback can be used to update the application's state with the chosen plan, and the UI will visually indicate which plan is currently selected.

### Handling `onSelect`

The `onSelect` callback is the core mechanism for handling user interaction. It's an async function that receives the `priceId` and `currencyId` of the chosen plan. Your application logic should reside here. Common actions include:

-   Storing the selected plan in your application's state.
-   Redirecting the user to a dedicated checkout page, passing the `priceId` as a URL parameter.
-   Using the `priceId` to create a checkout session with the payment service backend and then opening a payment form.