--- name: expo-glass-effect description: Guide for using expo-glass-effect to create iOS native liquid glass UI effects. Apply when implementing glass effect UI components, cards, or surfaces on iOS. allowed-tools: Read, Edit, Write, Grep, Glob --- # Expo Glass Effect Guide for using `expo-glass-effect` to create iOS native liquid glass UI effects. ## Overview - **Platform**: iOS 26+ only (falls back to regular `View` on unsupported platforms) - **Native API**: Uses `UIVisualEffectView` under the hood - **Package**: `expo-glass-effect` ## Installation ```bash npx expo install expo-glass-effect ``` ## Core Components ### GlassView Primary component for rendering glass effect surfaces. ```tsx import { GlassView } from 'expo-glass-effect'; ``` **Props:** - `glassEffectStyle`: `'regular'` (default) or `'clear'` - `isInteractive`: Boolean for interactive behavior (default: `false`) - `tintColor`: Optional color string for tinting the glass - All standard `View` props (style, children, etc.) ### GlassContainer Wrapper for combining multiple glass views with merged effects. ```tsx import { GlassContainer, GlassView } from 'expo-glass-effect'; ``` **Props:** - `spacing`: Distance (number) at which glass elements start merging effects - All standard `View` props ## Utility Functions ### isLiquidGlassAvailable() Check if glass components are available (validates system version, compiler version, Info.plist settings). ```tsx import { isLiquidGlassAvailable } from 'expo-glass-effect'; if (isLiquidGlassAvailable()) { // Render GlassView } else { // Render fallback UI } ``` **Note**: This checks component availability, not user accessibility settings. Use `AccessibilityInfo.isReduceTransparencyEnabled()` to check if user disabled transparency. ### isGlassEffectAPIAvailable() Runtime check for Glass Effect API availability on device (important for iOS 26 beta compatibility). ```tsx import { isGlassEffectAPIAvailable } from 'expo-glass-effect'; if (isGlassEffectAPIAvailable()) { // Safe to use GlassView } ``` ## Common Patterns ### Basic Glass Card ```tsx import { StyleSheet, View, Image, Text } from 'react-native'; import { GlassView } from 'expo-glass-effect'; export default function GlassCard() { return ( Glass Effect Card ); } const styles = StyleSheet.create({ container: { flex: 1, }, background: { ...StyleSheet.absoluteFill, }, card: { position: 'absolute', top: 100, left: 50, width: 200, height: 100, borderRadius: 12, padding: 20, }, }); ``` ### Merged Glass Elements ```tsx import { GlassContainer, GlassView } from 'expo-glass-effect'; ``` ### Conditional Rendering with Fallback ```tsx import { isLiquidGlassAvailable, GlassView } from 'expo-glass-effect'; import { View } from 'react-native'; function Card({ children, style }) { const GlassComponent = isLiquidGlassAvailable() ? GlassView : View; return ( {children} ); } ``` ## Known Issues & Limitations ### 1. isInteractive Cannot Change Dynamically ```tsx // ❌ BAD - Won't work after initial render const [interactive, setInteractive] = useState(false); // ✅ GOOD - Remount with different key const [interactive, setInteractive] = useState(false); ``` ### 2. Opacity Issues **Avoid `opacity < 1`** on `GlassView` or parent views - causes rendering issues. ```tsx // ❌ BAD // ✅ GOOD - Use tintColor instead ``` ### 3. Platform Support Always wrap in platform checks or use fallback components for cross-platform apps: ```tsx import { Platform } from 'react-native'; import { isLiquidGlassAvailable, GlassView } from 'expo-glass-effect'; const useGlass = Platform.OS === 'ios' && isLiquidGlassAvailable(); ``` ## Styling Best Practices 1. **Always use `position: 'absolute'`** for layering over background content 2. **Use `borderRadius`** to create rounded glass surfaces 3. **Layer backgrounds** using `StyleSheet.absoluteFill` for full coverage 4. **Avoid shadows** - glass effect provides natural depth 5. **Use `padding`** for content spacing within glass views ## Accessibility Check user preference for reduced transparency: ```tsx import { AccessibilityInfo } from 'react-native'; import { isLiquidGlassAvailable, GlassView } from 'expo-glass-effect'; const [reduceTransparency, setReduceTransparency] = useState(false); useEffect(() => { AccessibilityInfo.isReduceTransparencyEnabled().then(setReduceTransparency); }, []); const shouldUseGlass = isLiquidGlassAvailable() && !reduceTransparency; ``` ## References - [Expo Glass Effect Docs](https://docs.expo.dev/versions/latest/sdk/glass-effect/) - [Apple UIVisualEffectView](https://developer.apple.com/documentation/uikit/uivisualeffectview) - [GitHub Issue #41024](https://github.com/expo/expo/issues/41024) - Opacity rendering bug - [GitHub Issue #40911](https://github.com/expo/expo/issues/40911) - iOS 26 beta API availability