@event-calendar/core 4.7.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -51
- package/dist/index.css +627 -731
- package/dist/index.js +2500 -3191
- package/package.json +2 -2
- package/src/Auxiliary.svelte +2 -13
- package/src/Buttons.svelte +62 -52
- package/src/Calendar.svelte +9 -3
- package/src/lib/a11y.js +2 -2
- package/src/lib/attachments.js +61 -0
- package/src/lib/chunks.js +117 -0
- package/src/lib/components/BaseDay.svelte +50 -0
- package/src/lib/components/BaseEvent.svelte +3 -3
- package/src/lib/components/ColHead.svelte +34 -0
- package/src/lib/components/DayHeader.svelte +14 -0
- package/src/lib/components/InteractableEvent.svelte +1 -3
- package/src/lib/components/index.js +3 -0
- package/src/lib/date.js +1 -1
- package/src/lib/dom.js +0 -4
- package/src/lib/events.js +10 -134
- package/src/lib/index.js +3 -2
- package/src/lib/{times.js → slots.js} +14 -19
- package/src/lib/stores.js +0 -33
- package/src/lib/utils.js +11 -2
- package/src/lib/view.js +0 -4
- package/src/plugins/day-grid/Day.svelte +36 -129
- package/src/plugins/day-grid/Event.svelte +42 -41
- package/src/plugins/day-grid/Popup.svelte +65 -48
- package/src/plugins/day-grid/View.svelte +76 -4
- package/src/plugins/day-grid/index.js +5 -5
- package/src/plugins/day-grid/lib.js +61 -0
- package/src/plugins/day-grid/stores.js +2 -20
- package/src/plugins/interaction/Action.svelte +40 -45
- package/src/plugins/interaction/Auxiliary.svelte +4 -4
- package/src/plugins/interaction/Pointer.svelte +8 -12
- package/src/plugins/interaction/Resizer.svelte +2 -2
- package/src/plugins/interaction/lib/utils.js +1 -5
- package/src/plugins/list/Day.svelte +8 -24
- package/src/plugins/list/View.svelte +39 -2
- package/src/plugins/resource-time-grid/Label.svelte +2 -2
- package/src/plugins/resource-time-grid/View.svelte +38 -82
- package/src/plugins/resource-time-grid/index.js +18 -10
- package/src/plugins/resource-time-grid/lib.js +31 -0
- package/src/plugins/resource-time-grid/options.js +10 -0
- package/src/plugins/resource-time-grid/stores.js +34 -0
- package/src/plugins/resource-timeline/Day.svelte +10 -73
- package/src/plugins/resource-timeline/Event.svelte +14 -23
- package/src/plugins/resource-timeline/Header.svelte +5 -5
- package/src/plugins/resource-timeline/Label.svelte +4 -12
- package/src/plugins/resource-timeline/NowIndicator.svelte +33 -28
- package/src/plugins/resource-timeline/View.svelte +129 -14
- package/src/plugins/resource-timeline/index.js +26 -23
- package/src/plugins/resource-timeline/lib.js +115 -118
- package/src/plugins/resource-timeline/stores.js +11 -7
- package/src/plugins/time-grid/AllDayEvent.svelte +31 -0
- package/src/plugins/time-grid/Day.svelte +11 -99
- package/src/plugins/time-grid/Event.svelte +18 -20
- package/src/plugins/time-grid/NowIndicator.svelte +32 -10
- package/src/plugins/time-grid/View.svelte +127 -35
- package/src/plugins/time-grid/index.js +10 -8
- package/src/plugins/time-grid/lib.js +142 -0
- package/src/plugins/time-grid/options.js +57 -0
- package/src/plugins/time-grid/stores.js +41 -8
- package/src/storage/options.js +4 -39
- package/src/storage/state.js +1 -4
- package/src/storage/stores.js +42 -11
- package/src/styles/days.css +91 -0
- package/src/styles/events.css +180 -0
- package/src/styles/index.css +126 -0
- package/src/styles/now-indicator.css +35 -0
- package/src/styles/popup.css +30 -0
- package/src/styles/sidebar.css +59 -0
- package/src/styles/slots.css +42 -0
- package/src/styles/theme.css +68 -0
- package/src/styles/toolbar.css +80 -0
- package/src/lib/actions.js +0 -52
- package/src/plugins/day-grid/Body.svelte +0 -54
- package/src/plugins/day-grid/Header.svelte +0 -20
- package/src/plugins/day-grid/Week.svelte +0 -60
- package/src/plugins/list/Body.svelte +0 -44
- package/src/plugins/resource-timeline/Body.svelte +0 -67
- package/src/plugins/resource-timeline/Days.svelte +0 -72
- package/src/plugins/resource-timeline/Sidebar.svelte +0 -35
- package/src/plugins/time-grid/Body.svelte +0 -43
- package/src/plugins/time-grid/Section.svelte +0 -29
- package/src/plugins/time-grid/all-day/Day.svelte +0 -65
- package/src/plugins/time-grid/all-day/Event.svelte +0 -37
- package/src/plugins/time-grid/all-day/Week.svelte +0 -65
- package/src/plugins/time-grid/utils.js +0 -58
- package/src/styles/day-grid.scss +0 -51
- package/src/styles/index.scss +0 -553
- package/src/styles/theme.scss +0 -95
- package/src/styles/time-grid.scss +0 -83
- package/src/styles/timeline.scss +0 -152
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event-calendar/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"title": "Event Calendar Core package",
|
|
5
5
|
"description": "Full-sized drag & drop event calendar with resource & timeline views",
|
|
6
6
|
"keywords": [
|
|
@@ -32,6 +32,6 @@
|
|
|
32
32
|
"#components": "./src/lib/components/index.js"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"svelte": "^5.
|
|
35
|
+
"svelte": "^5.45.8"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/Auxiliary.svelte
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext, untrack} from 'svelte';
|
|
3
3
|
import {
|
|
4
|
-
toISOString, toLocalDate, toViewWithLocalDates, isFunction, task, flushDebounce
|
|
4
|
+
toISOString, toLocalDate, toViewWithLocalDates, isFunction, task, flushDebounce
|
|
5
5
|
} from '#lib';
|
|
6
6
|
|
|
7
7
|
let {
|
|
8
|
-
datesSet, eventAllUpdated, _auxiliary, _activeRange, _filteredEvents,
|
|
9
|
-
_queue, _view
|
|
8
|
+
datesSet, eventAllUpdated, _auxiliary, _activeRange, _filteredEvents, _tasks, _queue, _view
|
|
10
9
|
} = getContext('state');
|
|
11
10
|
|
|
12
11
|
// datesSet callback
|
|
@@ -41,16 +40,6 @@
|
|
|
41
40
|
flushDebounce($_queue);
|
|
42
41
|
});
|
|
43
42
|
});
|
|
44
|
-
|
|
45
|
-
$effect(() => {
|
|
46
|
-
$_recheckScrollable;
|
|
47
|
-
untrack(() => {
|
|
48
|
-
if ($_bodyEl) {
|
|
49
|
-
$_scrollable = hasYScroll($_bodyEl);
|
|
50
|
-
}
|
|
51
|
-
$_recheckScrollable = false;
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
43
|
</script>
|
|
55
44
|
|
|
56
45
|
{#each $_auxiliary as Component}
|
package/src/Buttons.svelte
CHANGED
|
@@ -1,49 +1,55 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext, tick} from 'svelte';
|
|
3
|
-
import {
|
|
2
|
+
import {getContext, tick, untrack} from 'svelte';
|
|
3
|
+
import {cloneDate, contentFrom, nextDate, prevDate, outsideRange} from '#lib';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
let {buttons} = $props();
|
|
6
6
|
|
|
7
7
|
let {
|
|
8
|
-
_currentRange, _viewTitle, _viewDates, buttonText, customButtons, date, duration, hiddenDays, theme,
|
|
9
|
-
view
|
|
8
|
+
_currentRange, _today, _viewTitle, _viewDates, buttonText, customButtons, date, duration, hiddenDays, theme,
|
|
9
|
+
validRange, view
|
|
10
10
|
} = getContext('state');
|
|
11
11
|
|
|
12
|
-
let
|
|
13
|
-
let
|
|
12
|
+
let prevDisabled = $state(false);
|
|
13
|
+
let nextDisabled = $state(false);
|
|
14
|
+
let todayDisabled = $state(false);
|
|
14
15
|
|
|
15
16
|
let running = false;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
17
|
+
$effect.pre(() => {
|
|
18
|
+
$_viewDates;
|
|
19
|
+
$validRange;
|
|
20
|
+
buttons;
|
|
21
|
+
untrack(() => {
|
|
22
|
+
if (!running) {
|
|
23
|
+
running = true;
|
|
24
|
+
if (buttons.includes('prev')) {
|
|
25
|
+
prevDisabled = false;
|
|
26
|
+
if ($validRange.start) {
|
|
27
|
+
prevDisabled = test(prev);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (buttons.includes('next')) {
|
|
31
|
+
nextDisabled = false;
|
|
32
|
+
if ($validRange.end) {
|
|
33
|
+
nextDisabled = test(next);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (buttons.includes('today')) {
|
|
37
|
+
todayDisabled = $_today >= $_currentRange.start && $_today < $_currentRange.end;
|
|
38
|
+
if (!todayDisabled && ($validRange.start || $validRange.end)) {
|
|
39
|
+
todayDisabled = test(today);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
tick().then(() => running = false);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
44
46
|
|
|
45
|
-
function test() {
|
|
46
|
-
|
|
47
|
+
function test(fn) {
|
|
48
|
+
let currentDate = cloneDate($date);
|
|
49
|
+
fn();
|
|
50
|
+
let result = $_viewDates.every(date => outsideRange(date, $validRange));
|
|
51
|
+
$date = currentDate;
|
|
52
|
+
return result;
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
function prev() {
|
|
@@ -53,45 +59,49 @@
|
|
|
53
59
|
function next() {
|
|
54
60
|
$date = nextDate($date, $duration);
|
|
55
61
|
}
|
|
62
|
+
|
|
63
|
+
function today() {
|
|
64
|
+
$date = cloneDate($_today);
|
|
65
|
+
}
|
|
56
66
|
</script>
|
|
57
67
|
|
|
58
68
|
{#each buttons as button}
|
|
59
|
-
{#if button
|
|
60
|
-
<!-- svelte-ignore
|
|
61
|
-
<h2 class="{$theme.title}"
|
|
62
|
-
{:else if button
|
|
69
|
+
{#if button === 'title'}
|
|
70
|
+
<!-- svelte-ignore a11y_missing_content -->
|
|
71
|
+
<h2 class="{$theme.title}" {@attach contentFrom($_viewTitle)}></h2>
|
|
72
|
+
{:else if button === 'prev'}
|
|
63
73
|
<button
|
|
64
74
|
class="{$theme.button} ec-{button}"
|
|
65
75
|
aria-label={$buttonText.prev}
|
|
66
76
|
title={$buttonText.prev}
|
|
67
|
-
|
|
77
|
+
onclick={prev}
|
|
68
78
|
disabled={prevDisabled}
|
|
69
79
|
><i class="{$theme.icon} ec-{button}"></i></button>
|
|
70
|
-
{:else if button
|
|
80
|
+
{:else if button === 'next'}
|
|
71
81
|
<button
|
|
72
82
|
class="{$theme.button} ec-{button}"
|
|
73
83
|
aria-label={$buttonText.next}
|
|
74
84
|
title={$buttonText.next}
|
|
75
|
-
|
|
85
|
+
onclick={next}
|
|
76
86
|
disabled={nextDisabled}
|
|
77
87
|
><i class="{$theme.icon} ec-{button}"></i></button>
|
|
78
|
-
{:else if button
|
|
88
|
+
{:else if button === 'today'}
|
|
79
89
|
<button
|
|
80
90
|
class="{$theme.button} ec-{button}"
|
|
81
|
-
|
|
91
|
+
onclick={today}
|
|
82
92
|
disabled={todayDisabled}
|
|
83
93
|
>{$buttonText[button]}</button>
|
|
84
94
|
{:else if $customButtons[button]}
|
|
85
95
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
86
96
|
<button
|
|
87
|
-
class=
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
class={[$theme.button, `ec-${button}`, $customButtons[button].active && $theme.active]}
|
|
98
|
+
onclick={$customButtons[button].click}
|
|
99
|
+
{@attach contentFrom($customButtons[button].text)}
|
|
90
100
|
></button>
|
|
91
|
-
{:else if button
|
|
101
|
+
{:else if button !== ''}
|
|
92
102
|
<button
|
|
93
|
-
class=
|
|
94
|
-
|
|
103
|
+
class={[$theme.button, `ec-${button}`, $view === button && $theme.active]}
|
|
104
|
+
onclick={() => $view = button}
|
|
95
105
|
>{$buttonText[button]}</button>
|
|
96
106
|
{/if}
|
|
97
107
|
{/each}
|
package/src/Calendar.svelte
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import '
|
|
2
|
+
import './styles/index.css';
|
|
3
3
|
import {setContext, untrack} from 'svelte';
|
|
4
4
|
import {get} from 'svelte/store';
|
|
5
5
|
import {diff} from './storage/options.js';
|
|
@@ -13,15 +13,17 @@
|
|
|
13
13
|
|
|
14
14
|
let {plugins = [], options = {}} = $props();
|
|
15
15
|
|
|
16
|
+
// svelte-ignore state_referenced_locally
|
|
16
17
|
let state = new State(plugins, options);
|
|
17
18
|
setContext('state', state);
|
|
18
19
|
|
|
19
20
|
let {
|
|
20
|
-
_viewComponent, _interaction, _iClass, _events,
|
|
21
|
+
_viewComponent, _interaction, _iClass, _events,
|
|
21
22
|
date, duration, hiddenDays, height, theme, view
|
|
22
23
|
} = state;
|
|
23
24
|
|
|
24
25
|
// Reactively update options that did change
|
|
26
|
+
// svelte-ignore state_referenced_locally
|
|
25
27
|
let prevOptions = {...options};
|
|
26
28
|
$effect(() => {
|
|
27
29
|
for (let [name, value] of diff(options, prevOptions)) {
|
|
@@ -122,7 +124,11 @@
|
|
|
122
124
|
</script>
|
|
123
125
|
|
|
124
126
|
<div
|
|
125
|
-
class=
|
|
127
|
+
class={[
|
|
128
|
+
$theme.calendar,
|
|
129
|
+
$theme.view,
|
|
130
|
+
$_iClass && $theme[$_iClass]
|
|
131
|
+
]}
|
|
126
132
|
style:height={$height}
|
|
127
133
|
role="{listView($view) ? 'list' : 'table'}"
|
|
128
134
|
>
|
package/src/lib/a11y.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
export function keyEnter(fn) {
|
|
2
|
+
export function keyEnter(fn, _this = undefined) {
|
|
3
3
|
return function (e) {
|
|
4
4
|
return e.key === 'Enter' || e.key === ' ' && !e.preventDefault() // prevent page scroll down
|
|
5
|
-
? fn.call(
|
|
5
|
+
? fn.call(_this, e)
|
|
6
6
|
: undefined;
|
|
7
7
|
};
|
|
8
8
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
export function contentFrom(content) {
|
|
3
|
+
return el => {
|
|
4
|
+
if (typeof content == 'string') {
|
|
5
|
+
el.innerText = content;
|
|
6
|
+
} else if (content?.domNodes) {
|
|
7
|
+
el.replaceChildren(...content.domNodes);
|
|
8
|
+
} else if (content?.html) {
|
|
9
|
+
el.innerHTML = content.html;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Dispatch event occurred outside of node */
|
|
15
|
+
export function outsideEvent(type) {
|
|
16
|
+
return el => {
|
|
17
|
+
let listener = jsEvent => {
|
|
18
|
+
if (el && !el.contains(jsEvent.target)) {
|
|
19
|
+
el.dispatchEvent(
|
|
20
|
+
new CustomEvent(type + 'outside', {detail: {jsEvent}})
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
document.addEventListener(type, listener, true);
|
|
25
|
+
|
|
26
|
+
return () => {
|
|
27
|
+
document.removeEventListener(type, listener, true);
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function resizeObserver(callback) {
|
|
33
|
+
return el => {
|
|
34
|
+
let observer = new ResizeObserver(entries => {
|
|
35
|
+
for (let entry of entries) {
|
|
36
|
+
callback(el, entry);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
observer.observe(el);
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
observer.unobserve(el);
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function intersectionObserver(callback, options) {
|
|
48
|
+
return el => {
|
|
49
|
+
let observer = new IntersectionObserver(entries => {
|
|
50
|
+
for (let entry of entries) {
|
|
51
|
+
callback(el, entry);
|
|
52
|
+
}
|
|
53
|
+
}, options);
|
|
54
|
+
|
|
55
|
+
observer.observe(el);
|
|
56
|
+
|
|
57
|
+
return () => {
|
|
58
|
+
observer.unobserve(el);
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {datesEqual} from './date.js';
|
|
2
|
+
import {eventIntersects} from './events.js';
|
|
3
|
+
import {assign} from './utils.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @returns {{
|
|
7
|
+
* start: Date,
|
|
8
|
+
* end: Date,
|
|
9
|
+
* event: Object,
|
|
10
|
+
* zeroDuration?: boolean,
|
|
11
|
+
* gridColumn?: Number,
|
|
12
|
+
* gridRow?: Number,
|
|
13
|
+
* group?: Object,
|
|
14
|
+
* groupColumn?: Number,
|
|
15
|
+
* dates?: Array
|
|
16
|
+
* day?: Array,
|
|
17
|
+
* long?: Object,
|
|
18
|
+
* prev?: Object,
|
|
19
|
+
* top?: Number,
|
|
20
|
+
* bottom?: Number,
|
|
21
|
+
* left?: Number,
|
|
22
|
+
* height?: Number,
|
|
23
|
+
* width?: Number,
|
|
24
|
+
* maxHeight?: Number
|
|
25
|
+
* }}
|
|
26
|
+
*/
|
|
27
|
+
export function createEventChunk(event, start, end) {
|
|
28
|
+
let chunk = {
|
|
29
|
+
start: event.start > start ? event.start : start,
|
|
30
|
+
end: event.end < end ? event.end : end,
|
|
31
|
+
event
|
|
32
|
+
};
|
|
33
|
+
chunk.zeroDuration = datesEqual(chunk.start, chunk.end);
|
|
34
|
+
|
|
35
|
+
return chunk;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create event chunk for month view and all-day slot in week view
|
|
40
|
+
*/
|
|
41
|
+
export function createAllDayChunks(event, days) {
|
|
42
|
+
let dates = [];
|
|
43
|
+
let lastEnd;
|
|
44
|
+
let gridColumn;
|
|
45
|
+
let gridRow;
|
|
46
|
+
for (let {gridColumn: column, gridRow: row, resource, dayStart, dayEnd, disabled} of days) {
|
|
47
|
+
if (!disabled && eventIntersects(event, dayStart, dayEnd, resource)) {
|
|
48
|
+
dates.push(dayStart);
|
|
49
|
+
lastEnd = dayEnd;
|
|
50
|
+
if (!gridColumn) {
|
|
51
|
+
gridColumn = column;
|
|
52
|
+
gridRow = row;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (dates.length) {
|
|
57
|
+
let chunk = createEventChunk(event, dates[0], lastEnd);
|
|
58
|
+
// Chunk layout
|
|
59
|
+
assign(chunk, {gridColumn, gridRow, dates});
|
|
60
|
+
|
|
61
|
+
return [chunk];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Prepare event chunks for month view and all-day slot in week view
|
|
69
|
+
*/
|
|
70
|
+
export function prepareAllDayChunks(chunks) {
|
|
71
|
+
let prevChunks = {};
|
|
72
|
+
let longChunks = {};
|
|
73
|
+
for (let chunk of chunks) {
|
|
74
|
+
let {gridColumn, gridRow} = chunk;
|
|
75
|
+
// Prepare long chunks
|
|
76
|
+
for (let i = 1; i < chunk.dates.length; ++ i) {
|
|
77
|
+
let key = `${gridRow}_${gridColumn + i}`;
|
|
78
|
+
if (longChunks[key]) {
|
|
79
|
+
longChunks[key].chunks.push(chunk);
|
|
80
|
+
} else {
|
|
81
|
+
longChunks[key] = {
|
|
82
|
+
sorted: false,
|
|
83
|
+
chunks: [chunk]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
let key = `${gridRow}_${gridColumn}`;
|
|
88
|
+
chunk.long = longChunks[key];
|
|
89
|
+
// Connect with previous chunk
|
|
90
|
+
chunk.prev = prevChunks[key];
|
|
91
|
+
prevChunks[key] = chunk;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function repositionEvent(chunk, height, top = 0) {
|
|
96
|
+
if (chunk.prev) {
|
|
97
|
+
top = chunk.prev.bottom + 1;
|
|
98
|
+
}
|
|
99
|
+
let bottom = top + height;
|
|
100
|
+
if (chunk.long) {
|
|
101
|
+
let longChunks = chunk.long;
|
|
102
|
+
if (!longChunks.sorted) {
|
|
103
|
+
longChunks.chunks.sort((a, b) => a.top - b.top);
|
|
104
|
+
longChunks.sorted = true;
|
|
105
|
+
}
|
|
106
|
+
for (let longChunk of longChunks.chunks) {
|
|
107
|
+
if (top < longChunk.bottom && bottom > longChunk.top) {
|
|
108
|
+
let offset = longChunk.bottom - top + 1;
|
|
109
|
+
top += offset;
|
|
110
|
+
bottom += offset;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
assign(chunk, {top, bottom});
|
|
115
|
+
|
|
116
|
+
return top;
|
|
117
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {getContext, onMount} from 'svelte';
|
|
3
|
+
import {datesEqual, identity, setPayload} from '#lib';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
el = $bindable(),
|
|
7
|
+
date,
|
|
8
|
+
allDay = false,
|
|
9
|
+
resource = undefined,
|
|
10
|
+
dateFromPoint = () => date,
|
|
11
|
+
classes = identity,
|
|
12
|
+
disabled = false,
|
|
13
|
+
highlight = false,
|
|
14
|
+
role = 'cell',
|
|
15
|
+
children
|
|
16
|
+
} = $props();
|
|
17
|
+
|
|
18
|
+
let {_interaction, _today, highlightedDates, theme} = getContext('state');
|
|
19
|
+
|
|
20
|
+
let isToday = $derived(datesEqual(date, $_today));
|
|
21
|
+
|
|
22
|
+
// Class
|
|
23
|
+
let classNames = $derived(classes([
|
|
24
|
+
$theme.day,
|
|
25
|
+
$theme.weekdays?.[date.getUTCDay()],
|
|
26
|
+
isToday && $theme.today,
|
|
27
|
+
highlight && $theme.highlight,
|
|
28
|
+
disabled && $theme.disabled
|
|
29
|
+
]));
|
|
30
|
+
|
|
31
|
+
// dateFromPoint
|
|
32
|
+
onMount(() => {
|
|
33
|
+
setPayload(el, (x, y) => {
|
|
34
|
+
return {
|
|
35
|
+
allDay,
|
|
36
|
+
date: dateFromPoint(x, y),
|
|
37
|
+
resource,
|
|
38
|
+
dayEl: el,
|
|
39
|
+
disabled
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<div
|
|
46
|
+
bind:this={el}
|
|
47
|
+
class={classNames}
|
|
48
|
+
{role}
|
|
49
|
+
onpointerdown={!disabled ? $_interaction.action?.select : undefined}
|
|
50
|
+
>{@render children?.()}</div>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {getContext, onMount} from 'svelte';
|
|
3
3
|
import {
|
|
4
4
|
bgEvent, createEventClasses, createEventContent, entries, helperEvent, identity, isFunction, keyEnter,
|
|
5
|
-
resourceBackgroundColor, resourceTextColor,
|
|
5
|
+
resourceBackgroundColor, resourceTextColor, contentFrom, toEventWithLocalDates, toViewWithLocalDates
|
|
6
6
|
} from '#lib';
|
|
7
7
|
|
|
8
8
|
let {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
let classNames = $derived(classes([
|
|
34
34
|
bgEvent(display) ? $theme.bgEvent : $theme.event,
|
|
35
35
|
...createEventClasses($eventClassNames, event, $_view)
|
|
36
|
-
])
|
|
36
|
+
]));
|
|
37
37
|
|
|
38
38
|
// Content
|
|
39
39
|
let [timeText, content] = $derived(createEventContent(
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
{onpointerdown}
|
|
79
79
|
>
|
|
80
80
|
{#snippet defaultBody()}
|
|
81
|
-
<div class={$theme.eventBody}
|
|
81
|
+
<div class={$theme.eventBody} {@attach contentFrom(content)}></div>
|
|
82
82
|
{/snippet}
|
|
83
83
|
{#if body}
|
|
84
84
|
{@render body(defaultBody, bgColor, txtColor)}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {getContext} from 'svelte';
|
|
3
|
+
import {datesEqual} from '#lib';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
date,
|
|
7
|
+
className,
|
|
8
|
+
weekday = true,
|
|
9
|
+
colSpan = 1,
|
|
10
|
+
colIndex,
|
|
11
|
+
ariaHidden = false,
|
|
12
|
+
disabled = false,
|
|
13
|
+
highlight = false,
|
|
14
|
+
children
|
|
15
|
+
} = $props();
|
|
16
|
+
|
|
17
|
+
let {_today, theme} = getContext('state');
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div
|
|
21
|
+
class={[
|
|
22
|
+
className ?? $theme.colHead,
|
|
23
|
+
weekday && $theme.weekdays?.[date.getUTCDay()],
|
|
24
|
+
weekday && datesEqual(date, $_today) && $theme.today,
|
|
25
|
+
highlight && $theme.highlight,
|
|
26
|
+
disabled && $theme.disabled
|
|
27
|
+
]}
|
|
28
|
+
role="{ariaHidden ? null : 'columnheader'}"
|
|
29
|
+
aria-colspan="{ariaHidden || colSpan <= 1 ? null : colSpan}"
|
|
30
|
+
aria-colindex="{ariaHidden ? null : colIndex}"
|
|
31
|
+
aria-hidden="{ariaHidden ? 'true' : null}"
|
|
32
|
+
>
|
|
33
|
+
{@render children()}
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {getContext} from 'svelte';
|
|
3
|
+
import {contentFrom, toISOString} from '#lib';
|
|
4
|
+
|
|
5
|
+
let {date, alPrefix = ''} = $props();
|
|
6
|
+
|
|
7
|
+
let {_intlDayHeader, _intlDayHeaderAL} = getContext('state');
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<time
|
|
11
|
+
datetime="{toISOString(date, 10)}"
|
|
12
|
+
aria-label="{alPrefix}{$_intlDayHeaderAL.format(date)}"
|
|
13
|
+
{@attach contentFrom($_intlDayHeader.format(date))}
|
|
14
|
+
></time>
|
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
function createDragHandler(event) {
|
|
24
24
|
return $_interaction.action?.draggable(event)
|
|
25
|
-
? jsEvent => $_interaction.action.drag(
|
|
26
|
-
event, jsEvent, forceDate?.(), forceMargin?.()
|
|
27
|
-
)
|
|
25
|
+
? jsEvent => $_interaction.action.drag(event, jsEvent, forceDate, forceMargin)
|
|
28
26
|
: $_interaction.action?.noAction;
|
|
29
27
|
}
|
|
30
28
|
let onpointerdown = $derived(!bgEvent(display) && !helperEvent(display) ? createDragHandler(event) : undefined);
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
export {default as BaseDay} from './BaseDay.svelte';
|
|
1
2
|
export {default as BaseEvent} from './BaseEvent.svelte';
|
|
3
|
+
export {default as ColHead} from './ColHead.svelte';
|
|
4
|
+
export {default as DayHeader} from './DayHeader.svelte';
|
|
2
5
|
export {default as InteractableEvent} from './InteractableEvent.svelte';
|
package/src/lib/date.js
CHANGED
|
@@ -159,7 +159,7 @@ export function prevDate(date, duration, hiddenDays) {
|
|
|
159
159
|
export function getWeekNumber(date, firstDay) {
|
|
160
160
|
// Copy date so don't modify original
|
|
161
161
|
date = cloneDate(date);
|
|
162
|
-
if (firstDay
|
|
162
|
+
if (firstDay === 0) { // Western
|
|
163
163
|
// Set to nearest Saturday: current date + 6 - current day number
|
|
164
164
|
date.setUTCDate(date.getUTCDate() + 6 - date.getUTCDay());
|
|
165
165
|
} else { // ISO
|
package/src/lib/dom.js
CHANGED