Slack's upcoming "Catch Up" tinder-like mobile app feature shared here, built in react-native
& typescript
with smooth ✨ 60fps ✨ native reanimated & gesture-handler animations.
full-demo.mp4
- 👆 Swipe right to mark as read, or left to keep unread.
- ✔ Show different overlays on basis of swipe direction with animated opactiy depending on translation.
- 🫰 Snap back card if swipe velocity is less than the configurable threshold.
- ↔ Action buttons for swipe left & swipe right functionalities for accessibility & quick action.
- ↩️ Undo anytime, we all make mistakes.
- 🔢 Show number of threads left to catch up.
- 👀 Show a peek of next card, if existing.
- 🙌 The OG emoji & title of Slack at stack end.
- 🔁 Reset whole stack to start again.
- ✨ 60fps native animtions running on UI thread.
- 💪 TypeScript support.
- ⚛️ Reusbale React functional components with configurable props.
- ♻ Supports Android, iOS & Web platforms.
The card stack smoothly slides in down on render. The action buttons below & header animates in same manner to compilment the motion.
The top most card smoothly scales up & down on touch to make the user feel it's interactive.
It's a design principle to always show a part of next item in a list, to give a hint to user that there's more to explore.
The card smoothly snaps back to it's position if the swipe velocity is less than a certain configurable threshold.
When user swipes in either direction, an overlay of the action is shown with animated opacity. the next card also scales up simultaneously as swipes away top card.
Buttons you wanna keep smashing because it feels like they're asking for it.
When the stack ends, the end view enters with a smooth zoom-in animation & an action button slides in from the bottom.
<ThreadStack
data={threads}
onSwipeLeft={(item) => {
console.warn('left, ', item);
}}
onSwipeRight={(item) => {
console.warn('right', item);
}}
allowSwipe
showActionButtons
stackEnd={{
emoji: '🙌',
heading: 'All Caught Up.',
showReset: true,
}}
header={{
visible: true,
showNumberOfThreadsLeft: true,
showUndoButton: true,
showResetIconButton: true,
}}
/>
Name | Description | Default | Required |
---|---|---|---|
data |
The array of data to be rendered in the stack | [] | Required |
onSwipeLeft |
Callback on swipe left action | Optional | |
onSwipeRight |
Callback on swipe right action | Optional | |
allowSwipe |
Whether to allow swipe gestures or not | true | Optional |
showActionButtons |
Whether to show the action buttons at the bottom | true | Optional |
header |
Configuration of header component | { visible : true , showNumberOfThreadsLeft : true , showUndoButton : true , showResetIconButton : true , } |
Optional |
stackEnd |
Configuration for the stack end view | { emoji : ' 🙌 ' , heading : ' All Caught Up. ' , showReset : true , } |
Note
The initial template was created with npx create-react-native-app my-app -t with-reanimated
react-native
- v72react-native-reanimated
- v3react-native-gesture-handler
- v2expo
- v49
- Run
yarn
ornpm install
- Run
yarn start
ornpm run start
to try it out.