@event-calendar/core 1.1.1 → 1.2.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 +2 -2
- package/index.js +646 -8
- package/package.json +2 -3
- package/src/Auxiliary.svelte +1 -1
- package/src/Buttons.svelte +1 -1
- package/src/Calendar.svelte +1 -1
- package/src/index.js +2 -1
- package/src/lib/actions.js +43 -0
- package/src/lib/date.js +219 -0
- package/src/lib/debounce.js +10 -0
- package/src/lib/dom.js +53 -0
- package/src/lib/events.js +224 -0
- package/src/lib/stores.js +54 -0
- package/src/lib/utils.js +23 -0
- package/src/lib/view.js +24 -0
- package/src/lib.js +8 -0
- package/src/storage/options.js +1 -2
- package/src/storage/state.js +1 -2
- package/src/storage/stores.js +5 -5
package/src/Auxiliary.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
3
|
import {is_function} from 'svelte/internal';
|
|
4
|
-
import {debounce, toISOString, toLocalDate, toViewWithLocalDates} from '
|
|
4
|
+
import {debounce, toISOString, toLocalDate, toViewWithLocalDates} from './lib.js';
|
|
5
5
|
|
|
6
6
|
let {datesSet, _auxiliary, _activeRange, _queue, _view} = getContext('state');
|
|
7
7
|
|
package/src/Buttons.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {createDate, cloneDate, subtractDay, addDuration, subtractDuration, setMidnight} from '
|
|
3
|
+
import {createDate, cloneDate, subtractDay, addDuration, subtractDuration, setMidnight} from './lib.js';
|
|
4
4
|
|
|
5
5
|
export let buttons;
|
|
6
6
|
|
package/src/Calendar.svelte
CHANGED
package/src/index.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {isObject} from './utils.js';
|
|
2
|
+
|
|
3
|
+
export function setContent(node, content) {
|
|
4
|
+
let actions = {
|
|
5
|
+
update(content) {
|
|
6
|
+
while (node.firstChild) {
|
|
7
|
+
node.removeChild(node.lastChild);
|
|
8
|
+
}
|
|
9
|
+
if (!isObject(content)) {
|
|
10
|
+
node.innerText = content;
|
|
11
|
+
} else if (content.domNodes) {
|
|
12
|
+
for (let child of content.domNodes) {
|
|
13
|
+
node.appendChild(child);
|
|
14
|
+
}
|
|
15
|
+
} else if (content.html) {
|
|
16
|
+
node.innerHTML = content.html;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
actions.update(content);
|
|
21
|
+
|
|
22
|
+
return actions;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Dispatch event occurred outside of node */
|
|
26
|
+
export function outsideEvent(node, type) {
|
|
27
|
+
|
|
28
|
+
const handlePointerDown = jsEvent => {
|
|
29
|
+
if (node && !node.contains(jsEvent.target)) {
|
|
30
|
+
node.dispatchEvent(
|
|
31
|
+
new CustomEvent(type + 'outside', {detail: {jsEvent}})
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
document.addEventListener(type, handlePointerDown, true);
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
destroy() {
|
|
40
|
+
document.removeEventListener(type, handlePointerDown, true);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
package/src/lib/date.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
export const DAY_IN_SECONDS = 86400;
|
|
2
|
+
|
|
3
|
+
export function createDate(input = undefined) {
|
|
4
|
+
if (input !== undefined) {
|
|
5
|
+
return input instanceof Date ? _fromLocalDate(input) : _fromISOString(input);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return _fromLocalDate(new Date());
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createDuration(input) {
|
|
12
|
+
if (typeof input === 'number') {
|
|
13
|
+
input = {seconds: input};
|
|
14
|
+
} else if (typeof input === 'string') {
|
|
15
|
+
// Expected format hh[:mm[:ss]]
|
|
16
|
+
let seconds = 0, exp = 2;
|
|
17
|
+
for (let part of input.split(':', 3)) {
|
|
18
|
+
seconds += parseInt(part, 10) * Math.pow(60, exp--);
|
|
19
|
+
}
|
|
20
|
+
input = {seconds};
|
|
21
|
+
} else if (input instanceof Date) {
|
|
22
|
+
input = {hours: input.getUTCHours(), minutes: input.getUTCMinutes(), seconds: input.getUTCSeconds()};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let weeks = input.weeks || input.week || 0;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
years: input.years || input.year || 0,
|
|
29
|
+
months: input.months || input.month || 0,
|
|
30
|
+
days: weeks * 7 + (input.days || input.day || 0),
|
|
31
|
+
seconds: (input.hours || input.hour || 0) * 60 * 60 +
|
|
32
|
+
(input.minutes || input.minute || 0) * 60 +
|
|
33
|
+
(input.seconds || input.second || 0),
|
|
34
|
+
inWeeks: !!weeks
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function cloneDate(date) {
|
|
39
|
+
return new Date(date.getTime());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function addDuration(date, duration, x = 1) {
|
|
43
|
+
date.setUTCFullYear(date.getUTCFullYear() + x * duration.years);
|
|
44
|
+
let month = date.getUTCMonth() + x * duration.months;
|
|
45
|
+
date.setUTCMonth(month);
|
|
46
|
+
month %= 12;
|
|
47
|
+
if (month < 0) {
|
|
48
|
+
month += 12;
|
|
49
|
+
}
|
|
50
|
+
while (date.getUTCMonth() !== month) {
|
|
51
|
+
subtractDay(date);
|
|
52
|
+
}
|
|
53
|
+
date.setUTCDate(date.getUTCDate() + x * duration.days);
|
|
54
|
+
date.setUTCSeconds(date.getUTCSeconds() + x * duration.seconds);
|
|
55
|
+
|
|
56
|
+
return date;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function subtractDuration(date, duration, x = 1) {
|
|
60
|
+
return addDuration(date, duration, -x);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function addDay(date, x = 1) {
|
|
64
|
+
date.setUTCDate(date.getUTCDate() + x);
|
|
65
|
+
|
|
66
|
+
return date;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function subtractDay(date, x = 1) {
|
|
70
|
+
return addDay(date, -x);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function setMidnight(date) {
|
|
74
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
75
|
+
|
|
76
|
+
return date;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function toLocalDate(date) {
|
|
80
|
+
return new Date(
|
|
81
|
+
date.getUTCFullYear(),
|
|
82
|
+
date.getUTCMonth(),
|
|
83
|
+
date.getUTCDate(),
|
|
84
|
+
date.getUTCHours(),
|
|
85
|
+
date.getUTCMinutes(),
|
|
86
|
+
date.getUTCSeconds()
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function toISOString(date) {
|
|
91
|
+
return date.toISOString().substring(0, 19);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function formatRange(start, end, intl) {
|
|
95
|
+
if (start.getFullYear() !== end.getFullYear()) {
|
|
96
|
+
return intl.format(start) + ' - ' + intl.format(end);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let diff = [];
|
|
100
|
+
if (start.getMonth() !== end.getMonth()) {
|
|
101
|
+
diff.push('month');
|
|
102
|
+
}
|
|
103
|
+
if (start.getDate() !== end.getDate()) {
|
|
104
|
+
diff.push('day');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!diff.length) {
|
|
108
|
+
return intl.format(start);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let opts1 = intl.resolvedOptions();
|
|
112
|
+
let opts2 = {};
|
|
113
|
+
for (let key of diff) {
|
|
114
|
+
opts2[key] = opts1[key];
|
|
115
|
+
}
|
|
116
|
+
let intl2 = new Intl.DateTimeFormat(opts1.locale, opts2);
|
|
117
|
+
|
|
118
|
+
let full1 = intl.format(start);
|
|
119
|
+
let full2 = intl.format(end);
|
|
120
|
+
let part1 = intl2.format(start);
|
|
121
|
+
let part2 = intl2.format(end);
|
|
122
|
+
|
|
123
|
+
let common = _commonChunks(full1, part1, full2, part2);
|
|
124
|
+
if (common) {
|
|
125
|
+
return common.head + part1 + ' - ' + part2 + common.tail;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return full1 + ' - ' + full2;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function datesEqual(date1, ...dates2) {
|
|
132
|
+
return dates2.every(date2 => date1.getTime() === date2.getTime());
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function nextClosestDay(date, day) {
|
|
136
|
+
let diff = day - date.getUTCDay();
|
|
137
|
+
date.setUTCDate(date.getUTCDate() + (diff >= 0 ? diff : diff + 7));
|
|
138
|
+
return date;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function prevClosestDay(date, day) {
|
|
142
|
+
let diff = day - date.getUTCDay();
|
|
143
|
+
date.setUTCDate(date.getUTCDate() + (diff <= 0 ? diff : diff - 7));
|
|
144
|
+
return date;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Check whether given date is string which contains no time part
|
|
149
|
+
*/
|
|
150
|
+
export function noTimePart(date) {
|
|
151
|
+
return typeof date === 'string' && date.length <= 10;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Private functions
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
function _fromLocalDate(date) {
|
|
159
|
+
return new Date(Date.UTC(
|
|
160
|
+
date.getFullYear(),
|
|
161
|
+
date.getMonth(),
|
|
162
|
+
date.getDate(),
|
|
163
|
+
date.getHours(),
|
|
164
|
+
date.getMinutes(),
|
|
165
|
+
date.getSeconds()
|
|
166
|
+
));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function _fromISOString(str) {
|
|
170
|
+
const parts = str.match(/\d+/g);
|
|
171
|
+
return new Date(Date.UTC(
|
|
172
|
+
Number(parts[0]),
|
|
173
|
+
Number(parts[1]) - 1,
|
|
174
|
+
Number(parts[2]),
|
|
175
|
+
Number(parts[3] || 0),
|
|
176
|
+
Number(parts[4] || 0),
|
|
177
|
+
Number(parts[5] || 0)
|
|
178
|
+
));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function _commonChunks(str1, substr1, str2, substr2) {
|
|
182
|
+
let i = 0;
|
|
183
|
+
while (i < str1.length) {
|
|
184
|
+
let res1;
|
|
185
|
+
[i, res1] = _cut(str1, substr1, i);
|
|
186
|
+
if (!res1) {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let j = 0;
|
|
191
|
+
while (j < str2.length) {
|
|
192
|
+
let res2;
|
|
193
|
+
[j, res2] = _cut(str2, substr2, j);
|
|
194
|
+
if (!res2) {
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (res1.head === res2.head && res1.tail === res2.tail) {
|
|
199
|
+
return res1;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function _cut(str, substr, from) {
|
|
208
|
+
let start = str.indexOf(substr, from);
|
|
209
|
+
if (start >= 0) {
|
|
210
|
+
let end = start + substr.length;
|
|
211
|
+
|
|
212
|
+
return [end, {
|
|
213
|
+
head: str.substr(0, start),
|
|
214
|
+
tail: str.substr(end)
|
|
215
|
+
}];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return [-1, null];
|
|
219
|
+
}
|
package/src/lib/dom.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {symbol} from './utils.js';
|
|
2
|
+
|
|
3
|
+
export function createElement(tag, className, html, text) {
|
|
4
|
+
let el = document.createElement(tag);
|
|
5
|
+
el.className = className;
|
|
6
|
+
if (html) {
|
|
7
|
+
el.innerHTML = html;
|
|
8
|
+
} else if (text) {
|
|
9
|
+
el.innerText = text;
|
|
10
|
+
}
|
|
11
|
+
return el;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function hasYScroll(el) {
|
|
15
|
+
return el.scrollHeight > el.clientHeight;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function rect(el) {
|
|
19
|
+
return el.getBoundingClientRect();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function ancestor(el, up) {
|
|
23
|
+
while (up--) {
|
|
24
|
+
el = el.parentElement;
|
|
25
|
+
}
|
|
26
|
+
return el;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function height(el) {
|
|
30
|
+
return rect(el).height;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let payloadProp = symbol();
|
|
34
|
+
export function setPayload(el, payload) {
|
|
35
|
+
el[payloadProp] = payload;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function hasPayload(el) {
|
|
39
|
+
return !!el?.[payloadProp];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getPayload(el) {
|
|
43
|
+
return el[payloadProp];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getElementWithPayload(x, y) {
|
|
47
|
+
for (let el of document.elementsFromPoint(x, y)) {
|
|
48
|
+
if (hasPayload(el)) {
|
|
49
|
+
return el;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import {addDay, datesEqual, createDate, cloneDate, setMidnight, toLocalDate, noTimePart} from './date';
|
|
2
|
+
import {createElement} from './dom';
|
|
3
|
+
import {assign} from './utils';
|
|
4
|
+
import {toViewWithLocalDates} from './view';
|
|
5
|
+
import {is_function} from 'svelte/internal';
|
|
6
|
+
|
|
7
|
+
let eventId = 1;
|
|
8
|
+
export function createEvents(input) {
|
|
9
|
+
return input.map(event => ({
|
|
10
|
+
id: 'id' in event ? String(event.id) : `{generated-${eventId++}}`,
|
|
11
|
+
resourceIds: Array.isArray(event.resourceIds)
|
|
12
|
+
? event.resourceIds.map(String)
|
|
13
|
+
: ('resourceId' in event ? [String(event.resourceId)] : []),
|
|
14
|
+
allDay: event.allDay ?? (noTimePart(event.start) && noTimePart(event.end)),
|
|
15
|
+
start: createDate(event.start),
|
|
16
|
+
end: createDate(event.end),
|
|
17
|
+
title: event.title || '',
|
|
18
|
+
titleHTML: event.titleHTML || '',
|
|
19
|
+
editable: event.editable,
|
|
20
|
+
startEditable: event.startEditable,
|
|
21
|
+
durationEditable: event.durationEditable,
|
|
22
|
+
display: event.display || 'auto',
|
|
23
|
+
extendedProps: event.extendedProps || {},
|
|
24
|
+
backgroundColor: event.backgroundColor || event.color,
|
|
25
|
+
textColor: event.textColor
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createEventSources(input) {
|
|
30
|
+
return input.map(source => ({
|
|
31
|
+
events: source.events,
|
|
32
|
+
url: (source.url && source.url.trimEnd('&')) || '',
|
|
33
|
+
method: (source.method && source.method.toUpperCase()) || 'GET',
|
|
34
|
+
extraParams: source.extraParams || {}
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function createEventChunk(event, start, end) {
|
|
39
|
+
return {
|
|
40
|
+
start: event.start > start ? event.start : start,
|
|
41
|
+
end: event.end < end ? event.end : end,
|
|
42
|
+
event
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function sortEventChunks(chunks) {
|
|
47
|
+
// Sort by start date
|
|
48
|
+
chunks.sort((a, b) => {
|
|
49
|
+
if (a.start < b.start) {
|
|
50
|
+
return -1;
|
|
51
|
+
}
|
|
52
|
+
if (a.start > b.start) {
|
|
53
|
+
return 1;
|
|
54
|
+
}
|
|
55
|
+
return 0;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Prepare event chunks for month view and all-day slot in week view
|
|
61
|
+
*/
|
|
62
|
+
export function prepareEventChunks(chunks, hiddenDays) {
|
|
63
|
+
let longChunks = {};
|
|
64
|
+
|
|
65
|
+
if (chunks.length) {
|
|
66
|
+
sortEventChunks(chunks);
|
|
67
|
+
|
|
68
|
+
let prevChunk;
|
|
69
|
+
for (let chunk of chunks) {
|
|
70
|
+
let dates = [];
|
|
71
|
+
let date = setMidnight(cloneDate(chunk.start));
|
|
72
|
+
while (chunk.end > date) {
|
|
73
|
+
if (!hiddenDays.includes(date.getUTCDay())) {
|
|
74
|
+
dates.push(cloneDate(date));
|
|
75
|
+
if (dates.length > 1) {
|
|
76
|
+
let key = date.getTime();
|
|
77
|
+
if (longChunks[key]) {
|
|
78
|
+
longChunks[key].chunks.push(chunk);
|
|
79
|
+
} else {
|
|
80
|
+
longChunks[key] = {
|
|
81
|
+
sorted: false,
|
|
82
|
+
chunks: [chunk]
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
addDay(date);
|
|
88
|
+
}
|
|
89
|
+
if (dates.length) {
|
|
90
|
+
chunk.date = dates[0];
|
|
91
|
+
chunk.days = dates.length;
|
|
92
|
+
chunk.dates = dates;
|
|
93
|
+
if (chunk.start < dates[0]) {
|
|
94
|
+
chunk.start = dates[0];
|
|
95
|
+
}
|
|
96
|
+
if (setMidnight(cloneDate(chunk.end)) > dates[dates.length - 1]) {
|
|
97
|
+
chunk.end = dates[dates.length - 1];
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
chunk.date = setMidnight(cloneDate(chunk.start));
|
|
101
|
+
chunk.days = 1;
|
|
102
|
+
chunk.dates = [chunk.date];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (prevChunk && datesEqual(prevChunk.date, chunk.date)) {
|
|
106
|
+
chunk.prev = prevChunk;
|
|
107
|
+
}
|
|
108
|
+
prevChunk = chunk;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return longChunks;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function repositionEvent(chunk, longChunks, height) {
|
|
116
|
+
chunk.top = 0;
|
|
117
|
+
if (chunk.prev) {
|
|
118
|
+
chunk.top = chunk.prev.bottom + 1;
|
|
119
|
+
}
|
|
120
|
+
chunk.bottom = chunk.top + height;
|
|
121
|
+
let margin = 1;
|
|
122
|
+
let key = chunk.date.getTime();
|
|
123
|
+
if (longChunks[key]) {
|
|
124
|
+
if (!longChunks[key].sorted) {
|
|
125
|
+
longChunks[key].chunks.sort((a, b) => a.top - b.top);
|
|
126
|
+
longChunks[key].sorted = true;
|
|
127
|
+
}
|
|
128
|
+
for (let longChunk of longChunks[key].chunks) {
|
|
129
|
+
if (chunk.top < longChunk.bottom && chunk.bottom > longChunk.top) {
|
|
130
|
+
let offset = longChunk.bottom - chunk.top + 1;
|
|
131
|
+
margin += offset;
|
|
132
|
+
chunk.top += offset;
|
|
133
|
+
chunk.bottom += offset;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return margin;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function createEventContent(chunk, displayEventEnd, eventContent, theme, _intlEventTime, _view) {
|
|
142
|
+
let timeText = _intlEventTime.format(chunk.start), content;
|
|
143
|
+
if (displayEventEnd && chunk.event.display !== 'pointer') {
|
|
144
|
+
timeText += ` - ${_intlEventTime.format(chunk.end)}`;
|
|
145
|
+
}
|
|
146
|
+
if (eventContent) {
|
|
147
|
+
content = is_function(eventContent)
|
|
148
|
+
? eventContent({
|
|
149
|
+
event: toEventWithLocalDates(chunk.event),
|
|
150
|
+
timeText,
|
|
151
|
+
view: toViewWithLocalDates(_view)
|
|
152
|
+
})
|
|
153
|
+
: eventContent;
|
|
154
|
+
} else {
|
|
155
|
+
switch (chunk.event.display) {
|
|
156
|
+
case 'background':
|
|
157
|
+
content = '';
|
|
158
|
+
break;
|
|
159
|
+
case 'pointer':
|
|
160
|
+
content = {
|
|
161
|
+
domNodes: [createElement('div', theme.eventTime, null, timeText)]
|
|
162
|
+
};
|
|
163
|
+
break;
|
|
164
|
+
default:
|
|
165
|
+
content = {
|
|
166
|
+
domNodes: [
|
|
167
|
+
createElement('div', theme.eventTime, null, timeText),
|
|
168
|
+
createElement('div', theme.eventTitle, chunk.event.titleHTML, chunk.event.title)
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return [timeText, content];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function toEventWithLocalDates(event) {
|
|
178
|
+
return _cloneEvent(event, toLocalDate);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function cloneEvent(event) {
|
|
182
|
+
return _cloneEvent(event, cloneDate);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function _cloneEvent(event, dateFn) {
|
|
186
|
+
event = assign({}, event);
|
|
187
|
+
event.start = dateFn(event.start);
|
|
188
|
+
event.end = dateFn(event.end);
|
|
189
|
+
|
|
190
|
+
return event;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Check whether the event intersects with the given date range and resource
|
|
195
|
+
* @param event
|
|
196
|
+
* @param start
|
|
197
|
+
* @param end
|
|
198
|
+
* @param [resource]
|
|
199
|
+
* @param [timeMode] Zero-length events should be allowed (@see https://github.com/vkurko/calendar/issues/50), except in time mode
|
|
200
|
+
* @return boolean
|
|
201
|
+
*/
|
|
202
|
+
export function eventIntersects(event, start, end, resource, timeMode) {
|
|
203
|
+
return (
|
|
204
|
+
event.start < end && event.end > start || !timeMode && datesEqual(event.start, event.end, start)
|
|
205
|
+
) && (
|
|
206
|
+
resource === undefined || event.resourceIds.includes(resource.id)
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function helperEvent(display) {
|
|
211
|
+
return display === 'preview' || display === 'ghost' || display === 'pointer';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function bgEvent(display) {
|
|
215
|
+
return display === 'background';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function previewEvent(display) {
|
|
219
|
+
return display === 'preview';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function ghostEvent(display) {
|
|
223
|
+
return display === 'ghost';
|
|
224
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {derived, writable, get} from 'svelte/store';
|
|
2
|
+
import {is_function} from 'svelte/internal';
|
|
3
|
+
import {toLocalDate, formatRange} from './date';
|
|
4
|
+
|
|
5
|
+
export function writable2(value, parser, start) {
|
|
6
|
+
return {
|
|
7
|
+
...writable(parser ? parser(value) : value, start),
|
|
8
|
+
parse: parser
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function derived2(stores, fn, initValue) {
|
|
13
|
+
let storeValue = initValue;
|
|
14
|
+
let hasSubscribers = false;
|
|
15
|
+
let auto = fn.length < 2;
|
|
16
|
+
let fn2 = (_, set) => {
|
|
17
|
+
hasSubscribers = true;
|
|
18
|
+
if (auto) {
|
|
19
|
+
storeValue = fn(_, set);
|
|
20
|
+
set(storeValue);
|
|
21
|
+
} else {
|
|
22
|
+
fn(_, value => {storeValue = value; set(value);});
|
|
23
|
+
}
|
|
24
|
+
return () => {hasSubscribers = false;};
|
|
25
|
+
};
|
|
26
|
+
let store = derived(stores, fn2, storeValue);
|
|
27
|
+
return {
|
|
28
|
+
...store,
|
|
29
|
+
get: () => hasSubscribers ? storeValue : get(store)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function intl(locale, format) {
|
|
34
|
+
return derived([locale, format], ([$locale, $format]) => {
|
|
35
|
+
let intl = is_function($format)
|
|
36
|
+
? {format: $format}
|
|
37
|
+
: new Intl.DateTimeFormat($locale, $format);
|
|
38
|
+
return {
|
|
39
|
+
format: date => intl.format(toLocalDate(date))
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function intlRange(locale, format) {
|
|
45
|
+
return derived([locale, format], ([$locale, $format]) => {
|
|
46
|
+
if (is_function($format)) {
|
|
47
|
+
return {format: (start, end) => $format(toLocalDate(start), toLocalDate(end))};
|
|
48
|
+
}
|
|
49
|
+
let intl = new Intl.DateTimeFormat($locale, $format);
|
|
50
|
+
return {
|
|
51
|
+
format: (start, end) => formatRange(toLocalDate(start), toLocalDate(end), intl)
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
package/src/lib/utils.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function assign(...args) {
|
|
2
|
+
return Object.assign(...args);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function floor(value) {
|
|
6
|
+
return Math.floor(value);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function min(...args) {
|
|
10
|
+
return Math.min(...args);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function max(...args) {
|
|
14
|
+
return Math.max(...args);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isObject(test) {
|
|
18
|
+
return typeof test === 'object' && test !== null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function symbol() {
|
|
22
|
+
return Symbol('ec');
|
|
23
|
+
}
|
package/src/lib/view.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {assign} from './utils';
|
|
2
|
+
import {toLocalDate} from './date';
|
|
3
|
+
|
|
4
|
+
export function createView(view, _viewTitle, _currentRange, _activeRange) {
|
|
5
|
+
return {
|
|
6
|
+
type: view,
|
|
7
|
+
title: _viewTitle,
|
|
8
|
+
currentStart: _currentRange.start,
|
|
9
|
+
currentEnd: _currentRange.end,
|
|
10
|
+
activeStart: _activeRange.start,
|
|
11
|
+
activeEnd: _activeRange.end,
|
|
12
|
+
calendar: undefined
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function toViewWithLocalDates(view) {
|
|
17
|
+
view = assign({}, view);
|
|
18
|
+
view.currentStart = toLocalDate(view.currentStart);
|
|
19
|
+
view.currentEnd = toLocalDate(view.currentEnd);
|
|
20
|
+
view.activeStart = toLocalDate(view.activeStart);
|
|
21
|
+
view.activeEnd = toLocalDate(view.activeEnd);
|
|
22
|
+
|
|
23
|
+
return view;
|
|
24
|
+
}
|
package/src/lib.js
ADDED