@event-calendar/core 5.0.5 → 5.1.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 +15 -4
- package/dist/index.css +2 -2
- package/dist/index.js +2201 -2128
- package/package.json +2 -2
- package/src/Buttons.svelte +36 -37
- package/src/Calendar.svelte +34 -37
- package/src/Toolbar.svelte +4 -4
- package/src/lib/components/BaseDay.svelte +13 -10
- package/src/lib/components/BaseEvent.svelte +17 -17
- package/src/lib/components/ColHead.svelte +6 -6
- package/src/lib/components/DayHeader.svelte +3 -3
- package/src/lib/components/InteractableEvent.svelte +7 -8
- package/src/lib/derived.js +80 -0
- package/src/lib/index.js +1 -2
- package/src/lib/slots.js +16 -16
- package/src/lib/utils.js +4 -9
- package/src/lib/view.js +0 -8
- package/src/plugins/day-grid/Day.svelte +25 -23
- package/src/plugins/day-grid/Event.svelte +15 -13
- package/src/plugins/day-grid/Popup.svelte +12 -12
- package/src/plugins/day-grid/View.svelte +24 -36
- package/src/plugins/day-grid/derived.js +102 -0
- package/src/plugins/day-grid/index.js +47 -36
- package/src/plugins/day-grid/state.svelte.js +19 -0
- package/src/plugins/interaction/Action.svelte +108 -76
- package/src/plugins/interaction/Auxiliary.svelte +9 -38
- package/src/plugins/interaction/Pointer.svelte +12 -17
- package/src/plugins/interaction/Resizer.svelte +9 -7
- package/src/plugins/interaction/effects.js +37 -0
- package/src/plugins/interaction/index.js +44 -38
- package/src/plugins/interaction/lib/utils.js +1 -1
- package/src/plugins/interaction/state.svelte.js +12 -0
- package/src/plugins/list/Day.svelte +8 -7
- package/src/plugins/list/Event.svelte +3 -3
- package/src/plugins/list/View.svelte +18 -13
- package/src/plugins/list/index.js +51 -43
- package/src/plugins/list/state.svelte.js +8 -0
- package/src/plugins/resource-time-grid/Label.svelte +8 -8
- package/src/plugins/resource-time-grid/View.svelte +38 -17
- package/src/plugins/resource-time-grid/derived.js +67 -0
- package/src/plugins/resource-time-grid/index.js +34 -28
- package/src/plugins/resource-time-grid/state.svelte.js +21 -0
- package/src/plugins/resource-timeline/Day.svelte +9 -4
- package/src/plugins/resource-timeline/Event.svelte +7 -6
- package/src/plugins/resource-timeline/Expander.svelte +7 -6
- package/src/plugins/resource-timeline/NowIndicator.svelte +10 -11
- package/src/plugins/resource-timeline/View.svelte +45 -63
- package/src/plugins/resource-timeline/derived.js +167 -0
- package/src/plugins/resource-timeline/index.js +17 -21
- package/src/plugins/resource-timeline/lib.js +4 -65
- package/src/plugins/resource-timeline/state.svelte.js +18 -0
- package/src/plugins/time-grid/Day.svelte +7 -2
- package/src/plugins/time-grid/Event.svelte +6 -6
- package/src/plugins/time-grid/NowIndicator.svelte +10 -9
- package/src/plugins/time-grid/View.svelte +46 -59
- package/src/plugins/time-grid/derived.js +162 -0
- package/src/plugins/time-grid/index.js +31 -25
- package/src/plugins/time-grid/lib.js +18 -74
- package/src/plugins/time-grid/options.js +21 -16
- package/src/plugins/time-grid/state.svelte.js +44 -0
- package/src/storage/derived.js +144 -0
- package/src/storage/effects.js +156 -0
- package/src/storage/options.svelte.js +275 -0
- package/src/storage/state.svelte.js +69 -0
- package/src/styles/events.css +1 -1
- package/src/Auxiliary.svelte +0 -47
- package/src/lib/debounce.js +0 -20
- package/src/lib/stores.js +0 -63
- package/src/plugins/day-grid/lib.js +0 -61
- package/src/plugins/day-grid/stores.js +0 -5
- package/src/plugins/resource-time-grid/lib.js +0 -31
- package/src/plugins/resource-time-grid/stores.js +0 -34
- package/src/plugins/resource-timeline/Header.svelte +0 -44
- package/src/plugins/resource-timeline/Label.svelte +0 -38
- package/src/plugins/resource-timeline/stores.js +0 -48
- package/src/plugins/time-grid/stores.js +0 -49
- package/src/storage/options.js +0 -136
- package/src/storage/state.js +0 -168
- package/src/storage/stores.js +0 -234
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {btnTextDay, btnTextMonth, btnTextWeek, themeView} from '#lib';
|
|
2
|
-
import {
|
|
1
|
+
import {btnTextDay, btnTextMonth, btnTextWeek, getPayload, themeView} from '#lib';
|
|
2
|
+
import {setExtensions} from '../time-grid/lib.js';
|
|
3
3
|
import {createTRROptions, createTRRParsers} from '../time-grid/options.js';
|
|
4
|
-
import {createTRRStores} from '../time-grid/stores.js';
|
|
5
4
|
import {createRROptions} from '../resource-time-grid/options.js';
|
|
6
|
-
import {createRRStores} from '../resource-time-grid/stores.js';
|
|
7
5
|
import View from './View.svelte';
|
|
8
6
|
|
|
9
7
|
export default {
|
|
10
8
|
createOptions(options) {
|
|
11
9
|
createTRROptions(options);
|
|
12
10
|
createRROptions(options);
|
|
13
|
-
options.slotWidth =
|
|
11
|
+
options.slotWidth = 32;
|
|
14
12
|
// Common options
|
|
15
13
|
options.buttonText.resourceTimelineDay = 'timeline';
|
|
16
14
|
options.buttonText.resourceTimelineWeek = 'timeline';
|
|
@@ -21,27 +19,23 @@ export default {
|
|
|
21
19
|
options.view = 'resourceTimelineWeek';
|
|
22
20
|
options.views.resourceTimelineDay = {
|
|
23
21
|
buttonText: btnTextDay,
|
|
24
|
-
component:
|
|
22
|
+
component: initViewComponent,
|
|
25
23
|
displayEventEnd: false,
|
|
26
24
|
dayHeaderFormat: {weekday: 'long'},
|
|
27
25
|
duration: {days: 1},
|
|
28
|
-
slotLabelInterval: '01:00',
|
|
29
|
-
slotDuration: '00:15',
|
|
30
26
|
theme: themeView('ec-resource ec-timeline ec-day-view'),
|
|
31
27
|
titleFormat: {year: 'numeric', month: 'long', day: 'numeric'}
|
|
32
28
|
};
|
|
33
29
|
options.views.resourceTimelineWeek = {
|
|
34
30
|
buttonText: btnTextWeek,
|
|
35
|
-
component:
|
|
31
|
+
component: initViewComponent,
|
|
36
32
|
displayEventEnd: false,
|
|
37
33
|
duration: {weeks: 1},
|
|
38
|
-
slotLabelInterval: '01:00',
|
|
39
|
-
slotDuration: '00:15',
|
|
40
34
|
theme: themeView('ec-resource ec-timeline ec-week-view')
|
|
41
35
|
};
|
|
42
36
|
options.views.resourceTimelineMonth = {
|
|
43
37
|
buttonText: btnTextMonth,
|
|
44
|
-
component:
|
|
38
|
+
component: initMonthViewComponent,
|
|
45
39
|
displayEventEnd: false,
|
|
46
40
|
dayHeaderFormat: {
|
|
47
41
|
weekday: 'short',
|
|
@@ -56,14 +50,16 @@ export default {
|
|
|
56
50
|
|
|
57
51
|
createParsers(parsers) {
|
|
58
52
|
createTRRParsers(parsers);
|
|
59
|
-
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function initViewComponent(mainState) {
|
|
57
|
+
setExtensions(mainState);
|
|
58
|
+
return initMonthViewComponent(mainState);
|
|
59
|
+
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
state._daySlots = daySlots(state);
|
|
66
|
-
state._monthView = monthView(state);
|
|
67
|
-
state._nestedResources = nestedResources(state);
|
|
68
|
-
}
|
|
61
|
+
function initMonthViewComponent(mainState) {
|
|
62
|
+
mainState.features = ['timeline'];
|
|
63
|
+
mainState.extensions.viewResources = resources => resources.filter(resource => !getPayload(resource).hidden);
|
|
64
|
+
return View;
|
|
69
65
|
}
|
|
@@ -1,67 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addDay, addDuration, assign, bgEvent, cloneDate, createDuration, createEventChunk, datesEqual, eventIntersects, max,
|
|
3
|
-
min, outsideRange
|
|
4
|
-
} from '#lib';
|
|
1
|
+
import {assign, createDuration, createEventChunk, eventIntersects, max, min} from '#lib';
|
|
5
2
|
|
|
6
|
-
export function
|
|
7
|
-
let grid = [];
|
|
8
|
-
let gridRow = 1
|
|
9
|
-
for (let resource of $_viewResources) {
|
|
10
|
-
let days = [];
|
|
11
|
-
let gridColumn = 1;
|
|
12
|
-
for (let date of $_viewDates) {
|
|
13
|
-
let slotTimeLimits = $_dayTimeLimits[date.getTime()];
|
|
14
|
-
days.push({
|
|
15
|
-
gridColumn,
|
|
16
|
-
gridRow,
|
|
17
|
-
resource,
|
|
18
|
-
start: addDuration(cloneDate(date), slotTimeLimits.min),
|
|
19
|
-
end: addDuration(cloneDate(date), slotTimeLimits.max),
|
|
20
|
-
dayStart: date,
|
|
21
|
-
dayEnd: addDay(cloneDate(date)),
|
|
22
|
-
disabled: outsideRange(date, $validRange),
|
|
23
|
-
highlight: $highlightedDates.some(d => datesEqual(d, date))
|
|
24
|
-
});
|
|
25
|
-
++ gridColumn;
|
|
26
|
-
}
|
|
27
|
-
grid.push(days);
|
|
28
|
-
++ gridRow;
|
|
29
|
-
}
|
|
30
|
-
return grid;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function createEventChunks($_filteredEvents, grid) {
|
|
34
|
-
let chunks = [];
|
|
35
|
-
let bgChunks = [];
|
|
36
|
-
for (let event of $_filteredEvents) {
|
|
37
|
-
for (let days of grid) {
|
|
38
|
-
if (bgEvent(event.display)) {
|
|
39
|
-
bgChunks = bgChunks.concat(createChunks(event, days));
|
|
40
|
-
} else {
|
|
41
|
-
chunks = chunks.concat(createChunks(event, days));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
prepareChunks(chunks);
|
|
46
|
-
|
|
47
|
-
return {chunks, bgChunks};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function createIEventChunks($_iEvents, grid) {
|
|
51
|
-
let iChunks = [];
|
|
52
|
-
for (let event of $_iEvents) {
|
|
53
|
-
if (!event) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
for (let days of grid) {
|
|
57
|
-
iChunks = iChunks.concat(createChunks(event, days));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return iChunks;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function createChunks(event, days) {
|
|
3
|
+
export function createChunks(event, days) {
|
|
65
4
|
let dates = [];
|
|
66
5
|
let firstStart;
|
|
67
6
|
let lastEnd;
|
|
@@ -131,6 +70,6 @@ export function repositionEvent(chunk, height, monthView) {
|
|
|
131
70
|
return top;
|
|
132
71
|
}
|
|
133
72
|
|
|
134
|
-
export function getSlotTimeLimits(
|
|
135
|
-
return
|
|
73
|
+
export function getSlotTimeLimits(dayTimeLimits, date) {
|
|
74
|
+
return dayTimeLimits[date.getTime()] ?? {min: createDuration(0), max: createDuration('24:00:00')};
|
|
136
75
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {TRRState} from '../time-grid/state.svelte.js';
|
|
2
|
+
import {RRState} from '../resource-time-grid/state.svelte.js';
|
|
3
|
+
import {daySlots, dayTimeLimits, eventChunks, grid, iEventChunks, monthView, nestedResources} from './derived.js';
|
|
4
|
+
|
|
5
|
+
export default class ViewState extends RRState(TRRState()) {
|
|
6
|
+
constructor(mainState) {
|
|
7
|
+
super(mainState);
|
|
8
|
+
this.dayTimeLimits = $derived.by(dayTimeLimits(mainState)); // flexible time limits per day
|
|
9
|
+
this.daySlots = $derived.by(daySlots(mainState, this));
|
|
10
|
+
this.grid = $derived.by(grid(mainState, this));
|
|
11
|
+
let {chunks, bgChunks} = $derived.by(eventChunks(mainState, this));
|
|
12
|
+
this.chunks = $derived(chunks);
|
|
13
|
+
this.bgChunks = $derived(bgChunks);
|
|
14
|
+
this.iChunks = $derived.by(iEventChunks(mainState, this));
|
|
15
|
+
this.monthView = $derived.by(monthView(mainState));
|
|
16
|
+
this.nestedResources = $derived.by(nestedResources(mainState));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
let {day, allDay = false, noIeb, noBeb} = $props();
|
|
7
7
|
|
|
8
|
-
let {
|
|
8
|
+
let {options: {slotHeight}} = $derived(getContext('state'));
|
|
9
|
+
let {snap} = $derived(getContext('view-state'));
|
|
9
10
|
|
|
10
11
|
let {dayStart: date, start, resource, disabled, highlight} = $derived(day);
|
|
11
12
|
|
|
@@ -17,7 +18,11 @@
|
|
|
17
18
|
} else {
|
|
18
19
|
let dayRect = rect(el);
|
|
19
20
|
let scaleY = dayRect.height / el.offsetHeight;
|
|
20
|
-
return addDuration(
|
|
21
|
+
return addDuration(
|
|
22
|
+
cloneDate(start),
|
|
23
|
+
snap.duration,
|
|
24
|
+
floor((y - dayRect.top) / (slotHeight * snap.ratio * scaleY))
|
|
25
|
+
);
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
</script>
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
let {chunk} = $props();
|
|
7
7
|
|
|
8
|
-
let {slotEventOverlap, slotDuration, slotHeight} = getContext('state');
|
|
8
|
+
let {options: {slotEventOverlap, slotDuration, slotHeight}} = $derived(getContext('state'));
|
|
9
9
|
|
|
10
10
|
// Style
|
|
11
11
|
let styles = $derived(style => {
|
|
12
|
-
let step = toSeconds(
|
|
13
|
-
let top = chunk.top / step *
|
|
14
|
-
let height = chunk.height / step *
|
|
15
|
-
let maxHeight = chunk.maxHeight / step *
|
|
12
|
+
let step = toSeconds(slotDuration);
|
|
13
|
+
let top = chunk.top / step * slotHeight;
|
|
14
|
+
let height = chunk.height / step * slotHeight || slotHeight;
|
|
15
|
+
let maxHeight = chunk.maxHeight / step * slotHeight;
|
|
16
16
|
style['grid-column'] = chunk.gridColumn;
|
|
17
17
|
style['inset-block-start'] = `${top}px`;
|
|
18
18
|
style['min-block-size'] = `${height}px`;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
let groupColumns = chunk.group.columns.length;
|
|
24
24
|
style['z-index'] = `${chunk.groupColumn + 1}`;
|
|
25
25
|
style['inset-inline-start'] = `calc((${maxWidth}) / ${groupColumns} * ${chunk.groupColumn})`;
|
|
26
|
-
style['inline-size'] = `calc((${maxWidth}) / ${groupColumns} * ${(
|
|
26
|
+
style['inline-size'] = `calc((${maxWidth}) / ${groupColumns} * ${(slotEventOverlap ? 0.5 * (1 + groupColumns - chunk.groupColumn) : 1)})`;
|
|
27
27
|
}
|
|
28
28
|
return style;
|
|
29
29
|
});
|
|
@@ -4,39 +4,40 @@
|
|
|
4
4
|
|
|
5
5
|
let {days, span = 1} = $props();
|
|
6
6
|
|
|
7
|
-
let {
|
|
7
|
+
let {mainEl, now, today, options: {slotDuration, slotHeight, theme}} = $derived(getContext('state'));
|
|
8
|
+
let {sidebarWidth} = $derived(getContext('view-state'));
|
|
8
9
|
|
|
9
10
|
// Layout
|
|
10
11
|
let {gridColumn, start, end} = $derived.by(() => {
|
|
11
12
|
for (let day of days) {
|
|
12
|
-
if (datesEqual(day.dayStart,
|
|
13
|
+
if (datesEqual(day.dayStart, today)) {
|
|
13
14
|
return day;
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
return {};
|
|
17
18
|
});
|
|
18
19
|
let top = $derived.by(() => {
|
|
19
|
-
if (
|
|
20
|
+
if (now < start || now > end) {
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
|
-
let step = toSeconds(
|
|
23
|
-
return (
|
|
23
|
+
let step = toSeconds(slotDuration);
|
|
24
|
+
return (now - start) / 1000 / step * slotHeight;
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
// Observe intersections
|
|
27
28
|
let observerOptions = $derived({
|
|
28
|
-
root:
|
|
29
|
-
rootMargin: isRtl() ? `0px -${
|
|
29
|
+
root: mainEl,
|
|
30
|
+
rootMargin: isRtl() ? `0px -${sidebarWidth + 5.5}px 0px 0px` : `0px 0px 0px -${sidebarWidth + 5.5}px`,
|
|
30
31
|
threshold: 0.0,
|
|
31
32
|
});
|
|
32
33
|
function onIntersect(el, entry) {
|
|
33
|
-
el.classList.toggle(
|
|
34
|
+
el.classList.toggle(theme.hidden, !entry.isIntersecting);
|
|
34
35
|
}
|
|
35
36
|
</script>
|
|
36
37
|
|
|
37
38
|
{#if gridColumn && top !== null}
|
|
38
39
|
<div {@attach intersectionObserver(onIntersect, observerOptions)}
|
|
39
|
-
class="{
|
|
40
|
+
class="{theme.nowIndicator}"
|
|
40
41
|
style:grid-column="{gridColumn + 1} / span {span}"
|
|
41
42
|
style:inset-block-start="{top}px"
|
|
42
43
|
></div>
|
|
@@ -1,55 +1,42 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext, tick} from 'svelte';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '#lib';
|
|
7
|
-
import {createAllDayContent, createGrid, createEventChunks, createIEventChunks} from './lib.js';
|
|
2
|
+
import {getContext, setContext, tick} from 'svelte';
|
|
3
|
+
import {contentFrom, resizeObserver, runReposition, toSeconds} from '#lib';
|
|
4
|
+
import {createAllDayContent} from './lib.js';
|
|
5
|
+
import ViewState from './state.svelte.js';
|
|
8
6
|
import {ColHead, DayHeader} from '#components';
|
|
9
7
|
import Day from './Day.svelte';
|
|
10
8
|
import Event from './Event.svelte';
|
|
11
9
|
import AllDayEvent from './AllDayEvent.svelte';
|
|
12
10
|
import NowIndicator from './NowIndicator.svelte';
|
|
13
11
|
|
|
14
|
-
let {header, nowIndicator,
|
|
12
|
+
let {header, nowIndicator, viewState} = $props();
|
|
15
13
|
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
let mainState = getContext('state');
|
|
15
|
+
// svelte-ignore state_referenced_locally
|
|
16
|
+
if (!viewState) {
|
|
17
|
+
viewState = new ViewState(mainState);
|
|
18
|
+
}
|
|
19
|
+
// svelte-ignore state_referenced_locally
|
|
20
|
+
setContext('view-state', viewState);
|
|
22
21
|
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
let {
|
|
22
|
+
let {mainEl, viewDates, options: {allDayContent, allDaySlot, columnWidth, nowIndicator: showNowIndicator,
|
|
23
|
+
scrollTime, slotHeight, slotDuration, theme}} = $derived(mainState);
|
|
24
|
+
let {allDayChunks, allDayBgChunks, allDayIChunks, bgChunks, chunks, iChunks, grid, sidebarWidth, slots,
|
|
25
|
+
slotLabelPeriodicity, slotTimeLimits} = $derived(viewState);
|
|
26
26
|
|
|
27
|
-
$
|
|
28
|
-
|
|
29
|
-
if ($slotMaxTime.days || $slotMaxTime.seconds > DAY_IN_SECONDS) {
|
|
30
|
-
addDuration(subtractDay(end), $slotMaxTime);
|
|
31
|
-
let start2 = subtractDay(cloneDate(end));
|
|
32
|
-
if (start2 < start) {
|
|
33
|
-
start = start2;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return {start, end};
|
|
37
|
-
};
|
|
38
|
-
return () => {
|
|
39
|
-
$_activeRangeExt = identity;
|
|
40
|
-
};
|
|
41
|
-
});
|
|
27
|
+
let headerHeight = $state(0);
|
|
28
|
+
let allDayText = $derived(createAllDayContent(allDayContent));
|
|
42
29
|
|
|
43
30
|
// Handle scrollTime
|
|
44
31
|
$effect(() => {
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
viewDates;
|
|
33
|
+
scrollTime;
|
|
47
34
|
tick().then(scrollToTime);
|
|
48
35
|
});
|
|
49
36
|
function scrollToTime() {
|
|
50
|
-
|
|
51
|
-
(toSeconds(
|
|
52
|
-
) *
|
|
37
|
+
mainEl.scrollTop = (
|
|
38
|
+
(toSeconds(scrollTime) - toSeconds(slotTimeLimits.min)) / toSeconds(slotDuration) - 0.5
|
|
39
|
+
) * slotHeight;
|
|
53
40
|
}
|
|
54
41
|
|
|
55
42
|
// Events reposition
|
|
@@ -61,22 +48,22 @@
|
|
|
61
48
|
</script>
|
|
62
49
|
|
|
63
50
|
<section
|
|
64
|
-
bind:this={
|
|
65
|
-
class="{
|
|
51
|
+
bind:this={mainState.mainEl}
|
|
52
|
+
class="{theme.main}"
|
|
66
53
|
style:--ec-grid-cols="{grid.length * grid[0].length}"
|
|
67
54
|
style:--ec-col-group-span="{grid[0].length}"
|
|
68
|
-
style:--ec-col-width="{
|
|
69
|
-
style:--ec-slot-label-periodicity="{
|
|
70
|
-
style:--ec-slot-height="{
|
|
55
|
+
style:--ec-col-width="{columnWidth ?? 'minmax(0, 1fr)'}"
|
|
56
|
+
style:--ec-slot-label-periodicity="{slotLabelPeriodicity}"
|
|
57
|
+
style:--ec-slot-height="{slotHeight}px"
|
|
71
58
|
style:--ec-header-height="{headerHeight}px"
|
|
72
|
-
style:--ec-sidebar-width="{
|
|
59
|
+
style:--ec-sidebar-width="{sidebarWidth}px"
|
|
73
60
|
{@attach resizeObserver(reposition)}
|
|
74
61
|
>
|
|
75
|
-
<header bind:offsetHeight={headerHeight} class="{
|
|
76
|
-
<aside class="{
|
|
77
|
-
<div class="{
|
|
62
|
+
<header bind:offsetHeight={headerHeight} class="{theme.header}">
|
|
63
|
+
<aside class="{theme.sidebar}" bind:offsetWidth={viewState.sidebarWidth}></aside>
|
|
64
|
+
<div class="{theme.grid}" role="row">
|
|
78
65
|
{#if header}
|
|
79
|
-
{@render header(
|
|
66
|
+
{@render header()}
|
|
80
67
|
{:else}
|
|
81
68
|
{#each grid[0] as {dayStart: date, disabled, highlight}, i}
|
|
82
69
|
<ColHead {date} colIndex={1 + i} {disabled} {highlight}>
|
|
@@ -86,17 +73,17 @@
|
|
|
86
73
|
{/if}
|
|
87
74
|
</div>
|
|
88
75
|
|
|
89
|
-
{#if
|
|
90
|
-
<div class="{
|
|
91
|
-
<aside class="{
|
|
92
|
-
<div class="{
|
|
76
|
+
{#if allDaySlot}
|
|
77
|
+
<div class="{theme.allDay}">
|
|
78
|
+
<aside class="{theme.sidebar}" {@attach contentFrom(allDayText)}></aside>
|
|
79
|
+
<div class="{theme.grid}" role="row">
|
|
93
80
|
{#each grid as days, i}
|
|
94
81
|
{#each days as day, j}
|
|
95
82
|
<Day {day} allDay noIeb={i + 1 === grid.length && j + 1 === days.length}/>
|
|
96
83
|
{/each}
|
|
97
84
|
{/each}
|
|
98
85
|
</div>
|
|
99
|
-
<div class="{
|
|
86
|
+
<div class="{theme.events}">
|
|
100
87
|
{#each allDayChunks as chunk, i}
|
|
101
88
|
<!-- svelte-ignore binding_property_non_reactive -->
|
|
102
89
|
<AllDayEvent bind:this={refs[i]} {chunk}/>
|
|
@@ -112,11 +99,11 @@
|
|
|
112
99
|
{/if}
|
|
113
100
|
</header>
|
|
114
101
|
|
|
115
|
-
<div class="{
|
|
116
|
-
<aside class="{
|
|
117
|
-
{#each
|
|
102
|
+
<div class="{theme.body}" role="rowgroup">
|
|
103
|
+
<aside class="{theme.sidebar}" aria-hidden="true">
|
|
104
|
+
{#each slots as slot, i}
|
|
118
105
|
<div
|
|
119
|
-
class={[
|
|
106
|
+
class={[theme.slot, !i && theme.hidden]}
|
|
120
107
|
style:--ec-slot-label-periodicity={slot[2]}
|
|
121
108
|
>
|
|
122
109
|
<time
|
|
@@ -126,14 +113,14 @@
|
|
|
126
113
|
</div>
|
|
127
114
|
{/each}
|
|
128
115
|
</aside>
|
|
129
|
-
<div class="{
|
|
116
|
+
<div class="{theme.grid}" role="row">
|
|
130
117
|
{#each grid as days, i}
|
|
131
118
|
{#each days as day, j}
|
|
132
119
|
<Day {day} noIeb={i + 1 === grid.length && j + 1 === days.length} noBeb/>
|
|
133
120
|
{/each}
|
|
134
121
|
{/each}
|
|
135
122
|
</div>
|
|
136
|
-
<div class="{
|
|
123
|
+
<div class="{theme.events}">
|
|
137
124
|
{#each chunks as chunk}
|
|
138
125
|
<Event {chunk}/>
|
|
139
126
|
{/each}
|
|
@@ -146,9 +133,9 @@
|
|
|
146
133
|
</div>
|
|
147
134
|
</div>
|
|
148
135
|
|
|
149
|
-
{#if
|
|
136
|
+
{#if showNowIndicator}
|
|
150
137
|
{#if nowIndicator}
|
|
151
|
-
{@render nowIndicator(
|
|
138
|
+
{@render nowIndicator()}
|
|
152
139
|
{:else}
|
|
153
140
|
<NowIndicator days={grid[0]}/>
|
|
154
141
|
{/if}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {untrack} from 'svelte';
|
|
2
|
+
import {
|
|
3
|
+
addDay, addDuration, bgEvent, ceil, cloneDate, createAllDayChunks, createDate, createSlots, createSlotTimeLimits,
|
|
4
|
+
datesEqual, outsideRange, prepareAllDayChunks, setMidnight, toSeconds
|
|
5
|
+
} from '#lib';
|
|
6
|
+
import {createChunks, groupChunks} from './lib.js';
|
|
7
|
+
|
|
8
|
+
export function grid(mainState, viewState) {
|
|
9
|
+
return () => {
|
|
10
|
+
// Dependencies
|
|
11
|
+
let {viewDates, options: {highlightedDates, validRange}} = mainState;
|
|
12
|
+
let {slotTimeLimits} = viewState;
|
|
13
|
+
|
|
14
|
+
let days = [];
|
|
15
|
+
|
|
16
|
+
untrack(() => {
|
|
17
|
+
let gridColumn = 1;
|
|
18
|
+
for (let date of viewDates) {
|
|
19
|
+
days.push({
|
|
20
|
+
gridColumn,
|
|
21
|
+
gridRow: 1,
|
|
22
|
+
resource: undefined,
|
|
23
|
+
start: addDuration(cloneDate(date), slotTimeLimits.min),
|
|
24
|
+
end: addDuration(cloneDate(date), slotTimeLimits.max),
|
|
25
|
+
dayStart: date,
|
|
26
|
+
dayEnd: addDay(cloneDate(date)),
|
|
27
|
+
disabled: outsideRange(date, validRange),
|
|
28
|
+
highlight: highlightedDates.some(d => datesEqual(d, date))
|
|
29
|
+
});
|
|
30
|
+
++gridColumn;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return [days];
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function eventChunks(mainState, viewState) {
|
|
39
|
+
return () => {
|
|
40
|
+
// Dependencies
|
|
41
|
+
let {filteredEvents} = mainState;
|
|
42
|
+
let {grid} = viewState;
|
|
43
|
+
|
|
44
|
+
let chunks = [];
|
|
45
|
+
let bgChunks = [];
|
|
46
|
+
let allDayChunks = [];
|
|
47
|
+
let allDayBgChunks = [];
|
|
48
|
+
|
|
49
|
+
untrack(() => {
|
|
50
|
+
for (let event of filteredEvents) {
|
|
51
|
+
for (let days of grid) {
|
|
52
|
+
if (bgEvent(event.display)) {
|
|
53
|
+
bgChunks = bgChunks.concat(createChunks(event, days));
|
|
54
|
+
if (event.allDay) {
|
|
55
|
+
allDayBgChunks = allDayBgChunks.concat(createAllDayChunks(event, days));
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
if (event.allDay) {
|
|
59
|
+
allDayChunks = allDayChunks.concat(createAllDayChunks(event, days));
|
|
60
|
+
} else {
|
|
61
|
+
chunks = chunks.concat(createChunks(event, days));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
groupChunks(chunks);
|
|
67
|
+
prepareAllDayChunks(allDayChunks);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return {chunks, bgChunks, allDayChunks, allDayBgChunks};
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function iEventChunks(mainState, viewState) {
|
|
75
|
+
return () => {
|
|
76
|
+
// Dependencies
|
|
77
|
+
let {iEvents} = mainState;
|
|
78
|
+
let {grid} = viewState;
|
|
79
|
+
|
|
80
|
+
let iChunks = [];
|
|
81
|
+
let allDayIChunks = [];
|
|
82
|
+
|
|
83
|
+
for (let [, event] of iEvents) {
|
|
84
|
+
if (!event) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
untrack(() => {
|
|
88
|
+
for (let days of grid) {
|
|
89
|
+
if (event.allDay) {
|
|
90
|
+
allDayIChunks = allDayIChunks.concat(createAllDayChunks(event, days));
|
|
91
|
+
} else {
|
|
92
|
+
iChunks = iChunks.concat(createChunks(event, days));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {iChunks, allDayIChunks};
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function slotTimeLimits(mainState) {
|
|
103
|
+
return () => {
|
|
104
|
+
// Dependencies
|
|
105
|
+
let {filteredEvents, viewDates, options: {flexibleSlotTimeLimits, slotMinTime, slotMaxTime}} = mainState;
|
|
106
|
+
|
|
107
|
+
let limits;
|
|
108
|
+
|
|
109
|
+
untrack(() => {
|
|
110
|
+
limits = createSlotTimeLimits(slotMinTime, slotMaxTime, flexibleSlotTimeLimits, viewDates, filteredEvents);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return limits;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function slotLabelPeriodicity(mainState) {
|
|
118
|
+
return () => {
|
|
119
|
+
// Dependencies
|
|
120
|
+
let {options: {slotDuration, slotLabelInterval}} = mainState;
|
|
121
|
+
|
|
122
|
+
let periodicity;
|
|
123
|
+
|
|
124
|
+
untrack(() => {
|
|
125
|
+
periodicity = slotLabelInterval === undefined
|
|
126
|
+
? toSeconds(slotDuration) < 3600 ? 2 : 1
|
|
127
|
+
: (ceil(toSeconds(slotLabelInterval) / toSeconds(slotDuration)) || 1)
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return periodicity;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function slots(mainState, viewState) {
|
|
135
|
+
return () => {
|
|
136
|
+
// Dependencies
|
|
137
|
+
let {options: {slotDuration}} = mainState;
|
|
138
|
+
let {intlSlotLabel, slotLabelPeriodicity, slotTimeLimits} = viewState;
|
|
139
|
+
|
|
140
|
+
let slots;
|
|
141
|
+
|
|
142
|
+
untrack(() => {
|
|
143
|
+
slots = createSlots(setMidnight(createDate()), slotDuration, slotLabelPeriodicity, slotTimeLimits, intlSlotLabel);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return slots;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function snap(mainState) {
|
|
151
|
+
return () => {
|
|
152
|
+
// Dependencies
|
|
153
|
+
let {options: {slotDuration, snapDuration}} = mainState;
|
|
154
|
+
|
|
155
|
+
snapDuration ??= slotDuration;
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
duration: snapDuration,
|
|
159
|
+
ratio: toSeconds(snapDuration) / toSeconds(slotDuration)
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
}
|