@fountain-ui/lab 2.0.0-beta.19 → 2.0.0-beta.22

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.
Files changed (125) hide show
  1. package/build/commonjs/ViewPager/FluxContext.js +13 -0
  2. package/build/commonjs/ViewPager/FluxContext.js.map +1 -0
  3. package/build/commonjs/ViewPager/PageStateContext.js +1 -7
  4. package/build/commonjs/ViewPager/PageStateContext.js.map +1 -1
  5. package/build/commonjs/ViewPager/{ViewPagerWeb.js → ViewPager.js} +10 -9
  6. package/build/commonjs/ViewPager/ViewPager.js.map +1 -0
  7. package/build/commonjs/ViewPager/{ViewPagerNative.js → ViewPager.native.js} +11 -10
  8. package/build/commonjs/ViewPager/ViewPager.native.js.map +1 -0
  9. package/build/commonjs/ViewPager/ViewPagerProps.js.map +1 -1
  10. package/build/commonjs/ViewPager/{ChildrenMemoizedPage.js → components/ChildrenMemoizedPage.js} +5 -3
  11. package/build/commonjs/ViewPager/components/ChildrenMemoizedPage.js.map +1 -0
  12. package/build/commonjs/ViewPager/components/FluxStoreProvider.js +37 -0
  13. package/build/commonjs/ViewPager/components/FluxStoreProvider.js.map +1 -0
  14. package/build/commonjs/ViewPager/components/index.js +24 -0
  15. package/build/commonjs/ViewPager/components/index.js.map +1 -0
  16. package/build/commonjs/ViewPager/hooks/index.js +56 -0
  17. package/build/commonjs/ViewPager/hooks/index.js.map +1 -0
  18. package/build/commonjs/ViewPager/hooks/useDispatch.js +22 -0
  19. package/build/commonjs/ViewPager/hooks/useDispatch.js.map +1 -0
  20. package/build/commonjs/ViewPager/hooks/useForceRender.js +16 -0
  21. package/build/commonjs/ViewPager/hooks/useForceRender.js.map +1 -0
  22. package/build/commonjs/ViewPager/hooks/useLazyState.js +45 -0
  23. package/build/commonjs/ViewPager/hooks/useLazyState.js.map +1 -0
  24. package/build/commonjs/ViewPager/{usePageStore.js → hooks/usePageStore.js} +0 -0
  25. package/build/commonjs/ViewPager/{usePageStore.js.map → hooks/usePageStore.js.map} +0 -0
  26. package/build/commonjs/ViewPager/hooks/useStore.js +26 -0
  27. package/build/commonjs/ViewPager/hooks/useStore.js.map +1 -0
  28. package/build/commonjs/ViewPager/hooks/useViewPagerPageState.js +19 -0
  29. package/build/commonjs/ViewPager/hooks/useViewPagerPageState.js.map +1 -0
  30. package/build/commonjs/ViewPager/index.js +30 -4
  31. package/build/commonjs/ViewPager/index.js.map +1 -1
  32. package/build/commonjs/ViewPager/types.js +0 -4
  33. package/build/commonjs/ViewPager/types.js.map +1 -1
  34. package/build/commonjs/ViewPager/utils.js +5 -8
  35. package/build/commonjs/ViewPager/utils.js.map +1 -1
  36. package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js +2 -4
  37. package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
  38. package/build/module/ViewPager/FluxContext.js +4 -0
  39. package/build/module/ViewPager/FluxContext.js.map +1 -0
  40. package/build/module/ViewPager/PageStateContext.js +1 -4
  41. package/build/module/ViewPager/PageStateContext.js.map +1 -1
  42. package/build/module/ViewPager/{ViewPagerWeb.js → ViewPager.js} +10 -10
  43. package/build/module/ViewPager/ViewPager.js.map +1 -0
  44. package/build/module/ViewPager/{ViewPagerNative.js → ViewPager.native.js} +10 -10
  45. package/build/module/ViewPager/ViewPager.native.js.map +1 -0
  46. package/build/module/ViewPager/ViewPagerProps.js.map +1 -1
  47. package/build/module/ViewPager/{ChildrenMemoizedPage.js → components/ChildrenMemoizedPage.js} +5 -4
  48. package/build/module/ViewPager/components/ChildrenMemoizedPage.js.map +1 -0
  49. package/build/module/ViewPager/components/FluxStoreProvider.js +20 -0
  50. package/build/module/ViewPager/components/FluxStoreProvider.js.map +1 -0
  51. package/build/module/ViewPager/components/index.js +3 -0
  52. package/build/module/ViewPager/components/index.js.map +1 -0
  53. package/build/module/ViewPager/hooks/index.js +7 -0
  54. package/build/module/ViewPager/hooks/index.js.map +1 -0
  55. package/build/module/ViewPager/hooks/useDispatch.js +10 -0
  56. package/build/module/ViewPager/hooks/useDispatch.js.map +1 -0
  57. package/build/module/ViewPager/hooks/useForceRender.js +7 -0
  58. package/build/module/ViewPager/hooks/useForceRender.js.map +1 -0
  59. package/build/module/ViewPager/hooks/useLazyState.js +30 -0
  60. package/build/module/ViewPager/hooks/useLazyState.js.map +1 -0
  61. package/build/module/ViewPager/{usePageStore.js → hooks/usePageStore.js} +0 -0
  62. package/build/module/ViewPager/{usePageStore.js.map → hooks/usePageStore.js.map} +0 -0
  63. package/build/module/ViewPager/hooks/useStore.js +14 -0
  64. package/build/module/ViewPager/hooks/useStore.js.map +1 -0
  65. package/build/module/ViewPager/hooks/useViewPagerPageState.js +7 -0
  66. package/build/module/ViewPager/hooks/useViewPagerPageState.js.map +1 -0
  67. package/build/module/ViewPager/index.js +3 -2
  68. package/build/module/ViewPager/index.js.map +1 -1
  69. package/build/module/ViewPager/types.js +1 -1
  70. package/build/module/ViewPager/types.js.map +1 -1
  71. package/build/module/ViewPager/utils.js +1 -2
  72. package/build/module/ViewPager/utils.js.map +1 -1
  73. package/build/module/hooks/useUnstableCollapsibleAppBar.js +3 -5
  74. package/build/module/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
  75. package/build/typescript/ViewPager/FluxContext.d.ts +5 -0
  76. package/build/typescript/ViewPager/PageStateContext.d.ts +1 -2
  77. package/build/typescript/ViewPager/{ViewPagerNative.d.ts → ViewPager.d.ts} +1 -1
  78. package/build/typescript/ViewPager/{ViewPagerWeb.d.ts → ViewPager.native.d.ts} +1 -1
  79. package/build/typescript/ViewPager/ViewPagerProps.d.ts +1 -6
  80. package/build/typescript/ViewPager/components/ChildrenMemoizedPage.d.ts +14 -0
  81. package/build/typescript/ViewPager/components/FluxStoreProvider.d.ts +6 -0
  82. package/build/typescript/ViewPager/components/index.d.ts +2 -0
  83. package/build/typescript/ViewPager/hooks/index.d.ts +6 -0
  84. package/build/typescript/ViewPager/hooks/useDispatch.d.ts +2 -0
  85. package/build/typescript/ViewPager/hooks/useForceRender.d.ts +2 -0
  86. package/build/typescript/ViewPager/hooks/useLazyState.d.ts +2 -0
  87. package/build/typescript/ViewPager/{usePageStore.d.ts → hooks/usePageStore.d.ts} +0 -0
  88. package/build/typescript/ViewPager/hooks/useStore.d.ts +2 -0
  89. package/build/typescript/ViewPager/hooks/useViewPagerPageState.d.ts +1 -0
  90. package/build/typescript/ViewPager/index.d.ts +3 -2
  91. package/build/typescript/ViewPager/types.d.ts +3 -10
  92. package/build/typescript/ViewPager/utils.d.ts +2 -2
  93. package/package.json +2 -2
  94. package/src/ViewPager/FluxContext.ts +8 -0
  95. package/src/ViewPager/PageStateContext.ts +2 -6
  96. package/src/ViewPager/{ViewPagerNative.tsx → ViewPager.native.tsx} +7 -7
  97. package/src/ViewPager/{ViewPagerWeb.tsx → ViewPager.tsx} +7 -7
  98. package/src/ViewPager/ViewPagerProps.ts +1 -7
  99. package/src/ViewPager/{ChildrenMemoizedPage.tsx → components/ChildrenMemoizedPage.tsx} +16 -5
  100. package/src/ViewPager/components/FluxStoreProvider.tsx +27 -0
  101. package/src/ViewPager/components/index.ts +2 -0
  102. package/src/ViewPager/hooks/index.ts +6 -0
  103. package/src/ViewPager/hooks/useDispatch.ts +11 -0
  104. package/src/ViewPager/hooks/useForceRender.ts +7 -0
  105. package/src/ViewPager/hooks/useLazyState.ts +32 -0
  106. package/src/ViewPager/{usePageStore.ts → hooks/usePageStore.ts} +0 -0
  107. package/src/ViewPager/hooks/useStore.ts +15 -0
  108. package/src/ViewPager/hooks/useViewPagerPageState.ts +6 -0
  109. package/src/ViewPager/index.ts +3 -2
  110. package/src/ViewPager/types.ts +4 -13
  111. package/src/ViewPager/utils.tsx +2 -3
  112. package/src/hooks/useUnstableCollapsibleAppBar.ts +3 -3
  113. package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +0 -1
  114. package/build/commonjs/ViewPager/ViewPagerNative.js.map +0 -1
  115. package/build/commonjs/ViewPager/ViewPagerWeb.js.map +0 -1
  116. package/build/commonjs/ViewPager/index.native.js +0 -24
  117. package/build/commonjs/ViewPager/index.native.js.map +0 -1
  118. package/build/module/ViewPager/ChildrenMemoizedPage.js.map +0 -1
  119. package/build/module/ViewPager/ViewPagerNative.js.map +0 -1
  120. package/build/module/ViewPager/ViewPagerWeb.js.map +0 -1
  121. package/build/module/ViewPager/index.native.js +0 -3
  122. package/build/module/ViewPager/index.native.js.map +0 -1
  123. package/build/typescript/ViewPager/ChildrenMemoizedPage.d.ts +0 -5
  124. package/build/typescript/ViewPager/index.native.d.ts +0 -2
  125. package/src/ViewPager/index.native.ts +0 -2
@@ -1 +1 @@
1
- {"version":3,"names":["useRef","Platform","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useAppbarStyles","useElevationStyle","useHeight","defaultOptions","shouldTranslateYReset","ANIMATION_DURATION_MILLIS","SUPPORTS_DRAG_DETECTION","OS","useLargerValueOfLastTwoValues","value","refLatestTwoValues","current","shift","push","Math","max","useUnstableCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","appBarMaxHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","prevOffsetY","overlapped","vectorY","elevationStyle","animatedStyle","transform","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","duration","savedOffsetY","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","deltaY","dy","min","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useUnstableCollapsibleAppBar.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { Falsy, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport {\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport useAppbarStyles from './useAppbarStyles';\nimport useElevationStyle from './useElevationStyle';\nimport useHeight from './useHeight';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n shouldTranslateYReset?: boolean;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n vectorY: SharedValue<number>;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n shouldTranslateYReset: false,\n};\n\nconst ANIMATION_DURATION_MILLIS = 100;\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nfunction useLargerValueOfLastTwoValues(value: number) {\n const refLatestTwoValues = useRef([0, 0]);\n\n refLatestTwoValues.current.shift();\n refLatestTwoValues.current.push(value);\n\n return Math.max(...refLatestTwoValues.current);\n}\n\nexport default function useUnstableCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { shouldTranslateYReset }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const appBarMaxHeight = useLargerValueOfLastTwoValues(appBarHeight);\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const prevOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n const vectorY = useSharedValue<number>(0);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = (nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n if (shouldTranslateYReset) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n offsetsRef.current = [];\n overlapped.value = false;\n }\n\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n }\n };\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n const deltaY = offsetY - prevOffsetY.value;\n vectorY.value = (vectorY.value * deltaY >= 0 && offsetY > 0) ? vectorY.value + deltaY : deltaY;\n prevOffsetY.value = offsetY;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n },\n }, [appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n vectorY,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarMaxHeight : 0 },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["useCallback","useRef","Platform","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useAppbarStyles","useElevationStyle","useHeight","defaultOptions","shouldTranslateYReset","ANIMATION_DURATION_MILLIS","SUPPORTS_DRAG_DETECTION","OS","useLargerValueOfLastTwoValues","value","refLatestTwoValues","current","shift","push","Math","max","useUnstableCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","appBarMaxHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","prevOffsetY","overlapped","vectorY","elevationStyle","animatedStyle","transform","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","duration","savedOffsetY","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","deltaY","dy","min","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useUnstableCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Falsy, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport {\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport useAppbarStyles from './useAppbarStyles';\nimport useElevationStyle from './useElevationStyle';\nimport useHeight from './useHeight';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n shouldTranslateYReset?: boolean;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n vectorY: SharedValue<number>;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n shouldTranslateYReset: false,\n};\n\nconst ANIMATION_DURATION_MILLIS = 100;\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nfunction useLargerValueOfLastTwoValues(value: number) {\n const refLatestTwoValues = useRef([0, 0]);\n\n refLatestTwoValues.current.shift();\n refLatestTwoValues.current.push(value);\n\n return Math.max(...refLatestTwoValues.current);\n}\n\nexport default function useUnstableCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { shouldTranslateYReset }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const appBarMaxHeight = useLargerValueOfLastTwoValues(appBarHeight);\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const prevOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n const vectorY = useSharedValue<number>(0);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n if (shouldTranslateYReset) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n offsetsRef.current = [];\n overlapped.value = false;\n }\n\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n const deltaY = offsetY - prevOffsetY.value;\n vectorY.value = (vectorY.value * deltaY >= 0 && offsetY > 0) ? vectorY.value + deltaY : deltaY;\n prevOffsetY.value = offsetY;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n },\n }, [appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n vectorY,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarMaxHeight : 0 },\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import type { MonoStore } from '@fountain-ui/core';
3
+ export declare type FluxStore<S> = MonoStore<S>;
4
+ declare const FluxContext: import("react").Context<FluxStore<any> | null>;
5
+ export default FluxContext;
@@ -1,7 +1,6 @@
1
1
  /// <reference types="react" />
2
- interface PageState {
2
+ export interface PageState {
3
3
  isActive: boolean;
4
4
  }
5
5
  declare const PageStateContext: import("react").Context<PageState>;
6
- export declare const useViewPagerPageState: () => PageState;
7
6
  export default PageStateContext;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type ViewPagerProps from './ViewPagerProps';
3
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>>;
4
+ declare const ViewPager: React.ForwardRefExoticComponent<Pick<ViewPagerProps, "style" | "children" | "onChange" | "scrollEnabled" | "keyboardDismissMode" | "initialPage" | "loading" | "offscreenPageRerenderLimit" | "pageForceRerenderKey" | "UNSTABLE_sharedPage"> & React.RefAttributes<ViewPagerInstance>>;
5
5
  export default ViewPager;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type ViewPagerProps from './ViewPagerProps';
3
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>>;
4
+ declare const ViewPager: React.ForwardRefExoticComponent<Pick<ViewPagerProps, "style" | "children" | "onChange" | "scrollEnabled" | "keyboardDismissMode" | "initialPage" | "loading" | "offscreenPageRerenderLimit" | "pageForceRerenderKey" | "UNSTABLE_sharedPage"> & React.RefAttributes<ViewPagerInstance>>;
5
5
  export default ViewPager;
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode, Ref } from 'react';
2
2
  import type { ComponentProps, SyncAnimatedValue } from '@fountain-ui/core';
