Skip to content
Native Animation
Stacked Category Cards animation preview

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

npx nativeanimation add stacked-category-cards

Stacked Category Cards

A category stack whose tabs unfold into detail cards, with configurable categories, title, colors, and fonts.

$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 category stack whose tabs unfold into detail cards, with configurable categories, title, colors, and fonts.

How it works

  1. A single spring-driven array holds each persistent card’s expansion weight. Position, type scale, folding, and stacking derive from those weights; jumping across categories does not briefly open the category between them.
  2. Tapping a tab springs it forward while the open card folds back into the stack.
  3. Pulling the open card down folds it away and advances to the next category.
  4. Chips enter in staggered stages. A supplied image rolls in and settles, the built-in map draws its route and drops its pin, and bar charts rise with a UI-thread numeric counter.
  5. Static print grain, an upper edge highlight, and moving shadows separate the layers. The arrow compresses on touch, exits diagonally, and returns.
  6. All cards remain mounted with stable IDs. No outgoing offset resets before React commits, and no recycled front card fades in over a placeholder.

Install

npx expo install @shopify/react-native-skia expo-image react-native-gesture-handler react-native-reanimated react-native-worklets

Wrap the host in GestureHandlerRootView. On web, initialize CanvasKit before importing the component with Skia’s LoadSkiaWeb or WithSkiaWeb, and serve the matching canvaskit.wasm. The catalog demo initializes CanvasKit in a web-only entry. Native platforms require no CanvasKit bootstrap. The host supplies safe-area insets.

Usage

const ref = useRef<StackedCategoryCardsRef>(null);
<StackedCategoryCards ref={ref} categories={categories} initialIndex={0} />
ref.current?.open(1);

Props

PropTypeDefaultDescription
titlestringCATEGORIESHeader title.
categoriesStackedCategory[]requiredCard labels, colors, chips, and optional media or stat.
initialIndexnumberlast categoryInitially expanded card.
colorsStackedCategoryColorsperiwinkle and whiteScreen and header colors.
fontFamilystringsystemUI typeface.
displayFontFamilystringfontFamilyTypeface used for the header and category titles.
monoFontFamilystringfontFamilyTypeface for the live count.
onInteraction() => void—Direct input notification; the demo stops autoplay here.
onOpen(id: string) => void—Called by the card arrow.
onChange(index: number) => void—Called when the expanded card changes.
onBack() => void—Called by the back control.
styleStyleProp<ViewStyle>—Root container style.
testIDstringstacked-category-cardsRoot test identifier.

Category records retain id, label, lines, color, ink, chips, image, and stat. Optional additions:

FieldTypeDefaultDescription
illustration'bars' | 'map'barsSupporting scene when no image is supplied.
statValuenumber—Counter target, formatted as a US integer.
barsnumber[]seven normalized valuesRelative bar heights from 0 to 1.
mapColors{ paper, fold, road, park }warm paper and sageMap illustration palette. Each field is a color string.
openLabelstringOpen <label>Spoken label for the arrow.

The surrounding colors palette additionally accepts control and controlInk for the back button. Each card’s ink also colors its arrow surface; the card fill colors the arrow. Images override built-in scenes. Keep local image density at least 3× its rendered size; the demo caps the 804 px truck at 268 pt.

Compatibility

Expo SDK 58, React Native 0.88, and Reanimated 4.7.1. Uses Skia 2.14.0, Expo Image, and Gesture Handler. No development build is required when the app already includes these dependencies.

Accessibility

The back and open controls expose button roles and labels. Reduced Motion snaps the card geometry and fades supporting content over 200 ms, without the fold, truck travel, pin drop, or arrow flight. The tab stack is selectable by touch as an alternative to dragging.

Why this one

Categories behave like separate physical folders: each one carries its own data and can be pulled forward or tucked back into the stack.

Icons: Feather, the Lucide predecessor, via Expo Vector Icons.