-
Notifications
You must be signed in to change notification settings - Fork 34
/
date.js
79 lines (71 loc) · 2.3 KB
/
date.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import {html} from "htl";
import {parse as isoparse} from "isoformat";
import {maybeWidth} from "./css.js";
import {maybeLabel} from "./label.js";
import {createText} from "./text.js";
const dateops = {
type: "date",
get: (input) => input.valueAsDate,
set: (input, value) => input.value = formatDate(value),
same: (input, value) => +input.valueAsDate === +value,
format: formatDate
};
// datetime-local pedantically refuses to support valueAsDate, so here we use
// the Date constructor to convert the input based on the user’s local time zone
// (which you think would be implied by datetime-local)?
// https://github.com/whatwg/html/issues/4770
const datetimeops = {
type: "datetime-local",
get: (input) => input.value ? new Date(input.value) : null,
set: (input, value) => input.value = formatDatetime(value),
same: (input, value) => +new Date(input.value) === +value,
format: formatDatetime
};
function createDate({
label,
min,
max,
required,
readonly,
disabled,
width,
value,
...options
} = {}, {
type,
format,
...ops
}) {
const input = html`<input type=${type} name=date readonly=${readonly} disabled=${disabled} required=${required} min=${format(min)} max=${format(max)}>`;
const form = html`<form class=__ns__ style=${maybeWidth(width)}>
${maybeLabel(label, input)}<div class=__ns__-input>
${input}
</div>
</form>`;
return createText(form, input, coerce(value), options, ops);
}
export function date(options) {
return createDate(options, dateops);
}
export function datetime(options) {
return createDate(options, datetimeops);
}
function coerce(value) {
return value instanceof Date && !isNaN(value) ? value
: typeof value === "string" ? isoparse(value, null)
: value == null || isNaN(value = +value) ? null
: new Date(+value);
}
function formatDate(value) {
return (value = coerce(value))
? value.toISOString().slice(0, 10)
: value;
}
// The datetime-local input uses YYYY-MM-DDThh:mm like ISO 8601, but in local
// time rather than UTC, so we apply the offset before calling toISOString.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local
function formatDatetime(value) {
return (value = coerce(value))
? (new Date(+value - value.getTimezoneOffset() * 1000 * 60)).toISOString().slice(0, 16)
: value;
}