Skip to content

Commit 419ae0e

Browse files
committed
Merge branch 'feature/timer-intervals' into develop
2 parents 2687cd3 + 221010f commit 419ae0e

File tree

9 files changed

+56
-20
lines changed

9 files changed

+56
-20
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ return (
445445
| maximumHours | The highest value on the hours picker | Number | 23 | false |
446446
| maximumMinutes | The highest value on the minutes picker | Number | 59 | false |
447447
| maximumSeconds | The highest value on the seconds picker | Number | 59 | false |
448+
| hourInterval | The interval between values on the hours picker | Number | 1 | false |
449+
| minuteInterval | The interval between values on the minutes picker | Number | 1 | false |
450+
| secondInterval | The interval between values on the seconds picker | Number | 1 | false |
448451
| hourLabel | Label for the hours picker | String \| React.ReactElement | h | false |
449452
| minuteLabel | Label for the minutes picker | String \| React.ReactElement | m | false |
450453
| secondLabel | Label for the seconds picker | String \| React.ReactElement | s | false |

src/components/DurationScroll/index.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
4040
FlatList = RNFlatList,
4141
Haptics,
4242
initialValue = 0,
43+
interval,
4344
is12HourPicker,
4445
isDisabled,
4546
label,
@@ -65,8 +66,8 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
6566
return 1;
6667
}
6768

68-
return maximumValue + 1;
69-
}, [maximumValue]);
69+
return Math.floor(maximumValue / interval) + 1;
70+
}, [interval, maximumValue]);
7071

7172
const safeRepeatNumbersNTimes = useMemo(() => {
7273
// do not repeat numbers if there is only one option
@@ -102,6 +103,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
102103
repeatNTimes: safeRepeatNumbersNTimes,
103104
disableInfiniteScroll,
104105
padWithNItems,
106+
interval,
105107
});
106108
}
107109

