@event-calendar/core 4.7.0 → 5.0.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 +29 -51
- package/dist/index.css +627 -731
- package/dist/index.js +2500 -3191
- package/package.json +2 -2
- package/src/Auxiliary.svelte +2 -13
- package/src/Buttons.svelte +62 -52
- package/src/Calendar.svelte +9 -3
- package/src/lib/a11y.js +2 -2
- package/src/lib/attachments.js +61 -0
- package/src/lib/chunks.js +117 -0
- package/src/lib/components/BaseDay.svelte +50 -0
- package/src/lib/components/BaseEvent.svelte +3 -3
- package/src/lib/components/ColHead.svelte +34 -0
- package/src/lib/components/DayHeader.svelte +14 -0
- package/src/lib/components/InteractableEvent.svelte +1 -3
- package/src/lib/components/index.js +3 -0
- package/src/lib/date.js +1 -1
- package/src/lib/dom.js +0 -4
- package/src/lib/events.js +10 -134
- package/src/lib/index.js +3 -2
- package/src/lib/{times.js → slots.js} +14 -19
- package/src/lib/stores.js +0 -33
- package/src/lib/utils.js +11 -2
- package/src/lib/view.js +0 -4
- package/src/plugins/day-grid/Day.svelte +36 -129
- package/src/plugins/day-grid/Event.svelte +42 -41
- package/src/plugins/day-grid/Popup.svelte +65 -48
- package/src/plugins/day-grid/View.svelte +76 -4
- package/src/plugins/day-grid/index.js +5 -5
- package/src/plugins/day-grid/lib.js +61 -0
- package/src/plugins/day-grid/stores.js +2 -20
- package/src/plugins/interaction/Action.svelte +40 -45
- package/src/plugins/interaction/Auxiliary.svelte +4 -4
- package/src/plugins/interaction/Pointer.svelte +8 -12
- package/src/plugins/interaction/Resizer.svelte +2 -2
- package/src/plugins/interaction/lib/utils.js +1 -5
- package/src/plugins/list/Day.svelte +8 -24
- package/src/plugins/list/View.svelte +39 -2
- package/src/plugins/resource-time-grid/Label.svelte +2 -2
- package/src/plugins/resource-time-grid/View.svelte +38 -82
- package/src/plugins/resource-time-grid/index.js +18 -10
- package/src/plugins/resource-time-grid/lib.js +31 -0
- package/src/plugins/resource-time-grid/options.js +10 -0
- package/src/plugins/resource-time-grid/stores.js +34 -0
- package/src/plugins/resource-timeline/Day.svelte +10 -73
- package/src/plugins/resource-timeline/Event.svelte +14 -23
- package/src/plugins/resource-timeline/Header.svelte +5 -5
- package/src/plugins/resource-timeline/Label.svelte +4 -12
- package/src/plugins/resource-timeline/NowIndicator.svelte +33 -28
- package/src/plugins/resource-timeline/View.svelte +129 -14
- package/src/plugins/resource-timeline/index.js +26 -23
- package/src/plugins/resource-timeline/lib.js +115 -118
- package/src/plugins/resource-timeline/stores.js +11 -7
- package/src/plugins/time-grid/AllDayEvent.svelte +31 -0
- package/src/plugins/time-grid/Day.svelte +11 -99
- package/src/plugins/time-grid/Event.svelte +18 -20
- package/src/plugins/time-grid/NowIndicator.svelte +32 -10
- package/src/plugins/time-grid/View.svelte +127 -35
- package/src/plugins/time-grid/index.js +10 -8
- package/src/plugins/time-grid/lib.js +142 -0
- package/src/plugins/time-grid/options.js +57 -0
- package/src/plugins/time-grid/stores.js +41 -8
- package/src/storage/options.js +4 -39
- package/src/storage/state.js +1 -4
- package/src/storage/stores.js +42 -11
- package/src/styles/days.css +91 -0
- package/src/styles/events.css +180 -0
- package/src/styles/index.css +126 -0
- package/src/styles/now-indicator.css +35 -0
- package/src/styles/popup.css +30 -0
- package/src/styles/sidebar.css +59 -0
- package/src/styles/slots.css +42 -0
- package/src/styles/theme.css +68 -0
- package/src/styles/toolbar.css +80 -0
- package/src/lib/actions.js +0 -52
- package/src/plugins/day-grid/Body.svelte +0 -54
- package/src/plugins/day-grid/Header.svelte +0 -20
- package/src/plugins/day-grid/Week.svelte +0 -60
- package/src/plugins/list/Body.svelte +0 -44
- package/src/plugins/resource-timeline/Body.svelte +0 -67
- package/src/plugins/resource-timeline/Days.svelte +0 -72
- package/src/plugins/resource-timeline/Sidebar.svelte +0 -35
- package/src/plugins/time-grid/Body.svelte +0 -43
- package/src/plugins/time-grid/Section.svelte +0 -29
- package/src/plugins/time-grid/all-day/Day.svelte +0 -65
- package/src/plugins/time-grid/all-day/Event.svelte +0 -37
- package/src/plugins/time-grid/all-day/Week.svelte +0 -65
- package/src/plugins/time-grid/utils.js +0 -58
- package/src/styles/day-grid.scss +0 -51
- package/src/styles/index.scss +0 -553
- package/src/styles/theme.scss +0 -95
- package/src/styles/time-grid.scss +0 -83
- package/src/styles/timeline.scss +0 -152
package/src/lib/events.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
addDay, cloneDate, copyTime, createDate, datesEqual, noTimePart, setMidnight, toISOString, toLocalDate
|
|
3
|
+
} from './date.js';
|
|
2
4
|
import {createElement} from './dom.js';
|
|
3
5
|
import {assign, isArray, isFunction} from './utils.js';
|
|
4
6
|
import {toViewWithLocalDates} from './view.js';
|
|
@@ -55,38 +57,6 @@ export function createEventSources(input) {
|
|
|
55
57
|
}));
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
export function createEventChunk(event, start, end) {
|
|
59
|
-
let chunk = {
|
|
60
|
-
start: event.start > start ? event.start : start,
|
|
61
|
-
end: event.end < end ? event.end : end,
|
|
62
|
-
event
|
|
63
|
-
};
|
|
64
|
-
chunk.zeroDuration = datesEqual(chunk.start, chunk.end);
|
|
65
|
-
|
|
66
|
-
return chunk;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function sortEventChunks(chunks, eventOrder) {
|
|
70
|
-
if (isFunction(eventOrder)) {
|
|
71
|
-
chunks.sort((a, b) => eventOrder(
|
|
72
|
-
_toChunkWithLocalDates(a),
|
|
73
|
-
_toChunkWithLocalDates(b)
|
|
74
|
-
));
|
|
75
|
-
} else {
|
|
76
|
-
// Sort by start date (all-day events always on top)
|
|
77
|
-
chunks.sort((a, b) => a.start - b.start || b.event.allDay - a.event.allDay);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function _toChunkWithLocalDates(chunk) {
|
|
82
|
-
return {
|
|
83
|
-
...chunk,
|
|
84
|
-
start: toLocalDate(chunk.start),
|
|
85
|
-
end: toLocalDate(chunk.end),
|
|
86
|
-
event: toEventWithLocalDates(chunk.event)
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
60
|
export function createEventContent(chunk, displayEventEnd, eventContent, theme, _intlEventTime, _view) {
|
|
91
61
|
let timeText = _intlEventTime.formatRange(
|
|
92
62
|
chunk.start,
|
|
@@ -113,7 +83,7 @@ export function createEventContent(chunk, displayEventEnd, eventContent, theme,
|
|
|
113
83
|
domNodes = [];
|
|
114
84
|
break;
|
|
115
85
|
case 'pointer':
|
|
116
|
-
domNodes = [createTimeElement(timeText, chunk, theme)];
|
|
86
|
+
domNodes = chunk.event.allDay ? [] : [createTimeElement(timeText, chunk, theme)];
|
|
117
87
|
break;
|
|
118
88
|
default:
|
|
119
89
|
domNodes = [
|
|
@@ -169,118 +139,24 @@ function _cloneEvent(event, dateFn) {
|
|
|
169
139
|
return event;
|
|
170
140
|
}
|
|
171
141
|
|
|
172
|
-
/**
|
|
173
|
-
* Prepare event chunks for month view and all-day slot in week view
|
|
174
|
-
*/
|
|
175
|
-
export function prepareEventChunks(chunks, hiddenDays, eventOrder) {
|
|
176
|
-
let longChunks = {};
|
|
177
|
-
|
|
178
|
-
if (chunks.length) {
|
|
179
|
-
sortEventChunks(chunks, eventOrder);
|
|
180
|
-
|
|
181
|
-
let prevChunk;
|
|
182
|
-
for (let chunk of chunks) {
|
|
183
|
-
let dates = [];
|
|
184
|
-
let date = setMidnight(cloneDate(chunk.start));
|
|
185
|
-
while (chunk.end > date) {
|
|
186
|
-
if (!hiddenDays.includes(date.getUTCDay())) {
|
|
187
|
-
dates.push(cloneDate(date));
|
|
188
|
-
if (dates.length > 1) {
|
|
189
|
-
let key = date.getTime();
|
|
190
|
-
if (longChunks[key]) {
|
|
191
|
-
longChunks[key].chunks.push(chunk);
|
|
192
|
-
} else {
|
|
193
|
-
longChunks[key] = {
|
|
194
|
-
sorted: false,
|
|
195
|
-
chunks: [chunk]
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
addDay(date);
|
|
201
|
-
}
|
|
202
|
-
if (dates.length) {
|
|
203
|
-
chunk.date = dates[0];
|
|
204
|
-
chunk.days = dates.length;
|
|
205
|
-
chunk.dates = dates;
|
|
206
|
-
// Adjust the start and end dates of the chunk if hidden days affected them
|
|
207
|
-
if (chunk.start < dates[0]) {
|
|
208
|
-
chunk.start = dates[0];
|
|
209
|
-
}
|
|
210
|
-
let maxEnd = addDay(cloneDate(dates.at(-1)));
|
|
211
|
-
if (chunk.end > maxEnd) {
|
|
212
|
-
chunk.end = maxEnd;
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
chunk.date = setMidnight(cloneDate(chunk.start));
|
|
216
|
-
chunk.days = 1;
|
|
217
|
-
chunk.dates = [chunk.date];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (prevChunk && datesEqual(prevChunk.date, chunk.date)) {
|
|
221
|
-
chunk.prev = prevChunk;
|
|
222
|
-
}
|
|
223
|
-
prevChunk = chunk;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return longChunks;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function repositionEvent(chunk, longChunks, height) {
|
|
231
|
-
chunk.top = 0;
|
|
232
|
-
if (chunk.prev) {
|
|
233
|
-
chunk.top = chunk.prev.bottom + 1;
|
|
234
|
-
}
|
|
235
|
-
chunk.bottom = chunk.top + height;
|
|
236
|
-
let margin = 1;
|
|
237
|
-
let key = chunk.date.getTime();
|
|
238
|
-
if (longChunks[key]) {
|
|
239
|
-
if (!longChunks[key].sorted) {
|
|
240
|
-
longChunks[key].chunks.sort((a, b) => a.top - b.top);
|
|
241
|
-
longChunks[key].sorted = true;
|
|
242
|
-
}
|
|
243
|
-
for (let longChunk of longChunks[key].chunks) {
|
|
244
|
-
if (chunk.top < longChunk.bottom && chunk.bottom > longChunk.top) {
|
|
245
|
-
let offset = longChunk.bottom - chunk.top + 1;
|
|
246
|
-
margin += offset;
|
|
247
|
-
chunk.top += offset;
|
|
248
|
-
chunk.bottom += offset;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return margin;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
142
|
export function runReposition(refs, data) {
|
|
257
143
|
refs.length = data.length;
|
|
258
|
-
let result = [];
|
|
259
144
|
for (let ref of refs) {
|
|
260
|
-
|
|
145
|
+
ref?.reposition();
|
|
261
146
|
}
|
|
262
|
-
return result;
|
|
263
147
|
}
|
|
264
148
|
|
|
265
149
|
/**
|
|
266
|
-
* Check whether the event intersects with the given date range and
|
|
150
|
+
* Check whether the event intersects with the given date range and resource
|
|
267
151
|
* @param event
|
|
268
152
|
* @param start
|
|
269
153
|
* @param end
|
|
270
|
-
* @param
|
|
154
|
+
* @param resource
|
|
271
155
|
* @return boolean
|
|
272
156
|
*/
|
|
273
|
-
export function eventIntersects(event, start, end,
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (!isArray(resources)) {
|
|
277
|
-
resources = [resources];
|
|
278
|
-
}
|
|
279
|
-
return resources.some(resource => event.resourceIds.includes(resource.id));
|
|
280
|
-
}
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
return false;
|
|
157
|
+
export function eventIntersects(event, start, end, resource = undefined) {
|
|
158
|
+
return (!resource || event.resourceIds.includes(resource.id)) && event.start < end && event.end > start;
|
|
159
|
+
|
|
284
160
|
}
|
|
285
161
|
|
|
286
162
|
export function helperEvent(display) {
|
package/src/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './a11y.js';
|
|
2
|
-
export * from './
|
|
2
|
+
export * from './attachments.js';
|
|
3
|
+
export * from './chunks.js';
|
|
3
4
|
export * from './date.js';
|
|
4
5
|
export * from './debounce.js';
|
|
5
6
|
export * from './dom.js';
|
|
@@ -8,7 +9,7 @@ export * from './options.js';
|
|
|
8
9
|
export * from './payload.js';
|
|
9
10
|
export * from './range.js';
|
|
10
11
|
export * from './resources.js';
|
|
12
|
+
export * from './slots.js';
|
|
11
13
|
export * from './stores.js';
|
|
12
|
-
export * from './times.js';
|
|
13
14
|
export * from './utils.js';
|
|
14
15
|
export * from './view.js';
|
|
@@ -1,37 +1,32 @@
|
|
|
1
1
|
import {addDuration, cloneDate, createDuration, DAY_IN_SECONDS, toISOString, toSeconds} from './date.js';
|
|
2
|
-
import {max as maxFn, min as minFn, isFunction} from './utils.js';
|
|
2
|
+
import {max as maxFn, min as minFn, isFunction, floor} from './utils.js';
|
|
3
3
|
import {bgEvent} from './events.js';
|
|
4
4
|
|
|
5
|
-
export function
|
|
5
|
+
export function createSlots(date, $slotDuration, $_slotLabelPeriodicity, $_slotTimeLimits, $_intlSlotLabel) {
|
|
6
|
+
let slots = [];
|
|
6
7
|
date = cloneDate(date);
|
|
7
|
-
let times = [];
|
|
8
8
|
let end = cloneDate(date);
|
|
9
9
|
addDuration(date, $_slotTimeLimits.min);
|
|
10
10
|
addDuration(end, $_slotTimeLimits.max);
|
|
11
|
-
//
|
|
12
|
-
if ($slotLabelInterval === undefined) {
|
|
13
|
-
$slotLabelInterval = $slotDuration.seconds < 3600
|
|
14
|
-
? createDuration($slotDuration.seconds * 2)
|
|
15
|
-
: $slotDuration;
|
|
16
|
-
}
|
|
17
|
-
let label = cloneDate(date);
|
|
18
|
-
// Build times
|
|
11
|
+
// Build slots
|
|
19
12
|
while (date < end) {
|
|
20
|
-
|
|
13
|
+
slots.push([
|
|
21
14
|
toISOString(date),
|
|
22
|
-
$_intlSlotLabel.format(date)
|
|
23
|
-
date >= label
|
|
15
|
+
$_intlSlotLabel.format(date)
|
|
24
16
|
]);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
addDuration(date, $slotDuration, $_slotLabelPeriodicity);
|
|
18
|
+
}
|
|
19
|
+
// Calculate span for last slot
|
|
20
|
+
let span = floor((date - end) / 1000 / toSeconds($slotDuration));
|
|
21
|
+
if (span && span !== $_slotLabelPeriodicity) {
|
|
22
|
+
slots.at(-1)[2] = $_slotLabelPeriodicity - span;
|
|
29
23
|
}
|
|
30
24
|
|
|
31
|
-
return
|
|
25
|
+
return slots;
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
export function createSlotTimeLimits($slotMinTime, $slotMaxTime, $flexibleSlotTimeLimits, $_viewDates, $_filteredEvents) {
|
|
29
|
+
// Copy values
|
|
35
30
|
let min = createDuration($slotMinTime);
|
|
36
31
|
let max = createDuration($slotMaxTime);
|
|
37
32
|
|
package/src/lib/stores.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {derived} from 'svelte/store';
|
|
2
2
|
import {isFunction} from './utils.js';
|
|
3
3
|
import {toLocalDate} from './date.js';
|
|
4
|
-
import {createResources} from './resources.js';
|
|
5
|
-
import {getPayload} from './payload.js';
|
|
6
4
|
|
|
7
5
|
export function intl(locale, format) {
|
|
8
6
|
return derived([locale, format], ([$locale, $format]) => {
|
|
@@ -63,34 +61,3 @@ function _getParts(source, parts) {
|
|
|
63
61
|
}
|
|
64
62
|
return result;
|
|
65
63
|
}
|
|
66
|
-
|
|
67
|
-
export function viewResources(state) {
|
|
68
|
-
return derived(
|
|
69
|
-
[state.resources, state.filterResourcesWithEvents, state._filteredEvents, state._activeRange],
|
|
70
|
-
([$resources, $filterResourcesWithEvents, $_filteredEvents, $_activeRange]) => {
|
|
71
|
-
let result = $resources.filter(resource => !getPayload(resource).hidden);
|
|
72
|
-
|
|
73
|
-
if ($filterResourcesWithEvents) {
|
|
74
|
-
result = $resources.filter(resource => {
|
|
75
|
-
for (let event of $_filteredEvents) {
|
|
76
|
-
if (
|
|
77
|
-
event.display !== 'background' &&
|
|
78
|
-
event.resourceIds.includes(resource.id) &&
|
|
79
|
-
event.start < $_activeRange.end &&
|
|
80
|
-
event.end > $_activeRange.start
|
|
81
|
-
) {
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!result.length) {
|
|
90
|
-
result = createResources([{}]);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
95
|
-
);
|
|
96
|
-
}
|
package/src/lib/utils.js
CHANGED
|
@@ -38,6 +38,15 @@ export function isFunction(value) {
|
|
|
38
38
|
return typeof value === 'function';
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export function isEmpty(obj) {
|
|
42
|
+
for (let prop in obj) {
|
|
43
|
+
if (Object.hasOwn(obj, prop)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
41
50
|
export function run(fn) {
|
|
42
51
|
return fn();
|
|
43
52
|
}
|
|
@@ -50,11 +59,11 @@ export function noop() {}
|
|
|
50
59
|
|
|
51
60
|
export const identity = (x) => x;
|
|
52
61
|
|
|
53
|
-
export function stopPropagation(fn) {
|
|
62
|
+
export function stopPropagation(fn, _this = undefined) {
|
|
54
63
|
return function (event) {
|
|
55
64
|
event.stopPropagation();
|
|
56
65
|
if (fn) {
|
|
57
|
-
fn.call(
|
|
66
|
+
fn.call(_this, event);
|
|
58
67
|
}
|
|
59
68
|
};
|
|
60
69
|
}
|
package/src/lib/view.js
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext
|
|
3
|
-
import {SvelteSet} from 'svelte/reactivity';
|
|
2
|
+
import {getContext} from 'svelte';
|
|
4
3
|
import {
|
|
5
|
-
|
|
6
|
-
runReposition, setContent, setPayload, toISOString, toLocalDate, stopPropagation
|
|
4
|
+
contentFrom, getWeekNumber, isFunction, keyEnter, toISOString, toLocalDate, stopPropagation
|
|
7
5
|
} from '#lib';
|
|
8
|
-
import
|
|
9
|
-
import Popup from './Popup.svelte';
|
|
6
|
+
import {BaseDay} from '#components';
|
|
10
7
|
|
|
11
|
-
let {
|
|
8
|
+
let {day} = $props();
|
|
12
9
|
|
|
13
10
|
let {
|
|
14
|
-
date
|
|
15
|
-
weekNumberContent, _hiddenEvents, _intlDayCell, _popupDate, _popupChunks, _today, _interaction
|
|
11
|
+
date, firstDay, moreLinkContent, theme, weekNumbers, weekNumberContent, _hiddenChunks, _intlDayCell, _popupDay
|
|
16
12
|
} = getContext('state');
|
|
17
13
|
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
$
|
|
21
|
-
$_hiddenEvents[date.getTime()] = untrack(() => hiddenEvents);
|
|
22
|
-
});
|
|
23
|
-
let refs = [];
|
|
24
|
-
let isToday = $derived(datesEqual(date, $_today));
|
|
25
|
-
let otherMonth = $derived(date.getUTCMonth() !== $currentDate.getUTCMonth());
|
|
26
|
-
let highlight = $derived($highlightedDates.some(d => datesEqual(d, date)));
|
|
27
|
-
let disabled = $derived(outsideRange(date, $validRange));
|
|
14
|
+
let {dayStart, disabled, highlight} = $derived(day);
|
|
15
|
+
let otherMonth = $derived(dayStart.getUTCMonth() !== $date.getUTCMonth());
|
|
16
|
+
let classes = $derived(classNames => [...classNames, otherMonth && $theme.otherMonth]);
|
|
28
17
|
|
|
29
|
-
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
18
|
+
// Week numbers
|
|
19
|
+
let showWeekNumber = $derived($weekNumbers && dayStart.getUTCDay() === ($firstDay ? 1 : 0));
|
|
20
|
+
let weekNumber = $derived.by(() => {
|
|
21
|
+
let weekNumber;
|
|
22
|
+
if (showWeekNumber) {
|
|
23
|
+
let week = getWeekNumber(dayStart, $firstDay);
|
|
24
|
+
if ($weekNumberContent) {
|
|
25
|
+
weekNumber = isFunction($weekNumberContent)
|
|
26
|
+
? $weekNumberContent({date: toLocalDate(dayStart), week})
|
|
27
|
+
: $weekNumberContent;
|
|
28
|
+
} else {
|
|
29
|
+
weekNumber = 'W' + String(week).padStart(2, '0');
|
|
40
30
|
}
|
|
41
31
|
}
|
|
42
|
-
return
|
|
43
|
-
});
|
|
44
|
-
$effect.pre(() => {
|
|
45
|
-
dayChunks;
|
|
46
|
-
hiddenEvents.clear();
|
|
32
|
+
return weekNumber;
|
|
47
33
|
});
|
|
48
34
|
|
|
35
|
+
// More link
|
|
36
|
+
let hiddenChunks = $derived($_hiddenChunks[dayStart.getTime()]);
|
|
49
37
|
let moreLink = $derived.by(() => {
|
|
50
38
|
let moreLink = '';
|
|
51
|
-
if (
|
|
52
|
-
let text = '+' +
|
|
39
|
+
if (hiddenChunks) {
|
|
40
|
+
let text = '+' + hiddenChunks.length + ' more';
|
|
53
41
|
if ($moreLinkContent) {
|
|
54
42
|
moreLink = isFunction($moreLinkContent)
|
|
55
|
-
? $moreLinkContent({num:
|
|
43
|
+
? $moreLinkContent({num: hiddenChunks.length, text})
|
|
56
44
|
: $moreLinkContent;
|
|
57
45
|
} else {
|
|
58
46
|
moreLink = text;
|
|
@@ -61,121 +49,40 @@
|
|
|
61
49
|
return moreLink;
|
|
62
50
|
});
|
|
63
51
|
|
|
64
|
-
// dateFromPoint
|
|
65
|
-
onMount(() => {
|
|
66
|
-
setPayload(el, () => ({allDay: true, date, resource: undefined, dayEl: el, disabled}));
|
|
67
|
-
});
|
|
68
|
-
|
|
69
52
|
// Popup
|
|
70
53
|
function showMore() {
|
|
71
|
-
$
|
|
72
|
-
}
|
|
73
|
-
let showPopup = $derived($_popupDate && datesEqual(date, $_popupDate));
|
|
74
|
-
// Use `pre` to tick before popup positioning tick
|
|
75
|
-
$effect.pre(() => {
|
|
76
|
-
dayChunks;
|
|
77
|
-
longChunks;
|
|
78
|
-
if (showPopup) {
|
|
79
|
-
// Let chunks to reposition then set popup chunks
|
|
80
|
-
tick().then(setPopupChunks);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
function setPopupChunks() {
|
|
84
|
-
let nextDay = addDay(cloneDate(date));
|
|
85
|
-
let chunks = dayChunks.concat(longChunks[date.getTime()]?.chunks || []);
|
|
86
|
-
$_popupChunks = chunks
|
|
87
|
-
.map(chunk => assign({}, chunk, createEventChunk(chunk.event, date, nextDay), {days: 1, dates: [date]}))
|
|
88
|
-
.sort((a, b) => a.top - b.top);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Week numbers
|
|
92
|
-
let showWeekNumber = $derived($weekNumbers && date.getUTCDay() == ($firstDay ? 1 : 0));
|
|
93
|
-
let weekNumber = $derived.by(() => {
|
|
94
|
-
let weekNumber;
|
|
95
|
-
if (showWeekNumber) {
|
|
96
|
-
let week = getWeekNumber(date, $firstDay);
|
|
97
|
-
if ($weekNumberContent) {
|
|
98
|
-
weekNumber = isFunction($weekNumberContent)
|
|
99
|
-
? $weekNumberContent({date: toLocalDate(date), week})
|
|
100
|
-
: $weekNumberContent;
|
|
101
|
-
} else {
|
|
102
|
-
weekNumber = 'W' + String(week).padStart(2, '0');
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return weekNumber;
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
export function reposition() {
|
|
109
|
-
if (!disabled) {
|
|
110
|
-
runReposition(refs, dayChunks);
|
|
111
|
-
}
|
|
54
|
+
$_popupDay = day;
|
|
112
55
|
}
|
|
113
56
|
</script>
|
|
114
57
|
|
|
115
|
-
<
|
|
116
|
-
bind:this={el}
|
|
117
|
-
class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{isToday ? ' ' + $theme.today : ''}{otherMonth ? ' ' + $theme.otherMonth : ''}{highlight ? ' ' + $theme.highlight : ''}{disabled ? ' ' + $theme.disabled : ''}"
|
|
118
|
-
role="cell"
|
|
119
|
-
onpointerdown={$_interaction.action?.select}
|
|
120
|
-
>
|
|
58
|
+
<BaseDay date={dayStart} allDay {classes} {disabled} {highlight}>
|
|
121
59
|
<div class="{$theme.dayHead}">
|
|
122
60
|
<time
|
|
123
|
-
datetime="{toISOString(
|
|
124
|
-
|
|
61
|
+
datetime="{toISOString(dayStart, 10)}"
|
|
62
|
+
{@attach contentFrom($_intlDayCell.format(dayStart))}
|
|
125
63
|
></time>
|
|
126
64
|
{#if showWeekNumber}
|
|
127
65
|
<span
|
|
128
66
|
class="{$theme.weekNumber}"
|
|
129
|
-
|
|
67
|
+
{@attach contentFrom(weekNumber)}
|
|
130
68
|
></span>
|
|
131
69
|
{/if}
|
|
132
70
|
</div>
|
|
133
|
-
|
|
134
|
-
{#if !disabled}
|
|
135
|
-
{#each dayBgChunks as chunk (chunk.event)}
|
|
136
|
-
<Event {chunk}/>
|
|
137
|
-
{/each}
|
|
138
|
-
{/if}
|
|
139
|
-
</div>
|
|
140
|
-
{#if !disabled}
|
|
141
|
-
<!-- Pointer -->
|
|
142
|
-
{#if iChunks[2] && datesEqual(iChunks[2].date, date)}
|
|
143
|
-
<div class="{$theme.events}">
|
|
144
|
-
<Event chunk={iChunks[2]}/>
|
|
145
|
-
</div>
|
|
146
|
-
{/if}
|
|
147
|
-
<!-- Drag & Resize -->
|
|
148
|
-
{#if iChunks[0] && datesEqual(iChunks[0].date, date)}
|
|
149
|
-
<div class="{$theme.events} {$theme.preview}">
|
|
150
|
-
<Event chunk={iChunks[0]}/>
|
|
151
|
-
</div>
|
|
152
|
-
{/if}
|
|
153
|
-
{/if}
|
|
154
|
-
<div class="{$theme.events}">
|
|
155
|
-
{#if !disabled}
|
|
156
|
-
{#each dayChunks as chunk, i (chunk.event)}
|
|
157
|
-
<!-- svelte-ignore binding_property_non_reactive -->
|
|
158
|
-
<Event {chunk} {longChunks} {dates} bind:this={refs[i]}/>
|
|
159
|
-
{/each}
|
|
160
|
-
{/if}
|
|
161
|
-
</div>
|
|
162
|
-
{#if showPopup}
|
|
163
|
-
<Popup/>
|
|
164
|
-
{/if}
|
|
71
|
+
|
|
165
72
|
<div class="{$theme.dayFoot}">
|
|
166
|
-
{#if
|
|
73
|
+
{#if hiddenChunks}
|
|
167
74
|
<!-- svelte-ignore a11y_missing_attribute -->
|
|
168
75
|
<!-- svelte-ignore a11y_missing_content -->
|
|
169
76
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
170
77
|
<a
|
|
171
78
|
role="button"
|
|
172
79
|
tabindex="0"
|
|
173
|
-
aria-haspopup="
|
|
80
|
+
aria-haspopup="dialog"
|
|
174
81
|
onclick={stopPropagation(showMore)}
|
|
175
82
|
onkeydown={keyEnter(showMore)}
|
|
176
83
|
onpointerdown={stopPropagation()}
|
|
177
|
-
|
|
84
|
+
{@attach contentFrom(moreLink)}
|
|
178
85
|
></a>
|
|
179
86
|
{/if}
|
|
180
87
|
</div>
|
|
181
|
-
</
|
|
88
|
+
</BaseDay>
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {
|
|
3
|
+
import {bgEvent, height, isEmpty, max, repositionEvent} from '#lib';
|
|
4
4
|
import {InteractableEvent} from '#components';
|
|
5
5
|
|
|
6
|
-
let {chunk,
|
|
6
|
+
let {chunk, gridEl, inPopup = false} = $props();
|
|
7
7
|
|
|
8
|
-
let {
|
|
8
|
+
let {_colsCount, _hiddenChunks, _popupDay, dayMaxEvents} = getContext('state');
|
|
9
9
|
|
|
10
10
|
let el = $state();
|
|
11
|
-
let margin = $state(
|
|
11
|
+
let margin = $state(0);
|
|
12
12
|
let hidden = $state(false);
|
|
13
13
|
|
|
14
14
|
let event = $derived(chunk.event);
|
|
15
15
|
let display = $derived(chunk.event.display);
|
|
16
|
+
let dayEl = $derived(gridEl?.children.item((chunk.gridRow - 1) * $_colsCount + chunk.gridColumn - 1));
|
|
17
|
+
|
|
18
|
+
$effect(() => {
|
|
19
|
+
if (dayEl) {
|
|
20
|
+
margin = height(dayEl.firstElementChild);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
16
23
|
|
|
17
24
|
// Style
|
|
18
25
|
let styles = $derived(style => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let marginTop = margin;
|
|
26
|
+
style['grid-column'] = `${chunk.gridColumn} / span ${chunk.dates.length}`;
|
|
27
|
+
style['grid-row'] = chunk.gridRow;
|
|
28
|
+
if (!bgEvent(display)) {
|
|
29
|
+
let marginTop = inPopup ? 1 : margin;
|
|
23
30
|
if (event._margin) {
|
|
24
31
|
// Force margin for helper events
|
|
25
|
-
let [_margin,
|
|
26
|
-
if (
|
|
32
|
+
let [_margin, _gridRow] = event._margin;
|
|
33
|
+
if (_margin > marginTop && chunk.gridRow === _gridRow) {
|
|
27
34
|
marginTop = _margin;
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
|
-
style['
|
|
31
|
-
style['margin-top'] = `${marginTop}px`;
|
|
37
|
+
style['margin-block-start'] = `${marginTop}px`;
|
|
32
38
|
}
|
|
33
39
|
if (hidden) {
|
|
34
40
|
style['visibility'] = 'hidden';
|
|
@@ -37,42 +43,37 @@
|
|
|
37
43
|
});
|
|
38
44
|
|
|
39
45
|
export function reposition() {
|
|
40
|
-
margin = repositionEvent(chunk,
|
|
41
|
-
if ($dayMaxEvents === true) {
|
|
42
|
-
hide();
|
|
43
|
-
} else {
|
|
44
|
-
hidden = false;
|
|
45
|
-
}
|
|
46
|
+
margin = repositionEvent(chunk, height(el), height(dayEl.firstElementChild));
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
function hide() {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (size !== hiddenEvents.size) {
|
|
64
|
-
update = true;
|
|
49
|
+
export function hide() {
|
|
50
|
+
if ($dayMaxEvents === true) {
|
|
51
|
+
let h = height(dayEl) - footHeight(dayEl);
|
|
52
|
+
hidden = chunk.bottom > h;
|
|
53
|
+
if (hidden) {
|
|
54
|
+
// Hide the event throughout all days
|
|
55
|
+
for (let date of chunk.dates) {
|
|
56
|
+
let key = date.getTime();
|
|
57
|
+
if ($_hiddenChunks[key]) {
|
|
58
|
+
if (!$_hiddenChunks[key].includes(chunk)) {
|
|
59
|
+
$_hiddenChunks[key] = [...$_hiddenChunks[key], chunk];
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
$_hiddenChunks[key] = [chunk];
|
|
63
|
+
}
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
$
|
|
66
|
+
} else {
|
|
67
|
+
hidden = false;
|
|
68
|
+
if (!isEmpty($_hiddenChunks)) {
|
|
69
|
+
$_hiddenChunks = {};
|
|
70
|
+
}
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
function footHeight(dayEl) {
|
|
74
75
|
let h = 0;
|
|
75
|
-
for (let i = 0; i < chunk.
|
|
76
|
+
for (let i = 0; i < chunk.dates.length; ++ i) {
|
|
76
77
|
h = max(h, height(dayEl.lastElementChild));
|
|
77
78
|
dayEl = dayEl.nextElementSibling;
|
|
78
79
|
if (!dayEl) {
|
|
@@ -88,6 +89,6 @@
|
|
|
88
89
|
{chunk}
|
|
89
90
|
{styles}
|
|
90
91
|
axis="x"
|
|
91
|
-
forceDate={
|
|
92
|
-
forceMargin={
|
|
92
|
+
forceDate={inPopup && $_popupDay.dayStart}
|
|
93
|
+
forceMargin={[margin, chunk.gridRow]}
|
|
93
94
|
/>
|