@event-calendar/core 5.4.2 → 5.5.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 +55 -17
- package/dist/index.css +4 -3
- package/dist/index.js +5440 -5647
- package/package.json +2 -2
- package/src/lib/components/ColHead.svelte +2 -0
- package/src/lib/date.js +11 -1
- package/src/plugins/day-grid/Day.svelte +5 -15
- package/src/plugins/day-grid/index.js +1 -2
- package/src/plugins/list/index.js +10 -7
- package/src/plugins/resource-time-grid/index.js +2 -2
- package/src/plugins/resource-timeline/View.svelte +27 -4
- package/src/plugins/resource-timeline/derived.js +41 -2
- package/src/plugins/resource-timeline/index.js +29 -8
- package/src/plugins/resource-timeline/state.svelte.js +6 -1
- package/src/storage/derived.js +4 -1
- package/src/storage/options.js +1 -0
- package/src/storage/state.svelte.js +3 -3
- package/src/styles/days.css +1 -1
- package/src/styles/index.css +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event-calendar/core",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.1",
|
|
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.54.0"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
ariaHidden = false,
|
|
12
12
|
disabled = false,
|
|
13
13
|
highlight = false,
|
|
14
|
+
cssSpan = false,
|
|
14
15
|
children
|
|
15
16
|
} = $props();
|
|
16
17
|
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
highlight && theme.highlight,
|
|
26
27
|
disabled && theme.disabled
|
|
27
28
|
]}
|
|
29
|
+
style:--ec-col-group-span={cssSpan ? colSpan : undefined}
|
|
28
30
|
role="{ariaHidden ? null : 'columnheader'}"
|
|
29
31
|
aria-colspan="{ariaHidden || colSpan <= 1 ? null : colSpan}"
|
|
30
32
|
aria-colindex="{ariaHidden ? null : colIndex}"
|
package/src/lib/date.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {isDate} from './utils.js';
|
|
1
|
+
import {isDate, isFunction} from './utils.js';
|
|
2
2
|
|
|
3
3
|
export const DAY_IN_SECONDS = 86400;
|
|
4
4
|
|
|
@@ -182,6 +182,16 @@ export function getWeekNumber(date, firstDay) {
|
|
|
182
182
|
return Math.ceil((((date - yearStart) / 1000 / DAY_IN_SECONDS) + 1) / 7);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
export function createWeekNumberContent(week, weekNumberContent, date) {
|
|
186
|
+
if (weekNumberContent) {
|
|
187
|
+
return isFunction(weekNumberContent)
|
|
188
|
+
? weekNumberContent({date: toLocalDate(date), week})
|
|
189
|
+
: weekNumberContent;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return 'W' + String(week).padStart(2, '0');
|
|
193
|
+
}
|
|
194
|
+
|
|
185
195
|
/**
|
|
186
196
|
* Private functions
|
|
187
197
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
3
|
import {
|
|
4
|
-
contentFrom, getWeekNumber, isFunction, keyEnter, toISOString,
|
|
4
|
+
contentFrom, getWeekNumber, isFunction, keyEnter, toISOString, stopPropagation, createWeekNumberContent
|
|
5
5
|
} from '#lib';
|
|
6
6
|
import {BaseDay} from '#components';
|
|
7
7
|
|
|
@@ -19,20 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
// Week numbers
|
|
21
21
|
let showWeekNumber = $derived(weekNumbers && dayStart.getUTCDay() === (firstDay ? 1 : 0));
|
|
22
|
-
let weekNumber = $derived
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (weekNumberContent) {
|
|
27
|
-
weekNumber = isFunction(weekNumberContent)
|
|
28
|
-
? weekNumberContent({date: toLocalDate(dayStart), week})
|
|
29
|
-
: weekNumberContent;
|
|
30
|
-
} else {
|
|
31
|
-
weekNumber = 'W' + String(week).padStart(2, '0');
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return weekNumber;
|
|
35
|
-
});
|
|
22
|
+
let weekNumber = $derived(showWeekNumber
|
|
23
|
+
? createWeekNumberContent(getWeekNumber(dayStart, firstDay), weekNumberContent, dayStart)
|
|
24
|
+
: undefined
|
|
25
|
+
);
|
|
36
26
|
|
|
37
27
|
// More link
|
|
38
28
|
let dayHiddenChunks = $derived(hiddenChunks.get(dayStart.getTime()));
|
|
@@ -12,10 +12,10 @@ export default {
|
|
|
12
12
|
view: 'listWeek'
|
|
13
13
|
});
|
|
14
14
|
assign(options.buttonText, {
|
|
15
|
-
listDay: '
|
|
16
|
-
listWeek: '
|
|
17
|
-
listMonth: '
|
|
18
|
-
listYear: '
|
|
15
|
+
listDay: 'day',
|
|
16
|
+
listWeek: 'week',
|
|
17
|
+
listMonth: 'month',
|
|
18
|
+
listYear: 'year'
|
|
19
19
|
});
|
|
20
20
|
assign(options.theme, {
|
|
21
21
|
daySide: 'ec-day-side',
|
|
@@ -27,7 +27,8 @@ export default {
|
|
|
27
27
|
buttonText: btnTextDay,
|
|
28
28
|
component: initViewComponent,
|
|
29
29
|
duration: {days: 1},
|
|
30
|
-
theme: themeView('ec-list ec-day-view')
|
|
30
|
+
theme: themeView('ec-list ec-day-view'),
|
|
31
|
+
titleFormat: {year: 'numeric', month: 'long', day: 'numeric'}
|
|
31
32
|
},
|
|
32
33
|
listWeek: {
|
|
33
34
|
buttonText: btnTextWeek,
|
|
@@ -39,13 +40,15 @@ export default {
|
|
|
39
40
|
buttonText: btnTextMonth,
|
|
40
41
|
component: initViewComponent,
|
|
41
42
|
duration: {months: 1},
|
|
42
|
-
theme: themeView('ec-list ec-month-view')
|
|
43
|
+
theme: themeView('ec-list ec-month-view'),
|
|
44
|
+
titleFormat: {year: 'numeric', month: 'long'}
|
|
43
45
|
},
|
|
44
46
|
listYear: {
|
|
45
47
|
buttonText: btnTextYear,
|
|
46
48
|
component: initViewComponent,
|
|
47
49
|
duration: {years: 1},
|
|
48
|
-
theme: themeView('ec-list ec-year-view')
|
|
50
|
+
theme: themeView('ec-list ec-year-view'),
|
|
51
|
+
titleFormat: {year: 'numeric'}
|
|
49
52
|
}
|
|
50
53
|
});
|
|
51
54
|
}
|
|
@@ -15,8 +15,8 @@ export default {
|
|
|
15
15
|
view: 'resourceTimeGridWeek'
|
|
16
16
|
});
|
|
17
17
|
assign(options.buttonText, {
|
|
18
|
-
resourceTimeGridDay: '
|
|
19
|
-
resourceTimeGridWeek: '
|
|
18
|
+
resourceTimeGridDay: 'day',
|
|
19
|
+
resourceTimeGridWeek: 'week'
|
|
20
20
|
});
|
|
21
21
|
assign(options.theme, {
|
|
22
22
|
colGroup: 'ec-col-group'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext, setContext, tick} from 'svelte';
|
|
3
3
|
import {
|
|
4
|
-
max, resizeObserver, runReposition, contentFrom, toSeconds, datesEqual, min, isRtl, empty, length
|
|
4
|
+
max, resizeObserver, runReposition, contentFrom, toSeconds, datesEqual, min, isRtl, empty, length, toISOString,
|
|
5
|
+
createWeekNumberContent
|
|
5
6
|
} from '#lib';
|
|
6
7
|
import {getSlotTimeLimits} from './lib.js';
|
|
7
8
|
import ViewState from './state.svelte.js';
|
|
@@ -16,9 +17,11 @@
|
|
|
16
17
|
let viewState = new ViewState(mainState);
|
|
17
18
|
setContext('view-state', viewState);
|
|
18
19
|
|
|
19
|
-
let {mainEl, today, viewDates, options: {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
let {mainEl, today, viewDates, options: {
|
|
21
|
+
columnWidth, nowIndicator, scrollTime, slotDuration, slotHeight, slotWidth, theme, weekNumberContent
|
|
22
|
+
}} = $derived(mainState);
|
|
23
|
+
let {chunks, bgChunks, iChunks, daySlots, dayTimeLimits, grid, extraHeads, intlMonthHeader, monthView,
|
|
24
|
+
nestedResources, sidebarWidth, slotLabelPeriodicity, viewResources} = $derived(viewState);
|
|
22
25
|
|
|
23
26
|
let headerHeight = $state(0);
|
|
24
27
|
|
|
@@ -84,6 +87,26 @@
|
|
|
84
87
|
<header bind:offsetHeight={headerHeight} class="{theme.header}">
|
|
85
88
|
<aside class="{theme.sidebar}" bind:offsetWidth={viewState.sidebarWidth}></aside>
|
|
86
89
|
<div class="{theme.grid}" role="row">
|
|
90
|
+
{#if length(extraHeads.months) > 1}
|
|
91
|
+
{#each extraHeads.months as {date, gridColumn, span}}
|
|
92
|
+
<ColHead className={theme.colGroup} colIndex={gridColumn} colSpan={span} cssSpan weekday={false}>
|
|
93
|
+
<time
|
|
94
|
+
datetime="{toISOString(date, 10)}"
|
|
95
|
+
{@attach contentFrom(intlMonthHeader.format(date))}
|
|
96
|
+
></time>
|
|
97
|
+
</ColHead>
|
|
98
|
+
{/each}
|
|
99
|
+
{/if}
|
|
100
|
+
{#if length(extraHeads.weeks) > 1}
|
|
101
|
+
{#each extraHeads.weeks as {number, date, gridColumn, span}}
|
|
102
|
+
<ColHead className={theme.colGroup} colIndex={gridColumn} colSpan={span} cssSpan weekday={false}>
|
|
103
|
+
<span
|
|
104
|
+
class="{theme.weekNumber}"
|
|
105
|
+
{@attach contentFrom(createWeekNumberContent(number, weekNumberContent, date))}
|
|
106
|
+
></span>
|
|
107
|
+
</ColHead>
|
|
108
|
+
{/each}
|
|
109
|
+
{/if}
|
|
87
110
|
{#each grid[0] as {dayStart: date, disabled, highlight}, i}
|
|
88
111
|
<ColHead {date} colIndex={1 + i} {disabled} {highlight}>
|
|
89
112
|
<DayHeader {date}/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {untrack} from 'svelte';
|
|
2
2
|
import {
|
|
3
|
-
addDay, addDuration, bgEvent, cloneDate, createSlots, createSlotTimeLimits, datesEqual,
|
|
4
|
-
toSeconds
|
|
3
|
+
addDay, addDuration, bgEvent, cloneDate, createSlots, createSlotTimeLimits, datesEqual, empty, getPayload,
|
|
4
|
+
getWeekNumber, outsideRange, toSeconds
|
|
5
5
|
} from '#lib';
|
|
6
6
|
import {createChunks, prepareChunks} from './lib.js';
|
|
7
7
|
|
|
@@ -42,6 +42,45 @@ export function grid(mainState, viewState) {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function extraHeads(mainState, viewState) {
|
|
46
|
+
return () => {
|
|
47
|
+
// Dependencies
|
|
48
|
+
let {features, options: {firstDay, weekNumbers}} = mainState;
|
|
49
|
+
let {grid} = viewState;
|
|
50
|
+
|
|
51
|
+
let months = [];
|
|
52
|
+
let weeks = [];
|
|
53
|
+
|
|
54
|
+
untrack(() => {
|
|
55
|
+
let month;
|
|
56
|
+
let week;
|
|
57
|
+
if (!empty(grid)) {
|
|
58
|
+
for (let {dayStart, gridColumn} of grid[0]) {
|
|
59
|
+
if (features.includes('month')) {
|
|
60
|
+
if (month && month.date.getUTCMonth() === dayStart.getUTCMonth()) {
|
|
61
|
+
++month.span;
|
|
62
|
+
} else {
|
|
63
|
+
month = {date: dayStart, gridColumn, span: 1};
|
|
64
|
+
months.push(month);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (weekNumbers) {
|
|
68
|
+
let number = getWeekNumber(dayStart, firstDay);
|
|
69
|
+
if (week && week.number === number) {
|
|
70
|
+
++week.span;
|
|
71
|
+
} else {
|
|
72
|
+
week = {number, date: dayStart, gridColumn, span: 1};
|
|
73
|
+
weeks.push(week);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return {months, weeks};
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
45
84
|
export function eventChunks(mainState, viewState) {
|
|
46
85
|
return () => {
|
|
47
86
|
// Dependencies
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {assign, btnTextDay, btnTextMonth, btnTextWeek, getPayload, themeView} from '#lib';
|
|
1
|
+
import {assign, btnTextDay, btnTextMonth, btnTextWeek, btnTextYear, getPayload, themeView} from '#lib';
|
|
2
2
|
import {setExtensions} from '../time-grid/lib.js';
|
|
3
3
|
import {createTRROptions, createTRRParsers} from '../time-grid/options.js';
|
|
4
4
|
import {createRROptions} from '../resource-time-grid/options.js';
|
|
@@ -9,17 +9,21 @@ export default {
|
|
|
9
9
|
createTRROptions(options);
|
|
10
10
|
createRROptions(options);
|
|
11
11
|
assign(options, {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
monthHeaderFormat: { // ec option
|
|
13
|
+
month: 'long'
|
|
14
|
+
},
|
|
15
|
+
resourceExpand: undefined, // ec option
|
|
16
|
+
slotWidth: 32, // ec option
|
|
14
17
|
// Common options
|
|
15
18
|
view: 'resourceTimelineWeek'
|
|
16
19
|
});
|
|
17
20
|
assign(options.buttonText, {
|
|
18
21
|
expand: 'Expand',
|
|
19
22
|
collapse: 'Collapse',
|
|
20
|
-
resourceTimelineDay: '
|
|
21
|
-
resourceTimelineWeek: '
|
|
22
|
-
resourceTimelineMonth: '
|
|
23
|
+
resourceTimelineDay: 'day',
|
|
24
|
+
resourceTimelineWeek: 'week',
|
|
25
|
+
resourceTimelineMonth: 'month',
|
|
26
|
+
resourceTimelineYear: 'year'
|
|
23
27
|
});
|
|
24
28
|
assign(options.icons, {
|
|
25
29
|
collapse: {html: '−'},
|
|
@@ -59,6 +63,19 @@ export default {
|
|
|
59
63
|
slotDuration: {days: 1},
|
|
60
64
|
theme: themeView('ec-resource ec-timeline ec-month-view'),
|
|
61
65
|
titleFormat: {year: 'numeric', month: 'long'}
|
|
66
|
+
},
|
|
67
|
+
resourceTimelineYear: {
|
|
68
|
+
buttonText: btnTextYear,
|
|
69
|
+
component: initMonthViewComponent,
|
|
70
|
+
displayEventEnd: false,
|
|
71
|
+
dayHeaderFormat: {
|
|
72
|
+
weekday: 'short',
|
|
73
|
+
day: 'numeric'
|
|
74
|
+
},
|
|
75
|
+
duration: {years: 1},
|
|
76
|
+
slotDuration: {days: 1},
|
|
77
|
+
theme: themeView('ec-resource ec-timeline ec-year-view'),
|
|
78
|
+
titleFormat: {year: 'numeric'}
|
|
62
79
|
}
|
|
63
80
|
});
|
|
64
81
|
},
|
|
@@ -70,11 +87,15 @@ export default {
|
|
|
70
87
|
|
|
71
88
|
function initViewComponent(mainState) {
|
|
72
89
|
setExtensions(mainState);
|
|
73
|
-
return
|
|
90
|
+
return _initViewComponent(mainState);
|
|
74
91
|
}
|
|
75
92
|
|
|
76
93
|
function initMonthViewComponent(mainState) {
|
|
77
|
-
mainState
|
|
94
|
+
return _initViewComponent(mainState, ['month']);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function _initViewComponent(mainState, extraFeatures = []) {
|
|
98
|
+
mainState.features = ['timeline', ...extraFeatures];
|
|
78
99
|
mainState.extensions.viewResources = resources => resources.filter(resource => !getPayload(resource).hidden);
|
|
79
100
|
return View;
|
|
80
101
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {intl} from '#lib';
|
|
1
2
|
import {TRRState} from '../time-grid/state.svelte.js';
|
|
2
3
|
import {RRState} from '../resource-time-grid/state.svelte.js';
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
daySlots, dayTimeLimits, eventChunks, extraHeads, grid, iEventChunks, monthView, nestedResources
|
|
6
|
+
} from './derived.js';
|
|
4
7
|
|
|
5
8
|
export default class ViewState extends RRState(TRRState()) {
|
|
6
9
|
constructor(mainState) {
|
|
@@ -8,6 +11,8 @@ export default class ViewState extends RRState(TRRState()) {
|
|
|
8
11
|
this.dayTimeLimits = $derived.by(dayTimeLimits(mainState)); // flexible time limits per day
|
|
9
12
|
this.daySlots = $derived.by(daySlots(mainState, this));
|
|
10
13
|
this.grid = $derived.by(grid(mainState, this));
|
|
14
|
+
this.extraHeads = $derived.by(extraHeads(mainState, this));
|
|
15
|
+
this.intlMonthHeader = $derived.by(intl(mainState, 'monthHeaderFormat'));
|
|
11
16
|
this.monthView = $derived.by(monthView(mainState));
|
|
12
17
|
let {chunks, bgChunks} = $derived.by(eventChunks(mainState, this));
|
|
13
18
|
this.chunks = $derived(chunks);
|
package/src/storage/derived.js
CHANGED
|
@@ -13,7 +13,10 @@ export function currentRange(mainState) {
|
|
|
13
13
|
|
|
14
14
|
untrack(() => {
|
|
15
15
|
start = cloneDate(date);
|
|
16
|
-
if (duration.
|
|
16
|
+
if (duration.years) {
|
|
17
|
+
start.setUTCMonth(0);
|
|
18
|
+
start.setUTCDate(1);
|
|
19
|
+
} else if (duration.months) {
|
|
17
20
|
start.setUTCDate(1);
|
|
18
21
|
} else if (duration.inWeeks) {
|
|
19
22
|
// First day of week
|
package/src/storage/options.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {SvelteMap} from 'svelte/reactivity';
|
|
2
|
-
import {createDate, identity, intl, intlRange, setMidnight} from '#lib';
|
|
2
|
+
import {cloneDate, createDate, identity, intl, intlRange, isArray, setMidnight} from '#lib';
|
|
3
3
|
import {optionsState} from './options.js';
|
|
4
4
|
import {
|
|
5
5
|
createLoadingInvoker, loadEvents, loadResources, runDatesSet, runEventAllUpdated, runViewDidMount, setNowAndToday,
|
|
@@ -27,8 +27,8 @@ export default class State {
|
|
|
27
27
|
this.filteredEvents = $derived.by(filteredEvents(this));
|
|
28
28
|
this.mainEl = $state();
|
|
29
29
|
this.now = $state(createDate());
|
|
30
|
-
this.resources = $state.raw(arrayProxy(this.options.resources));
|
|
31
|
-
this.today = $state(setMidnight(
|
|
30
|
+
this.resources = $state.raw(arrayProxy(isArray(this.options.resources) ? this.options.resources : []));
|
|
31
|
+
this.today = $state(setMidnight(cloneDate(this.now)));
|
|
32
32
|
this.intlEventTime = $derived.by(intlRange(this, 'eventTimeFormat'));
|
|
33
33
|
this.intlDayHeader = $derived.by(intl(this, 'dayHeaderFormat'));
|
|
34
34
|
this.intlDayHeaderAL = $derived.by(intl(this, 'dayHeaderAriaLabelFormat'));
|
package/src/styles/days.css
CHANGED