@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
package/src/lib/slots.js
CHANGED
|
@@ -2,47 +2,47 @@ import {addDuration, cloneDate, createDuration, DAY_IN_SECONDS, toISOString, toS
|
|
|
2
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 createSlots(date,
|
|
5
|
+
export function createSlots(date, slotDuration, slotLabelPeriodicity, slotTimeLimits, intlSlotLabel) {
|
|
6
6
|
let slots = [];
|
|
7
7
|
date = cloneDate(date);
|
|
8
8
|
let end = cloneDate(date);
|
|
9
|
-
addDuration(date,
|
|
10
|
-
addDuration(end,
|
|
9
|
+
addDuration(date, slotTimeLimits.min);
|
|
10
|
+
addDuration(end, slotTimeLimits.max);
|
|
11
11
|
// Build slots
|
|
12
12
|
while (date < end) {
|
|
13
13
|
slots.push([
|
|
14
14
|
toISOString(date),
|
|
15
|
-
|
|
15
|
+
intlSlotLabel.format(date)
|
|
16
16
|
]);
|
|
17
|
-
addDuration(date,
|
|
17
|
+
addDuration(date, slotDuration, slotLabelPeriodicity);
|
|
18
18
|
}
|
|
19
19
|
// Calculate span for last slot
|
|
20
|
-
let span = floor((date - end) / 1000 / toSeconds(
|
|
21
|
-
if (span && span !==
|
|
22
|
-
slots.at(-1)[2] =
|
|
20
|
+
let span = floor((date - end) / 1000 / toSeconds(slotDuration));
|
|
21
|
+
if (span && span !== slotLabelPeriodicity) {
|
|
22
|
+
slots.at(-1)[2] = slotLabelPeriodicity - span;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return slots;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function createSlotTimeLimits(
|
|
28
|
+
export function createSlotTimeLimits(slotMinTime, slotMaxTime, flexibleSlotTimeLimits, viewDates, filteredEvents) {
|
|
29
29
|
// Copy values
|
|
30
|
-
let min = createDuration(
|
|
31
|
-
let max = createDuration(
|
|
30
|
+
let min = createDuration(slotMinTime);
|
|
31
|
+
let max = createDuration(slotMaxTime);
|
|
32
32
|
|
|
33
|
-
if (
|
|
33
|
+
if (flexibleSlotTimeLimits) {
|
|
34
34
|
// If slotMaxTime goes past midnight, then extend it back by a maximum of 24 hours
|
|
35
35
|
let minMin = createDuration(minFn(toSeconds(min), maxFn(0, toSeconds(max) - DAY_IN_SECONDS)));
|
|
36
36
|
let maxMax = createDuration(maxFn(toSeconds(max), toSeconds(minMin) + DAY_IN_SECONDS));
|
|
37
|
-
let filter = isFunction(
|
|
38
|
-
?
|
|
37
|
+
let filter = isFunction(flexibleSlotTimeLimits?.eventFilter)
|
|
38
|
+
? flexibleSlotTimeLimits.eventFilter
|
|
39
39
|
: event => !bgEvent(event.display);
|
|
40
|
-
loop: for (let date of
|
|
40
|
+
loop: for (let date of viewDates) {
|
|
41
41
|
let start = addDuration(cloneDate(date), min);
|
|
42
42
|
let end = addDuration(cloneDate(date), max);
|
|
43
43
|
let minStart = addDuration(cloneDate(date), minMin);
|
|
44
44
|
let maxEnd = addDuration(cloneDate(date), maxMax);
|
|
45
|
-
for (let event of
|
|
45
|
+
for (let event of filteredEvents) {
|
|
46
46
|
if (!event.allDay && filter(event) && event.start < maxEnd && event.end > minStart) {
|
|
47
47
|
if (event.start < start) {
|
|
48
48
|
let seconds = maxFn((event.start - date) / 1000, toSeconds(minMin));
|
package/src/lib/utils.js
CHANGED
|
@@ -10,6 +10,10 @@ export function entries(object) {
|
|
|
10
10
|
return Object.entries(object);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export function hasOwn(object, property) {
|
|
14
|
+
return Object.hasOwn(object, property);
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export function floor(value) {
|
|
14
18
|
return Math.floor(value);
|
|
15
19
|
}
|
|
@@ -38,15 +42,6 @@ export function isFunction(value) {
|
|
|
38
42
|
return typeof value === 'function';
|
|
39
43
|
}
|
|
40
44
|
|
|
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
|
-
|
|
50
45
|
export function run(fn) {
|
|
51
46
|
return fn();
|
|
52
47
|
}
|
package/src/lib/view.js
CHANGED
|
@@ -7,24 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
let {day, noIeb, noBeb} = $props();
|
|
9
9
|
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
let mainState = getContext('state');
|
|
11
|
+
let viewState = getContext('view-state');
|
|
12
|
+
|
|
13
|
+
let {options: {date, firstDay, moreLinkContent, theme, weekNumbers, weekNumberContent}} = $derived(mainState);
|
|
14
|
+
let {hiddenChunks, intlDayCell} = $derived(viewState);
|
|
13
15
|
|
|
14
16
|
let {dayStart, disabled, highlight} = $derived(day);
|
|
15
|
-
let otherMonth = $derived(dayStart.getUTCMonth() !==
|
|
16
|
-
let classes = $derived(classNames => [...classNames, otherMonth &&
|
|
17
|
+
let otherMonth = $derived(dayStart.getUTCMonth() !== date.getUTCMonth());
|
|
18
|
+
let classes = $derived(classNames => [...classNames, otherMonth && theme.otherMonth]);
|
|
17
19
|
|
|
18
20
|
// Week numbers
|
|
19
|
-
let showWeekNumber = $derived(
|
|
21
|
+
let showWeekNumber = $derived(weekNumbers && dayStart.getUTCDay() === (firstDay ? 1 : 0));
|
|
20
22
|
let weekNumber = $derived.by(() => {
|
|
21
23
|
let weekNumber;
|
|
22
24
|
if (showWeekNumber) {
|
|
23
25
|
let week = getWeekNumber(dayStart, $firstDay);
|
|
24
|
-
if (
|
|
25
|
-
weekNumber = isFunction(
|
|
26
|
-
?
|
|
27
|
-
:
|
|
26
|
+
if (weekNumberContent) {
|
|
27
|
+
weekNumber = isFunction(weekNumberContent)
|
|
28
|
+
? weekNumberContent({date: toLocalDate(dayStart), week})
|
|
29
|
+
: weekNumberContent;
|
|
28
30
|
} else {
|
|
29
31
|
weekNumber = 'W' + String(week).padStart(2, '0');
|
|
30
32
|
}
|
|
@@ -33,15 +35,15 @@
|
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
// More link
|
|
36
|
-
let
|
|
38
|
+
let dayHiddenChunks = $derived(hiddenChunks.get(dayStart.getTime()));
|
|
37
39
|
let moreLink = $derived.by(() => {
|
|
38
40
|
let moreLink = '';
|
|
39
|
-
if (
|
|
40
|
-
let text = '+' +
|
|
41
|
-
if (
|
|
42
|
-
moreLink = isFunction(
|
|
43
|
-
?
|
|
44
|
-
:
|
|
41
|
+
if (dayHiddenChunks) {
|
|
42
|
+
let text = '+' + dayHiddenChunks.length + ' more';
|
|
43
|
+
if (moreLinkContent) {
|
|
44
|
+
moreLink = isFunction(moreLinkContent)
|
|
45
|
+
? moreLinkContent({num: dayHiddenChunks.length, text})
|
|
46
|
+
: moreLinkContent;
|
|
45
47
|
} else {
|
|
46
48
|
moreLink = text;
|
|
47
49
|
}
|
|
@@ -51,26 +53,26 @@
|
|
|
51
53
|
|
|
52
54
|
// Popup
|
|
53
55
|
function showMore() {
|
|
54
|
-
|
|
56
|
+
viewState.popupDay = day;
|
|
55
57
|
}
|
|
56
58
|
</script>
|
|
57
59
|
|
|
58
60
|
<BaseDay date={dayStart} allDay {classes} {disabled} {highlight} {noIeb} {noBeb}>
|
|
59
|
-
<div class="{
|
|
61
|
+
<div class="{theme.dayHead}">
|
|
60
62
|
<time
|
|
61
63
|
datetime="{toISOString(dayStart, 10)}"
|
|
62
|
-
{@attach contentFrom(
|
|
64
|
+
{@attach contentFrom(intlDayCell.format(dayStart))}
|
|
63
65
|
></time>
|
|
64
66
|
{#if showWeekNumber}
|
|
65
67
|
<span
|
|
66
|
-
class="{
|
|
68
|
+
class="{theme.weekNumber}"
|
|
67
69
|
{@attach contentFrom(weekNumber)}
|
|
68
70
|
></span>
|
|
69
71
|
{/if}
|
|
70
72
|
</div>
|
|
71
73
|
|
|
72
|
-
<div class="{
|
|
73
|
-
{#if
|
|
74
|
+
<div class="{theme.dayFoot}">
|
|
75
|
+
{#if dayHiddenChunks}
|
|
74
76
|
<!-- svelte-ignore a11y_missing_attribute -->
|
|
75
77
|
<!-- svelte-ignore a11y_missing_content -->
|
|
76
78
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {bgEvent, height,
|
|
3
|
+
import {bgEvent, height, max, repositionEvent} from '#lib';
|
|
4
4
|
import {InteractableEvent} from '#components';
|
|
5
5
|
|
|
6
|
-
let {chunk,
|
|
6
|
+
let {chunk, inPopup = false} = $props();
|
|
7
7
|
|
|
8
|
-
let {
|
|
8
|
+
let {options: {dayMaxEvents}} = $derived(getContext('state'));
|
|
9
|
+
let {colsCount, gridEl, hiddenChunks, popupDay} = $derived(getContext('view-state'));
|
|
9
10
|
|
|
10
11
|
let el = $state();
|
|
11
12
|
let margin = $state(0);
|
|
@@ -13,10 +14,10 @@
|
|
|
13
14
|
|
|
14
15
|
let event = $derived(chunk.event);
|
|
15
16
|
let display = $derived(chunk.event.display);
|
|
16
|
-
let dayEl = $derived(gridEl
|
|
17
|
+
let dayEl = $derived(gridEl.children.item((chunk.gridRow - 1) * colsCount + chunk.gridColumn - 1));
|
|
17
18
|
|
|
18
19
|
$effect(() => {
|
|
19
|
-
if (
|
|
20
|
+
if (!inPopup) {
|
|
20
21
|
margin = height(dayEl.firstElementChild);
|
|
21
22
|
}
|
|
22
23
|
});
|
|
@@ -47,26 +48,27 @@
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
export function hide() {
|
|
50
|
-
if (
|
|
51
|
+
if (dayMaxEvents === true) {
|
|
51
52
|
let h = height(dayEl) - footHeight(dayEl);
|
|
52
53
|
hidden = chunk.bottom > h;
|
|
53
54
|
if (hidden) {
|
|
54
55
|
// Hide the event throughout all days
|
|
55
56
|
for (let date of chunk.dates) {
|
|
56
57
|
let key = date.getTime();
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
if (hiddenChunks.has(key)) {
|
|
59
|
+
let chunks = hiddenChunks.get(key);
|
|
60
|
+
if (!chunks.includes(chunk)) {
|
|
61
|
+
hiddenChunks.set(key, [...chunks, chunk]);
|
|
60
62
|
}
|
|
61
63
|
} else {
|
|
62
|
-
|
|
64
|
+
hiddenChunks.set(key, [chunk]);
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
} else {
|
|
67
69
|
hidden = false;
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
+
if (hiddenChunks.size) {
|
|
71
|
+
hiddenChunks.clear();
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -89,6 +91,6 @@
|
|
|
89
91
|
{chunk}
|
|
90
92
|
{styles}
|
|
91
93
|
axis="x"
|
|
92
|
-
forceDate={inPopup &&
|
|
94
|
+
forceDate={inPopup && popupDay.dayStart}
|
|
93
95
|
forceMargin={[margin, chunk.gridRow]}
|
|
94
96
|
/>
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
} from '#lib';
|
|
6
6
|
import Event from './Event.svelte';
|
|
7
7
|
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
let {
|
|
8
|
+
let viewState = getContext('view-state');
|
|
9
|
+
let {interaction, options: {buttonText, theme}} = $derived(getContext('state'));
|
|
10
|
+
let {colsCount, chunks, gridEl, intlDayPopover, popupDay} = $derived(viewState);
|
|
11
11
|
|
|
12
12
|
let el = $state();
|
|
13
13
|
let style = $state('');
|
|
14
14
|
|
|
15
|
-
let {gridColumn, gridRow, dayStart, dayEnd} = $derived(
|
|
15
|
+
let {gridColumn, gridRow, dayStart, dayEnd} = $derived(popupDay);
|
|
16
16
|
|
|
17
17
|
let popupChunks = $derived.by(() => {
|
|
18
18
|
let result = [];
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
function position() {
|
|
41
|
-
let dayEl = gridEl.children.item((gridRow - 1) *
|
|
41
|
+
let dayEl = gridEl.children.item((gridRow - 1) * colsCount + gridColumn - 1);
|
|
42
42
|
let popupRect = rect(el);
|
|
43
43
|
let dayRect = rect(dayEl);
|
|
44
44
|
let gridRect = rect(gridEl);
|
|
@@ -76,18 +76,18 @@
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
function close() {
|
|
79
|
-
|
|
79
|
+
viewState.popupDay = null;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
function handlePointerDownOutside() {
|
|
83
83
|
close();
|
|
84
|
-
|
|
84
|
+
interaction.action?.noClick();
|
|
85
85
|
}
|
|
86
86
|
</script>
|
|
87
87
|
|
|
88
88
|
<dialog
|
|
89
89
|
bind:this={el}
|
|
90
|
-
class="{
|
|
90
|
+
class="{theme.popup}"
|
|
91
91
|
closedby="closerequest"
|
|
92
92
|
{style}
|
|
93
93
|
style:grid-area="{`${gridRow + 1} / ${gridColumn}`}"
|
|
@@ -95,20 +95,20 @@
|
|
|
95
95
|
onpointerdownoutside={handlePointerDownOutside}
|
|
96
96
|
onclose={close}
|
|
97
97
|
>
|
|
98
|
-
<header class="{
|
|
99
|
-
<time datetime="{toISOString(dayStart, 10)}" {@attach contentFrom(
|
|
98
|
+
<header class="{theme.dayHead}">
|
|
99
|
+
<time datetime="{toISOString(dayStart, 10)}" {@attach contentFrom(intlDayPopover.format(dayStart))}></time>
|
|
100
100
|
<!-- svelte-ignore a11y_missing_attribute -->
|
|
101
101
|
<!-- svelte-ignore a11y_autofocus -->
|
|
102
102
|
<a
|
|
103
103
|
autofocus
|
|
104
104
|
role="button"
|
|
105
105
|
tabindex="0"
|
|
106
|
-
aria-label={
|
|
106
|
+
aria-label={buttonText.close}
|
|
107
107
|
onclick={stopPropagation(close)}
|
|
108
108
|
onkeydown={keyEnter(close)}
|
|
109
109
|
>×</a>
|
|
110
110
|
</header>
|
|
111
|
-
<div class="{
|
|
111
|
+
<div class="{theme.events}">
|
|
112
112
|
{#each popupChunks as chunk}
|
|
113
113
|
<Event {chunk} inPopup />
|
|
114
114
|
{/each}
|
|
@@ -1,90 +1,78 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext} from 'svelte';
|
|
3
|
-
import {contentFrom,
|
|
2
|
+
import {getContext, setContext} from 'svelte';
|
|
3
|
+
import {contentFrom, resizeObserver, runReposition} from '#lib';
|
|
4
|
+
import ViewState from './state.svelte.js';
|
|
4
5
|
import Day from './Day.svelte';
|
|
5
6
|
import Event from './Event.svelte';
|
|
6
7
|
import Popup from './Popup.svelte';
|
|
7
|
-
import {createEventChunks, createIEventChunks, createGrid} from './lib.js';
|
|
8
8
|
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
let mainState = getContext('state');
|
|
10
|
+
let viewState = new ViewState(mainState);
|
|
11
|
+
setContext('view-state', viewState);
|
|
12
12
|
|
|
13
|
-
let
|
|
14
|
-
let grid
|
|
15
|
-
let {chunks, bgChunks} = $derived(createEventChunks($_filteredEvents, grid));
|
|
16
|
-
let iChunks = $derived(createIEventChunks($_iEvents, grid));
|
|
17
|
-
|
|
18
|
-
$effect.pre(() => {
|
|
19
|
-
$_activeRangeExt = ({start, end}) => ({
|
|
20
|
-
start: prevClosestDay(start, $firstDay),
|
|
21
|
-
end: nextClosestDay(end, $firstDay)
|
|
22
|
-
});
|
|
23
|
-
return () => {
|
|
24
|
-
$_activeRangeExt = identity;
|
|
25
|
-
};
|
|
26
|
-
});
|
|
13
|
+
let {intlDayHeader, intlDayHeaderAL, options: {dayMaxEvents, theme}} = $derived(mainState);
|
|
14
|
+
let {grid, chunks, bgChunks, iChunks, hiddenChunks, popupDay} = $derived(viewState);
|
|
27
15
|
|
|
28
16
|
// Events reposition
|
|
29
17
|
let refs = [];
|
|
30
18
|
function reposition() {
|
|
31
|
-
|
|
19
|
+
hiddenChunks.clear();
|
|
32
20
|
runReposition(refs, chunks);
|
|
33
21
|
}
|
|
34
22
|
$effect(reposition);
|
|
35
23
|
$effect(() => {
|
|
36
|
-
|
|
24
|
+
chunks;
|
|
37
25
|
refs.forEach(ref => ref.hide());
|
|
38
26
|
});
|
|
39
27
|
</script>
|
|
40
28
|
|
|
41
29
|
<section
|
|
42
|
-
bind:this={
|
|
43
|
-
class={[
|
|
30
|
+
bind:this={mainState.mainEl}
|
|
31
|
+
class={[theme.main, dayMaxEvents === true && theme.uniform]}
|
|
44
32
|
style:--ec-grid-cols="{grid[0].length}"
|
|
45
33
|
style:--ec-grid-rows="{grid.length}"
|
|
46
34
|
{@attach resizeObserver(reposition)}
|
|
47
35
|
>
|
|
48
|
-
<header class="{
|
|
49
|
-
<div class="{
|
|
36
|
+
<header class="{theme.header}">
|
|
37
|
+
<div class="{theme.grid}" role="row">
|
|
50
38
|
{#each grid[0] as {dayStart}, i}
|
|
51
39
|
<div
|
|
52
|
-
class={[
|
|
40
|
+
class={[theme.colHead, theme.weekdays?.[dayStart.getUTCDay()]]}
|
|
53
41
|
role="columnheader"
|
|
54
42
|
aria-colindex="{1 + i}"
|
|
55
43
|
>
|
|
56
44
|
<span
|
|
57
|
-
aria-label="{
|
|
58
|
-
{@attach contentFrom(
|
|
45
|
+
aria-label="{intlDayHeaderAL.format(dayStart)}"
|
|
46
|
+
{@attach contentFrom(intlDayHeader.format(dayStart))}
|
|
59
47
|
></span>
|
|
60
48
|
</div>
|
|
61
49
|
{/each}
|
|
62
50
|
</div>
|
|
63
51
|
</header>
|
|
64
52
|
|
|
65
|
-
<div class="{
|
|
66
|
-
<div bind:this={gridEl} class="{
|
|
53
|
+
<div class="{theme.body}">
|
|
54
|
+
<div bind:this={viewState.gridEl} class="{theme.grid}">
|
|
67
55
|
{#each grid as days, i}
|
|
68
56
|
{#each days as day, j}
|
|
69
57
|
<Day {day} noIeb={j + 1 === days.length} noBeb={i + 1 === grid.length}/>
|
|
70
58
|
{/each}
|
|
71
59
|
{/each}
|
|
72
60
|
</div>
|
|
73
|
-
<div class="{
|
|
61
|
+
<div class="{theme.events}">
|
|
74
62
|
{#each chunks as chunk, i}
|
|
75
63
|
<!-- svelte-ignore binding_property_non_reactive -->
|
|
76
|
-
<Event bind:this={refs[i]} {chunk}
|
|
64
|
+
<Event bind:this={refs[i]} {chunk}/>
|
|
77
65
|
{/each}
|
|
78
66
|
{#each bgChunks as chunk}
|
|
79
67
|
<Event {chunk}/>
|
|
80
68
|
{/each}
|
|
81
69
|
{#each iChunks as chunk}
|
|
82
|
-
<Event {chunk}
|
|
70
|
+
<Event {chunk}/>
|
|
83
71
|
{/each}
|
|
84
72
|
</div>
|
|
85
73
|
</div>
|
|
86
74
|
|
|
87
|
-
{#if
|
|
88
|
-
<Popup
|
|
75
|
+
{#if popupDay}
|
|
76
|
+
<Popup/>
|
|
89
77
|
{/if}
|
|
90
78
|
</section>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {untrack} from 'svelte';
|
|
2
|
+
import {addDay, bgEvent, cloneDate, createAllDayChunks, datesEqual, outsideRange, prepareAllDayChunks} from '#lib';
|
|
3
|
+
|
|
4
|
+
export function colsCount(mainState) {
|
|
5
|
+
return () => {
|
|
6
|
+
// Dependencies
|
|
7
|
+
let {options: {hiddenDays}} = mainState;
|
|
8
|
+
|
|
9
|
+
let count;
|
|
10
|
+
|
|
11
|
+
untrack(() => count = 7 - hiddenDays.length);
|
|
12
|
+
|
|
13
|
+
return count;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function grid(mainState, viewState) {
|
|
18
|
+
return () => {
|
|
19
|
+
// Dependencies
|
|
20
|
+
let {options: {highlightedDates, validRange}, viewDates} = mainState;
|
|
21
|
+
let {colsCount} = viewState;
|
|
22
|
+
|
|
23
|
+
let grid = [];
|
|
24
|
+
|
|
25
|
+
untrack(() => {
|
|
26
|
+
let days = [];
|
|
27
|
+
let gridColumn = 1;
|
|
28
|
+
let gridRow = 1;
|
|
29
|
+
for (let date of viewDates) {
|
|
30
|
+
days.push({
|
|
31
|
+
gridColumn,
|
|
32
|
+
gridRow,
|
|
33
|
+
resource: undefined,
|
|
34
|
+
dayStart: date,
|
|
35
|
+
dayEnd: addDay(cloneDate(date)),
|
|
36
|
+
disabled: outsideRange(date, validRange),
|
|
37
|
+
highlight: highlightedDates.some(d => datesEqual(d, date))
|
|
38
|
+
});
|
|
39
|
+
if (gridColumn === colsCount) {
|
|
40
|
+
grid.push(days);
|
|
41
|
+
days = [];
|
|
42
|
+
gridColumn = 0;
|
|
43
|
+
++ gridRow;
|
|
44
|
+
}
|
|
45
|
+
++ gridColumn;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return grid;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function eventChunks(mainState, viewState) {
|
|
54
|
+
return () => {
|
|
55
|
+
// Dependencies
|
|
56
|
+
let {filteredEvents} = mainState;
|
|
57
|
+
let {grid} = viewState;
|
|
58
|
+
|
|
59
|
+
let chunks = [];
|
|
60
|
+
let bgChunks = [];
|
|
61
|
+
|
|
62
|
+
untrack(() => {
|
|
63
|
+
for (let event of filteredEvents) {
|
|
64
|
+
for (let days of grid) {
|
|
65
|
+
if (bgEvent(event.display)) {
|
|
66
|
+
if (event.allDay) {
|
|
67
|
+
bgChunks = bgChunks.concat(createAllDayChunks(event, days));
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
chunks = chunks.concat(createAllDayChunks(event, days));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
prepareAllDayChunks(chunks);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return {chunks, bgChunks};
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function iEventChunks(mainState, viewState) {
|
|
82
|
+
return () => {
|
|
83
|
+
// Dependencies
|
|
84
|
+
let {iEvents} = mainState;
|
|
85
|
+
let {grid} = viewState;
|
|
86
|
+
|
|
87
|
+
let iChunks = [];
|
|
88
|
+
|
|
89
|
+
for (let [, event] of iEvents) {
|
|
90
|
+
if (!event) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
untrack(() => {
|
|
94
|
+
for (let days of grid) {
|
|
95
|
+
iChunks = iChunks.concat(createAllDayChunks(event, days));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return iChunks;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -1,42 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {btnTextMonth, intl, themeView} from '#lib';
|
|
3
|
-
import {colsCount} from './stores.js';
|
|
1
|
+
import {assign, btnTextMonth, nextClosestDay, prevClosestDay, themeView} from '#lib';
|
|
4
2
|
import View from './View.svelte';
|
|
5
3
|
|
|
6
4
|
export default {
|
|
7
5
|
createOptions(options) {
|
|
8
|
-
options
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
options.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
options.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
6
|
+
assign(options, {
|
|
7
|
+
dayMaxEvents: false,
|
|
8
|
+
dayCellFormat: {day: 'numeric'},
|
|
9
|
+
dayPopoverFormat: {month: 'long', day: 'numeric', year: 'numeric'},
|
|
10
|
+
moreLinkContent: undefined,
|
|
11
|
+
weekNumbers: false,
|
|
12
|
+
weekNumberContent: undefined,
|
|
13
|
+
// Common options
|
|
14
|
+
view: 'dayGridMonth'
|
|
15
|
+
});
|
|
16
|
+
assign(options.buttonText, {
|
|
17
|
+
dayGridMonth: 'month',
|
|
18
|
+
close: 'Close'
|
|
19
|
+
});
|
|
20
|
+
assign(options.theme, {
|
|
21
|
+
uniform: 'ec-uniform',
|
|
22
|
+
dayFoot: 'ec-day-foot',
|
|
23
|
+
otherMonth: 'ec-other-month',
|
|
24
|
+
popup: 'ec-popup',
|
|
25
|
+
weekNumber: 'ec-week-number'
|
|
26
|
+
});
|
|
27
|
+
assign(options.views, {
|
|
28
|
+
dayGridMonth: {
|
|
29
|
+
buttonText: btnTextMonth,
|
|
30
|
+
component: initViewComponent,
|
|
31
|
+
dayHeaderFormat: {weekday: 'short'},
|
|
32
|
+
dayHeaderAriaLabelFormat: {weekday: 'long'},
|
|
33
|
+
displayEventEnd: false,
|
|
34
|
+
duration: {months: 1},
|
|
35
|
+
theme: themeView('ec-day-grid ec-month-view'),
|
|
36
|
+
titleFormat: {year: 'numeric', month: 'long'}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
41
39
|
}
|
|
42
40
|
}
|
|
41
|
+
|
|
42
|
+
function initViewComponent(mainState) {
|
|
43
|
+
mainState.features = ['day-grid'];
|
|
44
|
+
mainState.extensions.activeRange = (start, end) => {
|
|
45
|
+
// Dependencies
|
|
46
|
+
let {options: {firstDay}} = mainState;
|
|
47
|
+
return {
|
|
48
|
+
start: prevClosestDay(start, firstDay),
|
|
49
|
+
end: nextClosestDay(end, firstDay)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return View;
|
|
53
|
+
}
|