Skip to content

Commit 851dbd5

Browse files
fix: convert Mantine v9 DateInput string values to Date for date-fns (HDX-3981)
Mantine v9 DateInput onChange now returns strings instead of Date objects. This broke the TimePicker which passes form values to date-fns functions (format, add, sub) and calls .getTime() on them. - Add toDate() helper to convert string values back to Date objects - Override DateInputCmp onChange to convert before storing in form - Guard handleApply, handleMove, and mode-switch with toDate() - Guard useTimePickerForm onValuesChange date comparison
1 parent 1e2fe74 commit 851dbd5

2 files changed

Lines changed: 28 additions & 15 deletions

File tree

packages/app/src/components/TimePicker/TimePicker.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ const modeAtom = atomWithStorage<TimePickerMode>(
4646
const DATE_INPUT_PLACEHOLDER = 'YYY-MM-DD HH:mm:ss';
4747
const DATE_INPUT_FORMAT = 'YYYY-MM-DD HH:mm:ss';
4848

49-
const DateInputCmp = (props: DateInputProps) => (
49+
/** Ensure a value is a Date object (Mantine v9 DateInput returns strings). */
50+
const toDate = (v: Date | string | null): Date | null =>
51+
v == null ? null : v instanceof Date ? v : new Date(v);
52+
53+
const DateInputCmp = ({ onChange: onChangeProp, ...props }: DateInputProps) => (
5054
<DateInput
5155
size="xs"
5256
highlightToday
@@ -60,6 +64,7 @@ const DateInputCmp = (props: DateInputProps) => (
6064
}
6165
}}
6266
{...props}
67+
onChange={v => onChangeProp?.(toDate(v) as any)}
6368
/>
6469
);
6570

@@ -176,7 +181,8 @@ const TimePickerComponent = ({
176181
if (!form.isValid() || !opened) {
177182
return;
178183
}
179-
const { startDate, endDate } = form.values;
184+
const startDate = toDate(form.values.startDate);
185+
const endDate = toDate(form.values.endDate);
180186
if (mode === TimePickerMode.Range) {
181187
handleSearch([startDate, endDate]);
182188
close();
@@ -194,7 +200,8 @@ const TimePickerComponent = ({
194200

195201
const handleMove = React.useCallback(
196202
(d: Duration) => {
197-
const { startDate, endDate } = form.values;
203+
const startDate = toDate(form.values.startDate);
204+
const endDate = toDate(form.values.endDate);
198205
const from = startDate && add(startDate, d);
199206
const to = endDate && add(endDate, d);
200207
handleSearch([from, to]);
@@ -368,15 +375,12 @@ const TimePickerComponent = ({
368375
form.values.startDate &&
369376
form.values.endDate
370377
) {
378+
const start = toDate(form.values.startDate)!;
379+
const end = toDate(form.values.endDate)!;
371380
const midpoint = new Date(
372-
(form.values.startDate.getTime() +
373-
form.values.endDate.getTime()) /
374-
2,
381+
(start.getTime() + end.getTime()) / 2,
375382
);
376-
const halfRangeMs =
377-
(form.values.endDate.getTime() -
378-
form.values.startDate.getTime()) /
379-
2;
383+
const halfRangeMs = (end.getTime() - start.getTime()) / 2;
380384

381385
// Find the closest duration option
382386
const halfRangeMinutes = halfRangeMs / (1000 * 60);

packages/app/src/components/TimePicker/useTimePickerForm.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,20 @@ export const useTimePickerForm = ({ mode }: { mode: TimePickerMode }) => {
3636

3737
onValuesChange: values => {
3838
// Ensure that end date is not before start date
39-
if (
40-
values.endDate &&
41-
values.startDate &&
42-
values.endDate < values.startDate
43-
) {
39+
// Guard with getTime() since Mantine v9 DateInput may supply strings
40+
const start =
41+
values.startDate instanceof Date
42+
? values.startDate
43+
: values.startDate
44+
? new Date(values.startDate)
45+
: null;
46+
const end =
47+
values.endDate instanceof Date
48+
? values.endDate
49+
: values.endDate
50+
? new Date(values.endDate)
51+
: null;
52+
if (start && end && end.getTime() < start.getTime()) {
4453
form.setFieldValue('endDate', values.startDate);
4554
}
4655
},

0 commit comments

Comments
 (0)