managarten/apps/picture/docs/features/LIQUID_GLASS.md
Wuesteon ff80aeec1f refactor: restructure
monorepo with apps/ and services/
  directories
2025-11-26 03:03:24 +01:00

14 KiB

Liquid Glass UI Implementation

Overview

This document describes the implementation of Apple's Liquid Glass design language in the Picture app using the @callstack/liquid-glass library. Liquid Glass provides a modern, translucent UI effect available on iOS 26+ with graceful fallbacks for older iOS versions.

Table of Contents


Technology

Library: @callstack/liquid-glass

Version: ^0.4.2

Installation:

npm install @callstack/liquid-glass

Key Features:

  • Native iOS Liquid Glass effects on iOS 26+
  • Automatic graceful fallback for iOS < 26
  • GPU-accelerated blur effects
  • Interactive touch feedback
  • Works with Expo SDK 54
  • Zero breaking changes for older devices

Alternative Considered

expo-glass-effect (Official Expo package)

  • Only works on iOS 26+ (no fallback)
  • Requires Xcode 26 beta
  • Known bugs in device builds
  • Not compatible with older iOS versions

Decision: We chose @callstack/liquid-glass for better compatibility and graceful degradation.


Why Liquid Glass?

Design Benefits

  1. Modern iOS Aesthetic

    • Aligns with iOS 26 design language
    • Provides visual depth and hierarchy
    • Creates premium, polished UI feel
  2. Improved Readability

    • Dynamic blur adapts to background
    • Maintains contrast automatically
    • Better focus on important UI elements
  3. Performance

    • GPU-accelerated rendering
    • Real-time blur calculations
    • Smooth animations and transitions
  4. User Experience

    • Interactive touch feedback
    • Familiar iOS design patterns
    • Consistent with native apps

Implementation Details

Basic Usage

import { LiquidGlassView } from '@callstack/liquid-glass';
import { PlatformColor } from 'react-native';

<LiquidGlassView
  effect="regular"         // 'clear' or 'regular'
  interactive={true}       // Enable touch feedback
  colorScheme="system"     // 'light', 'dark', or 'system'
  style={styles.container}
>
  {/* Your content with adaptive colors */}
  <Text style={{ color: PlatformColor('labelColor') }}>
    Adaptive Text
  </Text>
</LiquidGlassView>

Props Configuration

Prop Type Default Description
effect 'clear' | 'regular' 'regular' Glass effect style. 'regular' = stronger blur, 'clear' = minimal blur
interactive boolean false Enable interactive touch feedback effects
colorScheme 'light' | 'dark' | 'system' - Control appearance. 'system' auto-adapts to device theme
tintColor string - Optional color overlay
style ViewStyle - Standard React Native styles

Adaptive Content with PlatformColor

To make text and UI elements automatically adapt to the background behind the Liquid Glass, use PlatformColor:

import { PlatformColor } from 'react-native';

// Adaptive text color
<Text style={{ color: PlatformColor('labelColor') }}>
  This text adapts to the background
</Text>

// Adaptive icon color
<Ionicons
  name="heart"
  size={24}
  color={PlatformColor('labelColor')}
/>

// Adaptive border color
<View style={{
  borderWidth: 2,
  borderColor: PlatformColor('separatorColor')
}}>
  {/* Content */}
</View>

// Adaptive placeholder text
<TextInput
  placeholder="Type here..."
  placeholderTextColor={PlatformColor('placeholderTextColor')}
  style={{ color: PlatformColor('labelColor') }}
/>

Important Notes:

  • ⚠️ Adaptive colors only work if the glass view height is < 65px
  • For taller views, the glass effect is static and won't adapt to content behind it
  • Use colorScheme="system" for automatic light/dark mode switching

Available PlatformColors:

Color Usage
labelColor Primary text and icons
secondaryLabelColor Secondary text
tertiaryLabelColor Tertiary/hint text
placeholderTextColor Input placeholder text
separatorColor Borders and dividers
systemBackgroundColor Background surfaces

Components Using Liquid Glass

1. QuickGenerateBar

Location: components/QuickGenerateBar.tsx

Implementation:

  • 3 instances of LiquidGlassView replaced BlurView
  • Used for: Extended menu panel, FAB icon, main bar
  • All content uses PlatformColor for adaptive styling

Configuration:

<LiquidGlassView
  effect="regular"
  interactive={true}
  colorScheme="system"
  style={{ borderRadius: 16, overflow: 'hidden' }}
