Skip to content
Native Animation
Morphing Glass Surface animation preview

Morphing Glass Surface

React Native Morphing Glass Menu and Bottom Sheet

A single glass surface that transforms from a compact action button into a contextual menu and a focused bottom sheet.

$9 for this animation

Checkout opens soon. Leave your email and we will tell you the moment you can buy it.

One email when checkout opens. No spam.

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

npx nativeanimation add morphing-glass-surface

About this animation

A React Native morphing glass animation can connect an action button, contextual menu, and bottom sheet through one changing surface. This component derives size, position, corner radius, tint, depth, and content reveal from one Reanimated progress value. Springs start at the current position, and a downward Gesture Handler drag follows the same value before settling by release velocity. Expo Blur supplies the translucent material, including an Android blur target. Use it for contextual actions, journal tools, a save-and-share menu, or a focused detail sheet. Choose controlled or uncontrolled state, supply up to four action labels, and customize sheet copy, primary action, blur settings, accent, appearance, font, and background content. Callbacks expose state and action requests, while the ref opens or dismisses the surface.

When to use it

  • Expand a button into contextual actions.
  • Open a focused detail sheet.
  • Group save and share controls.
  • Add a glass tool menu to a journal.

A single glass surface that transforms from a compact action button into a contextual menu and a focused bottom sheet.

Why this one

Each state has one clear trigger: the button opens the menu, every menu row opens the sheet, and the backdrop or sheet handle closes one level. Hidden content cannot intercept touches, and the sheet follows a downward drag on the same continuous progress value that drives the entire morph. The glass keeps a generous, continuous silhouette throughout: a fully pill-shaped button, a 28-point menu, and 34-point top corners on the sheet. Content waits until its shape is nearly settled, keeping transitions crisp instead of crossfading through distorted layouts.

How it works

  1. The component measures its own container and derives button, menu, and sheet geometry from that size.
  2. One Reanimated progress value drives width, height, position, every corner radius, material tint, background depth, and content reveals.
  3. Spring animations always start from the current progress, so a new command can interrupt an in-flight morph.
  4. The sheet pan writes directly to progress and projects release velocity before settling to the sheet or menu.
  5. A BlurTargetView supplies the scene for native Android blur, while clipped BlurView content provides the changing glass shape.

Install

npx expo install expo-blur expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-worklets

Usage

import MorphingGlassSurface from './MorphingGlassSurface';

export function MemoryScreen() {
  return (
    <MorphingGlassSurface
      actions={['Save', 'Share', 'Add a note', 'Move']}
      onActionPress={(action) => selectAction(action)}
    />
  );
}

Customize the material, content, and state:

import { useRef } from 'react';
import MorphingGlassSurface, {
  type MorphingGlassSurfaceRef,
} from './MorphingGlassSurface';

export function JournalScreen() {
  const surfaceRef = useRef<MorphingGlassSurfaceRef>(null);

  return (
    <MorphingGlassSurface
      ref={surfaceRef}
      accentColor="#6E56FF"
      colorScheme="dark"
      glass={{ intensity: 64, tint: 'systemThinMaterialDark' }}
      sheetTitle="Keep this close"
      primaryLabel="Return to menu"
      onChange={(state) => trackSurfaceState(state)}
    />
  );
}

The forwarded ref exposes showMenu(), showSheet(), and dismiss().

Props

PropTypeDefaultDescription
value'button' | 'menu' | 'sheet'—Controlled state.
defaultValue'button' | 'menu' | 'sheet''button'Initial uncontrolled state.
onChange(value) => void—Called when an interaction requests a state.
actionsstring[]Four neutral actionsMenu labels; the first four are shown.
onActionPress(action, index) => void—Called before a menu item opens the sheet.
sheetTitlestring'Make space for what matters'Sheet heading.
sheetBodystringNeutral supporting copySheet description.
primaryLabelstring'Done'Sheet action label.
onPrimaryPress() => void—Called before the sheet returns to the menu.
glass{ intensity?, tint?, highlight? }Material defaultsBlur and highlight controls.
accentColorstring'#6E56FF'Accent and glow color.
colorScheme'light' | 'dark' | 'auto''auto'Material and text scheme.
fontFamilystringSystem fontFont for labels and copy.
backgroundReactNodeAmbient gradientContent rendered behind the glass.
accessibilityLabelstring'Open actions'Collapsed-button label.
styleStyleProp<ViewStyle>—Outer-container style.
testIDstring—Outer-container test identifier.

Compatibility

  • Expo SDK 57
  • React Native 0.86, Reanimated 4.5, and Worklets 0.10
  • iOS: supported; native bundle verified, device verification pending
  • Android: supported; native bundle verified, device verification pending
  • Web: supported and export verified
  • Works in Expo Go because its native dependencies are included in the SDK

Accessibility

The button, backdrop, menu rows, handle, and primary action expose descriptive button roles and labels. All interactive targets are at least 44 points. Touch controls provide alternatives to the drag gesture, hidden states cannot receive pointer or screen-reader focus, and reduced motion switches directly between geometry and content states without spring travel.

FAQ

What opens and closes the morphing glass sheet?
The collapsed button opens the menu and each menu row opens the sheet. The backdrop or sheet handle closes one level; a downward drag can settle back to the menu.
Can I control the glass menu state from my app?
Yes. value supports button, menu, and sheet states, with defaultValue for local state and onChange for requests. The ref exposes showMenu, showSheet, and dismiss.
Does the glass surface require a development build?
No. Its Expo Blur, Expo Linear Gradient, Gesture Handler, Reanimated, and Worklets dependencies are included in Expo SDK 57. Reduce Motion switches geometry and content directly.