Skip to content

Commit 8ced933

Browse files
committed
🦺 ensure non-negative initial scroll index in all cases + ensure safe inputs for repeatNumbersNTimes prop
1 parent bae480d commit 8ced933

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

‎src/components/DurationScroll/index.tsx‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,29 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
5656
topPickerGradientOverlayProps,
5757
} = props;
5858

59+
const safeRepeatNumbersNTimes = useMemo(() => {
60+
if (!disableInfiniteScroll && repeatNumbersNTimes < 2) {
61+
return 2;
62+
} else if (repeatNumbersNTimes < 1) {
63+
return 1;
64+
}
65+
66+
return Math.round(repeatNumbersNTimes);
67+
}, [disableInfiniteScroll, repeatNumbersNTimes]);
68+
5969
const data = useMemo(() => {
6070
if (is12HourPicker) {
6171
return generate12HourNumbers({
6272
padNumbersWithZero,
63-
repeatNTimes: repeatNumbersNTimes,
73+
repeatNTimes: safeRepeatNumbersNTimes,
6474
disableInfiniteScroll,
6575
padWithNItems,
6676
});
6777
}
6878

6979
return generateNumbers(numberOfItems, {
7080
padNumbersWithZero,
71-
repeatNTimes: repeatNumbersNTimes,
81+
repeatNTimes: safeRepeatNumbersNTimes,
7282
disableInfiniteScroll,
7383
padWithNItems,
7484
});
@@ -78,25 +88,27 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
7888
numberOfItems,
7989
padNumbersWithZero,
8090
padWithNItems,
81-
repeatNumbersNTimes,
91+
safeRepeatNumbersNTimes,
8292
]);
8393

8494
const initialScrollIndex = useMemo(
8595
() =>
8696
getScrollIndex({
8797
numberOfItems,
8898
padWithNItems,
89-
repeatNumbersNTimes,
99+
repeatNumbersNTimes: safeRepeatNumbersNTimes,
90100
value: initialValue,
91101
}),
92102
[
93103
initialValue,
94104
numberOfItems,
95105
padWithNItems,
96-
repeatNumbersNTimes,
106+
safeRepeatNumbersNTimes,
97107
]
98108
);
99109

110+
console.log(numberOfItems, initialScrollIndex);
111+
100112
const adjustedLimited = useMemo(
101113
() => getAdjustedLimit(limit, numberOfItems),
102114
[limit, numberOfItems]
@@ -156,7 +168,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
156168
index: getScrollIndex({
157169
numberOfItems,
158170
padWithNItems,
159-
repeatNumbersNTimes,
171+
repeatNumbersNTimes: safeRepeatNumbersNTimes,
160172
value: value,
161173
}),
162174
});
@@ -311,6 +323,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
311323

312324
// check limits
313325
if (newDuration > adjustedLimited.max) {
326+
// TODO (NOW): make this work for a quick scroll
314327
const targetScrollIndex =
315328
newIndex - (newDuration - adjustedLimited.max);
316329
flatListRef.current?.scrollToIndex({
@@ -363,15 +376,15 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
363376
} else if (
364377
viewableItems[0]?.index &&
365378
viewableItems[0].index >=
366-
numberOfItems * (repeatNumbersNTimes - 0.5)
379+
numberOfItems * (safeRepeatNumbersNTimes - 0.5)
367380
) {
368381
flatListRef.current?.scrollToIndex({
369382
animated: false,
370383
index: viewableItems[0].index - numberOfItems - 1,
371384
});
372385
}
373386
},
374-
[numberOfItems, repeatNumbersNTimes]
387+
[numberOfItems, safeRepeatNumbersNTimes]
375388
);
376389

377390
const getItemLayout = useCallback(

‎src/components/TimerPicker/index.tsx‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,22 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
5050
...otherProps
5151
} = props;
5252

53-
const checkedPadWithNItems =
54-
padWithNItems >= 0 ? Math.round(padWithNItems) : 0;
53+
const safePadWithNItems = useMemo(() => {
54+
if (padWithNItems < 0) {
55+
return 0;
56+
}
57+
// check if large values also work
58+
59+
return Math.round(padWithNItems);
60+
}, [padWithNItems]);
5561

5662
const styles = useMemo(
5763
() =>
5864
generateStyles(customStyles, {
59-
padWithNItems: checkedPadWithNItems,
65+
padWithNItems: safePadWithNItems,
6066
}),
6167

62-
[checkedPadWithNItems, customStyles]
68+
[safePadWithNItems, customStyles]
6369
);
6470

6571
const safeInitialValue = useMemo(
@@ -148,7 +154,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
148154
numberOfItems={23}
149155
onDurationChange={setSelectedHours}
150156
padNumbersWithZero={padHoursWithZero}
151-
padWithNItems={checkedPadWithNItems}
157+
padWithNItems={safePadWithNItems}
152158
pmLabel={pmLabel}
153159
repeatNumbersNTimes={repeatHourNumbersNTimes}
154160
styles={styles}
@@ -171,7 +177,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
171177
numberOfItems={59}
172178
onDurationChange={setSelectedMinutes}
173179
padNumbersWithZero={padMinutesWithZero}
174-
padWithNItems={checkedPadWithNItems}
180+
padWithNItems={safePadWithNItems}
175181
repeatNumbersNTimes={repeatMinuteNumbersNTimes}
176182
styles={styles}
177183
testID="duration-scroll-minute"
@@ -193,7 +199,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
193199
numberOfItems={59}
194200
onDurationChange={setSelectedSeconds}
195201
padNumbersWithZero={padSecondsWithZero}
196-
padWithNItems={checkedPadWithNItems}
202+
padWithNItems={safePadWithNItems}
197203
repeatNumbersNTimes={repeatSecondNumbersNTimes}
198204
styles={styles}
199205
testID="duration-scroll-second"

‎src/utils/generateNumbers.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const generateNumbers = (
66
disableInfiniteScroll?: boolean;
77
padNumbersWithZero?: boolean;
88
padWithNItems: number;
9-
repeatNTimes?: number;
9+
repeatNTimes: number;
1010
}
1111
) => {
1212
if (numberOfItems <= 0) {
@@ -18,10 +18,10 @@ export const generateNumbers = (
1818
numbers.push(padNumber(i, { padWithZero: options.padNumbersWithZero }));
1919
}
2020

21-
if ((options.repeatNTimes ?? 1) > 1) {
21+
if (options.repeatNTimes > 1) {
2222
numbers = Array(options.repeatNTimes).fill(numbers).flat();
2323
}
24-
if (options.disableInfiniteScroll) {
24+
if (options.disableInfiniteScroll || options.repeatNTimes === 1) {
2525
numbers.push(...Array(options.padWithNItems).fill(""));
2626
numbers.unshift(...Array(options.padWithNItems).fill(""));
2727
}

‎src/utils/getScrollIndex.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ export const getScrollIndex = (variables: {
77
const { numberOfItems, padWithNItems, repeatNumbersNTimes, value } =
88
variables;
99

10-
return (
10+
return Math.max(
1111
((value + numberOfItems) % (numberOfItems * repeatNumbersNTimes)) -
12-
(padWithNItems - 1)
12+
(padWithNItems - 1),
13+
0
1314
);
1415
};

0 commit comments

Comments
 (0)