Documentation

Build a pricing surface.

Motion Pricing ships as React + TypeScript source with a small, controlled API, scoped styling, and accessible responsive behavior.

Installation

Use the package manager your app already uses. These commands apply once @motion-pricing/free is available in your configured registry.

npm install @motion-pricing/free

Pro is delivered as private source. Keep packages/core and packages/pro together in an npm workspace, then build Core before Pro.

Usage

Pricing.tsx

import { useState } from 'react';
import { ProPricing, defaultPlans } from '@motion-pricing/pro';
import '@motion-pricing/pro/styles.css';

export function Pricing() {
  const [cycle, setCycle] = useState('monthly');
  return (
    <ProPricing
      plans={defaultPlans}
      billingCycle={cycle}
      onBillingCycleChange={setCycle}
      layout="featured"
      animation="lift"
      spotlight
      showYearlySavings
    />
  );
}

Plan data

Each plan requires an id, name, description, monthly and yearly prices, and a feature list. Optional fields configure currency, a badge, featured state, CTA text, destination, and accessible label.

types.ts

type PricingPlan = {
  id: string;
  name: string;
  description: string;
  monthlyPrice: number;
  yearlyPrice: number;
  features: Array<string | { label: string; included?: boolean; detail?: string }>;
  currency?: string;
  currencySymbol?: string;
  badge?: string;
  featured?: boolean;
  ctaLabel?: string;
  ctaHref?: string;
  ctaAriaLabel?: string;
};

Shared types

PricingPlan

Describes one plan shown by both components. Used by PricingTable.plans and ProPricing.plans.

FieldTypeRequiredDescription
idstringYesStable, unique plan identifier.
namestringYesPlan name displayed in cards and plan tabs.
descriptionstringYesShort supporting description for the plan.
monthlyPricenumberYesPrice displayed for the monthly billing cycle.
yearlyPricenumberYesTotal price displayed for the yearly billing cycle.
currencystringNoISO currency code; defaults to USD when formatting.
currencySymbolstringNoLiteral symbol to display instead of locale currency formatting.
featuresArray<string | PricingFeature>YesIncluded and excluded feature rows.
badgestringNoShort status label, such as “Most popular.”
featuredbooleanNoMarks the plan as featured and selects it initially on mobile.
ctaLabelstringNoCTA text; defaults to “Choose {name}.”
ctaHrefstringNoCTA destination; defaults to #.
ctaAriaLabelstringNoAccessible CTA label; defaults to ctaLabel or the generated CTA text.

PricingFeature

Describes a detailed entry in PricingPlan.features. A plain string is treated as an included feature.

FieldTypeDefaultDescription
labelstringrequiredFeature text shown to the visitor.
includedbooleantrueMarks the feature as included or unavailable.
detailstring—Additional explanatory text displayed below the label.

BillingCycle

'monthly' | 'yearly'. This controlled value selects the displayed price and billing copy. Used by the Free and Pro billing props and callbacks.

PricingTheme

'light' | 'dark'. Selects the component’s scoped color scheme. Used by PricingTable.theme and ProPricing.theme.

Free props

PricingTable is the primary Free component. Its billing value is controlled by the host.

PropTypeDefaultPurpose
plansPricingPlan[]requiredPlan content, prices, features, badge, and CTA metadata.
billingCycleBillingCyclerequiredControlled billing value used to calculate every displayed price.
onBillingCycleChange(cycle: BillingCycle) => void—Shows the built-in billing control and receives the requested cadence.
themePricingTheme'light'Selects the scoped color scheme.
headingReactNode—Optional section heading.
subheadingReactNode—Supporting copy below the heading.
showBillingTogglebooleantrueHides the built-in billing control when false.
yearlySavingsLabelstring'Save 20%'Display copy beside the yearly option; this value is not calculated.
priceSuffix{ monthly: string; yearly: string }{ monthly: '/month', yearly: '/year' }Replaces the cadence copy beside every price.
classNamestring''Adds a class to the outer section.
styleCSSProperties—Adds inline styles or scoped CSS custom-property overrides to the outer section.
stylesPricingTableStyles—Adds inline styles to named component parts.
onPlanSelect(plan: PricingPlan) => void—Runs when a plan CTA is selected; the component does not initiate checkout.

BillingToggle props

Use BillingToggle when you want the Free billing control outside PricingTable.

PropTypeDefaultPurpose
valueBillingCyclerequiredControlled selected billing cadence.
onChange(cycle: BillingCycle) => voidrequiredReceives keyboard and pointer selections.
monthlyLabelstring'Monthly'Monthly option copy.
yearlyLabelstring'Yearly'Yearly option copy.
savingsLabelstring'Save yearly'Supplemental copy shown with the yearly option.
classNamestring''Adds a class to the radiogroup.
styleCSSProperties—Adds inline styles to the radiogroup.
buttonStyleCSSProperties—Adds inline styles to both option buttons.

PricingTableStyles

