@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
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
3
|
import {
|
|
4
|
-
addDay, bgEvent, cloneDate, createEventChunk, datesEqual, eventIntersects, outsideRange,
|
|
5
|
-
sortEventChunks, toISOString
|
|
4
|
+
addDay, bgEvent, cloneDate, createEventChunk, datesEqual, eventIntersects, outsideRange, contentFrom, toISOString
|
|
6
5
|
} from '#lib';
|
|
6
|
+
import {BaseDay} from '#components';
|
|
7
7
|
import Event from './Event.svelte';
|
|
8
8
|
|
|
9
9
|
let {date} = $props();
|
|
10
10
|
|
|
11
|
-
let {_filteredEvents,
|
|
12
|
-
resources, eventOrder, filterEventsWithResources, highlightedDates, theme, validRange} = getContext('state');
|
|
11
|
+
let {_filteredEvents, _intlListDay, _intlListDaySide, highlightedDates, theme, validRange} = getContext('state');
|
|
13
12
|
|
|
14
|
-
let el = $state();
|
|
15
|
-
let isToday = $derived(datesEqual(date, $_today));
|
|
16
13
|
let highlight = $derived($highlightedDates.some(d => datesEqual(d, date)));
|
|
17
14
|
let disabled = $derived(outsideRange(date, $validRange));
|
|
18
15
|
let datetime = $derived(toISOString(date, 10));
|
|
@@ -23,38 +20,25 @@
|
|
|
23
20
|
let start = date;
|
|
24
21
|
let end = addDay(cloneDate(date));
|
|
25
22
|
for (let event of $_filteredEvents) {
|
|
26
|
-
if (!bgEvent(event.display) && eventIntersects(event, start, end
|
|
23
|
+
if (!bgEvent(event.display) && eventIntersects(event, start, end)) {
|
|
27
24
|
let chunk = createEventChunk(event, start, end);
|
|
28
25
|
chunks.push(chunk);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
sortEventChunks(chunks, $eventOrder);
|
|
32
28
|
}
|
|
33
29
|
return chunks;
|
|
34
30
|
});
|
|
35
|
-
|
|
36
|
-
// dateFromPoint
|
|
37
|
-
$effect(() => {
|
|
38
|
-
if (el) {
|
|
39
|
-
setPayload(el, () => ({allDay: true, date, resource: undefined, dayEl: el, disabled}));
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
31
|
</script>
|
|
43
32
|
|
|
44
33
|
{#if chunks.length}
|
|
45
|
-
<
|
|
46
|
-
bind:this={el}
|
|
47
|
-
class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{isToday ? ' ' + $theme.today : ''}{highlight ? ' ' + $theme.highlight : ''}"
|
|
48
|
-
role="listitem"
|
|
49
|
-
onpointerdown={$_interaction.action?.select}
|
|
50
|
-
>
|
|
34
|
+
<BaseDay {date} allDay role="listitem" {disabled} {highlight}>
|
|
51
35
|
<!-- svelte-ignore a11y_missing_content -->
|
|
52
36
|
<h4 class="{$theme.dayHead}">
|
|
53
|
-
<time {datetime}
|
|
54
|
-
<time class="{$theme.daySide}" {datetime}
|
|
37
|
+
<time {datetime} {@attach contentFrom($_intlListDay.format(date))}></time>
|
|
38
|
+
<time class="{$theme.daySide}" {datetime} {@attach contentFrom($_intlListDaySide.format(date))}></time>
|
|
55
39
|
</h4>
|
|
56
40
|
{#each chunks as chunk (chunk.event)}
|
|
57
41
|
<Event {chunk}/>
|
|
58
42
|
{/each}
|
|
59
|
-
</
|
|
43
|
+
</BaseDay>
|
|
60
44
|
{/if}
|
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
2
|
+
import {getContext} from 'svelte';
|
|
3
|
+
import {addDay, cloneDate, toViewWithLocalDates, contentFrom, bgEvent, isFunction} from '#lib';
|
|
4
|
+
import Day from './Day.svelte';
|
|
5
|
+
|
|
6
|
+
let {_mainEl, _filteredEvents, _view, _viewDates, noEventsClick, noEventsContent, theme} = getContext('state');
|
|
7
|
+
|
|
8
|
+
let noEvents = $derived.by(() => {
|
|
9
|
+
let noEvents = true;
|
|
10
|
+
if ($_viewDates.length) {
|
|
11
|
+
let start = $_viewDates[0];
|
|
12
|
+
let end = addDay(cloneDate($_viewDates.at(-1)));
|
|
13
|
+
for (let event of $_filteredEvents) {
|
|
14
|
+
if (!bgEvent(event.display) && event.start < end && event.end > start) {
|
|
15
|
+
noEvents = false;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return noEvents;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
let content = $derived(isFunction($noEventsContent) ? $noEventsContent() : $noEventsContent);
|
|
24
|
+
|
|
25
|
+
function onclick(jsEvent) {
|
|
26
|
+
if (isFunction($noEventsClick)) {
|
|
27
|
+
$noEventsClick({jsEvent, view: toViewWithLocalDates($_view)});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
3
30
|
</script>
|
|
4
31
|
|
|
5
|
-
<
|
|
32
|
+
<section bind:this={$_mainEl} class="{$theme.main}">
|
|
33
|
+
{#if noEvents}
|
|
34
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
35
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
36
|
+
<div {@attach contentFrom(content)} class="{$theme.noEvents}" {onclick}></div>
|
|
37
|
+
{:else}
|
|
38
|
+
{#each $_viewDates as date}
|
|
39
|
+
<Day {date}/>
|
|
40
|
+
{/each}
|
|
41
|
+
{/if}
|
|
42
|
+
</section>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext, onMount, untrack} from 'svelte';
|
|
3
|
-
import {
|
|
3
|
+
import {contentFrom, toLocalDate, isFunction} from '#lib';
|
|
4
4
|
|
|
5
5
|
let {resource, date = undefined, setLabel = undefined} = $props();
|
|
6
6
|
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
<span
|
|
49
49
|
bind:this={el}
|
|
50
50
|
aria-label="{ariaLabel}"
|
|
51
|
-
|
|
51
|
+
{@attach contentFrom(content)}
|
|
52
52
|
></span>
|
|
@@ -1,95 +1,51 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {createGrid} from './lib.js';
|
|
4
|
+
import {ColHead, DayHeader} from '#components';
|
|
5
5
|
import Label from './Label.svelte';
|
|
6
|
+
import View from '../time-grid/View.svelte';
|
|
6
7
|
|
|
7
|
-
let {
|
|
8
|
-
datesAboveResources, _today, _viewDates, _viewResources, _intlDayHeader, _intlDayHeaderAL, allDaySlot, theme
|
|
9
|
-
} = getContext('state');
|
|
10
|
-
|
|
11
|
-
let loops = $derived($datesAboveResources ? [$_viewDates, $_viewResources] : [$_viewResources, $_viewDates]);
|
|
8
|
+
let {_viewDates, _viewResources, _slotTimeLimits, datesAboveResources, highlightedDates, validRange, theme} = getContext('state');
|
|
12
9
|
|
|
13
10
|
let resourceLabels = $state([]);
|
|
14
11
|
</script>
|
|
15
12
|
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
<View
|
|
14
|
+
createGridFn={() => createGrid(
|
|
15
|
+
$_viewDates, $_viewResources, $_slotTimeLimits, $datesAboveResources, $validRange, $highlightedDates
|
|
16
|
+
)}
|
|
17
|
+
fullwidthNowIndicator={$datesAboveResources}
|
|
18
|
+
>
|
|
19
|
+
{#snippet header(grid)}
|
|
20
|
+
{#each grid as days, i}
|
|
21
|
+
{@const {dayStart: date, resource, disabled, highlight} = days[0]}
|
|
22
|
+
<ColHead
|
|
23
|
+
{date}
|
|
24
|
+
className={$theme.colGroup}
|
|
25
|
+
weekday={$datesAboveResources}
|
|
26
|
+
colSpan={days.length}
|
|
27
|
+
colIndex={1 + i * days.length}
|
|
28
|
+
disabled={$datesAboveResources && disabled}
|
|
29
|
+
highlight={$datesAboveResources && highlight}
|
|
30
|
+
>
|
|
20
31
|
{#if $datesAboveResources}
|
|
21
|
-
<
|
|
22
|
-
<time
|
|
23
|
-
datetime="{toISOString(item0, 10)}"
|
|
24
|
-
aria-label="{$_intlDayHeaderAL.format(item0)}"
|
|
25
|
-
use:setContent={$_intlDayHeader.format(item0)}
|
|
26
|
-
></time>
|
|
27
|
-
</div>
|
|
32
|
+
<DayHeader {date}/>
|
|
28
33
|
{:else}
|
|
29
|
-
<
|
|
30
|
-
<Label resource={item0} setLabel={e => resourceLabels[i] = e.detail + ', '} />
|
|
31
|
-
</div>
|
|
32
|
-
{/if}
|
|
33
|
-
{#if loops[1].length > 1}
|
|
34
|
-
<div class="{$theme.days}">
|
|
35
|
-
{#each loops[1] as item1}
|
|
36
|
-
{#if $datesAboveResources}
|
|
37
|
-
<div class="{$theme.day}" role="columnheader">
|
|
38
|
-
<Label resource={item1} date={item0} />
|
|
39
|
-
</div>
|
|
40
|
-
{:else}
|
|
41
|
-
<div
|
|
42
|
-
class="{$theme.day} {$theme.weekdays?.[item1.getUTCDay()]}{datesEqual(item1, $_today) ? ' ' + $theme.today : ''}"
|
|
43
|
-
role="columnheader"
|
|
44
|
-
>
|
|
45
|
-
<time
|
|
46
|
-
datetime="{toISOString(item1, 10)}"
|
|
47
|
-
aria-label="{resourceLabels[i]}{$_intlDayHeaderAL.format(item1)}"
|
|
48
|
-
use:setContent={$_intlDayHeader.format(item1)}
|
|
49
|
-
></time>
|
|
50
|
-
</div>
|
|
51
|
-
{/if}
|
|
52
|
-
{/each}
|
|
53
|
-
</div>
|
|
34
|
+
<Label {resource} setLabel={label => resourceLabels[i] = label + ', '}/>
|
|
54
35
|
{/if}
|
|
55
|
-
</
|
|
36
|
+
</ColHead>
|
|
56
37
|
{/each}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<Week dates={[date]} {resource}/>
|
|
69
|
-
{/each}
|
|
70
|
-
</div>
|
|
71
|
-
{/each}
|
|
72
|
-
{:else}
|
|
73
|
-
{#each $_viewResources as resource}
|
|
74
|
-
<div class="{$theme.resource}">
|
|
75
|
-
<Week dates={$_viewDates} {resource}/>
|
|
76
|
-
</div>
|
|
77
|
-
{/each}
|
|
78
|
-
{/if}
|
|
79
|
-
</Section>
|
|
80
|
-
<div class="{$theme.hiddenScroll}"></div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
{/if}
|
|
84
|
-
<Body>
|
|
85
|
-
{#each loops[0] as item0}
|
|
86
|
-
<div class="{$theme.resource}">
|
|
87
|
-
{#each loops[1] as item1}
|
|
88
|
-
<Day
|
|
89
|
-
date={$datesAboveResources ? item0 : item1}
|
|
90
|
-
resource={$datesAboveResources ? item1 : item0}
|
|
91
|
-
/>
|
|
38
|
+
{#each grid as days, i}
|
|
39
|
+
{#each days as day, j}
|
|
40
|
+
{@const {dayStart: date, resource, disabled, highlight} = day}
|
|
41
|
+
<ColHead {date} colIndex={1 + j + i * days.length} {disabled} {highlight}>
|
|
42
|
+
{#if $datesAboveResources}
|
|
43
|
+
<Label {resource} {date}/>
|
|
44
|
+
{:else}
|
|
45
|
+
<DayHeader {date} alPrefix={resourceLabels[i]}/>
|
|
46
|
+
{/if}
|
|
47
|
+
</ColHead>
|
|
48
|
+
{/each}
|
|
92
49
|
{/each}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
</Body>
|
|
50
|
+
{/snippet}
|
|
51
|
+
</View>
|
|
@@ -1,34 +1,42 @@
|
|
|
1
|
-
import {btnTextDay, btnTextWeek, themeView
|
|
2
|
-
import
|
|
1
|
+
import {btnTextDay, btnTextWeek, themeView} from '#lib';
|
|
2
|
+
import {createTROptions, createTRROptions, createTRRParsers} from '../time-grid/options.js';
|
|
3
|
+
import {createTRRStores, createTRStores} from '../time-grid/stores.js';
|
|
4
|
+
import {createRROptions} from './options.js';
|
|
5
|
+
import {createRRStores} from './stores.js';
|
|
3
6
|
import View from './View.svelte';
|
|
4
7
|
|
|
5
8
|
export default {
|
|
6
9
|
createOptions(options) {
|
|
10
|
+
createTROptions(options);
|
|
11
|
+
createTRROptions(options);
|
|
12
|
+
createRROptions(options);
|
|
7
13
|
options.datesAboveResources = false;
|
|
8
14
|
// Common options
|
|
9
15
|
options.buttonText.resourceTimeGridDay = 'resources';
|
|
10
16
|
options.buttonText.resourceTimeGridWeek = 'resources';
|
|
17
|
+
options.theme.colGroup = 'ec-col-group';
|
|
11
18
|
options.view = 'resourceTimeGridWeek';
|
|
12
19
|
options.views.resourceTimeGridDay = {
|
|
13
20
|
buttonText: btnTextDay,
|
|
14
21
|
component: View,
|
|
15
22
|
duration: {days: 1},
|
|
16
|
-
theme: themeView('ec-time-grid ec-
|
|
23
|
+
theme: themeView('ec-resource ec-time-grid ec-day-view')
|
|
17
24
|
};
|
|
18
25
|
options.views.resourceTimeGridWeek = {
|
|
19
26
|
buttonText: btnTextWeek,
|
|
20
27
|
component: View,
|
|
21
28
|
duration: {weeks: 1},
|
|
22
|
-
theme: themeView('ec-time-grid ec-
|
|
29
|
+
theme: themeView('ec-resource ec-time-grid ec-week-view')
|
|
23
30
|
};
|
|
24
31
|
},
|
|
25
32
|
|
|
33
|
+
createParsers(parsers) {
|
|
34
|
+
createTRRParsers(parsers);
|
|
35
|
+
},
|
|
36
|
+
|
|
26
37
|
createStores(state) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!('_viewResources' in state)) {
|
|
31
|
-
state._viewResources = viewResources(state);
|
|
32
|
-
}
|
|
38
|
+
createTRRStores(state);
|
|
39
|
+
createTRStores(state);
|
|
40
|
+
createRRStores(state);
|
|
33
41
|
}
|
|
34
42
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addDay, addDuration, cloneDate, datesEqual, outsideRange
|
|
3
|
+
} from '#lib';
|
|
4
|
+
|
|
5
|
+
export function createGrid($_viewDates, $_viewResources, $_slotTimeLimits, $datesAboveResources, $validRange, $highlightedDates) {
|
|
6
|
+
let grid = [];
|
|
7
|
+
let gridColumn = 1;
|
|
8
|
+
let loop = $datesAboveResources ? [$_viewDates, $_viewResources] : [$_viewResources, $_viewDates];
|
|
9
|
+
for (let item0 of loop[0]) {
|
|
10
|
+
let days = [];
|
|
11
|
+
for (let item1 of loop[1]) {
|
|
12
|
+
let date = $datesAboveResources ? item0 : item1;
|
|
13
|
+
let resource = $datesAboveResources ? item1 : item0;
|
|
14
|
+
days.push({
|
|
15
|
+
gridColumn,
|
|
16
|
+
gridRow: 1,
|
|
17
|
+
resource,
|
|
18
|
+
start: addDuration(cloneDate(date), $_slotTimeLimits.min),
|
|
19
|
+
end: addDuration(cloneDate(date), $_slotTimeLimits.max),
|
|
20
|
+
dayStart: date,
|
|
21
|
+
dayEnd: addDay(cloneDate(date)),
|
|
22
|
+
disabled: outsideRange(date, $validRange),
|
|
23
|
+
highlight: $highlightedDates.some(d => datesEqual(d, date))
|
|
24
|
+
});
|
|
25
|
+
++ gridColumn;
|
|
26
|
+
}
|
|
27
|
+
grid.push(days);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return grid;
|
|
31
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResourceTimeGrid + ResourceTimeline
|
|
3
|
+
*/
|
|
4
|
+
export function createRROptions(options) {
|
|
5
|
+
if (!('resourceLabelContent' in options)) {
|
|
6
|
+
options.filterResourcesWithEvents = false;
|
|
7
|
+
options.resourceLabelContent = undefined;
|
|
8
|
+
options.resourceLabelDidMount = undefined;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {derived} from 'svelte/store';
|
|
2
|
+
import {createResources, eventIntersects, getPayload} from '#lib';
|
|
3
|
+
|
|
4
|
+
function viewResources(state) {
|
|
5
|
+
return derived(
|
|
6
|
+
[state.resources, state.filterResourcesWithEvents, state._filteredEvents, state._activeRange],
|
|
7
|
+
([$resources, $filterResourcesWithEvents, $_filteredEvents, $_activeRange]) => {
|
|
8
|
+
let result = $resources.filter(resource => !getPayload(resource).hidden);
|
|
9
|
+
|
|
10
|
+
if ($filterResourcesWithEvents) {
|
|
11
|
+
result = $resources.filter(
|
|
12
|
+
resource => $_filteredEvents.some(
|
|
13
|
+
event => eventIntersects(event, $_activeRange.start, $_activeRange.end, resource)
|
|
14
|
+
)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!result.length) {
|
|
19
|
+
result = createResources([{}]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* ResourceTimeGrid + ResourceTimeline
|
|
29
|
+
*/
|
|
30
|
+
export function createRRStores(state) {
|
|
31
|
+
if (!('_viewResources' in state)) {
|
|
32
|
+
state._viewResources = viewResources(state);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,84 +1,21 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
} from '#lib';
|
|
6
|
-
import {getSlotTimeLimits} from './lib.js';
|
|
7
|
-
import Event from './Event.svelte';
|
|
3
|
+
import {addDuration, cloneDate, floor, rect} from '#lib';
|
|
4
|
+
import {BaseDay} from '#components';
|
|
8
5
|
|
|
9
|
-
let {
|
|
6
|
+
let {day} = $props();
|
|
10
7
|
|
|
11
|
-
let {
|
|
12
|
-
highlightedDates, slotDuration, slotWidth, theme, validRange, _interaction, _today, _dayTimeLimits
|
|
13
|
-
} = getContext('state');
|
|
8
|
+
let {_monthView, slotDuration, slotWidth} = getContext('state');
|
|
14
9
|
|
|
15
|
-
let
|
|
16
|
-
let refs = [];
|
|
17
|
-
|
|
18
|
-
let isToday = $derived(datesEqual(date, $_today));
|
|
19
|
-
let highlight = $derived($highlightedDates.some(d => datesEqual(d, date)));
|
|
20
|
-
let disabled = $derived(outsideRange(date, $validRange));
|
|
21
|
-
|
|
22
|
-
let slotTimeLimits = $derived(getSlotTimeLimits($_dayTimeLimits, date));
|
|
23
|
-
let allDay = $derived(!toSeconds($slotDuration));
|
|
24
|
-
let pointerIdx = $derived(allDay ? 2 : 1);
|
|
25
|
-
|
|
26
|
-
let dayChunks = $derived(chunks.filter(chunkIntersects));
|
|
27
|
-
let dayBgChunks = $derived(bgChunks.filter(bgChunk => (!allDay || bgChunk.event.allDay) && chunkIntersects(bgChunk)));
|
|
10
|
+
let {dayStart: date, start, resource, disabled, highlight} = $derived(day);
|
|
28
11
|
|
|
29
|
-
|
|
30
|
-
return datesEqual(chunk.date, date);
|
|
31
|
-
}
|
|
12
|
+
let el = $state();
|
|
32
13
|
|
|
33
14
|
function dateFromPoint(x, y) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
date: allDay
|
|
38
|
-
? cloneDate(date)
|
|
39
|
-
: addDuration(
|
|
40
|
-
addDuration(cloneDate(date), slotTimeLimits.min),
|
|
41
|
-
$slotDuration,
|
|
42
|
-
floor(x / $slotWidth)
|
|
43
|
-
),
|
|
44
|
-
resource,
|
|
45
|
-
dayEl: el,
|
|
46
|
-
disabled
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
$effect(() => {
|
|
50
|
-
setPayload(el, dateFromPoint);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export function reposition() {
|
|
54
|
-
return max(...runReposition(refs, dayChunks));
|
|
15
|
+
return $_monthView
|
|
16
|
+
? date
|
|
17
|
+
: addDuration(cloneDate(start), $slotDuration, floor((x - rect(el).left)/ $slotWidth));
|
|
55
18
|
}
|
|
56
19
|
</script>
|
|
57
20
|
|
|
58
|
-
<
|
|
59
|
-
bind:this={el}
|
|
60
|
-
class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{isToday ? ' ' + $theme.today : ''}{highlight ? ' ' + $theme.highlight : ''}{disabled ? ' ' + $theme.disabled : ''}"
|
|
61
|
-
style="flex-grow: {allDay ? null : ceil((toSeconds(slotTimeLimits.max) - toSeconds(slotTimeLimits.min)) / toSeconds($slotDuration))}"
|
|
62
|
-
role="cell"
|
|
63
|
-
onpointerdown={$_interaction.action?.select}
|
|
64
|
-
>
|
|
65
|
-
<div class="{$theme.events}">
|
|
66
|
-
{#if !disabled}
|
|
67
|
-
{#each dayBgChunks as chunk (chunk.event)}
|
|
68
|
-
<Event {chunk}/>
|
|
69
|
-
{/each}
|
|
70
|
-
<!-- Pointer -->
|
|
71
|
-
{#if iChunks[pointerIdx] && chunkIntersects(iChunks[pointerIdx])}
|
|
72
|
-
<Event chunk={iChunks[pointerIdx]}/>
|
|
73
|
-
{/if}
|
|
74
|
-
{#each dayChunks as chunk, i (chunk.event)}
|
|
75
|
-
<!-- svelte-ignore binding_property_non_reactive -->
|
|
76
|
-
<Event {chunk} {dayChunks} {longChunks} {resource} bind:this={refs[i]}/>
|
|
77
|
-
{/each}
|
|
78
|
-
<!-- Drag, Resize & Select -->
|
|
79
|
-
{#if iChunks[0] && chunkIntersects(iChunks[0])}
|
|
80
|
-
<Event chunk={iChunks[0]} {resource}/>
|
|
81
|
-
{/if}
|
|
82
|
-
{/if}
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
21
|
+
<BaseDay bind:el allDay={$_monthView} {date} {resource} {dateFromPoint} {disabled} {highlight}/>
|
|
@@ -4,46 +4,37 @@
|
|
|
4
4
|
import {repositionEvent} from './lib.js';
|
|
5
5
|
import {InteractableEvent} from '#components';
|
|
6
6
|
|
|
7
|
-
let {chunk
|
|
7
|
+
let {chunk} = $props();
|
|
8
8
|
|
|
9
|
-
let {slotDuration, slotWidth} = getContext('state');
|
|
9
|
+
let {slotDuration, slotWidth, _monthView} = getContext('state');
|
|
10
10
|
|
|
11
11
|
let el = $state();
|
|
12
|
-
let margin = $state(
|
|
12
|
+
let margin = $state(1);
|
|
13
13
|
let event = $derived(chunk.event);
|
|
14
14
|
// Style
|
|
15
|
-
let width = $derived('slots' in chunk ? chunk.slots * $slotWidth : chunk.days * 100);
|
|
16
15
|
let styles = $derived(style => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
style['width'] = `${width}%`;
|
|
16
|
+
style['grid-column'] = `${chunk.gridColumn} / span ${chunk.dates.length}`;
|
|
17
|
+
style['grid-row'] = chunk.gridRow;
|
|
18
|
+
if (!$_monthView) {
|
|
19
|
+
let left = chunk.left / toSeconds($slotDuration) * $slotWidth;
|
|
20
|
+
style['inset-inline-start'] = `${left}px`;
|
|
21
|
+
style['inline-size'] = `${chunk.width / toSeconds($slotDuration) * $slotWidth + chunk.dates.length - 1}px`;
|
|
24
22
|
}
|
|
25
23
|
let marginTop = margin;
|
|
26
24
|
if (event._margin) {
|
|
27
25
|
// Force margin for helper events
|
|
28
|
-
let [_margin,
|
|
29
|
-
if (
|
|
26
|
+
let [_margin, _gridRow] = event._margin;
|
|
27
|
+
if (chunk.gridRow === _gridRow) {
|
|
30
28
|
marginTop = _margin;
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
|
-
style['margin-
|
|
31
|
+
style['margin-block-start'] = `${marginTop}px`;
|
|
34
32
|
return style;
|
|
35
33
|
});
|
|
36
34
|
|
|
37
35
|
export function reposition() {
|
|
38
|
-
|
|
39
|
-
return 0;
|
|
40
|
-
}
|
|
41
|
-
let h = height(el);
|
|
42
|
-
margin = repositionEvent(chunk, dayChunks, longChunks, h, !toSeconds($slotDuration));
|
|
43
|
-
return margin + h;
|
|
36
|
+
margin = repositionEvent(chunk, height(el), $_monthView);
|
|
44
37
|
}
|
|
45
38
|
</script>
|
|
46
39
|
|
|
47
|
-
{
|
|
48
|
-
<InteractableEvent bind:el {chunk} {styles} axis="x" forceMargin={() => [margin, resource]} />
|
|
49
|
-
{/if}
|
|
40
|
+
<InteractableEvent bind:el {chunk} {styles} axis="x" forceMargin={[margin, chunk.gridRow]} />
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import {getContext} from 'svelte';
|
|
3
|
-
import {datesEqual,
|
|
3
|
+
import {datesEqual, contentFrom, toISOString, toSeconds, resizeObserver} from '#lib';
|
|
4
4
|
|
|
5
5
|
let {_headerEl, _headerHeight, _intlDayHeader, _intlDayHeaderAL, _dayTimes, _today, _viewDates,
|
|
6
6
|
slotDuration, theme} = getContext('state');
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
|
-
<div class="{$theme.header}" bind:this={$_headerEl}
|
|
9
|
+
<div class="{$theme.header}" bind:this={$_headerEl} {@attach resizeObserver(() => $_headerHeight = $_headerEl.clientHeight)}>
|
|
10
10
|
<div class="{$theme.days}" role="row">
|
|
11
11
|
{#each $_viewDates as date}
|
|
12
12
|
<div class="{$theme.day} {$theme.weekdays?.[date.getUTCDay()]}{datesEqual(date, $_today) ? ' ' + $theme.today : ''}">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<time
|
|
16
16
|
datetime="{toISOString(date, 10)}"
|
|
17
17
|
aria-label="{$_intlDayHeaderAL.format(date)}"
|
|
18
|
-
|
|
18
|
+
{@attach contentFrom($_intlDayHeader.format(date))}
|
|
19
19
|
></time>
|
|
20
20
|
</div>
|
|
21
21
|
<div class="{$theme.times}">
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<div class="{$theme.time}{time[2] ? '' : ' ' + $theme.minor}" role="columnheader">
|
|
24
24
|
<time
|
|
25
25
|
datetime="{time[0]}"
|
|
26
|
-
|
|
26
|
+
{@attach contentFrom(time[1])}
|
|
27
27
|
></time>
|
|
28
28
|
</div>
|
|
29
29
|
{/each}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<time
|
|
34
34
|
datetime="{toISOString(date, 10)}"
|
|
35
35
|
aria-label="{$_intlDayHeaderAL.format(date)}"
|
|
36
|
-
|
|
36
|
+
{@attach contentFrom($_intlDayHeader.format(date))}
|
|
37
37
|
></time>
|
|
38
38
|
</div>
|
|
39
39
|
{/if}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {getContext, onMount
|
|
3
|
-
import {
|
|
2
|
+
import {getContext, onMount} from 'svelte';
|
|
3
|
+
import {contentFrom, toLocalDate, isFunction} from '#lib';
|
|
4
4
|
|
|
5
5
|
let {resource, date = undefined} = $props();
|
|
6
6
|
|
|
7
|
-
let {resourceLabelContent, resourceLabelDidMount
|
|
7
|
+
let {resourceLabelContent, resourceLabelDidMount} = getContext('state');
|
|
8
8
|
|
|
9
9
|
let el = $state();
|
|
10
10
|
// Content
|
|
@@ -21,14 +21,6 @@
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
$effect(() => {
|
|
25
|
-
content;
|
|
26
|
-
untrack(() => {
|
|
27
|
-
$_resHs.set(resource, ceil(height(el) + 10));
|
|
28
|
-
$_resHs = $_resHs;
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
24
|
onMount(() => {
|
|
33
25
|
if (isFunction($resourceLabelDidMount)) {
|
|
34
26
|
$resourceLabelDidMount({
|
|
@@ -42,5 +34,5 @@
|
|
|
42
34
|
|
|
43
35
|
<span
|
|
44
36
|
bind:this={el}
|
|
45
|
-
|
|
37
|
+
{@attach contentFrom(content)}
|
|
46
38
|
></span>
|