rit3zh GitHub avatar

expo-dynamic-tray

rit3zh

expo-dynamic-tray is a morphing, keyboard-aware bottom-sheet tray for React Native with auto-sizing, multi-view history navigation, and swipe-to-dismiss.

Stars

154

7-day growth

No data

Forks

11

Open issues

0

License

No data

Last updated

2026-07-02

AI repository intelligence
FR-AI / ANALYSIS

Why it is worth attention

It combines a spring-driven morphing animation (translateY, backdrop opacity, and scale) with auto-sizing to content, a genuine navigation history stack, and keyboard following via react-native-keyboard-controller, offering a first-party feel in a single component.

Who it is for

  • React Native developers building custom bottom sheets or modals
  • Expo users seeking a polished, keyboard-aware tray component
  • Teams that need multi-view navigation inside a sheet with persistent footers
  • Developers who prefer TypeScript-first, fully typed APIs

Use cases

  • Settings panels that morph open and follow the keyboard
  • Multi-step forms or wizards inside a bottom sheet with back navigation
  • Action sheets that auto-size to content and support swipe dismiss
  • Custom modals requiring a persistent footer (e.g., primary action buttons)

Strengths

  • Morphing spring animation creates a smooth, cohesive opening/closing feel
  • Auto-sizing sheet eliminates the need for fixed heights or manual calculations
  • Multi-view history stack with crossfade transitions enables natural drill-down UIs
  • Keyboard-following ensures the tray stays above the keyboard without extra work

Considerations

  • Requires several peer dependencies (reanimated, gesture handler, keyboard controller, etc.) not included out-of-the-box
  • Built specifically for Expo SDK 56 and React Native 0.85, limiting compatibility with older setups
  • Relatively new library; may not have the extensive community testing of more established bottom-sheet solutions

README quick start

expo-dynamic-tray

A morphing, keyboard-aware bottom-sheet tray for React Native.

✨ Features

  • 🫧 Morphing presentation — a single spring drives translateY, backdrop opacity, and sheet scale together, so the tray grows into place instead of just sliding
  • 📐 Auto-sizing — the sheet springs to whatever its content measures; no fixed heights to maintain
  • 🧭 Multi-view navigation with a real history stack — setView("…") pushes, goBack() unwinds however deep you went
  • 🎞️ Crossfade + scale morph between views (incoming views scale/fade in, outgoing ones fade out) for a continuous, first-party feel
  • ⌨️ Keyboard-following via react-native-keyboard-controller — the tray lifts itself above the keyboard and stays glued to it
  • 👆 Swipe / flick to dismiss with both distance-threshold and velocity detection, plus a spring rubber-band return
  • 🧩 Persistent footer slot — pass footer per view; it never unmounts while switching views, so buttons don't pop or collide
  • 🪝 Imperative or declarative — open with `` or drive it from anywhere with useTray().open()
  • 🧠 TypeScript-first, fully typed surface

⚙️ Installation

git clone https://github.com/rit3zh/expo-dynamic-tray
cd expo-dynamic-tray
bun start -c

Peer dependencies (already wired up in this template):

bun add react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-keyboard-controller @expo/ui expo-symbols

🚀 Usage

Wrap your app once with GestureHandlerRootView and KeyboardProvider, then compose a `` anywhere in the tree.

// app/_layout.tsx
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { KeyboardProvider } from "react-native-keyboard-controller";

export default function RootLayout() {
  return (
    
      
        
      
    
  );
}

The simplest possible tray — one trigger, one view:

import { Tray } from "@/components/tray";
import { Text, View } from "react-native";

export function Example() {
  return (
    
      
        Show Tray
      

      
        
          
            Dynamic Tray
            Springs to its content's size and follows the keyboard.
          
        
      
    
  );
}

Preview

https://github.com/user-attachments/assets/f4359500-fa88-464f-a4e9-894903401c1a

Opening imperati

Description

📚 A morphing, keyboard-aware bottom-sheet tray.

Related repositories

Similar projects matched by category, topics, and programming language.

TanStack
Featured
TanStack GitHub avatar

router

TanStack Router is a type-safe, data-driven React router with built-in caching, prefetching, and nested layouts, while TanStack Start extends it into a full-stack SSR framework.

Web DevelopmentFrontend Frameworks
14,861
vercel-labs
Featured
vercel-labs GitHub avatar

scriptc

scriptc compiles ordinary TypeScript into small, fast native executables without needing Node.js, V8, or any JavaScript runtime in the binary.

Developer ToolsCode Quality & Build
1,985
Jakubantalik
Featured
Jakubantalik GitHub avatar

thinking-orbs

A React component library that renders six hand-tuned animated thought orb loading indicators on a plain 2D canvas, with two purpose-tuned sizes and automatic theme detection for AI and agent UIs.

AI & Machine LearningAI Agents
1,191