mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 23:39:40 +02:00
533 lines
14 KiB
Markdown
533 lines
14 KiB
Markdown
# 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](#technology)
|
||
- [Why Liquid Glass?](#why-liquid-glass)
|
||
- [Implementation Details](#implementation-details)
|
||
- [Components Using Liquid Glass](#components-using-liquid-glass)
|
||
- [Configuration](#configuration)
|
||
- [Platform Support](#platform-support)
|
||
- [Performance Considerations](#performance-considerations)
|
||
- [Future Improvements](#future-improvements)
|
||
|
||
---
|
||
|
||
## Technology
|
||
|
||
### Library: `@callstack/liquid-glass`
|
||
|
||
**Version:** ^0.4.2
|
||
|
||
**Installation:**
|
||
```bash
|
||
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
|
||
|
||
```tsx
|
||
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`:
|
||
|
||
```tsx
|
||
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:**
|
||
```tsx
|
||
<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:**
|
||
```tsx
|
||
<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:**
|
||
```tsx
|
||
<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:**
|
||
```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)
|
||
|
||
```tsx
|
||
import { BlurView } from 'expo-blur';
|
||
|
||
<BlurView
|
||
intensity={80}
|
||
tint="systemChromeMaterialDark"
|
||
style={styles.container}
|
||
>
|
||
<View>{/* Content */}</View>
|
||
</BlurView>
|
||
```
|
||
|
||
### After (liquid-glass)
|
||
|
||
```tsx
|
||
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:**
|
||
```tsx
|
||
// ✅ 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:
|
||
```tsx
|
||
<LiquidGlassView
|
||
style={{
|
||
borderRadius: 26,
|
||
overflow: 'hidden', // ← Critical for rounded corners
|
||
}}
|
||
>
|
||
```
|
||
|
||
---
|
||
|
||
## References
|
||
|
||
### Documentation
|
||
- [Callstack Liquid Glass Blog Post](https://www.callstack.com/blog/how-to-use-liquid-glass-in-react-native)
|
||
- [NPM Package](https://www.npmjs.com/package/@callstack/liquid-glass)
|
||
- [Expo SDK 54 Changelog](https://expo.dev/changelog/sdk-54)
|
||
|
||
### Related Files
|
||
- `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
|