Skip to content

Commit 75cc839

Browse files
committed
feat: add debug prop
1 parent db490d9 commit 75cc839

File tree

8 files changed

+79
-5
lines changed

8 files changed

+79
-5
lines changed

example/app/scrollviews/vertical.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function VerticalScrollView() {
1818
ref={ref}
1919
offset={OFFSET}
2020
showsVerticalScrollIndicator={false}
21+
debug
2122
>
2223
<Blocks />
2324
</LazyScrollView>

example/components/blocks/Blocks.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export function Blocks({ horizontal }: { horizontal?: boolean }) {
2929
<FireOnceBlock
3030
key={`fire-once-child-${index}`}
3131
percentVisibleThreshold={1}
32+
debug
3233
/>
3334
);
3435
}
@@ -38,6 +39,7 @@ export function Blocks({ horizontal }: { horizontal?: boolean }) {
3839
key={`${source.toString()}-${index}`}
3940
source={source}
4041
percentVisibleThreshold={1}
42+
debug
4143
/>
4244
);
4345
},

src/components/LazyChild/LazyChild.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const LazyChild = function (props: LazyChildProps) {
1212
<BareLazyChild
1313
onEnterThresholdPass={props.onEnterThresholdPass}
1414
onVisibilityEnter={props.onVisibilityEnter}
15+
debug={props.debug}
1516
>
1617
{props.children}
1718
</BareLazyChild>
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import React, { useEffect, useRef } from 'react';
22
import { LazyChildProps } from '../types';
3+
import { logger } from '../../../utils/logger';
34

45
export function BareLazyChild({
56
children,
67
onEnterThresholdPass,
78
onVisibilityEnter,
9+
debug = false,
810
}: Pick<
911
LazyChildProps,
10-
'children' | 'onEnterThresholdPass' | 'onVisibilityEnter'
12+
'children' | 'onEnterThresholdPass' | 'onVisibilityEnter' | 'debug'
1113
>) {
1214
const _hasFired = useRef(false);
1315

@@ -17,11 +19,19 @@ export function BareLazyChild({
1719
if (typeof onEnterThresholdPass === 'function') {
1820
onEnterThresholdPass();
1921
}
22+
2023
if (typeof onVisibilityEnter === 'function') {
2124
onVisibilityEnter();
2225
}
26+
27+
if (debug) {
28+
logger.log(
29+
'<LazyChild>',
30+
'No LazyScrollView provider found. Firing onEnterThresholdPass and onVisibilityEnter once.'
31+
);
32+
}
2333
}
24-
}, [onEnterThresholdPass, onVisibilityEnter]);
34+
}, [debug, onEnterThresholdPass, onVisibilityEnter]);
2535

2636
return <>{children}</>;
2737
}

