react-native-timer-picker
Version:
A simple, flexible, performant duration picker for React Native apps 🔥 Great for timers, alarms and duration inputs ⏰🕰️⏳ Includes iOS-style haptic and audio feedback 🍏
228 lines • 11.4 kB
JavaScript
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import { View } from "react-native";
import { getSafeInitialValue } from "../../utils/getSafeInitialValue";
import DurationScroll from "../DurationScroll";
import { generateStyles } from "./styles";
const TimerPicker = /*#__PURE__*/forwardRef((props, ref) => {
const {
aggressivelyGetLatestDuration = false,
allowFontScaling = false,
amLabel = "am",
dayInterval = 1,
dayLabel,
dayLimit,
daysPickerIsDisabled = false,
decelerationRate = 0.88,
disableInfiniteScroll = false,
hideDays = true,
hideHours = false,
hideMinutes = false,
hideSeconds = false,
hourInterval = 1,
hourLabel,
hourLimit,
hoursPickerIsDisabled = false,
initialValue,
maximumDays = 30,
maximumHours = 23,
maximumMinutes = 59,
maximumSeconds = 59,
minuteInterval = 1,
minuteLabel,
minuteLimit,
minutesPickerIsDisabled = false,
onDurationChange,
padDaysWithZero = false,
padHoursWithZero = false,
padMinutesWithZero = true,
padSecondsWithZero = true,
padWithNItems = 1,
pickerContainerProps,
pmLabel = "pm",
repeatDayNumbersNTimes = 3,
repeatHourNumbersNTimes = 8,
repeatMinuteNumbersNTimes = 3,
repeatSecondNumbersNTimes = 3,
secondInterval = 1,
secondLabel,
secondLimit,
secondsPickerIsDisabled = false,
styles: customStyles,
use12HourPicker = false,
...otherProps
} = props;
useEffect(() => {
if (otherProps.Audio) {
console.warn('The "Audio" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.');
}
if (otherProps.Haptics) {
console.warn('The "Haptics" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.');
}
if (otherProps.clickSoundAsset) {
console.warn('The "clickSoundAsset" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.');
}
}, [otherProps.Audio, otherProps.Haptics, otherProps.clickSoundAsset]);
const safePadWithNItems = useMemo(() => {
if (padWithNItems < 0 || isNaN(padWithNItems)) {
return 0;
}
const maxPadWithNItems = hideHours ? 15 : 6;
if (padWithNItems > maxPadWithNItems) {
return maxPadWithNItems;
}
return Math.round(padWithNItems);
}, [hideHours, padWithNItems]);
const safeInitialValue = useMemo(() => getSafeInitialValue({
days: initialValue === null || initialValue === void 0 ? void 0 : initialValue.days,
hours: initialValue === null || initialValue === void 0 ? void 0 : initialValue.hours,
minutes: initialValue === null || initialValue === void 0 ? void 0 : initialValue.minutes,
seconds: initialValue === null || initialValue === void 0 ? void 0 : initialValue.seconds
}), [initialValue === null || initialValue === void 0 ? void 0 : initialValue.days, initialValue === null || initialValue === void 0 ? void 0 : initialValue.hours, initialValue === null || initialValue === void 0 ? void 0 : initialValue.minutes, initialValue === null || initialValue === void 0 ? void 0 : initialValue.seconds]);
const styles = useMemo(() => generateStyles(customStyles), [customStyles]);
const [selectedDays, setSelectedDays] = useState(safeInitialValue.days);
const [selectedHours, setSelectedHours] = useState(safeInitialValue.hours);
const [selectedMinutes, setSelectedMinutes] = useState(safeInitialValue.minutes);
const [selectedSeconds, setSelectedSeconds] = useState(safeInitialValue.seconds);
useEffect(() => {
onDurationChange === null || onDurationChange === void 0 || onDurationChange({
days: selectedDays,
hours: selectedHours,
minutes: selectedMinutes,
seconds: selectedSeconds
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedDays, selectedHours, selectedMinutes, selectedSeconds]);
const daysDurationScrollRef = useRef(null);
const hoursDurationScrollRef = useRef(null);
const minutesDurationScrollRef = useRef(null);
const secondsDurationScrollRef = useRef(null);
useImperativeHandle(ref, () => {
var _daysDurationScrollRe3, _hoursDurationScrollR3, _minutesDurationScrol3, _secondsDurationScrol3;
return {
reset: options => {
var _daysDurationScrollRe, _hoursDurationScrollR, _minutesDurationScrol, _secondsDurationScrol;
setSelectedDays(safeInitialValue.days);
setSelectedHours(safeInitialValue.hours);
setSelectedMinutes(safeInitialValue.minutes);
setSelectedSeconds(safeInitialValue.seconds);
(_daysDurationScrollRe = daysDurationScrollRef.current) === null || _daysDurationScrollRe === void 0 || _daysDurationScrollRe.reset(options);
(_hoursDurationScrollR = hoursDurationScrollRef.current) === null || _hoursDurationScrollR === void 0 || _hoursDurationScrollR.reset(options);
(_minutesDurationScrol = minutesDurationScrollRef.current) === null || _minutesDurationScrol === void 0 || _minutesDurationScrol.reset(options);
(_secondsDurationScrol = secondsDurationScrollRef.current) === null || _secondsDurationScrol === void 0 || _secondsDurationScrol.reset(options);
},
setValue: (value, options) => {
if (value.days) {
var _daysDurationScrollRe2;
setSelectedDays(value.days);
(_daysDurationScrollRe2 = daysDurationScrollRef.current) === null || _daysDurationScrollRe2 === void 0 || _daysDurationScrollRe2.setValue(value.days, options);
}
if (value.hours) {
var _hoursDurationScrollR2;
setSelectedHours(value.hours);
(_hoursDurationScrollR2 = hoursDurationScrollRef.current) === null || _hoursDurationScrollR2 === void 0 || _hoursDurationScrollR2.setValue(value.hours, options);
}
if (value.minutes) {
var _minutesDurationScrol2;
setSelectedMinutes(value.minutes);
(_minutesDurationScrol2 = minutesDurationScrollRef.current) === null || _minutesDurationScrol2 === void 0 || _minutesDurationScrol2.setValue(value.minutes, options);
}
if (value.seconds) {
var _secondsDurationScrol2;
setSelectedSeconds(value.seconds);
(_secondsDurationScrol2 = secondsDurationScrollRef.current) === null || _secondsDurationScrol2 === void 0 || _secondsDurationScrol2.setValue(value.seconds, options);
}
},
latestDuration: {
days: (_daysDurationScrollRe3 = daysDurationScrollRef.current) === null || _daysDurationScrollRe3 === void 0 ? void 0 : _daysDurationScrollRe3.latestDuration,
hours: (_hoursDurationScrollR3 = hoursDurationScrollRef.current) === null || _hoursDurationScrollR3 === void 0 ? void 0 : _hoursDurationScrollR3.latestDuration,
minutes: (_minutesDurationScrol3 = minutesDurationScrollRef.current) === null || _minutesDurationScrol3 === void 0 ? void 0 : _minutesDurationScrol3.latestDuration,
seconds: (_secondsDurationScrol3 = secondsDurationScrollRef.current) === null || _secondsDurationScrol3 === void 0 ? void 0 : _secondsDurationScrol3.latestDuration
}
};
});
return /*#__PURE__*/React.createElement(View, _extends({}, pickerContainerProps, {
style: styles.pickerContainer,
testID: "timer-picker"
}), !hideDays ? /*#__PURE__*/React.createElement(DurationScroll, _extends({
ref: daysDurationScrollRef,
aggressivelyGetLatestDuration: aggressivelyGetLatestDuration,
allowFontScaling: allowFontScaling,
disableInfiniteScroll: disableInfiniteScroll,
initialValue: safeInitialValue.days,
interval: dayInterval,
isDisabled: daysPickerIsDisabled,
label: dayLabel ?? "d",
limit: dayLimit,
maximumValue: maximumDays,
onDurationChange: setSelectedDays,
padNumbersWithZero: padDaysWithZero,
padWithNItems: safePadWithNItems,
repeatNumbersNTimes: repeatDayNumbersNTimes,
repeatNumbersNTimesNotExplicitlySet: (props === null || props === void 0 ? void 0 : props.repeatDayNumbersNTimes) === undefined,
styles: styles,
testID: "duration-scroll-day"
}, otherProps)) : null, !hideHours ? /*#__PURE__*/React.createElement(DurationScroll, _extends({
ref: hoursDurationScrollRef,
aggressivelyGetLatestDuration: aggressivelyGetLatestDuration,
allowFontScaling: allowFontScaling,
amLabel: amLabel,
decelerationRate: decelerationRate,
disableInfiniteScroll: disableInfiniteScroll,
initialValue: safeInitialValue.hours,
interval: hourInterval,
is12HourPicker: use12HourPicker,
isDisabled: hoursPickerIsDisabled,
label: hourLabel ?? (!use12HourPicker ? "h" : undefined),
limit: hourLimit,
maximumValue: maximumHours,
onDurationChange: setSelectedHours,
padNumbersWithZero: padHoursWithZero,
padWithNItems: safePadWithNItems,
pmLabel: pmLabel,
repeatNumbersNTimes: repeatHourNumbersNTimes,
repeatNumbersNTimesNotExplicitlySet: (props === null || props === void 0 ? void 0 : props.repeatHourNumbersNTimes) === undefined,
styles: styles,
testID: "duration-scroll-hour"
}, otherProps)) : null, !hideMinutes ? /*#__PURE__*/React.createElement(DurationScroll, _extends({
ref: minutesDurationScrollRef,
aggressivelyGetLatestDuration: aggressivelyGetLatestDuration,
allowFontScaling: allowFontScaling,
decelerationRate: decelerationRate,
disableInfiniteScroll: disableInfiniteScroll,
initialValue: safeInitialValue.minutes,
interval: minuteInterval,
isDisabled: minutesPickerIsDisabled,
label: minuteLabel ?? "m",
limit: minuteLimit,
maximumValue: maximumMinutes,
onDurationChange: setSelectedMinutes,
padNumbersWithZero: padMinutesWithZero,
padWithNItems: safePadWithNItems,
repeatNumbersNTimes: repeatMinuteNumbersNTimes,
repeatNumbersNTimesNotExplicitlySet: (props === null || props === void 0 ? void 0 : props.repeatMinuteNumbersNTimes) === undefined,
styles: styles,
testID: "duration-scroll-minute"
}, otherProps)) : null, !hideSeconds ? /*#__PURE__*/React.createElement(DurationScroll, _extends({
ref: secondsDurationScrollRef,
aggressivelyGetLatestDuration: aggressivelyGetLatestDuration,
allowFontScaling: allowFontScaling,
decelerationRate: decelerationRate,
disableInfiniteScroll: disableInfiniteScroll,
initialValue: safeInitialValue.seconds,
interval: secondInterval,
isDisabled: secondsPickerIsDisabled,
label: secondLabel ?? "s",
limit: secondLimit,
maximumValue: maximumSeconds,
onDurationChange: setSelectedSeconds,
padNumbersWithZero: padSecondsWithZero,
padWithNItems: safePadWithNItems,
repeatNumbersNTimes: repeatSecondNumbersNTimes,
repeatNumbersNTimesNotExplicitlySet: (props === null || props === void 0 ? void 0 : props.repeatSecondNumbersNTimes) === undefined,
styles: styles,
testID: "duration-scroll-second"
}, otherProps)) : null);
});
export default /*#__PURE__*/React.memo(TimerPicker);
//# sourceMappingURL=TimerPicker.js.map