@event-calendar/core 5.0.6 → 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 +2200 -2122
- 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 -33
- 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 +17 -16
- 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 -60
- 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 -55
- 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,51 +1,42 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext, tick} from 'svelte';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
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';
|
|
7
6
|
import {ColHead, DayHeader} from '#components';
|
|
8
7
|
import Day from './Day.svelte';
|
|
9
8
|
import Event from './Event.svelte';
|
|
10
9
|
import AllDayEvent from './AllDayEvent.svelte';
|
|
11
10
|
import NowIndicator from './NowIndicator.svelte';
|
|
12
11
|
|
|
13
|
-
let {header, nowIndicator,
|
|
12
|
+
let {header, nowIndicator, viewState} = $props();
|
|
14
13
|
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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);
|
|
21
21
|
|
|
22
|
-
let
|
|
23
|
-
|
|
24
|
-
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);
|
|
25
26
|
|
|
26
|
-
$
|
|
27
|
-
|
|
28
|
-
if ($slotMaxTime.days || $slotMaxTime.seconds > DAY_IN_SECONDS) {
|
|
29
|
-
addDuration(subtractDay(end), $slotMaxTime);
|
|
30
|
-
let start2 = subtractDay(cloneDate(end));
|
|
31
|
-
if (start2 < start) {
|
|
32
|
-
start = start2;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return {start, end};
|
|
36
|
-
};
|
|
37
|
-
});
|
|
27
|
+
let headerHeight = $state(0);
|
|
28
|
+
let allDayText = $derived(createAllDayContent(allDayContent));
|
|
38
29
|
|
|
39
30
|
// Handle scrollTime
|
|
40
31
|
$effect(() => {
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
viewDates;
|
|
33
|
+
scrollTime;
|
|
43
34
|
tick().then(scrollToTime);
|
|
44
35
|
});
|
|
45
36
|
function scrollToTime() {
|
|
46
|
-
|
|
47
|
-
(toSeconds(
|
|
48
|
-
) *
|
|
37
|
+
mainEl.scrollTop = (
|
|
38
|
+
(toSeconds(scrollTime) - toSeconds(slotTimeLimits.min)) / toSeconds(slotDuration) - 0.5
|
|
39
|
+
) * slotHeight;
|
|
49
40
|
}
|
|
50
41
|
|
|
51
42
|
// Events reposition
|
|
@@ -57,22 +48,22 @@
|
|
|
57
48
|
</script>
|
|
58
49
|
|
|
59
50
|
<section
|
|
60
|
-
bind:this={
|
|
61
|
-
class="{
|
|
51
|
+
bind:this={mainState.mainEl}
|
|
52
|
+
class="{theme.main}"
|
|
62
53
|
style:--ec-grid-cols="{grid.length * grid[0].length}"
|
|
63
54
|
style:--ec-col-group-span="{grid[0].length}"
|
|
64
|
-
style:--ec-col-width="{
|
|
65
|
-
style:--ec-slot-label-periodicity="{
|
|
66
|
-
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"
|
|
67
58
|
style:--ec-header-height="{headerHeight}px"
|
|
68
|
-
style:--ec-sidebar-width="{
|
|
59
|
+
style:--ec-sidebar-width="{sidebarWidth}px"
|
|
69
60
|
{@attach resizeObserver(reposition)}
|
|
70
61
|
>
|
|
71
|
-
<header bind:offsetHeight={headerHeight} class="{
|
|
72
|
-
<aside class="{
|
|
73
|
-
<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">
|
|
74
65
|
{#if header}
|
|
75
|
-
{@render header(
|
|
66
|
+
{@render header()}
|
|
76
67
|
{:else}
|
|
77
68
|
{#each grid[0] as {dayStart: date, disabled, highlight}, i}
|
|
78
69
|
<ColHead {date} colIndex={1 + i} {disabled} {highlight}>
|
|
@@ -82,17 +73,17 @@
|
|
|
82
73
|
{/if}
|
|
83
74
|
</div>
|
|
84
75
|
|
|
85
|
-
{#if
|
|
86
|
-
<div class="{
|
|
87
|
-
<aside class="{
|
|
88
|
-
<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">
|
|
89
80
|
{#each grid as days, i}
|
|
90
81
|
{#each days as day, j}
|
|
91
82
|
<Day {day} allDay noIeb={i + 1 === grid.length && j + 1 === days.length}/>
|
|
92
83
|
{/each}
|
|
93
84
|
{/each}
|
|
94
85
|
</div>
|
|
95
|
-
<div class="{
|
|
86
|
+
<div class="{theme.events}">
|
|
96
87
|
{#each allDayChunks as chunk, i}
|
|
97
88
|
<!-- svelte-ignore binding_property_non_reactive -->
|
|
98
89
|
<AllDayEvent bind:this={refs[i]} {chunk}/>
|
|
@@ -108,11 +99,11 @@
|
|
|
108
99
|
{/if}
|
|
109
100
|
</header>
|
|
110
101
|
|
|
111
|
-
<div class="{
|
|
112
|
-
<aside class="{
|
|
113
|
-
{#each
|
|
102
|
+
<div class="{theme.body}" role="rowgroup">
|
|
103
|
+
<aside class="{theme.sidebar}" aria-hidden="true">
|
|
104
|
+
{#each slots as slot, i}
|
|
114
105
|
<div
|
|
115
|
-
class={[
|
|
106
|
+
class={[theme.slot, !i && theme.hidden]}
|
|
116
107
|
style:--ec-slot-label-periodicity={slot[2]}
|
|
117
108
|
>
|
|
118
109
|
<time
|
|
@@ -122,14 +113,14 @@
|
|
|
122
113
|
</div>
|
|
123
114
|
{/each}
|
|
124
115
|
</aside>
|
|
125
|
-
<div class="{
|
|
116
|
+
<div class="{theme.grid}" role="row">
|
|
126
117
|
{#each grid as days, i}
|
|
127
118
|
{#each days as day, j}
|
|
128
119
|
<Day {day} noIeb={i + 1 === grid.length && j + 1 === days.length} noBeb/>
|
|
129
120
|
{/each}
|
|
130
121
|
{/each}
|
|
131
122
|
</div>
|
|
132
|
-
<div class="{
|
|
123
|
+
<div class="{theme.events}">
|
|
133
124
|
{#each chunks as chunk}
|
|
134
125
|
<Event {chunk}/>
|
|
135
126
|
{/each}
|
|
@@ -142,9 +133,9 @@
|
|
|
142
133
|
</div>
|
|
143
134
|
</div>
|
|
144
135
|
|
|
145
|
-
{#if
|
|
136
|
+
{#if showNowIndicator}
|
|
146
137
|
{#if nowIndicator}
|
|
147
|
-
{@render nowIndicator(
|
|
138
|
+
{@render nowIndicator()}
|
|
148
139
|
{:else}
|
|
149
140
|
<NowIndicator days={grid[0]}/>
|
|
150
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
|
+
}
|