Skip to content

Commit

Permalink
refactor: refactor PageView
Browse files Browse the repository at this point in the history
  • Loading branch information
mahaaoo committed Sep 13, 2024
1 parent ee502e8 commit ee00496
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 73 deletions.
79 changes: 6 additions & 73 deletions src/components/PageView/PageView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { forwardRef, useImperativeHandle } from 'react';
import { Dimensions, View, ViewStyle } from 'react-native';
import { View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
runOnJS,
Expand All @@ -9,64 +9,9 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';
import { snapPoint, clamp } from '../../index';

interface PageViewProps {
children: React.ReactElement;

style?: ViewStyle;
initialPage?: number;
scrollEnabled?: boolean;
bounces?: boolean;
gestureBack?: boolean;

onPageScroll?: (translate: number) => void;
onPageSelected?: (currentPage: number) => void;
onPageScrollStateChanged?: (state: PageStateType) => void;
}

interface PageViewRef {
setPage: (index: number) => void;
setPageWithoutAnimation: (index: number) => void;
getCurrentPage: () => number;
}

const { width, height } = Dimensions.get('window');
const DURATION = 350;

type PageStateType = 'dragging' | 'settling' | 'idle';

interface PageViewVerifyProps extends PageViewProps {
pageSize: number;
contentSize: number;
snapPoints: number[];
}

const verifyProps = (props: PageViewProps): PageViewVerifyProps => {
const { children, style } = props;
const pageSize = React.Children.count(children);
if (pageSize === 0) {
throw new Error('PageView must be contains at least one chid');
}
let contentSize: number = width;
if (style && style.width) {
if (typeof style.width === 'number') {
contentSize = style.width;
} else {
throw new Error('PageView width only support number');
}
}

const snapPoints = new Array(pageSize)
.fill(0)
.map((_, index) => -index * contentSize);

return {
...props,
pageSize,
contentSize,
snapPoints,
};
};
import { PageViewRef, PageViewProps, PageStateType, DURATION } from './type';
import { useVerifyProps } from './hook';
import SiglePage from './SiglePage';

const PageView = forwardRef<PageViewRef, PageViewProps>((props, ref) => {
const {
Expand All @@ -82,7 +27,7 @@ const PageView = forwardRef<PageViewRef, PageViewProps>((props, ref) => {
onPageScroll,
onPageSelected,
onPageScrollStateChanged,
} = verifyProps(props);
} = useVerifyProps(props);

const pageMove = useSharedValue(-initialPage * contentSize);
const offset = useSharedValue(0);
Expand Down Expand Up @@ -220,24 +165,12 @@ const PageView = forwardRef<PageViewRef, PageViewProps>((props, ref) => {
]}
>
{React.Children.map(children, (child) => {
return (
<PageContainer contentSize={contentSize}>{child}</PageContainer>
);
return <SiglePage contentSize={contentSize}>{child}</SiglePage>;
})}
</Animated.View>
</GestureDetector>
</View>
);
});

interface PageContainerProps {
children: React.ReactElement;
contentSize: number;
}

const PageContainer: React.FC<PageContainerProps> = (props) => {
const { children, contentSize } = props;
return <View style={{ width: contentSize }}>{children}</View>;
};

export default PageView;
13 changes: 13 additions & 0 deletions src/components/PageView/SiglePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { View } from 'react-native';

interface SiglePageProps {
children: React.ReactElement;
contentSize: number;
}

const SiglePage: React.FC<SiglePageProps> = (props) => {
const { children, contentSize } = props;
return <View style={{ width: contentSize }}>{children}</View>;
};

export default SiglePage;
32 changes: 32 additions & 0 deletions src/components/PageView/hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { Dimensions } from 'react-native';
import { PageViewProps, PageViewVerifyProps } from './type';

const { width } = Dimensions.get('window');

export const useVerifyProps = (props: PageViewProps): PageViewVerifyProps => {
const { children, style } = props;
const pageSize = React.Children.count(children);
if (pageSize === 0) {
throw new Error('PageView must be contains at least one chid');
}
let contentSize: number = width;
if (style && style.width) {
if (typeof style.width === 'number') {
contentSize = style.width;
} else {
throw new Error('PageView width only support number');
}
}

const snapPoints = new Array(pageSize)
.fill(0)
.map((_, index) => -index * contentSize);

return {
...props,
pageSize,
contentSize,
snapPoints,
};
};
31 changes: 31 additions & 0 deletions src/components/PageView/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ViewStyle } from 'react-native';

export interface PageViewProps {
children: React.ReactElement;

style?: ViewStyle;
initialPage?: number;
scrollEnabled?: boolean;
bounces?: boolean;
gestureBack?: boolean;

onPageScroll?: (translate: number) => void;
onPageSelected?: (currentPage: number) => void;
onPageScrollStateChanged?: (state: PageStateType) => void;
}

export interface PageViewRef {
setPage: (index: number) => void;
setPageWithoutAnimation: (index: number) => void;
getCurrentPage: () => number;
}

export const DURATION = 350;

export type PageStateType = 'dragging' | 'settling' | 'idle';

export interface PageViewVerifyProps extends PageViewProps {
pageSize: number;
contentSize: number;
snapPoints: number[];
}

0 comments on commit ee00496

Please sign in to comment.