react-native-timer-picker 1.1.1 → 1.1.3
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 +15 -15
- package/dist/components/Modal/Modal.styles.d.ts +22 -0
- package/dist/components/Modal/Modal.styles.js +26 -0
- package/dist/components/Modal/index.d.ts +15 -0
- package/dist/components/Modal/index.js +121 -0
- package/dist/components/TimerPicker/DurationScroll.d.ts +28 -0
- package/dist/components/TimerPicker/DurationScroll.js +123 -0
- package/dist/components/TimerPicker/TimerPicker.styles.d.ts +21 -0
- package/dist/components/TimerPicker/TimerPicker.styles.js +40 -0
- package/dist/components/TimerPicker/index.d.ts +28 -0
- package/dist/components/TimerPicker/index.js +56 -0
- package/dist/components/TimerPickerModal.styles.d.ts +19 -0
- package/dist/components/TimerPickerModal.styles.js +41 -0
- package/dist/components/index.d.ts +31 -0
- package/dist/components/index.js +108 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10 -0
- package/dist/utils/colorToRgba.d.ts +4 -0
- package/dist/utils/colorToRgba.js +48 -0
- package/dist/utils/generateNumbers.d.ts +7 -0
- package/dist/utils/generateNumbers.js +30 -0
- package/dist/utils/padWithZero.d.ts +1 -0
- package/dist/utils/padWithZero.js +12 -0
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Great for timers, alarms and duration inputs ⏰🕰️⏳
|
|
|
11
11
|
|
|
12
12
|
Works with Expo and bare React Native apps.
|
|
13
13
|
|
|
14
|
-
- [Demos 📱](#demos
|
|
14
|
+
- [Demos 📱](#demos-📱)
|
|
15
15
|
- [Peer Dependencies 👶](#peer-dependencies-)
|
|
16
16
|
- [Installation 🚀](#installation-)
|
|
17
17
|
- [Examples 😎](#examples-)
|
|
@@ -23,7 +23,7 @@ Works with Expo and bare React Native apps.
|
|
|
23
23
|
- [TimerPicker ⏲️](#timerpicker-️)
|
|
24
24
|
- [Custom Styles 👗](#custom-styles-)
|
|
25
25
|
- [TimerPickerModal ⏰](#timerpickermodal-)
|
|
26
|
-
- [Custom Styles
|
|
26
|
+
- [Custom Styles 👕](#custom-styles--1)
|
|
27
27
|
- [Methods 🔄](#methods-)
|
|
28
28
|
- [TimerPickerModal](#timerpickermodal)
|
|
29
29
|
- [License 📝](#license-)
|
|
@@ -299,7 +299,7 @@ return (
|
|
|
299
299
|
|
|
300
300
|
### TimerPicker ⏲️
|
|
301
301
|
|
|
302
|
-
| Prop | Description | Type | Default
|
|
302
|
+
| Prop | Description | Type | Default | Required |
|
|
303
303
|
| :--------------------------:|:----------------------------------------------------------|:-------------------------------------------------:|:-------------------:|:--------:|
|
|
304
304
|
| onDurationChange | Callback when the duration changes | `(duration: { hours: number, minutes: number, seconds: number }) => void` | - | false |
|
|
305
305
|
| initialHours | Initial value for hours | Number | - | false |
|
|
@@ -313,10 +313,10 @@ return (
|
|
|
313
313
|
| secondLabel | Label for the seconds picker | String | s | false |
|
|
314
314
|
| padWithNItems | Number of items to pad the picker with on either side | Number | 1 | false |
|
|
315
315
|
| disableInfiniteScroll | Disable the infinite scroll feature | Boolean | false | false |
|
|
316
|
-
| LinearGradient | Linear Gradient Component | expo-linear-gradient.LinearGradient or react-native-linear-gradient.default | - | false |
|
|
316
|
+
| 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 |
|
|
317
317
|
| pickerContainerProps | Props for the picker container | `React.ComponentProps<typeof View>` | - | false |
|
|
318
318
|
| pickerGradientOverlayProps | Props for the gradient overlay | LinearGradientProps | - | false |
|
|
319
|
-
| styles | Custom styles for the timer picker | [CustomTimerPickerStyles](#custom-styles) | - | false |
|
|
319
|
+
| styles | Custom styles for the timer picker | [CustomTimerPickerStyles](#custom-styles-) | - | false |
|
|
320
320
|
|
|
321
321
|
#### Custom Styles 👗
|
|
322
322
|
|
|
@@ -336,29 +336,29 @@ The following custom styles can be supplied to re-style the component in any way
|
|
|
336
336
|
|
|
337
337
|
### TimerPickerModal ⏰
|
|
338
338
|
|
|
339
|
-
The TimerPickerModal component accepts all [TimerPicker props](#timerpicker), and the below additional props.
|
|
339
|
+
The TimerPickerModal component accepts all [TimerPicker props](#timerpicker-️), and the below additional props.
|
|
340
340
|
|
|
341
|
-
| Prop | Description | Type | Default
|
|
341
|
+
| Prop | Description | Type | Default | Required |
|
|
342
342
|
| :--------------------:|:----------------------------------------------------------|:---------------------------------------------------------:|:-------------------:|:--------:|
|
|
343
343
|
| visible | Determines if the modal is visible | Boolean | - | true |
|
|
344
344
|
| setIsVisible | Callback to set modal visibility | `(isVisible: boolean) => void` | - | true |
|
|
345
345
|
| onConfirm | Callback when the user confirms the selected time | `({ hours, minutes, seconds }: { hours: number, minutes: number, seconds: number }) => void` | - | true |
|
|
346
346
|
| onCancel | Callback when the user cancels the selection | `() => void` | - | false |
|
|
347
|
-
| closeOnOverlayPress | Determines if the modal should close on overlay press | Boolean |
|
|
348
|
-
| hideCancelButton | Hide the cancel button within the modal | Boolean |
|
|
349
|
-
| confirmButtonText | Text for the confirm button | String |
|
|
350
|
-
| cancelButtonText | Text for the cancel button | String |
|
|
347
|
+
| closeOnOverlayPress | Determines if the modal should close on overlay press | Boolean | false | false |
|
|
348
|
+
| hideCancelButton | Hide the cancel button within the modal | Boolean | false | false |
|
|
349
|
+
| confirmButtonText | Text for the confirm button | String | Confirm | false |
|
|
350
|
+
| cancelButtonText | Text for the cancel button | String | Cancel | false |
|
|
351
351
|
| modalTitle | Title text for the modal | String | - | false |
|
|
352
352
|
| modalProps | Props for the main modal component | `React.ComponentProps<typeof Modal>` | - | false |
|
|
353
353
|
| containerProps | Props for the main container | `React.ComponentProps<typeof View>` | - | false |
|
|
354
354
|
| contentContainerProps | Props for the content container | `React.ComponentProps<typeof View>` | - | false |
|
|
355
355
|
| buttonContainerProps | Props for the button container | `React.ComponentProps<typeof View>` | - | false |
|
|
356
356
|
| modalTitleProps | Props for the modal title text component | `React.ComponentProps<typeof Text>` | - | false |
|
|
357
|
-
| styles | Custom styles for the timer picker modal | [CustomTimerPickerModalStyles](#custom-styles
|
|
357
|
+
| styles | Custom styles for the timer picker modal | [CustomTimerPickerModalStyles](#custom-styles--1) | - | false |
|
|
358
358
|
|
|
359
|
-
#### Custom Styles
|
|
359
|
+
#### Custom Styles 👕
|
|
360
360
|
|
|
361
|
-
The following custom styles can be supplied to re-style the component in any way. You can also supply all of the styles specified in [CustomTimerPickerStyles](#custom-styles). Various styles are applied by default - you can take a look at these [here](src/components/TimerPickerModal.styles.ts).
|
|
361
|
+
The following custom styles can be supplied to re-style the component in any way. You can also supply all of the styles specified in [CustomTimerPickerStyles](#custom-styles-). Various styles are applied by default - you can take a look at these [here](src/components/TimerPickerModal.styles.ts).
|
|
362
362
|
|
|
363
363
|
| Style Prop | Description | Type |
|
|
364
364
|
| :---------------: | :------------------------------------- | :-------: |
|
|
@@ -383,4 +383,4 @@ timerPickerModalRef.current.reset();
|
|
|
383
383
|
|
|
384
384
|
## License 📝
|
|
385
385
|
|
|
386
|
-
This project is licensed under the MIT License.
|
|
386
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const styles: {
|
|
2
|
+
container: {
|
|
3
|
+
position: "absolute";
|
|
4
|
+
top: number;
|
|
5
|
+
left: number;
|
|
6
|
+
right: number;
|
|
7
|
+
bottom: number;
|
|
8
|
+
};
|
|
9
|
+
backdrop: {
|
|
10
|
+
position: "absolute";
|
|
11
|
+
top: number;
|
|
12
|
+
bottom: number;
|
|
13
|
+
left: number;
|
|
14
|
+
right: number;
|
|
15
|
+
backgroundColor: string;
|
|
16
|
+
opacity: number;
|
|
17
|
+
};
|
|
18
|
+
content: {
|
|
19
|
+
flex: number;
|
|
20
|
+
justifyContent: "flex-end";
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.styles = void 0;
|
|
4
|
+
var react_native_1 = require("react-native");
|
|
5
|
+
exports.styles = react_native_1.StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
position: "absolute",
|
|
8
|
+
top: 0,
|
|
9
|
+
left: 0,
|
|
10
|
+
right: 0,
|
|
11
|
+
bottom: 0,
|
|
12
|
+
},
|
|
13
|
+
backdrop: {
|
|
14
|
+
position: "absolute",
|
|
15
|
+
top: 0,
|
|
16
|
+
bottom: 0,
|
|
17
|
+
left: 0,
|
|
18
|
+
right: 0,
|
|
19
|
+
backgroundColor: "black",
|
|
20
|
+
opacity: 0,
|
|
21
|
+
},
|
|
22
|
+
content: {
|
|
23
|
+
flex: 1,
|
|
24
|
+
justifyContent: "flex-end",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface ModalProps {
|
|
3
|
+
children?: React.ReactElement;
|
|
4
|
+
onOverlayPress?: () => void;
|
|
5
|
+
onHide?: () => void;
|
|
6
|
+
isVisible?: boolean;
|
|
7
|
+
animationDuration?: number;
|
|
8
|
+
overlayOpacity?: number;
|
|
9
|
+
modalProps?: any;
|
|
10
|
+
contentStyle?: any;
|
|
11
|
+
overlayStyle?: any;
|
|
12
|
+
testID?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const Modal: ({ children, onOverlayPress, onHide, isVisible, animationDuration, overlayOpacity, modalProps, contentStyle, overlayStyle, testID }: ModalProps) => React.ReactElement;
|
|
15
|
+
export default Modal;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Modal = void 0;
|
|
27
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
28
|
+
var react_1 = __importStar(require("react"));
|
|
29
|
+
var react_native_1 = require("react-native");
|
|
30
|
+
var Modal_styles_1 = require("./Modal.styles");
|
|
31
|
+
var Modal = function (_a) {
|
|
32
|
+
var children = _a.children, onOverlayPress = _a.onOverlayPress, onHide = _a.onHide, _b = _a.isVisible, isVisible = _b === void 0 ? false : _b, _c = _a.animationDuration, animationDuration = _c === void 0 ? 300 : _c, _d = _a.overlayOpacity, overlayOpacity = _d === void 0 ? 0.4 : _d, modalProps = _a.modalProps, contentStyle = _a.contentStyle, overlayStyle = _a.overlayStyle, testID = _a.testID;
|
|
33
|
+
var _e = (0, react_1.useState)(react_native_1.Dimensions.get("window").height), screenHeight = _e[0], setScreenHeight = _e[1];
|
|
34
|
+
var _f = (0, react_1.useState)(react_native_1.Dimensions.get("window").width), screenWidth = _f[0], setScreenWidth = _f[1];
|
|
35
|
+
var isMounted = (0, react_1.useRef)(false);
|
|
36
|
+
var animatedOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0));
|
|
37
|
+
var handleDimensionsUpdate = function (dimensionsUpdate) {
|
|
38
|
+
var updatedScreenWidth = dimensionsUpdate.window.width;
|
|
39
|
+
var updateadScreenHeight = dimensionsUpdate.window.height;
|
|
40
|
+
if (updatedScreenWidth !== screenWidth ||
|
|
41
|
+
updateadScreenHeight !== screenHeight) {
|
|
42
|
+
setScreenHeight(updateadScreenHeight);
|
|
43
|
+
setScreenWidth(updatedScreenWidth);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
(0, react_1.useEffect)(function () {
|
|
47
|
+
isMounted.current = true;
|
|
48
|
+
if (isVisible) {
|
|
49
|
+
show();
|
|
50
|
+
}
|
|
51
|
+
var deviceEventEmitter = react_native_1.DeviceEventEmitter.addListener("didUpdateDimensions", handleDimensionsUpdate);
|
|
52
|
+
return function () {
|
|
53
|
+
deviceEventEmitter.remove();
|
|
54
|
+
isMounted.current = false;
|
|
55
|
+
};
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
}, []);
|
|
58
|
+
var backdropAnimatedStyle = {
|
|
59
|
+
opacity: animatedOpacity.current.interpolate({
|
|
60
|
+
inputRange: [0, 1],
|
|
61
|
+
outputRange: [0, overlayOpacity],
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
var contentAnimatedStyle = {
|
|
65
|
+
transform: [
|
|
66
|
+
{
|
|
67
|
+
translateY: animatedOpacity.current.interpolate({
|
|
68
|
+
inputRange: [0, 1],
|
|
69
|
+
outputRange: [screenHeight, 0],
|
|
70
|
+
extrapolate: "clamp",
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
var show = (0, react_1.useCallback)(function () {
|
|
76
|
+
react_native_1.Animated.timing(animatedOpacity.current, {
|
|
77
|
+
easing: react_native_1.Easing.inOut(react_native_1.Easing.quad),
|
|
78
|
+
// Using native driver in the modal makes the content flash
|
|
79
|
+
useNativeDriver: false,
|
|
80
|
+
duration: animationDuration,
|
|
81
|
+
toValue: 1,
|
|
82
|
+
}).start();
|
|
83
|
+
}, [animationDuration]);
|
|
84
|
+
var hide = (0, react_1.useCallback)(function () {
|
|
85
|
+
react_native_1.Animated.timing(animatedOpacity.current, {
|
|
86
|
+
easing: react_native_1.Easing.inOut(react_native_1.Easing.quad),
|
|
87
|
+
// Using native driver in the modal makes the content flash
|
|
88
|
+
useNativeDriver: false,
|
|
89
|
+
duration: animationDuration,
|
|
90
|
+
toValue: 0,
|
|
91
|
+
}).start(function () {
|
|
92
|
+
if (isMounted.current) {
|
|
93
|
+
onHide === null || onHide === void 0 ? void 0 : onHide();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}, [animationDuration, onHide]);
|
|
97
|
+
(0, react_1.useEffect)(function () {
|
|
98
|
+
if (isVisible) {
|
|
99
|
+
show();
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
hide();
|
|
103
|
+
}
|
|
104
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
105
|
+
}, [isVisible]);
|
|
106
|
+
return (<react_native_1.Modal transparent animationType="fade" visible={isVisible} {...modalProps} testID={testID !== null && testID !== void 0 ? testID : "modal"}>
|
|
107
|
+
<react_native_1.TouchableWithoutFeedback onPress={onOverlayPress} testID="modal-backdrop">
|
|
108
|
+
<react_native_1.Animated.View style={[
|
|
109
|
+
Modal_styles_1.styles.backdrop,
|
|
110
|
+
backdropAnimatedStyle,
|
|
111
|
+
{ width: screenWidth, height: screenHeight },
|
|
112
|
+
overlayStyle,
|
|
113
|
+
]}/>
|
|
114
|
+
</react_native_1.TouchableWithoutFeedback>
|
|
115
|
+
<react_native_1.Animated.View style={[Modal_styles_1.styles.content, contentAnimatedStyle, contentStyle]} pointerEvents="box-none">
|
|
116
|
+
{children}
|
|
117
|
+
</react_native_1.Animated.View>
|
|
118
|
+
</react_native_1.Modal>);
|
|
119
|
+
};
|
|
120
|
+
exports.Modal = Modal;
|
|
121
|
+
exports.default = exports.Modal;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { generateStyles } from "./TimerPicker.styles";
|
|
4
|
+
type LinearGradientPoint = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
};
|
|
8
|
+
export type LinearGradientProps = React.ComponentProps<typeof View> & {
|
|
9
|
+
colors: string[];
|
|
10
|
+
locations?: number[] | null;
|
|
11
|
+
start?: LinearGradientPoint | null;
|
|
12
|
+
end?: LinearGradientPoint | null;
|
|
13
|
+
};
|
|
14
|
+
interface DurationScrollProps {
|
|
15
|
+
numberOfItems: number;
|
|
16
|
+
label?: string;
|
|
17
|
+
initialIndex?: number;
|
|
18
|
+
onDurationChange: (duration: number) => void;
|
|
19
|
+
padNumbersWithZero?: boolean;
|
|
20
|
+
disableInfiniteScroll?: boolean;
|
|
21
|
+
padWithNItems: number;
|
|
22
|
+
pickerGradientOverlayProps?: LinearGradientProps;
|
|
23
|
+
LinearGradient?: any;
|
|
24
|
+
testID?: string;
|
|
25
|
+
styles: ReturnType<typeof generateStyles>;
|
|
26
|
+
}
|
|
27
|
+
declare const DurationScroll: ({ numberOfItems, label, initialIndex, onDurationChange, padNumbersWithZero, disableInfiniteScroll, padWithNItems, pickerGradientOverlayProps, LinearGradient, testID, styles, }: DurationScrollProps) => React.ReactElement;
|
|
28
|
+
export default DurationScroll;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
26
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
27
|
+
if (ar || !(i in from)) {
|
|
28
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
29
|
+
ar[i] = from[i];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
36
|
+
var react_1 = __importStar(require("react"));
|
|
37
|
+
var react_native_1 = require("react-native");
|
|
38
|
+
var generateNumbers_1 = require("../../utils/generateNumbers");
|
|
39
|
+
var colorToRgba_1 = require("../../utils/colorToRgba");
|
|
40
|
+
var DurationScroll = function (_a) {
|
|
41
|
+
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;
|
|
43
|
+
var flatListRef = (0, react_1.useRef)(null);
|
|
44
|
+
var data = (0, generateNumbers_1.generateNumbers)(numberOfItems, {
|
|
45
|
+
padWithZero: padNumbersWithZero,
|
|
46
|
+
repeatNTimes: 3,
|
|
47
|
+
disableInfiniteScroll: disableInfiniteScroll,
|
|
48
|
+
padWithNItems: padWithNItems,
|
|
49
|
+
});
|
|
50
|
+
var numberOfItemsToShow = 1 + padWithNItems * 2;
|
|
51
|
+
var renderItem = function (_a) {
|
|
52
|
+
var item = _a.item;
|
|
53
|
+
return (<react_native_1.View key={item} style={styles.pickerItemContainer} testID="picker-item">
|
|
54
|
+
<react_native_1.Text style={styles.pickerItem}>{item}</react_native_1.Text>
|
|
55
|
+
</react_native_1.View>);
|
|
56
|
+
};
|
|
57
|
+
var onViewableItemsChanged = (0, react_1.useCallback)(function (_a) {
|
|
58
|
+
var _b, _c, _d, _e;
|
|
59
|
+
var viewableItems = _a.viewableItems;
|
|
60
|
+
if (((_b = viewableItems[0]) === null || _b === void 0 ? void 0 : _b.index) &&
|
|
61
|
+
viewableItems[0].index < numberOfItems * 0.5) {
|
|
62
|
+
(_c = flatListRef.current) === null || _c === void 0 ? void 0 : _c.scrollToIndex({
|
|
63
|
+
animated: false,
|
|
64
|
+
index: viewableItems[0].index + numberOfItems,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (((_d = viewableItems[0]) === null || _d === void 0 ? void 0 : _d.index) &&
|
|
68
|
+
viewableItems[0].index >= numberOfItems * 2.5) {
|
|
69
|
+
(_e = flatListRef.current) === null || _e === void 0 ? void 0 : _e.scrollToIndex({
|
|
70
|
+
animated: false,
|
|
71
|
+
index: viewableItems[0].index - numberOfItems,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}, [numberOfItems]);
|
|
75
|
+
var viewabilityConfigCallbackPairs = (0, react_1.useRef)([
|
|
76
|
+
{
|
|
77
|
+
viewabilityConfig: { viewAreaCoveragePercentThreshold: 25 },
|
|
78
|
+
onViewableItemsChanged: onViewableItemsChanged,
|
|
79
|
+
},
|
|
80
|
+
]);
|
|
81
|
+
return (<react_native_1.View testID={testID} style={{
|
|
82
|
+
height: styles.pickerItemContainer.height * numberOfItemsToShow,
|
|
83
|
+
overflow: "hidden",
|
|
84
|
+
}}>
|
|
85
|
+
<react_native_1.FlatList ref={flatListRef} data={data} getItemLayout={function (_, index) { return ({
|
|
86
|
+
length: styles.pickerItemContainer.height,
|
|
87
|
+
offset: styles.pickerItemContainer.height * index,
|
|
88
|
+
index: index,
|
|
89
|
+
}); }} initialScrollIndex={(initialIndex % numberOfItems) +
|
|
90
|
+
numberOfItems +
|
|
91
|
+
(disableInfiniteScroll ? padWithNItems : 0) -
|
|
92
|
+
(padWithNItems - 1)} windowSize={numberOfItemsToShow} renderItem={renderItem} keyExtractor={function (_, index) { return index.toString(); }} showsVerticalScrollIndicator={false} decelerationRate="fast" scrollEventThrottle={16} snapToAlignment="start"
|
|
93
|
+
// used in place of snapToOffset due to bug on Android
|
|
94
|
+
snapToOffsets={__spreadArray([], Array(data.length), true).map(function (_, i) { return i * styles.pickerItemContainer.height; })} viewabilityConfigCallbackPairs={!disableInfiniteScroll
|
|
95
|
+
? viewabilityConfigCallbackPairs === null || viewabilityConfigCallbackPairs === void 0 ? void 0 : viewabilityConfigCallbackPairs.current
|
|
96
|
+
: undefined} onMomentumScrollEnd={function (e) {
|
|
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"/>
|
|
102
|
+
<react_native_1.View style={styles.pickerLabelContainer}>
|
|
103
|
+
<react_native_1.Text style={styles.pickerLabel}>{label}</react_native_1.Text>
|
|
104
|
+
</react_native_1.View>
|
|
105
|
+
{LinearGradient ? (<>
|
|
106
|
+
<LinearGradient colors={[
|
|
107
|
+
(_b = styles.pickerContainer.backgroundColor) !== null && _b !== void 0 ? _b : "white",
|
|
108
|
+
(0, colorToRgba_1.colorToRgba)({
|
|
109
|
+
color: (_c = styles.pickerContainer.backgroundColor) !== null && _c !== void 0 ? _c : "white",
|
|
110
|
+
opacity: 0,
|
|
111
|
+
}),
|
|
112
|
+
]} start={{ x: 1, y: 0.3 }} end={{ x: 1, y: 1 }} {...pickerGradientOverlayProps} style={[styles.pickerGradientOverlay, { top: 0 }]}/>
|
|
113
|
+
<LinearGradient colors={[
|
|
114
|
+
(0, colorToRgba_1.colorToRgba)({
|
|
115
|
+
color: (_d = styles.pickerContainer.backgroundColor) !== null && _d !== void 0 ? _d : "white",
|
|
116
|
+
opacity: 0,
|
|
117
|
+
}),
|
|
118
|
+
(_e = styles.pickerContainer.backgroundColor) !== null && _e !== void 0 ? _e : "white",
|
|
119
|
+
]} start={{ x: 1, y: 0 }} end={{ x: 1, y: 0.7 }} {...pickerGradientOverlayProps} style={[styles.pickerGradientOverlay, { bottom: -1 }]}/>
|
|
120
|
+
</>) : null}
|
|
121
|
+
</react_native_1.View>);
|
|
122
|
+
};
|
|
123
|
+
exports.default = DurationScroll;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface CustomTimerPickerStyles {
|
|
2
|
+
theme?: "light" | "dark";
|
|
3
|
+
backgroundColor?: string;
|
|
4
|
+
textColor?: string;
|
|
5
|
+
pickerContainer?: any;
|
|
6
|
+
pickerLabelContainer?: any;
|
|
7
|
+
pickerLabel?: any;
|
|
8
|
+
pickerItemContainer?: any;
|
|
9
|
+
pickerItem?: any;
|
|
10
|
+
pickerGradientOverlay?: any;
|
|
11
|
+
}
|
|
12
|
+
export declare const generateStyles: (customStyles: CustomTimerPickerStyles | undefined, options: {
|
|
13
|
+
padWithNItems: number;
|
|
14
|
+
}) => {
|
|
15
|
+
pickerContainer: any;
|
|
16
|
+
pickerLabelContainer: any;
|
|
17
|
+
pickerLabel: any;
|
|
18
|
+
pickerItemContainer: any;
|
|
19
|
+
pickerItem: any;
|
|
20
|
+
pickerGradientOverlay: any;
|
|
21
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.generateStyles = void 0;
|
|
15
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
16
|
+
var react_native_1 = require("react-native");
|
|
17
|
+
var DARK_MODE_BACKGROUND_COLOR = "#232323";
|
|
18
|
+
var DARK_MODE_TEXT_COLOR = "#E9E9E9";
|
|
19
|
+
var LIGHT_MODE_BACKGROUND_COLOR = "#F1F1F1";
|
|
20
|
+
var LIGHT_MODE_TEXT_COLOR = "#1B1B1B";
|
|
21
|
+
var generateStyles = function (customStyles, options) {
|
|
22
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
23
|
+
return react_native_1.StyleSheet.create({
|
|
24
|
+
pickerContainer: __assign({ flexDirection: "row", marginRight: "8%", backgroundColor: (_a = customStyles === null || customStyles === void 0 ? void 0 : customStyles.backgroundColor) !== null && _a !== void 0 ? _a : ((customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark"
|
|
25
|
+
? DARK_MODE_BACKGROUND_COLOR
|
|
26
|
+
: LIGHT_MODE_BACKGROUND_COLOR) }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerContainer),
|
|
27
|
+
pickerLabelContainer: __assign({ position: "absolute", right: 4, top: 0, bottom: 0, justifyContent: "center" }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerLabelContainer),
|
|
28
|
+
pickerLabel: __assign({ fontSize: 18, fontWeight: "bold", marginTop: ((_c = (_b = customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItem) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 25) / 6, color: (_d = customStyles === null || customStyles === void 0 ? void 0 : customStyles.textColor) !== null && _d !== void 0 ? _d : ((customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark"
|
|
29
|
+
? DARK_MODE_TEXT_COLOR
|
|
30
|
+
: LIGHT_MODE_TEXT_COLOR) }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerLabel),
|
|
31
|
+
pickerItemContainer: __assign({ height: 50, justifyContent: "center", alignItems: "center", width: ((_f = (_e = customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItem) === null || _e === void 0 ? void 0 : _e.fontSize) !== null && _f !== void 0 ? _f : 25) * 3.6 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItemContainer),
|
|
32
|
+
pickerItem: __assign({ textAlignVertical: "center", fontSize: 25, color: (_g = customStyles === null || customStyles === void 0 ? void 0 : customStyles.textColor) !== null && _g !== void 0 ? _g : ((customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark"
|
|
33
|
+
? DARK_MODE_TEXT_COLOR
|
|
34
|
+
: LIGHT_MODE_TEXT_COLOR) }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItem),
|
|
35
|
+
pickerGradientOverlay: __assign({ position: "absolute", left: 0, right: 0, height: options.padWithNItems === 0
|
|
36
|
+
? "30%"
|
|
37
|
+
: ((_j = (_h = customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerItemContainer) === null || _h === void 0 ? void 0 : _h.height) !== null && _j !== void 0 ? _j : 50) * 0.8 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.pickerGradientOverlay),
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
exports.generateStyles = generateStyles;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { CustomTimerPickerStyles } from "./TimerPicker.styles";
|
|
4
|
+
import { LinearGradientProps } from "./DurationScroll";
|
|
5
|
+
export interface TimerPickerProps {
|
|
6
|
+
onDurationChange?: (duration: {
|
|
7
|
+
hours: number;
|
|
8
|
+
minutes: number;
|
|
9
|
+
seconds: number;
|
|
10
|
+
}) => void;
|
|
11
|
+
initialHours?: number;
|
|
12
|
+
initialMinutes?: number;
|
|
13
|
+
initialSeconds?: number;
|
|
14
|
+
hideHours?: boolean;
|
|
15
|
+
hideMinutes?: boolean;
|
|
16
|
+
hideSeconds?: boolean;
|
|
17
|
+
hourLabel?: string;
|
|
18
|
+
minuteLabel?: string;
|
|
19
|
+
secondLabel?: string;
|
|
20
|
+
padWithNItems?: number;
|
|
21
|
+
disableInfiniteScroll?: boolean;
|
|
22
|
+
LinearGradient?: any;
|
|
23
|
+
pickerContainerProps?: React.ComponentProps<typeof View>;
|
|
24
|
+
pickerGradientOverlayProps?: LinearGradientProps;
|
|
25
|
+
styles?: CustomTimerPickerStyles;
|
|
26
|
+
}
|
|
27
|
+
declare const TimerPicker: ({ onDurationChange, initialHours, initialMinutes, initialSeconds, hideHours, hideMinutes, hideSeconds, hourLabel, minuteLabel, secondLabel, padWithNItems, disableInfiniteScroll, LinearGradient, pickerContainerProps, pickerGradientOverlayProps, styles: customStyles, }: TimerPickerProps) => React.ReactElement;
|
|
28
|
+
export default TimerPicker;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
var react_1 = __importStar(require("react"));
|
|
30
|
+
var react_native_1 = require("react-native");
|
|
31
|
+
var DurationScroll_1 = __importDefault(require("./DurationScroll"));
|
|
32
|
+
var TimerPicker_styles_1 = require("./TimerPicker.styles");
|
|
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;
|
|
35
|
+
var checkedPadWithNItems = padWithNItems >= 0 ? Math.round(padWithNItems) : 0;
|
|
36
|
+
var styles = (0, TimerPicker_styles_1.generateStyles)(customStyles, {
|
|
37
|
+
padWithNItems: checkedPadWithNItems,
|
|
38
|
+
});
|
|
39
|
+
var _o = (0, react_1.useState)(initialHours), selectedHours = _o[0], setSelectedHours = _o[1];
|
|
40
|
+
var _p = (0, react_1.useState)(initialMinutes), selectedMinutes = _p[0], setSelectedMinutes = _p[1];
|
|
41
|
+
var _q = (0, react_1.useState)(initialSeconds), selectedSeconds = _q[0], setSelectedSeconds = _q[1];
|
|
42
|
+
(0, react_1.useEffect)(function () {
|
|
43
|
+
onDurationChange === null || onDurationChange === void 0 ? void 0 : onDurationChange({
|
|
44
|
+
hours: selectedHours,
|
|
45
|
+
minutes: selectedMinutes,
|
|
46
|
+
seconds: selectedSeconds,
|
|
47
|
+
});
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
|
+
}, [selectedHours, selectedMinutes, selectedSeconds]);
|
|
50
|
+
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}
|
|
54
|
+
</react_native_1.View>);
|
|
55
|
+
};
|
|
56
|
+
exports.default = TimerPicker;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CustomTimerPickerStyles } from "./TimerPicker/TimerPicker.styles";
|
|
2
|
+
export interface CustomTimerPickerModalStyles extends CustomTimerPickerStyles {
|
|
3
|
+
container?: any;
|
|
4
|
+
contentContainer?: any;
|
|
5
|
+
buttonContainer?: any;
|
|
6
|
+
button?: any;
|
|
7
|
+
cancelButton?: any;
|
|
8
|
+
confirmButton?: any;
|
|
9
|
+
modalTitle?: any;
|
|
10
|
+
}
|
|
11
|
+
export declare const generateStyles: (customStyles: CustomTimerPickerModalStyles | undefined) => {
|
|
12
|
+
container: any;
|
|
13
|
+
contentContainer: any;
|
|
14
|
+
buttonContainer: any;
|
|
15
|
+
button: any;
|
|
16
|
+
cancelButton: any;
|
|
17
|
+
confirmButton: any;
|
|
18
|
+
modalTitle: any;
|
|
19
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.generateStyles = void 0;
|
|
15
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
16
|
+
var react_native_1 = require("react-native");
|
|
17
|
+
var DARK_MODE_BACKGROUND_COLOR = "#232323";
|
|
18
|
+
var DARK_MODE_TEXT_COLOR = "#E9E9E9";
|
|
19
|
+
var LIGHT_MODE_BACKGROUND_COLOR = "#F1F1F1";
|
|
20
|
+
var LIGHT_MODE_TEXT_COLOR = "#1B1B1B";
|
|
21
|
+
var generateStyles = function (customStyles) {
|
|
22
|
+
var _a, _b, _c, _d;
|
|
23
|
+
return react_native_1.StyleSheet.create({
|
|
24
|
+
container: __assign({ flex: 1, justifyContent: "center", alignItems: "center" }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.container),
|
|
25
|
+
contentContainer: __assign({ backgroundColor: ((_a = customStyles === null || customStyles === void 0 ? void 0 : customStyles.backgroundColor) !== null && _a !== void 0 ? _a : (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark")
|
|
26
|
+
? DARK_MODE_BACKGROUND_COLOR
|
|
27
|
+
: LIGHT_MODE_BACKGROUND_COLOR, justifyContent: "center", alignItems: "center", borderRadius: 20, padding: 20 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.contentContainer),
|
|
28
|
+
buttonContainer: __assign({ flexDirection: "row", marginTop: 25 }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.buttonContainer),
|
|
29
|
+
button: __assign({ marginHorizontal: 12, paddingVertical: 10, paddingHorizontal: 20, borderWidth: 1, borderRadius: 10, fontSize: 16, overflow: "hidden" }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.button),
|
|
30
|
+
cancelButton: __assign({ borderColor: "gray", color: ((_b = customStyles === null || customStyles === void 0 ? void 0 : customStyles.textColor) !== null && _b !== void 0 ? _b : (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark")
|
|
31
|
+
? DARK_MODE_TEXT_COLOR
|
|
32
|
+
: "gray", backgroundColor: (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark" ? "gray" : undefined }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.cancelButton),
|
|
33
|
+
confirmButton: __assign({ borderColor: "green", color: ((_c = customStyles === null || customStyles === void 0 ? void 0 : customStyles.textColor) !== null && _c !== void 0 ? _c : (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark")
|
|
34
|
+
? DARK_MODE_TEXT_COLOR
|
|
35
|
+
: "green", backgroundColor: (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark" ? "green" : undefined }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.confirmButton),
|
|
36
|
+
modalTitle: __assign({ fontSize: 24, fontWeight: "bold", marginBottom: 15, color: ((_d = customStyles === null || customStyles === void 0 ? void 0 : customStyles.textColor) !== null && _d !== void 0 ? _d : (customStyles === null || customStyles === void 0 ? void 0 : customStyles.theme) === "dark")
|
|
37
|
+
? DARK_MODE_TEXT_COLOR
|
|
38
|
+
: LIGHT_MODE_TEXT_COLOR }, customStyles === null || customStyles === void 0 ? void 0 : customStyles.modalTitle),
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
exports.generateStyles = generateStyles;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View, Text } from "react-native";
|
|
3
|
+
import { TimerPickerProps } from "./TimerPicker";
|
|
4
|
+
import Modal from "./Modal";
|
|
5
|
+
import { CustomTimerPickerModalStyles } from "./TimerPickerModal.styles";
|
|
6
|
+
interface TimePickerModalRef {
|
|
7
|
+
reset: () => void;
|
|
8
|
+
}
|
|
9
|
+
export interface TimerPickerModalProps extends TimerPickerProps {
|
|
10
|
+
visible: boolean;
|
|
11
|
+
setIsVisible: (isVisible: boolean) => void;
|
|
12
|
+
onConfirm: ({ hours, minutes, seconds, }: {
|
|
13
|
+
hours: number;
|
|
14
|
+
minutes: number;
|
|
15
|
+
seconds: number;
|
|
16
|
+
}) => void;
|
|
17
|
+
onCancel?: () => void;
|
|
18
|
+
closeOnOverlayPress?: boolean;
|
|
19
|
+
hideCancelButton?: boolean;
|
|
20
|
+
confirmButtonText?: string;
|
|
21
|
+
cancelButtonText?: string;
|
|
22
|
+
modalTitle?: string;
|
|
23
|
+
modalProps?: React.ComponentProps<typeof Modal>;
|
|
24
|
+
containerProps?: React.ComponentProps<typeof View>;
|
|
25
|
+
contentContainerProps?: React.ComponentProps<typeof View>;
|
|
26
|
+
buttonContainerProps?: React.ComponentProps<typeof View>;
|
|
27
|
+
modalTitleProps?: React.ComponentProps<typeof Text>;
|
|
28
|
+
styles?: CustomTimerPickerModalStyles;
|
|
29
|
+
}
|
|
30
|
+
declare const TimerPickerModal: React.ForwardRefExoticComponent<TimerPickerModalProps & React.RefAttributes<TimePickerModalRef>>;
|
|
31
|
+
export default TimerPickerModal;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
var react_1 = __importStar(require("react"));
|
|
30
|
+
var react_native_1 = require("react-native");
|
|
31
|
+
var TimerPicker_1 = __importDefault(require("./TimerPicker"));
|
|
32
|
+
var Modal_1 = __importDefault(require("./Modal"));
|
|
33
|
+
var TimerPickerModal_styles_1 = require("./TimerPickerModal.styles");
|
|
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;
|
|
36
|
+
var styles = (0, TimerPickerModal_styles_1.generateStyles)(customStyles);
|
|
37
|
+
var _r = (0, react_1.useState)({
|
|
38
|
+
hours: initialHours,
|
|
39
|
+
minutes: initialMinutes,
|
|
40
|
+
seconds: initialSeconds,
|
|
41
|
+
}), selectedDuration = _r[0], setSelectedDuration = _r[1];
|
|
42
|
+
var _s = (0, react_1.useState)({
|
|
43
|
+
hours: initialHours,
|
|
44
|
+
minutes: initialMinutes,
|
|
45
|
+
seconds: initialSeconds,
|
|
46
|
+
}), confirmedDuration = _s[0], setConfirmedDuration = _s[1];
|
|
47
|
+
var hideModal = function () {
|
|
48
|
+
setSelectedDuration({
|
|
49
|
+
hours: confirmedDuration.hours,
|
|
50
|
+
minutes: confirmedDuration.minutes,
|
|
51
|
+
seconds: confirmedDuration.seconds,
|
|
52
|
+
});
|
|
53
|
+
setIsVisible(false);
|
|
54
|
+
};
|
|
55
|
+
var confirm = function () {
|
|
56
|
+
setConfirmedDuration(selectedDuration);
|
|
57
|
+
onConfirm(selectedDuration);
|
|
58
|
+
};
|
|
59
|
+
var cancel = function () {
|
|
60
|
+
setIsVisible(false);
|
|
61
|
+
setSelectedDuration(confirmedDuration);
|
|
62
|
+
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
63
|
+
};
|
|
64
|
+
(0, react_1.useImperativeHandle)(ref, function () { return ({
|
|
65
|
+
reset: function () {
|
|
66
|
+
var initialDuration = {
|
|
67
|
+
hours: initialHours,
|
|
68
|
+
minutes: initialMinutes,
|
|
69
|
+
seconds: initialSeconds,
|
|
70
|
+
};
|
|
71
|
+
setSelectedDuration(initialDuration);
|
|
72
|
+
setConfirmedDuration(initialDuration);
|
|
73
|
+
setIsVisible(false);
|
|
74
|
+
},
|
|
75
|
+
}); });
|
|
76
|
+
return (<Modal_1.default isVisible={visible} onOverlayPress={closeOnOverlayPress ? hideModal : undefined} {...modalProps} testID="timer-picker-modal">
|
|
77
|
+
<react_native_1.View {...containerProps} style={styles.container}>
|
|
78
|
+
<react_native_1.View {...contentContainerProps} style={styles.contentContainer}>
|
|
79
|
+
{modalTitle ? (<react_native_1.Text {...modalTitleProps} style={styles.modalTitle}>
|
|
80
|
+
{modalTitle}
|
|
81
|
+
</react_native_1.Text>) : null}
|
|
82
|
+
<TimerPicker_1.default onDurationChange={function (duration) {
|
|
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}/>
|
|
86
|
+
<react_native_1.View {...buttonContainerProps} style={styles.buttonContainer}>
|
|
87
|
+
{!hideCancelButton ? (<react_native_1.TouchableOpacity onPress={cancel}>
|
|
88
|
+
<react_native_1.Text style={[
|
|
89
|
+
styles.cancelButton,
|
|
90
|
+
styles.button,
|
|
91
|
+
]}>
|
|
92
|
+
{cancelButtonText}
|
|
93
|
+
</react_native_1.Text>
|
|
94
|
+
</react_native_1.TouchableOpacity>) : null}
|
|
95
|
+
<react_native_1.TouchableOpacity onPress={confirm}>
|
|
96
|
+
<react_native_1.Text style={[
|
|
97
|
+
styles.confirmButton,
|
|
98
|
+
styles.button,
|
|
99
|
+
]}>
|
|
100
|
+
{confirmButtonText}
|
|
101
|
+
</react_native_1.Text>
|
|
102
|
+
</react_native_1.TouchableOpacity>
|
|
103
|
+
</react_native_1.View>
|
|
104
|
+
</react_native_1.View>
|
|
105
|
+
</react_native_1.View>
|
|
106
|
+
</Modal_1.default>);
|
|
107
|
+
});
|
|
108
|
+
exports.default = TimerPickerModal;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as TimerPickerModal, TimerPickerModalProps, } from "./components";
|
|
2
|
+
export { default as TimerPicker, TimerPickerProps, } from "./components/TimerPicker";
|
|
3
|
+
export { CustomTimerPickerModalStyles } from "./components/TimerPickerModal.styles";
|
|
4
|
+
export { CustomTimerPickerStyles } from "./components/TimerPicker/TimerPicker.styles";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TimerPicker = exports.TimerPickerModal = void 0;
|
|
7
|
+
var components_1 = require("./components");
|
|
8
|
+
Object.defineProperty(exports, "TimerPickerModal", { enumerable: true, get: function () { return __importDefault(components_1).default; } });
|
|
9
|
+
var TimerPicker_1 = require("./components/TimerPicker");
|
|
10
|
+
Object.defineProperty(exports, "TimerPicker", { enumerable: true, get: function () { return __importDefault(TimerPicker_1).default; } });
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.colorToRgba = void 0;
|
|
4
|
+
var colorToRgba = function (variables) {
|
|
5
|
+
// this function is required for expo-linear-gradient on iOS. To fade to transparent, we need
|
|
6
|
+
// to be able to add opacity to the background color. Supplying 'transparent' does not work
|
|
7
|
+
// because that is actually a transparent black (rgba(0, 0, 0, 1)), which results in dodgy rendering
|
|
8
|
+
var color = variables.color, _a = variables.opacity, opacity = _a === void 0 ? 1 : _a;
|
|
9
|
+
// Handle named colors
|
|
10
|
+
var namedColors = {
|
|
11
|
+
transparent: "rgba(0, 0, 0, 0)",
|
|
12
|
+
black: "rgba(0, 0, 0, 1)",
|
|
13
|
+
white: "rgba(255, 255, 255, 1)",
|
|
14
|
+
blue: "rgba(0, 0, 255, 1)",
|
|
15
|
+
green: "rgba(0, 128, 0, 1)",
|
|
16
|
+
gray: "rgba(128, 128, 128, 1)",
|
|
17
|
+
red: "rgba(255, 0, 0, 1)",
|
|
18
|
+
};
|
|
19
|
+
if (color in namedColors) {
|
|
20
|
+
return namedColors[color];
|
|
21
|
+
}
|
|
22
|
+
// Handle RGB format
|
|
23
|
+
if (color.startsWith("rgb(")) {
|
|
24
|
+
var rgbValues = color
|
|
25
|
+
.replace("rgb(", "")
|
|
26
|
+
.replace(")", "")
|
|
27
|
+
.split(",")
|
|
28
|
+
.map(function (value) { return parseInt(value.trim(), 10); });
|
|
29
|
+
var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2];
|
|
30
|
+
return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(opacity, ")");
|
|
31
|
+
}
|
|
32
|
+
// Handle hex format
|
|
33
|
+
if (color.startsWith("#")) {
|
|
34
|
+
var hexColor = color.slice(1);
|
|
35
|
+
if (hexColor.length === 3) {
|
|
36
|
+
hexColor = hexColor
|
|
37
|
+
.split("")
|
|
38
|
+
.map(function (value) { return value + value; })
|
|
39
|
+
.join("");
|
|
40
|
+
}
|
|
41
|
+
var r = parseInt(hexColor.slice(0, 2), 16);
|
|
42
|
+
var g = parseInt(hexColor.slice(2, 4), 16);
|
|
43
|
+
var b = parseInt(hexColor.slice(4, 6), 16);
|
|
44
|
+
return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(opacity, ")");
|
|
45
|
+
}
|
|
46
|
+
return color; // Return unchanged if unable to parse
|
|
47
|
+
};
|
|
48
|
+
exports.colorToRgba = colorToRgba;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateNumbers = void 0;
|
|
4
|
+
var padWithZero_1 = require("./padWithZero");
|
|
5
|
+
var generateNumbers = function (numberOfItems, options) {
|
|
6
|
+
var _a;
|
|
7
|
+
if (numberOfItems <= 0) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
var numbers = [];
|
|
11
|
+
if (options.padWithZero) {
|
|
12
|
+
for (var i = 0; i <= numberOfItems; i++) {
|
|
13
|
+
numbers.push((0, padWithZero_1.padWithZero)(i));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
for (var i = 0; i <= numberOfItems; i++) {
|
|
18
|
+
numbers.push(String(i));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (((_a = options.repeatNTimes) !== null && _a !== void 0 ? _a : 1) > 1) {
|
|
22
|
+
numbers = Array(options.repeatNTimes).fill(numbers).flat();
|
|
23
|
+
}
|
|
24
|
+
if (options.disableInfiniteScroll) {
|
|
25
|
+
numbers.push.apply(numbers, Array(options.padWithNItems).fill(""));
|
|
26
|
+
numbers.unshift.apply(numbers, Array(options.padWithNItems).fill(""));
|
|
27
|
+
}
|
|
28
|
+
return numbers;
|
|
29
|
+
};
|
|
30
|
+
exports.generateNumbers = generateNumbers;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const padWithZero: (value: number) => string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.padWithZero = void 0;
|
|
4
|
+
var padWithZero = function (value) {
|
|
5
|
+
if (value < 10) {
|
|
6
|
+
return "0" + value;
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
return String(value);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
exports.padWithZero = padWithZero;
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/troberts-28"
|
|
7
7
|
},
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.3",
|
|
10
10
|
"main": "dist/index.js",
|
|
11
11
|
"types": "dist/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"registry": "https://registry.npmjs.org/"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
|
-
"index.ts",
|
|
35
34
|
"dist",
|
|
36
35
|
"package.json",
|
|
37
36
|
"README.md",
|