@@ -110,10 +112,12 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
110112
repeatNTimes: safeRepeatNumbersNTimes,
111113
disableInfiniteScroll,
112114
padWithNItems,
115+
interval,
113116
});
114117
}, [
115118
disableInfiniteScroll,
116119
is12HourPicker,
120+
interval,
117121
numberOfItems,
118122
padNumbersWithZero,
119123
padWithNItems,
@@ -124,6 +128,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
124128
() =>
125129
getInitialScrollIndex({
126130
disableInfiniteScroll,
131+
interval,
127132
numberOfItems,
128133
padWithNItems,
129134
repeatNumbersNTimes: safeRepeatNumbersNTimes,
@@ -132,15 +137,16 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
132137
[
133138
disableInfiniteScroll,
134139
initialValue,
140+
interval,
135141
numberOfItems,
136142
padWithNItems,
137143
safeRepeatNumbersNTimes,
138144
]
139145
);
140146

141147
const adjustedLimited = useMemo(
142-
() => getAdjustedLimit(limit, numberOfItems),
143-
[limit, numberOfItems]
148+
() => getAdjustedLimit(limit, numberOfItems, interval),
149+
[interval, limit, numberOfItems]
144150
);
145151

146152
const numberOfItemsToShow = 1 + padWithNItems * 2;
@@ -261,6 +267,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
261267
if (aggressivelyGetLatestDuration) {
262268
const newValues = getDurationAndIndexFromScrollOffset({
263269
disableInfiniteScroll,
270+
interval,
264271
itemHeight: styles.pickerItemContainer.height,
265272
numberOfItems,
266273
padWithNItems,
@@ -322,6 +329,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
322329
aggressivelyGetLatestDuration,
323330
clickSound,
324331
disableInfiniteScroll,
332+
interval,
325333
numberOfItems,
326334
padWithNItems,
327335
styles.pickerItemContainer.height,
@@ -332,6 +340,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
332340
(e: NativeSyntheticEvent<NativeScrollEvent>) => {
333341
const newValues = getDurationAndIndexFromScrollOffset({
334342
disableInfiniteScroll,
343+
interval,
335344
itemHeight: styles.pickerItemContainer.height,
336345
numberOfItems,
337346
padWithNItems,
@@ -370,14 +379,15 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
370379
onDurationChange(newValues.duration);
371380
},
372381
[
373-
adjustedLimited.max,
374-
adjustedLimited.min,
375-
numbersForFlatList.length,
376382
disableInfiniteScroll,
383+
interval,
384+
styles.pickerItemContainer.height,
377385
numberOfItems,
378-
onDurationChange,
379386
padWithNItems,
380-
styles.pickerItemContainer.height,
387+
adjustedLimited.max,
388+
adjustedLimited.min,
389+
onDurationChange,
390+
numbersForFlatList.length,
381391
]
382392
);
383393

@@ -474,6 +484,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
474484
animated: options?.animated ?? false,
475485
index: getInitialScrollIndex({
476486
disableInfiniteScroll,
487+
interval,
477488
numberOfItems,
478489
padWithNItems,
479490
repeatNumbersNTimes: safeRepeatNumbersNTimes,

src/components/DurationScroll/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface DurationScrollProps {
2828
clickSoundAsset?: SoundAssetType;
2929
disableInfiniteScroll?: boolean;
3030
initialValue?: number;
31+
interval: number;
3132
is12HourPicker?: boolean;
3233
isDisabled?: boolean;
3334
label?: string | React.ReactElement;

src/components/TimerPicker/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
2525
hideHours = false,
2626
hideMinutes = false,
2727
hideSeconds = false,
28+
hourInterval = 1,
2829
hourLabel,
2930
hourLimit,
3031
hoursPickerIsDisabled = false,
3132
initialValue,
3233
maximumHours = 23,
3334
maximumMinutes = 59,
3435
maximumSeconds = 59,
36+
minuteInterval = 1,
3537
minuteLabel,
3638
minuteLimit,
3739
minutesPickerIsDisabled = false,
@@ -45,6 +47,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
4547
repeatHourNumbersNTimes = 8,
4648
repeatMinuteNumbersNTimes = 3,
4749
repeatSecondNumbersNTimes = 3,
50+
secondInterval = 1,
4851
secondLabel,
4952
secondLimit,
5053
secondsPickerIsDisabled = false,
@@ -153,6 +156,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
153156
amLabel={amLabel}
154157
disableInfiniteScroll={disableInfiniteScroll}
155158
initialValue={safeInitialValue.hours}
159+
interval={hourInterval}
156160
is12HourPicker={use12HourPicker}
157161
isDisabled={hoursPickerIsDisabled}
158162
label={
@@ -182,6 +186,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
182186
allowFontScaling={allowFontScaling}
183187
disableInfiniteScroll={disableInfiniteScroll}
184188
initialValue={safeInitialValue.minutes}
189+
interval={minuteInterval}
185190
isDisabled={minutesPickerIsDisabled}
186191
label={minuteLabel ?? "m"}
187192
limit={minuteLimit}
@@ -207,6 +212,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
207212
allowFontScaling={allowFontScaling}
208213
disableInfiniteScroll={disableInfiniteScroll}
209214
initialValue={safeInitialValue.seconds}
215+
interval={secondInterval}
210216
isDisabled={secondsPickerIsDisabled}
211217
label={secondLabel ?? "s"}
212218
limit={secondLimit}

src/components/TimerPicker/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export interface TimerPickerProps {
4545
hideHours?: boolean;
4646
hideMinutes?: boolean;
4747
hideSeconds?: boolean;
48+
hourInterval?: number;
4849
hourLabel?: string | React.ReactElement;
4950
hourLimit?: LimitType;
5051
hoursPickerIsDisabled?: boolean;
@@ -56,6 +57,7 @@ export interface TimerPickerProps {
5657
maximumHours?: number;
5758
maximumMinutes?: number;
5859
maximumSeconds?: number;
60+
minuteInterval?: number;
5961
minuteLabel?: string | React.ReactElement;
6062
minuteLimit?: LimitType;
6163
minutesPickerIsDisabled?: boolean;
@@ -75,6 +77,7 @@ export interface TimerPickerProps {
7577
repeatHourNumbersNTimes?: number;
7678
repeatMinuteNumbersNTimes?: number;
7779
repeatSecondNumbersNTimes?: number;
80+
secondInterval?: number;
7881
secondLabel?: string | React.ReactElement;
7982
secondLimit?: LimitType;
8083
secondsPickerIsDisabled?: boolean;

src/utils/generateNumbers.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const generateNumbers = (
44
numberOfItems: number,
55
options: {
66
disableInfiniteScroll?: boolean;
7+
interval: number;
78
padNumbersWithZero?: boolean;
89
padWithNItems: number;
910
repeatNTimes: number;
@@ -15,7 +16,10 @@ export const generateNumbers = (
1516

1617
let numbers: string[] = [];
1718
for (let i = 0; i < numberOfItems; i++) {
18-
numbers.push(padNumber(i, { padWithZero: options.padNumbersWithZero }));
19+
const value = i * options.interval;
20+
numbers.push(
21+
padNumber(value, { padWithZero: options.padNumbersWithZero })
22+
);
1923
}
2024

2125
if (options.repeatNTimes > 1) {
@@ -30,21 +34,22 @@ export const generateNumbers = (
3034

3135
export const generate12HourNumbers = (options: {
3236
disableInfiniteScroll?: boolean;
37+
interval: number;
3338
padNumbersWithZero?: boolean;
3439
padWithNItems: number;
3540
repeatNTimes?: number;
3641
}) => {
3742
let numbers: string[] = [];
3843

3944
// Generate numbers from 0 to 11 for AM
40-
for (let i = 0; i <= 11; i++) {
45+
for (let i = 0; i < 12; i += options.interval) {
4146
numbers.push(
4247
`${padNumber(i, { padWithZero: options.padNumbersWithZero })} AM`
4348
);
4449
}
4550

4651
// Generate numbers from 12 to 11 for PM
47-
for (let i = 12; i <= 23; i++) {
52+
for (let i = 12; i < 24; i += options.interval) {
4853
const hour = i > 12 ? i - 12 : i;
4954
numbers.push(
5055
`${padNumber(hour, { padWithZero: options.padNumbersWithZero })} PM`

src/utils/getAdjustedLimit.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,31 @@ import type { LimitType } from "../components/DurationScroll/types";
22

33
export const getAdjustedLimit = (
44
limit: LimitType | undefined,
5-
numberOfItems: number
5+
numberOfItems: number,
6+
interval: number
67
): {
78
max: number;
89
min: number;
910
} => {
10-
const maxIndex = numberOfItems - 1;
11+
const maxValue = (numberOfItems - 1) * interval;
1112

1213
if (!limit || (!limit.max && !limit.min)) {
1314
return {
14-
max: maxIndex,
15+
max: maxValue,
1516
min: 0,
1617
};
1718
}
1819

1920
// guard against limits that are out of bounds
2021
const adjustedMaxLimit = limit.max
21-
? Math.min(limit.max, maxIndex)
22-
: maxIndex;
22+
? Math.min(limit.max, maxValue)
23+
: maxValue;
2324
const adjustedMinLimit = limit.min ? Math.max(limit.min, 0) : 0;
2425

2526
// guard against invalid limits
2627
if (adjustedMaxLimit < adjustedMinLimit) {
2728
return {
28-
max: maxIndex,
29+
max: maxValue,
2930
min: 0,
3031
};
3132
}

src/utils/getDurationAndIndexFromScrollOffset.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
export const getDurationAndIndexFromScrollOffset = (variables: {
22
disableInfiniteScroll: boolean;
3+
interval: number;
34
itemHeight: number;
45
numberOfItems: number;
56
padWithNItems: number;
67
yContentOffset: number;
78
}) => {
89
const {
910
disableInfiniteScroll,
11+
interval,
1012
itemHeight,
1113
numberOfItems,
1214
padWithNItems,
@@ -16,7 +18,9 @@ export const getDurationAndIndexFromScrollOffset = (variables: {
1618
const index = Math.round(yContentOffset / itemHeight);
1719

1820
const duration =
19-
(disableInfiniteScroll ? index : index + padWithNItems) % numberOfItems;
21+
((disableInfiniteScroll ? index : index + padWithNItems) %
22+
numberOfItems) *
23+
interval;
2024

2125
return {
2226
duration,

src/utils/getInitialScrollIndex.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
export const getInitialScrollIndex = (variables: {
22
disableInfiniteScroll: boolean;
3+
interval: number;
34
numberOfItems: number;
45
padWithNItems: number;
56
repeatNumbersNTimes: number;
67
value: number;
78
}) => {
89
const {
910
disableInfiniteScroll,
11+
interval,
1012
numberOfItems,
1113
padWithNItems,
1214
repeatNumbersNTimes,
@@ -15,7 +17,7 @@ export const getInitialScrollIndex = (variables: {
1517

1618
return Math.max(
1719
numberOfItems * Math.floor(repeatNumbersNTimes / 2) +
18-
((value + numberOfItems) % numberOfItems) -
20+
((value / interval + numberOfItems) % numberOfItems) -
1921
(!disableInfiniteScroll ? padWithNItems : 0),
2022
0
2123
);

0 commit comments

Comments
 (0)