@event-calendar/core 4.7.1 → 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.
Files changed (93) hide show
  1. package/README.md +29 -51
  2. package/dist/index.css +627 -731
  3. package/dist/index.js +2499 -3191
  4. package/package.json +2 -2
  5. package/src/Auxiliary.svelte +2 -13
  6. package/src/Buttons.svelte +62 -52
  7. package/src/Calendar.svelte +9 -3
  8. package/src/lib/a11y.js +2 -2
  9. package/src/lib/attachments.js +61 -0
  10. package/src/lib/chunks.js +117 -0
  11. package/src/lib/components/BaseDay.svelte +50 -0
  12. package/src/lib/components/BaseEvent.svelte +3 -3
  13. package/src/lib/components/ColHead.svelte +34 -0
  14. package/src/lib/components/DayHeader.svelte +14 -0
  15. package/src/lib/components/InteractableEvent.svelte +1 -3
  16. package/src/lib/components/index.js +3 -0
  17. package/src/lib/date.js +1 -1
  18. package/src/lib/dom.js +0 -4
  19. package/src/lib/events.js +10 -134
  20. package/src/lib/index.js +3 -2
  21. package/src/lib/{times.js → slots.js} +14 -19
  22. package/src/lib/stores.js +0 -33
  23. package/src/lib/utils.js +11 -2
  24. package/src/lib/view.js +0 -4
  25. package/src/plugins/day-grid/Day.svelte +36 -129
  26. package/src/plugins/day-grid/Event.svelte +42 -41
  27. package/src/plugins/day-grid/Popup.svelte +65 -48
  28. package/src/plugins/day-grid/View.svelte +76 -4
  29. package/src/plugins/day-grid/index.js +5 -5
  30. package/src/plugins/day-grid/lib.js +61 -0
  31. package/src/plugins/day-grid/stores.js +2 -20
  32. package/src/plugins/interaction/Action.svelte +37 -43
  33. package/src/plugins/interaction/Auxiliary.svelte +4 -4
  34. package/src/plugins/interaction/Pointer.svelte +8 -12
  35. package/src/plugins/interaction/Resizer.svelte +2 -2
  36. package/src/plugins/interaction/lib/utils.js +1 -5
  37. package/src/plugins/list/Day.svelte +8 -24
  38. package/src/plugins/list/View.svelte +39 -2
  39. package/src/plugins/resource-time-grid/Label.svelte +2 -2
  40. package/src/plugins/resource-time-grid/View.svelte +38 -82
  41. package/src/plugins/resource-time-grid/index.js +18 -10
  42. package/src/plugins/resource-time-grid/lib.js +31 -0
  43. package/src/plugins/resource-time-grid/options.js +10 -0
  44. package/src/plugins/resource-time-grid/stores.js +34 -0
  45. package/src/plugins/resource-timeline/Day.svelte +10 -73
  46. package/src/plugins/resource-timeline/Event.svelte +14 -23
  47. package/src/plugins/resource-timeline/Header.svelte +5 -5
  48. package/src/plugins/resource-timeline/Label.svelte +4 -12
  49. package/src/plugins/resource-timeline/NowIndicator.svelte +33 -28
  50. package/src/plugins/resource-timeline/View.svelte +129 -14
  51. package/src/plugins/resource-timeline/index.js +26 -23
  52. package/src/plugins/resource-timeline/lib.js +115 -118
  53. package/src/plugins/resource-timeline/stores.js +11 -7
  54. package/src/plugins/time-grid/AllDayEvent.svelte +31 -0
  55. package/src/plugins/time-grid/Day.svelte +11 -99
  56. package/src/plugins/time-grid/Event.svelte +18 -20
  57. package/src/plugins/time-grid/NowIndicator.svelte +32 -10
  58. package/src/plugins/time-grid/View.svelte +127 -35
  59. package/src/plugins/time-grid/index.js +10 -8
  60. package/src/plugins/time-grid/lib.js +142 -0
  61. package/src/plugins/time-grid/options.js +57 -0
  62. package/src/plugins/time-grid/stores.js +41 -8
  63. package/src/storage/options.js +4 -39
  64. package/src/storage/state.js +1 -4
  65. package/src/storage/stores.js +42 -11
  66. package/src/styles/days.css +91 -0
  67. package/src/styles/events.css +180 -0
  68. package/src/styles/index.css +126 -0
  69. package/src/styles/now-indicator.css +35 -0
  70. package/src/styles/popup.css +30 -0
  71. package/src/styles/sidebar.css +59 -0
  72. package/src/styles/slots.css +42 -0
  73. package/src/styles/theme.css +68 -0
  74. package/src/styles/toolbar.css +80 -0
  75. package/src/lib/actions.js +0 -52
  76. package/src/plugins/day-grid/Body.svelte +0 -54
  77. package/src/plugins/day-grid/Header.svelte +0 -20
  78. package/src/plugins/day-grid/Week.svelte +0 -60
  79. package/src/plugins/list/Body.svelte +0 -44
  80. package/src/plugins/resource-timeline/Body.svelte +0 -67
  81. package/src/plugins/resource-timeline/Days.svelte +0 -72
  82. package/src/plugins/resource-timeline/Sidebar.svelte +0 -35
  83. package/src/plugins/time-grid/Body.svelte +0 -43
  84. package/src/plugins/time-grid/Section.svelte +0 -29
  85. package/src/plugins/time-grid/all-day/Day.svelte +0 -65
  86. package/src/plugins/time-grid/all-day/Event.svelte +0 -37
  87. package/src/plugins/time-grid/all-day/Week.svelte +0 -65
  88. package/src/plugins/time-grid/utils.js +0 -58
  89. package/src/styles/day-grid.scss +0 -51
  90. package/src/styles/index.scss +0 -553
  91. package/src/styles/theme.scss +0 -95
  92. package/src/styles/time-grid.scss +0 -83
  93. 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": "4.7.1",
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.41.2"
35
+ "svelte": "^5.45.8"
36
36
  }
