@nomideusz/svelte-calendar 0.13.0 → 0.14.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 +2 -0
- package/dist/calendar/Calendar.svelte +5 -1
- package/dist/calendar/Calendar.svelte.d.ts +7 -0
- package/dist/engine/event-store.svelte.d.ts +7 -1
- package/dist/engine/event-store.svelte.js +35 -11
- package/dist/views/planner/PlannerWeek.svelte +61 -14
- package/dist/views/shared/context.svelte.d.ts +1 -0
- package/dist/views/shared/context.svelte.js +1 -0
- package/package.json +73 -72
- package/widget/widget.js +90 -33
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @nomideusz/svelte-calendar
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@nomideusz/svelte-calendar) [](https://github.com/nomideusz/svelte-calendar/blob/main/LICENSE)
|
|
4
|
+
|
|
3
5
|
A themeable **Svelte 5** calendar with **Day/Week Planner & Agenda** views, touch-first mobile views, and a smart auto-theme that adapts to any page.
|
|
4
6
|
|
|
5
7
|
**[Live demo → svelte-calendar.xyz](https://svelte-calendar.xyz/)**
|
|
@@ -57,6 +57,7 @@ let {
|
|
|
57
57
|
visibleHours,
|
|
58
58
|
initialDate,
|
|
59
59
|
snapInterval = 15,
|
|
60
|
+
minColumnWidth = 110,
|
|
60
61
|
showModePills = true,
|
|
61
62
|
showNavigation = true,
|
|
62
63
|
equalDays = false,
|
|
@@ -132,7 +133,7 @@ const effectiveTheme = $derived(theme === auto && autoTheme !== false ? probedTh
|
|
|
132
133
|
const effectiveAdapter = $derived(
|
|
133
134
|
timezone ? wrapAdapterWithTimezone(adapter, timezone) : adapter
|
|
134
135
|
);
|
|
135
|
-
const store =
|
|
136
|
+
const store = createEventStore(() => effectiveAdapter);
|
|
136
137
|
const viewState = createViewState(untrack(() => ({
|
|
137
138
|
view: activeViewId ?? views[0]?.id,
|
|
138
139
|
mondayStart,
|
|
@@ -256,6 +257,9 @@ setContext("calendar", {
|
|
|
256
257
|
get snapInterval() {
|
|
257
258
|
return snapInterval;
|
|
258
259
|
},
|
|
260
|
+
get minColumnWidth() {
|
|
261
|
+
return minColumnWidth;
|
|
262
|
+
},
|
|
259
263
|
get eventSnippet() {
|
|
260
264
|
return eventSnippet;
|
|
261
265
|
},
|
|
@@ -57,6 +57,13 @@ interface Props {
|
|
|
57
57
|
initialDate?: Date;
|
|
58
58
|
/** Drag snap interval in minutes (default: 15) */
|
|
59
59
|
snapInterval?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Minimum width (px) of a day column in planner views (default: 110).
|
|
62
|
+
* Below the resulting total the grid scrolls horizontally. Lower it when
|
|
63
|
+
* the calendar shares its row with a sidebar and the whole week must stay
|
|
64
|
+
* visible without scrolling.
|
|
65
|
+
*/
|
|
66
|
+
minColumnWidth?: number;
|
|
60
67
|
/** Show the Day/Week mode pills (default: true) */
|
|
61
68
|
showModePills?: boolean;
|
|
62
69
|
/** Show prev/next/today navigation controls (default: true) */
|
|
@@ -26,5 +26,11 @@ export interface EventStore {
|
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Create a reactive event store backed by a CalendarAdapter.
|
|
29
|
+
*
|
|
30
|
+
* Pass a getter instead of an adapter when the adapter identity can change
|
|
31
|
+
* (a `$derived` adapter, a host that rebuilds it to force a refetch): the
|
|
32
|
+
* store then stays alive across the swap and reloads, instead of being torn
|
|
33
|
+
* down and rebuilt with an empty event map — which reads as every event
|
|
34
|
+
* blinking out and reappearing.
|
|
29
35
|
*/
|
|
30
|
-
export declare function createEventStore(adapter: CalendarAdapter): EventStore;
|
|
36
|
+
export declare function createEventStore(adapter: CalendarAdapter | (() => CalendarAdapter)): EventStore;
|
|
@@ -19,11 +19,20 @@ import { SvelteMap } from 'svelte/reactivity';
|
|
|
19
19
|
import { sod, DAY_MS } from '../core/time.js';
|
|
20
20
|
/**
|
|
21
21
|
* Create a reactive event store backed by a CalendarAdapter.
|
|
22
|
+
*
|
|
23
|
+
* Pass a getter instead of an adapter when the adapter identity can change
|
|
24
|
+
* (a `$derived` adapter, a host that rebuilds it to force a refetch): the
|
|
25
|
+
* store then stays alive across the swap and reloads, instead of being torn
|
|
26
|
+
* down and rebuilt with an empty event map — which reads as every event
|
|
27
|
+
* blinking out and reappearing.
|
|
22
28
|
*/
|
|
23
29
|
export function createEventStore(adapter) {
|
|
30
|
+
const getAdapter = typeof adapter === 'function' ? adapter : () => adapter;
|
|
24
31
|
let eventMap = new SvelteMap();
|
|
25
32
|
let loading = $state(false);
|
|
26
33
|
let error = $state(null);
|
|
34
|
+
/** Guards against an older in-flight load pruning a newer one's result */
|
|
35
|
+
let loadSeq = 0;
|
|
27
36
|
// Derived array view of the map — consumers read this.
|
|
28
37
|
const eventArray = $derived([...eventMap.values()]);
|
|
29
38
|
// ── Internal helpers ──
|
|
@@ -48,11 +57,21 @@ export function createEventStore(adapter) {
|
|
|
48
57
|
return error;
|
|
49
58
|
},
|
|
50
59
|
async load(range) {
|
|
60
|
+
const seq = ++loadSeq;
|
|
51
61
|
loading = true;
|
|
52
62
|
error = null;
|
|
53
63
|
try {
|
|
54
|
-
const fetched = await
|
|
55
|
-
|
|
64
|
+
const fetched = await getAdapter().fetchEvents(range);
|
|
65
|
+
if (seq !== loadSeq)
|
|
66
|
+
return; // superseded by a newer load
|
|
67
|
+
// Merge: upsert fetched, don't blow away events outside this range.
|
|
68
|
+
// Inside the range the adapter is authoritative — drop what it no
|
|
69
|
+
// longer returns, or deleted/moved events linger until remount.
|
|
70
|
+
const keep = new Set(fetched.map((ev) => ev.id));
|
|
71
|
+
for (const ev of [...eventMap.values()]) {
|
|
72
|
+
if (!keep.has(ev.id) && overlaps(ev, range.start, range.end))
|
|
73
|
+
removeEvent(ev.id);
|
|
74
|
+
}
|
|
56
75
|
for (const ev of fetched) {
|
|
57
76
|
upsertEvent(ev);
|
|
58
77
|
}
|
|
@@ -61,7 +80,8 @@ export function createEventStore(adapter) {
|
|
|
61
80
|
error = e instanceof Error ? e.message : String(e);
|
|
62
81
|
}
|
|
63
82
|
finally {
|
|
64
|
-
|
|
83
|
+
if (seq === loadSeq)
|
|
84
|
+
loading = false;
|
|
65
85
|
}
|
|
66
86
|
},
|
|
67
87
|
forRange(start, end) {
|
|
@@ -76,12 +96,12 @@ export function createEventStore(adapter) {
|
|
|
76
96
|
return eventMap.get(id);
|
|
77
97
|
},
|
|
78
98
|
async add(eventData) {
|
|
79
|
-
if (!
|
|
99
|
+
if (!getAdapter().createEvent)
|
|
80
100
|
throw new Error('Adapter is read-only: createEvent not implemented');
|
|
81
101
|
loading = true;
|
|
82
102
|
error = null;
|
|
83
103
|
try {
|
|
84
|
-
const created = await
|
|
104
|
+
const created = await getAdapter().createEvent(eventData);
|
|
85
105
|
upsertEvent(created);
|
|
86
106
|
return created;
|
|
87
107
|
}
|
|
@@ -94,12 +114,12 @@ export function createEventStore(adapter) {
|
|
|
94
114
|
}
|
|
95
115
|
},
|
|
96
116
|
async update(id, patch) {
|
|
97
|
-
if (!
|
|
117
|
+
if (!getAdapter().updateEvent)
|
|
98
118
|
throw new Error('Adapter is read-only: updateEvent not implemented');
|
|
99
119
|
loading = true;
|
|
100
120
|
error = null;
|
|
101
121
|
try {
|
|
102
|
-
const updated = await
|
|
122
|
+
const updated = await getAdapter().updateEvent(id, patch);
|
|
103
123
|
upsertEvent(updated);
|
|
104
124
|
}
|
|
105
125
|
catch (e) {
|
|
@@ -111,12 +131,12 @@ export function createEventStore(adapter) {
|
|
|
111
131
|
}
|
|
112
132
|
},
|
|
113
133
|
async remove(id) {
|
|
114
|
-
if (!
|
|
134
|
+
if (!getAdapter().deleteEvent)
|
|
115
135
|
throw new Error('Adapter is read-only: deleteEvent not implemented');
|
|
116
136
|
loading = true;
|
|
117
137
|
error = null;
|
|
118
138
|
try {
|
|
119
|
-
await
|
|
139
|
+
await getAdapter().deleteEvent(id);
|
|
120
140
|
removeEvent(id);
|
|
121
141
|
}
|
|
122
142
|
catch (e) {
|
|
@@ -138,8 +158,12 @@ export function createEventStore(adapter) {
|
|
|
138
158
|
await this.update(id, { start: newStart, end: newEnd });
|
|
139
159
|
}
|
|
140
160
|
catch (e) {
|
|
141
|
-
// Revert optimistic update on failure
|
|
142
|
-
|
|
161
|
+
// Revert optimistic update on failure — except for a read-only
|
|
162
|
+
// adapter, where the HOST owns persistence (Calendar forwards to
|
|
163
|
+
// oneventmove). Reverting there snaps the block back to its old
|
|
164
|
+
// slot for the length of the host's round-trip.
|
|
165
|
+
const msg = e instanceof Error ? e.message : '';
|
|
166
|
+
if (existing && !msg.includes('read-only'))
|
|
143
167
|
upsertEvent(existing);
|
|
144
168
|
throw e;
|
|
145
169
|
}
|
|
@@ -53,7 +53,7 @@ const disabledSet = $derived(ctx.disabledSet);
|
|
|
53
53
|
const SNAP_MS = $derived(ctx.snapInterval * 6e4);
|
|
54
54
|
const HOUR_H = 48;
|
|
55
55
|
const GUTTER_W = 48;
|
|
56
|
-
const MIN_COL_W =
|
|
56
|
+
const MIN_COL_W = $derived(ctx.minColumnWidth);
|
|
57
57
|
const ALLDAY_MAX = 3;
|
|
58
58
|
const startHour = $derived(visibleHours?.[0] ?? 0);
|
|
59
59
|
const endHour = $derived(visibleHours?.[1] ?? 24);
|
|
@@ -135,7 +135,6 @@ const layoutByDay = $derived.by(() => {
|
|
|
135
135
|
const infos = [];
|
|
136
136
|
for (const ev of events) {
|
|
137
137
|
if (isAllDay(ev) || isMultiDay(ev)) continue;
|
|
138
|
-
if (ev.id === movingId) continue;
|
|
139
138
|
const isResizing = rsP?.eventId === ev.id;
|
|
140
139
|
const s0 = isResizing ? rsP.start.getTime() : ev.start.getTime();
|
|
141
140
|
const e0 = isResizing ? rsP.end.getTime() : ev.end.getTime();
|
|
@@ -143,7 +142,7 @@ const layoutByDay = $derived.by(() => {
|
|
|
143
142
|
const sMs = Math.max(s0, bandStart);
|
|
144
143
|
const eMs = Math.min(e0, bandEnd);
|
|
145
144
|
if (eMs <= sMs) continue;
|
|
146
|
-
infos.push({ ev, startMs: sMs, endMs: eMs, isResizing, col: 0, totalCols: 1 });
|
|
145
|
+
infos.push({ ev, startMs: sMs, endMs: eMs, isResizing, isMoving: ev.id === movingId, col: 0, totalCols: 1 });
|
|
147
146
|
}
|
|
148
147
|
infos.sort((a, b) => a.startMs - b.startMs || b.endMs - a.endMs);
|
|
149
148
|
const par = infos.map((_, i) => i);
|
|
@@ -185,7 +184,8 @@ const layoutByDay = $derived.by(() => {
|
|
|
185
184
|
height: Math.max(24, (inf.endMs - inf.startMs) / HOUR_MS * HOUR_H),
|
|
186
185
|
col: inf.col,
|
|
187
186
|
totalCols: inf.totalCols,
|
|
188
|
-
isResizing: inf.isResizing
|
|
187
|
+
isResizing: inf.isResizing,
|
|
188
|
+
isMoving: inf.isMoving
|
|
189
189
|
}))
|
|
190
190
|
);
|
|
191
191
|
}
|
|
@@ -222,8 +222,41 @@ $effect(() => {
|
|
|
222
222
|
el.scrollTop = (targetHour - startHour) * HOUR_H;
|
|
223
223
|
});
|
|
224
224
|
});
|
|
225
|
+
let rafId = 0;
|
|
226
|
+
let rafRun = null;
|
|
227
|
+
let rectCache = null;
|
|
228
|
+
function perFrame(handler) {
|
|
229
|
+
return (e) => {
|
|
230
|
+
rafRun = () => {
|
|
231
|
+
rectCache = colsEl?.getBoundingClientRect() ?? null;
|
|
232
|
+
try {
|
|
233
|
+
handler(e);
|
|
234
|
+
} finally {
|
|
235
|
+
rectCache = null;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
if (rafId) return;
|
|
239
|
+
rafId = requestAnimationFrame(flushFrame);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function flushFrame() {
|
|
243
|
+
if (rafId) {
|
|
244
|
+
cancelAnimationFrame(rafId);
|
|
245
|
+
rafId = 0;
|
|
246
|
+
}
|
|
247
|
+
const run = rafRun;
|
|
248
|
+
rafRun = null;
|
|
249
|
+
run?.();
|
|
250
|
+
}
|
|
251
|
+
function cancelFrame() {
|
|
252
|
+
if (rafId) {
|
|
253
|
+
cancelAnimationFrame(rafId);
|
|
254
|
+
rafId = 0;
|
|
255
|
+
}
|
|
256
|
+
rafRun = null;
|
|
257
|
+
}
|
|
225
258
|
function colsRect() {
|
|
226
|
-
return colsEl.getBoundingClientRect();
|
|
259
|
+
return rectCache ?? colsEl.getBoundingClientRect();
|
|
227
260
|
}
|
|
228
261
|
function pointerDayIndex(clientX) {
|
|
229
262
|
const r = colsRect();
|
|
@@ -339,7 +372,7 @@ function onColsPointerDown(e) {
|
|
|
339
372
|
window.addEventListener("pointerup", onColsCreateUp, { once: true });
|
|
340
373
|
window.addEventListener("pointercancel", onColsCreateCancel, { once: true });
|
|
341
374
|
}
|
|
342
|
-
|
|
375
|
+
const onColsCreateMove = perFrame((e) => {
|
|
343
376
|
if (!drag) return;
|
|
344
377
|
if (!crStarted) {
|
|
345
378
|
if (longPressTimer !== null) {
|
|
@@ -357,8 +390,9 @@ function onColsCreateMove(e) {
|
|
|
357
390
|
new Date(Math.min(crAnchorMs, snapped)),
|
|
358
391
|
new Date(Math.max(crAnchorMs + SNAP_MS, snapped))
|
|
359
392
|
);
|
|
360
|
-
}
|
|
393
|
+
});
|
|
361
394
|
function cleanupColsCreate() {
|
|
395
|
+
cancelFrame();
|
|
362
396
|
clearLongPress();
|
|
363
397
|
removeTouchScrollBlock();
|
|
364
398
|
window.removeEventListener("pointermove", onColsCreateMove);
|
|
@@ -367,6 +401,7 @@ function cleanupColsCreate() {
|
|
|
367
401
|
crStarted = false;
|
|
368
402
|
}
|
|
369
403
|
function onColsCreateUp() {
|
|
404
|
+
if (crStarted) flushFrame();
|
|
370
405
|
if (drag && crStarted) {
|
|
371
406
|
suppressColsClick = true;
|
|
372
407
|
commitDragCtx?.();
|
|
@@ -421,7 +456,7 @@ function onEventPointerDown(e, ev) {
|
|
|
421
456
|
window.addEventListener("pointerup", onEvUp, { once: true });
|
|
422
457
|
window.addEventListener("pointercancel", onEvCancel, { once: true });
|
|
423
458
|
}
|
|
424
|
-
|
|
459
|
+
const onEvMove = perFrame((e) => {
|
|
425
460
|
const ev = evDragEvent;
|
|
426
461
|
if (!drag || !ev || !evDragMovable) return;
|
|
427
462
|
if (!evDragStarted) {
|
|
@@ -434,8 +469,9 @@ function onEvMove(e) {
|
|
|
434
469
|
const raw = pointerTimeMs(e.clientX, e.clientY) - evGrabOffsetMs;
|
|
435
470
|
const snapped = Math.round(raw / SNAP_MS) * SNAP_MS;
|
|
436
471
|
drag.updatePointer(new Date(snapped), new Date(snapped + duration));
|
|
437
|
-
}
|
|
472
|
+
});
|
|
438
473
|
function cleanupEvDrag() {
|
|
474
|
+
cancelFrame();
|
|
439
475
|
window.removeEventListener("pointermove", onEvMove);
|
|
440
476
|
window.removeEventListener("pointerup", onEvUp);
|
|
441
477
|
window.removeEventListener("pointercancel", onEvCancel);
|
|
@@ -444,6 +480,7 @@ function cleanupEvDrag() {
|
|
|
444
480
|
evDragEvent = null;
|
|
445
481
|
}
|
|
446
482
|
function onEvUp() {
|
|
483
|
+
if (evDragStarted) flushFrame();
|
|
447
484
|
if (!evDragStarted && evDragEvent) {
|
|
448
485
|
oneventclick?.(evDragEvent);
|
|
449
486
|
} else if (evDragStarted && drag) {
|
|
@@ -474,7 +511,7 @@ function onResizePointerDown(e, ev, edge) {
|
|
|
474
511
|
window.addEventListener("pointerup", onResizeUp, { once: true });
|
|
475
512
|
window.addEventListener("pointercancel", onResizeCancel, { once: true });
|
|
476
513
|
}
|
|
477
|
-
|
|
514
|
+
const onResizeMove = perFrame((e) => {
|
|
478
515
|
const ev = rsEvent;
|
|
479
516
|
if (!drag || !ev) return;
|
|
480
517
|
if (!rsStarted) {
|
|
@@ -493,8 +530,9 @@ function onResizeMove(e) {
|
|
|
493
530
|
const start = Math.min(snapped, ev.end.getTime() - SNAP_MS);
|
|
494
531
|
drag.updatePointer(new Date(start), ev.end);
|
|
495
532
|
}
|
|
496
|
-
}
|
|
533
|
+
});
|
|
497
534
|
function cleanupResize() {
|
|
535
|
+
cancelFrame();
|
|
498
536
|
removeTouchScrollBlock();
|
|
499
537
|
window.removeEventListener("pointermove", onResizeMove);
|
|
500
538
|
window.removeEventListener("pointerup", onResizeUp);
|
|
@@ -503,6 +541,7 @@ function cleanupResize() {
|
|
|
503
541
|
rsEvent = null;
|
|
504
542
|
}
|
|
505
543
|
function onResizeUp() {
|
|
544
|
+
if (rsStarted) flushFrame();
|
|
506
545
|
if (drag && rsStarted) {
|
|
507
546
|
suppressColsClick = true;
|
|
508
547
|
commitDragCtx?.();
|
|
@@ -568,6 +607,7 @@ function onWindowKeydown(e) {
|
|
|
568
607
|
class="tw"
|
|
569
608
|
class:tw--auto={autoHeight}
|
|
570
609
|
style={style || undefined}
|
|
610
|
+
style:--tw-col-min="{MIN_COL_W}px"
|
|
571
611
|
style:height={autoHeight ? undefined : (height ? `${height}px` : '100%')}
|
|
572
612
|
role="region"
|
|
573
613
|
aria-label={L.weekAhead}
|
|
@@ -703,6 +743,7 @@ function onWindowKeydown(e) {
|
|
|
703
743
|
class:tw-ev--selected={selectedEventId === p.ev.id}
|
|
704
744
|
class:tw-ev--current={isCurrent}
|
|
705
745
|
class:tw-ev--resizing={p.isResizing}
|
|
746
|
+
class:tw-ev--moving={p.isMoving}
|
|
706
747
|
class:tw-ev--readonly={p.ev.data?.readOnly}
|
|
707
748
|
class:tw-ev--cancelled={p.ev.status === 'cancelled'}
|
|
708
749
|
class:tw-ev--tentative={p.ev.status === 'tentative'}
|
|
@@ -857,7 +898,7 @@ function onWindowKeydown(e) {
|
|
|
857
898
|
|
|
858
899
|
.tw-hd {
|
|
859
900
|
flex: 1 1 0;
|
|
860
|
-
min-width: 110px;
|
|
901
|
+
min-width: var(--tw-col-min, 110px);
|
|
861
902
|
display: flex;
|
|
862
903
|
flex-direction: column;
|
|
863
904
|
align-items: center;
|
|
@@ -923,7 +964,7 @@ function onWindowKeydown(e) {
|
|
|
923
964
|
|
|
924
965
|
.tw-ad-cell {
|
|
925
966
|
flex: 1 1 0;
|
|
926
|
-
min-width: 110px;
|
|
967
|
+
min-width: var(--tw-col-min, 110px);
|
|
927
968
|
display: flex;
|
|
928
969
|
flex-direction: column;
|
|
929
970
|
gap: 2px;
|
|
@@ -1075,7 +1116,7 @@ function onWindowKeydown(e) {
|
|
|
1075
1116
|
/* ─── Day column ─────────────────────────────────── */
|
|
1076
1117
|
.tw-col {
|
|
1077
1118
|
flex: 1 1 0;
|
|
1078
|
-
min-width: 110px;
|
|
1119
|
+
min-width: var(--tw-col-min, 110px);
|
|
1079
1120
|
position: relative;
|
|
1080
1121
|
border-left: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
|
|
1081
1122
|
box-sizing: border-box;
|
|
@@ -1197,6 +1238,12 @@ function onWindowKeydown(e) {
|
|
|
1197
1238
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
|
1198
1239
|
cursor: ns-resize;
|
|
1199
1240
|
}
|
|
1241
|
+
/* Origin of an in-flight move: still there, clearly no longer the subject. */
|
|
1242
|
+
.tw-ev--moving {
|
|
1243
|
+
opacity: 0.3;
|
|
1244
|
+
pointer-events: none;
|
|
1245
|
+
box-shadow: none;
|
|
1246
|
+
}
|
|
1200
1247
|
/* Status treatments: token-level dims + a non-opacity signal
|
|
1201
1248
|
(strikethrough / border style) — consistent with the other views. */
|
|
1202
1249
|
.tw-ev--cancelled {
|
|
@@ -8,6 +8,7 @@ export interface CalendarContext {
|
|
|
8
8
|
readonly drag: DragState | undefined;
|
|
9
9
|
readonly commitDrag: (() => void) | undefined;
|
|
10
10
|
readonly snapInterval: number;
|
|
11
|
+
readonly minColumnWidth: number;
|
|
11
12
|
readonly equalDays: boolean;
|
|
12
13
|
readonly showDates: boolean;
|
|
13
14
|
readonly hideDays: number[] | undefined;
|
|
@@ -28,6 +28,7 @@ export function useCalendarContext() {
|
|
|
28
28
|
get drag() { return raw?.drag; },
|
|
29
29
|
get commitDrag() { return raw?.commitDrag; },
|
|
30
30
|
get snapInterval() { return raw?.snapInterval ?? 15; },
|
|
31
|
+
get minColumnWidth() { return raw?.minColumnWidth ?? 110; },
|
|
31
32
|
get equalDays() { return raw?.equalDays ?? false; },
|
|
32
33
|
get showDates() { return raw?.showDates ?? true; },
|
|
33
34
|
get hideDays() { return raw?.hideDays; },
|
package/package.json
CHANGED
|
@@ -1,74 +1,75 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
2
|
+
"name": "@nomideusz/svelte-calendar",
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "A themeable Svelte 5 calendar with Day and Week views — Planner and Agenda.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"svelte": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"svelte": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./widget": "./widget/widget.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"widget",
|
|
21
|
+
"!dist/**/*.test.*",
|
|
22
|
+
"!dist/**/*.spec.*"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "vite dev",
|
|
26
|
+
"build": "vite build",
|
|
27
|
+
"package": "svelte-kit sync && svelte-package",
|
|
28
|
+
"package:watch": "svelte-kit sync && svelte-package --watch",
|
|
29
|
+
"build:widget": "vite build --config vite.config.widget.ts",
|
|
30
|
+
"prepublishOnly": "npm run package",
|
|
31
|
+
"preview": "vite preview",
|
|
32
|
+
"prepare": "svelte-kit sync && svelte-package",
|
|
33
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
34
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"svelte": "^5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
43
|
+
"@sveltejs/kit": "^2.69.1",
|
|
44
|
+
"@sveltejs/package": "^2.5.8",
|
|
45
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
46
|
+
"@types/node": "^22.20.0",
|
|
47
|
+
"@vercel/analytics": "^1.6.1",
|
|
48
|
+
"jsdom": "^29.1.1",
|
|
49
|
+
"marked": "^17.0.6",
|
|
50
|
+
"svelte": "^5.56.4",
|
|
51
|
+
"svelte-check": "^4.7.1",
|
|
52
|
+
"typescript": "^5.9.3",
|
|
53
|
+
"vite": "^7.3.6",
|
|
54
|
+
"vitest": "^4.1.9"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"date-fns": "^4.4.0",
|
|
58
|
+
"date-fns-tz": "^3.2.0"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"svelte",
|
|
62
|
+
"calendar",
|
|
63
|
+
"scheduler",
|
|
64
|
+
"timeline",
|
|
65
|
+
"week",
|
|
66
|
+
"day",
|
|
67
|
+
"booking",
|
|
68
|
+
"svelte5"
|
|
69
|
+
],
|
|
70
|
+
"repository": {
|
|
71
|
+
"type": "git",
|
|
72
|
+
"url": "https://github.com/nomideusz/svelte-calendar"
|
|
73
|
+
},
|
|
74
|
+
"homepage": "https://svelte-calendar.xyz/"
|
|
74
75
|
}
|