@fountain-ui/lab 2.0.0-beta.10 → 2.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commonjs/ViewPager/ChildrenMemoizedPage.js +90 -22
- package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerNative.js +41 -34
- package/build/commonjs/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerWeb.js +32 -25
- package/build/commonjs/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/commonjs/ViewPager/index.js.map +1 -1
- package/build/commonjs/ViewPager/utils.js +3 -41
- package/build/commonjs/ViewPager/utils.js.map +1 -1
- package/build/module/ViewPager/ChildrenMemoizedPage.js +85 -23
- package/build/module/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/module/ViewPager/ViewPagerNative.js +40 -34
- package/build/module/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/module/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/module/ViewPager/ViewPagerWeb.js +26 -23
- package/build/module/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/module/ViewPager/index.js.map +1 -1
- package/build/module/ViewPager/utils.js +1 -32
- package/build/module/ViewPager/utils.js.map +1 -1
- package/build/typescript/ViewPager/ChildrenMemoizedPage.d.ts +2 -1
- package/build/typescript/ViewPager/ViewPagerNative.d.ts +4 -1
- package/build/typescript/ViewPager/ViewPagerProps.d.ts +20 -19
- package/build/typescript/ViewPager/ViewPagerWeb.d.ts +4 -1
- package/build/typescript/ViewPager/index.d.ts +1 -1
- package/build/typescript/ViewPager/utils.d.ts +2 -19
- package/package.json +2 -2
- package/src/ViewPager/ChildrenMemoizedPage.tsx +91 -22
- package/src/ViewPager/ViewPagerNative.tsx +43 -38
- package/src/ViewPager/ViewPagerProps.ts +20 -19
- package/src/ViewPager/ViewPagerWeb.tsx +34 -29
- package/src/ViewPager/index.ts +1 -1
- package/src/ViewPager/utils.tsx +2 -55
|
@@ -1,73 +1,78 @@
|
|
|
1
|
-
import React, { useCallback,
|
|
1
|
+
import React, { Children, forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
|
|
2
2
|
import type { ViewPagerOnPageSelectedEvent } from 'react-native-pager-view';
|
|
3
3
|
import RNViewPager from 'react-native-pager-view';
|
|
4
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
4
5
|
import type ViewPagerProps from './ViewPagerProps';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
defaultEnableVisibleHint,
|
|
8
|
-
defaultLoading,
|
|
9
|
-
defaultPageComponent,
|
|
10
|
-
usePageRenderer,
|
|
11
|
-
} from './utils';
|
|
6
|
+
import type { ViewPagerInstance } from './ViewPagerProps';
|
|
7
|
+
import { defaultInitialPage, defaultLoading, defaultPageComponent } from './utils';
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPager(props, ref) {
|
|
14
10
|
const {
|
|
15
11
|
children,
|
|
16
|
-
|
|
17
|
-
index,
|
|
12
|
+
initialPage = defaultInitialPage,
|
|
18
13
|
keyboardDismissMode = 'on-drag',
|
|
19
14
|
loading = defaultLoading,
|
|
20
15
|
onChange,
|
|
21
16
|
pageComponent = defaultPageComponent,
|
|
22
|
-
enableNeighborPageRerender = defaultEnableNeighborPageRerender,
|
|
23
17
|
pageForceRerenderKey,
|
|
24
18
|
scrollEnabled = true,
|
|
25
19
|
style,
|
|
26
20
|
} = props;
|
|
27
21
|
|
|
28
|
-
const
|
|
22
|
+
const sharedIndex = useSharedValue<number>(initialPage);
|
|
29
23
|
const pagerRef = useRef<RNViewPager | null>(null);
|
|
30
24
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
const setPage = (newIndex: number) => {
|
|
26
|
+
requestAnimationFrame(() => {
|
|
27
|
+
pagerRef.current?.setPage(newIndex);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
useImperativeHandle(
|
|
32
|
+
ref,
|
|
33
|
+
() => ({ setPage }),
|
|
34
|
+
[],
|
|
35
|
+
);
|
|
39
36
|
|
|
40
37
|
const handlePageSelected = useCallback((e: ViewPagerOnPageSelectedEvent) => {
|
|
41
|
-
|
|
38
|
+
const currentIndex = sharedIndex.value;
|
|
39
|
+
const nextIndex = e.nativeEvent.position;
|
|
40
|
+
|
|
41
|
+
if (currentIndex === nextIndex) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
sharedIndex.value = nextIndex;
|
|
42
46
|
|
|
43
47
|
if (onChange) {
|
|
44
|
-
onChange(
|
|
48
|
+
onChange(nextIndex);
|
|
45
49
|
}
|
|
46
50
|
}, [onChange]);
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
const handleNumber = index !== indexRef.current
|
|
50
|
-
? requestAnimationFrame(() => pagerRef.current?.setPage(index))
|
|
51
|
-
: undefined;
|
|
52
|
-
|
|
53
|
-
return () => {
|
|
54
|
-
if (handleNumber) {
|
|
55
|
-
cancelAnimationFrame(handleNumber);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}, [index]);
|
|
52
|
+
const PageComponent = pageComponent;
|
|
59
53
|
|
|
60
54
|
return (
|
|
61
55
|
<RNViewPager
|
|
62
|
-
|
|
56
|
+
ref={pagerRef}
|
|
57
|
+
initialPage={initialPage}
|
|
63
58
|
keyboardDismissMode={keyboardDismissMode}
|
|
64
59
|
onPageSelected={handlePageSelected}
|
|
65
60
|
pageMargin={8}
|
|
66
|
-
ref={pagerRef}
|
|
67
61
|
scrollEnabled={scrollEnabled}
|
|
68
62
|
style={style}
|
|
69
63
|
>
|
|
70
|
-
{
|
|
64
|
+
{Children.map(children, (child, index) => (
|
|
65
|
+
<PageComponent
|
|
66
|
+
key={index}
|
|
67
|
+
children={child}
|
|
68
|
+
index={index}
|
|
69
|
+
loading={loading}
|
|
70
|
+
rerenderKey={pageForceRerenderKey}
|
|
71
|
+
sharedIndex={sharedIndex}
|
|
72
|
+
/>
|
|
73
|
+
))}
|
|
71
74
|
</RNViewPager>
|
|
72
75
|
);
|
|
73
|
-
};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export default ViewPager;
|
|
@@ -1,41 +1,42 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from 'react';
|
|
2
2
|
import type { ViewProps } from 'react-native';
|
|
3
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
3
4
|
import type { ComponentProps } from '@fountain-ui/core';
|
|
4
5
|
|
|
5
6
|
export type KeyboardDismissMode = 'none' | 'on-drag';
|
|
6
7
|
|
|
7
|
-
export type PageProps =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export type PageProps = PropsWithChildren<ViewProps> & {
|
|
9
|
+
index: number;
|
|
10
|
+
loading: ViewPagerProps['loading'];
|
|
11
|
+
sharedIndex: SharedValue<number>;
|
|
12
|
+
rerenderKey?: ViewPagerProps['pageForceRerenderKey'];
|
|
11
13
|
};
|
|
12
14
|
|
|
13
|
-
export type PageComponent =
|
|
15
|
+
export type PageComponent = ComponentType<PageProps>;
|
|
14
16
|
|
|
15
17
|
export type Loading = 'lazy' | 'eager';
|
|
16
18
|
|
|
17
|
-
export
|
|
19
|
+
export interface ViewPagerInstance {
|
|
18
20
|
/**
|
|
19
|
-
*
|
|
21
|
+
* Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
|
|
22
|
+
* @param index
|
|
20
23
|
*/
|
|
21
|
-
|
|
24
|
+
setPage: (index: number) => void;
|
|
25
|
+
}
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* @default false
|
|
26
|
-
*/
|
|
27
|
-
enableVisibleHint?: boolean;
|
|
27
|
+
export default interface ViewPagerProps extends ComponentProps<{
|
|
28
|
+
ref?: Ref<ViewPagerInstance>;
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @default false
|
|
31
|
+
* Collection of ViewPager components.
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
children?: ReactNode;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Index of initial page that should be selected.
|
|
37
|
+
* @default 0
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
|
+
initialPage?: number;
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Whether to load the page immediately (`eager`) or on an as-needed basis (`lazy`).
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import React, { Children, forwardRef, useImperativeHandle } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
4
|
+
import { StyleSheet } from '@fountain-ui/core';
|
|
3
5
|
import type ViewPagerProps from './ViewPagerProps';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
defaultEnableVisibleHint,
|
|
7
|
-
defaultLoading,
|
|
8
|
-
defaultPageComponent,
|
|
9
|
-
usePageRenderer,
|
|
10
|
-
} from './utils';
|
|
6
|
+
import type { ViewPagerInstance } from './ViewPagerProps';
|
|
7
|
+
import { defaultInitialPage, defaultLoading, defaultPageComponent } from './utils';
|
|
11
8
|
|
|
12
9
|
const styles = StyleSheet.create({
|
|
13
10
|
root: {
|
|
@@ -15,38 +12,46 @@ const styles = StyleSheet.create({
|
|
|
15
12
|
overflow: 'auto',
|
|
16
13
|
position: 'relative',
|
|
17
14
|
},
|
|
18
|
-
none: { display: 'none' },
|
|
19
15
|
});
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPager(props, ref) {
|
|
22
18
|
const {
|
|
23
19
|
children,
|
|
24
|
-
|
|
25
|
-
enableNeighborPageRerender = defaultEnableNeighborPageRerender,
|
|
26
|
-
index,
|
|
20
|
+
initialPage = defaultInitialPage,
|
|
27
21
|
loading = defaultLoading,
|
|
28
22
|
pageComponent = defaultPageComponent,
|
|
29
23
|
pageForceRerenderKey,
|
|
30
24
|
style,
|
|
31
25
|
} = props;
|
|
32
26
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
const sharedIndex = useSharedValue<number>(initialPage);
|
|
28
|
+
|
|
29
|
+
const setPage = (newIndex: number) => {
|
|
30
|
+
sharedIndex.value = newIndex;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
useImperativeHandle(
|
|
34
|
+
ref,
|
|
35
|
+
() => ({ setPage }),
|
|
36
|
+
[],
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const PageComponent = pageComponent;
|
|
41
40
|
|
|
42
41
|
return (
|
|
43
42
|
<View style={[styles.root, style]}>
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
{Children.map(children, (child, index) => (
|
|
44
|
+
<PageComponent
|
|
45
|
+
key={index}
|
|
46
|
+
children={child}
|
|
47
|
+
index={index}
|
|
48
|
+
loading={loading}
|
|
49
|
+
rerenderKey={pageForceRerenderKey}
|
|
50
|
+
sharedIndex={sharedIndex}
|
|
51
|
+
/>
|
|
52
|
+
))}
|
|
50
53
|
</View>
|
|
51
54
|
);
|
|
52
|
-
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export default ViewPager;
|
package/src/ViewPager/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './ViewPagerWeb';
|
|
2
|
-
export type { default as ViewPagerProps } from './ViewPagerProps';
|
|
2
|
+
export type { default as ViewPagerProps, ViewPagerInstance } from './ViewPagerProps';
|
package/src/ViewPager/utils.tsx
CHANGED
|
@@ -1,62 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { Loading, PageComponent } from './ViewPagerProps';
|
|
3
3
|
import ChildrenMemoizedPage from './ChildrenMemoizedPage';
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
visited?: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface PageRenderOption {
|
|
10
|
-
enableVisibleHint: boolean;
|
|
11
|
-
enableNeighborPageRerender: boolean;
|
|
12
|
-
index: number;
|
|
13
|
-
loading: Loading;
|
|
14
|
-
pageComponent: PageComponent;
|
|
15
|
-
pageForceRerenderKey?: any;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface PageRenderer {
|
|
19
|
-
(children: ViewPagerProps['children']): React.ReactNode;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const defaultEnableVisibleHint: boolean = false;
|
|
23
|
-
|
|
24
|
-
export const defaultEnableNeighborPageRerender: boolean = false;
|
|
5
|
+
export const defaultInitialPage: number = 0;
|
|
25
6
|
|
|
26
7
|
export const defaultLoading: Loading = 'lazy';
|
|
27
8
|
|
|
28
9
|
export const defaultPageComponent: PageComponent = ChildrenMemoizedPage;
|
|
29
|
-
|
|
30
|
-
export const usePageRenderer = ({
|
|
31
|
-
enableVisibleHint,
|
|
32
|
-
index: currentIndex,
|
|
33
|
-
loading,
|
|
34
|
-
pageComponent: PageComponent,
|
|
35
|
-
pageForceRerenderKey,
|
|
36
|
-
enableNeighborPageRerender,
|
|
37
|
-
}: PageRenderOption): PageRenderer => {
|
|
38
|
-
const pagesStateRef = React.useRef<Array<PageState>>([]);
|
|
39
|
-
|
|
40
|
-
pagesStateRef.current[currentIndex] = {
|
|
41
|
-
...pagesStateRef.current[currentIndex],
|
|
42
|
-
visited: true,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return (children => React.Children.map(children, (child, index) => {
|
|
46
|
-
const visited = pagesStateRef.current[index]?.visited ?? false;
|
|
47
|
-
const content = (loading === 'eager' || visited) ? child : null;
|
|
48
|
-
|
|
49
|
-
const isVisible = enableVisibleHint ? (index === currentIndex) : false;
|
|
50
|
-
const isNeighborIndex = index === currentIndex - 1 || index === currentIndex + 1;
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<PageComponent
|
|
54
|
-
key={index}
|
|
55
|
-
children={content}
|
|
56
|
-
isNeighbor={enableNeighborPageRerender && isNeighborIndex}
|
|
57
|
-
isVisible={isVisible}
|
|
58
|
-
rerenderKey={pageForceRerenderKey}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
61
|
-
}));
|
|
62
|
-
};
|