Skip to content
Native Animation
Amount Entry Keypad animation preview

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

npx nativeanimation add amount-entry-keypad

Amount Entry Keypad

A money keypad with rolling digits and an amount-to-avatar flight, with configurable palette, recipient details, fonts, and quick amounts.

$9 for this animation

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 animation

Related guides

A money keypad with rolling digits and an amount-to-avatar flight, with configurable palette, recipient details, fonts, and quick amounts.

Why this one

Long amounts stay centered and fit the available width instead of clipping. New digits rise into place, existing digits move with springs, and thousands separators expand visually. Balance errors have a short three-cycle shake and color feedback. Sending turns the amount into a personal confirmation with a drawn ring and check.

How it works

  1. Validate the amount as text, retaining a decimal point and trailing zeros. Accept at most six integer digits and two decimal places, and remove leading zeros.
  2. Measure a glyph using onLayout at 76 pt. Derive the formatted amount's width from the monospaced cells and currency prefix.
  3. Animate individual cell positions to keep the whole amount centered. Spring the measured scale between 76 and 40 pt; inserted commas expand horizontally. New characters enter from 14 pt below with a 4 pt blur where the platform supports text filters.
  4. Replace a preset amount with a synchronized rolling entrance. Digit updates and their animation start together in a layout effect.
  5. Derive the avatar flight, continuous ring stroke, check stroke, and confirmation from one UI-thread progress value. A completed animation calls onSend on the JS thread.
  6. Hold Delete to repeat every 70 ms until the amount reaches zero. Closing or resetting cancels the repeat timer.

Install

npx expo install react-native-reanimated react-native-worklets expo-linear-gradient expo-blur @shopify/react-native-skia

