Envelope Card
CardsA paper flap lifts in 3D as a message slides out of its envelope.
Swipe through a stack of cards with a spring-like return.
Copy the component and its CSS module into your project.
Matches your current playground settings.
import DraggableCardStack from "./DraggableCardStack";export default function Example() {return (<DraggableCardStackitems={[{"id": "dune","title": "Dune studies","description": "01 / Shapes in the sand","image": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%20700%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%22.7%22%20numOctaves%3D%223%22%20stitchTiles%3D%22stitch%22%2F%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%23d8ad8c%22%20d%3D%22M0%200h600v700H0z%22%2F%3E%3Ccircle%20cx%3D%22390%22%20cy%3D%22190%22%20r%3D%2290%22%20fill%3D%22%23f9d7ae%22%2F%3E%3Cpath%20d%3D%22M0%20450Q200%20190%20600%20410V700H0Z%22%20fill%3D%22%23b78461%22%2F%3E%3Cpath%20d%3D%22M0%20520Q380%20300%20600%20490V700H0Z%22%20fill%3D%22%23805848%22%2F%3E%3Cpath%20d%3D%22M0%20650Q250%20400%20600%20620V700H0Z%22%20fill%3D%22%234b3935%22%2F%3E%3Cpath%20d%3D%22M0%200h600v700H0z%22%20filter%3D%22url(%23n)%22%20opacity%3D%22.085%22%2F%3E%3C%2Fsvg%3E","color": "#fff3e8"},{"id": "tide","title": "In the current","description": "02 / A study in motion","image": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%20700%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%22.7%22%20numOctaves%3D%223%22%20stitchTiles%3D%22stitch%22%2F%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%23234652%22%20d%3D%22M0%200h600v700H0z%22%2F%3E%3Cpath%20d%3D%22M-50%20560C120%2020%20300%20750%20670%20120%22%20fill%3D%22none%22%20stroke%3D%22%23648b90%22%20stroke-width%3D%22250%22%2F%3E%3Cpath%20d%3D%22M-50%20560C120%2020%20300%20750%20670%20120%22%20fill%3D%22none%22%20stroke%3D%22%2394b2af%22%20stroke-width%3D%22155%22%2F%3E%3Cpath%20d%3D%22M-50%20560C120%2020%20300%20750%20670%20120%22%20fill%3D%22none%22%20stroke%3D%22%23c1d0c4%22%20stroke-width%3D%2265%22%2F%3E%3Cpath%20d%3D%22M0%200h600v700H0z%22%20filter%3D%22url(%23n)%22%20opacity%3D%22.085%22%2F%3E%3C%2Fsvg%3E","color": "#f1fcf4"},{"id": "bloom","title": "Full bloom","description": "03 / Colour in balance","image": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%20700%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%22.7%22%20numOctaves%3D%223%22%20stitchTiles%3D%22stitch%22%2F%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%23a35574%22%20d%3D%22M0%200h600v700H0z%22%2F%3E%3Ccircle%20cx%3D%22300%22%20cy%3D%22350%22%20r%3D%22205%22%20fill%3D%22%23c77488%22%2F%3E%3Cellipse%20cx%3D%22300%22%20cy%3D%22350%22%20rx%3D%2270%22%20ry%3D%22230%22%20fill%3D%22%23f4c4bd%22%20transform%3D%22rotate(-40%20300%20350)%22%2F%3E%3Cellipse%20cx%3D%22300%22%20cy%3D%22350%22%20rx%3D%2270%22%20ry%3D%22230%22%20fill%3D%22%23e99b9f%22%20transform%3D%22rotate(40%20300%20350)%22%2F%3E%3Ccircle%20cx%3D%22300%22%20cy%3D%22350%22%20r%3D%2262%22%20fill%3D%22%2363344e%22%2F%3E%3Cpath%20d%3D%22M0%200h600v700H0z%22%20filter%3D%22url(%23n)%22%20opacity%3D%22.085%22%2F%3E%3C%2Fsvg%3E","color": "#fff2f0"}]}cardHeight={320}swipeThreshold={80}rotation={10}loop={true}/>);}
Supply an ordered collection through items and give the stack enough height for its cards. swipeThreshold controls how far a drag must travel before advancing.
Use activeIndex and onIndexChange to synchronise another control. Set loop according to whether reaching the end should wrap to the first card.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| items | object[] | No | [] | Array of { id, content?, title?, description?, image?, background?, color? }. content accepts any React node. |
| activeIndex | number | No | undefined | Optional controlled card index. |
| defaultIndex | number | No | 0 | Initial card index when uncontrolled. |
| onIndexChange | function | No | undefined | Called with the next index after a swipe or navigation action. |
| cardHeight | number | No | 300 | Card height in pixels. |
| swipeThreshold | number | No | 80 | Horizontal travel required to change cards, in pixels. |
| rotation | number | No | 10 | Rotation of the stacked cards and exit animation, in degrees. |
| loop | boolean | No | true | Wrap from the last card to the first. |
| label | string | No | "Card stack" | Accessible group label. |
| className | string | No | "" | Additional CSS classes, merged with the component styles. |
| style | CSSProperties | No | undefined | Inline styles for caller-defined sizing and visual overrides. |