>
  {/* Adaptive content */}
  <Ionicons name="sparkles" size={20} color={PlatformColor('labelColor')} />
  <TextInput
    style={{ color: PlatformColor('labelColor') }}
    placeholderTextColor={PlatformColor('placeholderTextColor')}
  />
</LiquidGlassView>

Visual Elements:

  1. Extended Settings Panel - Full options menu with blur backdrop
  2. FAB Icon - Minimized floating action button
  3. Main Input Bar - Quick generate text input with actions

User Benefits:

  • Premium feel when generating images
  • 🎯 Better visual separation from gallery
  • 📱 Modern iOS-aligned design
  • 🌓 Automatic light/dark mode adaptation

2. FilterBar

Location: components/FilterBar.tsx

Implementation:

  • 2 instances of LiquidGlassView (FAB + expanded bar)
  • All icons, text, and borders use adaptive PlatformColor
  • Favorites and tag filter pills

Configuration:

<LiquidGlassView
  effect="regular"
  interactive={true}
  colorScheme="system"
  style={{ borderRadius: 999, overflow: 'hidden' }}
>
  {/* Pills with adaptive styling */}
  <View style={{
    borderWidth: 2,
    borderColor: PlatformColor('separatorColor')
  }}>
    <Ionicons color={PlatformColor('labelColor')} />
    <Text style={{ color: PlatformColor('labelColor') }}>Label</Text>
  </View>
</LiquidGlassView>

Adaptive Elements:

  • Filter icon (FAB)
  • Favorites pill icon and text
  • Tag pill text
  • Clear filters icon
  • Tag management icon
  • All pill borders

3. ExploreSortBar

Location: components/ExploreSortBar.tsx

Implementation:

  • 2 instances of LiquidGlassView (FAB + expanded bar)
  • Sort mode pills (Neueste, Beliebt, Trending) with adaptive colors
  • Tag filter pills with adaptive styling

Configuration:

<LiquidGlassView
  effect="regular"
  interactive={true}
  colorScheme="system"
  style={{ borderRadius: 999, overflow: 'hidden' }}
>
  {/* Sort pills with adaptive styling */}
  <Ionicons
    name="time-outline"
    color={isSelected ? 'white' : PlatformColor('labelColor')}
  />
</LiquidGlassView>

Adaptive Elements:

  • Funnel icon (FAB)
  • Sort mode icons (time, heart)
  • Sort mode text
  • Tag pill text
  • Clear filters icon
  • All pill borders

Configuration

Development Setup

No additional configuration required! The library works out-of-the-box with Expo SDK 54.

EAS Build (Optional - for iOS 26 features)

To enable full iOS 26 Liquid Glass features in production builds:

eas.json:

{
  "build": {
    "production": {
      "ios": {
        "image": "macos-sequoia-15.5-xcode-26.0"
      }
    }
  }
}

⚠️ Note: This is optional. The app works perfectly on older iOS versions with automatic fallback.


Platform Support

iOS 26+

  • Full Liquid Glass effects
  • GPU-accelerated blur
  • Interactive touch feedback
  • Real-time blur updates

iOS < 26

  • Automatic fallback to standard blur
  • Same visual hierarchy maintained
  • No breaking changes
  • Graceful degradation

Android

  • ⚠️ Not applicable (iOS-only feature)
  • Renders as standard View
  • No crashes or errors

Performance Considerations

Best Practices

  1. Use Sparingly

    • Apply only to key UI elements (bars, modals, cards)
    • Avoid excessive layering
    • Don't use on every component
  2. Optimize Hierarchy

    • Keep view hierarchy shallow
    • Minimize nested LiquidGlassViews
    • Use interactive={false} when touch feedback not needed
  3. Monitor Performance

    • GPU usage is efficient but not free
    • Test on older devices (iPhone 12, 13)
    • Profile in release builds

Current Usage

Total LiquidGlassView Instances: 7

  • QuickGenerateBar: 3 instances (settings panel, FAB, main bar)
  • FilterBar: 2 instances (FAB, expanded bar)
  • ExploreSortBar: 2 instances (FAB, expanded bar)
  • No performance issues observed
  • Smooth 60 FPS on iPhone 13 and newer
  • All instances use PlatformColor for adaptive content

Future Improvements

