Skip to content

Commit e2df77b

Browse files
committed
fix(forms): fix date parsing when default value is provided
1 parent 182bed4 commit e2df77b

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

demo/FormExamples.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function FormExamples() {
2121
switchField2: true,
2222
checkboxField2: true,
2323
radioField2: 'b',
24+
dateField: new Date().toISOString(),
2425
}}
2526
onChange={console.info}
2627
onSubmit={(formData, reset) => {
@@ -105,7 +106,7 @@ export function FormExamples() {
105106
<FormGroupInput name="numberField" label="Number field" type="number" />
106107
</div>
107108
<div className="col">
108-
<FormGroupInput name="dateField" label="Date field " type="datetime-local" />
109+
<FormGroupInput name="dateField" label="Date field" type="datetime-local" />
109110
</div>
110111
</div>
111112

src/forms/helpers/useFormControl.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useContext } from 'react';
22
import { FormContext } from './form-helpers';
3+
import { toDatetimeLocal, fromDatetimeLocal } from '../../utils/formatters';
34

45
export function useFormControl(name, type) {
56
const formState = useContext(FormContext);
@@ -44,7 +45,7 @@ function encode(value, type) {
4445
}
4546

4647
if (type === 'datetime-local') {
47-
return value && value.toISOString().slice(0, 16);
48+
return toDatetimeLocal(value);
4849
}
4950

5051
return value;
@@ -58,7 +59,7 @@ function getTargetValue(target) {
5859
}
5960

6061
if (target.type === 'datetime-local') {
61-
value = new Date(Date.parse(target.value));
62+
value = fromDatetimeLocal(target.value);
6263
}
6364

6465
if (target.type === 'select-one') {

src/utils/formatters.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { isISOString, isDate } from './types';
2+
3+
export function toDatetimeLocal(value) {
4+
let date = value;
5+
6+
if (isISOString(date)) {
7+
date = new Date(date);
8+
}
9+
10+
if (!isDate(date)) {
11+
throw new Error('toDatetimeLocal only accepts date objects and ISO date strings');
12+
}
13+
14+
const YYYY = date.getFullYear().toString();
15+
const MM = (date.getMonth() + 1).toString().padStart(2, '0');
16+
const DD = date.getDate().toString().padStart(2, '0');
17+
const hh = date.getHours().toString().padStart(2, '0');
18+
const mm = date.getMinutes().toString().padStart(2, '0');
19+
20+
return `${YYYY}-${MM}-${DD}T${hh}:${mm}`;
21+
}
22+
23+
export function fromDatetimeLocal(value) {
24+
return new Date(Date.parse(value));
25+
}

src/utils/types.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export function isISOString(value) {
2+
if (!isString(value)) {
3+
return false;
4+
}
5+
6+
if (value.length !== 24) {
7+
return false;
8+
}
9+
10+
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value);
11+
}
12+
13+
export function isString(value) {
14+
return typeof value === 'string';
15+
}
16+
17+
export function isDate(value) {
18+
return Object.prototype.toString.call(value) === '[object Date]';
19+
}

0 commit comments

Comments
 (0)