u
This commit is contained in:
1 parent
c0862702e8
commit
230f3bdf5c
6 files changed
+603
-301
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 { 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>
|
||||
);
|
||||
}
|
||||
@@ -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",
|
||||
},
|
||||
});
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user