# Pricing

> A complete screen built from PageHeader, Panel, PlanCard, Segmented and 3 more components.

Pattern · Pro kit · [Live page](https://ui.twentyfirst.media/pro/patterns/PricingScreen/)

## Code

```tsx
import { PageHeader, Panel, PlanCard, Segmented, UsageMeter } from "@twentyfirstmedia/pro";
import { Shell } from "./_workspace";

function App() {
  return (
    <Shell
      area="Account"
      current={"Plan & billing"}
      pages={[
        {
          id: "Profile",
          label: "Profile & theme",
          icon: "user",
        },
        {
          id: "Roles",
          label: "Roles & access",
          icon: "lock",
        },
        {
          id: "Plan & billing",
          label: "Plan & billing",
          icon: "card",
        },
      ]}
    >
      <PageHeader
        title={"Plan & billing"}
        subtitle="You’re on Team · renews on May 1, 2026"
        actions={[
          <Segmented
            key="y"
            defaultValue="Yearly"
            options={[
              "Monthly",
              {
                value: "Yearly",
                label: "Yearly · save 17%",
              },
            ]}
          />,
        ]}
      />
      <div className="tf-plans">
        <PlanCard
          name="Starter"
          price={9}
          was={12}
          text="For small teams"
          features={["3 projects", "1 agent", "-Audit log"]}
        />
        <PlanCard
          name="Team"
          price={24}
          was={29}
          featured
          current
          text="For growing companies"
          features={["Unlimited projects", "10 agents", "Audit log"]}
        />
        <PlanCard
          name="Business"
          price={null}
          cta="Talk to sales"
          text="Security and an SLA"
          features={["Everything in Team", "SSO and SCIM", "SLA"]}
        />
      </div>
      <Panel title="Usage this month">
        <UsageMeter
          label="Agent usage"
          used={84}
          limit={120}
          format={(v) => "€" + v}
          caption="Included up to €120"
        />
      </Panel>
    </Shell>
  );
}
export default App;
```

## Props

### Icon

| Prop | Type | Notes |
| --- | --- | --- |
| `name` | `IconName` | Required |
| `size?` | `number` |  |
| `label?` | `string` |  |
| `className?` | `string` |  |
| `style?` | `CSSProperties` | Inline style on the root element. |

### PageHeader

| Prop | Type | Notes |
| --- | --- | --- |
| `crumbs?` | `(string \| Crumb)[]` | A breadcrumb above the title (see `Breadcrumb`): labels, or items with `href`/`onClick`. |
| `crumbLinkAs?` | `ElementType` | The element crumb links render as, e.g. Next.js `Link`. |
| `title` | `string` | Required |
| `subtitle?` | `string` |  |
| `actions?` | `ReactNode[]` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Panel

| Prop | Type | Notes |
| --- | --- | --- |
| `side?` | `boolean` |  |
| `title?` | `string` |  |
| `subtitle?` | `string` |  |
| `action?` | `ReactNode` |  |
| `children?` | `ReactNode` |  |
| `surface?` | `Surface` | `"glass"`: translucent glass over what is behind (maps, 3D, video, photos); `"solid"` opts out inside a glass `UIProvider`. |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### PlanCard

| Prop | Type | Notes |
| --- | --- | --- |
| `name` | `string` | Required |
| `text?` | `string` |  |
| `price` | `number \| null \| ReactNode` | A number is formatted as money (0 = "Free", null = "Let's talk"); any other node is shown as it is, e.g. a placeholder ("—") or a price the app formatted itself. |
| `pricePrefix?` | `ReactNode` | Before the price, e.g. "from". |
| `priceNote?` | `ReactNode` | Under the price: net or gross, billed yearly, VAT note … |
| `was?` | `number` |  |
| `per?` | `string` |  |
| `features?` | `string[]` |  |
| `featured?` | `boolean` |  |
| `flag?` | `string` |  |
| `current?` | `boolean` |  |
| `cta?` | `string` |  |
| `disabled?` | `boolean` | Disable the button, e.g. while a checkout starts or when the plan cannot be picked. |
| `onPick?` | `() => void` |  |
| `href?` | `string` | The action as a link (checkout or sign-up page), with `linkAs` for a router's link. |
| `linkAs?` | `ElementType` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Segmented

| Prop | Type | Notes |
| --- | --- | --- |
| `options` | `(string \| Option)[]` | Required |
| `value?` | `string` |  |
| `defaultValue?` | `string` |  |
| `onChange?` | `(v: string) => void` |  |
| `size?` | `"sm"` |  |
| `block?` | `boolean` |  |
| `label?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### SubNav

| Prop | Type | Notes |
| --- | --- | --- |
| `eyebrow?` | `string` |  |
| `action?` | `{ label: string; icon?: IconName; onClick?: () => void }` |  |
| `items` | `SubNavItem[]` | Required |
| `current?` | `string` |  |
| `onPick?` | `(id: string) => void` |  |
| `children?` | `ReactNode` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### TopBar

| Prop | Type | Notes |
| --- | --- | --- |
| `brand?` | `ReactNode` | The product name, or a node (a logo mark with the name). |
| `tag?` | `string` |  |
| `items` | `NavItem[]` | Required |
| `active?` | `string` |  |
| `user?` | `{ name: string; email?: string }` |  |
| `onNavigate?` | `(label: string) => void` |  |
| `extra?` | `ReactNode` |  |
| `userOpen?` | `boolean` |  |
| `onUser?` | `() => void` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### UsageMeter

| Prop | Type | Notes |
| --- | --- | --- |
| `used` | `number` | Required |
| `limit` | `number` | Required |
| `label?` | `string` |  |
| `caption?` | `string` |  |
| `format?` | `(v: number) => string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |
