Skip to content
This repository has been archived by the owner on Jan 6, 2023. It is now read-only.

Commit

Permalink
add: useFocus() hook, fix: setValue() calls, remove: single-stack com…
Browse files Browse the repository at this point in the history
…ponent
  • Loading branch information
Andrew Smith authored and Andrew Smith committed Sep 29, 2019
1 parent c46bc1c commit 2a0de99
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 530 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ From App.js in /example directory
import React, { useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';

import { Pager } from '@crowdlinker/react-native-pager';
import { Pager, useFocus } from '@crowdlinker/react-native-pager';

const children = Array.from({ length: 1000 }, (_, i) => (
<Slide key={i} i={i} />
Expand Down Expand Up @@ -99,6 +99,7 @@ const colors = [
];

function Slide({ i }: { i: number }) {
const focused = useFocus();
return (
<View
style={{
Expand All @@ -111,6 +112,7 @@ function Slide({ i }: { i: number }) {
}}
>
<Text>{`Screen: ${i}`}</Text>
<Text>{`Focused: ${focused}`}</Text>
</View>
);
}
Expand Down
1 change: 0 additions & 1 deletion example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {SwipeCards} from './src/swipe-cards';
import {Stack} from './src/stack';
import {Tabs} from './src/tabs';
import {MyPager} from './src/basic-example';
import {SingleStackExample} from './src/single-stack-example';
import {PagerProvider} from '@crowdlinker/react-native-pager';

const App = () => {
Expand Down
13 changes: 11 additions & 2 deletions example/src/basic-example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ import {StyleSheet, View, Text, TouchableOpacity} from 'react-native';
import {Pager} from '@crowdlinker/react-native-pager';
import {Slide, NavigationButtons} from './shared-components';

const children = Array.from({length: 1000}, (_, i) => <Slide key={i} i={i} />);
const children = Array.from({length: 10000}, (_, i) => <Slide key={i} i={i} />);

function MyPager() {
const [activeIndex, onChange] = useState(400);
const [activeIndex, onChange] = useState(5000);

return (
<View>
<Text
style={{
textAlign: 'center',
marginBottom: 20,
}}>
{`Number of screens: ${children.length}`}
</Text>

<Pager
activeIndex={activeIndex}
onChange={onChange}
Expand All @@ -20,6 +28,7 @@ function MyPager() {
}}>
{children}
</Pager>

<NavigationButtons activeIndex={activeIndex} onChange={onChange} />
</View>
);
Expand Down
16 changes: 13 additions & 3 deletions example/src/shared-components.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import React, {useState} from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
import {
Text,
View,
TouchableOpacity,
StyleSheet,
TextInput,
Button,
} from 'react-native';
import {useFocus} from '@crowdlinker/react-native-pager';

const colors = [
'aquamarine',
Expand All @@ -12,8 +20,10 @@ const colors = [
'salmon',
];

function Slide({i, focused}: {i: number; focused?: boolean}) {
const [count, setCount] = useState(0);
function Slide({i}: {i: number}) {
// const [count, setCount] = useState(0);
const focused = useFocus();

return (
<View
style={{
Expand Down
57 changes: 0 additions & 57 deletions example/src/single-stack-example.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion example/src/stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function Stack() {
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={{color: colors[activeIndex]}}>Push</Text>
<Text style={{color: colors[activeIndex % colors.length]}}>Push</Text>
</TouchableOpacity>
</View>
</View>
Expand Down
1 change: 0 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './pager';
export * from './pagination';
export * from './single-stack';
66 changes: 50 additions & 16 deletions src/pager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, {
useContext,
useEffect,
memo,
cloneElement,
useRef,
} from 'react';
import { StyleSheet, LayoutChangeEvent, ViewStyle } from 'react-native';
import Animated from 'react-native-reanimated';
Expand All @@ -15,7 +15,7 @@ import {
State,
PanGestureHandlerProperties,
} from 'react-native-gesture-handler';
import { memoize, mapConfigToStyle } from './util';
import { memoize, mapConfigToStyle, safelyUpdateValues } from './util';

export type SpringConfig = {
damping: Animated.Adaptable<number>;
Expand Down Expand Up @@ -98,7 +98,7 @@ const DEFAULT_SPRING_CONFIG = {
restSpeedThreshold: 0.01,
};

export interface PagerProps {
export interface iPager {
activeIndex?: number;
onChange?: (nextIndex: number) => void;
initialIndex?: number;
Expand Down Expand Up @@ -152,7 +152,7 @@ function Pager({
next: REALLY_BIG_NUMBER,
},
animatedIndex: parentAnimatedIndex,
}: PagerProps) {
}: iPager) {
const context = useContext(PagerContext);

// register these props if they exist -- they can be shared with other
Expand Down Expand Up @@ -209,8 +209,11 @@ function Pager({
// set this up on first render, and update when the value from above changes
const maxIndex = memoize(new Value(maxIndexValue));

const maxIndexUpdateReq = useRef<undefined | number>(undefined);
useEffect(() => {
maxIndex.setValue(maxIndexValue);
safelyUpdateValues(() => {
maxIndex.setValue(maxIndexValue);
}, maxIndexUpdateReq);
}, [maxIndexValue]);

const dragX = memoize(new Value(0));
Expand Down Expand Up @@ -252,15 +255,19 @@ function Pager({
const width = memoize(new Value(0));
const height = memoize(new Value(0));

const layoutRequest = useRef<undefined | number>(undefined);

function handleLayout({ nativeEvent: { layout } }: LayoutChangeEvent) {
width.setValue(layout.width as any);
height.setValue(layout.height as any);

// this sets the initial offset to the correct translation w/o animation
// e.g an initial index of 4 will be centered when layout registers
translationValue.setValue((activeIndex *
layout[targetDimension] *
-1) as any);
safelyUpdateValues(() => {
width.setValue(layout.width as any);
height.setValue(layout.height as any);

// this sets the initial offset to the correct translation w/o animation
// e.g an initial index of 4 will be centered when layout registers
translationValue.setValue((activeIndex *
layout[targetDimension] *
-1) as any);
}, layoutRequest);
}

// correctly assign variables based on vertical / horizontal configurations
Expand Down Expand Up @@ -343,9 +350,14 @@ function Pager({

// not sure if Animated.useCode is any better here, it seemed to fire much more
// frequently than activeIndex was actually changing.

const indexChangeRequest = useRef<undefined | number>(undefined);

useEffect(() => {
if (activeIndex >= minIndex && activeIndex <= maxIndexValue) {
nextPosition.setValue(activeIndex);
safelyUpdateValues(() => {
nextPosition.setValue(activeIndex);
}, indexChangeRequest);
}
}, [activeIndex, nextPosition]);

Expand Down Expand Up @@ -525,7 +537,9 @@ function Pager({
clampNext={clampNext}
pageInterpolation={pageInterpolation}
>
{cloneElement(child, { focused: activeIndex === index })}
<FocusProvider focused={index === activeIndex}>
{child}
</FocusProvider>
</Page>
);
})}
Expand Down Expand Up @@ -679,4 +693,24 @@ function usePager(): iPagerContext {
return context;
}

export { Pager, PagerProvider, usePager, PagerContext };
// provide hook for child screens to access pager focus:
const FocusContext = React.createContext(false);

interface iFocusProvider {
children: React.ReactNode;
focused: boolean;
}

function FocusProvider({ focused, children }: iFocusProvider) {
return (
<FocusContext.Provider value={focused}>{children}</FocusContext.Provider>
);
}

function useFocus() {
const focused = useContext(FocusContext);

return focused;
}

export { Pager, PagerProvider, usePager, PagerContext, useFocus };
14 changes: 10 additions & 4 deletions src/pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Children } from 'react';
import React, { Children, useRef } from 'react';
import Animated from 'react-native-reanimated';
import { ViewStyle, LayoutChangeEvent } from 'react-native';
import { iPageInterpolation, usePager } from './pager';
import { memoize, mapConfigToStyle } from './util';
import { memoize, mapConfigToStyle, safelyUpdateValues } from './util';

const { sub, Value, divide, multiply, add } = Animated;

Expand Down Expand Up @@ -105,9 +105,12 @@ function Slider({
: new Value(0);

const width = memoize(new Value(0));
const request = useRef<undefined | number>(undefined);

function handleLayout({ nativeEvent: { layout } }: LayoutChangeEvent) {
width.setValue(layout.width as any);
safelyUpdateValues(() => {
width.setValue(layout.width as any);
}, request);
}

const sliderWidth = divide(width, numberOfScreens);
Expand Down Expand Up @@ -142,9 +145,12 @@ function Progress({
: new Value(0);

const width = memoize(new Value(0));
const request = useRef<undefined | number>(undefined);

function handleLayout({ nativeEvent: { layout } }: LayoutChangeEvent) {
width.setValue(layout.width as any);
safelyUpdateValues(() => {
width.setValue(layout.width as any);
}, request);
}

const sliderWidth = divide(
Expand Down
Loading

0 comments on commit 2a0de99

Please sign in to comment.