Skip to content
Native Animation
Limited Drop Stock animation preview

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

npx nativeanimation add limited-drop-stock

Limited Drop Stock

A limited-release product screen with hold-to-reserve feedback, with configurable image, stock, fonts, and accent color.

$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

A limited-release product screen with hold-to-reserve feedback, with configurable image, stock, fonts, and accent color.

On hosts shorter than 740 pt, the release screen scrolls vertically so the product description, countdown, stock feedback, and purchase control keep their own space.

Why this one

Urgency becomes visible: inventory drains while real purchase labels stack beneath the product. A bottom-to-top light curtain turns the silhouette into the edition artwork, then the bottle leaps into the bag and a numbered receipt rewards the purchase. The reveal and receipt give the familiar product page its own identity.

How it works

  1. onLayout measures the host container; the product is centered at 36% of its height, with a 42% width stage.
  2. The countdown updates once per second. Each digit rolls independently on the UI thread and rests at an exact integer.
  3. A shared reveal value expands a bottom-aligned image clip. The light curtain uses a tinted copy of the artwork, so light stays inside the product silhouette.
  4. Stock events update a shared inventory ratio. A critically damped spring moves the 6-point bar; fewer than 50 units switches it to a pulsing warning color.
  5. Holding advances one continuous shared value over 1.1 seconds. Releasing a hold early springs the fill back. A quick tap starts the same deliberate confirmation for users who cannot hold.
  6. Completion schedules the callback on the React Native thread, flies the product into the bag, and displays the order number with fine confetti. At most three purchase labels remain visible.

Install

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

Copy this folder without demo/. Configure Reanimated and worklets for your Expo project. For web, load CanvasKit before mounting this component, using Skia's documented web setup or your app's existing deferred Skia loader. The component uses up to four canvases, rather than a canvas for each feed entry or particle.

Usage

import { LimitedDropStock } from './limited-drop-stock';

<LimitedDropStock
  productSource={require('./assets/bottle.png')}
  title="Night edition."
  onPurchase={() => openCheckout()}
/>

Use real inventory from your backend in production:

const drop = useRef<LimitedDropStockRef>(null);

<LimitedDropStock
  ref={drop}
  productSource={require('./assets/bottle.png')}
  initialStock={412}
  stock={inventory.available}
  totalStock={500}
  holdDuration={1100}
  accentColor="#60A5FA"
  lowStockColor="#F87171"
  colorScheme="dark"
  fontFamily="YourInterfaceFont"
  titleFontFamily="YourEditorialFont"
  monoFontFamily="YourMonoFont"
  onPurchase={order => openCheckout(order)}
/>

The callback requests checkout; this UI does not charge a card, authenticate a buyer, or guarantee a reservation. The host must validate availability and handle checkout failures. The displayed order number is supplied by the host. simulateSales is off by default; the Tidewell demo explicitly enables illustrative inventory and purchase events. The bundled demo artwork has square transparent margins; replace it with artwork using the same framing, or adjust the stage framing for your asset.

Props

PropTypeDefaultPurpose
productSourceImageSourcePropTyperequiredLocal transparent artwork
productLabelstringLimited edition bottleImage description
brandReactNodeGeneric wordmarkBrand slot
titlestringLimited editionEditorial heading
editionstringDrop 01Edition label
descriptionstringMade for every day. Available just once.Product detail
pricestring$48Formatted price
initialStocknumber412Stock at reset
totalStocknumber500Edition size, clamped to at least one
stocknumber—Backend inventory updates
countdownSecondsnumber3Countdown, clamped to 0–99 seconds
holdDurationnumber1100Confirmation time in milliseconds, minimum 200
orderNumbernumber388Receipt number
accentColorstring#60A5FASix-digit hex accent
lowStockColorstring#F87171Warning accent
colorSchemedark | light | autodarkTheme
fontFamilystringsystemInterface font
titleFontFamilystringsystemEditorial font
monoFontFamilystringsystemCountdown font
simulateSalesbooleanfalseIllustrative sales every 300–900 ms
purchaseFeedstring[]Someone just got oneLabels cycled by simulated sales
onPurchase(number) => void—Checkout request
onStateChange(state) => void—Countdown, live, purchased, or sold-out
styleStyleProp<ViewStyle>—Host container
testIDstring—Root test identifier

The exported LimitedDropStockRef provides reset(), launch(), buy(), and cancelHold(). Autoplay belongs to the demo: countdown 0–3 seconds, reveal 3–3.56 seconds, hold 5–6.1 seconds, flight 6.1–6.68 seconds, restart at 10 seconds. A physical touch cancels subsequent autoplay actions.

Compatibility

Built for Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, and Skia 2.14.0. The installed Expo Go runtime includes the required native modules. Android blur shares one BlurTargetView and uses the SDK 31+ blur method; older Android versions retain the translucent surface. Supports iOS, Android, and web.

Accessibility

The purchase button has a role, state, descriptive label, hint, and accessibility tap action. A quick tap runs the same confirmation as holding; a released hold of at least 220 ms cancels. Stock exposes progress-bar semantics. Countdown and key lifecycle changes have live-region labels and spoken announcements; the low-stock threshold announces once. The bag and artwork have descriptive labels.

Reduced motion uses a 200 ms product fade, removes the flight, light curtain, particles, blur, and digit rolling, and disables press scaling and the warning pulse. The inventory bar uses a short non-spring transition. UI animation never uses React state per frame; React updates only for layout and discrete inventory, countdown, feed, and lifecycle events. Timers and repeating animations are cleaned up on unmount.

Icons: Lucide (ISC), copied from the repository kit. Demo brand: Tidewell, with the kit's droplet tile and teal gradient. The blue accent belongs to the ink edition.