@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
|
@@ -2,24 +2,22 @@
|
|
|
2
2
|
* In-memory adapter — the default for demos and testing.
|
|
3
3
|
*
|
|
4
4
|
* Events are stored in a plain array. No persistence across page loads.
|
|
5
|
-
*
|
|
5
|
+
* Events without a `color` are auto-assigned one from a palette,
|
|
6
|
+
* grouped by `category` or `title` so related events share a color.
|
|
6
7
|
*
|
|
7
8
|
* Usage:
|
|
8
9
|
* import { createMemoryAdapter } from './';
|
|
9
10
|
* const adapter = createMemoryAdapter(initialEvents);
|
|
10
|
-
* const
|
|
11
|
+
* const adapter = createMemoryAdapter(initialEvents, { palette: myColors });
|
|
11
12
|
*/
|
|
12
13
|
import type { TimelineEvent } from '../core/types.js';
|
|
13
14
|
import type { CalendarAdapter } from './types.js';
|
|
14
15
|
export interface MemoryAdapterOptions {
|
|
15
|
-
/** Map of category/title to color */
|
|
16
|
-
colorMap?: Record<string, string>;
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* theme-harmonious palette via golden-angle hue rotation
|
|
17
|
+
* Custom color palette for auto-coloring events.
|
|
18
|
+
* Defaults to VIVID_PALETTE. Pass `generatePalette(accent)` to
|
|
19
|
+
* make event colors adapt to your theme.
|
|
22
20
|
*/
|
|
23
|
-
|
|
21
|
+
palette?: string[];
|
|
24
22
|
}
|
|
25
23
|
export declare function createMemoryAdapter(initial?: TimelineEvent[], options?: MemoryAdapterOptions): CalendarAdapter;
|
package/dist/adapters/memory.js
CHANGED
|
@@ -1,38 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VIVID_PALETTE } from '../core/palette.js';
|
|
2
2
|
let counter = 0;
|
|
3
3
|
function uid() {
|
|
4
4
|
return `mem-${Date.now()}-${++counter}`;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
const AUTO_COLORS = VIVID_PALETTE;
|
|
8
|
-
export function createMemoryAdapter(initial = [], options = {}) {
|
|
9
|
-
const { colorMap, autoColor } = options;
|
|
6
|
+
export function createMemoryAdapter(initial = [], options) {
|
|
10
7
|
const events = [...initial];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
? typeof autoColor === 'string'
|
|
14
|
-
? generatePalette(autoColor)
|
|
15
|
-
: AUTO_COLORS
|
|
16
|
-
: AUTO_COLORS;
|
|
17
|
-
// Build auto-color assignments
|
|
8
|
+
const palette = options?.palette ?? VIVID_PALETTE;
|
|
9
|
+
// Auto-color: assign from vivid palette by category/title
|
|
18
10
|
const colorAssignments = new Map();
|
|
19
11
|
let colorIndex = 0;
|
|
20
12
|
function resolveColor(ev) {
|
|
21
13
|
if (ev.color)
|
|
22
14
|
return ev.color;
|
|
23
|
-
if (!colorMap && !autoColor)
|
|
24
|
-
return undefined;
|
|
25
15
|
const key = ev.category ?? ev.title;
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!colorAssignments.has(key)) {
|
|
30
|
-
colorAssignments.set(key, palette[colorIndex % palette.length]);
|
|
31
|
-
colorIndex++;
|
|
32
|
-
}
|
|
33
|
-
return colorAssignments.get(key);
|
|
16
|
+
if (!colorAssignments.has(key)) {
|
|
17
|
+
colorAssignments.set(key, palette[colorIndex % palette.length]);
|
|
18
|
+
colorIndex++;
|
|
34
19
|
}
|
|
35
|
-
return
|
|
20
|
+
return colorAssignments.get(key);
|
|
36
21
|
}
|
|
37
22
|
function withColor(ev) {
|
|
38
23
|
const color = resolveColor(ev);
|
|
@@ -63,19 +63,21 @@ export interface RecurringEvent {
|
|
|
63
63
|
export interface RecurringAdapterOptions {
|
|
64
64
|
/** Start weeks on Monday (default: true) */
|
|
65
65
|
mondayStart?: boolean;
|
|
66
|
-
/** Map of category/title to color */
|
|
67
|
-
colorMap?: Record<string, string>;
|
|
68
66
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
67
|
+
* Custom color palette for auto-coloring events.
|
|
68
|
+
* Pass `generatePalette('#yourAccent')` to get theme-harmonious colors,
|
|
69
|
+
* or provide your own array of hex strings.
|
|
70
|
+
* Defaults to the built-in vivid palette.
|
|
72
71
|
*/
|
|
73
|
-
|
|
72
|
+
palette?: string[];
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
75
|
* Create a CalendarAdapter that projects recurring events onto concrete
|
|
77
76
|
* dates for whatever range the calendar requests.
|
|
78
77
|
*
|
|
78
|
+
* Events without a `color` are auto-assigned one from a vivid palette,
|
|
79
|
+
* grouped by `category` or `title` so related events share a color.
|
|
80
|
+
*
|
|
79
81
|
* Read-only by default — create/update/delete throw.
|
|
80
82
|
*/
|
|
81
83
|
export declare function createRecurringAdapter(schedule: RecurringEvent[], options?: RecurringAdapterOptions): CalendarAdapter;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { startOfWeek, DAY_MS } from '../core/time.js';
|
|
2
|
-
import {
|
|
2
|
+
import { VIVID_PALETTE } from '../core/palette.js';
|
|
3
3
|
// ── Helpers ─────────────────────────────────────────────
|
|
4
4
|
/** Parse "HH:MM" into [hours, minutes] */
|
|
5
5
|
function parseTime(time) {
|
|
@@ -46,14 +46,21 @@ function clampDayOfMonth(year, month, day) {
|
|
|
46
46
|
const lastDay = new Date(year, month + 1, 0).getDate();
|
|
47
47
|
return new Date(year, month, Math.min(day, lastDay));
|
|
48
48
|
}
|
|
49
|
+
/** Format a Date as a compact "YYYYMMDD" key for stable instance IDs. */
|
|
50
|
+
function dateKey(d) {
|
|
51
|
+
const y = d.getFullYear();
|
|
52
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
53
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
54
|
+
return `${y}${m}${day}`;
|
|
55
|
+
}
|
|
49
56
|
/** Create a concrete TimelineEvent from a recurring def + occurrence date */
|
|
50
|
-
function createConcreteEvent(rec, date
|
|
57
|
+
function createConcreteEvent(rec, date) {
|
|
51
58
|
const [sh, sm] = parseTime(rec.startTime);
|
|
52
59
|
const [eh, em] = parseTime(rec.endTime);
|
|
53
60
|
const start = new Date(date.getFullYear(), date.getMonth(), date.getDate(), sh, sm);
|
|
54
61
|
const end = new Date(date.getFullYear(), date.getMonth(), date.getDate(), eh, em);
|
|
55
62
|
return {
|
|
56
|
-
id: `${rec.id}--${
|
|
63
|
+
id: `${rec.id}--${dateKey(date)}`,
|
|
57
64
|
title: rec.title,
|
|
58
65
|
start,
|
|
59
66
|
end,
|
|
@@ -129,16 +136,14 @@ function projectDaily(rec, range, startDate, effectiveUntil, out) {
|
|
|
129
136
|
if (cursor < rangeStart)
|
|
130
137
|
cursor.setDate(cursor.getDate() + interval);
|
|
131
138
|
}
|
|
132
|
-
let idx = 0;
|
|
133
139
|
while (cursor < range.end) {
|
|
134
140
|
if (effectiveUntil && cursor > effectiveUntil)
|
|
135
141
|
break;
|
|
136
|
-
const ev = createConcreteEvent(rec, cursor
|
|
142
|
+
const ev = createConcreteEvent(rec, cursor);
|
|
137
143
|
if (ev.start < range.end && ev.end > range.start) {
|
|
138
144
|
out.push(ev);
|
|
139
145
|
}
|
|
140
146
|
cursor.setDate(cursor.getDate() + interval);
|
|
141
|
-
idx++;
|
|
142
147
|
}
|
|
143
148
|
}
|
|
144
149
|
function projectWeekly(rec, range, startDate, effectiveUntil, mondayStart, out) {
|
|
@@ -165,7 +170,6 @@ function projectWeekly(rec, range, startDate, effectiveUntil, mondayStart, out)
|
|
|
165
170
|
weekMs += interval * 7 * DAY_MS;
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
|
-
let weekIndex = Math.round((weekMs - anchorWeekMs) / (7 * DAY_MS));
|
|
169
173
|
while (weekMs < rangeEndMs) {
|
|
170
174
|
for (const day of days) {
|
|
171
175
|
const dayMs = weekMs + isoWeekdayToOffset(day) * DAY_MS;
|
|
@@ -176,13 +180,12 @@ function projectWeekly(rec, range, startDate, effectiveUntil, mondayStart, out)
|
|
|
176
180
|
if (effectiveUntil && dayMs > effectiveUntil.getTime())
|
|
177
181
|
return;
|
|
178
182
|
const dayDate = new Date(dayMs);
|
|
179
|
-
const ev = createConcreteEvent(rec, dayDate
|
|
183
|
+
const ev = createConcreteEvent(rec, dayDate);
|
|
180
184
|
if (ev.start < range.end && ev.end > range.start) {
|
|
181
185
|
out.push(ev);
|
|
182
186
|
}
|
|
183
187
|
}
|
|
184
188
|
weekMs += interval * 7 * DAY_MS;
|
|
185
|
-
weekIndex += interval;
|
|
186
189
|
}
|
|
187
190
|
}
|
|
188
191
|
function projectMonthly(rec, range, startDate, effectiveUntil, out) {
|
|
@@ -206,7 +209,7 @@ function projectMonthly(rec, range, startDate, effectiveUntil, out) {
|
|
|
206
209
|
if (effectiveUntil && date > effectiveUntil)
|
|
207
210
|
break;
|
|
208
211
|
if (date >= range.start && (!startDate || date >= startDate)) {
|
|
209
|
-
const ev = createConcreteEvent(rec, date
|
|
212
|
+
const ev = createConcreteEvent(rec, date);
|
|
210
213
|
if (ev.start < range.end && ev.end > range.start) {
|
|
211
214
|
out.push(ev);
|
|
212
215
|
}
|
|
@@ -216,34 +219,29 @@ function projectMonthly(rec, range, startDate, effectiveUntil, out) {
|
|
|
216
219
|
}
|
|
217
220
|
// ── Adapter factory ─────────────────────────────────────
|
|
218
221
|
/** Default palette for auto-coloring */
|
|
219
|
-
const
|
|
222
|
+
const PALETTE = VIVID_PALETTE;
|
|
220
223
|
/**
|
|
221
224
|
* Create a CalendarAdapter that projects recurring events onto concrete
|
|
222
225
|
* dates for whatever range the calendar requests.
|
|
223
226
|
*
|
|
227
|
+
* Events without a `color` are auto-assigned one from a vivid palette,
|
|
228
|
+
* grouped by `category` or `title` so related events share a color.
|
|
229
|
+
*
|
|
224
230
|
* Read-only by default — create/update/delete throw.
|
|
225
231
|
*/
|
|
226
232
|
export function createRecurringAdapter(schedule, options = {}) {
|
|
227
|
-
const { mondayStart = true,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
? typeof autoColor === 'string'
|
|
231
|
-
? generatePalette(autoColor)
|
|
232
|
-
: AUTO_COLORS
|
|
233
|
-
: AUTO_COLORS;
|
|
234
|
-
// Build auto-color assignments
|
|
233
|
+
const { mondayStart = true, palette } = options;
|
|
234
|
+
const colors = palette?.length ? palette : PALETTE;
|
|
235
|
+
// Auto-color: assign from palette by category/title
|
|
235
236
|
const colorAssignments = new Map();
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
colorAssignments.set(key, palette[colorIndex % palette.length]);
|
|
245
|
-
colorIndex++;
|
|
246
|
-
}
|
|
237
|
+
let colorIndex = 0;
|
|
238
|
+
for (const rec of schedule) {
|
|
239
|
+
if (rec.color)
|
|
240
|
+
continue;
|
|
241
|
+
const key = rec.category ?? rec.title;
|
|
242
|
+
if (!colorAssignments.has(key)) {
|
|
243
|
+
colorAssignments.set(key, colors[colorIndex % colors.length]);
|
|
244
|
+
colorIndex++;
|
|
247
245
|
}
|
|
248
246
|
}
|
|
249
247
|
function resolveColor(rec) {
|