mirror of
https://github.com/khairul169/vaulterm.git
synced 2025-04-28 08:39:37 +07:00
70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import React, { useMemo } from "react";
|
|
import { GetProps, ScrollView, View, ViewStyle } from "tamagui";
|
|
|
|
type GridItem = { key: string };
|
|
|
|
type GridViewProps<T extends GridItem> = GetProps<typeof ScrollView> &
|
|
GridLayoutProps<T>;
|
|
|
|
const GridView = <T extends GridItem>({
|
|
data,
|
|
renderItem,
|
|
columns,
|
|
gap,
|
|
...props
|
|
}: GridViewProps<T>) => {
|
|
return (
|
|
<ScrollView {...props}>
|
|
<GridLayout
|
|
data={data}
|
|
renderItem={renderItem}
|
|
gap={gap}
|
|
columns={columns}
|
|
/>
|
|
</ScrollView>
|
|
);
|
|
};
|
|
|
|
type GridLayoutProps<T extends GridItem> = GetProps<typeof View> & {
|
|
data?: T[] | null;
|
|
renderItem: (item: T, index: number) => React.ReactNode;
|
|
gap?: string | number;
|
|
columns: {
|
|
xs?: number;
|
|
sm?: number;
|
|
md?: number;
|
|
lg?: number;
|
|
xl?: number;
|
|
};
|
|
};
|
|
|
|
export const GridLayout = <T extends GridItem>({
|
|
columns,
|
|
data,
|
|
renderItem,
|
|
gap,
|
|
...props
|
|
}: GridViewProps<T>) => {
|
|
const basisProps = useMemo(() => {
|
|
const basis: ViewStyle = { flexBasis: "100%" };
|
|
if (columns.xs) basis.flexBasis = `${100 / columns.xs}%`;
|
|
if (columns.sm) basis.$gtXs = { flexBasis: `${100 / columns.sm}%` };
|
|
if (columns.md) basis.$gtSm = { flexBasis: `${100 / columns.md}%` };
|
|
if (columns.lg) basis.$gtMd = { flexBasis: `${100 / columns.lg}%` };
|
|
if (columns.xl) basis.$gtLg = { flexBasis: `${100 / columns.xl}%` };
|
|
return basis;
|
|
}, [columns]);
|
|
|
|
return (
|
|
<View flexDirection="row" flexWrap="wrap" alignItems="stretch" {...props}>
|
|
{data?.map((item, idx) => (
|
|
<View key={item.key} p={gap} flexShrink={0} {...basisProps}>
|
|
{renderItem(item, idx)}
|
|
</View>
|
|
))}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default GridView;
|