@event-calendar/core 4.7.1 → 5.0.1
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 +636 -731
- package/dist/index.js +2576 -3178
- 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 +44 -43
- 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 +55 -83
- package/src/plugins/resource-time-grid/index.js +19 -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 +35 -10
- package/src/plugins/time-grid/View.svelte +129 -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 +43 -12
- 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 +60 -0
- package/src/styles/slots.css +42 -0
- package/src/styles/theme.css +68 -0
- package/src/styles/toolbar.css +88 -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
|
@@ -1,109 +1,21 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
setPayload
|
|
6
|
-
} from '#lib';
|
|
7
|
-
import {groupEventChunks} from './utils.js';
|
|
8
|
-
import Event from './Event.svelte';
|
|
9
|
-
import NowIndicator from './NowIndicator.svelte';
|
|
2
|
+
import {getContext} from 'svelte';
|
|
3
|
+
import {addDuration, cloneDate, floor, rect} from '#lib';
|
|
4
|
+
import {BaseDay} from '#components';
|
|
10
5
|
|
|
11
|
-
let {
|
|
6
|
+
let {day, allDay = false} = $props();
|
|
12
7
|
|
|
13
|
-
let {
|
|
14
|
-
eventOrder, theme, resources, validRange, _interaction, _today, _slotTimeLimits} = getContext('state');
|
|
8
|
+
let {slotDuration, slotHeight} = getContext('state');
|
|
15
9
|
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
let isToday = $derived(datesEqual(date, $_today));
|
|
19
|
-
let highlight = $derived($highlightedDates.some(d => datesEqual(d, date)));
|
|
20
|
-
let disabled = $derived(outsideRange(date, $validRange));
|
|
21
|
-
|
|
22
|
-
let start = $derived(addDuration(cloneDate(date), $_slotTimeLimits.min));
|
|
23
|
-
let end = $derived(addDuration(cloneDate(date), $_slotTimeLimits.max));
|
|
24
|
-
|
|
25
|
-
let resourceFilter = $derived(resource ?? ($filterEventsWithResources ? $resources : undefined));
|
|
10
|
+
let {dayStart: date, start, resource, disabled, highlight} = $derived(day);
|
|
26
11
|
|
|
27
|
-
let
|
|
28
|
-
if (disabled) {
|
|
29
|
-
return [[], []];
|
|
30
|
-
}
|
|
31
|
-
let chunks = [];
|
|
32
|
-
let bgChunks = [];
|
|
33
|
-
for (let event of $_filteredEvents) {
|
|
34
|
-
if ((!event.allDay || bgEvent(event.display)) && eventIntersects(event, start, end, resourceFilter)) {
|
|
35
|
-
let chunk = createEventChunk(event, start, end);
|
|
36
|
-
switch (event.display) {
|
|
37
|
-
case 'background': bgChunks.push(chunk); break;
|
|
38
|
-
default: chunks.push(chunk);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
groupEventChunks(chunks, $eventOrder);
|
|
43
|
-
return [chunks, bgChunks];
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
let iChunks = $derived.by(() => {
|
|
47
|
-
if (disabled) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
return $_iEvents.map(
|
|
51
|
-
event => event && eventIntersects(event, start, end, resource) ? createEventChunk(event, start, end) : null
|
|
52
|
-
);
|
|
53
|
-
});
|
|
12
|
+
let el = $state();
|
|
54
13
|
|
|
55
14
|
function dateFromPoint(x, y) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
date: addDuration(
|
|
60
|
-
addDuration(cloneDate(date), $_slotTimeLimits.min),
|
|
61
|
-
$slotDuration,
|
|
62
|
-
floor(y / $slotHeight)
|
|
63
|
-
),
|
|
64
|
-
resource,
|
|
65
|
-
dayEl: el,
|
|
66
|
-
disabled
|
|
67
|
-
};
|
|
15
|
+
return allDay
|
|
16
|
+
? date
|
|
17
|
+
: addDuration(cloneDate(start), $slotDuration, floor((y - rect(el).top) / $slotHeight));
|
|
68
18
|
}
|
|
69
|
-
|
|
70
|
-
onMount(() => {
|
|
71
|
-
setPayload(el, dateFromPoint);
|
|
72
|
-
});
|
|
73
19
|
</script>
|
|
74
20
|
|
|
75
|
-
<
|
|
76
|
-
bind:this={el}
|
|
77
|
-
class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{isToday ? ' ' + $theme.today : ''}{highlight ? ' ' + $theme.highlight : ''}{disabled ? ' ' + $theme.disabled : ''}"
|
|
78
|
-
role="cell"
|
|
79
|
-
onpointerdown={!disabled ? $_interaction.action?.select : undefined}
|
|
80
|
-
>
|
|
81
|
-
<div class="{$theme.bgEvents}">
|
|
82
|
-
{#if !disabled}
|
|
83
|
-
{#each bgChunks as chunk (chunk.event)}
|
|
84
|
-
<Event {date} {chunk}/>
|
|
85
|
-
{/each}
|
|
86
|
-
{/if}
|
|
87
|
-
</div>
|
|
88
|
-
<div class="{$theme.events}">
|
|
89
|
-
{#if !disabled}
|
|
90
|
-
<!-- Pointer -->
|
|
91
|
-
{#if iChunks[1]}
|
|
92
|
-
<Event {date} chunk={iChunks[1]}/>
|
|
93
|
-
{/if}
|
|
94
|
-
{#each chunks as chunk (chunk.event)}
|
|
95
|
-
<Event {date} {chunk}/>
|
|
96
|
-
{/each}
|
|
97
|
-
<!-- Drag, Resize & Select -->
|
|
98
|
-
{#if iChunks[0] && !iChunks[0].event.allDay}
|
|
99
|
-
<Event {date} chunk={iChunks[0]}/>
|
|
100
|
-
{/if}
|
|
101
|
-
{/if}
|
|
102
|
-
</div>
|
|
103
|
-
<div class="{$theme.extra}">
|
|
104
|
-
<!-- Now indicator -->
|
|
105
|
-
{#if $nowIndicator && isToday && !disabled}
|
|
106
|
-
<NowIndicator />
|
|
107
|
-
{/if}
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
21
|
+
<BaseDay bind:el {date} {allDay} {resource} {dateFromPoint} {disabled} {highlight}/>
|
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {
|
|
3
|
+
import {toSeconds} from '#lib';
|
|
4
4
|
import {InteractableEvent} from '#components';
|
|
5
5
|
|
|
6
|
-
let {
|
|
6
|
+
let {chunk} = $props();
|
|
7
7
|
|
|
8
|
-
let {slotEventOverlap, slotDuration, slotHeight
|
|
9
|
-
|
|
10
|
-
let display = $derived(chunk.event.display);
|
|
8
|
+
let {slotEventOverlap, slotDuration, slotHeight} = getContext('state');
|
|
11
9
|
|
|
12
10
|
// Style
|
|
13
11
|
let styles = $derived(style => {
|
|
14
|
-
let step = $slotDuration
|
|
15
|
-
let
|
|
16
|
-
let
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
style['
|
|
22
|
-
style['
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
style['z-index'] = `${chunk.
|
|
27
|
-
style['
|
|
28
|
-
style['
|
|
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
|
+
style['grid-column'] = chunk.gridColumn;
|
|
17
|
+
style['inset-block-start'] = `${top}px`;
|
|
18
|
+
style['min-block-size'] = `${height}px`;
|
|
19
|
+
style['block-size'] = `${height}px`;
|
|
20
|
+
style['max-block-size'] = `${maxHeight}px`;
|
|
21
|
+
let maxWidth = '100% - var(--ec-event-col-gap)';
|
|
22
|
+
if (chunk.group) {
|
|
23
|
+
let groupColumns = chunk.group.columns.length;
|
|
24
|
+
style['z-index'] = `${chunk.groupColumn + 1}`;
|
|
25
|
+
style['inset-inline-start'] = `calc((${maxWidth}) / ${groupColumns} * ${chunk.groupColumn})`;
|
|
26
|
+
style['inline-size'] = `calc((${maxWidth}) / ${groupColumns} * ${($slotEventOverlap ? 0.5 * (1 + groupColumns - chunk.groupColumn) : 1)})`;
|
|
29
27
|
}
|
|
30
28
|
return style;
|
|
31
29
|
});
|
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
+
import {datesEqual, toSeconds, intersectionObserver} from '#lib';
|
|
3
4
|
|
|
4
|
-
let {
|
|
5
|
+
let {days, span = 1} = $props();
|
|
5
6
|
|
|
6
|
-
let
|
|
7
|
-
|
|
7
|
+
let {_mainEl, _now, _today, _sidebarWidth, slotDuration, slotHeight, theme} = getContext('state');
|
|
8
|
+
|
|
9
|
+
// Layout
|
|
10
|
+
let {gridColumn, start, end} = $derived.by(() => {
|
|
11
|
+
for (let day of days) {
|
|
12
|
+
if (datesEqual(day.dayStart, $_today)) {
|
|
13
|
+
return day;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return {};
|
|
17
|
+
});
|
|
8
18
|
let top = $derived.by(() => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
19
|
+
if ($_now < start || $_now > end) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
let step = toSeconds($slotDuration);
|
|
23
|
+
return ($_now - start) / 1000 / step * $slotHeight;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Observe intersections
|
|
27
|
+
let observerOptions = $derived({
|
|
28
|
+
root: $_mainEl,
|
|
29
|
+
rootMargin: `0px 0px 0px -${$_sidebarWidth + 5.5}px`,
|
|
30
|
+
threshold: 0.0,
|
|
12
31
|
});
|
|
32
|
+
function onIntersect(el, entry) {
|
|
33
|
+
el.classList.toggle($theme.hidden, !entry.isIntersecting);
|
|
34
|
+
}
|
|
13
35
|
</script>
|
|
14
36
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
37
|
+
{#if gridColumn && top !== null}
|
|
38
|
+
<div {@attach intersectionObserver(onIntersect, observerOptions)}
|
|
39
|
+
class="{$theme.nowIndicator}"
|
|
40
|
+
style:grid-column="{gridColumn + 1} / span {span}"
|
|
41
|
+
style:inset-block-start="{top}px"
|
|
42
|
+
></div>
|
|
43
|
+
{/if}
|
|
@@ -1,43 +1,137 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext} from 'svelte';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import {getContext, tick} from 'svelte';
|
|
3
|
+
import {contentFrom, resizeObserver, runReposition, toSeconds} from '#lib';
|
|
4
|
+
import {createAllDayContent, createGrid, createEventChunks, createIEventChunks} from './lib.js';
|
|
5
|
+
import {ColHead, DayHeader} from '#components';
|
|
6
6
|
import Day from './Day.svelte';
|
|
7
|
-
import
|
|
7
|
+
import Event from './Event.svelte';
|
|
8
|
+
import AllDayEvent from './AllDayEvent.svelte';
|
|
9
|
+
import NowIndicator from './NowIndicator.svelte';
|
|
8
10
|
|
|
9
|
-
let {
|
|
11
|
+
let {header, nowIndicator, createGridFn} = $props();
|
|
12
|
+
|
|
13
|
+
let {_mainEl, _filteredEvents, _iEvents, _sidebarWidth, _slotLabelPeriodicity, _slotTimeLimits, _slots,
|
|
14
|
+
_viewDates, allDayContent, allDaySlot, columnWidth, highlightedDates, nowIndicator: showNowIndicator,
|
|
15
|
+
scrollTime, slotHeight, slotDuration, theme, validRange} = getContext('state');
|
|
16
|
+
|
|
17
|
+
let headerHeight = $state(0);
|
|
18
|
+
let allDayText = $derived(createAllDayContent($allDayContent));
|
|
19
|
+
|
|
20
|
+
let grid = $derived(createGridFn?.() ?? createGrid($_viewDates, $_slotTimeLimits, $validRange, $highlightedDates));
|
|
21
|
+
let {chunks, bgChunks, allDayChunks, allDayBgChunks} = $derived(createEventChunks($_filteredEvents, grid));
|
|
22
|
+
let {iChunks, allDayIChunks} = $derived(createIEventChunks($_iEvents, grid));
|
|
23
|
+
|
|
24
|
+
// Handle scrollTime
|
|
25
|
+
$effect(() => {
|
|
26
|
+
$_viewDates;
|
|
27
|
+
$scrollTime;
|
|
28
|
+
tick().then(scrollToTime);
|
|
29
|
+
});
|
|
30
|
+
function scrollToTime() {
|
|
31
|
+
$_mainEl.scrollTop = (
|
|
32
|
+
(toSeconds($scrollTime) - toSeconds($_slotTimeLimits.min)) / toSeconds($slotDuration) - 0.5
|
|
33
|
+
) * $slotHeight;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Events reposition
|
|
37
|
+
let refs = [];
|
|
38
|
+
function reposition() {
|
|
39
|
+
runReposition(refs, allDayChunks);
|
|
40
|
+
}
|
|
41
|
+
$effect(reposition);
|
|
10
42
|
</script>
|
|
11
43
|
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
<section
|
|
45
|
+
bind:this={$_mainEl}
|
|
46
|
+
class="{$theme.main}"
|
|
47
|
+
style:--ec-grid-cols="{grid.length * grid[0].length}"
|
|
48
|
+
style:--ec-col-group-span="{grid[0].length}"
|
|
49
|
+
style:--ec-col-width="{$columnWidth ?? 'minmax(0, 1fr)'}"
|
|
50
|
+
style:--ec-slot-label-periodicity="{$_slotLabelPeriodicity}"
|
|
51
|
+
style:--ec-slot-height="{$slotHeight}px"
|
|
52
|
+
style:--ec-header-height="{headerHeight}px"
|
|
53
|
+
style:--ec-sidebar-width="{$_sidebarWidth}px"
|
|
54
|
+
{@attach resizeObserver(reposition)}
|
|
55
|
+
>
|
|
56
|
+
<header bind:offsetHeight={headerHeight} class="{$theme.header}">
|
|
57
|
+
<aside class="{$theme.sidebar}" bind:offsetWidth={$_sidebarWidth}></aside>
|
|
58
|
+
<div class="{$theme.grid}" role="row">
|
|
59
|
+
{#if header}
|
|
60
|
+
{@render header(grid)}
|
|
61
|
+
{:else}
|
|
62
|
+
{#each grid[0] as {dayStart: date, disabled, highlight}, i}
|
|
63
|
+
<ColHead {date} colIndex={1 + i} {disabled} {highlight}>
|
|
64
|
+
<DayHeader {date}/>
|
|
65
|
+
</ColHead>
|
|
66
|
+
{/each}
|
|
67
|
+
{/if}
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
{#if $allDaySlot}
|
|
71
|
+
<div class="{$theme.allDay}">
|
|
72
|
+
<aside class="{$theme.sidebar}" {@attach contentFrom(allDayText)}></aside>
|
|
73
|
+
<div class="{$theme.grid}" role="row">
|
|
74
|
+
{#each grid as days}
|
|
75
|
+
{#each days as day}
|
|
76
|
+
<Day {day} allDay/>
|
|
77
|
+
{/each}
|
|
78
|
+
{/each}
|
|
79
|
+
</div>
|
|
80
|
+
<div class="{$theme.events}">
|
|
81
|
+
{#each allDayChunks as chunk, i}
|
|
82
|
+
<!-- svelte-ignore binding_property_non_reactive -->
|
|
83
|
+
<AllDayEvent bind:this={refs[i]} {chunk}/>
|
|
84
|
+
{/each}
|
|
85
|
+
{#each allDayBgChunks as chunk}
|
|
86
|
+
<AllDayEvent {chunk}/>
|
|
87
|
+
{/each}
|
|
88
|
+
{#each allDayIChunks as chunk}
|
|
89
|
+
<AllDayEvent {chunk}/>
|
|
90
|
+
{/each}
|
|
91
|
+
</div>
|
|
24
92
|
</div>
|
|
25
|
-
{/
|
|
26
|
-
</
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
93
|
+
{/if}
|
|
94
|
+
</header>
|
|
95
|
+
|
|
96
|
+
<div class="{$theme.body}" role="rowgroup">
|
|
97
|
+
<aside class="{$theme.sidebar}" aria-hidden="true">
|
|
98
|
+
{#each $_slots as slot, i}
|
|
99
|
+
<div
|
|
100
|
+
class={[$theme.slot, !i && $theme.hidden]}
|
|
101
|
+
style:--ec-slot-label-periodicity={slot[2]}
|
|
102
|
+
>
|
|
103
|
+
<time
|
|
104
|
+
datetime="{slot[0]}"
|
|
105
|
+
{@attach contentFrom(slot[1])}
|
|
106
|
+
></time>
|
|
107
|
+
</div>
|
|
108
|
+
{/each}
|
|
109
|
+
</aside>
|
|
110
|
+
<div class="{$theme.grid}" role="row">
|
|
111
|
+
{#each grid as days}
|
|
112
|
+
{#each days as day}
|
|
113
|
+
<Day {day}/>
|
|
114
|
+
{/each}
|
|
115
|
+
{/each}
|
|
116
|
+
</div>
|
|
117
|
+
<div class="{$theme.events}">
|
|
118
|
+
{#each chunks as chunk}
|
|
119
|
+
<Event {chunk}/>
|
|
120
|
+
{/each}
|
|
121
|
+
{#each bgChunks as chunk}
|
|
122
|
+
<Event {chunk}/>
|
|
123
|
+
{/each}
|
|
124
|
+
{#each iChunks as chunk}
|
|
125
|
+
<Event {chunk}/>
|
|
126
|
+
{/each}
|
|
36
127
|
</div>
|
|
37
128
|
</div>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{#
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
|
|
129
|
+
|
|
130
|
+
{#if $showNowIndicator}
|
|
131
|
+
{#if nowIndicator}
|
|
132
|
+
{@render nowIndicator(grid)}
|
|
133
|
+
{:else}
|
|
134
|
+
<NowIndicator days={grid[0]}/>
|
|
135
|
+
{/if}
|
|
136
|
+
{/if}
|
|
137
|
+
</section>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import {btnTextDay, btnTextWeek, themeView} from '#lib';
|
|
2
|
-
import {
|
|
2
|
+
import {createTROptions, createTRROptions, createTRRParsers} from './options.js';
|
|
3
|
+
import {createTRRStores, createTRStores} from './stores.js';
|
|
3
4
|
import View from './View.svelte';
|
|
4
5
|
|
|
5
|
-
export {default as Section} from './Section.svelte';
|
|
6
|
-
export {default as Body} from './Body.svelte';
|
|
7
|
-
export {default as Day} from './Day.svelte';
|
|
8
|
-
export {default as Week} from './all-day/Week.svelte';
|
|
9
|
-
|
|
10
6
|
export default {
|
|
11
7
|
createOptions(options) {
|
|
8
|
+
createTROptions(options);
|
|
9
|
+
createTRROptions(options);
|
|
12
10
|
// Common options
|
|
13
11
|
options.buttonText.timeGridDay = 'day';
|
|
14
12
|
options.buttonText.timeGridWeek = 'week';
|
|
@@ -29,8 +27,12 @@ export default {
|
|
|
29
27
|
};
|
|
30
28
|
},
|
|
31
29
|
|
|
30
|
+
createParsers(parsers) {
|
|
31
|
+
createTRRParsers(parsers);
|
|
32
|
+
},
|
|
33
|
+
|
|
32
34
|
createStores(state) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
createTRRStores(state);
|
|
36
|
+
createTRStores(state);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addDay, addDuration, assign, bgEvent, cloneDate, createAllDayChunks, createEventChunk, datesEqual, eventIntersects,
|
|
3
|
+
isFunction, outsideRange, prepareAllDayChunks,
|
|
4
|
+
} from '#lib';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Days with prepared start and end times
|
|
8
|
+
*/
|
|
9
|
+
export function createGrid($_viewDates, $_slotTimeLimits, $validRange, $highlightedDates) {
|
|
10
|
+
let days = [];
|
|
11
|
+
let gridColumn = 1;
|
|
12
|
+
for (let date of $_viewDates) {
|
|
13
|
+
days.push({
|
|
14
|
+
gridColumn,
|
|
15
|
+
gridRow: 1,
|
|
16
|
+
resource: undefined,
|
|
17
|
+
start: addDuration(cloneDate(date), $_slotTimeLimits.min),
|
|
18
|
+
end: addDuration(cloneDate(date), $_slotTimeLimits.max),
|
|
19
|
+
dayStart: date,
|
|
20
|
+
dayEnd: addDay(cloneDate(date)),
|
|
21
|
+
disabled: outsideRange(date, $validRange),
|
|
22
|
+
highlight: $highlightedDates.some(d => datesEqual(d, date))
|
|
23
|
+
});
|
|
24
|
+
++ gridColumn;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [days];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function createEventChunks($_filteredEvents, grid) {
|
|
31
|
+
let chunks = [];
|
|
32
|
+
let bgChunks = [];
|
|
33
|
+
let allDayChunks = [];
|
|
34
|
+
let allDayBgChunks = [];
|
|
35
|
+
for (let event of $_filteredEvents) {
|
|
36
|
+
for (let days of grid) {
|
|
37
|
+
if (bgEvent(event.display)) {
|
|
38
|
+
bgChunks = bgChunks.concat(createChunks(event, days));
|
|
39
|
+
if (event.allDay) {
|
|
40
|
+
allDayBgChunks = allDayBgChunks.concat(createAllDayChunks(event, days));
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
if (event.allDay) {
|
|
44
|
+
allDayChunks = allDayChunks.concat(createAllDayChunks(event, days));
|
|
45
|
+
} else {
|
|
46
|
+
chunks = chunks.concat(createChunks(event, days));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
groupChunks(chunks);
|
|
52
|
+
prepareAllDayChunks(allDayChunks);
|
|
53
|
+
|
|
54
|
+
return {chunks, bgChunks, allDayChunks, allDayBgChunks};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function createIEventChunks($_iEvents, grid) {
|
|
58
|
+
let iChunks = [];
|
|
59
|
+
let allDayIChunks = [];
|
|
60
|
+
for (let event of $_iEvents) {
|
|
61
|
+
if (!event) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
for (let days of grid) {
|
|
65
|
+
if (event.allDay) {
|
|
66
|
+
allDayIChunks = allDayIChunks.concat(createAllDayChunks(event, days));
|
|
67
|
+
} else {
|
|
68
|
+
iChunks = iChunks.concat(createChunks(event, days));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {iChunks, allDayIChunks};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function createChunks(event, days) {
|
|
77
|
+
let chunks = [];
|
|
78
|
+
for (let {gridColumn, gridRow, resource, start, end, disabled} of days) {
|
|
79
|
+
if (!disabled && eventIntersects(event, start, end, resource)) {
|
|
80
|
+
let chunk = createEventChunk(event, start, end);
|
|
81
|
+
// Chunk layout
|
|
82
|
+
assign(chunk, {
|
|
83
|
+
gridColumn,
|
|
84
|
+
gridRow,
|
|
85
|
+
top: (chunk.start - start) / 1000,
|
|
86
|
+
height: (chunk.end - chunk.start) / 1000,
|
|
87
|
+
maxHeight: (end - chunk.start) / 1000
|
|
88
|
+
});
|
|
89
|
+
chunks.push(chunk);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return chunks;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function groupChunks(chunks) {
|
|
96
|
+
let groups = {};
|
|
97
|
+
for (let chunk of chunks) {
|
|
98
|
+
let {gridColumn} = chunk;
|
|
99
|
+
let group = groups[gridColumn];
|
|
100
|
+
let column = 0;
|
|
101
|
+
if (group && chunk.start < group.end) {
|
|
102
|
+
for (; column < group.columns.length; ++ column) {
|
|
103
|
+
if (group.columns[column].at(-1).end <= chunk.start) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (chunk.end > group.end) {
|
|
108
|
+
group.end = chunk.end;
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
group = {
|
|
112
|
+
columns: [],
|
|
113
|
+
end: chunk.end
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (group.columns.length < column + 1) {
|
|
117
|
+
group.columns.push([]);
|
|
118
|
+
}
|
|
119
|
+
group.columns[column].push(chunk);
|
|
120
|
+
groups[gridColumn] = group;
|
|
121
|
+
// Chunk layout
|
|
122
|
+
chunk.group = group;
|
|
123
|
+
chunk.groupColumn = column;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function createAllDayContent(allDayContent) {
|
|
128
|
+
let text = 'all-day';
|
|
129
|
+
let content;
|
|
130
|
+
if (allDayContent) {
|
|
131
|
+
content = isFunction(allDayContent) ? allDayContent({text}) : allDayContent;
|
|
132
|
+
if (typeof content === 'string') {
|
|
133
|
+
content = {html: content};
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
content = {
|
|
137
|
+
html: text
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return content;
|
|
142
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {assign, createDuration} from '#lib';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TimeGrid + ResourceTimeGrid
|
|
5
|
+
*/
|
|
6
|
+
export function createTROptions(options) {
|
|
7
|
+
if (!('allDaySlot' in options)) {
|
|
8
|
+
assign(options, {
|
|
9
|
+
allDayContent: undefined,
|
|
10
|
+
allDaySlot: true,
|
|
11
|
+
slotEventOverlap: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* TimeGrid + ResourceTimeGrid + ResourceTimeline
|
|
18
|
+
*/
|
|
19
|
+
export function createTRROptions(options) {
|
|
20
|
+
if (!('scrollTime' in options)) {
|
|
21
|
+
assign(options, {
|
|
22
|
+
columnWidth: undefined, // ec option
|
|
23
|
+
flexibleSlotTimeLimits: false, // ec option
|
|
24
|
+
nowIndicator: false,
|
|
25
|
+
scrollTime: '06:00:00',
|
|
26
|
+
slotDuration: '00:30:00',
|
|
27
|
+
slotHeight: 24, // ec option
|
|
28
|
+
slotLabelInterval: undefined,
|
|
29
|
+
slotLabelFormat: {
|
|
30
|
+
hour: 'numeric',
|
|
31
|
+
minute: '2-digit'
|
|
32
|
+
},
|
|
33
|
+
slotMaxTime: '24:00:00',
|
|
34
|
+
slotMinTime: '00:00:00'
|
|
35
|
+
});
|
|
36
|
+
assign(options.theme, {
|
|
37
|
+
nowIndicator: 'ec-now-indicator',
|
|
38
|
+
sidebar: 'ec-sidebar',
|
|
39
|
+
slot: 'ec-slot',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* TimeGrid + ResourceTimeGrid + ResourceTimeline
|
|
46
|
+
*/
|
|
47
|
+
export function createTRRParsers(parsers) {
|
|
48
|
+
if (!('scrollTime' in parsers)) {
|
|
49
|
+
assign(parsers, {
|
|
50
|
+
scrollTime: createDuration,
|
|
51
|
+
slotDuration: createDuration,
|
|
52
|
+
slotLabelInterval: input => input !== undefined ? createDuration(input) : undefined,
|
|
53
|
+
slotMaxTime: createDuration,
|
|
54
|
+
slotMinTime: createDuration
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|