@fieldia/calendar 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/package.json +4 -4
- package/src/lib/calendar-view.js +61 -22
- package/src/lib/calendar-view.js.map +1 -1
- package/src/lib/calendar-view.mjs +64 -25
- package/src/lib/calendar-view.mjs.map +1 -1
- package/src/lib/dates.d.mts +27 -8
- package/src/lib/dates.d.ts +27 -8
- package/src/lib/dates.js +63 -25
- package/src/lib/dates.js.map +1 -1
- package/src/lib/dates.mjs +57 -24
- package/src/lib/dates.mjs.map +1 -1
- package/src/lib/events.d.mts +5 -4
- package/src/lib/events.d.ts +5 -4
- package/src/lib/events.js +24 -10
- package/src/lib/events.js.map +1 -1
- package/src/lib/events.mjs +25 -11
- package/src/lib/events.mjs.map +1 -1
- package/src/lib/gestures.js +3 -3
- package/src/lib/gestures.js.map +1 -1
- package/src/lib/gestures.mjs +4 -4
- package/src/lib/gestures.mjs.map +1 -1
- package/src/lib/keys.js +2 -2
- package/src/lib/keys.js.map +1 -1
- package/src/lib/keys.mjs +3 -3
- package/src/lib/keys.mjs.map +1 -1
- package/src/lib/labels.d.mts +9 -0
- package/src/lib/labels.d.ts +9 -0
- package/src/lib/labels.js +24 -1
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +24 -1
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/move-to.js +3 -3
- package/src/lib/move-to.js.map +1 -1
- package/src/lib/move-to.mjs +4 -4
- package/src/lib/move-to.mjs.map +1 -1
- package/src/lib/styles.d.mts +1 -1
- package/src/lib/styles.d.ts +1 -1
- package/src/lib/styles.js +2 -0
- package/src/lib/styles.js.map +1 -1
- package/src/lib/styles.mjs +2 -0
- package/src/lib/styles.mjs.map +1 -1
package/src/lib/dates.js
CHANGED
|
@@ -1,42 +1,79 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.format = exports.intlTag = exports.startOfWeek = exports.writeWhen = exports.daysBetween = exports.atMinutes = exports.minutesOf = exports.sameDay = exports.addMinutes = exports.addDays = exports.startOfDay = exports.dayKey = void 0;
|
|
3
|
+
exports.format = exports.intlTag = exports.startOfWeek = exports.writeWhen = exports.daysBetween = exports.atMinutes = exports.weekdayOf = exports.minutesOf = exports.sameDay = exports.addMinutes = exports.addDays = exports.startOfDay = exports.dayOn = exports.dayKey = void 0;
|
|
4
|
+
exports.zoneOfCalendar = zoneOfCalendar;
|
|
5
|
+
exports.toWall = toWall;
|
|
6
|
+
exports.fromWall = fromWall;
|
|
4
7
|
exports.readWhen = readWhen;
|
|
5
8
|
exports.readDay = readDay;
|
|
6
9
|
exports.firstDayOf = firstDayOf;
|
|
7
10
|
exports.rangeOf = rangeOf;
|
|
8
11
|
exports.stepFrom = stepFrom;
|
|
9
|
-
const
|
|
12
|
+
const core_1 = require("@fieldia/core");
|
|
13
|
+
const MINUTE = 60000;
|
|
14
|
+
const DAY = 86400000;
|
|
15
|
+
const pad = (n, width = 2) => String(n).padStart(width, '0');
|
|
16
|
+
/**
|
|
17
|
+
* The zone a calendar is on the clock of, by its IANA name: its start's own, when a date and time names one; else its
|
|
18
|
+
* page's; undefined for the reader's own — as a date and time field's box is (`zoneOf` in @fieldia/widgets).
|
|
19
|
+
*/
|
|
20
|
+
function zoneOfCalendar(page, spec) {
|
|
21
|
+
const field = page.fields[spec.start];
|
|
22
|
+
return (field?.type === 'datetime' ? field.timeZone : undefined) ?? page.timeZone;
|
|
23
|
+
}
|
|
24
|
+
/** An instant as a time on the zone's clock: its day and time in the Date's UTC fields, its seconds kept. */
|
|
25
|
+
function toWall(at, zone) {
|
|
26
|
+
const ms = typeof at === 'number' ? at : at.getTime();
|
|
27
|
+
const wall = (0, core_1.wallTime)(ms, zone);
|
|
28
|
+
return new Date(Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute) + (((ms % MINUTE) + MINUTE) % MINUTE));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A time on the zone's clock as the instant it is: the earlier of the two in the hour the clocks repeat; in the hour
|
|
32
|
+
* they skip, as far past the change as it is past the hour it skips from (02:30 is 03:30), as a clock's own day reads it.
|
|
33
|
+
*/
|
|
34
|
+
function fromWall(d, zone) {
|
|
35
|
+
const wall = { year: d.getUTCFullYear(), month: d.getUTCMonth() + 1, day: d.getUTCDate(), hour: d.getUTCHours(), minute: d.getUTCMinutes() };
|
|
36
|
+
const seconds = d.getTime() - Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute);
|
|
37
|
+
const found = (0, core_1.instantsAt)(wall, zone);
|
|
38
|
+
const local = Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute);
|
|
39
|
+
return (found.length ? found[0] : local - (0, core_1.zoneOffset)(local - DAY, zone) * MINUTE) + seconds;
|
|
40
|
+
}
|
|
10
41
|
/** A day's key, as a date field keeps it: "2026-10-14". */
|
|
11
|
-
const dayKey = (d) => `${d.
|
|
42
|
+
const dayKey = (d) => `${pad(d.getUTCFullYear(), 4)}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}`;
|
|
12
43
|
exports.dayKey = dayKey;
|
|
13
|
-
|
|
44
|
+
/** A day on the clock: its year, its month (0 to 11) and its day, at midnight; a day past a month's end is the next month's. */
|
|
45
|
+
const dayOn = (year, month, day, minutes = 0) => new Date(Date.UTC(year, month, day, Math.floor(minutes / 60), minutes % 60));
|
|
46
|
+
exports.dayOn = dayOn;
|
|
47
|
+
const startOfDay = (d) => (0, exports.dayOn)(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
|
14
48
|
exports.startOfDay = startOfDay;
|
|
15
|
-
const addDays = (d, n) => new Date(d.
|
|
49
|
+
const addDays = (d, n) => new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() + n, d.getUTCHours(), d.getUTCMinutes()));
|
|
16
50
|
exports.addDays = addDays;
|
|
17
|
-
const addMinutes = (d, n) => new Date(d.getTime() + n *
|
|
51
|
+
const addMinutes = (d, n) => new Date(d.getTime() + n * MINUTE);
|
|
18
52
|
exports.addMinutes = addMinutes;
|
|
19
53
|
const sameDay = (a, b) => (0, exports.dayKey)(a) === (0, exports.dayKey)(b);
|
|
20
54
|
exports.sameDay = sameDay;
|
|
21
55
|
/** Minutes since the day's midnight. */
|
|
22
|
-
const minutesOf = (d) => d.
|
|
56
|
+
const minutesOf = (d) => d.getUTCHours() * 60 + d.getUTCMinutes();
|
|
23
57
|
exports.minutesOf = minutesOf;
|
|
58
|
+
/** The day of the week: 0 Sunday to 6 Saturday. */
|
|
59
|
+
const weekdayOf = (d) => d.getUTCDay();
|
|
60
|
+
exports.weekdayOf = weekdayOf;
|
|
24
61
|
/** The moment `minutes` after a day's midnight, by the clock on the wall. */
|
|
25
|
-
const atMinutes = (day, minutes) =>
|
|
62
|
+
const atMinutes = (day, minutes) => (0, exports.dayOn)(day.getUTCFullYear(), day.getUTCMonth(), day.getUTCDate(), minutes);
|
|
26
63
|
exports.atMinutes = atMinutes;
|
|
27
64
|
/** Whole days from one day to another, by the calendar. */
|
|
28
|
-
const daysBetween = (from, to) => Math.round((
|
|
65
|
+
const daysBetween = (from, to) => Math.round(((0, exports.startOfDay)(to).getTime() - (0, exports.startOfDay)(from).getTime()) / DAY);
|
|
29
66
|
exports.daysBetween = daysBetween;
|
|
30
|
-
/** A field's value as a moment: a date at its midnight, a date and time as it holds. Null when it holds none. */
|
|
31
|
-
function readWhen(value, kind) {
|
|
67
|
+
/** A field's value as a moment on the zone's clock: a date at its midnight, a date and time as it holds. Null when it holds none. */
|
|
68
|
+
function readWhen(value, kind, zone) {
|
|
32
69
|
if (typeof value !== 'string' || !value)
|
|
33
70
|
return null;
|
|
34
71
|
if (kind === 'date') {
|
|
35
72
|
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
|
|
36
|
-
return m ?
|
|
73
|
+
return m ? (0, exports.dayOn)(Number(m[1]), Number(m[2]) - 1, Number(m[3])) : null;
|
|
37
74
|
}
|
|
38
|
-
const
|
|
39
|
-
return Number.isNaN(
|
|
75
|
+
const at = new Date(value).getTime();
|
|
76
|
+
return Number.isNaN(at) ? null : toWall(at, zone);
|
|
40
77
|
}
|
|
41
78
|
/**
|
|
42
79
|
* A day as a date input writes it, "2026-10-14", at its midnight: null for one that is no day ("2026-02-30", "", a
|
|
@@ -47,12 +84,12 @@ function readDay(text) {
|
|
|
47
84
|
if (!m)
|
|
48
85
|
return null;
|
|
49
86
|
const [y, mo, d] = [Number(m[1]), Number(m[2]) - 1, Number(m[3])];
|
|
50
|
-
const day = new Date(
|
|
51
|
-
day.
|
|
52
|
-
return day.
|
|
87
|
+
const day = new Date(0);
|
|
88
|
+
day.setUTCFullYear(y, mo, d);
|
|
89
|
+
return day.getUTCFullYear() === y && day.getUTCMonth() === mo && day.getUTCDate() === d ? day : null;
|
|
53
90
|
}
|
|
54
|
-
/** A moment as its field keeps it: a date's day, or a date and time as the date widgets write one
|
|
55
|
-
const writeWhen = (d, kind) => (kind === 'date' ? (0, exports.dayKey)(d) : d.toISOString());
|
|
91
|
+
/** A moment as its field keeps it: a date's day, or a date and time as the date widgets write one — the instant it is on the zone's clock, in UTC. */
|
|
92
|
+
const writeWhen = (d, kind, zone) => (kind === 'date' ? (0, exports.dayKey)(d) : new Date(fromWall(d, zone)).toISOString());
|
|
56
93
|
exports.writeWhen = writeWhen;
|
|
57
94
|
/** The week's first day by language: Saturday in Arabic (as Egypt's week runs), Monday elsewhere, as Fieldia's date picker has it. */
|
|
58
95
|
function firstDayOf(locale, own) {
|
|
@@ -60,7 +97,7 @@ function firstDayOf(locale, own) {
|
|
|
60
97
|
return own;
|
|
61
98
|
return locale === 'ar' ? 6 : 1;
|
|
62
99
|
}
|
|
63
|
-
const startOfWeek = (d, firstDay) => (0, exports.addDays)((0, exports.startOfDay)(d), -((
|
|
100
|
+
const startOfWeek = (d, firstDay) => (0, exports.addDays)((0, exports.startOfDay)(d), -(((0, exports.weekdayOf)(d) - firstDay + 7) % 7));
|
|
64
101
|
exports.startOfWeek = startOfWeek;
|
|
65
102
|
function rangeOf(view, anchor, firstDay) {
|
|
66
103
|
let from;
|
|
@@ -72,8 +109,8 @@ function rangeOf(view, anchor, firstDay) {
|
|
|
72
109
|
}
|
|
73
110
|
else if (view === 'month') {
|
|
74
111
|
// Whole weeks round the month: from the week of its first day to the week of its last.
|
|
75
|
-
from = (0, exports.startOfWeek)(
|
|
76
|
-
const last =
|
|
112
|
+
from = (0, exports.startOfWeek)((0, exports.dayOn)(anchor.getUTCFullYear(), anchor.getUTCMonth(), 1), firstDay);
|
|
113
|
+
const last = (0, exports.dayOn)(anchor.getUTCFullYear(), anchor.getUTCMonth() + 1, 0);
|
|
77
114
|
count = (0, exports.daysBetween)(from, (0, exports.startOfWeek)(last, firstDay)) + 7;
|
|
78
115
|
}
|
|
79
116
|
else {
|
|
@@ -89,12 +126,13 @@ function stepFrom(view, anchor, by) {
|
|
|
89
126
|
return (0, exports.addDays)(anchor, by);
|
|
90
127
|
if (view !== 'month')
|
|
91
128
|
return (0, exports.addDays)(anchor, 7 * by);
|
|
92
|
-
const last =
|
|
93
|
-
return
|
|
129
|
+
const last = (0, exports.dayOn)(anchor.getUTCFullYear(), anchor.getUTCMonth() + by + 1, 0).getUTCDate();
|
|
130
|
+
return (0, exports.dayOn)(anchor.getUTCFullYear(), anchor.getUTCMonth() + by, Math.min(anchor.getUTCDate(), last));
|
|
94
131
|
}
|
|
95
132
|
/** The language as Intl reads it: British English's day before month, every language's digits Latin, as Fieldia writes dates. */
|
|
96
133
|
const intlTag = (locale) => (locale === 'en' ? 'en-GB' : locale);
|
|
97
134
|
exports.intlTag = intlTag;
|
|
98
|
-
|
|
135
|
+
/** A moment on the calendar's clock in words: its UTC fields, which are that clock's day and time. */
|
|
136
|
+
const format = (locale, options) => new Intl.DateTimeFormat((0, exports.intlTag)(locale), { numberingSystem: 'latn', ...options, timeZone: 'UTC' });
|
|
99
137
|
exports.format = format;
|
|
100
138
|
//# sourceMappingURL=dates.js.map
|
package/src/lib/dates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/dates.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/dates.ts"],"names":[],"mappings":"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"}
|
package/src/lib/dates.mjs
CHANGED
|
@@ -1,26 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
import { instantsAt, wallTime, zoneOffset } from '@fieldia/core';
|
|
2
|
+
const MINUTE = 60000;
|
|
3
|
+
const DAY = 86400000;
|
|
4
|
+
const pad = (n, width = 2) => String(n).padStart(width, '0');
|
|
5
|
+
/**
|
|
6
|
+
* The zone a calendar is on the clock of, by its IANA name: its start's own, when a date and time names one; else its
|
|
7
|
+
* page's; undefined for the reader's own — as a date and time field's box is (`zoneOf` in @fieldia/widgets).
|
|
8
|
+
*/
|
|
9
|
+
export function zoneOfCalendar(page, spec) {
|
|
10
|
+
const field = page.fields[spec.start];
|
|
11
|
+
return (field?.type === 'datetime' ? field.timeZone : undefined) ?? page.timeZone;
|
|
12
|
+
}
|
|
13
|
+
/** An instant as a time on the zone's clock: its day and time in the Date's UTC fields, its seconds kept. */
|
|
14
|
+
export function toWall(at, zone) {
|
|
15
|
+
const ms = typeof at === 'number' ? at : at.getTime();
|
|
16
|
+
const wall = wallTime(ms, zone);
|
|
17
|
+
return new Date(Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute) + (((ms % MINUTE) + MINUTE) % MINUTE));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A time on the zone's clock as the instant it is: the earlier of the two in the hour the clocks repeat; in the hour
|
|
21
|
+
* they skip, as far past the change as it is past the hour it skips from (02:30 is 03:30), as a clock's own day reads it.
|
|
22
|
+
*/
|
|
23
|
+
export function fromWall(d, zone) {
|
|
24
|
+
const wall = { year: d.getUTCFullYear(), month: d.getUTCMonth() + 1, day: d.getUTCDate(), hour: d.getUTCHours(), minute: d.getUTCMinutes() };
|
|
25
|
+
const seconds = d.getTime() - Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute);
|
|
26
|
+
const found = instantsAt(wall, zone);
|
|
27
|
+
const local = Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute);
|
|
28
|
+
return (found.length ? found[0] : local - zoneOffset(local - DAY, zone) * MINUTE) + seconds;
|
|
29
|
+
}
|
|
2
30
|
/** A day's key, as a date field keeps it: "2026-10-14". */
|
|
3
|
-
export const dayKey = (d) => `${d.
|
|
4
|
-
|
|
5
|
-
export const
|
|
6
|
-
export const
|
|
31
|
+
export const dayKey = (d) => `${pad(d.getUTCFullYear(), 4)}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}`;
|
|
32
|
+
/** A day on the clock: its year, its month (0 to 11) and its day, at midnight; a day past a month's end is the next month's. */
|
|
33
|
+
export const dayOn = (year, month, day, minutes = 0) => new Date(Date.UTC(year, month, day, Math.floor(minutes / 60), minutes % 60));
|
|
34
|
+
export const startOfDay = (d) => dayOn(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
|
35
|
+
export const addDays = (d, n) => new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() + n, d.getUTCHours(), d.getUTCMinutes()));
|
|
36
|
+
export const addMinutes = (d, n) => new Date(d.getTime() + n * MINUTE);
|
|
7
37
|
export const sameDay = (a, b) => dayKey(a) === dayKey(b);
|
|
8
38
|
/** Minutes since the day's midnight. */
|
|
9
|
-
export const minutesOf = (d) => d.
|
|
39
|
+
export const minutesOf = (d) => d.getUTCHours() * 60 + d.getUTCMinutes();
|
|
40
|
+
/** The day of the week: 0 Sunday to 6 Saturday. */
|
|
41
|
+
export const weekdayOf = (d) => d.getUTCDay();
|
|
10
42
|
/** The moment `minutes` after a day's midnight, by the clock on the wall. */
|
|
11
|
-
export const atMinutes = (day, minutes) =>
|
|
43
|
+
export const atMinutes = (day, minutes) => dayOn(day.getUTCFullYear(), day.getUTCMonth(), day.getUTCDate(), minutes);
|
|
12
44
|
/** Whole days from one day to another, by the calendar. */
|
|
13
|
-
export const daysBetween = (from, to) => Math.round((
|
|
14
|
-
/** A field's value as a moment: a date at its midnight, a date and time as it holds. Null when it holds none. */
|
|
15
|
-
export function readWhen(value, kind) {
|
|
45
|
+
export const daysBetween = (from, to) => Math.round((startOfDay(to).getTime() - startOfDay(from).getTime()) / DAY);
|
|
46
|
+
/** A field's value as a moment on the zone's clock: a date at its midnight, a date and time as it holds. Null when it holds none. */
|
|
47
|
+
export function readWhen(value, kind, zone) {
|
|
16
48
|
if (typeof value !== 'string' || !value)
|
|
17
49
|
return null;
|
|
18
50
|
if (kind === 'date') {
|
|
19
51
|
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
|
|
20
|
-
return m ?
|
|
52
|
+
return m ? dayOn(Number(m[1]), Number(m[2]) - 1, Number(m[3])) : null;
|
|
21
53
|
}
|
|
22
|
-
const
|
|
23
|
-
return Number.isNaN(
|
|
54
|
+
const at = new Date(value).getTime();
|
|
55
|
+
return Number.isNaN(at) ? null : toWall(at, zone);
|
|
24
56
|
}
|
|
25
57
|
/**
|
|
26
58
|
* A day as a date input writes it, "2026-10-14", at its midnight: null for one that is no day ("2026-02-30", "", a
|
|
@@ -31,19 +63,19 @@ export function readDay(text) {
|
|
|
31
63
|
if (!m)
|
|
32
64
|
return null;
|
|
33
65
|
const [y, mo, d] = [Number(m[1]), Number(m[2]) - 1, Number(m[3])];
|
|
34
|
-
const day = new Date(
|
|
35
|
-
day.
|
|
36
|
-
return day.
|
|
66
|
+
const day = new Date(0);
|
|
67
|
+
day.setUTCFullYear(y, mo, d);
|
|
68
|
+
return day.getUTCFullYear() === y && day.getUTCMonth() === mo && day.getUTCDate() === d ? day : null;
|
|
37
69
|
}
|
|
38
|
-
/** A moment as its field keeps it: a date's day, or a date and time as the date widgets write one
|
|
39
|
-
export const writeWhen = (d, kind) => (kind === 'date' ? dayKey(d) : d.toISOString());
|
|
70
|
+
/** A moment as its field keeps it: a date's day, or a date and time as the date widgets write one — the instant it is on the zone's clock, in UTC. */
|
|
71
|
+
export const writeWhen = (d, kind, zone) => (kind === 'date' ? dayKey(d) : new Date(fromWall(d, zone)).toISOString());
|
|
40
72
|
/** The week's first day by language: Saturday in Arabic (as Egypt's week runs), Monday elsewhere, as Fieldia's date picker has it. */
|
|
41
73
|
export function firstDayOf(locale, own) {
|
|
42
74
|
if (own !== undefined)
|
|
43
75
|
return own;
|
|
44
76
|
return locale === 'ar' ? 6 : 1;
|
|
45
77
|
}
|
|
46
|
-
export const startOfWeek = (d, firstDay) => addDays(startOfDay(d), -((d
|
|
78
|
+
export const startOfWeek = (d, firstDay) => addDays(startOfDay(d), -((weekdayOf(d) - firstDay + 7) % 7));
|
|
47
79
|
export function rangeOf(view, anchor, firstDay) {
|
|
48
80
|
let from;
|
|
49
81
|
let count;
|
|
@@ -54,8 +86,8 @@ export function rangeOf(view, anchor, firstDay) {
|
|
|
54
86
|
}
|
|
55
87
|
else if (view === 'month') {
|
|
56
88
|
// Whole weeks round the month: from the week of its first day to the week of its last.
|
|
57
|
-
from = startOfWeek(
|
|
58
|
-
const last =
|
|
89
|
+
from = startOfWeek(dayOn(anchor.getUTCFullYear(), anchor.getUTCMonth(), 1), firstDay);
|
|
90
|
+
const last = dayOn(anchor.getUTCFullYear(), anchor.getUTCMonth() + 1, 0);
|
|
59
91
|
count = daysBetween(from, startOfWeek(last, firstDay)) + 7;
|
|
60
92
|
}
|
|
61
93
|
else {
|
|
@@ -71,10 +103,11 @@ export function stepFrom(view, anchor, by) {
|
|
|
71
103
|
return addDays(anchor, by);
|
|
72
104
|
if (view !== 'month')
|
|
73
105
|
return addDays(anchor, 7 * by);
|
|
74
|
-
const last =
|
|
75
|
-
return
|
|
106
|
+
const last = dayOn(anchor.getUTCFullYear(), anchor.getUTCMonth() + by + 1, 0).getUTCDate();
|
|
107
|
+
return dayOn(anchor.getUTCFullYear(), anchor.getUTCMonth() + by, Math.min(anchor.getUTCDate(), last));
|
|
76
108
|
}
|
|
77
109
|
/** The language as Intl reads it: British English's day before month, every language's digits Latin, as Fieldia writes dates. */
|
|
78
110
|
export const intlTag = (locale) => (locale === 'en' ? 'en-GB' : locale);
|
|
79
|
-
|
|
111
|
+
/** A moment on the calendar's clock in words: its UTC fields, which are that clock's day and time. */
|
|
112
|
+
export const format = (locale, options) => new Intl.DateTimeFormat(intlTag(locale), { numberingSystem: 'latn', ...options, timeZone: 'UTC' });
|
|
80
113
|
//# sourceMappingURL=dates.mjs.map
|
package/src/lib/dates.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dates.mjs","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/dates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dates.mjs","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/dates.ts"],"names":[],"mappings":"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"}
|
package/src/lib/events.d.mts
CHANGED
|
@@ -6,8 +6,9 @@ export interface CalendarEvent {
|
|
|
6
6
|
/** The record as the list gave it: its values, its version, what may be done with it. */
|
|
7
7
|
record: ListedRecord;
|
|
8
8
|
title: string;
|
|
9
|
+
/** When it starts, on the calendar's clock (dates.ts). */
|
|
9
10
|
start: Date;
|
|
10
|
-
/** The moment it ends: past its last moment, so a day's event ends at the next midnight. */
|
|
11
|
+
/** The moment it ends, on that clock: past its last moment, so a day's event ends at the next midnight. */
|
|
11
12
|
end: Date;
|
|
12
13
|
/** Drawn with the days rather than the hours: a date, or a day and time across whole days. */
|
|
13
14
|
allDay: boolean;
|
|
@@ -47,9 +48,9 @@ export interface Resource {
|
|
|
47
48
|
key: string;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
|
-
* The values a move writes: its start where it lands (its length kept
|
|
51
|
-
* its end alone when stretched (`end`), and its person when it lands in
|
|
52
|
-
*
|
|
51
|
+
* The values a move writes: its start where it lands (its length kept — the time it really lasts, across a change of
|
|
52
|
+
* the clocks too), or its end alone when stretched (`end`), and its person when it lands in another's column. Each
|
|
53
|
+
* moment on the calendar's clock is written as the instant it is there.
|
|
53
54
|
*/
|
|
54
55
|
export declare function moved(event: CalendarEvent, start: Date, spec: ListCalendar, page: Page, resource?: Resource, end?: Date): Values;
|
|
55
56
|
/** Where a move lands, in words: "Wed 14 Oct, 11:15", or the day alone for a whole day's; its year too, when it leaves the record's own. */
|
package/src/lib/events.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ export interface CalendarEvent {
|
|
|
6
6
|
/** The record as the list gave it: its values, its version, what may be done with it. */
|
|
7
7
|
record: ListedRecord;
|
|
8
8
|
title: string;
|
|
9
|
+
/** When it starts, on the calendar's clock (dates.ts). */
|
|
9
10
|
start: Date;
|
|
10
|
-
/** The moment it ends: past its last moment, so a day's event ends at the next midnight. */
|
|
11
|
+
/** The moment it ends, on that clock: past its last moment, so a day's event ends at the next midnight. */
|
|
11
12
|
end: Date;
|
|
12
13
|
/** Drawn with the days rather than the hours: a date, or a day and time across whole days. */
|
|
13
14
|
allDay: boolean;
|
|
@@ -47,9 +48,9 @@ export interface Resource {
|
|
|
47
48
|
key: string;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
|
-
* The values a move writes: its start where it lands (its length kept
|
|
51
|
-
* its end alone when stretched (`end`), and its person when it lands in
|
|
52
|
-
*
|
|
51
|
+
* The values a move writes: its start where it lands (its length kept — the time it really lasts, across a change of
|
|
52
|
+
* the clocks too), or its end alone when stretched (`end`), and its person when it lands in another's column. Each
|
|
53
|
+
* moment on the calendar's clock is written as the instant it is there.
|
|
53
54
|
*/
|
|
54
55
|
export declare function moved(event: CalendarEvent, start: Date, spec: ListCalendar, page: Page, resource?: Resource, end?: Date): Values;
|
|
55
56
|
/** Where a move lands, in words: "Wed 14 Oct, 11:15", or the day alone for a whole day's; its year too, when it leaves the record's own. */
|
package/src/lib/events.js
CHANGED
|
@@ -24,14 +24,15 @@ exports.kindOf = kindOf;
|
|
|
24
24
|
/** Each record with a start as an event: an hour long with no end (or an end before its start), a whole day for a date. */
|
|
25
25
|
function eventsOf(records, spec, page, locale) {
|
|
26
26
|
const kind = (0, exports.kindOf)(page, spec);
|
|
27
|
+
const zone = (0, dates_1.zoneOfCalendar)(page, spec);
|
|
27
28
|
const say = (name, values) => (name && page.fields[name] ? (0, widgets_1.displayValue)(page.fields[name], values[name], values, locale) : '');
|
|
28
29
|
const events = [];
|
|
29
30
|
for (const record of records) {
|
|
30
31
|
const values = record.values;
|
|
31
|
-
const start = (0, dates_1.readWhen)(values[spec.start], kind);
|
|
32
|
+
const start = (0, dates_1.readWhen)(values[spec.start], kind, zone);
|
|
32
33
|
if (!start)
|
|
33
34
|
continue;
|
|
34
|
-
const given = spec.end ? (0, dates_1.readWhen)(values[spec.end], kind) : null;
|
|
35
|
+
const given = spec.end ? (0, dates_1.readWhen)(values[spec.end], kind, zone) : null;
|
|
35
36
|
let end;
|
|
36
37
|
if (kind === 'date')
|
|
37
38
|
end = (0, dates_1.addDays)(given && given >= start ? given : start, 1);
|
|
@@ -101,32 +102,45 @@ function sideBySide(events) {
|
|
|
101
102
|
return placed;
|
|
102
103
|
}
|
|
103
104
|
/**
|
|
104
|
-
* The values a move writes: its start where it lands (its length kept
|
|
105
|
-
* its end alone when stretched (`end`), and its person when it lands in
|
|
106
|
-
*
|
|
105
|
+
* The values a move writes: its start where it lands (its length kept — the time it really lasts, across a change of
|
|
106
|
+
* the clocks too), or its end alone when stretched (`end`), and its person when it lands in another's column. Each
|
|
107
|
+
* moment on the calendar's clock is written as the instant it is there.
|
|
107
108
|
*/
|
|
108
109
|
function moved(event, start, spec, page, resource, end) {
|
|
109
110
|
const kind = (0, exports.kindOf)(page, spec);
|
|
111
|
+
const zone = (0, dates_1.zoneOfCalendar)(page, spec);
|
|
110
112
|
const values = {};
|
|
111
113
|
if (end) {
|
|
112
114
|
if (spec.end)
|
|
113
|
-
values[spec.end] = (0, dates_1.writeWhen)(kind === 'date' ? (0, dates_1.addDays)((0, dates_1.startOfDay)(end), -1) : end, kind);
|
|
115
|
+
values[spec.end] = (0, dates_1.writeWhen)(kind === 'date' ? (0, dates_1.addDays)((0, dates_1.startOfDay)(end), -1) : end, kind, zone);
|
|
114
116
|
return values;
|
|
115
117
|
}
|
|
116
118
|
if (start.getTime() !== event.start.getTime()) {
|
|
117
|
-
values[spec.start] = (0, dates_1.writeWhen)(start, kind);
|
|
119
|
+
values[spec.start] = (0, dates_1.writeWhen)(start, kind, zone);
|
|
118
120
|
if (spec.end) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
if (kind === 'date')
|
|
122
|
+
values[spec.end] = (0, dates_1.writeWhen)((0, dates_1.addDays)(start, (0, dates_1.daysBetween)(event.start, event.end) - 1), kind, zone);
|
|
123
|
+
else
|
|
124
|
+
values[spec.end] = new Date((0, dates_1.fromWall)(start, zone) + lasts(event, spec, zone)).toISOString();
|
|
121
125
|
}
|
|
122
126
|
}
|
|
123
127
|
if (resource && spec.resource && resource.key !== event.resource)
|
|
124
128
|
values[spec.resource] = resource.value;
|
|
125
129
|
return values;
|
|
126
130
|
}
|
|
131
|
+
/** How long a record lasts, in ms: from its own start to its own end as kept, else as the calendar draws it (an hour). */
|
|
132
|
+
function lasts(event, spec, zone) {
|
|
133
|
+
const kept = (name) => {
|
|
134
|
+
const value = name ? event.record.values[name] : undefined;
|
|
135
|
+
const at = typeof value === 'string' && value ? new Date(value).getTime() : NaN;
|
|
136
|
+
return Number.isNaN(at) ? null : at;
|
|
137
|
+
};
|
|
138
|
+
const [from, to] = [kept(spec.start), kept(spec.end)];
|
|
139
|
+
return from !== null && to !== null && to > from ? to - from : (0, dates_1.fromWall)(event.end, zone) - (0, dates_1.fromWall)(event.start, zone);
|
|
140
|
+
}
|
|
127
141
|
/** Where a move lands, in words: "Wed 14 Oct, 11:15", or the day alone for a whole day's; its year too, when it leaves the record's own. */
|
|
128
142
|
function whereTo(event, start, locale) {
|
|
129
|
-
const day = (0, dates_1.format)(locale, { weekday: 'short', day: 'numeric', month: 'short', ...(start.
|
|
143
|
+
const day = (0, dates_1.format)(locale, { weekday: 'short', day: 'numeric', month: 'short', ...(start.getUTCFullYear() !== event.start.getUTCFullYear() ? { year: 'numeric' } : {}) }).format(start);
|
|
130
144
|
return event.allDay ? day : `${day}${comma(locale)}${(0, dates_1.format)(locale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(start)}`;
|
|
131
145
|
}
|
|
132
146
|
/** What joins the parts of a sentence as the language writes it: ", ", or in Arabic its own comma, "، ". */
|
package/src/lib/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/events.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../../libs/calendar/src/lib/events.ts"],"names":[],"mappings":"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"}
|
package/src/lib/events.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { displayValue } from '@fieldia/widgets';
|
|
2
|
-
import { addDays, addMinutes, daysBetween, format, minutesOf, readWhen, startOfDay, writeWhen } from './dates.mjs';
|
|
2
|
+
import { addDays, addMinutes, daysBetween, format, fromWall, minutesOf, readWhen, startOfDay, writeWhen, zoneOfCalendar } from './dates.mjs';
|
|
3
3
|
/** A link's id, or a value as it is, as a key. */
|
|
4
4
|
export function keyOf(value) {
|
|
5
5
|
if (value === null || value === undefined || value === '' || value === false)
|
|
@@ -13,14 +13,15 @@ export const kindOf = (page, spec) => (page.fields[spec.start]?.type === 'date'
|
|
|
13
13
|
/** Each record with a start as an event: an hour long with no end (or an end before its start), a whole day for a date. */
|
|
14
14
|
export function eventsOf(records, spec, page, locale) {
|
|
15
15
|
const kind = kindOf(page, spec);
|
|
16
|
+
const zone = zoneOfCalendar(page, spec);
|
|
16
17
|
const say = (name, values) => (name && page.fields[name] ? displayValue(page.fields[name], values[name], values, locale) : '');
|
|
17
18
|
const events = [];
|
|
18
19
|
for (const record of records) {
|
|
19
20
|
const values = record.values;
|
|
20
|
-
const start = readWhen(values[spec.start], kind);
|
|
21
|
+
const start = readWhen(values[spec.start], kind, zone);
|
|
21
22
|
if (!start)
|
|
22
23
|
continue;
|
|
23
|
-
const given = spec.end ? readWhen(values[spec.end], kind) : null;
|
|
24
|
+
const given = spec.end ? readWhen(values[spec.end], kind, zone) : null;
|
|
24
25
|
let end;
|
|
25
26
|
if (kind === 'date')
|
|
26
27
|
end = addDays(given && given >= start ? given : start, 1);
|
|
@@ -90,32 +91,45 @@ export function sideBySide(events) {
|
|
|
90
91
|
return placed;
|
|
91
92
|
}
|
|
92
93
|
/**
|
|
93
|
-
* The values a move writes: its start where it lands (its length kept
|
|
94
|
-
* its end alone when stretched (`end`), and its person when it lands in
|
|
95
|
-
*
|
|
94
|
+
* The values a move writes: its start where it lands (its length kept — the time it really lasts, across a change of
|
|
95
|
+
* the clocks too), or its end alone when stretched (`end`), and its person when it lands in another's column. Each
|
|
96
|
+
* moment on the calendar's clock is written as the instant it is there.
|
|
96
97
|
*/
|
|
97
98
|
export function moved(event, start, spec, page, resource, end) {
|
|
98
99
|
const kind = kindOf(page, spec);
|
|
100
|
+
const zone = zoneOfCalendar(page, spec);
|
|
99
101
|
const values = {};
|
|
100
102
|
if (end) {
|
|
101
103
|
if (spec.end)
|
|
102
|
-
values[spec.end] = writeWhen(kind === 'date' ? addDays(startOfDay(end), -1) : end, kind);
|
|
104
|
+
values[spec.end] = writeWhen(kind === 'date' ? addDays(startOfDay(end), -1) : end, kind, zone);
|
|
103
105
|
return values;
|
|
104
106
|
}
|
|
105
107
|
if (start.getTime() !== event.start.getTime()) {
|
|
106
|
-
values[spec.start] = writeWhen(start, kind);
|
|
108
|
+
values[spec.start] = writeWhen(start, kind, zone);
|
|
107
109
|
if (spec.end) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
if (kind === 'date')
|
|
111
|
+
values[spec.end] = writeWhen(addDays(start, daysBetween(event.start, event.end) - 1), kind, zone);
|
|
112
|
+
else
|
|
113
|
+
values[spec.end] = new Date(fromWall(start, zone) + lasts(event, spec, zone)).toISOString();
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
if (resource && spec.resource && resource.key !== event.resource)
|
|
113
117
|
values[spec.resource] = resource.value;
|
|
114
118
|
return values;
|
|
115
119
|
}
|
|
120
|
+
/** How long a record lasts, in ms: from its own start to its own end as kept, else as the calendar draws it (an hour). */
|
|
121
|
+
function lasts(event, spec, zone) {
|
|
122
|
+
const kept = (name) => {
|
|
123
|
+
const value = name ? event.record.values[name] : undefined;
|
|
124
|
+
const at = typeof value === 'string' && value ? new Date(value).getTime() : NaN;
|
|
125
|
+
return Number.isNaN(at) ? null : at;
|
|
126
|
+
};
|
|
127
|
+
const [from, to] = [kept(spec.start), kept(spec.end)];
|
|
128
|
+
return from !== null && to !== null && to > from ? to - from : fromWall(event.end, zone) - fromWall(event.start, zone);
|
|
129
|
+
}
|
|
116
130
|
/** Where a move lands, in words: "Wed 14 Oct, 11:15", or the day alone for a whole day's; its year too, when it leaves the record's own. */
|
|
117
131
|
export function whereTo(event, start, locale) {
|
|
118
|
-
const day = format(locale, { weekday: 'short', day: 'numeric', month: 'short', ...(start.
|
|
132
|
+
const day = format(locale, { weekday: 'short', day: 'numeric', month: 'short', ...(start.getUTCFullYear() !== event.start.getUTCFullYear() ? { year: 'numeric' } : {}) }).format(start);
|
|
119
133
|
return event.allDay ? day : `${day}${comma(locale)}${format(locale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(start)}`;
|
|
120
134
|
}
|
|
121
135
|
/** What joins the parts of a sentence as the language writes it: ", ", or in Arabic its own comma, "، ". */
|