Price Table
Responsive pricing plans with features, actions, and highlighted offers
PricingTable (shown as Price Table in the component menu) presents multiple plans side by side. PriceTable is also available as an alias. It provides the visual structure and selection callbacks; billing logic, checkout, subscription state, and persistence stay in the application using the component.
Basic usage
import { PricingTable } from '@mosmox/ui';
<PricingTable
plans={[
{
key: 'starter',
name: 'Starter',
price: 0,
billing: '/month',
description: 'For trying the essentials.',
features: [
{ label: '1 workspace', included: true },
{ label: 'Advanced analytics', included: false },
],
actionLabel: 'Get started',
},
]}
currency="USD"
onSelect={(plan) => startCheckout(plan.key)}
/>price may be a number or any React content. Numeric prices are formatted with currency using the browser locale. Use a string or custom node for prices such as Contact us or Custom.
The table renders plans in the order supplied. columns is clamped to the range 1–6; when it is omitted, the component uses the provider default or the plan count capped at four. fullWidth={false} removes the full-width modifier so the surrounding layout controls the table width.
Plans, features, and actions
Each plan has a stable key, a name, price, optional billing text, description, features, badge, icon, accent color, and action. A plan can be marked popular to give it stronger visual emphasis.
<PricingTable
plans={plans}
renderFeature={(feature) => feature.tooltip ? <span>{feature.label} ⓘ</span> : feature.label}
renderPlanAction={(plan) => <Button onClick={() => choose(plan.key)}>{plan.actionLabel}</Button>}
showFeatureStates
/>included: false displays a muted feature with a dash when showFeatureStates is enabled. highlight emphasizes an individual feature. value can replace the feature label with a plan-specific value such as 10 GB or Unlimited.
Variants and responsive layout
Five variants are available: cards, bordered, flat, spotlight, and compact. size accepts sm, default, or lg. columns controls the intended desktop column count, from 1 to 6; the layout automatically reduces to two columns and then one column on narrow screens.
<PricingTable plans={plans} variant="spotlight" columns={3} size="lg" />
<PricingTable plans={plans} variant="bordered" columns={4} />
<PricingTable plans={plans} variant="flat" size="sm" fullWidth={false} />The spotlight variant lifts and emphasizes the plan with popular: true. fullWidth controls whether the table uses the available width. Use style or className for application-specific layout rules.
Selection and controlled state
Use defaultSelectedKey for an initially emphasized plan. Use selectedKey when the parent owns the selection state. The component calls onSelect when a built-in plan action is activated.
<PricingTable
plans={plans}
selectedKey={selectedPlan}
defaultSelectedKey="pro"
onSelect={(plan) => setSelectedPlan(plan.key)}
/>When renderPlanAction is provided, it replaces both the built-in button and plan.action. Otherwise plan.action is rendered as supplied; if neither is present, the component creates a native button using actionLabel. Disabled plans still render for comparison but their built-in action is disabled. selectedKey takes precedence over defaultSelectedKey and applies the selected visual state to the matching plan.
ConfigProvider
Set defaults for a group of pricing tables with ConfigProvider. Instance props take precedence.
<ConfigProvider
components={{
pricingTable: {
columns: 3,
size: 'default',
variant: 'cards',
},
}}
>
<PricingTable plans={plans} currency="USD" />
</ConfigProvider>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
plans | PricingPlan[] | required | Plans to display. |
columns | number | provider value or plan count, max 4 | Intended desktop column count, clamped to 1–6. |
variant | cards | bordered | flat | spotlight | compact | provider value or cards | Visual treatment for the plan cards. |
size | sm | default | lg | provider value or default | Spacing and price typography scale. |
currency | string | — | ISO currency code used for numeric prices. |
heading | ReactNode | — | Optional content above the plan grid. |
fullWidth | boolean | true | Uses the available table width. |
defaultSelectedKey | string | — | Initially emphasized plan key. |
selectedKey | string | — | Controlled selected plan key. |
onSelect | (plan: PricingPlan) => void | — | Called by a built-in plan action. |
renderFeature | (feature, plan) => ReactNode | — | Custom feature content renderer. |
renderPlanAction | (plan) => ReactNode | — | Replaces the built-in action button. |
showFeatureStates | boolean | true | Shows included and excluded feature marks. |
className | string | — | Additional table class. |
style | CSSProperties | — | Additional styles and CSS custom properties. |
style can also provide the --mm-pricing-columns CSS custom property for application-specific layout control, although the columns prop is the normal API.
PricingPlan
| Field | Type | Default | Description |
|---|---|---|---|
key | string | required | Stable plan identifier. |
name | ReactNode | required | Plan name. |
price | ReactNode | required | Numeric price or custom display content. |
billing | ReactNode | — | Suffix such as /month or per year. |
description | ReactNode | — | Short plan explanation. |
features | PricingFeature[] | — | Feature list for the plan. |
action | ReactNode | — | Custom action content. |
actionLabel | ReactNode | Choose plan | Label for the built-in action. |
badge | ReactNode | — | Badge such as Most popular. |
icon | ReactNode | — | Optional decorative icon. |
popular | boolean | false | Highlights the plan. |
disabled | boolean | false | Disables the built-in action and dims the plan. |
accent | string | theme primary | CSS color used for the plan accent. |
PricingFeature
| Field | Type | Default | Description |
|---|---|---|---|
key | string | generated | Stable feature key. |
label | ReactNode | required | Feature name. |
value | ReactNode | — | Value shown instead of the label. |
included | boolean | true | Whether the plan includes the feature. |
highlight | boolean | false | Emphasizes the feature row. |
tooltip | ReactNode | — | Native tooltip text for the feature. |
Accessibility
Each plan is exposed as an article with an accessible name when its name is text. Built-in actions are native buttons, feature states are represented by text and visual marks, and responsive layout preserves the reading order of plans on small screens. Use meaningful labels and descriptions for custom content.