Potential Enhancements

  1. FilterBar Component - DONE

    • Added Liquid Glass to filter/tag bar
    • Consistency with QuickGenerateBar
    • Adaptive colors with PlatformColor
  2. ExploreSortBar Component - DONE

    • Added Liquid Glass to explore sort bar
    • Adaptive colors for all UI elements
  3. RemixBottomSheet

    • Replace solid background with Liquid Glass
    • Modern modal appearance
  4. ImageCard Grid Overlays

    • Tag/info overlays with blur effect
    • Better readability on images
  5. LiquidGlassContainerView

    • Use container for merging glass effects
    • Smooth transitions between elements

Design Considerations

When to Use:

  • Navigation bars and headers
  • Modal overlays and bottom sheets
  • Floating action buttons
  • Quick action bars

When to Avoid:

  • List items (performance impact)
  • Rapidly animating elements
  • Full-screen backgrounds
  • Non-critical UI elements

Code Examples

Before (expo-blur)

import { BlurView } from 'expo-blur';

<BlurView
  intensity={80}
  tint="systemChromeMaterialDark"
  style={styles.container}
>
  <View>{/* Content */}</View>
</BlurView>

After (liquid-glass)

import { LiquidGlassView } from '@callstack/liquid-glass';
import { PlatformColor } from 'react-native';

<LiquidGlassView
  effect="regular"
  interactive={true}
  colorScheme="system"
  style={styles.container}
>
  <View>
    <Text style={{ color: PlatformColor('labelColor') }}>
      Adaptive Content
    </Text>
  </View>
</LiquidGlassView>

Key Differences

Feature expo-blur liquid-glass
iOS 26+ Support No Yes
Fallback None Automatic
Interactive No Yes
GPU Acceleration ⚠️ Limited Full
Compatibility All iOS All iOS
Adaptive Content No Yes (with PlatformColor)
System Theme ⚠️ Manual Automatic (colorScheme="system")

Troubleshooting

Issue: Liquid Glass not visible

Check:

  1. Device is running iOS 26+ for full effect
  2. effect="regular" is set (stronger blur than "clear")
  3. Background has content to blur
  4. View has proper dimensions
  5. borderRadius and overflow: 'hidden' are set

Issue: Performance lag

Solutions:

  1. Reduce number of LiquidGlassView instances
  2. Set interactive={false} where not needed
  3. Simplify view hierarchy
  4. Test on device (not just simulator)

Issue: Fallback looks different

This is expected!

  • Older iOS versions show standard blur
  • Visual hierarchy is maintained
  • Functionality remains identical

Issue: Content not adapting to background

Check:

  1. Are you using PlatformColor for text/icons?
  2. Is the glass view height < 65px? (Limitation of adaptive colors)
  3. Is colorScheme="system" set?

Solution:

// ✅ Correct - Adaptive
<Text style={{ color: PlatformColor('labelColor') }}>Text</Text>

// ❌ Wrong - Static
<Text style={{ color: 'black' }}>Text</Text>

Issue: Rendering artifacts on rounded corners

Solution: Always add overflow: 'hidden' to the LiquidGlassView style:

<LiquidGlassView
  style={{
    borderRadius: 26,
    overflow: 'hidden', // ← Critical for rounded corners
  }}
>

References

Documentation

  • components/QuickGenerateBar.tsx - Main implementation with adaptive colors
  • components/FilterBar.tsx - Filter bar with Liquid Glass
  • components/ExploreSortBar.tsx - Explore sort bar with Liquid Glass
  • package.json - Dependency configuration

Summary

Liquid Glass implementation provides a modern, iOS 26-aligned design language while maintaining full backward compatibility. The @callstack/liquid-glass library ensures graceful degradation on older devices, making it a production-ready solution for premium UI effects. All content within Liquid Glass views uses PlatformColor for dynamic adaptation to backgrounds.

Key Takeaways:

  • Modern iOS 26 design language
  • Zero breaking changes
  • Automatic fallback for older iOS
  • GPU-accelerated performance
  • Adaptive content with PlatformColor
  • System theme support (light/dark auto-switching)
  • Production-ready

Implementation Stats:

  • 7 LiquidGlassView instances across 3 components
  • All use effect="regular" for stronger blur
  • All use colorScheme="system" for auto-theming
  • All content uses PlatformColor for adaptive styling
  • Icons, text, borders all adapt to background

Status: Implemented and tested Last Updated: 2025-10-08