@fountain-ui/lab 2.0.0-beta.13 → 2.0.0-beta.14
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 +32 -35
- package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/commonjs/ViewPager/InternalContext.js +17 -0
- package/build/commonjs/ViewPager/InternalContext.js.map +1 -0
- package/build/commonjs/ViewPager/ViewPagerNative.js +40 -16
- package/build/commonjs/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerWeb.js +19 -8
- package/build/commonjs/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/commonjs/ViewPager/index.js.map +1 -1
- package/build/commonjs/ViewPager/types.js +6 -0
- package/build/commonjs/ViewPager/types.js.map +1 -0
- package/build/commonjs/ViewPager/usePageStore.js +30 -0
- package/build/commonjs/ViewPager/usePageStore.js.map +1 -0
- package/build/commonjs/ViewPager/utils.js.map +1 -1
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js +1 -1
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/module/ViewPager/ChildrenMemoizedPage.js +30 -33
- package/build/module/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/module/ViewPager/InternalContext.js +7 -0
- package/build/module/ViewPager/InternalContext.js.map +1 -0
- package/build/module/ViewPager/ViewPagerNative.js +38 -16
- package/build/module/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/module/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/module/ViewPager/ViewPagerWeb.js +16 -8
- package/build/module/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/module/ViewPager/index.js.map +1 -1
- package/build/module/ViewPager/types.js +2 -0
- package/build/module/ViewPager/types.js.map +1 -0
- package/build/module/ViewPager/usePageStore.js +20 -0
- package/build/module/ViewPager/usePageStore.js.map +1 -0
- package/build/module/ViewPager/utils.js.map +1 -1
- package/build/module/hooks/useUnstableCollapsibleAppBar.js +1 -1
- package/build/module/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/typescript/ViewPager/ChildrenMemoizedPage.d.ts +1 -1
- package/build/typescript/ViewPager/InternalContext.d.ts +7 -0
- package/build/typescript/ViewPager/ViewPagerNative.d.ts +2 -2
- package/build/typescript/ViewPager/ViewPagerProps.d.ts +4 -22
- package/build/typescript/ViewPager/ViewPagerWeb.d.ts +2 -2
- package/build/typescript/ViewPager/index.d.ts +2 -1
- package/build/typescript/ViewPager/types.d.ts +19 -0
- package/build/typescript/ViewPager/usePageStore.d.ts +2 -0
- package/build/typescript/ViewPager/utils.d.ts +1 -1
- package/package.json +2 -2
- package/src/ViewPager/ChildrenMemoizedPage.tsx +30 -34
- package/src/ViewPager/InternalContext.ts +13 -0
- package/src/ViewPager/ViewPagerNative.tsx +52 -38
- package/src/ViewPager/ViewPagerProps.ts +4 -27
- package/src/ViewPager/ViewPagerWeb.tsx +23 -18
- package/src/ViewPager/index.ts +2 -1
- package/src/ViewPager/types.ts +24 -0
- package/src/ViewPager/usePageStore.ts +24 -0
- package/src/ViewPager/utils.tsx +1 -1
- package/src/hooks/useUnstableCollapsibleAppBar.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type ViewPagerProps from './ViewPagerProps';
|
|
3
|
-
import type { ViewPagerInstance } from './
|
|
4
|
-
declare const ViewPager: React.ForwardRefExoticComponent<Pick<ViewPagerProps, "style" | "children" | "onChange" | "scrollEnabled" | "keyboardDismissMode" | "
|
|
3
|
+
import type { ViewPagerInstance } from './types';
|
|
4
|
+
declare const ViewPager: React.ForwardRefExoticComponent<Pick<ViewPagerProps, "style" | "children" | "onChange" | "scrollEnabled" | "keyboardDismissMode" | "initialPage" | "loading" | "offscreenPageRerenderLimit" | "pageComponent" | "pageForceRerenderKey" | "UNSTABLE_sharedPage"> & React.RefAttributes<ViewPagerInstance>>;
|
|
5
5
|
export default ViewPager;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { default } from './ViewPagerWeb';
|
|
2
|
-
export type { default as ViewPagerProps
|
|
2
|
+
export type { default as ViewPagerProps } from './ViewPagerProps';
|
|
3
|
+
export type { ViewPagerInstance } from './types';
|
|
3
4
|
export { useViewPagerPageState } from './PageStateContext';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ComponentType, PropsWithChildren } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
|
+
export declare type PageProps = PropsWithChildren<ViewProps> & {
|
|
4
|
+
index: number;
|
|
5
|
+
initialPage: number;
|
|
6
|
+
loading: Loading;
|
|
7
|
+
offscreenPageRerenderLimit: number;
|
|
8
|
+
rerenderKey?: any;
|
|
9
|
+
};
|
|
10
|
+
export declare type KeyboardDismissMode = 'none' | 'on-drag';
|
|
11
|
+
export declare type PageComponent = ComponentType<PageProps>;
|
|
12
|
+
export declare type Loading = 'lazy' | 'eager';
|
|
13
|
+
export interface ViewPagerInstance {
|
|
14
|
+
/**
|
|
15
|
+
* Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
|
|
16
|
+
* @param index
|
|
17
|
+
*/
|
|
18
|
+
setPage: (index: number) => void;
|
|
19
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Loading, PageComponent } from './
|
|
1
|
+
import type { Loading, PageComponent } from './types';
|
|
2
2
|
export declare const defaultInitialPage: number;
|
|
3
3
|
export declare const defaultLoading: Loading;
|
|
4
4
|
export declare const defaultOffscreenPageRerenderLimit: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "bd0ccbf7db51f1418dffb2da36fe167654a58f7e"
|
|
74
74
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React, { memo, useMemo, useState } from 'react';
|
|
1
|
+
import React, { memo, useContext, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { Platform, View } from 'react-native';
|
|
3
|
-
import { runOnJS, useAnimatedReaction } from 'react-native-reanimated';
|
|
4
3
|
import { StyleSheet } from '@fountain-ui/core';
|
|
5
|
-
import type { PageProps } from './
|
|
4
|
+
import type { PageProps } from './types';
|
|
6
5
|
import PageStateContext from './PageStateContext';
|
|
6
|
+
import InternalContext from './InternalContext';
|
|
7
7
|
|
|
8
8
|
const styles = StyleSheet.create({
|
|
9
9
|
fill: { width: '100%', height: '100%' },
|
|
@@ -18,14 +18,16 @@ interface InternalPageState {
|
|
|
18
18
|
function Page(props: PageProps) {
|
|
19
19
|
const {
|
|
20
20
|
index,
|
|
21
|
+
initialPage,
|
|
21
22
|
children,
|
|
22
23
|
loading,
|
|
23
24
|
offscreenPageRerenderLimit,
|
|
24
|
-
sharedIndex,
|
|
25
25
|
} = props;
|
|
26
26
|
|
|
27
|
+
const { pageStore } = useContext(InternalContext);
|
|
28
|
+
|
|
27
29
|
const assumeInitialPageState = (): InternalPageState => {
|
|
28
|
-
const activeIndex =
|
|
30
|
+
const activeIndex = initialPage;
|
|
29
31
|
|
|
30
32
|
const isActive = index === activeIndex;
|
|
31
33
|
|
|
@@ -43,24 +45,9 @@ function Page(props: PageProps) {
|
|
|
43
45
|
|
|
44
46
|
const content = pageState.isLoaded ? children : null;
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
isActive,
|
|
50
|
-
isLoaded: isActive || prevState.isLoaded,
|
|
51
|
-
}));
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const onBecomeNeighbor = () => {
|
|
55
|
-
setPageState(prevState => ({
|
|
56
|
-
...prevState,
|
|
57
|
-
isLoaded: true,
|
|
58
|
-
}));
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
useAnimatedReaction(
|
|
62
|
-
() => {
|
|
63
|
-
const activeIndex = sharedIndex.value;
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
return pageStore.subscribe(newPage => {
|
|
50
|
+
const activeIndex = newPage;
|
|
64
51
|
|
|
65
52
|
const isActive = index === activeIndex;
|
|
66
53
|
|
|
@@ -69,17 +56,26 @@ function Page(props: PageProps) {
|
|
|
69
56
|
|
|
70
57
|
const becomeNeighbor = shouldRerender && !isActive;
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
59
|
+
setPageState(prevState => {
|
|
60
|
+
if (prevState.isActive !== isActive) {
|
|
61
|
+
return {
|
|
62
|
+
...prevState,
|
|
63
|
+
isActive,
|
|
64
|
+
isLoaded: isActive || prevState.isLoaded,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (becomeNeighbor && !prevState.isLoaded) {
|
|
69
|
+
return {
|
|
70
|
+
...prevState,
|
|
71
|
+
isLoaded: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return prevState;
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}, [pageStore, index]);
|
|
83
79
|
|
|
84
80
|
const contextValue = useMemo(() => ({
|
|
85
81
|
isActive: pageState.isActive,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import type { MonoStore } from '@fountain-ui/core';
|
|
3
|
+
import { MockStore } from '@fountain-ui/core';
|
|
4
|
+
|
|
5
|
+
export interface InternalContextValue {
|
|
6
|
+
pageStore: MonoStore<number>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const InternalContext = createContext<InternalContextValue>({
|
|
10
|
+
pageStore: new MockStore(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export default InternalContext;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, { Children, forwardRef, useCallback, useEffect, 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 {
|
|
4
|
+
import { useSyncAnimatedValue } from '@fountain-ui/core';
|
|
5
5
|
import type ViewPagerProps from './ViewPagerProps';
|
|
6
|
-
import type { ViewPagerInstance } from './
|
|
6
|
+
import type { ViewPagerInstance } from './types';
|
|
7
7
|
import { defaultInitialPage, defaultLoading, defaultOffscreenPageRerenderLimit, defaultPageComponent } from './utils';
|
|
8
|
+
import usePageStore from './usePageStore';
|
|
9
|
+
import InternalContext from './InternalContext';
|
|
8
10
|
|
|
9
11
|
const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPager(props, ref) {
|
|
10
12
|
const {
|
|
@@ -21,10 +23,12 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
21
23
|
UNSTABLE_sharedPage,
|
|
22
24
|
} = props;
|
|
23
25
|
|
|
24
|
-
const fallbackSharedPage =
|
|
26
|
+
const fallbackSharedPage = useSyncAnimatedValue({ initialValue: initialPage });
|
|
25
27
|
|
|
26
28
|
const sharedPage = UNSTABLE_sharedPage ?? fallbackSharedPage;
|
|
27
29
|
|
|
30
|
+
const pageRef = useRef<number>(sharedPage.initialValue);
|
|
31
|
+
|
|
28
32
|
const desiredPageRef = useRef<number>(NaN);
|
|
29
33
|
|
|
30
34
|
const pagerRef = useRef<RNViewPager | null>(null);
|
|
@@ -38,7 +42,7 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
38
42
|
|
|
39
43
|
animationFrameRef.current = requestAnimationFrame(() => {
|
|
40
44
|
if (Number.isFinite(desiredPageRef.current)) {
|
|
41
|
-
if (
|
|
45
|
+
if (pageRef.current === desiredPageRef.current) {
|
|
42
46
|
// end of state machine. clear desired page.
|
|
43
47
|
desiredPageRef.current = NaN;
|
|
44
48
|
return;
|
|
@@ -62,13 +66,18 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
62
66
|
};
|
|
63
67
|
}, []);
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const animatedValue = sharedPage.animatedValue;
|
|
71
|
+
const id = animatedValue.addListener(newValue => {
|
|
72
|
+
const newPage = newValue.value;
|
|
73
|
+
pageRef.current = newPage;
|
|
74
|
+
setPage(newPage);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return () => {
|
|
78
|
+
animatedValue.removeListener(id);
|
|
79
|
+
};
|
|
80
|
+
}, [sharedPage]);
|
|
72
81
|
|
|
73
82
|
const handlePageSelected = useCallback((e: ViewPagerOnPageSelectedEvent) => {
|
|
74
83
|
if (Number.isFinite(desiredPageRef.current)) {
|
|
@@ -80,24 +89,25 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
80
89
|
|
|
81
90
|
const desiredPage = desiredPageRef.current;
|
|
82
91
|
|
|
83
|
-
if (
|
|
92
|
+
if (pageRef.current === desiredPage) {
|
|
84
93
|
// end of state machine. clear desired page.
|
|
85
94
|
desiredPageRef.current = NaN;
|
|
86
95
|
} else {
|
|
87
|
-
sharedPage.
|
|
96
|
+
sharedPage.animatedValue.setValue(desiredPage);
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
onChange?.(desiredPage);
|
|
91
100
|
} else {
|
|
92
101
|
const trustfulNextPage = e.nativeEvent.position;
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
103
|
+
if (trustfulNextPage !== pageRef.current) {
|
|
104
|
+
desiredPageRef.current = trustfulNextPage;
|
|
105
|
+
sharedPage.animatedValue.setValue(trustfulNextPage);
|
|
106
|
+
}
|
|
97
107
|
|
|
98
108
|
onChange?.(trustfulNextPage);
|
|
99
109
|
}
|
|
100
|
-
}, [onChange]);
|
|
110
|
+
}, [onChange, sharedPage]);
|
|
101
111
|
|
|
102
112
|
useImperativeHandle(
|
|
103
113
|
ref,
|
|
@@ -105,30 +115,34 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
105
115
|
[setPage],
|
|
106
116
|
);
|
|
107
117
|
|
|
118
|
+
const pageStore = usePageStore(sharedPage);
|
|
119
|
+
|
|
108
120
|
const PageComponent = pageComponent;
|
|
109
121
|
|
|
110
122
|
return (
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
<InternalContext.Provider value={{ pageStore }}>
|
|
124
|
+
<RNViewPager
|
|
125
|
+
ref={pagerRef}
|
|
126
|
+
initialPage={sharedPage.initialValue}
|
|
127
|
+
keyboardDismissMode={keyboardDismissMode}
|
|
128
|
+
onPageSelected={handlePageSelected}
|
|
129
|
+
pageMargin={8}
|
|
130
|
+
scrollEnabled={scrollEnabled}
|
|
131
|
+
style={style}
|
|
132
|
+
>
|
|
133
|
+
{Children.map(children, (child, index) => (
|
|
134
|
+
<PageComponent
|
|
135
|
+
key={index}
|
|
136
|
+
children={child}
|
|
137
|
+
index={index}
|
|
138
|
+
initialPage={sharedPage.initialValue}
|
|
139
|
+
loading={loading}
|
|
140
|
+
offscreenPageRerenderLimit={offscreenPageRerenderLimit}
|
|
141
|
+
rerenderKey={pageForceRerenderKey}
|
|
142
|
+
/>
|
|
143
|
+
))}
|
|
144
|
+
</RNViewPager>
|
|
145
|
+
</InternalContext.Provider>
|
|
132
146
|
);
|
|
133
147
|
});
|
|
134
148
|
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type { ComponentProps } from '@fountain-ui/core';
|
|
5
|
-
|
|
6
|
-
export type KeyboardDismissMode = 'none' | 'on-drag';
|
|
7
|
-
|
|
8
|
-
export type PageProps = PropsWithChildren<ViewProps> & {
|
|
9
|
-
index: number;
|
|
10
|
-
loading: ViewPagerProps['loading'];
|
|
11
|
-
offscreenPageRerenderLimit: number;
|
|
12
|
-
sharedIndex: SharedValue<number>;
|
|
13
|
-
rerenderKey?: ViewPagerProps['pageForceRerenderKey'];
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type PageComponent = ComponentType<PageProps>;
|
|
17
|
-
|
|
18
|
-
export type Loading = 'lazy' | 'eager';
|
|
19
|
-
|
|
20
|
-
export interface ViewPagerInstance {
|
|
21
|
-
/**
|
|
22
|
-
* Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
|
|
23
|
-
* @param index
|
|
24
|
-
*/
|
|
25
|
-
setPage: (index: number) => void;
|
|
26
|
-
}
|
|
1
|
+
import type { ReactNode, Ref } from 'react';
|
|
2
|
+
import type { ComponentProps, SyncAnimatedValue } from '@fountain-ui/core';
|
|
3
|
+
import type { KeyboardDismissMode, Loading, PageComponent, ViewPagerInstance } from './types';
|
|
27
4
|
|
|
28
5
|
export default interface ViewPagerProps extends ComponentProps<{
|
|
29
6
|
ref?: Ref<ViewPagerInstance>;
|
|
@@ -83,5 +60,5 @@ export default interface ViewPagerProps extends ComponentProps<{
|
|
|
83
60
|
/**
|
|
84
61
|
* Unstable API.
|
|
85
62
|
*/
|
|
86
|
-
UNSTABLE_sharedPage?:
|
|
63
|
+
UNSTABLE_sharedPage?: SyncAnimatedValue;
|
|
87
64
|
}> {}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React, { Children, forwardRef, useCallback, useImperativeHandle } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
import { StyleSheet } from '@fountain-ui/core';
|
|
3
|
+
import { StyleSheet, useSyncAnimatedValue } from '@fountain-ui/core';
|
|
5
4
|
import type ViewPagerProps from './ViewPagerProps';
|
|
6
|
-
import type { ViewPagerInstance } from './
|
|
5
|
+
import type { ViewPagerInstance } from './types';
|
|
7
6
|
import { defaultInitialPage, defaultLoading, defaultPageComponent } from './utils';
|
|
7
|
+
import usePageStore from './usePageStore';
|
|
8
|
+
import InternalContext from './InternalContext';
|
|
8
9
|
|
|
9
10
|
const styles = StyleSheet.create({
|
|
10
11
|
root: {
|
|
@@ -25,12 +26,12 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
25
26
|
UNSTABLE_sharedPage,
|
|
26
27
|
} = props;
|
|
27
28
|
|
|
28
|
-
const fallbackSharedPage =
|
|
29
|
+
const fallbackSharedPage = useSyncAnimatedValue({ initialValue: initialPage });
|
|
29
30
|
|
|
30
31
|
const sharedPage = UNSTABLE_sharedPage ?? fallbackSharedPage;
|
|
31
32
|
|
|
32
33
|
const setPage = useCallback((newPage: number) => {
|
|
33
|
-
sharedPage.
|
|
34
|
+
sharedPage.animatedValue.setValue(newPage);
|
|
34
35
|
}, [sharedPage]);
|
|
35
36
|
|
|
36
37
|
useImperativeHandle(
|
|
@@ -39,22 +40,26 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
|
|
|
39
40
|
[setPage],
|
|
40
41
|
);
|
|
41
42
|
|
|
43
|
+
const pageStore = usePageStore(sharedPage);
|
|
44
|
+
|
|
42
45
|
const PageComponent = pageComponent;
|
|
43
46
|
|
|
44
47
|
return (
|
|
45
|
-
<
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
<InternalContext.Provider value={{ pageStore }}>
|
|
49
|
+
<View style={[styles.root, style]}>
|
|
50
|
+
{Children.map(children, (child, index) => (
|
|
51
|
+
<PageComponent
|
|
52
|
+
key={index}
|
|
53
|
+
children={child}
|
|
54
|
+
index={index}
|
|
55
|
+
initialPage={sharedPage.initialValue}
|
|
56
|
+
loading={loading}
|
|
57
|
+
offscreenPageRerenderLimit={0} // All offscreen pages will not be re-rendered
|
|
58
|
+
rerenderKey={pageForceRerenderKey}
|
|
59
|
+
/>
|
|
60
|
+
))}
|
|
61
|
+
</View>
|
|
62
|
+
</InternalContext.Provider>
|
|
58
63
|
);
|
|
59
64
|
});
|
|
60
65
|
|
package/src/ViewPager/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { default } from './ViewPagerWeb';
|
|
2
|
-
export type { default as ViewPagerProps
|
|
2
|
+
export type { default as ViewPagerProps } from './ViewPagerProps';
|
|
3
|
+
export type { ViewPagerInstance } from './types';
|
|
3
4
|
export { useViewPagerPageState } from './PageStateContext';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ComponentType, PropsWithChildren } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export type PageProps = PropsWithChildren<ViewProps> & {
|
|
5
|
+
index: number;
|
|
6
|
+
initialPage: number;
|
|
7
|
+
loading: Loading;
|
|
8
|
+
offscreenPageRerenderLimit: number;
|
|
9
|
+
rerenderKey?: any;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type KeyboardDismissMode = 'none' | 'on-drag';
|
|
13
|
+
|
|
14
|
+
export type PageComponent = ComponentType<PageProps>;
|
|
15
|
+
|
|
16
|
+
export type Loading = 'lazy' | 'eager';
|
|
17
|
+
|
|
18
|
+
export interface ViewPagerInstance {
|
|
19
|
+
/**
|
|
20
|
+
* Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
|
|
21
|
+
* @param index
|
|
22
|
+
*/
|
|
23
|
+
setPage: (index: number) => void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import type { MonoStore, SyncAnimatedValue } from '@fountain-ui/core';
|
|
3
|
+
import { SimpleStore } from '@fountain-ui/core';
|
|
4
|
+
|
|
5
|
+
export default function usePageStore(value: SyncAnimatedValue): MonoStore<number> {
|
|
6
|
+
const {
|
|
7
|
+
animatedValue,
|
|
8
|
+
initialValue,
|
|
9
|
+
} = value;
|
|
10
|
+
|
|
11
|
+
const store = useRef(new SimpleStore(initialValue)).current;
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const id = animatedValue.addListener((newPage) => {
|
|
15
|
+
store.dispatch(newPage.value);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return () => {
|
|
19
|
+
animatedValue.removeListener(id);
|
|
20
|
+
};
|
|
21
|
+
}, [animatedValue]);
|
|
22
|
+
|
|
23
|
+
return store;
|
|
24
|
+
};
|
package/src/ViewPager/utils.tsx
CHANGED