@nomideusz/svelte-calendar 0.14.0 → 0.15.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/dist/calendar/Calendar.svelte +451 -373
- package/dist/calendar/Calendar.svelte.d.ts +2 -1
- package/dist/headless/types.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/primitives/DayHeader.svelte +1 -7
- package/dist/primitives/EmptySlot.svelte +8 -10
- package/dist/primitives/EventBlock.svelte +12 -22
- package/dist/primitives/FloatingPanel.svelte +185 -0
- package/dist/primitives/FloatingPanel.svelte.d.ts +23 -0
- package/dist/primitives/NowIndicator.svelte +2 -13
- package/dist/primitives/TimeGutter.svelte +1 -7
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +1 -0
- package/dist/views/agenda/AgendaDay.svelte +68 -45
- package/dist/views/agenda/AgendaWeek.svelte +181 -92
- package/dist/views/mobile/MobileDay.svelte +313 -276
- package/dist/views/mobile/MobileWeek.svelte +91 -84
- package/dist/views/month/MonthGrid.svelte +101 -104
- package/dist/views/planner/PlannerWeek.svelte +475 -407
- package/dist/views/planner/PlannerWeek.svelte.d.ts +1 -1
- package/dist/views/shared/context.svelte.d.ts +4 -0
- package/dist/views/shared/context.svelte.js +1 -0
- package/dist/widget/CalendarWidget.svelte +64 -83
- package/package.json +17 -10
- package/widget/widget.js +12723 -12135
|
@@ -26,6 +26,10 @@ export interface CalendarContext {
|
|
|
26
26
|
readonly minDuration: number | undefined;
|
|
27
27
|
readonly maxDuration: number | undefined;
|
|
28
28
|
readonly oneventhover: ((event: TimelineEvent) => void) | undefined;
|
|
29
|
+
/** Move callback (already readOnly-gated and timezone-unzoning at the
|
|
30
|
+
* Calendar layer) — lets non-planner views offer coarser drags, e.g.
|
|
31
|
+
* AgendaWeek's day-to-day card drop. */
|
|
32
|
+
readonly oneventmove: ((event: TimelineEvent, newStart: Date, newEnd: Date) => void) | undefined;
|
|
29
33
|
readonly ondayclick: ((date: Date) => void) | undefined;
|
|
30
34
|
readonly timezone: string | undefined;
|
|
31
35
|
readonly disabledDates: Date[] | undefined;
|
|
@@ -42,6 +42,7 @@ export function useCalendarContext() {
|
|
|
42
42
|
get minDuration() { return raw?.minDuration; },
|
|
43
43
|
get maxDuration() { return raw?.maxDuration; },
|
|
44
44
|
get oneventhover() { return raw?.oneventhover; },
|
|
45
|
+
get oneventmove() { return raw?.oneventmove; },
|
|
45
46
|
get ondayclick() { return raw?.ondayclick; },
|
|
46
47
|
get timezone() { return raw?.timezone; },
|
|
47
48
|
get disabledDates() { return raw?.disabledDates; },
|
|
@@ -17,101 +17,82 @@
|
|
|
17
17
|
import { createRestAdapter } from "../adapters/rest.js";
|
|
18
18
|
import { createMemoryAdapter } from "../adapters/memory.js";
|
|
19
19
|
import { presets } from "../theme/presets.js";
|
|
20
|
-
let {
|
|
21
|
-
|
|
22
|
-
events,
|
|
23
|
-
theme = "auto",
|
|
24
|
-
view = "week-planner",
|
|
25
|
-
height = "600",
|
|
26
|
-
locale,
|
|
27
|
-
dir,
|
|
28
|
-
mondaystart = "true",
|
|
29
|
-
headers,
|
|
30
|
-
readonly,
|
|
31
|
-
pills,
|
|
32
|
-
nav,
|
|
33
|
-
mobile,
|
|
34
|
-
days,
|
|
35
|
-
compact,
|
|
36
|
-
timezone
|
|
37
|
-
} = $props();
|
|
20
|
+
let { api, events, theme = "auto", view = "week-planner", height = "600", locale, dir, mondaystart = "true", headers, readonly, pills, nav, mobile, days, compact, timezone } = $props();
|
|
21
|
+
// ── Parse attributes ──
|
|
38
22
|
const heightValue = $derived.by(() => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
23
|
+
const trimmed = height.trim();
|
|
24
|
+
if (trimmed === "auto") return "auto";
|
|
25
|
+
if (/^\d+(px)?$/.test(trimmed)) return parseInt(trimmed, 10);
|
|
26
|
+
// "100%" / "50vh" aren't supported — warn instead of rendering a 100px sliver
|
|
27
|
+
console.warn(`[day-calendar] Unsupported height "${height}" — use pixels or "auto". Falling back to 600.`);
|
|
28
|
+
return 600;
|
|
44
29
|
});
|
|
45
30
|
const isMondayStart = $derived(mondaystart !== "false");
|
|
46
|
-
const themeStyle = $derived(
|
|
47
|
-
|
|
48
|
-
);
|
|
49
|
-
const dirValue = $derived(
|
|
50
|
-
dir === "rtl" || dir === "ltr" || dir === "auto" ? dir : void 0
|
|
51
|
-
);
|
|
52
|
-
const mobileValue = $derived(
|
|
53
|
-
mobile === "true" ? true : mobile === "false" ? false : "auto"
|
|
54
|
-
);
|
|
31
|
+
const themeStyle = $derived(theme in presets ? presets[theme] : presets.neutral);
|
|
32
|
+
const dirValue = $derived(dir === "rtl" || dir === "ltr" || dir === "auto" ? dir : undefined);
|
|
33
|
+
const mobileValue = $derived(mobile === "true" ? true : mobile === "false" ? false : "auto");
|
|
55
34
|
const daysValue = $derived.by(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
35
|
+
if (!days) return undefined;
|
|
36
|
+
const n = parseInt(days, 10);
|
|
37
|
+
return Number.isNaN(n) || n < 1 || n > 7 ? undefined : n;
|
|
59
38
|
});
|
|
39
|
+
// ── Parse static events from JSON attribute ──
|
|
60
40
|
function parseHeaders(json) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
41
|
+
if (!json) return undefined;
|
|
42
|
+
try {
|
|
43
|
+
const parsed = JSON.parse(json);
|
|
44
|
+
const out = {};
|
|
45
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
46
|
+
out[k] = String(v);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
} catch {
|
|
50
|
+
console.warn("[day-calendar] Failed to parse headers JSON:", json);
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
73
53
|
}
|
|
74
54
|
function toEvent(raw, fallbackId) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
55
|
+
const start = new Date(String(raw.start ?? ""));
|
|
56
|
+
const end = new Date(String(raw.end ?? ""));
|
|
57
|
+
if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end <= start) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
id: String(raw.id ?? fallbackId),
|
|
62
|
+
title: String(raw.title ?? "Untitled"),
|
|
63
|
+
start,
|
|
64
|
+
end,
|
|
65
|
+
color: raw.color ? String(raw.color) : undefined
|
|
66
|
+
};
|
|
87
67
|
}
|
|
88
68
|
function parseEvents(json) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
69
|
+
if (!json) return [];
|
|
70
|
+
try {
|
|
71
|
+
const raw = JSON.parse(json);
|
|
72
|
+
const parsed = raw.map((e, idx) => toEvent(e, `inline-${idx}`)).filter((ev) => ev !== null);
|
|
73
|
+
if (parsed.length !== raw.length) {
|
|
74
|
+
console.warn(`[day-calendar] Ignored ${raw.length - parsed.length} invalid event(s) from events JSON.`);
|
|
75
|
+
}
|
|
76
|
+
return parsed;
|
|
77
|
+
} catch {
|
|
78
|
+
console.warn("[day-calendar] Failed to parse events JSON:", json);
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
101
81
|
}
|
|
82
|
+
// ── Create adapter ──
|
|
102
83
|
const adapter = $derived.by(() => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
84
|
+
if (api) {
|
|
85
|
+
const parsedHeaders = parseHeaders(headers);
|
|
86
|
+
return createRestAdapter({
|
|
87
|
+
baseUrl: api,
|
|
88
|
+
headers: parsedHeaders,
|
|
89
|
+
mapEvents: (data) => {
|
|
90
|
+
const arr = Array.isArray(data) ? data : data.events ?? [];
|
|
91
|
+
return arr.map((e, idx) => toEvent(e, `api-${idx}`)).filter((ev) => ev !== null);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return createMemoryAdapter(parseEvents(events));
|
|
115
96
|
});
|
|
116
97
|
</script>
|
|
117
98
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomideusz/svelte-calendar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "A themeable Svelte 5 calendar with Day and Week views — Planner and Agenda.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"sideEffects":
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"./widget/widget.js"
|
|
8
|
+
],
|
|
7
9
|
"license": "MIT",
|
|
8
10
|
"svelte": "./dist/index.js",
|
|
9
11
|
"types": "./dist/index.d.ts",
|
|
@@ -21,6 +23,10 @@
|
|
|
21
23
|
"!dist/**/*.test.*",
|
|
22
24
|
"!dist/**/*.spec.*"
|
|
23
25
|
],
|
|
26
|
+
"imports": {
|
|
27
|
+
"#lib": "./src/lib",
|
|
28
|
+
"#lib/*": "./src/lib/*"
|
|
29
|
+
},
|
|
24
30
|
"scripts": {
|
|
25
31
|
"dev": "vite dev",
|
|
26
32
|
"build": "vite build",
|
|
@@ -39,19 +45,20 @@
|
|
|
39
45
|
"svelte": "^5.0.0"
|
|
40
46
|
},
|
|
41
47
|
"devDependencies": {
|
|
42
|
-
"@sveltejs/adapter-auto": "
|
|
43
|
-
"@sveltejs/
|
|
44
|
-
"@sveltejs/
|
|
45
|
-
"@sveltejs/
|
|
48
|
+
"@sveltejs/adapter-auto": "8.0.0-next.3",
|
|
49
|
+
"@sveltejs/adapter-vercel": "7.0.0-next.6",
|
|
50
|
+
"@sveltejs/kit": "3.0.0-next.23",
|
|
51
|
+
"@sveltejs/package": "3.0.0-next.7",
|
|
52
|
+
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
46
53
|
"@types/node": "^22.20.0",
|
|
47
54
|
"@vercel/analytics": "^1.6.1",
|
|
48
55
|
"jsdom": "^29.1.1",
|
|
49
56
|
"marked": "^17.0.6",
|
|
50
|
-
"svelte": "^5.56.
|
|
57
|
+
"svelte": "^5.56.9",
|
|
51
58
|
"svelte-check": "^4.7.1",
|
|
52
|
-
"typescript": "^
|
|
53
|
-
"vite": "^
|
|
54
|
-
"vitest": "^4.1.
|
|
59
|
+
"typescript": "^6.0.3",
|
|
60
|
+
"vite": "^8.2.1",
|
|
61
|
+
"vitest": "^4.1.10"
|
|
55
62
|
},
|
|
56
63
|
"dependencies": {
|
|
57
64
|
"date-fns": "^4.4.0",
|