3
- import type { KeyboardDismissMode, Loading, PageComponent, ViewPagerInstance } from './types';
3
+ import type { KeyboardDismissMode, Loading, ViewPagerInstance } from './types';
4
4
  export default interface ViewPagerProps extends ComponentProps<{
5
5
  ref?: Ref<ViewPagerInstance>;
6
6
  /**
@@ -27,11 +27,6 @@ export default interface ViewPagerProps extends ComponentProps<{
27
27
  * Callback fired when an index is changed.
28
28
  */
29
29
  onChange?: (newIndex: number) => void;
30
- /**
31
- * The component used to render the wrapper of the page.
32
- * @default 'ChildrenMemoizedPage'
33
- */
34
- pageComponent?: PageComponent;
35
30
  /**
36
31
  * When this value is changed, page will be rerender.
37
32
  */
@@ -0,0 +1,14 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import React from 'react';
3
+ import type { ViewProps } from 'react-native';
4
+ import type { Loading } from '../types';
5
+ export declare type PageProps = PropsWithChildren<ViewProps> & {
6
+ index: number;
7
+ initialPage: number;
8
+ loading: Loading;
9
+ offscreenPageRerenderLimit: number;
10
+ rerenderKey?: any;
11
+ };
12
+ declare function Page(props: PageProps): JSX.Element;
13
+ declare const _default: React.MemoExoticComponent<typeof Page>;
14
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface FluxStoreProviderProps<State> {
3
+ children: React.ReactElement;
4
+ initialState: State;
5
+ }
6
+ export default function FluxStoreProvider<State>(props: FluxStoreProviderProps<State>): JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { default as ChildrenMemoizedPage } from './ChildrenMemoizedPage';
2
+ export { default as FluxStoreProvider } from './FluxStoreProvider';
@@ -0,0 +1,6 @@
1
+ export { default as useDispatch } from './useDispatch';
2
+ export { default as useForceRender } from './useForceRender';
3
+ export { default as useLazyState } from './useLazyState';
4
+ export { default as usePageStore } from './usePageStore';
5
+ export { default as useStore } from './useStore';
6
+ export { default as useViewPagerPageState } from './useViewPagerPageState';
@@ -0,0 +1,2 @@
1
+ import type { DispatchAction } from '@fountain-ui/core';
2
+ export default function useDispatch<State>(): (action: DispatchAction<State>) => void;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function useForceRender(): import("react").DispatchWithoutAction;
@@ -0,0 +1,2 @@
1
+ import type { EqualityFunction } from '../types';
2
+ export default function useLazyState<State>(equalityFn?: EqualityFunction<State>): State;
@@ -0,0 +1,2 @@
1
+ import type { FluxStore } from '../FluxContext';
2
+ export default function useStore<State>(): FluxStore<State>;
@@ -0,0 +1 @@
1
+ export default function useViewPagerPageState(): import("../PageStateContext").PageState;
@@ -1,4 +1,5 @@
1
- export { default } from './ViewPagerWeb';
1
+ export { default } from './ViewPager';
2
2
  export type { default as ViewPagerProps } from './ViewPagerProps';
3
3
  export type { ViewPagerInstance } from './types';
4
- export { useViewPagerPageState } from './PageStateContext';
4
+ export { useViewPagerPageState, useDispatch as useFluxDispatch, useLazyState, useStore as useFluxStore } from './hooks';
5
+ export { FluxStoreProvider } from './components';
@@ -1,15 +1,8 @@
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
1
  export declare type KeyboardDismissMode = 'none' | 'on-drag';
11
- export declare type PageComponent = ComponentType<PageProps>;
12
2
  export declare type Loading = 'lazy' | 'eager';
3
+ export interface EqualityFunction<State> {
4
+ (a: State, b: State): boolean;
5
+ }
13
6
  export interface ViewPagerInstance {
14
7
  /**
15
8
  * Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
@@ -1,5 +1,5 @@
1
- import type { Loading, PageComponent } from './types';
1
+ import type { EqualityFunction, Loading } from './types';
2
2
  export declare const defaultInitialPage: number;
3
3
  export declare const defaultLoading: Loading;
4
4
  export declare const defaultOffscreenPageRerenderLimit: number;
5
- export declare const defaultPageComponent: PageComponent;
5
+ export declare const refEqual: EqualityFunction<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.19",
3
+ "version": "2.0.0-beta.22",
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": "d18fb7ba86bc8aa042122e5321b9c26381bd5d5f"
73
+ "gitHead": "fecf3188c95df22fd559194feb24b8662872852b"
74
74
  }
@@ -0,0 +1,8 @@
1
+ import { createContext } from 'react';
2
+ import type { MonoStore } from '@fountain-ui/core';
3
+
4
+ export type FluxStore<S> = MonoStore<S>;
5
+
6
+ const FluxContext = createContext<FluxStore<any> | null>(null);
7
+
8
+ export default FluxContext;
@@ -1,6 +1,6 @@
1
- import { createContext, useContext } from 'react';
1
+ import { createContext } from 'react';
2
2
 
3
- interface PageState {
3
+ export interface PageState {
4
4
  isActive: boolean;
5
5
  }
6
6
 
@@ -8,8 +8,4 @@ const initialPageState: Readonly<PageState> = { isActive: false };
8
8
 
9
9
  const PageStateContext = createContext<PageState>(initialPageState);
10
10
 
11
- export const useViewPagerPageState = () => {
12
- return useContext(PageStateContext);
13
- };
14
-
15
11
  export default PageStateContext;
@@ -1,11 +1,12 @@
1
- import React, { Children, forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
1
+ import React, { Children, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
2
2
  import type { ViewPagerOnPageSelectedEvent } from 'react-native-pager-view';
3
3
  import RNViewPager from 'react-native-pager-view';
4
4
  import { useSyncAnimatedValue } from '@fountain-ui/core';
5
+ import { ChildrenMemoizedPage } from './components';
5
6
  import type ViewPagerProps from './ViewPagerProps';
6
7
  import type { ViewPagerInstance } from './types';
7
- import { defaultInitialPage, defaultLoading, defaultOffscreenPageRerenderLimit, defaultPageComponent } from './utils';
8
- import usePageStore from './usePageStore';
8
+ import { usePageStore } from './hooks';
9
+ import { defaultInitialPage, defaultLoading, defaultOffscreenPageRerenderLimit } from './utils';
9
10
  import InternalContext from './InternalContext';
10
11
 
11
12
  const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPager(props, ref) {
@@ -16,7 +17,6 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
16
17
  loading = defaultLoading,
17
18
  offscreenPageRerenderLimit = defaultOffscreenPageRerenderLimit,
18
19
  onChange,
19
- pageComponent = defaultPageComponent,
20
20
  pageForceRerenderKey,
21
21
  scrollEnabled = true,
22
22
  style,
@@ -117,10 +117,10 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
117
117
 
118
118
  const pageStore = usePageStore(sharedPage);
119
119
 
120
- const PageComponent = pageComponent;
120
+ const contextValue = useMemo(() => ({ pageStore }), [pageStore]);
121
121
 
122
122
  return (
123
- <InternalContext.Provider value={{ pageStore }}>
123
+ <InternalContext.Provider value={contextValue}>
124
124
  <RNViewPager
125
125
  ref={pagerRef}
126
126
  initialPage={sharedPage.initialValue}
@@ -131,7 +131,7 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
131
131
  style={style}
132
132
  >
133
133
  {Children.map(children, (child, index) => (
134
- <PageComponent
134
+ <ChildrenMemoizedPage
135
135
  key={index}
136
136
  children={child}
137
137
  index={index}
@@ -1,10 +1,11 @@
1
- import React, { Children, forwardRef, useCallback, useImperativeHandle } from 'react';
1
+ import React, { Children, forwardRef, useCallback, useImperativeHandle, useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { StyleSheet, useSyncAnimatedValue } from '@fountain-ui/core';
4
+ import { ChildrenMemoizedPage } from './components';
4
5
  import type ViewPagerProps from './ViewPagerProps';
5
6
  import type { ViewPagerInstance } from './types';
6
- import { defaultInitialPage, defaultLoading, defaultPageComponent } from './utils';
7
- import usePageStore from './usePageStore';
7
+ import { defaultInitialPage, defaultLoading } from './utils';
8
+ import { usePageStore } from './hooks';
8
9
  import InternalContext from './InternalContext';
9
10
 
10
11
  const styles = StyleSheet.create({
@@ -20,7 +21,6 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
20
21
  children,
21
22
  initialPage = defaultInitialPage,
22
23
  loading = defaultLoading,
23
- pageComponent = defaultPageComponent,
24
24
  pageForceRerenderKey,
25
25
  style,
26
26
  UNSTABLE_sharedPage,
@@ -42,13 +42,13 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
42
42
 
43
43
  const pageStore = usePageStore(sharedPage);
44
44
 
45
- const PageComponent = pageComponent;
45
+ const contextValue = useMemo(() => ({ pageStore }), [pageStore]);
46
46
 
47
47
  return (
48
- <InternalContext.Provider value={{ pageStore }}>
48
+ <InternalContext.Provider value={contextValue}>
49
49
  <View style={[styles.root, style]}>
50
50
  {Children.map(children, (child, index) => (
51
- <PageComponent
51
+ <ChildrenMemoizedPage
52
52
  key={index}
53
53
  children={child}
54
54
  index={index}
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode, Ref } from 'react';
2
2
  import type { ComponentProps, SyncAnimatedValue } from '@fountain-ui/core';
3
- import type { KeyboardDismissMode, Loading, PageComponent, ViewPagerInstance } from './types';
3
+ import type { KeyboardDismissMode, Loading, ViewPagerInstance } from './types';
4
4
 
5
5
  export default interface ViewPagerProps extends ComponentProps<{
6
6
  ref?: Ref<ViewPagerInstance>;
@@ -34,12 +34,6 @@ export default interface ViewPagerProps extends ComponentProps<{
34
34
  */
35
35
  onChange?: (newIndex: number) => void,
36
36
 
37
- /**
38
- * The component used to render the wrapper of the page.
39
- * @default 'ChildrenMemoizedPage'
40
- */
41
- pageComponent?: PageComponent,
42
-
43
37
  /**
44
38
  * When this value is changed, page will be rerender.
45
39
  */
@@ -1,15 +1,26 @@
1
- import React, { memo, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from 'react';
1
+ import type { PropsWithChildren } from 'react';
2
+ import React, { memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
3
+ import type { ViewProps } from 'react-native';
2
4
  import { Platform, View } from 'react-native';
3
5
  import { StyleSheet } from '@fountain-ui/core';
4
- import type { PageProps } from './types';
5
- import PageStateContext from './PageStateContext';
6
- import InternalContext from './InternalContext';
6
+ import type { Loading } from '../types';
7
+ import { useForceRender } from '../hooks';
8
+ import PageStateContext from '../PageStateContext';
9
+ import InternalContext from '../InternalContext';
7
10
 
8
11
  const styles = StyleSheet.create({
9
12
  fill: { width: '100%', height: '100%' },
10
13
  none: { display: 'none' },
11
14
  });
12
15
 
16
+ export type PageProps = PropsWithChildren<ViewProps> & {
17
+ index: number;
18
+ initialPage: number;
19
+ loading: Loading;
20
+ offscreenPageRerenderLimit: number;
21
+ rerenderKey?: any;
22
+ };
23
+
13
24
  interface InternalPageDescription {
14
25
  isActive: boolean;
15
26
  becomeNeighbor: boolean;
@@ -56,7 +67,7 @@ function Page(props: PageProps) {
56
67
 
57
68
  // `Bailing out of a state update` is not working as expected.
58
69
  const pageStateRef = useRef<InternalPageState>(initialState);
59
- const [, forceRender] = useReducer((s) => s + 1, 0);
70
+ const forceRender = useForceRender();
60
71
 
61
72
  const { active, loaded } = pageStateRef.current;
62
73
 
@@ -0,0 +1,27 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { SimpleStore } from '@fountain-ui/core';
3
+ import type { FluxStore } from '../FluxContext';
4
+ import FluxContext from '../FluxContext';
5
+
6
+ export interface FluxStoreProviderProps<State> {
7
+ children: React.ReactElement;
8
+ initialState: State;
9
+ }
10
+
11
+ export default function FluxStoreProvider<State>(props: FluxStoreProviderProps<State>) {
12
+ const { children, initialState } = props;
13
+
14
+ const store = useRef<FluxStore<State>>(new SimpleStore(initialState)).current;
15
+
16
+ useEffect(() => {
17
+ return () => {
18
+ store.removeAllListeners();
19
+ };
20
+ }, [store]);
21
+
22
+ return (
23
+ <FluxContext.Provider value={store}>
24
+ {children}
25
+ </FluxContext.Provider>
26
+ );
27
+ };
@@ -0,0 +1,2 @@
1
+ export { default as ChildrenMemoizedPage } from './ChildrenMemoizedPage';
2
+ export { default as FluxStoreProvider } from './FluxStoreProvider';
@@ -0,0 +1,6 @@
1
+ export { default as useDispatch } from './useDispatch';
2
+ export { default as useForceRender } from './useForceRender';
3
+ export { default as useLazyState } from './useLazyState';
4
+ export { default as usePageStore } from './usePageStore';
5
+ export { default as useStore } from './useStore';
6
+ export { default as useViewPagerPageState } from './useViewPagerPageState';
@@ -0,0 +1,11 @@
1
+ import { useCallback } from 'react';
2
+ import type { DispatchAction } from '@fountain-ui/core';
3
+ import useStore from './useStore';
4
+
5
+ export default function useDispatch<State>() {
6
+ const store = useStore<State>();
7
+
8
+ return useCallback((action: DispatchAction<State>) => {
9
+ store.dispatch(action);
10
+ }, [store]);
11
+ };
@@ -0,0 +1,7 @@
1
+ import { useReducer } from 'react';
2
+
3
+ export default function useForceRender() {
4
+ const [, forceRender] = useReducer((s) => s + 1, 0);
5
+
6
+ return forceRender;
7
+ };
@@ -0,0 +1,32 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import type { EqualityFunction } from '../types';
3
+ import { refEqual } from '../utils';
4
+ import useForceRender from './useForceRender';
5
+ import useViewPagerPageState from './useViewPagerPageState';
6
+ import useStore from './useStore';
7
+
8
+ export default function useLazyState<State>(equalityFn: EqualityFunction<State> = refEqual): State {
9
+ const store = useStore<State>();
10
+
11
+ const stateRef = useRef<State>(store.getState());
12
+
13
+ const forceRender = useForceRender();
14
+
15
+ const { isActive } = useViewPagerPageState();
16
+
17
+ useEffect(() => {
18
+ return store.subscribe(newState => {
19
+ if (equalityFn(stateRef.current, newState)) {
20
+ return;
21
+ }
22
+
23
+ stateRef.current = newState;
24
+
25
+ if (isActive) {
26
+ forceRender();
27
+ }
28
+ });
29
+ }, [store, isActive]);
30
+
31
+ return stateRef.current;
32
+ };
@@ -0,0 +1,15 @@
1
+ import { useContext } from 'react';
2
+ import type { FluxStore } from '../FluxContext';
3
+ import FluxContext from '../FluxContext';
4
+
5
+ export default function useStore<State>(): FluxStore<State> {
6
+ // @ts-ignore
7
+ const store = useContext<FluxStore<State>>(FluxContext);
8
+ if (store == null) {
9
+ throw new Error(
10
+ 'You should wrap your parent component with `FluxStoreProvider`',
11
+ );
12
+ }
13
+
14
+ return store;
15
+ };
@@ -0,0 +1,6 @@
1
+ import { useContext } from 'react';
2
+ import PageStateContext from '../PageStateContext';
3
+
4
+ export default function useViewPagerPageState() {
5
+ return useContext(PageStateContext);
6
+ };
@@ -1,4 +1,5 @@
1
- export { default } from './ViewPagerWeb';
1
+ export { default } from './ViewPager';
2
2
  export type { default as ViewPagerProps } from './ViewPagerProps';
3
3
  export type { ViewPagerInstance } from './types';
4
- export { useViewPagerPageState } from './PageStateContext';
4
+ export { useViewPagerPageState, useDispatch as useFluxDispatch, useLazyState, useStore as useFluxStore } from './hooks';
5
+ export { FluxStoreProvider } from './components';
@@ -1,20 +1,11 @@
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
1
  export type KeyboardDismissMode = 'none' | 'on-drag';
13
2
 
14
- export type PageComponent = ComponentType<PageProps>;
15
-
16
3
  export type Loading = 'lazy' | 'eager';
17
4
 
5
+ export interface EqualityFunction<State> {
6
+ (a: State, b: State): boolean;
7
+ }
8
+
18
9
  export interface ViewPagerInstance {
19
10
  /**
20
11
  * Function to scroll to a specific page in the ViewPager. Invalid index is ignored.
@@ -1,5 +1,4 @@
1
- import ChildrenMemoizedPage from './ChildrenMemoizedPage';
2
- import type { Loading, PageComponent } from './types';
1
+ import type { EqualityFunction, Loading } from './types';
3
2
 
4
3
  export const defaultInitialPage: number = 0;
5
4
 
@@ -7,4 +6,4 @@ export const defaultLoading: Loading = 'lazy';
7
6
 
8
7
  export const defaultOffscreenPageRerenderLimit: number = 0;
9
8
 
10
- export const defaultPageComponent: PageComponent = ChildrenMemoizedPage;
9
+ export const refEqual: EqualityFunction<any> = (a: any, b: any) => a === b;
@@ -1,4 +1,4 @@
1
- import { useRef } from 'react';
1
+ import { useCallback, useRef } from 'react';
2
2
  import { Falsy, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';
3
3
  import type { SharedValue } from 'react-native-reanimated';
4
4
  import {
@@ -117,7 +117,7 @@ export default function useUnstableCollapsibleAppBar(userOptions: Options = defa
117
117
  const indexRef = useRef<number>(0);
118
118
  const offsetsRef = useRef<Array<number>>([]);
119
119
 
120
- const onScrollViewChanged = (nextIndex: number) => {
120
+ const onScrollViewChanged = useCallback((nextIndex: number) => {
121
121
  const prevIndex = indexRef.current;
122
122
  if (prevIndex === nextIndex) {
123
123
  if (shouldTranslateYReset) {
@@ -151,7 +151,7 @@ export default function useUnstableCollapsibleAppBar(userOptions: Options = defa
151
151
 
152
152
  vectorY.value = 0;
153
153
  }
154
- };
154
+ }, [appBarHeight]);
155
155
 
156
156
  const scrollHandler = useAnimatedScrollHandler({
157
157
  onBeginDrag: () => {