@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event-calendar/core",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.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.46.
|
|
35
|
+
"svelte": "^5.46.1"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/Buttons.svelte
CHANGED
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
let {buttons} = $props();
|
|
6
6
|
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
validRange, view
|
|
10
|
-
} = getContext('state');
|
|
7
|
+
let mainState = getContext('state');
|
|
8
|
+
let {currentRange, today, viewTitle, viewDates, options: {buttonText, customButtons, date, duration, hiddenDays,
|
|
9
|
+
theme, validRange, view}} = $derived(mainState);
|
|
11
10
|
|
|
12
11
|
let prevDisabled = $state(false);
|
|
13
12
|
let nextDisabled = $state(false);
|
|
@@ -15,28 +14,28 @@
|
|
|
15
14
|
|
|
16
15
|
let running = false;
|
|
17
16
|
$effect.pre(() => {
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
viewDates;
|
|
18
|
+
validRange;
|
|
20
19
|
buttons;
|
|
21
20
|
untrack(() => {
|
|
22
21
|
if (!running) {
|
|
23
22
|
running = true;
|
|
24
23
|
if (buttons.includes('prev')) {
|
|
25
24
|
prevDisabled = false;
|
|
26
|
-
if (
|
|
25
|
+
if (validRange.start) {
|
|
27
26
|
prevDisabled = test(prev);
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
if (buttons.includes('next')) {
|
|
31
30
|
nextDisabled = false;
|
|
32
|
-
if (
|
|
31
|
+
if (validRange.end) {
|
|
33
32
|
nextDisabled = test(next);
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
if (buttons.includes('today')) {
|
|
37
|
-
todayDisabled =
|
|
38
|
-
if (!todayDisabled && (
|
|
39
|
-
todayDisabled = test(
|
|
36
|
+
todayDisabled = today >= currentRange.start && today < currentRange.end;
|
|
37
|
+
if (!todayDisabled && (validRange.start || validRange.end)) {
|
|
38
|
+
todayDisabled = test(setToday);
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
tick().then(() => running = false);
|
|
@@ -45,63 +44,63 @@
|
|
|
45
44
|
});
|
|
46
45
|
|
|
47
46
|
function test(fn) {
|
|
48
|
-
let currentDate =
|
|
47
|
+
let currentDate = date;
|
|
49
48
|
fn();
|
|
50
|
-
let result =
|
|
51
|
-
|
|
49
|
+
let result = viewDates.every(date => outsideRange(date, validRange));
|
|
50
|
+
mainState.setOption('date', currentDate);
|
|
52
51
|
return result;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
function prev() {
|
|
56
|
-
|
|
55
|
+
mainState.setOption('date', prevDate(cloneDate(date), duration, hiddenDays));
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
function next() {
|
|
60
|
-
|
|
59
|
+
mainState.setOption('date', nextDate(cloneDate(date), duration));
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
function
|
|
64
|
-
|
|
62
|
+
function setToday() {
|
|
63
|
+
mainState.setOption('date', cloneDate(today));
|
|
65
64
|
}
|
|
66
65
|
</script>
|
|
67
66
|
|
|
68
67
|
{#each buttons as button}
|
|
69
68
|
{#if button === 'title'}
|
|
70
69
|
<!-- svelte-ignore a11y_missing_content -->
|
|
71
|
-
<h2 class="{
|
|
70
|
+
<h2 class="{theme.title}" {@attach contentFrom(viewTitle)}></h2>
|
|
72
71
|
{:else if button === 'prev'}
|
|
73
72
|
<button
|
|
74
|
-
class="{
|
|
75
|
-
aria-label={
|
|
76
|
-
title={
|
|
73
|
+
class="{theme.button} ec-{button}"
|
|
74
|
+
aria-label={buttonText.prev}
|
|
75
|
+
title={buttonText.prev}
|
|
77
76
|
onclick={prev}
|
|
78
77
|
disabled={prevDisabled}
|
|
79
|
-
><i class="{
|
|
78
|
+
><i class="{theme.icon} ec-{button}"></i></button>
|
|
80
79
|
{:else if button === 'next'}
|
|
81
80
|
<button
|
|
82
|
-
class="{
|
|
83
|
-
aria-label={
|
|
84
|
-
title={
|
|
81
|
+
class="{theme.button} ec-{button}"
|
|
82
|
+
aria-label={buttonText.next}
|
|
83
|
+
title={buttonText.next}
|
|
85
84
|
onclick={next}
|
|
86
85
|
disabled={nextDisabled}
|
|
87
|
-
><i class="{
|
|
86
|
+
><i class="{theme.icon} ec-{button}"></i></button>
|
|
88
87
|
{:else if button === 'today'}
|
|
89
88
|
<button
|
|
90
|
-
class="{
|
|
91
|
-
onclick={
|
|
89
|
+
class="{theme.button} ec-{button}"
|
|
90
|
+
onclick={setToday}
|
|
92
91
|
disabled={todayDisabled}
|
|
93
|
-
>{
|
|
94
|
-
{:else if
|
|
92
|
+
>{buttonText[button]}</button>
|
|
93
|
+
{:else if customButtons[button]}
|
|
95
94
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
96
95
|
<button
|
|
97
|
-
class={[
|
|
98
|
-
onclick={
|
|
99
|
-
{@attach contentFrom(
|
|
96
|
+
class={[theme.button, `ec-${button}`, customButtons[button].active && theme.active]}
|
|
97
|
+
onclick={customButtons[button].click}
|
|
98
|
+
{@attach contentFrom(customButtons[button].text)}
|
|
100
99
|
></button>
|
|
101
100
|
{:else if button !== ''}
|
|
102
101
|
<button
|
|
103
|
-
class={[
|
|
104
|
-
onclick={() =>
|
|
105
|
-
>{
|
|
102
|
+
class={[theme.button, `ec-${button}`, view === button && theme.active]}
|
|
103
|
+
onclick={() => mainState.setOption('view', button)}
|
|
104
|
+
>{buttonText[button]}</button>
|
|
106
105
|
{/if}
|
|
107
106
|
{/each}
|
package/src/Calendar.svelte
CHANGED
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import './styles/index.css';
|
|
3
3
|
import {setContext, untrack} from 'svelte';
|
|
4
|
-
import {get} from 'svelte/store';
|
|
5
|
-
import {diff} from './storage/options.js';
|
|
6
|
-
import State from './storage/state.js';
|
|
7
|
-
import Toolbar from './Toolbar.svelte';
|
|
8
|
-
import Auxiliary from './Auxiliary.svelte';
|
|
9
4
|
import {
|
|
10
|
-
assign, createEvents, getElementWithPayload, getPayload,
|
|
5
|
+
assign, cloneDate, createEvents, getElementWithPayload, getPayload, nextDate,
|
|
11
6
|
prevDate, toEventWithLocalDates, toLocalDate, toViewWithLocalDates
|
|
12
7
|
} from '#lib';
|
|
8
|
+
import MainState from './storage/state.svelte.js';
|
|
9
|
+
import {diff} from './storage/options.svelte.js';
|
|
10
|
+
import Toolbar from './Toolbar.svelte';
|
|
13
11
|
|
|
14
12
|
let {plugins = [], options = {}} = $props();
|
|
15
13
|
|
|
16
14
|
// svelte-ignore state_referenced_locally
|
|
17
|
-
let
|
|
18
|
-
setContext('state',
|
|
15
|
+
let mainState = new MainState(plugins, options);
|
|
16
|
+
setContext('state', mainState);
|
|
19
17
|
|
|
20
18
|
let {
|
|
21
|
-
|
|
22
|
-
date, duration,
|
|
23
|
-
} =
|
|
19
|
+
auxComponents, features, events, interaction, iClass, view, viewComponent: View,
|
|
20
|
+
options: {date, duration, height, hiddenDays, theme}
|
|
21
|
+
} = $derived(mainState);
|
|
24
22
|
|
|
25
23
|
// Reactively update options that did change
|
|
26
24
|
// svelte-ignore state_referenced_locally
|
|
27
25
|
let prevOptions = {...options};
|
|
28
|
-
$effect(() => {
|
|
26
|
+
$effect.pre(() => {
|
|
29
27
|
for (let [name, value] of diff(options, prevOptions)) {
|
|
30
28
|
untrack(() => {
|
|
31
29
|
setOption(name, value);
|
|
@@ -35,27 +33,28 @@
|
|
|
35
33
|
});
|
|
36
34
|
|
|
37
35
|
export function setOption(name, value) {
|
|
38
|
-
|
|
36
|
+
mainState.setOption(name, value, false);
|
|
39
37
|
return this;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
export function getOption(name) {
|
|
43
|
-
let value =
|
|
41
|
+
let value = mainState.options[name];
|
|
44
42
|
return value instanceof Date ? toLocalDate(value) : value;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
export function refetchEvents() {
|
|
48
|
-
|
|
46
|
+
mainState.fetchedRange = {start: undefined, end: undefined};
|
|
49
47
|
return this;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
export function getEvents() {
|
|
53
|
-
return
|
|
51
|
+
return events.map(toEventWithLocalDates);
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
export function getEventById(id) {
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
id = String(id);
|
|
56
|
+
for (let event of events) {
|
|
57
|
+
if (event.id === id) {
|
|
59
58
|
return toEventWithLocalDates(event);
|
|
60
59
|
}
|
|
61
60
|
}
|
|
@@ -64,17 +63,16 @@
|
|
|
64
63
|
|
|
65
64
|
export function addEvent(event) {
|
|
66
65
|
event = createEvents([event])[0];
|
|
67
|
-
|
|
68
|
-
$_events = $_events;
|
|
66
|
+
events.push(event);
|
|
69
67
|
return toEventWithLocalDates(event);
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
export function updateEvent(event) {
|
|
73
71
|
let id = String(event.id);
|
|
74
|
-
let idx =
|
|
72
|
+
let idx = events.findIndex(event => event.id === id);
|
|
75
73
|
if (idx >= 0) {
|
|
76
74
|
event = createEvents([event])[0];
|
|
77
|
-
|
|
75
|
+
events[idx] = event;
|
|
78
76
|
return toEventWithLocalDates(event);
|
|
79
77
|
}
|
|
80
78
|
return null;
|
|
@@ -82,20 +80,19 @@
|
|
|
82
80
|
|
|
83
81
|
export function removeEventById(id) {
|
|
84
82
|
id = String(id);
|
|
85
|
-
let idx =
|
|
83
|
+
let idx = events.findIndex(event => event.id === id);
|
|
86
84
|
if (idx >= 0) {
|
|
87
|
-
|
|
88
|
-
$_events = $_events;
|
|
85
|
+
events.splice(idx, 1);
|
|
89
86
|
}
|
|
90
87
|
return this;
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
export function getView() {
|
|
94
|
-
return toViewWithLocalDates(
|
|
91
|
+
return toViewWithLocalDates(view);
|
|
95
92
|
}
|
|
96
93
|
|
|
97
94
|
export function unselect() {
|
|
98
|
-
|
|
95
|
+
interaction.action?.unselect();
|
|
99
96
|
return this;
|
|
100
97
|
}
|
|
101
98
|
|
|
@@ -111,28 +108,28 @@
|
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
export function next() {
|
|
114
|
-
|
|
111
|
+
mainState.setOption('date', nextDate(cloneDate(date), duration));
|
|
115
112
|
return this;
|
|
116
113
|
}
|
|
117
114
|
|
|
118
115
|
export function prev() {
|
|
119
|
-
|
|
116
|
+
mainState.setOption('date', prevDate(cloneDate(date), duration, hiddenDays));
|
|
120
117
|
return this;
|
|
121
118
|
}
|
|
122
|
-
|
|
123
|
-
let View = $derived($_viewComponent);
|
|
124
119
|
</script>
|
|
125
120
|
|
|
126
121
|
<div
|
|
127
122
|
class={[
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
theme.calendar,
|
|
124
|
+
theme.view,
|
|
125
|
+
iClass && theme[iClass]
|
|
131
126
|
]}
|
|
132
|
-
style:height
|
|
133
|
-
role="{
|
|
127
|
+
style:height
|
|
128
|
+
role="{features.includes('list') ? 'list' : 'table'}"
|
|
134
129
|
>
|
|
135
130
|
<Toolbar/>
|
|
136
131
|
<View/>
|
|
132
|
+
{#each auxComponents as AuxComponent}
|
|
133
|
+
<AuxComponent/>
|
|
134
|
+
{/each}
|
|
137
135
|
</div>
|
|
138
|
-
<Auxiliary/>
|
package/src/Toolbar.svelte
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
import {keys} from '#lib';
|
|
4
4
|
import Buttons from './Buttons.svelte';
|
|
5
5
|
|
|
6
|
-
let {headerToolbar, theme} = getContext('state');
|
|
6
|
+
let {options: {headerToolbar, theme}} = $derived(getContext('state'));
|
|
7
7
|
|
|
8
8
|
let sections = $derived.by(() => {
|
|
9
9
|
let sections = {};
|
|
10
10
|
for (let key of ['start', 'center', 'end']) {
|
|
11
|
-
sections[key] =
|
|
11
|
+
sections[key] = headerToolbar[key]?.split(' ').map(group => group.split(',')) ?? [];
|
|
12
12
|
}
|
|
13
13
|
return sections;
|
|
14
14
|
});
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<nav class="{
|
|
17
|
+
<nav class="{theme.toolbar}">
|
|
18
18
|
{#each keys(sections) as key}
|
|
19
19
|
<div class="ec-{key}">
|
|
20
20
|
{#each sections[key] as buttons}
|
|
21
21
|
{#if buttons.length > 1}
|
|
22
|
-
<div class="{
|
|
22
|
+
<div class="{theme.buttonGroup}">
|
|
23
23
|
<Buttons {buttons}/>
|
|
24
24
|
</div>
|
|
25
25
|
{:else}
|
|
@@ -17,19 +17,20 @@
|
|
|
17
17
|
children
|
|
18
18
|
} = $props();
|
|
19
19
|
|
|
20
|
-
let {
|
|
20
|
+
let {today, interaction: {action}, options: {theme}} = $derived(getContext('state'));
|
|
21
|
+
let {snap} = $derived(getContext('view-state')); // timeGrid has snap, others don't
|
|
21
22
|
|
|
22
|
-
let isToday = $derived(datesEqual(date,
|
|
23
|
+
let isToday = $derived(datesEqual(date, today));
|
|
23
24
|
|
|
24
25
|
// Class
|
|
25
26
|
let classNames = $derived(classes([
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
isToday &&
|
|
29
|
-
highlight &&
|
|
30
|
-
disabled &&
|
|
31
|
-
noIeb &&
|
|
32
|
-
noBeb &&
|
|
27
|
+
theme.day,
|
|
28
|
+
theme.weekdays?.[date.getUTCDay()],
|
|
29
|
+
isToday && theme.today,
|
|
30
|
+
highlight && theme.highlight,
|
|
31
|
+
disabled && theme.disabled,
|
|
32
|
+
noIeb && theme.noIeb,
|
|
33
|
+
noBeb && theme.noBeb
|
|
33
34
|
]));
|
|
34
35
|
|
|
35
36
|
// dateFromPoint
|
|
@@ -44,11 +45,13 @@
|
|
|
44
45
|
};
|
|
45
46
|
});
|
|
46
47
|
});
|
|
48
|
+
|
|
49
|
+
let onpointerdown = $derived(!disabled && action ? jsEvent => action.select(jsEvent, snap) : undefined);
|
|
47
50
|
</script>
|
|
48
51
|
|
|
49
52
|
<div
|
|
50
53
|
bind:this={el}
|
|
51
54
|
class={classNames}
|
|
52
55
|
{role}
|
|
53
|
-
onpointerdown
|
|
56
|
+
{onpointerdown}
|
|
54
57
|
>{@render children?.()}</div>
|
|
@@ -14,54 +14,54 @@
|
|
|
14
14
|
body
|
|
15
15
|
} = $props();
|
|
16
16
|
|
|
17
|
-
let {
|
|
17
|
+
let {intlEventTime, view, options: {
|
|
18
18
|
displayEventEnd, eventBackgroundColor, eventColor, eventContent, eventClick, eventDidMount, eventClassNames,
|
|
19
|
-
eventMouseEnter, eventMouseLeave, eventTextColor, resources, theme
|
|
20
|
-
} = getContext('state');
|
|
19
|
+
eventMouseEnter, eventMouseLeave, eventTextColor, resources, theme
|
|
20
|
+
}} = $derived(getContext('state'));
|
|
21
21
|
|
|
22
22
|
let event = $derived(chunk.event);
|
|
23
23
|
let display = $derived(chunk.event.display);
|
|
24
24
|
|
|
25
25
|
// Style
|
|
26
|
-
let bgColor = $derived(event.backgroundColor ?? resourceBackgroundColor(event,
|
|
27
|
-
let txtColor = $derived(event.textColor ?? resourceTextColor(event,
|
|
26
|
+
let bgColor = $derived(event.backgroundColor ?? resourceBackgroundColor(event, resources) ?? eventBackgroundColor ?? eventColor);
|
|
27
|
+
let txtColor = $derived(event.textColor ?? resourceTextColor(event, resources) ?? eventTextColor);
|
|
28
28
|
let style = $derived(entries(styles(
|
|
29
29
|
{'background-color': bgColor, 'color': txtColor}
|
|
30
30
|
)).map(entry => `${entry[0]}:${entry[1]}`).concat(event.styles).join(';'));
|
|
31
31
|
|
|
32
32
|
// Class
|
|
33
33
|
let classNames = $derived(classes([
|
|
34
|
-
bgEvent(display) ?
|
|
35
|
-
...createEventClasses(
|
|
34
|
+
bgEvent(display) ? theme.bgEvent : theme.event,
|
|
35
|
+
...createEventClasses(eventClassNames, event, view)
|
|
36
36
|
]));
|
|
37
37
|
|
|
38
38
|
// Content
|
|
39
39
|
let [timeText, content] = $derived(createEventContent(
|
|
40
|
-
chunk,
|
|
40
|
+
chunk, displayEventEnd, eventContent, theme, intlEventTime, view
|
|
41
41
|
));
|
|
42
42
|
|
|
43
43
|
onMount(() => {
|
|
44
|
-
if (isFunction(
|
|
45
|
-
|
|
44
|
+
if (isFunction(eventDidMount)) {
|
|
45
|
+
eventDidMount({
|
|
46
46
|
event: toEventWithLocalDates(event),
|
|
47
47
|
timeText,
|
|
48
48
|
el,
|
|
49
|
-
view: toViewWithLocalDates(
|
|
49
|
+
view: toViewWithLocalDates(view)
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
function createHandler(fn, display) {
|
|
55
|
-
return
|
|
56
|
-
? jsEvent => fn({event: toEventWithLocalDates(event), el, jsEvent, view: toViewWithLocalDates(
|
|
55
|
+
return isFunction(fn) && !helperEvent(display)
|
|
56
|
+
? jsEvent => fn({event: toEventWithLocalDates(event), el, jsEvent, view: toViewWithLocalDates(view)})
|
|
57
57
|
: undefined;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Handlers
|
|
61
|
-
let onclick = $derived(!bgEvent(display) && createHandler(
|
|
61
|
+
let onclick = $derived(!bgEvent(display) && createHandler(eventClick, display) || undefined);
|
|
62
62
|
let onkeydown = $derived(onclick && keyEnter(onclick));
|
|
63
|
-
let onmouseenter = $derived(createHandler(
|
|
64
|
-
let onmouseleave = $derived(createHandler(
|
|
63
|
+
let onmouseenter = $derived(createHandler(eventMouseEnter, display));
|
|
64
|
+
let onmouseleave = $derived(createHandler(eventMouseLeave, display));
|
|
65
65
|
</script>
|
|
66
66
|
|
|
67
67
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
{onpointerdown}
|
|
79
79
|
>
|
|
80
80
|
{#snippet defaultBody()}
|
|
81
|
-
<div class={
|
|
81
|
+
<div class={theme.eventBody} {@attach contentFrom(content)}></div>
|
|
82
82
|
{/snippet}
|
|
83
83
|
{#if body}
|
|
84
84
|
{@render body(defaultBody, bgColor, txtColor)}
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
children
|
|
15
15
|
} = $props();
|
|
16
16
|
|
|
17
|
-
let {
|
|
17
|
+
let {today, options: {theme}} = $derived(getContext('state'));
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<div
|
|
21
21
|
class={[
|
|
22
|
-
className ??
|
|
23
|
-
weekday &&
|
|
24
|
-
weekday && datesEqual(date,
|
|
25
|
-
highlight &&
|
|
26
|
-
disabled &&
|
|
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
27
|
]}
|
|
28
28
|
role="{ariaHidden ? null : 'columnheader'}"
|
|
29
29
|
aria-colspan="{ariaHidden || colSpan <= 1 ? null : colSpan}"
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
let {date, alPrefix = ''} = $props();
|
|
6
6
|
|
|
7
|
-
let {
|
|
7
|
+
let {intlDayHeader, intlDayHeaderAL} = $derived(getContext('state'));
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<time
|
|
11
11
|
datetime="{toISOString(date, 10)}"
|
|
12
|
-
aria-label="{alPrefix}{
|
|
13
|
-
{@attach contentFrom(
|
|
12
|
+
aria-label="{alPrefix}{intlDayHeaderAL.format(date)}"
|
|
13
|
+
{@attach contentFrom(intlDayHeader.format(date))}
|
|
14
14
|
></time>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
3
|
import BaseEvent from './BaseEvent.svelte';
|
|
4
|
-
import {bgEvent, helperEvent} from
|
|
4
|
+
import {bgEvent, helperEvent} from '#lib';
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
el = $bindable(),
|
|
@@ -12,22 +12,21 @@
|
|
|
12
12
|
forceMargin
|
|
13
13
|
} = $props();
|
|
14
14
|
|
|
15
|
-
let {
|
|
15
|
+
let {iClasses, interaction: {action, resizer: Resizer}} = $derived(getContext('state'));
|
|
16
|
+
let {snap} = $derived(getContext('view-state')); // timeGrid has snap, others don't
|
|
16
17
|
|
|
17
18
|
let event = $derived(chunk.event);
|
|
18
19
|
let display = $derived(chunk.event.display);
|
|
19
20
|
|
|
20
21
|
// Class
|
|
21
|
-
let classes = $derived(classNames =>
|
|
22
|
+
let classes = $derived(classNames => iClasses(classNames, event));
|
|
22
23
|
|
|
23
24
|
function createDragHandler(event) {
|
|
24
|
-
return
|
|
25
|
-
? jsEvent =>
|
|
26
|
-
:
|
|
25
|
+
return action?.draggable(event)
|
|
26
|
+
? jsEvent => action.drag(event, jsEvent, forceDate, forceMargin, snap)
|
|
27
|
+
: action?.noAction;
|
|
27
28
|
}
|
|
28
29
|
let onpointerdown = $derived(!bgEvent(display) && !helperEvent(display) ? createDragHandler(event) : undefined);
|
|
29
|
-
|
|
30
|
-
let Resizer = $derived($_interaction.resizer);
|
|
31
30
|
</script>
|
|
32
31
|
|
|
33
32
|
<BaseEvent bind:el {chunk} {classes} {styles} {onpointerdown}>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {untrack} from 'svelte';
|
|
2
|
+
import {isFunction} from './utils.js';
|
|
3
|
+
import {toLocalDate} from './date.js';
|
|
4
|
+
|
|
5
|
+
export function intl(mainState, option) {
|
|
6
|
+
return () => {
|
|
7
|
+
// Dependencies
|
|
8
|
+
let {options: {locale}} = mainState;
|
|
9
|
+
let format = mainState.options[option];
|
|
10
|
+
|
|
11
|
+
let intl;
|
|
12
|
+
|
|
13
|
+
untrack(() => {
|
|
14
|
+
intl = isFunction(format)
|
|
15
|
+
? {format}
|
|
16
|
+
: new Intl.DateTimeFormat(locale, format);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
format: date => intl.format(toLocalDate(date))
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function intlRange(mainState, option) {
|
|
26
|
+
return () => {
|
|
27
|
+
// Dependencies
|
|
28
|
+
let {options: {locale}} = mainState;
|
|
29
|
+
let format = mainState.options[option];
|
|
30
|
+
|
|
31
|
+
let formatRange;
|
|
32
|
+
|
|
33
|
+
untrack(() => {
|
|
34
|
+
if (isFunction(format)) {
|
|
35
|
+
formatRange = format;
|
|
36
|
+
} else {
|
|
37
|
+
let intl = new Intl.DateTimeFormat(locale, format);
|
|
38
|
+
formatRange = (start, end) => {
|
|
39
|
+
if (start <= end) {
|
|
40
|
+
return intl.formatRange(start, end);
|
|
41
|
+
} else {
|
|
42
|
+
// In iOS 16 and older, intl.formatRange() throws an exception if the start date is later than the end date.
|
|
43
|
+
// Therefore, we first swap the parameters, and then swap the resulting parts.
|
|
44
|
+
/** @see https://github.com/vkurko/calendar/issues/227 */
|
|
45
|
+
let parts = intl.formatRangeToParts(end, start);
|
|
46
|
+
let result = '';
|
|
47
|
+
let sources = ['startRange', 'endRange'];
|
|
48
|
+
let processed = [false, false];
|
|
49
|
+
for (let part of parts) {
|
|
50
|
+
let i = sources.indexOf(part.source);
|
|
51
|
+
if (i >= 0) {
|
|
52
|
+
if (!processed[i]) {
|
|
53
|
+
result += _getParts(sources[1 - i], parts);
|
|
54
|
+
processed[i] = true;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
result += part.value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
formatRange: (start, end) => formatRange(toLocalDate(start), toLocalDate(end))
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function _getParts(source, parts) {
|
|
73
|
+
let result = '';
|
|
74
|
+
for (let part of parts) {
|
|
75
|
+
if (part.source == source) {
|
|
76
|
+
result += part.value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
package/src/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export * from './a11y.js';
|
|
|
2
2
|
export * from './attachments.js';
|
|
3
3
|
export * from './chunks.js';
|
|
4
4
|
export * from './date.js';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './derived.js';
|
|
6
6
|
export * from './dom.js';
|
|
7
7
|
export * from './events.js';
|
|
8
8
|
export * from './options.js';
|
|
@@ -10,6 +10,5 @@ export * from './payload.js';
|
|
|
10
10
|
export * from './range.js';
|
|
11
11
|
export * from './resources.js';
|
|
12
12
|
export * from './slots.js';
|
|
13
|
-
export * from './stores.js';
|
|
14
13
|
export * from './utils.js';
|
|
15
14
|
export * from './view.js';
|