37
37
  }
@@ -1,12 +1,11 @@
1
1
  <script>
2
2
  import {getContext, untrack} from 'svelte';
3
3
  import {
4
- toISOString, toLocalDate, toViewWithLocalDates, isFunction, task, flushDebounce, hasYScroll
4
+ toISOString, toLocalDate, toViewWithLocalDates, isFunction, task, flushDebounce
5
5
  } from '#lib';
6
6
 
7
7
  let {
8
- datesSet, eventAllUpdated, _auxiliary, _activeRange, _filteredEvents, _scrollable, _bodyEl, _tasks, _recheckScrollable,
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}
@@ -1,49 +1,55 @@
1
1
  <script>
2
- import {getContext, tick} from 'svelte';
3
- import {createDate, cloneDate, setContent, setMidnight, nextDate, prevDate, outsideRange} from '#lib';
2
+ import {getContext, tick, untrack} from 'svelte';
3
+ import {cloneDate, contentFrom, nextDate, prevDate, outsideRange} from '#lib';
4
4
 
5
- export let buttons;
5
+ let {buttons} = $props();
6
6
 
7
7
  let {
8
- _currentRange, _viewTitle, _viewDates, buttonText, customButtons, date, duration, hiddenDays, theme, validRange,
9
- view
8
+ _currentRange, _today, _viewTitle, _viewDates, buttonText, customButtons, date, duration, hiddenDays, theme,
9
+ validRange, view
10
10
  } = getContext('state');
11
11
 
12
- let today = setMidnight(createDate());
13
- let prevDisabled, nextDisabled, todayDisabled;
12
+ let prevDisabled = $state(false);
13
+ let nextDisabled = $state(false);
14
+ let todayDisabled = $state(false);
14
15
 
15
16
  let running = false;
16
- function isRunning() {
17
- return running;
18
- }
19
- $: if (!isRunning()) {
20
- running = true;
21
- prevDisabled = false;
22
- nextDisabled = false;
23
- if ($validRange.start) {
24
- let currentDate = cloneDate($date);
25
- $date = prevDate($date, $duration, $hiddenDays);
26
- prevDisabled = test();
27
- $date = currentDate;
28
- }
29
- if ($validRange.end) {
30
- let currentDate = cloneDate($date);
31
- $date = nextDate($date, $duration);
32
- nextDisabled = test();
33
- $date = currentDate;
34
- }
35
- todayDisabled = today >= $_currentRange.start && today < $_currentRange.end;
36
- if (!todayDisabled && ($validRange.start || $validRange.end)) {
37
- let currentDate = cloneDate($date);
38
- $date = cloneDate(today);
39
- todayDisabled = test();
40
- $date = currentDate;
41
- }
42
- tick().then(() => running = false);
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
- return $_viewDates.every(date => outsideRange(date, $validRange));
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 == 'title'}
60
- <!-- svelte-ignore a11y-missing-content -->
61
- <h2 class="{$theme.title}" use:setContent={$_viewTitle}></h2>
62
- {:else if button == 'prev'}
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
- on:click={prev}
77
+ onclick={prev}
68
78
  disabled={prevDisabled}
69
79
  ><i class="{$theme.icon} ec-{button}"></i></button>
70
- {:else if button == 'next'}
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
- on:click={next}
85
+ onclick={next}
76
86
  disabled={nextDisabled}
77
87
  ><i class="{$theme.icon} ec-{button}"></i></button>
78
- {:else if button == 'today'}
88
+ {:else if button === 'today'}
79
89
  <button
80
90
  class="{$theme.button} ec-{button}"
81
- on:click={() => $date = cloneDate(today)}
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="{$theme.button} ec-{button}{$customButtons[button].active ? ' ' + $theme.active : ''}"
88
- on:click={$customButtons[button].click}
89
- use:setContent={$customButtons[button].text}
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="{$theme.button}{$view === button ? ' ' + $theme.active : ''} ec-{button}"
94
- on:click={() => $view = button}
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}
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import '../dist/index.css';
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, _scrollable,
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="{$theme.calendar} {$theme.view}{$_scrollable ? ' ' + $theme.withScroll : ''}{$_iClass ? ' ' + $theme[$_iClass] : ''}"
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(this, e)
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, setContent, toEventWithLocalDates, toViewWithLocalDates
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
- ]).join(' '));
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} use:setContent={content}></div>
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 == 0) { // Western
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
@@ -16,10 +16,6 @@ export function createElement(tag, className, content, attrs = []) {
16
16
  return el;
17
17
  }
18
18
 
19
- export function hasYScroll(el) {
20
- return el.scrollHeight > el.clientHeight;
21
- }
22
-
23
19
  export function rect(el) {
24
20
  return el.getBoundingClientRect();
25
21
  }