Inline CSSProperties slots used by PricingTable.styles. featuredCard is applied after card; the top-level style prop is applied after styles.root.

SlotApplies toDescription
rootOuter pricing sectionStyles the component container before the top-level style prop is merged.
headerHeader wrapperStyles the heading, supporting copy, and built-in billing control area.
billingToggleBuilt-in BillingToggleStyles the billing control radiogroup.
billingToggleButtonBuilt-in BillingToggle buttonsStyles both monthly and yearly option buttons.
tabsPlan tablistStyles the mobile plan selector.
gridPlan gridStyles the container that arranges the plan cards.
cardEvery plan cardApplies to each plan card.
featuredCardFeatured plan cardAdds to card styles for a plan with featured set to true.
cardHeaderPlan card headingStyles the plan name and description wrapper.
badgePlan badgeStyles the optional plan status badge.
descriptionPlan descriptionStyles the individual plan description.
pricePrice rowStyles the formatted price and billing suffix.
featureListFeature listStyles the list that contains a plan’s features.
featureFeature rowStyles each included or excluded feature row.
ctaPlan CTAStyles the plan’s call-to-action link.

Pro props

ProPricing includes the controlled pricing behavior of Free, plus layout, animation, and token controls.

PropTypeDefaultPurpose
plansPricingPlan[]requiredPlan content, prices, features, badge, and CTA metadata.
billingCycleBillingCyclerequiredControlled billing value used to calculate every displayed price.
onBillingCycleChange(cycle: BillingCycle) => void—Renders and controls the built-in billing selector when supplied.
themePricingTheme'light'Selects the component color scheme.
layoutPricingLayout'standard'Changes information density and plan presentation.
animationAnimationPreset'subtle'Controls card entrance and hover motion.
spotlightbooleanfalseAdds a pointer-following surface glow and border reflection.
tokensProPricingTokens—Typed overrides for accent, surfaces, text, border, radius, gap, and font.
headingReactNode—Optional component heading.
eyebrowReactNode—Optional content displayed above the heading.
subheadingReactNode—Supporting copy below the heading.
showBillingTogglebooleantrueAllows the built-in billing selector to be hidden.
showYearlySavingsbooleanfalseShows calculated annual savings and the yearly Best value label.
classNamestring''Adds a class to the outer section.
styleCSSProperties—Adds inline styles to the outer section after styles.root.
stylesProPricingStyles—Adds inline styles to named component parts.
onPlanSelect(plan: PricingPlan) => void—Notifies the host when a plan CTA is selected; it performs no checkout itself.

PricingLayout

'standard' | 'compact' | 'featured' | 'comparison'. Used by ProPricing.layout. standard is the default card grid, compact reduces visual density, featured emphasizes a featured plan, and comparison renders a feature comparison table.

AnimationPreset

'none' | 'subtle' | 'lift' | 'cascade'. Used by ProPricing.animation to select the card motion treatment.

Customization tokens

ProPricingTokens

Optional string values passed through ProPricing.tokens as scoped CSS custom properties.

FieldDescription
accentPrimary interactive and emphasis color.
accentContrastText or icon color placed over the accent color.
backgroundOuter component background.
surfaceCard and elevated surface color.
textPrimary text color.
mutedSecondary text and subdued UI color.
borderBorder and separator color.
radiusCard and control corner radius.
cardGapSpacing between pricing cards.
fontFamilyFont family for the component.

ProPricingStyles

Inline CSSProperties slots used by ProPricing.styles. featuredCard is applied after card; the top-level style prop is applied after styles.root. Free can also be customized through its scoped --mp-* CSS variables.

SlotApplies toDescription
rootOuter pricing sectionStyles the component container before the top-level style prop is merged.
headerHeader wrapperStyles the eyebrow, heading, supporting copy, and billing control area.
billingToggleBuilt-in billing controlStyles the Pro monthly/yearly selector.
tabsPlan tablistStyles the plan selector above the card grid.
gridPlan gridStyles the container that arranges the plan cards.
cardEvery plan cardApplies to each plan card.
featuredCardFeatured plan cardAdds to card styles for a plan with featured set to true.
cardHeaderPlan card headingStyles the plan index, name, and badge wrapper.
badgePlan badgeStyles the optional plan status badge.
descriptionPlan descriptionStyles the individual plan description.
pricePrice rowStyles the formatted price, billing suffix, and yearly-savings content.
featureListFeature listStyles the list that contains a plan’s features.
featureFeature rowStyles each included or excluded feature row.
ctaPlan CTAStyles the plan’s call-to-action link.
comparisonTableComparison table wrapperStyles the focusable, horizontally scrollable comparison table region.

Responsive and accessible behavior

Desktop layouts display plans side by side. At mobile component widths, plans become keyboard-operable tabs so visitors can focus on one decision at a time. Billing controls use radio semantics and arrow keys, data tables reflow into readable rows, and all motion respects prefers-reduced-motion.