A tiny, playful stacking component with smooth expand & collapse animations ✨
Stacklet is a fun, reusable UI component for stacking elements that smoothly expand and collapse.
It’s designed to add a sense of depth, motion, and delight to your interface — without locking you into a specific use-case.
You can use Stacklet for:
- notifications
- cards
- images
- toasts
- previews
…and pretty much anything you want to stack 🪄
- React
- Motion
- TypeScript
- Tailwind CSS
- Smooth expand & collapse animations
- Control which item stays on top (stackedFrom)
- Control stack growth direction (direction)
- Control how items pile up (align)
- Vertical and horizontal stacks (auto layout handling)
- Limit visible items when collapsed
- Graceful handling of large item counts
- Extra items fade in/out (no visual popping)
- Works with any trigger (hover, click, state, etc.)
- Content-agnostic — not tied to notifications
- Lightweight & reusable
This component didn’t start as Stacklet.
A while ago, I built a collapsible notification UI and later noticed similar stacked interactions floating around the internet.
That’s when a thought popped into my head:
“Why should this be just for notifications?”
So I decided to strip away all notification-specific logic and rebuild the idea as a generic stacking system —
something that could work for cards, images, toasts, or any custom element.
The goal wasn’t to build a finished UI component, but a small motion primitive focused purely on:
- layout
- depth
- direction
- animation
The result is Stacklet — flexible, composable, and assumption-free.
Stacklet exposes a small set of focused props.
You don’t need all of them — just the ones you care about.
open: boolean
Controls whether the stack is expanded or collapsed.
-
stackedFrom?: "start" | "end"
Controls which item stays on top in the stack.
"start"→ first item is the hero
"end"→ last item is the hero -
direction?: "up" | "down" | "left" | "right"
Controls the axis and direction the stack expands in. -
align?: "forward" | "backward"
Controls how items pile relative to the hero item.
Useful for creating mirrored or inverted stacks.
-
itemSize?: number
Size of one item along the stack axis
(height for vertical stacks, width for horizontal stacks).
Recommended for stable layouts (no reflow). -
expandedSpacing?: number (default: 8)
Space between items when expanded. -
collapsedSpacing?: number (default: 10)
Offset between items when collapsed.
-
scaleStep?: number (default: 0.04)
How much each stacked item scales down. -
opacityStep?: number (default: 0.08)
How much each stacked item fades.
-
collapsedCount?: number
Limits how many items participate in the stack when collapsed. -
extraItemsDelay?: number (default: 0.01)
Delay before extra (non-stacked) items fade in when expanded. -
extraItemsDuration?: number (default: 0.15)
Fade animation duration for extra items.
Extra items are intentionally not part of the stack animation.
They fade in and out subtly to keep the stack animation clean and satisfying.
Here’s a simple example:
<div className="w-[240px]">
<Stacklet
open={isHovered}
stackedFrom="start"
direction="up"
align="forward"
itemSize={64}
collapsedCount={3}
>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</Stacklet>
</div>
You control when it opens.
Stacklet handles how it stacks and animates ✨
- clone the repo:
git clone https://github.com/your-username/stacklet.git - install dependencies:
npm install - start dev server:
npm run dev
Then open your browser and enjoy the stack magic 🪄
Stacklet.Notifications.mp4 |
Stacklet.Profiles.Stack.Preview.mp4 |
Stacklet is built with curiosity, experimentation, and a love for delightful UI interactions.
Feel free to fork it, break it, remix it, or use it in your own projects.
If you build something cool with it — I’d genuinely love to see it ✨