Skip to content

Commit b0ae01f

Browse files
committed
Merge branch 'release/v1.7.0'
2 parents badd4ff + 901a24a commit b0ae01f

File tree

6 files changed

+83
-69
lines changed

6 files changed

+83
-69
lines changed

README.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Works with Expo and bare React Native apps.
3030
- [Contributing 🧑‍🤝‍🧑](#contributing-)
3131
- [Dev Setup](#dev-setup)
3232
- [GitHub Guidelines](#github-guidelines)
33+
- [Limitations ⚠](#limitations-)
3334
- [License 📝](#license-)
3435

3536
<br>
@@ -332,18 +333,16 @@ return (
332333
| Prop | Description | Type | Default | Required |
333334
| :------------------------------: | :------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----: | :------: |
334335
| onDurationChange | Callback when the duration changes | `(duration: { hours: number, minutes: number, seconds: number }) => void` | - | false |
335-
| initialHours | Initial value for hours | Number | - | false |
336-
| initialMinutes | Initial value for minutes | Number | - | false |
337-
| initialSeconds | Initial value for seconds | Number | - | false |
336+
| initialValue | Initial value for the picker | `{ hours?: number, minutes?: number, seconds?: number }` | - | false |
338337
| hideHours | Hide the hours picker | Boolean | false | false |
339338
| hideMinutes | Hide the minutes picker | Boolean | false | false |
340339
| hideSeconds | Hide the seconds picker | Boolean | false | false |
341340
| hoursPickerIsDisabled | Disable the hours picker picker | Boolean | false | false |
342341
| minutesPickerIsDisabled | Disable the minutes picker picker | Boolean | false | false |
343342
| secondsPickerIsDisabled | Disable the seconds picker picker | Boolean | false | false |
344-
| hourLimit | Limit on the hours it is possible to select | { max?: Number, min?: Number } | - | false |
345-
| minuteLimit | Limit on the minutes it is possible to select | { max?: Number, min?: Number } | - | false |
346-
| secondLimit | Limit on the seconds it is possible to select | { max?: Number, min?: Number } | - | false |
343+
| hourLimit | Limit on the hours it is possible to select | `{ max?: Number, min?: Number }` | - | false |
344+
| minuteLimit | Limit on the minutes it is possible to select | `{ max?: Number, min?: Number }` | - | false |
345+
| secondLimit | Limit on the seconds it is possible to select | `{ max?: Number, min?: Number }` | - | false |
347346
| hourLabel | Label for the hours picker | String \| React.ReactElement | h | false |
348347
| minuteLabel | Label for the minutes picker | String \| React.ReactElement | m | false |
349348
| secondLabel | Label for the seconds picker | String \| React.ReactElement | s | false |
@@ -370,17 +369,19 @@ The following custom styles can be supplied to re-style the component in any way
370369
| theme | Theme of the component | "light" \| "dark" |
371370
| backgroundColor | Main background color | string |
372371
| text | Base text style | TextStyle |
373-
| pickerContainer | Main container for the picker | ViewStyle |
372+
| pickerContainer | Main container for the picker | ViewStyle & { backgroundColor?: string } |
374373
| pickerLabelContainer | Container for the picker's labels | ViewStyle |
375374
| pickerLabel | Style for the picker's labels | TextStyle |
376375
| pickerAmPmContainer | Style for the picker's labels | ViewStyle |
377376
| pickerAmPmLabel | Style for the picker's labels | TextStyle |
378-
| pickerItemContainer | Container for each number in the picker | ViewStyle |
377+
| pickerItemContainer | Container for each number in the picker | ViewStyle & { height?: number } |
379378
| pickerItem | Style for each individual picker number | TextStyle |
380379
| disabledPickerItem | Style for any numbers outside any set limits | TextStyle |
381380
| disabledPickerContainer | Style for disabled pickers | ViewStyle |
382381
| pickerGradientOverlay | Style for the gradient overlay (fade out) | ViewStyle |
383382

383+
Note the minor limitations to the allowed styles for `pickerContainer` and `pickerItemContainer`. These are made because these styles are used for internal calculations and all possible `backgroundColor`/`height` types are not supported.
384+
384385
### TimerPickerModal ⏰
385386

386387
The TimerPickerModal component accepts all [TimerPicker props](#timerpicker-️), and the below additional props.
@@ -486,6 +487,12 @@ There are two permenant branches: `main` and `develop`. You should never work di
486487
487488
<br>
488489
490+
## Limitations ⚠
491+
492+
Nesting the `TimerPicker` component inside a vertical ScrollView is not supported. React Native will throw an error and the picker will not be scrollable. The modal component works fine in this scenario however.
493+
494+
<br>
495+
489496
## License 📝
490497
491498
This project is licensed under the [MIT License](LICENSE).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"url": "https://github.com/troberts-28"
77
},
88
"license": "MIT",
9-
"version": "1.6.0",
9+
"version": "1.7.0",
1010
"main": "dist/commonjs/index.js",
1111
"types": "dist/typescript/src/index.d.ts",
1212
"scripts": {

src/components/TimerPicker/TimerPicker.styles.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
import { StyleSheet } from "react-native";
2+
import { StyleSheet, TextStyle, ViewStyle } from "react-native";
33

44
export interface CustomTimerPickerStyles {
55
theme?: "light" | "dark";
66
backgroundColor?: string;
7-
text?: any;
8-
pickerContainer?: any;
9-
pickerLabelContainer?: any;
10-
pickerLabel?: any;
11-
pickerAmPmContainer?: any;
12-
pickerAmPmLabel?: any;
13-
pickerItemContainer?: any;
14-
pickerItem?: any;
15-
disabledPickerContainer?: any;
16-
disabledPickerItem?: any;
17-
pickerGradientOverlay?: any;
7+
text?: TextStyle;
8+
pickerContainer?: ViewStyle & { backgroundColor?: string };
9+
pickerLabelContainer?: ViewStyle;
10+
pickerLabel?: TextStyle;
11+
pickerAmPmContainer?: ViewStyle;
12+
pickerAmPmLabel?: TextStyle;
13+
pickerItemContainer?: ViewStyle & { height?: number };
14+
pickerItem?: TextStyle;
15+
disabledPickerContainer?: ViewStyle;
16+
disabledPickerItem?: TextStyle;
17+
pickerGradientOverlay?: ViewStyle;
1818
}
1919

2020
const DARK_MODE_BACKGROUND_COLOR = "#232323";

src/components/TimerPicker/index.tsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ export interface TimerPickerProps {
3838
minutes: number;
3939
seconds: number;
4040
}) => void;
41-
initialHours?: number;
42-
initialMinutes?: number;
43-
initialSeconds?: number;
41+
initialValue?: {
42+
hours?: number;
43+
minutes?: number;
44+
seconds?: number;
45+
};
4446
aggressivelyGetLatestDuration?: boolean;
4547
use12HourPicker?: boolean;
4648
amLabel?: string;
@@ -73,9 +75,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
7375
{
7476
allowFontScaling = false,
7577
onDurationChange,
76-
initialHours = 0,
77-
initialMinutes = 0,
78-
initialSeconds = 0,
78+
initialValue,
7979
hideHours = false,
8080
hideMinutes = false,
8181
hideSeconds = false,
@@ -115,9 +115,21 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
115115
[checkedPadWithNItems, customStyles]
116116
);
117117

118-
const [selectedHours, setSelectedHours] = useState(initialHours);
119-
const [selectedMinutes, setSelectedMinutes] = useState(initialMinutes);
120-
const [selectedSeconds, setSelectedSeconds] = useState(initialSeconds);
118+
const safeInitialValue = {
119+
hours: initialValue?.hours ?? 0,
120+
minutes: initialValue?.minutes ?? 0,
121+
seconds: initialValue?.seconds ?? 0,
122+
};
123+
124+
const [selectedHours, setSelectedHours] = useState(
125+
safeInitialValue.hours
126+
);
127+
const [selectedMinutes, setSelectedMinutes] = useState(
128+
safeInitialValue.minutes
129+
);
130+
const [selectedSeconds, setSelectedSeconds] = useState(
131+
safeInitialValue.seconds
132+
);
121133

122134
useEffect(() => {
123135
onDurationChange?.({
@@ -134,9 +146,9 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
134146

135147
useImperativeHandle(ref, () => ({
136148
reset: (options) => {
137-
setSelectedHours(initialHours);
138-
setSelectedMinutes(initialMinutes);
139-
setSelectedSeconds(initialSeconds);
149+
setSelectedHours(safeInitialValue.hours);
150+
setSelectedMinutes(safeInitialValue.minutes);
151+
setSelectedSeconds(safeInitialValue.seconds);
140152
hoursDurationScrollRef.current?.reset(options);
141153
minutesDurationScrollRef.current?.reset(options);
142154
secondsDurationScrollRef.current?.reset(options);
@@ -175,7 +187,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
175187
hourLabel ?? (!use12HourPicker ? "h" : undefined)
176188
}
177189
isDisabled={hoursPickerIsDisabled}
178-
initialValue={initialHours}
190+
initialValue={safeInitialValue.hours}
179191
allowFontScaling={allowFontScaling}
180192
aggressivelyGetLatestDuration={
181193
aggressivelyGetLatestDuration
@@ -205,7 +217,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
205217
numberOfItems={59}
206218
label={minuteLabel ?? "m"}
207219
isDisabled={minutesPickerIsDisabled}
208-
initialValue={initialMinutes}
220+
initialValue={safeInitialValue.minutes}
209221
allowFontScaling={allowFontScaling}
210222
aggressivelyGetLatestDuration={
211223
aggressivelyGetLatestDuration
@@ -233,7 +245,7 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
233245
numberOfItems={59}
234246
label={secondLabel ?? "s"}
235247
isDisabled={secondsPickerIsDisabled}
236-
initialValue={initialSeconds}
248+
initialValue={safeInitialValue.seconds}
237249
allowFontScaling={allowFontScaling}
238250
aggressivelyGetLatestDuration={
239251
aggressivelyGetLatestDuration

src/components/TimerPickerModal.styles.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
import { StyleSheet } from "react-native";
2+
import { StyleSheet, TextStyle, ViewStyle } from "react-native";
33

44
import type { CustomTimerPickerStyles } from "./TimerPicker/TimerPicker.styles";
55

66
export interface CustomTimerPickerModalStyles extends CustomTimerPickerStyles {
7-
container?: any;
8-
contentContainer?: any;
9-
buttonContainer?: any;
10-
button?: any;
11-
cancelButton?: any;
12-
confirmButton?: any;
13-
modalTitle?: any;
7+
container?: ViewStyle;
8+
contentContainer?: ViewStyle;
9+
buttonContainer?: ViewStyle;
10+
button?: TextStyle;
11+
cancelButton?: TextStyle;
12+
confirmButton?: TextStyle;
13+
modalTitle?: TextStyle;
1414
}
1515

1616
const DARK_MODE_BACKGROUND_COLOR = "#232323";

src/components/index.tsx

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ const TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(
7070
onCancel,
7171
onDurationChange,
7272
closeOnOverlayPress,
73-
initialHours = 0,
74-
initialMinutes = 0,
75-
initialSeconds = 0,
73+
initialValue,
7674
hideHours = false,
7775
hideMinutes = false,
7876
hideSeconds = false,
@@ -114,33 +112,32 @@ const TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(
114112

115113
const timerPickerRef = useRef<TimerPickerRef>(null);
116114

117-
const [selectedDuration, setSelectedDuration] = useState({
118-
hours: initialHours,
119-
minutes: initialMinutes,
120-
seconds: initialSeconds,
121-
});
122-
const [confirmedDuration, setConfirmedDuration] = useState({
123-
hours: initialHours,
124-
minutes: initialMinutes,
125-
seconds: initialSeconds,
126-
});
115+
const safeInitialValue = {
116+
hours: initialValue?.hours ?? 0,
117+
minutes: initialValue?.minutes ?? 0,
118+
seconds: initialValue?.seconds ?? 0,
119+
};
120+
121+
const [selectedDuration, setSelectedDuration] =
122+
useState(safeInitialValue);
123+
const [confirmedDuration, setConfirmedDuration] =
124+
useState(safeInitialValue);
127125

128126
const reset = (options?: { animated?: boolean }) => {
129-
const initialDuration = {
130-
hours: initialHours,
131-
minutes: initialMinutes,
132-
seconds: initialSeconds,
133-
};
134-
setSelectedDuration(initialDuration);
135-
setConfirmedDuration(initialDuration);
127+
setSelectedDuration(safeInitialValue);
128+
setConfirmedDuration(safeInitialValue);
136129
timerPickerRef.current?.reset(options);
137130
};
138131

139-
// reset state if the initial times change
132+
// reset state if the initial value changes
140133
useEffect(() => {
141134
reset();
142135
// eslint-disable-next-line react-hooks/exhaustive-deps
143-
}, [initialHours, initialMinutes, initialSeconds]);
136+
}, [
137+
safeInitialValue.hours,
138+
safeInitialValue.minutes,
139+
safeInitialValue.seconds,
140+
]);
144141

145142
const hideModalHandler = () => {
146143
setSelectedDuration({
@@ -217,9 +214,7 @@ const TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(
217214
<TimerPicker
218215
ref={timerPickerRef}
219216
onDurationChange={durationChangeHandler}
220-
initialHours={confirmedDuration.hours}
221-
initialMinutes={confirmedDuration.minutes}
222-
initialSeconds={confirmedDuration.seconds}
217+
initialValue={confirmedDuration}
223218
aggressivelyGetLatestDuration={true}
224219
hideHours={hideHours}
225220
hideMinutes={hideMinutes}

0 commit comments

Comments
 (0)