react-native-timer-picker 1.1.4 → 1.2.0
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.
- package/README.md +21 -3
- package/dist/components/Modal/index.d.ts +3 -2
- package/dist/components/Modal/index.js +3 -3
- package/dist/components/TimerPicker/DurationScroll.d.ts +8 -3
- package/dist/components/TimerPicker/DurationScroll.js +76 -19
- package/dist/components/TimerPicker/TimerPicker.styles.d.ts +2 -0
- package/dist/components/TimerPicker/TimerPicker.styles.js +1 -0
- package/dist/components/TimerPicker/index.d.ts +9 -5
- package/dist/components/TimerPicker/index.js +10 -8
- package/dist/components/index.d.ts +8 -3
- package/dist/components/index.js +12 -6
- package/dist/index.d.ts +1 -1
- package/dist/utils/getAdjustedLimit.d.ts +5 -0
- package/dist/utils/getAdjustedLimit.js +28 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -308,9 +308,12 @@ return (
|
|
|
308
308
|
| hideHours | Hide the hours picker | Boolean | false | false |
|
|
309
309
|
| hideMinutes | Hide the minutes picker | Boolean | false | false |
|
|
310
310
|
| hideSeconds | Hide the seconds picker | Boolean | false | false |
|
|
311
|
-
|
|
|
312
|
-
|
|
|
313
|
-
|
|
|
311
|
+
| hourLimit | Limit on the hours it is possible to select | { max?: Number, min?: Number } | - | false |
|
|
312
|
+
| minuteLimit | Limit on the minutes it is possible to select | { max?: Number, min?: Number } | - | false |
|
|
313
|
+
| secondLimit | Limit on the seconds it is possible to select | { max?: Number, min?: Number } | - | false |
|
|
314
|
+
| hourLabel | Label for the hours picker | String \| React.ReactElement | h | false |
|
|
315
|
+
| minuteLabel | Label for the minutes picker | String \| React.ReactElement | m | false |
|
|
316
|
+
| secondLabel | Label for the seconds picker | String \| React.ReactElement | s | false |
|
|
314
317
|
| padWithNItems | Number of items to pad the picker with on either side | Number | 1 | false |
|
|
315
318
|
| disableInfiniteScroll | Disable the infinite scroll feature | Boolean | false | false |
|
|
316
319
|
| LinearGradient | Linear Gradient Component | [expo-linear-gradient](https://www.npmjs.com/package/expo-linear-gradient).LinearGradient or [react-native-linear-gradient](https://www.npmjs.com/package/react-native-linear-gradient).default | - | false |
|
|
@@ -332,6 +335,7 @@ The following custom styles can be supplied to re-style the component in any way
|
|
|
332
335
|
| pickerLabel | Style for the picker's labels | TextStyle |
|
|
333
336
|
| pickerItemContainer | Container for each number in the picker | ViewStyle |
|
|
334
337
|
| pickerItem | Style for each individual picker number | TextStyle |
|
|
338
|
+
| disabledPickerItem | Style for any numbers outside any set limits | TextStyle |
|
|
335
339
|
| pickerGradientOverlay | Style for the gradient overlay (fade out) | ViewStyle |
|
|
336
340
|
|
|
337
341
|
### TimerPickerModal ⏰
|
|
@@ -375,12 +379,26 @@ The following custom styles can be supplied to re-style the component in any way
|
|
|
375
379
|
|
|
376
380
|
### TimerPickerModal
|
|
377
381
|
|
|
382
|
+
The library exposes a TimerPickerModalRef type, which can be used to type your ref to the modal:
|
|
383
|
+
|
|
384
|
+
```javascript
|
|
385
|
+
const timerPickerModalRef = useRef<TimerPickerModalRef>(null);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
It has the following available methods:
|
|
389
|
+
|
|
378
390
|
`reset` - imperative method to reset the selected duration to their initial values.
|
|
379
391
|
|
|
380
392
|
```javascript
|
|
381
393
|
timerPickerModalRef.current.reset();
|
|
382
394
|
```
|
|
383
395
|
|
|
396
|
+
`setValue` - imperative method to set the selected duration to a particular value
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
timerPickerModalRef.current.setValue({hours: number, minutes: number, seconds: number});
|
|
400
|
+
```
|
|
401
|
+
|
|
384
402
|
## License 📝
|
|
385
403
|
|
|
386
404
|
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -11,5 +11,6 @@ interface ModalProps {
|
|
|
11
11
|
overlayStyle?: any;
|
|
12
12
|
testID?: string;
|
|
13
13
|
}
|
|
14
|
-
export declare const Modal: ({ children, onOverlayPress, onHide, isVisible, animationDuration, overlayOpacity, modalProps, contentStyle, overlayStyle, testID }: ModalProps) => React.ReactElement;
|
|
15
|
-
|
|
14
|
+
export declare const Modal: ({ children, onOverlayPress, onHide, isVisible, animationDuration, overlayOpacity, modalProps, contentStyle, overlayStyle, testID, }: ModalProps) => React.ReactElement;
|
|
15
|
+
declare const _default: React.MemoExoticComponent<({ children, onOverlayPress, onHide, isVisible, animationDuration, overlayOpacity, modalProps, contentStyle, overlayStyle, testID, }: ModalProps) => React.ReactElement<any, string | React.JSXElementConstructor<any>>>;
|
|
16
|
+
export default _default;
|
|
@@ -76,7 +76,7 @@ var Modal = function (_a) {
|
|
|
76
76
|
react_native_1.Animated.timing(animatedOpacity.current, {
|
|
77
77
|
easing: react_native_1.Easing.inOut(react_native_1.Easing.quad),
|
|
78
78
|
// Using native driver in the modal makes the content flash
|
|
79
|
-
useNativeDriver:
|
|
79
|
+
useNativeDriver: true,
|
|
80
80
|
duration: animationDuration,
|
|
81
81
|
toValue: 1,
|
|
82
82
|
}).start();
|
|
@@ -85,7 +85,7 @@ var Modal = function (_a) {
|
|
|
85
85
|
react_native_1.Animated.timing(animatedOpacity.current, {
|
|
86
86
|
easing: react_native_1.Easing.inOut(react_native_1.Easing.quad),
|
|
87
87
|
// Using native driver in the modal makes the content flash
|
|
88
|
-
useNativeDriver:
|
|
88
|
+
useNativeDriver: true,
|
|
89
89
|
duration: animationDuration,
|
|
90
90
|
toValue: 0,
|
|
91
91
|
}).start(function () {
|
|
@@ -118,4 +118,4 @@ var Modal = function (_a) {
|
|
|
118
118
|
</react_native_1.Modal>);
|
|
119
119
|
};
|
|
120
120
|
exports.Modal = Modal;
|
|
121
|
-
exports.default = exports.Modal;
|
|
121
|
+
exports.default = react_1.default.memo(exports.Modal);
|
|
@@ -11,18 +11,23 @@ export type LinearGradientProps = React.ComponentProps<typeof View> & {
|
|
|
11
11
|
start?: LinearGradientPoint | null;
|
|
12
12
|
end?: LinearGradientPoint | null;
|
|
13
13
|
};
|
|
14
|
+
export type LimitType = {
|
|
15
|
+
max?: number;
|
|
16
|
+
min?: number;
|
|
17
|
+
};
|
|
14
18
|
interface DurationScrollProps {
|
|
15
19
|
numberOfItems: number;
|
|
16
|
-
label?: string;
|
|
20
|
+
label?: string | React.ReactElement;
|
|
17
21
|
initialIndex?: number;
|
|
18
22
|
onDurationChange: (duration: number) => void;
|
|
19
23
|
padNumbersWithZero?: boolean;
|
|
20
24
|
disableInfiniteScroll?: boolean;
|
|
25
|
+
limit?: LimitType;
|
|
21
26
|
padWithNItems: number;
|
|
22
27
|
pickerGradientOverlayProps?: LinearGradientProps;
|
|
23
28
|
LinearGradient?: any;
|
|
24
29
|
testID?: string;
|
|
25
30
|
styles: ReturnType<typeof generateStyles>;
|
|
26
31
|
}
|
|
27
|
-
declare const
|
|
28
|
-
export default
|
|
32
|
+
declare const _default: React.MemoExoticComponent<({ numberOfItems, label, initialIndex, onDurationChange, padNumbersWithZero, disableInfiniteScroll, limit, padWithNItems, pickerGradientOverlayProps, LinearGradient, testID, styles, }: DurationScrollProps) => React.ReactElement<any, string | React.JSXElementConstructor<any>>>;
|
|
33
|
+
export default _default;
|
|
@@ -37,9 +37,12 @@ var react_1 = __importStar(require("react"));
|
|
|
37
37
|
var react_native_1 = require("react-native");
|
|
38
38
|
var generateNumbers_1 = require("../../utils/generateNumbers");
|
|
39
39
|
var colorToRgba_1 = require("../../utils/colorToRgba");
|
|
40
|
+
var getAdjustedLimit_1 = require("../../utils/getAdjustedLimit");
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
var KEY_EXTRACTOR = function (_, index) { return index.toString(); };
|
|
40
43
|
var DurationScroll = function (_a) {
|
|
41
44
|
var _b, _c, _d, _e;
|
|
42
|
-
var numberOfItems = _a.numberOfItems, label = _a.label, _f = _a.initialIndex, initialIndex = _f === void 0 ? 0 : _f, onDurationChange = _a.onDurationChange, _g = _a.padNumbersWithZero, padNumbersWithZero = _g === void 0 ? false : _g, _h = _a.disableInfiniteScroll, disableInfiniteScroll = _h === void 0 ? false : _h, padWithNItems = _a.padWithNItems, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, LinearGradient = _a.LinearGradient, testID = _a.testID, styles = _a.styles;
|
|
45
|
+
var numberOfItems = _a.numberOfItems, label = _a.label, _f = _a.initialIndex, initialIndex = _f === void 0 ? 0 : _f, onDurationChange = _a.onDurationChange, _g = _a.padNumbersWithZero, padNumbersWithZero = _g === void 0 ? false : _g, _h = _a.disableInfiniteScroll, disableInfiniteScroll = _h === void 0 ? false : _h, limit = _a.limit, padWithNItems = _a.padWithNItems, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, LinearGradient = _a.LinearGradient, testID = _a.testID, styles = _a.styles;
|
|
43
46
|
var flatListRef = (0, react_1.useRef)(null);
|
|
44
47
|
var data = (0, generateNumbers_1.generateNumbers)(numberOfItems, {
|
|
45
48
|
padWithZero: padNumbersWithZero,
|
|
@@ -48,12 +51,70 @@ var DurationScroll = function (_a) {
|
|
|
48
51
|
padWithNItems: padWithNItems,
|
|
49
52
|
});
|
|
50
53
|
var numberOfItemsToShow = 1 + padWithNItems * 2;
|
|
51
|
-
var
|
|
54
|
+
var adjustedLimited = (0, getAdjustedLimit_1.getAdjustedLimit)(limit, numberOfItems);
|
|
55
|
+
var renderItem = (0, react_1.useCallback)(function (_a) {
|
|
52
56
|
var item = _a.item;
|
|
57
|
+
var intItem = parseInt(item);
|
|
53
58
|
return (<react_native_1.View key={item} style={styles.pickerItemContainer} testID="picker-item">
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
<react_native_1.Text style={[
|
|
60
|
+
styles.pickerItem,
|
|
61
|
+
intItem > adjustedLimited.max ||
|
|
62
|
+
intItem < adjustedLimited.min
|
|
63
|
+
? styles.disabledPickerItem
|
|
64
|
+
: {},
|
|
65
|
+
]}>
|
|
66
|
+
{item}
|
|
67
|
+
</react_native_1.Text>
|
|
68
|
+
</react_native_1.View>);
|
|
69
|
+
}, [
|
|
70
|
+
adjustedLimited.max,
|
|
71
|
+
adjustedLimited.min,
|
|
72
|
+
styles.disabledPickerItem,
|
|
73
|
+
styles.pickerItem,
|
|
74
|
+
styles.pickerItemContainer,
|
|
75
|
+
]);
|
|
76
|
+
var onMomentumScrollEnd = (0, react_1.useCallback)(function (e) {
|
|
77
|
+
var _a, _b;
|
|
78
|
+
var newIndex = Math.round(e.nativeEvent.contentOffset.y /
|
|
79
|
+
styles.pickerItemContainer.height);
|
|
80
|
+
var newDuration = (disableInfiniteScroll ? newIndex : newIndex + padWithNItems) %
|
|
81
|
+
(numberOfItems + 1);
|
|
82
|
+
// check limits
|
|
83
|
+
if (newDuration > adjustedLimited.max) {
|
|
84
|
+
var targetScrollIndex = newIndex - (newDuration - adjustedLimited.max);
|
|
85
|
+
(_a = flatListRef.current) === null || _a === void 0 ? void 0 : _a.scrollToIndex({
|
|
86
|
+
animated: true,
|
|
87
|
+
index:
|
|
88
|
+
// guard against scrolling beyond end of list
|
|
89
|
+
targetScrollIndex >= 0
|
|
90
|
+
? targetScrollIndex
|
|
91
|
+
: adjustedLimited.max - 1,
|
|
92
|
+
}); // scroll down to max
|
|
93
|
+
newDuration = adjustedLimited.max;
|
|
94
|
+
}
|
|
95
|
+
else if (newDuration < adjustedLimited.min) {
|
|
96
|
+
var targetScrollIndex = newIndex + (adjustedLimited.min - newDuration);
|
|
97
|
+
(_b = flatListRef.current) === null || _b === void 0 ? void 0 : _b.scrollToIndex({
|
|
98
|
+
animated: true,
|
|
99
|
+
index:
|
|
100
|
+
// guard against scrolling beyond end of list
|
|
101
|
+
targetScrollIndex <= data.length - 1
|
|
102
|
+
? targetScrollIndex
|
|
103
|
+
: adjustedLimited.min,
|
|
104
|
+
}); // scroll up to min
|
|
105
|
+
newDuration = adjustedLimited.min;
|
|
106
|
+
}
|
|
107
|
+
onDurationChange(newDuration);
|
|
108
|
+
}, [
|
|
109
|
+
adjustedLimited.max,
|
|
110
|
+
adjustedLimited.min,
|
|
111
|
+
data.length,
|
|
112
|
+
disableInfiniteScroll,
|
|
113
|
+
numberOfItems,
|
|
114
|
+
onDurationChange,
|
|
115
|
+
padWithNItems,
|
|
116
|
+
styles.pickerItemContainer.height,
|
|
117
|
+
]);
|
|
57
118
|
var onViewableItemsChanged = (0, react_1.useCallback)(function (_a) {
|
|
58
119
|
var _b, _c, _d, _e;
|
|
59
120
|
var viewableItems = _a.viewableItems;
|
|
@@ -72,6 +133,11 @@ var DurationScroll = function (_a) {
|
|
|
72
133
|
});
|
|
73
134
|
}
|
|
74
135
|
}, [numberOfItems]);
|
|
136
|
+
var getItemLayout = (0, react_1.useCallback)(function (_, index) { return ({
|
|
137
|
+
length: styles.pickerItemContainer.height,
|
|
138
|
+
offset: styles.pickerItemContainer.height * index,
|
|
139
|
+
index: index,
|
|
140
|
+
}); }, [styles.pickerItemContainer.height]);
|
|
75
141
|
var viewabilityConfigCallbackPairs = (0, react_1.useRef)([
|
|
76
142
|
{
|
|
77
143
|
viewabilityConfig: { viewAreaCoveragePercentThreshold: 25 },
|
|
@@ -82,25 +148,16 @@ var DurationScroll = function (_a) {
|
|
|
82
148
|
height: styles.pickerItemContainer.height * numberOfItemsToShow,
|
|
83
149
|
overflow: "hidden",
|
|
84
150
|
}}>
|
|
85
|
-
<react_native_1.FlatList ref={flatListRef} data={data} getItemLayout={
|
|
86
|
-
length: styles.pickerItemContainer.height,
|
|
87
|
-
offset: styles.pickerItemContainer.height * index,
|
|
88
|
-
index: index,
|
|
89
|
-
}); }} initialScrollIndex={(initialIndex % numberOfItems) +
|
|
151
|
+
<react_native_1.FlatList ref={flatListRef} data={data} getItemLayout={getItemLayout} initialScrollIndex={(initialIndex % numberOfItems) +
|
|
90
152
|
numberOfItems +
|
|
91
153
|
(disableInfiniteScroll ? padWithNItems : 0) -
|
|
92
|
-
(padWithNItems - 1)} windowSize={numberOfItemsToShow} renderItem={renderItem} keyExtractor={
|
|
154
|
+
(padWithNItems - 1)} windowSize={numberOfItemsToShow} renderItem={renderItem} keyExtractor={KEY_EXTRACTOR} showsVerticalScrollIndicator={false} decelerationRate="fast" scrollEventThrottle={16} snapToAlignment="start"
|
|
93
155
|
// used in place of snapToOffset due to bug on Android
|
|
94
156
|
snapToOffsets={__spreadArray([], Array(data.length), true).map(function (_, i) { return i * styles.pickerItemContainer.height; })} viewabilityConfigCallbackPairs={!disableInfiniteScroll
|
|
95
157
|
? viewabilityConfigCallbackPairs === null || viewabilityConfigCallbackPairs === void 0 ? void 0 : viewabilityConfigCallbackPairs.current
|
|
96
|
-
: undefined} onMomentumScrollEnd={
|
|
97
|
-
var newIndex = Math.round(e.nativeEvent.contentOffset.y /
|
|
98
|
-
styles.pickerItemContainer.height);
|
|
99
|
-
onDurationChange((disableInfiniteScroll ? newIndex : newIndex + padWithNItems) %
|
|
100
|
-
(numberOfItems + 1));
|
|
101
|
-
}} testID="duration-scroll-flatlist"/>
|
|
158
|
+
: undefined} onMomentumScrollEnd={onMomentumScrollEnd} testID="duration-scroll-flatlist"/>
|
|
102
159
|
<react_native_1.View style={styles.pickerLabelContainer}>
|
|
103
|
-
<react_native_1.Text style={styles.pickerLabel}>{label}</react_native_1.Text>
|
|
160
|
+
{typeof label === "string" ? (<react_native_1.Text style={styles.pickerLabel}>{label}</react_native_1.Text>) : (label !== null && label !== void 0 ? label : null)}
|
|
104
161
|
</react_native_1.View>
|
|
105
162
|
{LinearGradient ? (<>
|
|
106
163
|
<LinearGradient colors={[
|
|
@@ -120,4 +177,4 @@ var DurationScroll = function (_a) {
|
|
|
120
177
|
</>) : null}
|
|
121
178
|
</react_native_1.View>);
|
|
122
179
|
};
|
|
123
|
-
exports.default = DurationScroll;
|
|
180
|
+
exports.default = react_1.default.memo(DurationScroll);
|
|
@@ -7,6 +7,7 @@ export interface CustomTimerPickerStyles {
|
|
|
7
7
|
pickerLabel?: any;
|
|
8
8
|
pickerItemContainer?: any;
|
|
9
9
|
pickerItem?: any;
|
|
10
|
+
disabledPickerItem?: any;
|
|
10
11
|
pickerGradientOverlay?: any;
|
|
11
12
|
}
|
|
12
13
|
export declare const generateStyles: (customStyles: CustomTimerPickerStyles | undefined, options: {
|
|
@@ -17,5 +18,6 @@ export declare const generateStyles: (customStyles: CustomTimerPickerStyles | un
|
|
|
17
18
|
pickerLabel: any;
|
|
18
19
|
pickerItemContainer: any;
|
|
19
20
|
pickerItem: any;
|
|
21
|
+
disabledPickerItem: any;
|
|
20
22
|
pickerGradientOverlay: any;
|
|
21
23
|
};
|
|
@@ -32,6 +32,7 @@ var generateStyles = function (customStyles, options) {
|
|
|
32
32
|
pickerItem: __assign(__assign({ textAlignVertical: "center", fontSize: 25, color: (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark"
|
|
33
33
|
? DARK_MODE_TEXT_COLOR
|
|
34
34
|
: LIGHT_MODE_TEXT_COLOR }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.text), customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItem),
|
|
35
|
+
disabledPickerItem: __assign({ opacity: 0.2 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.disabledPickerItem),
|
|
35
36
|
pickerGradientOverlay: __assign({ position: "absolute", left: 0, right: 0, height: options.padWithNItems === 0
|
|
36
37
|
? "30%"
|
|
37
38
|
: ((_g = (_f = customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItemContainer) === null || _f === void 0 ? void 0 : _f.height) !== null && _g !== void 0 ? _g : 50) * 0.8 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerGradientOverlay),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
+
import { LimitType } from "./DurationScroll";
|
|
3
4
|
import { CustomTimerPickerStyles } from "./TimerPicker.styles";
|
|
4
5
|
import { LinearGradientProps } from "./DurationScroll";
|
|
5
6
|
export interface TimerPickerProps {
|
|
@@ -14,9 +15,12 @@ export interface TimerPickerProps {
|
|
|
14
15
|
hideHours?: boolean;
|
|
15
16
|
hideMinutes?: boolean;
|
|
16
17
|
hideSeconds?: boolean;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
hourLimit?: LimitType;
|
|
19
|
+
minuteLimit?: LimitType;
|
|
20
|
+
secondLimit?: LimitType;
|
|
21
|
+
hourLabel?: string | React.ReactElement;
|
|
22
|
+
minuteLabel?: string | React.ReactElement;
|
|
23
|
+
secondLabel?: string | React.ReactElement;
|
|
20
24
|
padWithNItems?: number;
|
|
21
25
|
disableInfiniteScroll?: boolean;
|
|
22
26
|
LinearGradient?: any;
|
|
@@ -24,5 +28,5 @@ export interface TimerPickerProps {
|
|
|
24
28
|
pickerGradientOverlayProps?: LinearGradientProps;
|
|
25
29
|
styles?: CustomTimerPickerStyles;
|
|
26
30
|
}
|
|
27
|
-
declare const
|
|
28
|
-
export default
|
|
31
|
+
declare const _default: React.MemoExoticComponent<({ onDurationChange, initialHours, initialMinutes, initialSeconds, hideHours, hideMinutes, hideSeconds, hourLimit, minuteLimit, secondLimit, hourLabel, minuteLabel, secondLabel, padWithNItems, disableInfiniteScroll, LinearGradient, pickerContainerProps, pickerGradientOverlayProps, styles: customStyles, }: TimerPickerProps) => React.ReactElement<any, string | React.JSXElementConstructor<any>>>;
|
|
32
|
+
export default _default;
|
|
@@ -31,11 +31,13 @@ var react_native_1 = require("react-native");
|
|
|
31
31
|
var DurationScroll_1 = __importDefault(require("./DurationScroll"));
|
|
32
32
|
var TimerPicker_styles_1 = require("./TimerPicker.styles");
|
|
33
33
|
var TimerPicker = function (_a) {
|
|
34
|
-
var onDurationChange = _a.onDurationChange, _b = _a.initialHours, initialHours = _b === void 0 ? 0 : _b, _c = _a.initialMinutes, initialMinutes = _c === void 0 ? 0 : _c, _d = _a.initialSeconds, initialSeconds = _d === void 0 ? 0 : _d, _e = _a.hideHours, hideHours = _e === void 0 ? false : _e, _f = _a.hideMinutes, hideMinutes = _f === void 0 ? false : _f, _g = _a.hideSeconds, hideSeconds = _g === void 0 ? false : _g, _h = _a.hourLabel, hourLabel = _h === void 0 ? "h" : _h, _j = _a.minuteLabel, minuteLabel = _j === void 0 ? "m" : _j, _k = _a.secondLabel, secondLabel = _k === void 0 ? "s" : _k, _l = _a.padWithNItems, padWithNItems = _l === void 0 ? 1 : _l, _m = _a.disableInfiniteScroll, disableInfiniteScroll = _m === void 0 ? false : _m, LinearGradient = _a.LinearGradient, pickerContainerProps = _a.pickerContainerProps, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, customStyles = _a.styles;
|
|
34
|
+
var onDurationChange = _a.onDurationChange, _b = _a.initialHours, initialHours = _b === void 0 ? 0 : _b, _c = _a.initialMinutes, initialMinutes = _c === void 0 ? 0 : _c, _d = _a.initialSeconds, initialSeconds = _d === void 0 ? 0 : _d, _e = _a.hideHours, hideHours = _e === void 0 ? false : _e, _f = _a.hideMinutes, hideMinutes = _f === void 0 ? false : _f, _g = _a.hideSeconds, hideSeconds = _g === void 0 ? false : _g, hourLimit = _a.hourLimit, minuteLimit = _a.minuteLimit, secondLimit = _a.secondLimit, _h = _a.hourLabel, hourLabel = _h === void 0 ? "h" : _h, _j = _a.minuteLabel, minuteLabel = _j === void 0 ? "m" : _j, _k = _a.secondLabel, secondLabel = _k === void 0 ? "s" : _k, _l = _a.padWithNItems, padWithNItems = _l === void 0 ? 1 : _l, _m = _a.disableInfiniteScroll, disableInfiniteScroll = _m === void 0 ? false : _m, LinearGradient = _a.LinearGradient, pickerContainerProps = _a.pickerContainerProps, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, customStyles = _a.styles;
|
|
35
35
|
var checkedPadWithNItems = padWithNItems >= 0 ? Math.round(padWithNItems) : 0;
|
|
36
|
-
var styles = (0,
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
var styles = (0, react_1.useMemo)(function () {
|
|
37
|
+
return (0, TimerPicker_styles_1.generateStyles)(customStyles, {
|
|
38
|
+
padWithNItems: checkedPadWithNItems,
|
|
39
|
+
});
|
|
40
|
+
}, [checkedPadWithNItems, customStyles]);
|
|
39
41
|
var _o = (0, react_1.useState)(initialHours), selectedHours = _o[0], setSelectedHours = _o[1];
|
|
40
42
|
var _p = (0, react_1.useState)(initialMinutes), selectedMinutes = _p[0], setSelectedMinutes = _p[1];
|
|
41
43
|
var _q = (0, react_1.useState)(initialSeconds), selectedSeconds = _q[0], setSelectedSeconds = _q[1];
|
|
@@ -48,9 +50,9 @@ var TimerPicker = function (_a) {
|
|
|
48
50
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
51
|
}, [selectedHours, selectedMinutes, selectedSeconds]);
|
|
50
52
|
return (<react_native_1.View {...pickerContainerProps} style={styles.pickerContainer} testID="timer-picker">
|
|
51
|
-
{!hideHours ? (<DurationScroll_1.default numberOfItems={23} label={hourLabel} initialIndex={initialHours} onDurationChange={setSelectedHours} pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-hour"/>) : null}
|
|
52
|
-
{!hideMinutes ? (<DurationScroll_1.default numberOfItems={59} label={minuteLabel} initialIndex={initialMinutes} onDurationChange={setSelectedMinutes} padNumbersWithZero pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-minute"/>) : null}
|
|
53
|
-
{!hideSeconds ? (<DurationScroll_1.default numberOfItems={59} label={secondLabel} initialIndex={initialSeconds} onDurationChange={setSelectedSeconds} padNumbersWithZero pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-second"/>) : null}
|
|
53
|
+
{!hideHours ? (<DurationScroll_1.default numberOfItems={23} label={hourLabel} initialIndex={initialHours} onDurationChange={setSelectedHours} pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} limit={hourLimit} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-hour"/>) : null}
|
|
54
|
+
{!hideMinutes ? (<DurationScroll_1.default numberOfItems={59} label={minuteLabel} initialIndex={initialMinutes} onDurationChange={setSelectedMinutes} padNumbersWithZero pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} limit={minuteLimit} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-minute"/>) : null}
|
|
55
|
+
{!hideSeconds ? (<DurationScroll_1.default numberOfItems={59} label={secondLabel} initialIndex={initialSeconds} onDurationChange={setSelectedSeconds} padNumbersWithZero pickerGradientOverlayProps={pickerGradientOverlayProps} disableInfiniteScroll={disableInfiniteScroll} padWithNItems={checkedPadWithNItems} limit={secondLimit} LinearGradient={LinearGradient} styles={styles} testID="duration-scroll-second"/>) : null}
|
|
54
56
|
</react_native_1.View>);
|
|
55
57
|
};
|
|
56
|
-
exports.default = TimerPicker;
|
|
58
|
+
exports.default = react_1.default.memo(TimerPicker);
|
|
@@ -3,8 +3,13 @@ import { View, Text } from "react-native";
|
|
|
3
3
|
import { TimerPickerProps } from "./TimerPicker";
|
|
4
4
|
import Modal from "./Modal";
|
|
5
5
|
import { CustomTimerPickerModalStyles } from "./TimerPickerModal.styles";
|
|
6
|
-
interface
|
|
6
|
+
export interface TimerPickerModalRef {
|
|
7
7
|
reset: () => void;
|
|
8
|
+
setValue: (value: {
|
|
9
|
+
hours: number;
|
|
10
|
+
minutes: number;
|
|
11
|
+
seconds: number;
|
|
12
|
+
}) => void;
|
|
8
13
|
}
|
|
9
14
|
export interface TimerPickerModalProps extends TimerPickerProps {
|
|
10
15
|
visible: boolean;
|
|
@@ -27,5 +32,5 @@ export interface TimerPickerModalProps extends TimerPickerProps {
|
|
|
27
32
|
modalTitleProps?: React.ComponentProps<typeof Text>;
|
|
28
33
|
styles?: CustomTimerPickerModalStyles;
|
|
29
34
|
}
|
|
30
|
-
declare const
|
|
31
|
-
export default
|
|
35
|
+
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<TimerPickerModalProps & React.RefAttributes<TimerPickerModalRef>>>;
|
|
36
|
+
export default _default;
|
package/dist/components/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var TimerPicker_1 = __importDefault(require("./TimerPicker"));
|
|
|
32
32
|
var Modal_1 = __importDefault(require("./Modal"));
|
|
33
33
|
var TimerPickerModal_styles_1 = require("./TimerPickerModal.styles");
|
|
34
34
|
var TimerPickerModal = (0, react_1.forwardRef)(function (_a, ref) {
|
|
35
|
-
var visible = _a.visible, setIsVisible = _a.setIsVisible, onConfirm = _a.onConfirm, onCancel = _a.onCancel, onDurationChange = _a.onDurationChange, closeOnOverlayPress = _a.closeOnOverlayPress, _b = _a.initialHours, initialHours = _b === void 0 ? 0 : _b, _c = _a.initialMinutes, initialMinutes = _c === void 0 ? 0 : _c, _d = _a.initialSeconds, initialSeconds = _d === void 0 ? 0 : _d, _e = _a.hideHours, hideHours = _e === void 0 ? false : _e, _f = _a.hideMinutes, hideMinutes = _f === void 0 ? false : _f, _g = _a.hideSeconds, hideSeconds = _g === void 0 ? false : _g, _h = _a.hourLabel, hourLabel = _h === void 0 ? "h" : _h, _j = _a.minuteLabel, minuteLabel = _j === void 0 ? "m" : _j, _k = _a.secondLabel, secondLabel = _k === void 0 ? "s" : _k, _l = _a.padWithNItems, padWithNItems = _l === void 0 ? 1 : _l, _m = _a.disableInfiniteScroll, disableInfiniteScroll = _m === void 0 ? false : _m, _o = _a.hideCancelButton, hideCancelButton = _o === void 0 ? false : _o, _p = _a.confirmButtonText, confirmButtonText = _p === void 0 ? "Confirm" : _p, _q = _a.cancelButtonText, cancelButtonText = _q === void 0 ? "Cancel" : _q, modalTitle = _a.modalTitle, LinearGradient = _a.LinearGradient, modalProps = _a.modalProps, containerProps = _a.containerProps, contentContainerProps = _a.contentContainerProps, pickerContainerProps = _a.pickerContainerProps, buttonContainerProps = _a.buttonContainerProps, modalTitleProps = _a.modalTitleProps, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, customStyles = _a.styles;
|
|
35
|
+
var visible = _a.visible, setIsVisible = _a.setIsVisible, onConfirm = _a.onConfirm, onCancel = _a.onCancel, onDurationChange = _a.onDurationChange, closeOnOverlayPress = _a.closeOnOverlayPress, _b = _a.initialHours, initialHours = _b === void 0 ? 0 : _b, _c = _a.initialMinutes, initialMinutes = _c === void 0 ? 0 : _c, _d = _a.initialSeconds, initialSeconds = _d === void 0 ? 0 : _d, _e = _a.hideHours, hideHours = _e === void 0 ? false : _e, _f = _a.hideMinutes, hideMinutes = _f === void 0 ? false : _f, _g = _a.hideSeconds, hideSeconds = _g === void 0 ? false : _g, hourLimit = _a.hourLimit, minuteLimit = _a.minuteLimit, secondLimit = _a.secondLimit, _h = _a.hourLabel, hourLabel = _h === void 0 ? "h" : _h, _j = _a.minuteLabel, minuteLabel = _j === void 0 ? "m" : _j, _k = _a.secondLabel, secondLabel = _k === void 0 ? "s" : _k, _l = _a.padWithNItems, padWithNItems = _l === void 0 ? 1 : _l, _m = _a.disableInfiniteScroll, disableInfiniteScroll = _m === void 0 ? false : _m, _o = _a.hideCancelButton, hideCancelButton = _o === void 0 ? false : _o, _p = _a.confirmButtonText, confirmButtonText = _p === void 0 ? "Confirm" : _p, _q = _a.cancelButtonText, cancelButtonText = _q === void 0 ? "Cancel" : _q, modalTitle = _a.modalTitle, LinearGradient = _a.LinearGradient, modalProps = _a.modalProps, containerProps = _a.containerProps, contentContainerProps = _a.contentContainerProps, pickerContainerProps = _a.pickerContainerProps, buttonContainerProps = _a.buttonContainerProps, modalTitleProps = _a.modalTitleProps, pickerGradientOverlayProps = _a.pickerGradientOverlayProps, customStyles = _a.styles;
|
|
36
36
|
var styles = (0, TimerPickerModal_styles_1.generateStyles)(customStyles);
|
|
37
37
|
var _r = (0, react_1.useState)({
|
|
38
38
|
hours: initialHours,
|
|
@@ -61,6 +61,11 @@ var TimerPickerModal = (0, react_1.forwardRef)(function (_a, ref) {
|
|
|
61
61
|
setSelectedDuration(confirmedDuration);
|
|
62
62
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
63
63
|
};
|
|
64
|
+
// wrapped in useCallback to avoid unnecessary re-renders of TimerPicker
|
|
65
|
+
var durationChange = (0, react_1.useCallback)(function (duration) {
|
|
66
|
+
setSelectedDuration(duration);
|
|
67
|
+
onDurationChange === null || onDurationChange === void 0 ? void 0 : onDurationChange(duration);
|
|
68
|
+
}, [onDurationChange]);
|
|
64
69
|
(0, react_1.useImperativeHandle)(ref, function () { return ({
|
|
65
70
|
reset: function () {
|
|
66
71
|
var initialDuration = {
|
|
@@ -72,6 +77,10 @@ var TimerPickerModal = (0, react_1.forwardRef)(function (_a, ref) {
|
|
|
72
77
|
setConfirmedDuration(initialDuration);
|
|
73
78
|
setIsVisible(false);
|
|
74
79
|
},
|
|
80
|
+
setValue: function (value) {
|
|
81
|
+
setSelectedDuration(value);
|
|
82
|
+
setConfirmedDuration(value);
|
|
83
|
+
},
|
|
75
84
|
}); });
|
|
76
85
|
return (<Modal_1.default isVisible={visible} onOverlayPress={closeOnOverlayPress ? hideModal : undefined} {...modalProps} testID="timer-picker-modal">
|
|
77
86
|
<react_native_1.View {...containerProps} style={styles.container}>
|
|
@@ -79,10 +88,7 @@ var TimerPickerModal = (0, react_1.forwardRef)(function (_a, ref) {
|
|
|
79
88
|
{modalTitle ? (<react_native_1.Text {...modalTitleProps} style={styles.modalTitle}>
|
|
80
89
|
{modalTitle}
|
|
81
90
|
</react_native_1.Text>) : null}
|
|
82
|
-
<TimerPicker_1.default onDurationChange={
|
|
83
|
-
setSelectedDuration(duration);
|
|
84
|
-
onDurationChange === null || onDurationChange === void 0 ? void 0 : onDurationChange(duration);
|
|
85
|
-
}} initialHours={confirmedDuration.hours} initialMinutes={confirmedDuration.minutes} initialSeconds={confirmedDuration.seconds} hideHours={hideHours} hideMinutes={hideMinutes} hideSeconds={hideSeconds} hourLabel={hourLabel} minuteLabel={minuteLabel} secondLabel={secondLabel} padWithNItems={padWithNItems} disableInfiniteScroll={disableInfiniteScroll} LinearGradient={LinearGradient} pickerContainerProps={pickerContainerProps} pickerGradientOverlayProps={pickerGradientOverlayProps} styles={customStyles}/>
|
|
91
|
+
<TimerPicker_1.default onDurationChange={durationChange} initialHours={confirmedDuration.hours} initialMinutes={confirmedDuration.minutes} initialSeconds={confirmedDuration.seconds} hideHours={hideHours} hideMinutes={hideMinutes} hideSeconds={hideSeconds} hourLimit={hourLimit} minuteLimit={minuteLimit} secondLimit={secondLimit} hourLabel={hourLabel} minuteLabel={minuteLabel} secondLabel={secondLabel} padWithNItems={padWithNItems} disableInfiniteScroll={disableInfiniteScroll} LinearGradient={LinearGradient} pickerContainerProps={pickerContainerProps} pickerGradientOverlayProps={pickerGradientOverlayProps} styles={customStyles}/>
|
|
86
92
|
<react_native_1.View {...buttonContainerProps} style={styles.buttonContainer}>
|
|
87
93
|
{!hideCancelButton ? (<react_native_1.TouchableOpacity onPress={cancel}>
|
|
88
94
|
<react_native_1.Text style={[
|
|
@@ -105,4 +111,4 @@ var TimerPickerModal = (0, react_1.forwardRef)(function (_a, ref) {
|
|
|
105
111
|
</react_native_1.View>
|
|
106
112
|
</Modal_1.default>);
|
|
107
113
|
});
|
|
108
|
-
exports.default = TimerPickerModal;
|
|
114
|
+
exports.default = react_1.default.memo(TimerPickerModal);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as TimerPickerModal, TimerPickerModalProps, } from "./components";
|
|
1
|
+
export { default as TimerPickerModal, TimerPickerModalProps, TimerPickerModalRef, } from "./components";
|
|
2
2
|
export { default as TimerPicker, TimerPickerProps, } from "./components/TimerPicker";
|
|
3
3
|
export { CustomTimerPickerModalStyles } from "./components/TimerPickerModal.styles";
|
|
4
4
|
export { CustomTimerPickerStyles } from "./components/TimerPicker/TimerPicker.styles";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAdjustedLimit = void 0;
|
|
4
|
+
var getAdjustedLimit = function (limit, numberOfItems) {
|
|
5
|
+
if (!limit || (!limit.max && !limit.min)) {
|
|
6
|
+
return {
|
|
7
|
+
max: numberOfItems,
|
|
8
|
+
min: 0,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
// guard against limits that are out of bounds
|
|
12
|
+
var adjustedMaxLimit = limit.max
|
|
13
|
+
? Math.min(limit.max, numberOfItems)
|
|
14
|
+
: numberOfItems;
|
|
15
|
+
var adjustedMinLimit = limit.min ? Math.max(limit.min, 0) : 0;
|
|
16
|
+
// guard against invalid limits
|
|
17
|
+
if (adjustedMaxLimit < adjustedMinLimit) {
|
|
18
|
+
return {
|
|
19
|
+
max: numberOfItems,
|
|
20
|
+
min: 0,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
max: adjustedMaxLimit,
|
|
25
|
+
min: adjustedMinLimit,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
exports.getAdjustedLimit = getAdjustedLimit;
|