Skip to content
Native Animation
Base Plans Block animation previewBase Plans Block animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add base-plans-block

Base Plans Block

React Native Plans Block

A plan-selection screen with configurable monthly and annual prices, plan content and icons, features, FAQ, selection callbacks, copy, loading, errors…

Native Animation Base · Free · MIT

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this component

A plan-selection screen with configurable monthly and annual prices, plan content and icons, features, FAQ, selection callbacks, copy, loading, errors, insets, and theme.

How it works

  1. Composes segmented billing tabs, a savings badge, selectable plan cards, feature checks, FAQ disclosures, and one primary continue action.
  2. Recommended cards use the theme primary border; selected cards also expose selected accessibility state. No nested buttons are placed inside pressable cards.
  3. Prices are full billing-period amounts: monthlyPrice per month, yearlyPrice per year. The CTA price composes Base sliding digits and an explicit period suffix.
  4. Sections reveal in 300 ms from 6 pt, with 30 ms staggering; all other movement belongs to the composed Base controls.
  5. Continue calls onSelectPlan(plan, period). The host handles checkout/navigation; this block never collects payment information or starts a transaction.

Install

npx nativeanimation add base-plans-block

The CLI copies the exact family modules listed in registryDependencies, including their transitive dependencies. To copy by hand, copy those modules too and install their native packages with:

npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets lucide-react-native react-native-svg

Mount GestureHandlerRootView at the app root. Load the Geist regular and medium fonts once, or supply your own font names through the theme. Free forever. MIT.

Usage

import { BasePlansBlock } from './base-plans-block';

<BasePlansBlock
  plans={plans}
  period={period}
  onPeriodChange={setPeriod}
  selectedPlan={selectedPlan}
  onSelectedPlanChange={setSelectedPlan}
  onSelectPlan={(plan, billingPeriod) => openCheckout(plan.id, billingPeriod)}
  insets={insets}
/>

Wrap your app in BaseThemeProvider from base-theme to choose light/dark and neutral, blue, green, or violet accents. A theme prop overrides the provider and is inherited by nested controls, sheets, and dialogs. Place the block inside a bounded container with flex: 1; screens scroll vertically when space is limited. Supply safe-area insets from the host.

Set copy.savings to match your prices, or to an empty string to hide the badge. copy.continue supports {plan}; copy.priceAction supports {action}, {price}, and {period}. Prices should be finite nonnegative numbers. Update a controlled selected ID when replacing the plan collection.

Use with an agent

Use Native Animation MCP to add base-plans-block with monthly and annual plans, a recommended tier, FAQ, and a callback to my checkout.

Props

PropTypeDefaultDescription
copyPartial<copy>Northwind copyAll headings, billing/price labels, savings badge, disclaimer, and templates.
plansBlockPlan[]Personal / TeamID, name, description, monthly/yearly prices, features, optional recommended and icon.
period / defaultPeriodBillingPeriodmonthlyControlled or initial monthly/yearly period.
onPeriodChange(period: BillingPeriod) => void—Reports billing changes.
selectedPlan / defaultSelectedPlanstringrecommended or first initial planControlled or initial plan ID. Unknown IDs disable Continue.
onSelectedPlanChange(id: string) => void—Card-selection callback, separate from submission.
onSelectPlan(plan: BlockPlan, period: BillingPeriod) => void—Continue callback; no payment processing.
faqBaseAccordionItem[]three questionsCaller-owned FAQ titles/content; [] hides it.
openFaq / onOpenFaqChangestring / (value: string) => voiduncontrolledOptional FAQ open state.
currency / localestringUSD / en-USIntl number-format settings.
featureIconReactNodeCheckCaller-owned feature icon; null hides it.
insets{ top?: number; bottom?: number }0 / 0Host safe-area insets; no internal SafeAreaView.
themeBaseThemenearest providerFull shared theme override inherited by every nested control.
onBack / backLabel() => void / string— / BackOptional host back action and its accessible name.
loading / errorboolean / stringfalse / —Host pending state and failure message.
testIDstringpiece IDStable identifier on the screen primary action.
styleStyleProp<ViewStyle>flex: 1Container override.

copy supports these keys: title, heading, description, monthly, yearly, savings, recommended, selected, monthSuffix, yearSuffix, faq, continue, priceAction, disclaimer, loading, errorTitle, emptyTitle, emptyDescription, back. Unspecified keys keep the generic English defaults. Icons and content remain caller-owned.

Compatibility

Expo SDK 58 · React Native 0.88 · Reanimated 4.7 · react-native-worklets 0.13. Targets iOS, Android, and web, in Expo Go and development builds. Native bundle compilation does not replace device interaction testing. Part of Native Animation Base. Free forever. MIT. No router, network, or storage dependency.

Go further

Accessibility

Plan cards announce the plan, price, billing period, and selected state. The primary action has one complete accessible price label; digit wheels stay decorative. FAQ triggers expose expanded state. Loading is announced as busy and empty/error states remain readable. Reduce Motion removes section displacement and applies composed-control changes without motion.

Source code

Loading public source…