Browse the docs
Theme Default
العربيةGet Ritla UI

Components

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.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry is coming soon. Until then, these are the commands you will run.
npx ritla add pricing-pair

Also works with shadcn: npx shadcn@latest add @ritla/pricing-pair

Dependencies it brings: @phosphor-icons/react

Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.

Usage

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

PropTypeDefaultDescription
childrenReactNodeNoneTwo PricingPanels: what is bought once, then what is subscribed to.

PricingPanel

PropTypeDefaultDescription
eyebrowReactNodeNoneThe small label above the title. Capitals in English; Arabic is never tracked.
titleReactNodeNoneThe product's name, a heading.
headingLevel2 | 3 | 43The title's heading level under the section's heading.
tone"default" | "brand""default"brand puts the panel on the sky band.

PricingPlan

PropTypeDefaultDescription
nameReactNodeNoneThe plan's name.
amountnumberNoneThe amount from your pricing data; no amount is written into the component.
currencystringNoneThe ISO 4217 code from your data (USD, SAR).
periodReactNodeNoneAfter the amount, smaller (“/mo”). Leave it out for a free plan.
descriptionReactNodeNoneWhat the plan includes, one line.

PricingPlans

PropTypeDefaultDescription
labelstringNoneNames the list for screen readers (“Account plans”).

PricingFeatures

PropTypeDefaultDescription
itemsReactNode[]NoneWhat 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.