CardSwap
card-swapCycles stacked cards through animated front-to-back swaps.
Usage
Basic usage
Wrap each card with CardSwap.Card, at least 2 cards will be automatically rotated; placement="center" allows the entire stack to be framed into the container.
Hulian Card Shuffling
3D Pivot stacking · Automatic rotation · Zero external dependencies
<div
className="relative h-96 overflow-hidden rounded-xl"
style={{ background: "oklch(0.16 0.02 255)" }}
>
<CardSwap width={300} height={200} placement="center">
<CardSwap.Card>Real-time synchronization</CardSwap.Card>
<CardSwap.Card>Visual Arrangement</CardSwap.Card>
<CardSwap.Card>Permission Kernel</CardSwap.Card>
</CardSwap>
</div>Smooth and easing motion
easing="smooth" removes the elastic rebound and makes the rhythm more restrained, suitable for enterprise scenarios.
Hulian Card Shuffling
3D Pivot stacking · Automatic rotation · Zero external dependencies
<CardSwap
width={300}
height={200}
placement="center"
easing="smooth"
skewAmount={4}
delay={2600}
>
{cards}
</CardSwap>Compact fit (no tilt)
Adjust cardDistance / verticalDistance to make the stack more compact, skewAmount={0} has no tilt when viewed from the front.
Hulian Card Shuffling
3D Pivot stacking · Automatic rotation · Zero external dependencies
<CardSwap
width={300}
height={190}
placement="center"
cardDistance={32}
verticalDistance={40}
skewAmount={0}
delay={2800}
>
{cards}
</CardSwap>When to use
Use CardSwap for an automatically cycling perspective stack in a marketing edge composition or centered gallery. Use BounceCards for a static fanned entrance or ChromaGrid for spotlight reveal. Use <CardSwap.Card> for the built-in skin or any custom element; at least two cards are required to cycle.
Import
import { CardSwap } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| width | number | 380 | Card width in pixels. |
| height | number | 280 | Card height in pixels. |
| cardDistance | number | 56 | Horizontal and depth separation. |
| verticalDistance | number | 64 | Vertical step distance. |
| delay | number | 5000 | Cycle interval in milliseconds. |
| pauseOnHover | boolean | false | Whether hover pauses cycling. |
| skewAmount | number | 5 | skewY depth angle in degrees. |
| easing | "elastic" | "smooth" | "elastic" | Bouncy or restrained transition. |
| placement | "bottom-right" | "center" | "bottom-right" | Edge-overflow marketing layout or fully visible centered stack. |
| className | string | — | Root class name. |
| style | CSSProperties | — | Root inline styles. |
Events
| Event | Type | Description |
|---|---|---|
| onCardClick | (index: number) => void | Reports the clicked child's original index. |
Slots
| Slot | Type | Description |
|---|---|---|
| children | ReactNode | Cards, preferably <CardSwap.Card>; two or more are needed for cycling. |
Example
<div className="relative h-96 overflow-hidden rounded-xl">
<CardSwap width={300} height={200} delay={3000} placement="center" pauseOnHover>
<CardSwap.Card><p className="text-sm font-semibold">Real-time sync</p><p className="mt-2 text-xs">Millisecond updates across devices.</p></CardSwap.Card>
<CardSwap.Card>...</CardSwap.Card><CardSwap.Card>...</CardSwap.Card>
</CardSwap>
</div>Smooth restrained motion:
<CardSwap easing="smooth" skewAmount={4} placement="center" delay={2600}>{cards}</CardSwap>Usage guidelines
- The default bottom-right placement intentionally overflows. Use center in ordinary gallery containers.
- One card remains static.
- delay is milliseconds, and the parent needs relative positioning and overflow clipping.
- Reduced motion stops automatic cycling.
Related
Table · Book3D · ProTable · PricingTable · JsonViewer · EditableTable
Playground
Hulian Card Shuffling
3D Pivot stacking · Automatic rotation · Zero external dependencies
<div className="relative h-96 overflow-hidden rounded-xl"
style={{ background: "oklch(0.16 0.02 255)" }}>
<CardSwap
width={300}
height={200}
placement="center"
delay={3000}
cardDistance={56}
verticalDistance={64}
skewAmount={5}
easing="elastic"
pauseOnHover={true}
>
<CardSwap.Card>Real-time synchronization</CardSwap.Card>
<CardSwap.Card>Visual Arrangement</CardSwap.Card>
<CardSwap.Card>Permission Kernel</CardSwap.Card>
</CardSwap>
</div>