This commit is contained in:
oneao committed 2026-04-15 21:23:25 +08:00
1 parent c0862702e8
commit 230f3bdf5c
6 files changed
+603 -301

No files matched your search

+409 -235
View File
File diff suppressed because it is too large. Load diff
+41 -5
View File
@@ -1,10 +1,46 @@
import React from "react";
import { View, Text } from "react-native";
import { ScrollShadow, Surface } from "heroui-native";
import { LinearGradient } from "expo-linear-gradient";
import { FlatList, ScrollView, Text, View } from "react-native";
export default function ScrollShadowExample() {
const horizontalData = Array.from({ length: 10 }, (_, i) => ({
id: i,
title: `Card ${i + 1}`,
}));
export default function Chat() {
return (
<View className="flex-1">
<Text className="text-base text-black">Chat</Text>
<View className="flex-1 bg-background">
<Text className="px-5 py-3 text-lg font-semibold">Horizontal List</Text>
<ScrollShadow LinearGradientComponent={LinearGradient}>
<FlatList
data={horizontalData}
horizontal
renderItem={({ item }) => (
<Surface variant="2" className="w-32 h-24 justify-center px-4">
<Text>{item.title}</Text>
</Surface>
)}
showsHorizontalScrollIndicator={false}
contentContainerClassName="p-5 gap-4"
/>
</ScrollShadow>
<Text className="px-5 py-3 text-lg font-semibold">Vertical Content</Text>
<ScrollShadow size={80} className="h-48" LinearGradientComponent={LinearGradient}>
<ScrollView contentContainerClassName="p-5" showsVerticalScrollIndicator={false}>
<Text className="mb-4 text-2xl font-bold">Long Content</Text>
<Text className="mb-4 text-base leading-6">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris.
</Text>
<Text className="mb-4 text-base leading-6">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
architecto beatae vitae.
</Text>
</ScrollView>
</ScrollShadow>
</View>
);
}
+39 -11
View File
@@ -1,21 +1,49 @@
import { Text, View } from "react-native";
import { ScrollShadow } from "heroui-native";
import { LinearGradient } from "expo-linear-gradient";
import { ScrollView, Text, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import LayoutView from "@/components/layout/view";
export default function ScrollShadowExample() {
const list = Array.from({ length: 20 }, (_, i) => i.toString());
const items = [];
for (let i = 0; i < list.length; i++) {
items.push(
<Text key={list[i]} className="py-2 text-base">
{list[i]}
</Text>,
);
}
return (
<View className="flex-1 bg-background">
<LayoutView.LegendList
data={list}
renderItem={({ item }) => (
<View className="p-4 border-b border-gray-200">
<Text>{item}</Text>
</View>
)}
keyExtractor={(item) => item}
recycleItems
/>
<LayoutView.ScrollView
contentContainerStyle={{
paddingTop: 0,
}}
>
<Text className="mb-4 text-2xl font-bold">Long Content</Text>
{items}
</LayoutView.ScrollView>
{/* <View style={{ flex: 1, overflow: "hidden" }}>
<ScrollShadow className="flex-1" size={300} LinearGradientComponent={LinearGradient}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{
padding: 16,
paddingBottom: TABBAR_HEIGHT + insets.bottom + 40,
paddingTop: NAVBAR_HEIGHT + insets.top + 20,
zIndex: 1,
}}
>
<Text className="mb-4 text-2xl font-bold">Long Content</Text>
{items}
</ScrollView>
</ScrollShadow>
</View> */}
</View>
);
}
@@ -28,7 +28,7 @@ export default function Tabbar({ tabs, value, onChange, className, style }: Tabb
};
return (
<View className={cn("mx-3", className)} style={style}>
<View className={cn("m-3", className)} style={style}>
<Shadow
distance={20}
startColor="rgba(0,0,0,0.04)"
@@ -173,7 +173,6 @@ const styles = StyleSheet.create({
borderWidth: 0.5,
borderColor: "rgba(255,255,255,0.6)",
height: 56,
marginBottom: 12,
backgroundColor: "#fff",
},
});
+96 -37
View File
@@ -1,57 +1,116 @@
import React from "react";
import {
ScrollView,
SectionList,
FlatList,
ScrollViewProps,
SectionListProps,
FlatListProps,
} from "react-native";
import { ScrollView, SectionList, FlatList, View } from "react-native";
import { ScrollShadow } from "heroui-native";
import { LinearGradient } from "expo-linear-gradient";
import { LegendList } from "@legendapp/list";
import { useSafeAreaInsets } from "react-native-safe-area-context";
export function LVScrollShadow(props: React.ComponentProps<typeof ScrollShadow>) {
const { children } = props;
/**
* 固定额外间距(你可以随便调)
*/
const TOP_EXTRA_PADDING = 60;
const BOTTOM_EXTRA_PADDING = 80;
/**
* Wrapper
*/
function Wrapper({ children }: { children: React.ReactNode }) {
return <View style={{ flex: 1, overflow: "hidden" }}>{children}</View>;
}
/**
* Shadow(只封装一次 ScrollShadow)
*/
function Shadow({ children }: { children: React.ReactElement }) {
return (
<ScrollShadow className="flex-1 my-18" LinearGradientComponent={LinearGradient}>
<ScrollShadow className="flex-1" size={300} LinearGradientComponent={LinearGradient}>
{children}
</ScrollShadow>
);
}
export function LVScrollView(props: ScrollViewProps) {
return <ScrollView {...props} />;
}
export function LVSectionView<T>(props: SectionListProps<T>) {
return <SectionList {...props} />;
}
export function LVLegendList<T>(props: React.ComponentProps<typeof LegendList<T>>) {
const { style, ...rest } = props;
return (
<ScrollShadow className="flex-1 my-18" LinearGradientComponent={LinearGradient}>
<LegendList<T> {...rest} style={[{ flex: 1 }, style]} />
</ScrollShadow>
);
}
export function LVFastList<T>(props: FlatListProps<T>) {
return <FlatList {...props} />;
/**
* 统一 padding 计算
*/
function useContentPadding() {
const insets = useSafeAreaInsets();
return {
paddingTop: insets.top + TOP_EXTRA_PADDING,
paddingBottom: insets.bottom + BOTTOM_EXTRA_PADDING,
};
}
/**
* LayoutView
*/
const LayoutView = (props: { children?: React.ReactNode }) => {
return <>{props.children}</>;
return <View style={{ flex: 1 }}>{props.children}</View>;
};
LayoutView.ScrollShadow = LVScrollShadow;
LayoutView.ScrollView = LVScrollView;
LayoutView.SectionView = LVSectionView;
LayoutView.LegendList = LVLegendList;
LayoutView.FastList = LVFastList;
/**
* ScrollView
*/
LayoutView.ScrollView = (props: React.ComponentProps<typeof ScrollView>) => {
const padding = useContentPadding();
return (
<Wrapper>
<Shadow>
<ScrollView
{...props}
showsVerticalScrollIndicator={false}
contentContainerStyle={[padding, props.contentContainerStyle]}
/>
</Shadow>
</Wrapper>
);
};
/**
* SectionList
*/
LayoutView.SectionView = <T,>(props: React.ComponentProps<typeof SectionList<T>>) => {
const padding = useContentPadding();
return (
<Wrapper>
<Shadow>
<SectionList {...props} contentContainerStyle={[padding, props.contentContainerStyle]} />
</Shadow>
</Wrapper>
);
};
/**
* FlatList
*/
LayoutView.FastList = <T,>(props: React.ComponentProps<typeof FlatList<T>>) => {
const padding = useContentPadding();
return (
<Wrapper>
<Shadow>
<FlatList {...props} contentContainerStyle={[padding, props.contentContainerStyle]} />
</Shadow>
</Wrapper>
);
};
/**
* LegendList
*/
LayoutView.LegendList = <T,>(props: React.ComponentProps<typeof LegendList<T>>) => {
const padding = useContentPadding();
return (
<Wrapper>
<Shadow>
<LegendList<T> {...props} contentContainerStyle={[padding, props.contentContainerStyle]} />
</Shadow>
</Wrapper>
);
};
export default LayoutView;
+17 -11
View File
@@ -20,7 +20,7 @@ export default function ModuleLayout({ tabs }: { tabs: TabbarItem[] }) {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, zIndex: 0 }}>
<Slot />
</View>
@@ -47,16 +47,22 @@ export default function ModuleLayout({ tabs }: { tabs: TabbarItem[] }) {
</View>
</View>
<View style={{ position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 10 }}>
<View style={{ paddingBottom: insets.bottom }}>
<Tabbar
tabs={tabs}
value={activeTabItem?.id}
onChange={(id) => {
router.push(id as any);
}}
/>
</View>
<View
style={{
position: "absolute",
left: 0,
right: 0,
bottom: insets.bottom + 16,
zIndex: 10,
}}
>
<Tabbar
tabs={tabs}
value={activeTabItem?.id}
onChange={(id) => {
router.push(id as any);
}}
/>
</View>
</View>
);