u
This commit is contained in:
1 parent
c0862702e8
commit
230f3bdf5c
6 files changed
+596
-294
No files matched your search
Generated
+409
-235
File diff suppressed because it is too large.
Load diff
@@ -1,10 +1,46 @@
|
|||||||
import React from "react";
|
import { ScrollShadow, Surface } from "heroui-native";
|
||||||
import { View, Text } from "react-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 (
|
return (
|
||||||
<View className="flex-1">
|
<View className="flex-1 bg-background">
|
||||||
<Text className="text-base text-black">Chat</Text>
|
<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>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -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";
|
import LayoutView from "@/components/layout/view";
|
||||||
|
|
||||||
export default function ScrollShadowExample() {
|
export default function ScrollShadowExample() {
|
||||||
const list = Array.from({ length: 20 }, (_, i) => i.toString());
|
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 (
|
return (
|
||||||
<View className="flex-1 bg-background">
|
<View className="flex-1 bg-background">
|
||||||
<LayoutView.LegendList
|
<LayoutView.ScrollView
|
||||||
data={list}
|
contentContainerStyle={{
|
||||||
renderItem={({ item }) => (
|
paddingTop: 0,
|
||||||
<View className="p-4 border-b border-gray-200">
|
}}
|
||||||
<Text>{item}</Text>
|
>
|
||||||
</View>
|
<Text className="mb-4 text-2xl font-bold">Long Content</Text>
|
||||||
)}
|
{items}
|
||||||
keyExtractor={(item) => item}
|
</LayoutView.ScrollView>
|
||||||
recycleItems
|
|
||||||
/>
|
{/* <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>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ export default function Tabbar({ tabs, value, onChange, className, style }: Tabb
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={cn("mx-3", className)} style={style}>
|
<View className={cn("m-3", className)} style={style}>
|
||||||
<Shadow
|
<Shadow
|
||||||
distance={20}
|
distance={20}
|
||||||
startColor="rgba(0,0,0,0.04)"
|
startColor="rgba(0,0,0,0.04)"
|
||||||
@@ -173,7 +173,6 @@ const styles = StyleSheet.create({
|
|||||||
borderWidth: 0.5,
|
borderWidth: 0.5,
|
||||||
borderColor: "rgba(255,255,255,0.6)",
|
borderColor: "rgba(255,255,255,0.6)",
|
||||||
height: 56,
|
height: 56,
|
||||||
marginBottom: 12,
|
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1,57 +1,116 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { ScrollView, SectionList, FlatList, View } from "react-native";
|
||||||
ScrollView,
|
|
||||||
SectionList,
|
|
||||||
FlatList,
|
|
||||||
ScrollViewProps,
|
|
||||||
SectionListProps,
|
|
||||||
FlatListProps,
|
|
||||||
} from "react-native";
|
|
||||||
|
|
||||||
import { ScrollShadow } from "heroui-native";
|
import { ScrollShadow } from "heroui-native";
|
||||||
import { LinearGradient } from "expo-linear-gradient";
|
import { LinearGradient } from "expo-linear-gradient";
|
||||||
import { LegendList } from "@legendapp/list";
|
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 (
|
return (
|
||||||
<ScrollShadow className="flex-1 my-18" LinearGradientComponent={LinearGradient}>
|
<ScrollShadow className="flex-1" size={300} LinearGradientComponent={LinearGradient}>
|
||||||
{children}
|
{children}
|
||||||
</ScrollShadow>
|
</ScrollShadow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LVScrollView(props: ScrollViewProps) {
|
/**
|
||||||
return <ScrollView {...props} />;
|
* 统一 padding 计算
|
||||||
}
|
*/
|
||||||
|
function useContentPadding() {
|
||||||
export function LVSectionView<T>(props: SectionListProps<T>) {
|
const insets = useSafeAreaInsets();
|
||||||
return <SectionList {...props} />;
|
|
||||||
}
|
return {
|
||||||
|
paddingTop: insets.top + TOP_EXTRA_PADDING,
|
||||||
export function LVLegendList<T>(props: React.ComponentProps<typeof LegendList<T>>) {
|
paddingBottom: insets.bottom + BOTTOM_EXTRA_PADDING,
|
||||||
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} />;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LayoutView
|
||||||
|
*/
|
||||||
const LayoutView = (props: { children?: React.ReactNode }) => {
|
const LayoutView = (props: { children?: React.ReactNode }) => {
|
||||||
return <>{props.children}</>;
|
return <View style={{ flex: 1 }}>{props.children}</View>;
|
||||||
};
|
};
|
||||||
|
|
||||||
LayoutView.ScrollShadow = LVScrollShadow;
|
/**
|
||||||
LayoutView.ScrollView = LVScrollView;
|
* ScrollView
|
||||||
LayoutView.SectionView = LVSectionView;
|
*/
|
||||||
LayoutView.LegendList = LVLegendList;
|
LayoutView.ScrollView = (props: React.ComponentProps<typeof ScrollView>) => {
|
||||||
LayoutView.FastList = LVFastList;
|
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;
|
export default LayoutView;
|
||||||
@@ -20,7 +20,7 @@ export default function ModuleLayout({ tabs }: { tabs: TabbarItem[] }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1, zIndex: 0 }}>
|
||||||
<Slot />
|
<Slot />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -47,8 +47,15 @@ export default function ModuleLayout({ tabs }: { tabs: TabbarItem[] }) {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 10 }}>
|
<View
|
||||||
<View style={{ paddingBottom: insets.bottom }}>
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: insets.bottom + 16,
|
||||||
|
zIndex: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Tabbar
|
<Tabbar
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
value={activeTabItem?.id}
|
value={activeTabItem?.id}
|
||||||
@@ -58,6 +65,5 @@ export default function ModuleLayout({ tabs }: { tabs: TabbarItem[] }) {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user