@nomideusz/svelte-calendar 0.5.2 → 0.6.3
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 +408 -178
- package/dist/adapters/memory.d.ts +7 -9
- package/dist/adapters/memory.js +8 -23
- package/dist/adapters/recurring.d.ts +8 -6
- package/dist/adapters/recurring.js +28 -30
- package/dist/calendar/Calendar.svelte +776 -356
- package/dist/calendar/Calendar.svelte.d.ts +57 -6
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/core/locale.js +2 -2
- package/dist/core/palette.d.ts +5 -0
- package/dist/core/palette.js +8 -0
- package/dist/core/types.d.ts +14 -0
- package/dist/engine/event-store.svelte.d.ts +0 -17
- package/dist/engine/event-store.svelte.js +30 -17
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/view-state.svelte.d.ts +10 -5
- package/dist/engine/view-state.svelte.js +32 -16
- package/dist/index.d.ts +7 -7
- package/dist/index.js +3 -4
- package/dist/primitives/DayHeader.svelte +103 -103
- package/dist/primitives/EmptySlot.svelte +105 -105
- package/dist/primitives/EventBlock.svelte +312 -312
- package/dist/primitives/NowIndicator.svelte +178 -178
- package/dist/primitives/TimeGutter.svelte +104 -104
- package/dist/theme/auto.d.ts +53 -0
- package/dist/theme/auto.js +534 -0
- package/dist/theme/index.d.ts +3 -1
- package/dist/theme/index.js +3 -1
- package/dist/theme/presets.d.ts +20 -6
- package/dist/theme/presets.js +55 -42
- package/dist/views/agenda/AgendaDay.svelte +1073 -976
- package/dist/views/agenda/AgendaWeek.svelte +934 -775
- package/dist/views/agenda/index.d.ts +0 -2
- package/dist/views/agenda/index.js +0 -2
- package/dist/views/index.d.ts +3 -2
- package/dist/views/index.js +3 -2
- package/dist/views/mobile/Mobile.svelte +17 -0
- package/dist/views/mobile/Mobile.svelte.d.ts +7 -0
- package/dist/views/mobile/MobileDay.svelte +702 -0
- package/dist/views/mobile/MobileDay.svelte.d.ts +20 -0
- package/dist/views/mobile/MobileWeek.svelte +461 -0
- package/dist/views/mobile/MobileWeek.svelte.d.ts +20 -0
- package/dist/views/mobile/index.d.ts +1 -0
- package/dist/views/mobile/index.js +1 -0
- package/dist/views/planner/PlannerDay.svelte +1129 -957
- package/dist/views/planner/PlannerWeek.svelte +949 -840
- package/dist/widget/CalendarWidget.svelte +142 -157
- package/package.json +2 -1
|
@@ -1,157 +1,142 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CalendarWidget — self-contained calendar for embedding via <day-calendar> custom element.
|
|
3
|
-
|
|
4
|
-
Accepts simple HTML attributes and wires up the full Calendar with sensible defaults.
|
|
5
|
-
Designed for non-Svelte sites (plain HTML, WordPress, Squarespace, etc.).
|
|
6
|
-
|
|
7
|
-
Usage as custom element:
|
|
8
|
-
<day-calendar
|
|
9
|
-
api="https://myschool.com/api/events"
|
|
10
|
-
theme="neutral"
|
|
11
|
-
view="week-planner"
|
|
12
|
-
height="600"
|
|
13
|
-
locale="en-US"
|
|
14
|
-
></day-calendar>
|
|
15
|
-
-->
|
|
16
|
-
<script lang="ts">
|
|
17
|
-
import Calendar from '../calendar/Calendar.svelte';
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
{ id: 'day-agenda', label: L.agenda, granularity: 'day', component: Agenda, props: { mode: 'day' } },
|
|
144
|
-
{ id: 'week-agenda', label: L.agenda, granularity: 'week', component: Agenda, props: { mode: 'week' } },
|
|
145
|
-
]);
|
|
146
|
-
</script>
|
|
147
|
-
|
|
148
|
-
<Calendar
|
|
149
|
-
{adapter}
|
|
150
|
-
views={defaultViews}
|
|
151
|
-
defaultView={view}
|
|
152
|
-
theme={themeStyle}
|
|
153
|
-
height={heightPx}
|
|
154
|
-
mondayStart={isMondayStart}
|
|
155
|
-
dir={dirValue}
|
|
156
|
-
{locale}
|
|
157
|
-
/>
|
|
1
|
+
<!--
|
|
2
|
+
CalendarWidget — self-contained calendar for embedding via <day-calendar> custom element.
|
|
3
|
+
|
|
4
|
+
Accepts simple HTML attributes and wires up the full Calendar with sensible defaults.
|
|
5
|
+
Designed for non-Svelte sites (plain HTML, WordPress, Squarespace, etc.).
|
|
6
|
+
|
|
7
|
+
Usage as custom element:
|
|
8
|
+
<day-calendar
|
|
9
|
+
api="https://myschool.com/api/events"
|
|
10
|
+
theme="neutral"
|
|
11
|
+
view="week-planner"
|
|
12
|
+
height="600"
|
|
13
|
+
locale="en-US"
|
|
14
|
+
></day-calendar>
|
|
15
|
+
-->
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import Calendar from '../calendar/Calendar.svelte';
|
|
18
|
+
import { createRestAdapter } from '../adapters/rest.js';
|
|
19
|
+
import { createMemoryAdapter } from '../adapters/memory.js';
|
|
20
|
+
import { presets } from '../theme/presets.js';
|
|
21
|
+
import type { PresetName } from '../theme/presets.js';
|
|
22
|
+
import type { TimelineEvent } from '../core/types.js';
|
|
23
|
+
|
|
24
|
+
interface Props {
|
|
25
|
+
/** REST API base URL — if provided, fetches events from this endpoint */
|
|
26
|
+
api?: string;
|
|
27
|
+
/** JSON string of events for static/inline data (alternative to api) */
|
|
28
|
+
events?: string;
|
|
29
|
+
/** Theme preset name: midnight, neutral */
|
|
30
|
+
theme?: string;
|
|
31
|
+
/** Default view ID */
|
|
32
|
+
view?: string;
|
|
33
|
+
/** Calendar height in pixels */
|
|
34
|
+
height?: string;
|
|
35
|
+
/** BCP 47 locale tag (e.g. 'en-US', 'pl-PL') */
|
|
36
|
+
locale?: string;
|
|
37
|
+
/** Text direction: ltr, rtl, auto */
|
|
38
|
+
dir?: string;
|
|
39
|
+
/** Start week on Monday (default: true) */
|
|
40
|
+
mondaystart?: string;
|
|
41
|
+
/** Custom HTTP headers as JSON string for REST adapter */
|
|
42
|
+
headers?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let {
|
|
46
|
+
api,
|
|
47
|
+
events,
|
|
48
|
+
theme = 'neutral',
|
|
49
|
+
view = 'week-planner',
|
|
50
|
+
height = '600',
|
|
51
|
+
locale,
|
|
52
|
+
dir,
|
|
53
|
+
mondaystart = 'true',
|
|
54
|
+
headers,
|
|
55
|
+
}: Props = $props();
|
|
56
|
+
|
|
57
|
+
// ── Parse attributes ──
|
|
58
|
+
const heightPx = $derived(parseInt(height, 10) || 600);
|
|
59
|
+
const isMondayStart = $derived(mondaystart !== 'false');
|
|
60
|
+
const themeStyle = $derived(
|
|
61
|
+
(presets as Record<string, string>)[theme] || presets.neutral
|
|
62
|
+
);
|
|
63
|
+
const dirValue = $derived(
|
|
64
|
+
(dir === 'rtl' || dir === 'ltr' || dir === 'auto') ? dir as 'ltr' | 'rtl' | 'auto' : undefined
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// ── Parse static events from JSON attribute ──
|
|
68
|
+
function parseHeaders(json?: string): Record<string, string> | undefined {
|
|
69
|
+
if (!json) return undefined;
|
|
70
|
+
try {
|
|
71
|
+
const parsed = JSON.parse(json) as Record<string, unknown>;
|
|
72
|
+
const out: Record<string, string> = {};
|
|
73
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
74
|
+
out[k] = String(v);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
} catch {
|
|
78
|
+
console.warn('[day-calendar] Failed to parse headers JSON:', json);
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function toEvent(raw: Record<string, unknown>, fallbackId: string): TimelineEvent | null {
|
|
84
|
+
const start = new Date(String(raw.start ?? ''));
|
|
85
|
+
const end = new Date(String(raw.end ?? ''));
|
|
86
|
+
if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end <= start) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
id: String(raw.id ?? fallbackId),
|
|
91
|
+
title: String(raw.title ?? 'Untitled'),
|
|
92
|
+
start,
|
|
93
|
+
end,
|
|
94
|
+
color: raw.color ? String(raw.color) : undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function parseEvents(json?: string): TimelineEvent[] {
|
|
99
|
+
if (!json) return [];
|
|
100
|
+
try {
|
|
101
|
+
const raw = JSON.parse(json) as Array<Record<string, unknown>>;
|
|
102
|
+
const parsed = raw
|
|
103
|
+
.map((e, idx) => toEvent(e, `inline-${idx}`))
|
|
104
|
+
.filter((ev): ev is TimelineEvent => ev !== null);
|
|
105
|
+
if (parsed.length !== raw.length) {
|
|
106
|
+
console.warn(`[day-calendar] Ignored ${raw.length - parsed.length} invalid event(s) from events JSON.`);
|
|
107
|
+
}
|
|
108
|
+
return parsed;
|
|
109
|
+
} catch {
|
|
110
|
+
console.warn('[day-calendar] Failed to parse events JSON:', json);
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ── Create adapter ──
|
|
116
|
+
const adapter = $derived.by(() => {
|
|
117
|
+
if (api) {
|
|
118
|
+
const parsedHeaders = parseHeaders(headers);
|
|
119
|
+
return createRestAdapter({
|
|
120
|
+
baseUrl: api,
|
|
121
|
+
headers: parsedHeaders,
|
|
122
|
+
mapEvents: (data: unknown) => {
|
|
123
|
+
const arr = Array.isArray(data) ? data : (data as Record<string, unknown>).events as unknown[] ?? [];
|
|
124
|
+
return arr
|
|
125
|
+
.map((e: unknown, idx) => toEvent(e as Record<string, unknown>, `api-${idx}`))
|
|
126
|
+
.filter((ev): ev is TimelineEvent => ev !== null);
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return createMemoryAdapter(parseEvents(events));
|
|
131
|
+
});
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<Calendar
|
|
135
|
+
{adapter}
|
|
136
|
+
{view}
|
|
137
|
+
theme={themeStyle}
|
|
138
|
+
height={heightPx}
|
|
139
|
+
mondayStart={isMondayStart}
|
|
140
|
+
dir={dirValue}
|
|
141
|
+
{locale}
|
|
142
|
+
/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomideusz/svelte-calendar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "A themeable Svelte 5 calendar with Day and Week views — Planner and Agenda.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
44
44
|
"@types/node": "^22.0.0",
|
|
45
45
|
"@vercel/analytics": "^1.6.1",
|
|
46
|
+
"jsdom": "^28.1.0",
|
|
46
47
|
"marked": "^17.0.3",
|
|
47
48
|
"svelte": "^5.51.0",
|
|
48
49
|
"svelte-check": "^4.3.6",
|