feat: update ui

This commit is contained in:
2024-11-08 18:53:30 +00:00
parent 887cb64878
commit 334d90e691
32 changed files with 829 additions and 262 deletions
+30 -5
View File
@@ -1,26 +1,51 @@
import { useDebounceCallback } from "@/hooks/useDebounce";
import React, { ComponentPropsWithoutRef, useEffect, useRef } from "react";
import RNPagerView from "react-native-pager-view";
export type PagerViewProps = ComponentPropsWithoutRef<typeof RNPagerView> & {
page?: number;
onChangePage?: (page: number) => void;
EmptyComponent?: () => JSX.Element;
};
const PagerView = ({ page, onChangePage, ...props }: PagerViewProps) => {
const PagerView = ({
page,
onChangePage,
EmptyComponent,
children,
...props
}: PagerViewProps) => {
const ref = useRef<RNPagerView>(null);
const [onPageSelect, clearPageSelectDebounce] = useDebounceCallback(
(page) => onChangePage?.(page),
100
);
const [setPage] = useDebounceCallback((page) => {
ref.current?.setPage(page);
clearPageSelectDebounce();
}, 300);
useEffect(() => {
if (page != null) {
ref.current?.setPage(page);
const npage = EmptyComponent != null ? page + 1 : page;
setPage(npage);
}
}, [page]);
}, [page, EmptyComponent]);
return (
<RNPagerView
ref={ref}
{...props}
onPageSelected={(e) => onChangePage?.(e.nativeEvent.position)}
/>
onPageSelected={(e) => {
const pos = e.nativeEvent.position;
onPageSelect(EmptyComponent ? pos - 1 : pos);
}}
>
{EmptyComponent ? <EmptyComponent key="-1" /> : null}
{children}
</RNPagerView>
);
};
+11 -2
View File
@@ -3,7 +3,7 @@ import { View } from "react-native";
import { PagerViewProps } from "./pager-view";
const PagerView = ({
className,
EmptyComponent,
children,
page,
initialPage,
@@ -33,7 +33,16 @@ const PagerView = ({
});
}, [curPage, children]);
return content;
const pageElement = useMemo(() => {
return Array.isArray(children) ? children[curPage] : null;
}, [curPage, children]);
return (
<>
{!pageElement && EmptyComponent ? <EmptyComponent key="-1" /> : null}
{content}
</>
);
};
export default PagerView;
+56 -4
View File
@@ -1,7 +1,17 @@
import { Pressable as BasePressable } from "react-native";
import { GetProps, styled, ViewStyle } from "tamagui";
import { useRef } from "react";
import {
TapGestureHandler,
State as GestureState,
} from "react-native-gesture-handler";
import { Button, GetProps, styled, View, ViewStyle } from "tamagui";
const StyledPressable = styled(Button, {
unstyled: true,
backgroundColor: "$colorTransparent",
borderWidth: 0,
cursor: "pointer",
});
const StyledPressable = styled(BasePressable);
export type PressableProps = GetProps<typeof StyledPressable> & {
$hover?: ViewStyle;
$pressed?: ViewStyle;
@@ -13,7 +23,49 @@ const Pressable = ({
...props
}: PressableProps) => {
return (
<StyledPressable pressStyle={$pressed} hoverStyle={$hover} {...props} />
<StyledPressable
hoverStyle={$hover}
pressStyle={$pressed}
{...(props as any)}
/>
);
};
type MultiTapPressableProps = GetProps<typeof View> & {
numberOfTaps: number;
onTap?: () => void;
onMultiTap?: () => void;
};
export const MultiTapPressable = ({
numberOfTaps,
onTap,
onMultiTap,
...props
}: MultiTapPressableProps) => {
const tapRef = useRef<any>();
return (
<TapGestureHandler
onHandlerStateChange={(e) => {
if (e.nativeEvent.state === GestureState.ACTIVE) {
onTap?.();
}
}}
waitFor={tapRef}
>
<TapGestureHandler
onHandlerStateChange={(e) => {
if (e.nativeEvent.state === GestureState.ACTIVE) {
onMultiTap?.();
}
}}
numberOfTaps={numberOfTaps}
ref={tapRef}
>
<View pressStyle={{ opacity: 0.5 }} {...props} />
</TapGestureHandler>
</TapGestureHandler>
);
};
+25
View File
@@ -0,0 +1,25 @@
import React from "react";
import { GetProps, Input, View, ViewStyle } from "tamagui";
import Icons from "./icons";
type SearchInputProps = GetProps<typeof Input> & {
_container?: ViewStyle;
};
const SearchInput = ({ _container, ...props }: SearchInputProps) => {
return (
<View position="relative" {..._container}>
<Icons
name="magnify"
size={20}
position="absolute"
top={11}
left="$3"
zIndex={1}
/>
<Input pl="$7" placeholder="Search..." {...props} />
</View>
);
};
export default SearchInput;