src/components/LazyChild/components/FullLazyChild.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useCallback } from 'react';
22
import { Dimensions, type LayoutChangeEvent } from 'react-native';
33
import Animated, {
44
measure,
5+
runOnJS,
56
runOnUI,
67
useAnimatedReaction,
78
useAnimatedRef,
@@ -12,16 +13,22 @@ import { useAnimatedContext } from '../../../context/AnimatedContext';
1213
import { useEnteringCallbacks } from '../hooks/useEnteringCallbacks';
1314
import { useVisibilityCallbacks } from '../hooks/useVisibilityCallbacks';
1415
import { LazyChildProps } from '../types';
16+
import { logger } from '../../../utils/logger';
1517

1618
const SCREEN_HEIGHT = Dimensions.get('window').height;
1719

20+
const log = (...args: Parameters<typeof console.log>) => {
21+
logger.log('<LazyChild>', ...args);
22+
};
23+
1824
export function FullLazyChild({
1925
children,
2026
onEnterThresholdPass,
2127
onExitThresholdPass,
2228
percentVisibleThreshold = 1,
2329
onVisibilityEnter,
2430
onVisibilityExit,
31+
debug = false,
2532
}: LazyChildProps) {
2633
const {
2734
startTrigger,
@@ -45,6 +52,8 @@ export function FullLazyChild({
4552
*/
4653
const _measurement = useSharedValue<ReturnType<typeof measure>>(null);
4754

55+
const _debug = useSharedValue(debug);
56+
4857
const _shouldFireThresholdEnter = useSharedValue(
4958
typeof onEnterThresholdPass === 'function'
5059
);
@@ -70,6 +79,10 @@ export function FullLazyChild({
7079
'worklet';
7180
const measurement = measure(_viewRef);
7281

82+
if (_debug.value) {
83+
runOnJS(log)('measurement:', measurement);
84+
}
85+
7386
if (measurement && (measurement?.height || measurement?.width)) {
7487
_measurement.value = measurement;
7588
}
@@ -85,6 +98,10 @@ export function FullLazyChild({
8598
);
8699
},
87100
(shouldMeasure) => {
101+
if (_debug.value) {
102+
runOnJS(log)('shouldMeasure:', shouldMeasure);
103+
}
104+
88105
if (shouldMeasure) {
89106
measureView();
90107
}

src/components/LazyChild/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ export interface LazyChildProps extends LazyChildCallbacks {
3131
* @defaultValue 1.0
3232
*/
3333
percentVisibleThreshold?: number;
34+
/**
35+
* When true, console.logs LazyChilds measurement data. Even if true, will not call console.log in production.
36+
*/
37+
debug?: boolean;
3438
}

src/components/LazyScrollView.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@ import {
1414
} from 'react-native';
1515
import Animated, {
1616
measure,
17+
runOnJS,
1718
runOnUI,
1819
useAnimatedRef,
1920
useDerivedValue,
2021
useScrollViewOffset,
2122
useSharedValue,
2223
} from 'react-native-reanimated';
2324
import { AnimatedContext } from '../context/AnimatedContext';
25+
import { logger } from '../utils/logger';
26+
27+
const log = (...args: Parameters<typeof console.log>) => {
28+
logger.log('<LazyScrollView>', ...args);
29+
};
2430

2531
export interface LazyScrollViewMethods {
2632
scrollTo: typeof ScrollView.prototype.scrollTo;
@@ -38,6 +44,10 @@ export interface LazyScrollViewProps {
3844
* Ref to the LazyScrollView. Exposes scrollTo, scrollToStart, and scrollToEnd methods.
3945
*/
4046
ref?: MutableRefObject<LazyScrollViewMethods>;
47+
/**
48+
* When true, console.logs scrollview measurements. Even if true, will not call console.log in production.
49+
*/
50+
debug?: boolean;
4151
}
4252

4353
type Props = LazyScrollViewProps &
@@ -50,14 +60,15 @@ type Props = LazyScrollViewProps &
5060
* ScrollView to wrap Lazy Children in.
5161
*/
5262
const LazyScrollView = forwardRef<LazyScrollViewMethods, Props>(
53-
({ children, offset: injectedOffset, ...rest }, ref) => {
63+
({ children, offset: injectedOffset, debug = false, ...rest }, ref) => {
5464
const _scrollRef = useAnimatedRef<Animated.ScrollView>();
5565
const _wrapperRef = useRef<View>(null);
5666
const _offset = useSharedValue(injectedOffset || 0);
5767
const _containerDimensions = useSharedValue({ width: 0, height: 0 });
5868
const _containerCoordinates = useSharedValue({ x: 0, y: 0 });
5969
const _contentDimensions = useSharedValue({ width: 0, height: 0 });
6070
const _statusBarHeight = useSharedValue(StatusBar.currentHeight || 0);
71+
const _debug = useSharedValue(debug);
6172
const horizontal = useSharedValue(!!rest.horizontal);
6273

6374
useImperativeHandle(ref, () => ({
@@ -107,17 +118,30 @@ const LazyScrollView = forwardRef<LazyScrollViewMethods, Props>(
107118
width: e.nativeEvent.layout.width,
108119
};
109120

121+
if (debug) {
122+
log('dimensions:', {
123+
height: _containerDimensions.value.height,
124+
width: _containerDimensions.value.width,
125+
});
126+
}
127+
110128
// onLayout runs when RN finishes render, but native layout may not be fully settled until the next frame.
111129
requestAnimationFrame(() => {
112130
runOnUI(() => {
113131
'worklet';
114132
const measurement = measure(_scrollRef);
115133

116134
if (measurement) {
117-
_containerCoordinates.value = {
135+
const coordinates = {
118136
x: measurement.pageX,
119137
y: measurement.pageY + _statusBarHeight.value,
120138
};
139+
140+
if (_debug.value) {
141+
runOnJS(log)('coordinates:', coordinates);
142+
}
143+
144+
_containerCoordinates.value = coordinates;
121145
}
122146
})();
123147
});
@@ -128,10 +152,16 @@ const LazyScrollView = forwardRef<LazyScrollViewMethods, Props>(
128152

129153
const measureContent = useCallback(
130154
(e: LayoutChangeEvent) => {
131-
_contentDimensions.value = {
155+
const dimensions = {
132156
height: e.nativeEvent.layout.height,
133157
width: e.nativeEvent.layout.width,
134158
};
159+
160+
if (debug) {
161+
log('content dimensions:', dimensions);
162+
}
163+
164+
_contentDimensions.value = dimensions;
135165
},
136166
// eslint-disable-next-line react-hooks/exhaustive-deps -- shared values do not trigger re-renders
137167
[]

src/utils/logger.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export const log = (TAG: string, ...args: Parameters<typeof console.log>) => {
2+
if (__DEV__) {
3+
console.log('[LazyScrollView]', TAG, ...args);
4+
}
5+
};
6+
7+
export const logger = {
8+
log,
9+
};

0 commit comments

Comments
 (0)