Copy this folder without demo/. Set up Reanimated and Skia in the host application. On web, load CanvasKit before importing this component (for example, a lazy component inside Skia's WithSkiaWeb). Native supports direct imports. Fonts are supplied by the host; monospaced fonts give accurate tabular measurements.

Usage

import { AmountEntryKeypad } from './amount-entry-keypad';

export default function TransferScreen() {
  return (
    <AmountEntryKeypad
      recipientName="Recipient"
      recipientHandle="@recipient"
      initials="RE"
      balance={4218.4}
      onSend={(amount, note) => handleConfirmation(amount, note)}
    />
  );
}
<AmountEntryKeypad
  gradientColors={['#A78BFA', '#4C1D95']}
  backgroundColor="#0B0B10"
  fontFamily="YourInterfaceFont"
  monoFontFamily="YourMonoFont"
  quickAmounts={[25, 75, 150]}
  springDamping={24}
  springStiffness={340}
/>

onSend reports completion of a local visual confirmation. Integrate payment authorization and processing in your host application; this component does not transfer money.

Props

PropTypeDefaultPurpose
colorScheme'light' | 'dark' | 'auto''dark'Complete light/dark material; auto follows the system.
palettePartial<AmountEntryKeypadPalette>Selected presetOverride background, ink, muted, currency, border, control, controlHighlight, accent, accentBorder, successBorder, successSurface, onAccent, accentOutline, avatarOutline, and error colors.
recipientNamestringRecipientDisplay name
recipientShortNamestringFirst word of nameConfirmation name
recipientHandlestring@recipientAccount handle
initialsstringRERecipient avatar initials
balancenumber4218.4Available dollar balance
initialAmountstring0Valid initial amount
quickAmountsnumber[][20, 50, 100]First three preset chips
gradientColorsreadonly [string, string]Violet pairAvatar and button colors
backgroundColorstringSelected preset (#0B0B10 in dark)Override the palette background.
fontFamilystringSystemInterface font
monoFontFamilystringSystemAmount font; use a monospaced font
springDampingnumber58Amount damping. Values below the damping needed for ζ ≥ 0.8 are raised to that minimum.
springStiffnessnumber320Amount stiffness
onSend(amount: number, note: string) => void—Local completion callback
onAmountChange(amount: string) => void—Valid edit callback
onClose() => void—Close callback
styleStyleProp<ViewStyle>—Container override
testIDstring—Container identifier
sendAgainLabelstring'Send again'Label for starting another payment.
sendLabelstring'Send'Label for the send action.
recipientNamestring'Recipient'Recipient's display name.
recipientShortNamestringundefinedShort name used in the confirmation. Defaults to the first name.
recipientHandlestring'@recipient'Recipient's account handle.
initialsstring'RE'Avatar initials.
balancenumber4218.4Available balance in dollars.
initialAmountstring'0'Initial amount, with up to two decimal places.
quickAmountsnumber[][20, 50, 100]Preset amounts.
gradientColorsreadonly [string, string]['#A78BFA', '#4C1D95']Gradient colors.
backgroundColorstringSelected presetOverride the palette background.
fontFamilystringundefinedInterface font; falls back to the system font.
monoFontFamilystringundefinedMonospaced amount font; falls back to the system font.
springDampingnumber58Amount spring damping.
springStiffnessnumber320Amount spring stiffness.
onSend(amount: number, note: string) => voidundefinedCalled after the local confirmation animation; does not execute a payment.
onAmountChange(amount: string) => voidundefinedCalled whenever a valid edit changes the amount.
onClose() => voidundefinedCalled when Close is pressed.
styleStyleProp<ViewStyle>undefinedOuter container style.
testIDstringundefinedOuter container test identifier.
successMessagestring'A little closer, instantly.'Supporting copy below the payment confirmation.
notePlaceholderstringAdd a noteNote input placeholder and empty-note action copy.
balanceLabelstringBalanceAvailable-balance caption prefix.
insufficientBalanceLabelstringNot enough balanceCopy shown when the amount exceeds the balance.
formatSentMessage(amount: string, recipient: string) => stringSent $<amount> to <recipient>Formats the confirmation heading; amount is already formatted with two decimal places.

AmountEntryKeypadRef exposes typeKey(key), setAmount(text), send(), and reset(). typeKey accepts digits, ., or delete. Preset replacements animate as rolls. Input is ignored during sending and after confirmation; reset restores entry.

Compatibility

Built for Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, and Skia 2.14.0. Uses installed Expo Go modules. Text blur uses a style filter with platform-dependent support; the opacity and spring entrance remain available everywhere. Glass chips use Expo BlurView with a translucent gradient fallback on Android.

The component measures its own container, hides the unmeasured first frame, and uses a compact layout below 760 pt high. The demo targets 390×844 and 320×694. Autoplay enters 248.50 at 180 ms intervals starting at 540 ms and sends at 3.5 seconds (3.4 seconds after each loop begins). The first three seconds show digit insertion and measured resizing; the confirmation follows at the specified Send time. Loops every 6.2 seconds.

Accessibility

All controls have button roles and descriptive labels, with at least 44 pt targets. The amount is announced as one value, and balance/confirmation changes use polite live regions. Zero disables Send. Reduced motion removes digit displacement, blur, shake, flight, and sparkles; error feedback remains visible in color and text. Entry and confirmation use short fades instead. Every action is available by touch without gestures.

Icons: Lucide (ISC). Paths are copied from the repository kit. The demo uses the kit's fictional Aster identity and host-loaded Geist/Geist Mono fonts.

Spring damping floors use Reanimated 4.7.1’s default mass of 4 when the configuration does not set a mass. Stiffness and mass remain unchanged.

Complete themes

Use colorScheme="light" with a light background; the default dark preset preserves the original appearance. backgroundColor overrides the preset background, and palette merges over the chosen preset. Ink applies to digits, recipient, keypad, chips, note input, and confirmation; muted applies to captions and placeholders. onAccent colors text on the avatar and send gradients, which remain configurable with gradientColors.

<AmountEntryKeypad
  colorScheme="light"
  backgroundColor="#FFFFFF"
  palette={{ ink: '#17131F', muted: '#625C70', border: '#29203326' }}
/>