# Pricing Pair

> Two panels side by side in one frame: what is bought once on a sky band, then the monthly plans. Every price comes from your data.

Source: https://ritla.app/ui/pricing-pair

## Installation

Installing from the registry is coming soon. Until then, these are the commands you will run.

```bash
npx ritla add pricing-pair
```

With the shadcn CLI instead:

```bash
npx shadcn@latest add @ritla/pricing-pair
```

Dependencies: `@phosphor-icons/react`

## Usage

```tsx
import { PricingFeatures, PricingPair, PricingPanel, PricingPlan, PricingPlans } from "@/components/ui/pricing-pair";

<PricingPair>
  <PricingPanel tone="brand" eyebrow="One-time purchase" title="Card kit">
    <PricingFeatures items={["Card designs, lifetime updates", "A license key for your team"]} />
  </PricingPanel>
  <PricingPanel eyebrow="Monthly subscription" title="Accounts">
    <PricingPlans label="Account plans">
      {plans.map((p) => <PricingPlan key={p.id} name={p.name} amount={p.amount} currency="USD" period="/mo" description={p.text} />)}
    </PricingPlans>
  </PricingPanel>
</PricingPair>
```

## API reference

### `PricingPair`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | None | Two `PricingPanel`s: what is bought once, then what is subscribed to. |

### `PricingPanel`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `eyebrow` | `ReactNode` | None | The small label above the title. Capitals in English; Arabic is never tracked. |
| `title` | `ReactNode` | None | The product's name, a heading. |
| `headingLevel` | `2 \| 3 \| 4` | `3` | The title's heading level under the section's heading. |
| `tone` | `"default" \| "brand"` | `"default"` | `brand` puts the panel on the sky band. |

### `PricingPlan`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `ReactNode` | None | The plan's name. |
| `amount` | `number` | None | The amount from your pricing data; no amount is written into the component. |
| `currency` | `string` | None | The ISO 4217 code from your data (`USD`, `SAR`). |
| `period` | `ReactNode` | None | After the amount, smaller (“/mo”). Leave it out for a free plan. |
| `description` | `ReactNode` | None | What the plan includes, one line. |

### `PricingPlans`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | None | Names the list for screen readers (“Account plans”). |

### `PricingFeatures`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `items` | `ReactNode[]` | None | What is included, one line each. |

## Accessibility

ARIA:

- Each panel is a `section` with a heading; the plans are a list named by `label`; the features are a list.
- An amount and its currency are one isolated unit, so their order never flips inside Arabic text.

## Arabic and RTL notes

Mirrors:

- The first panel sits on the right, and the rules between panels and between plans sit at their inline start.
- The check sits at the start of each line.

Does not mirror:

- The check doesn't mirror, and the amount keeps its language's order.

Numerals: Prices are always in Western digits (`123`) in both languages, whatever the numerals setting, to match the checkout. The currency comes from your data.

Arabic typography: Title `body-20` Medium, amount `heading-32`, eyebrow `label-12` in English and `label-14` in Arabic.

Mixed-direction text: The amount is isolated; Latin product names are isolated inside Arabic text.
