From 1af0945a2f915b65e15d6ae14eb28423176e09d5 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Thu, 11 Sep 2025 23:25:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20glass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/_layout.tsx | 39 +++++++++++++++++++++++++++++++++++++-- ios/Podfile.lock | 6 ++++++ package-lock.json | 12 ++++++++++++ package.json | 3 ++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 53cdb14..fd4ad86 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -1,4 +1,5 @@ import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs'; +import { GlassContainer, GlassView, isLiquidGlassAvailable } from 'expo-glass-effect'; import * as Haptics from 'expo-haptics'; import { Tabs, usePathname } from 'expo-router'; import React from 'react'; @@ -27,6 +28,7 @@ export default function TabLayout() { const theme = (useColorScheme() ?? 'light') as 'light' | 'dark'; const colorTokens = Colors[theme]; const pathname = usePathname(); + const glassEffectAvailable = isLiquidGlassAvailable(); // Helper function to determine if a tab is selected const isTabSelected = (routeName: string): boolean => { @@ -96,20 +98,51 @@ export default function TabLayout() { ); }; + // Custom tab bar background component + const TabBarBackground = () => { + if (glassEffectAvailable) { + return ( + + + + ); + } + return null; + }; + // Common screen options const getScreenOptions = (routeName: string): BottomTabNavigationOptions => ({ headerShown: false, tabBarActiveTintColor: colorTokens.tabIconSelected, tabBarButton: createTabButton(routeName), + tabBarBackground: TabBarBackground, tabBarStyle: { position: 'absolute', bottom: TAB_BAR_BOTTOM_OFFSET, height: TAB_BAR_HEIGHT, borderRadius: 34, - backgroundColor: colorTokens.tabBarBackground, + backgroundColor: glassEffectAvailable ? 'transparent' : colorTokens.tabBarBackground, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.2, + shadowOpacity: glassEffectAvailable ? 0.1 : 0.2, shadowRadius: 10, elevation: 5, paddingHorizontal: 10, @@ -119,6 +152,8 @@ export default function TabLayout() { left: 20, right: 20, alignSelf: 'center', + borderWidth: glassEffectAvailable ? 1 : 0, + borderColor: glassEffectAvailable ? (theme === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)') : 'transparent', } as ViewStyle, tabBarItemStyle: { backgroundColor: 'transparent', diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d7f72c0..adcd63c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -57,6 +57,8 @@ PODS: - ExpoModulesCore - ExpoFont (14.0.7): - ExpoModulesCore + - ExpoGlassEffect (0.1.1): + - ExpoModulesCore - ExpoHaptics (15.0.6): - ExpoModulesCore - ExpoHead (6.0.0): @@ -3052,6 +3054,7 @@ DEPENDENCIES: - ExpoCamera (from `../node_modules/expo-camera/ios`) - ExpoFileSystem (from `../node_modules/expo-file-system/ios`) - ExpoFont (from `../node_modules/expo-font/ios`) + - ExpoGlassEffect (from `../node_modules/expo-glass-effect/ios`) - ExpoHaptics (from `../node_modules/expo-haptics/ios`) - ExpoHead (from `../node_modules/expo-router/ios`) - ExpoImage (from `../node_modules/expo-image/ios`) @@ -3203,6 +3206,8 @@ EXTERNAL SOURCES: :path: "../node_modules/expo-file-system/ios" ExpoFont: :path: "../node_modules/expo-font/ios" + ExpoGlassEffect: + :path: "../node_modules/expo-glass-effect/ios" ExpoHaptics: :path: "../node_modules/expo-haptics/ios" ExpoHead: @@ -3426,6 +3431,7 @@ SPEC CHECKSUMS: ExpoCamera: ae1d6691b05b753261a845536d2b19a9788a8750 ExpoFileSystem: 7b4a4f6c67a738e826fd816139bac9d098b3b084 ExpoFont: 74a14c605637c2d32337a2f542065408a8ca3454 + ExpoGlassEffect: 9aa58a46e8abe720971f2b588bc1e10d58728ba8 ExpoHaptics: e0912a9cf05ba958eefdc595f1990b8f89aa1f3f ExpoHead: 275ef6292a9ab92669fd9554f19e1b1bbb5aa986 ExpoImage: 18d9836939f8e271364a5a2a3566f099ea73b2e4 diff --git a/package-lock.json b/package-lock.json index ed91bb5..085b497 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "expo-camera": "~17.0.7", "expo-constants": "~18.0.8", "expo-font": "~14.0.7", + "expo-glass-effect": "^0.1.1", "expo-haptics": "~15.0.6", "expo-image": "~3.0.7", "expo-image-picker": "~17.0.7", @@ -7910,6 +7911,17 @@ "react-native": "*" } }, + "node_modules/expo-glass-effect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expo-glass-effect/-/expo-glass-effect-0.1.1.tgz", + "integrity": "sha512-81xXB2CVjgyg7gaq/fDVAOu/j43uTP0F6bI0sah81v3/guA+YfSM3QjyfegIVQPUkX/9AP2zkU9ihkHEZQv7pg==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, "node_modules/expo-haptics": { "version": "15.0.6", "resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-15.0.6.tgz", diff --git a/package.json b/package.json index 1ee9a6f..ce2f917 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "expo-camera": "~17.0.7", "expo-constants": "~18.0.8", "expo-font": "~14.0.7", + "expo-glass-effect": "^0.1.1", "expo-haptics": "~15.0.6", "expo-image": "~3.0.7", "expo-image-picker": "~17.0.7", @@ -80,4 +81,4 @@ "typescript": "~5.9.2" }, "private": true -} \ No newline at end of file +}