u'
This commit is contained in:
1 parent
cd191fdc60
commit
4fe17847d0
18 files changed
+474
-130
No files matched your search
@@ -32,6 +32,7 @@
|
||||
"expo-symbols": "~55.0.7",
|
||||
"expo-system-ui": "~55.0.15",
|
||||
"expo-web-browser": "~55.0.14",
|
||||
"lucide-react-native": "^1.8.0",
|
||||
"nativewind": "^4.2.3",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
|
||||
Generated
+41
-1
@@ -71,6 +71,9 @@ importers:
|
||||
expo-web-browser:
|
||||
specifier: ~55.0.14
|
||||
version: 55.0.14(expo@55.0.13)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
|
||||
lucide-react-native:
|
||||
specifier: ^1.8.0
|
||||
version: 1.8.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
|
||||
nativewind:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(tailwindcss@3.4.19(yaml@2.8.3))
|
||||
@@ -999,48 +1002,56 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-arm64-musl@0.44.0':
|
||||
resolution: {integrity: sha512-AlObQIXyVRZ96LbtVljtFq0JqH5B92NU+BQeDFrXWBUWlCKAM0wF5GLfIhCLT5kQ3Sl+U0YjRJ7Alqj5hGQaCg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.44.0':
|
||||
resolution: {integrity: sha512-YcFE8/q/BbrCiIiM5piwbkA6GwJc5QqhMQp2yDrqQ2fuVkZ7CInb1aIijZ/k8EXc72qXMSwKpVlBv1w/MsGO/A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.44.0':
|
||||
resolution: {integrity: sha512-eOdzs6RqkRzuqNHUX5C8ISN5xfGh4xDww8OEd9YAmc3OWN8oAe5bmlIqQ+rrHLpv58/0BuU48bxkhnIGjA/ATQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.44.0':
|
||||
resolution: {integrity: sha512-YBgNTxntD/QvlFUfgvh8bEdwOhXiquX8gaofZJAwYa/Xp1S1DQrFVZEeck7GFktr24DztsSp8N8WtWCBwxs0Hw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.44.0':
|
||||
resolution: {integrity: sha512-GLIh1R6WHWshl/i4QQDNgj0WtT25aRO4HNUWEoitxiywyRdhTFmFEYT2rXlcl9U6/26vhmOqG5cRlMLG3ocaIA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-gnu@0.44.0':
|
||||
resolution: {integrity: sha512-gZOpgTlOsLcLfAF9qgpTr7FIIFSKnQN3hDf/0JvQ4CIwMY7h+eilNjxq/CorqvYcEOu+LRt1W4ZS7KccEHLOdA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-musl@0.44.0':
|
||||
resolution: {integrity: sha512-1CyS9JTB+pCUFYFI6pkQGGZaT/AY5gnhHVrQQLhFba6idP9AzVYm1xbdWfywoldTYvjxQJV6x4SuduCIfP3W+A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-openharmony-arm64@0.44.0':
|
||||
resolution: {integrity: sha512-bmEv70Ak6jLr1xotCbF5TxIKjsmQaiX+jFRtnGtfA03tJPf6VG3cKh96S21boAt3JZc+Vjx8PYcDuLj39vM2Pw==}
|
||||
@@ -1113,48 +1124,56 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-arm64-musl@1.59.0':
|
||||
resolution: {integrity: sha512-3CtsKp7NFB3OfqQzbuAecrY7GIZeiv7AD+xutU4tefVQzlfmTI7/ygWLrvkzsDEjTlMq41rYHxgsn6Yh8tybmA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.59.0':
|
||||
resolution: {integrity: sha512-K0diOpT3ncDmOfl9I1HuvpEsAuTxkts0VYwIv/w6Xiy9CdwyPBVX88Ga9l8VlGgMrwBMnSY4xIvVlVY/fkQk7Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.59.0':
|
||||
resolution: {integrity: sha512-xAU7+QDU6kTJJ7mJLOGgo7oOjtAtkKyFZ0Yjdb5cEo3DiCCPFLvyr08rWiQh6evZ7RiUTf+o65NY/bqttzJiQQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-musl@1.59.0':
|
||||
resolution: {integrity: sha512-KUmZmKlTTyauOnvUNVxK7G40sSSx0+w5l1UhaGsC6KPpOYHenx2oqJTnabmpLJicok7IC+3Y6fXAUOMyexaeJQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-s390x-gnu@1.59.0':
|
||||
resolution: {integrity: sha512-4usRxC8gS0PGdkHnRmwJt/4zrQNZyk6vL0trCxwZSsAKM+OxhB8nKiR+mhjdBbl8lbMh2gc3bZpNN/ik8c4c2A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-gnu@1.59.0':
|
||||
resolution: {integrity: sha512-s/rNE2gDmbwAOOP493xk2X7M8LZfI1LJFSSW1+yanz3vuQCFPiHkx4GY+O1HuLUDtkzGlhtMrIcxxzyYLv308w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-musl@1.59.0':
|
||||
resolution: {integrity: sha512-+yYj1udJa2UvvIUmEm0IcKgc0UlPMgz0nsSTvkPL2y6n0uU5LgIHSwVu4AHhrve6j9BpVSoRksnz8c9QcvITJA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-openharmony-arm64@1.59.0':
|
||||
resolution: {integrity: sha512-bUplUb48LYsB3hHlQXP2ZMOenpieWoOyppLAnnAhuPag3MGPnt+7caxE3w/Vl9wpQsTA3gzLntQi9rxWrs7Xqg==}
|
||||
@@ -2932,7 +2951,7 @@ packages:
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
@@ -3208,48 +3227,56 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-gnu@1.32.0:
|
||||
resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.27.0:
|
||||
resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.27.0:
|
||||
resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.32.0:
|
||||
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.27.0:
|
||||
resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.27.0:
|
||||
resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==}
|
||||
@@ -3318,6 +3345,13 @@ packages:
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
lucide-react-native@1.8.0:
|
||||
resolution: {integrity: sha512-trgqSA2ghSHUE3yLUBTdhjF1EMbgcJuccI1VXe6zTI2u4tbeUXbtXeHGORRdeGUdC80XBn/XJa1YrG8uvKhpNg==}
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-native: '*'
|
||||
react-native-svg: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0
|
||||
|
||||
makeerror@1.0.12:
|
||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||
|
||||
@@ -8414,6 +8448,12 @@ snapshots:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
|
||||
lucide-react-native@1.8.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0):
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
|
||||
react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
|
||||
|
||||
makeerror@1.0.12:
|
||||
dependencies:
|
||||
tmpl: 1.0.5
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function RootLayout() {
|
||||
|
||||
return (
|
||||
<ThemeProvider value={isDark ? DarkTheme : DefaultTheme}>
|
||||
<StatusBar style={isDark ? "light" : "dark"} />
|
||||
{/* <StatusBar style={isDark ? "light" : "dark"} /> */}
|
||||
|
||||
<Stack screenOptions={{ headerShown: false }} />
|
||||
</ThemeProvider>
|
||||
|
||||
+102
-128
@@ -1,144 +1,118 @@
|
||||
import { BlurTargetView, BlurView } from "expo-blur";
|
||||
import React, { useRef } from "react";
|
||||
import { ScrollView, StyleSheet, Text, View } from "react-native";
|
||||
|
||||
export default function OnlyBlurDemo() {
|
||||
const targetRef = useRef(null);
|
||||
import Layout from "@/components/layout";
|
||||
import { View, Text } from "react-native";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{/* 👇 Blur 目标区域 */}
|
||||
<BlurTargetView ref={targetRef} style={{ flex: 1 }}>
|
||||
<ScrollView
|
||||
contentContainerStyle={{ padding: 16, paddingBottom: 120 }}
|
||||
removeClippedSubviews={false}
|
||||
scrollEventThrottle={16}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<View style={[styles.card, { backgroundColor: "#4EA0FF" }]}>
|
||||
<Text style={styles.cardText}>蓝色卡片</Text>
|
||||
</View>
|
||||
|
||||
<View style={[styles.card, { backgroundColor: "#FF9500" }]}>
|
||||
<Text style={styles.cardText}>橙色卡片</Text>
|
||||
</View>
|
||||
|
||||
<View style={[styles.card, { backgroundColor: "#34C759" }]}>
|
||||
<Text style={styles.cardText}>绿色卡片</Text>
|
||||
</View>
|
||||
|
||||
{Array.from({ length: 10 }).map((_, i) => (
|
||||
<View
|
||||
key={i}
|
||||
style={[
|
||||
styles.listItem,
|
||||
{
|
||||
backgroundColor: i % 2 === 0 ? "#FFFFFF" : "#F2F2F7",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Text style={styles.listText}>列表项 {i + 1}</Text>
|
||||
</View>
|
||||
))}
|
||||
|
||||
<View style={[styles.card, { backgroundColor: "#AF52DE" }]}>
|
||||
<Text style={styles.cardText}>紫色区域</Text>
|
||||
</View>
|
||||
|
||||
<View style={[styles.card, { backgroundColor: "#FF2D55" }]}>
|
||||
<Text style={styles.cardText}>红色区域</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</BlurTargetView>
|
||||
|
||||
{/* 👇 毛玻璃底部栏(稳定版) */}
|
||||
<BlurView
|
||||
intensity={60}
|
||||
tint="light"
|
||||
blurMethod="dimezisBlurView"
|
||||
blurTarget={targetRef}
|
||||
style={styles.blur}
|
||||
>
|
||||
{/* 用 overlay 替代 opacity(避免闪烁) */}
|
||||
<View style={styles.overlay} />
|
||||
|
||||
<View style={styles.tabContent}>
|
||||
<Text style={styles.tabText}>TabBar</Text>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
<Layout>
|
||||
<View>
|
||||
<Text>123</Text>
|
||||
</View>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
blur: {
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
height: 56,
|
||||
overflow: "hidden",
|
||||
borderRadius: 999,
|
||||
margin: 16,
|
||||
// import React, { useState } from "react";
|
||||
// import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
|
||||
// import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
// ✨ 关键:只保留极轻“环境感”
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 10 },
|
||||
shadowOpacity: 0.03,
|
||||
shadowRadius: 20,
|
||||
// const TABS = [
|
||||
// { label: "首页", icon: "home-outline", activeIcon: "home" },
|
||||
// { label: "统计", icon: "stats-chart-outline", activeIcon: "stats-chart" },
|
||||
// { label: "应用", icon: "grid-outline", activeIcon: "grid" }, // 中间
|
||||
// { label: "聊天", icon: "chatbubble-ellipses-outline", activeIcon: "chatbubble-ellipses" },
|
||||
// { label: "我的", icon: "person-outline", activeIcon: "person" },
|
||||
// ];
|
||||
|
||||
// Android 基本关闭
|
||||
elevation: 0,
|
||||
// export default function CapsuleTabBarIconDemo() {
|
||||
// const [active, setActive] = useState(0);
|
||||
|
||||
// ✨ 玻璃底(很关键)
|
||||
backgroundColor: "rgba(255,255,255,0.10)",
|
||||
// return (
|
||||
// <View style={styles.container}>
|
||||
// <View style={{ flex: 1 }} />
|
||||
|
||||
// ✨ 极弱边缘,不要存在感
|
||||
borderWidth: 0.5,
|
||||
borderColor: "rgba(255,255,255,0.12)",
|
||||
},
|
||||
// {/* 👇 悬浮 TabBar */}
|
||||
// <View style={styles.wrapper}>
|
||||
// <View style={styles.tabBar}>
|
||||
// {TABS.map((item, index) => {
|
||||
// const isActive = index === active;
|
||||
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: "rgba(249,249,249,0.4)",
|
||||
},
|
||||
// return (
|
||||
// <TouchableOpacity
|
||||
// key={index}
|
||||
// style={styles.tabItem}
|
||||
// onPress={() => setActive(index)}
|
||||
// activeOpacity={0.8}
|
||||
// >
|
||||
// <Ionicons
|
||||
// name={isActive ? item.activeIcon : item.icon}
|
||||
// size={20}
|
||||
// color={isActive ? "#111" : "#888"}
|
||||
// />
|
||||
|
||||
tabContent: {
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
// <Text style={[styles.text, isActive && styles.activeText]}>{item.label}</Text>
|
||||
// </TouchableOpacity>
|
||||
// );
|
||||
// })}
|
||||
// </View>
|
||||
// </View>
|
||||
// </View>
|
||||
// );
|
||||
// }
|
||||
|
||||
tabText: {
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
color: "#333",
|
||||
},
|
||||
// const styles = StyleSheet.create({
|
||||
// container: {
|
||||
// flex: 1,
|
||||
// backgroundColor: "#F2F3F5",
|
||||
// },
|
||||
|
||||
card: {
|
||||
height: 120,
|
||||
borderRadius: 16,
|
||||
marginBottom: 16,
|
||||
padding: 16,
|
||||
justifyContent: "flex-end",
|
||||
},
|
||||
// wrapper: {
|
||||
// position: "absolute",
|
||||
// left: 0,
|
||||
// right: 0,
|
||||
// bottom: 24,
|
||||
// alignItems: "center",
|
||||
// },
|
||||
|
||||
cardText: {
|
||||
color: "#FFFFFF",
|
||||
fontSize: 18,
|
||||
fontWeight: "600",
|
||||
},
|
||||
// tabBar: {
|
||||
// flexDirection: "row",
|
||||
// height: 64,
|
||||
// paddingHorizontal: 8,
|
||||
// borderRadius: 999,
|
||||
|
||||
listItem: {
|
||||
height: 60,
|
||||
borderRadius: 12,
|
||||
marginBottom: 12,
|
||||
paddingHorizontal: 16,
|
||||
justifyContent: "center",
|
||||
},
|
||||
// // ✅ 半透明更高级
|
||||
// backgroundColor: "rgba(255,255,255,0.95)",
|
||||
|
||||
listText: {
|
||||
fontSize: 16,
|
||||
color: "#333",
|
||||
},
|
||||
});
|
||||
// // ✅ 极弱阴影(可去掉)
|
||||
// shadowColor: "#000",
|
||||
// shadowOffset: { width: 0, height: 4 },
|
||||
// shadowOpacity: 0.05,
|
||||
// shadowRadius: 12,
|
||||
// },
|
||||
|
||||
// tabItem: {
|
||||
// flex: 1,
|
||||
// alignItems: "center",
|
||||
// justifyContent: "center",
|
||||
// },
|
||||
|
||||
// text: {
|
||||
// fontSize: 11,
|
||||
// marginTop: 2,
|
||||
// color: "#888",
|
||||
// },
|
||||
|
||||
// activeText: {
|
||||
// color: "#111",
|
||||
// fontWeight: "600",
|
||||
// },
|
||||
|
||||
// // ⭐ 精髓:比背景高亮更高级
|
||||
// indicator: {
|
||||
// position: "absolute",
|
||||
// bottom: 6,
|
||||
// width: 16,
|
||||
// height: 3,
|
||||
// borderRadius: 2,
|
||||
// backgroundColor: "#111",
|
||||
// },
|
||||
// });
|
||||
@@ -0,0 +1,72 @@
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import React, { ReactNode } from "react";
|
||||
import { View, Text } from "react-native";
|
||||
import Ionicons from "@expo/vector-icons/Ionicons";
|
||||
import AntDesign from "@expo/vector-icons/AntDesign";
|
||||
import { ChevronLeft, SwatchBook, CircleChevronLeft, CirclePower } from "lucide-react-native";
|
||||
|
||||
type LayoutProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function Layout({ children }: LayoutProps) {
|
||||
const insets = useSafeAreaInsets();
|
||||
return (
|
||||
<View className="flex-1 bg-white">
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
paddingTop: insets.top + 44,
|
||||
paddingBottom: insets.bottom + 56,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</View>
|
||||
<View
|
||||
className="absolute top-0 left-0 right-0"
|
||||
style={{
|
||||
paddingTop: insets.top,
|
||||
height: insets.top + 48,
|
||||
}}
|
||||
>
|
||||
<View className="h-12 flex-row items-center px-3">
|
||||
{/* 左区域 */}
|
||||
<View className="h-12 w-12 rounded-full bg-white items-center justify-center shadow-md">
|
||||
<ChevronLeft size={28} />
|
||||
</View>
|
||||
|
||||
{/* 中间标题 */}
|
||||
<View className="flex-1 items-center ">
|
||||
<Text className="text-xl font-semibold text-black">记账</Text>
|
||||
</View>
|
||||
|
||||
{/* 右区域 */}
|
||||
<View className="w-28 ">
|
||||
<View className="h-12 flex-row items-center rounded-full bg-white shadow-md overflow-hidden">
|
||||
<View className="px-4 items-center justify-center">
|
||||
<SwatchBook size={22} />
|
||||
</View>
|
||||
|
||||
<View className="w-[1px] h-4 bg-black/10" />
|
||||
|
||||
<View className="px-4 items-center justify-center">
|
||||
<CirclePower size={22} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
paddingBottom: insets.bottom,
|
||||
}}
|
||||
>
|
||||
<Text>footer</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { View, ViewProps } from 'react-native';
|
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { boxStyle } from './styles';
|
||||
|
||||
type IBoxProps = ViewProps &
|
||||
VariantProps<typeof boxStyle> & { className?: string };
|
||||
|
||||
const Box = React.forwardRef<React.ComponentRef<typeof View>, IBoxProps>(
|
||||
function Box({ className, ...props }, ref) {
|
||||
return (
|
||||
<View ref={ref} {...props} className={boxStyle({ class: className })} />
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Box.displayName = 'Box';
|
||||
export { Box };
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { boxStyle } from './styles';
|
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
type IBoxProps = React.ComponentPropsWithoutRef<'div'> &
|
||||
VariantProps<typeof boxStyle> & { className?: string };
|
||||
|
||||
const Box = React.forwardRef<HTMLDivElement, IBoxProps>(function Box(
|
||||
{ className, ...props },
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<div ref={ref} className={boxStyle({ class: className })} {...props} />
|
||||
);
|
||||
});
|
||||
|
||||
Box.displayName = 'Box';
|
||||
export { Box };
|
||||
@@ -0,0 +1,10 @@
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
|
||||
: '';
|
||||
|
||||
export const boxStyle = tva({
|
||||
base: baseStyle,
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { View, ViewProps } from 'react-native';
|
||||
import React from 'react';
|
||||
import { centerStyle } from './styles';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
type ICenterProps = ViewProps & VariantProps<typeof centerStyle>;
|
||||
|
||||
const Center = React.forwardRef<React.ComponentRef<typeof View>, ICenterProps>(
|
||||
function Center({ className, ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
className={centerStyle({ class: className })}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Center.displayName = 'Center';
|
||||
|
||||
export { Center };
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { centerStyle } from './styles';
|
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
type ICenterProps = React.ComponentPropsWithoutRef<'div'> &
|
||||
VariantProps<typeof centerStyle>;
|
||||
|
||||
const Center = React.forwardRef<HTMLDivElement, ICenterProps>(function Center(
|
||||
{ className, ...props },
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<div className={centerStyle({ class: className })} {...props} ref={ref} />
|
||||
);
|
||||
});
|
||||
|
||||
Center.displayName = 'Center';
|
||||
|
||||
export { Center };
|
||||
@@ -0,0 +1,8 @@
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb ? 'flex flex-col relative z-0' : '';
|
||||
|
||||
export const centerStyle = tva({
|
||||
base: `justify-center items-center ${baseStyle}`,
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { View } from 'react-native';
|
||||
import type { ViewProps } from 'react-native';
|
||||
import { hstackStyle } from './styles';
|
||||
|
||||
type IHStackProps = ViewProps & VariantProps<typeof hstackStyle>;
|
||||
|
||||
const HStack = React.forwardRef<React.ComponentRef<typeof View>, IHStackProps>(
|
||||
function HStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
className={hstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
HStack.displayName = 'HStack';
|
||||
|
||||
export { HStack };
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { hstackStyle } from './styles';
|
||||
|
||||
type IHStackProps = React.ComponentPropsWithoutRef<'div'> &
|
||||
VariantProps<typeof hstackStyle>;
|
||||
|
||||
const HStack = React.forwardRef<React.ComponentRef<'div'>, IHStackProps>(
|
||||
function HStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<div
|
||||
className={hstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
HStack.displayName = 'HStack';
|
||||
|
||||
export { HStack };
|
||||
@@ -0,0 +1,25 @@
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'flex relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
|
||||
: '';
|
||||
|
||||
export const hstackStyle = tva({
|
||||
base: `flex-row ${baseStyle}`,
|
||||
variants: {
|
||||
space: {
|
||||
'xs': 'gap-1',
|
||||
'sm': 'gap-2',
|
||||
'md': 'gap-3',
|
||||
'lg': 'gap-4',
|
||||
'xl': 'gap-5',
|
||||
'2xl': 'gap-6',
|
||||
'3xl': 'gap-7',
|
||||
'4xl': 'gap-8',
|
||||
},
|
||||
reversed: {
|
||||
true: 'flex-row-reverse',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { View } from 'react-native';
|
||||
|
||||
import { vstackStyle } from './styles';
|
||||
|
||||
type IVStackProps = React.ComponentProps<typeof View> &
|
||||
VariantProps<typeof vstackStyle>;
|
||||
|
||||
const VStack = React.forwardRef<React.ComponentRef<typeof View>, IVStackProps>(
|
||||
function VStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
className={vstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
VStack.displayName = 'VStack';
|
||||
|
||||
export { VStack };
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
import { vstackStyle } from './styles';
|
||||
|
||||
type IVStackProps = React.ComponentProps<'div'> &
|
||||
VariantProps<typeof vstackStyle>;
|
||||
|
||||
const VStack = React.forwardRef<React.ComponentRef<'div'>, IVStackProps>(
|
||||
function VStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<div
|
||||
className={vstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
VStack.displayName = 'VStack';
|
||||
|
||||
export { VStack };
|
||||
@@ -0,0 +1,25 @@
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
|
||||
: '';
|
||||
|
||||
export const vstackStyle = tva({
|
||||
base: `flex-col ${baseStyle}`,
|
||||
variants: {
|
||||
space: {
|
||||
'xs': 'gap-1',
|
||||
'sm': 'gap-2',
|
||||
'md': 'gap-3',
|
||||
'lg': 'gap-4',
|
||||
'xl': 'gap-5',
|
||||
'2xl': 'gap-6',
|
||||
'3xl': 'gap-7',
|
||||
'4xl': 'gap-8',
|
||||
},
|
||||
reversed: {
|
||||
true: 'flex-col-reverse',
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user