@nomideusz/svelte-calendar 0.1.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 (77) hide show
  1. package/README.md +168 -0
  2. package/dist/adapters/index.d.ts +4 -0
  3. package/dist/adapters/index.js +2 -0
  4. package/dist/adapters/memory.d.ts +14 -0
  5. package/dist/adapters/memory.js +33 -0
  6. package/dist/adapters/rest.d.ts +20 -0
  7. package/dist/adapters/rest.js +48 -0
  8. package/dist/adapters/types.d.ts +23 -0
  9. package/dist/adapters/types.js +1 -0
  10. package/dist/assets/favicon.svg +1 -0
  11. package/dist/calendar/Calendar.svelte +213 -0
  12. package/dist/calendar/Calendar.svelte.d.ts +45 -0
  13. package/dist/calendar/Toolbar.svelte +241 -0
  14. package/dist/calendar/Toolbar.svelte.d.ts +19 -0
  15. package/dist/calendar/index.d.ts +3 -0
  16. package/dist/calendar/index.js +3 -0
  17. package/dist/core/clock.svelte.d.ts +21 -0
  18. package/dist/core/clock.svelte.js +53 -0
  19. package/dist/core/index.d.ts +6 -0
  20. package/dist/core/index.js +8 -0
  21. package/dist/core/locale.d.ts +38 -0
  22. package/dist/core/locale.js +96 -0
  23. package/dist/core/time.d.ts +37 -0
  24. package/dist/core/time.js +68 -0
  25. package/dist/core/types.d.ts +91 -0
  26. package/dist/core/types.js +11 -0
  27. package/dist/engine/drag.svelte.d.ts +31 -0
  28. package/dist/engine/drag.svelte.js +58 -0
  29. package/dist/engine/event-store.svelte.d.ts +47 -0
  30. package/dist/engine/event-store.svelte.js +120 -0
  31. package/dist/engine/index.d.ts +8 -0
  32. package/dist/engine/index.js +5 -0
  33. package/dist/engine/selection.svelte.d.ts +24 -0
  34. package/dist/engine/selection.svelte.js +58 -0
  35. package/dist/engine/view-state.svelte.d.ts +24 -0
  36. package/dist/engine/view-state.svelte.js +74 -0
  37. package/dist/index.d.ts +13 -0
  38. package/dist/index.js +14 -0
  39. package/dist/primitives/DayHeader.svelte +103 -0
  40. package/dist/primitives/DayHeader.svelte.d.ts +15 -0
  41. package/dist/primitives/EmptySlot.svelte +101 -0
  42. package/dist/primitives/EmptySlot.svelte.d.ts +16 -0
  43. package/dist/primitives/EventBlock.svelte +241 -0
  44. package/dist/primitives/EventBlock.svelte.d.ts +24 -0
  45. package/dist/primitives/NowIndicator.svelte +175 -0
  46. package/dist/primitives/NowIndicator.svelte.d.ts +22 -0
  47. package/dist/primitives/TimeGutter.svelte +105 -0
  48. package/dist/primitives/TimeGutter.svelte.d.ts +14 -0
  49. package/dist/primitives/index.d.ts +5 -0
  50. package/dist/primitives/index.js +6 -0
  51. package/dist/theme/index.d.ts +2 -0
  52. package/dist/theme/index.js +2 -0
  53. package/dist/theme/presets.d.ts +24 -0
  54. package/dist/theme/presets.js +89 -0
  55. package/dist/views/agenda/Agenda.svelte +1404 -0
  56. package/dist/views/agenda/Agenda.svelte.d.ts +20 -0
  57. package/dist/views/agenda/index.d.ts +1 -0
  58. package/dist/views/agenda/index.js +1 -0
  59. package/dist/views/day/DayGrid.svelte +1063 -0
  60. package/dist/views/day/DayGrid.svelte.d.ts +33 -0
  61. package/dist/views/day/DayTimeline.svelte +505 -0
  62. package/dist/views/day/DayTimeline.svelte.d.ts +4 -0
  63. package/dist/views/day/index.d.ts +2 -0
  64. package/dist/views/day/index.js +2 -0
  65. package/dist/views/index.d.ts +5 -0
  66. package/dist/views/index.js +5 -0
  67. package/dist/views/settings/Settings.svelte +303 -0
  68. package/dist/views/settings/Settings.svelte.d.ts +23 -0
  69. package/dist/views/settings/index.d.ts +2 -0
  70. package/dist/views/settings/index.js +1 -0
  71. package/dist/views/week/WeekGrid.svelte +594 -0
  72. package/dist/views/week/WeekGrid.svelte.d.ts +21 -0
  73. package/dist/views/week/WeekHeatmap.svelte +453 -0
  74. package/dist/views/week/WeekHeatmap.svelte.d.ts +4 -0
  75. package/dist/views/week/index.d.ts +2 -0
  76. package/dist/views/week/index.js +2 -0
  77. package/package.json +62 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared TypeScript types for the timeline design system.
3
+ */
4
+ /**
5
+ * Represents an event on the timeline / scheduler.
6
+ * Core interface for all views, adapters, and the event store.
7
+ */
8
+ export interface TimelineEvent {
9
+ id: string;
10
+ title: string;
11
+ start: Date;
12
+ end: Date;
13
+ color?: string;
14
+ /** All-day event (renders as a banner, not a timed block) */
15
+ allDay?: boolean;
16
+ /** Category for grouping (e.g. "wellness", "work", "life") */
17
+ category?: string;
18
+ /** Recurrence rule — iCalendar RRULE string (e.g. "FREQ=WEEKLY;BYDAY=MO") */
19
+ recurrence?: string;
20
+ /** Whether this event can be moved / resized by the user */
21
+ editable?: boolean;
22
+ /** Arbitrary payload from the source app (bookings, attendees, etc.) */
23
+ data?: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * Shared props contract for all WeekTimeline variants.
27
+ * Every variant MUST accept this exact interface so they can be
28
+ * hot-swapped without changing bindings.
29
+ */
30
+ export interface WeekTimelineProps {
31
+ /** Week offset: 0 = this week, -1 = last, +1 = next (ignored when focusDate is set) */
32
+ weekOffset?: number;
33
+ /** Start on Monday (true) or Sunday (false) */
34
+ mondayStart?: boolean;
35
+ /** Pixel height of one hour row */
36
+ hourHeight?: number;
37
+ /** Pixel width of each day column (0 = equal flex) */
38
+ dayWidth?: number;
39
+ /** Where "now" sits vertically (0 = top edge, 1 = bottom edge) */
40
+ nowPosition?: number;
41
+ /** Total visible height of the component */
42
+ height?: number;
43
+ /** Events to render */
44
+ events?: TimelineEvent[];
45
+ /** Inline style for CSS variable overrides (theme) */
46
+ style?: string;
47
+ /** The date to centre this view on. Overrides weekOffset when set. */
48
+ focusDate?: Date;
49
+ /** Called when the user clicks an event */
50
+ oneventclick?: (event: TimelineEvent) => void;
51
+ /** Called when the user clicks an empty time slot */
52
+ oneventcreate?: (range: {
53
+ start: Date;
54
+ end: Date;
55
+ }) => void;
56
+ /** Currently selected event ID (for highlight) */
57
+ selectedEventId?: string | null;
58
+ }
59
+ /**
60
+ * Shared props contract for the DayTimeline component.
61
+ */
62
+ export interface DayTimelineProps {
63
+ /** Number of past days visible */
64
+ pastDays?: number;
65
+ /** Number of future days visible */
66
+ futureDays?: number;
67
+ /** Pixel width of one hour */
68
+ hourWidth?: number;
69
+ /** Where "now" sits in the viewport (0 = left edge, 1 = right edge) */
70
+ nowPosition?: number;
71
+ /** Events to render */
72
+ events?: TimelineEvent[];
73
+ /** Inline style for CSS custom property overrides */
74
+ style?: string;
75
+ /** The date to centre this view on */
76
+ focusDate?: Date;
77
+ /** Called when the user clicks an event */
78
+ oneventclick?: (event: TimelineEvent) => void;
79
+ /** Called when the user clicks an empty time slot */
80
+ oneventcreate?: (range: {
81
+ start: Date;
82
+ end: Date;
83
+ }) => void;
84
+ /** Currently selected event ID (for highlight) */
85
+ selectedEventId?: string | null;
86
+ }
87
+ /**
88
+ * Convert a Date (or timestamp) to a pixel offset on the timeline.
89
+ * Useful for external apps that need to position overlays.
90
+ */
91
+ export declare function timeToX(time: Date | number, rangeStartMs: number, hourWidth: number): number;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared TypeScript types for the timeline design system.
3
+ */
4
+ /**
5
+ * Convert a Date (or timestamp) to a pixel offset on the timeline.
6
+ * Useful for external apps that need to position overlays.
7
+ */
8
+ export function timeToX(time, rangeStartMs, hourWidth) {
9
+ const ms = typeof time === 'number' ? time : time.getTime();
10
+ return ((ms - rangeStartMs) / 3_600_000) * hourWidth;
11
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Reactive drag state — tracks drag-to-create, drag-to-move, and resize operations.
3
+ *
4
+ * This is a state machine, not actual DOM event handling.
5
+ * View components use Svelte `use:` actions (from actions/) to wire
6
+ * pointer events → this state. The engine reads this state and commits
7
+ * changes to the event store on drop.
8
+ */
9
+ export type DragMode = 'none' | 'create' | 'move' | 'resize-start' | 'resize-end';
10
+ export interface DragPayload {
11
+ /** The event being dragged (null for create) */
12
+ eventId: string | null;
13
+ /** Current tentative start */
14
+ start: Date;
15
+ /** Current tentative end */
16
+ end: Date;
17
+ /** Which day column / row is the pointer over */
18
+ dayIndex: number;
19
+ }
20
+ export interface DragState {
21
+ readonly mode: DragMode;
22
+ readonly payload: DragPayload | null;
23
+ readonly active: boolean;
24
+ beginCreate(start: Date, end: Date, dayIndex?: number): void;
25
+ beginMove(eventId: string, start: Date, end: Date): void;
26
+ beginResize(eventId: string, edge: 'start' | 'end', start: Date, end: Date): void;
27
+ updatePointer(start: Date, end: Date, dayIndex?: number): void;
28
+ commit(): DragPayload | null;
29
+ cancel(): void;
30
+ }
31
+ export declare function createDragState(): DragState;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Reactive drag state — tracks drag-to-create, drag-to-move, and resize operations.
3
+ *
4
+ * This is a state machine, not actual DOM event handling.
5
+ * View components use Svelte `use:` actions (from actions/) to wire
6
+ * pointer events → this state. The engine reads this state and commits
7
+ * changes to the event store on drop.
8
+ */
9
+ export function createDragState() {
10
+ let mode = $state('none');
11
+ let payload = $state(null);
12
+ const active = $derived(mode !== 'none');
13
+ function reset() {
14
+ mode = 'none';
15
+ payload = null;
16
+ }
17
+ return {
18
+ get mode() {
19
+ return mode;
20
+ },
21
+ get payload() {
22
+ return payload;
23
+ },
24
+ get active() {
25
+ return active;
26
+ },
27
+ beginCreate(start, end, dayIndex = 0) {
28
+ mode = 'create';
29
+ payload = { eventId: null, start, end, dayIndex };
30
+ },
31
+ beginMove(eventId, start, end) {
32
+ mode = 'move';
33
+ payload = { eventId, start, end, dayIndex: 0 };
34
+ },
35
+ beginResize(eventId, edge, start, end) {
36
+ mode = edge === 'start' ? 'resize-start' : 'resize-end';
37
+ payload = { eventId, start, end, dayIndex: 0 };
38
+ },
39
+ updatePointer(start, end, dayIndex) {
40
+ if (!payload)
41
+ return;
42
+ payload = {
43
+ ...payload,
44
+ start,
45
+ end,
46
+ ...(dayIndex !== undefined ? { dayIndex } : {}),
47
+ };
48
+ },
49
+ commit() {
50
+ const result = payload;
51
+ reset();
52
+ return result;
53
+ },
54
+ cancel() {
55
+ reset();
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Reactive event store — the CRUD brain of the calendar.
3
+ *
4
+ * Wraps a CalendarAdapter and exposes Svelte 5 rune-mode reactive state.
5
+ * All mutations go through the adapter first, then update local state.
6
+ *
7
+ * Usage:
8
+ * const store = createEventStore(adapter);
9
+ * // store.events — all loaded events (reactive)
10
+ * // store.forRange() — query by date range
11
+ * // store.forDay() — query single day
12
+ * // store.add() — create event
13
+ * // store.update() — patch event
14
+ * // store.remove() — delete event
15
+ * // store.move() — drag-move shorthand
16
+ * // store.load() — fetch from adapter for a range
17
+ */
18
+ import type { TimelineEvent } from '../core/types.js';
19
+ import type { CalendarAdapter, DateRange } from '../adapters/types.js';
20
+ export interface EventStore {
21
+ /** All currently loaded events (reactive) */
22
+ readonly events: TimelineEvent[];
23
+ /** Whether a load/mutation is in-flight */
24
+ readonly loading: boolean;
25
+ /** Last error, if any */
26
+ readonly error: string | null;
27
+ /** Load events from the adapter for a date range */
28
+ load(range: DateRange): Promise<void>;
29
+ /** Get events overlapping a date range (client-side filter) */
30
+ forRange(start: Date, end: Date): TimelineEvent[];
31
+ /** Get events for a single day */
32
+ forDay(date: Date): TimelineEvent[];
33
+ /** Get a single event by ID */
34
+ byId(id: string): TimelineEvent | undefined;
35
+ /** Create a new event */
36
+ add(event: Omit<TimelineEvent, 'id'>): Promise<TimelineEvent>;
37
+ /** Patch an existing event */
38
+ update(id: string, patch: Partial<TimelineEvent>): Promise<void>;
39
+ /** Delete an event */
40
+ remove(id: string): Promise<void>;
41
+ /** Move an event to a new time range (drag shorthand) */
42
+ move(id: string, newStart: Date, newEnd: Date): Promise<void>;
43
+ }
44
+ /**
45
+ * Create a reactive event store backed by a CalendarAdapter.
46
+ */
47
+ export declare function createEventStore(adapter: CalendarAdapter): EventStore;
@@ -0,0 +1,120 @@
1
+ import { sod } from '../core/time.js';
2
+ /**
3
+ * Create a reactive event store backed by a CalendarAdapter.
4
+ */
5
+ export function createEventStore(adapter) {
6
+ let events = $state([]);
7
+ let loading = $state(false);
8
+ let error = $state(null);
9
+ // ── Internal helpers ──
10
+ function overlaps(ev, start, end) {
11
+ return ev.start < end && ev.end > start;
12
+ }
13
+ function replaceEvent(id, updated) {
14
+ const idx = events.findIndex((e) => e.id === id);
15
+ if (idx >= 0) {
16
+ events[idx] = updated;
17
+ }
18
+ }
19
+ function removeEvent(id) {
20
+ events = events.filter((e) => e.id !== id);
21
+ }
22
+ function upsertEvent(ev) {
23
+ const idx = events.findIndex((e) => e.id === ev.id);
24
+ if (idx >= 0) {
25
+ events[idx] = ev;
26
+ }
27
+ else {
28
+ events.push(ev);
29
+ }
30
+ }
31
+ // ── Public API ──
32
+ return {
33
+ get events() {
34
+ return events;
35
+ },
36
+ get loading() {
37
+ return loading;
38
+ },
39
+ get error() {
40
+ return error;
41
+ },
42
+ async load(range) {
43
+ loading = true;
44
+ error = null;
45
+ try {
46
+ const fetched = await adapter.fetchEvents(range);
47
+ // Merge: upsert fetched, don't blow away events outside this range
48
+ for (const ev of fetched) {
49
+ upsertEvent(ev);
50
+ }
51
+ }
52
+ catch (e) {
53
+ error = e instanceof Error ? e.message : String(e);
54
+ }
55
+ finally {
56
+ loading = false;
57
+ }
58
+ },
59
+ forRange(start, end) {
60
+ return events.filter((ev) => overlaps(ev, start, end));
61
+ },
62
+ forDay(date) {
63
+ const dayStart = new Date(sod(date.getTime()));
64
+ const dayEnd = new Date(dayStart.getTime() + 86_400_000);
65
+ return events.filter((ev) => overlaps(ev, dayStart, dayEnd));
66
+ },
67
+ byId(id) {
68
+ return events.find((e) => e.id === id);
69
+ },
70
+ async add(eventData) {
71
+ loading = true;
72
+ error = null;
73
+ try {
74
+ const created = await adapter.createEvent(eventData);
75
+ events.push(created);
76
+ return created;
77
+ }
78
+ catch (e) {
79
+ error = e instanceof Error ? e.message : String(e);
80
+ throw e;
81
+ }
82
+ finally {
83
+ loading = false;
84
+ }
85
+ },
86
+ async update(id, patch) {
87
+ loading = true;
88
+ error = null;
89
+ try {
90
+ const updated = await adapter.updateEvent(id, patch);
91
+ replaceEvent(id, updated);
92
+ }
93
+ catch (e) {
94
+ error = e instanceof Error ? e.message : String(e);
95
+ throw e;
96
+ }
97
+ finally {
98
+ loading = false;
99
+ }
100
+ },
101
+ async remove(id) {
102
+ loading = true;
103
+ error = null;
104
+ try {
105
+ await adapter.deleteEvent(id);
106
+ removeEvent(id);
107
+ }
108
+ catch (e) {
109
+ error = e instanceof Error ? e.message : String(e);
110
+ throw e;
111
+ }
112
+ finally {
113
+ loading = false;
114
+ }
115
+ },
116
+ async move(id, newStart, newEnd) {
117
+ return this.update(id, { start: newStart, end: newEnd });
118
+ },
119
+ };
120
+ }
@@ -0,0 +1,8 @@
1
+ export { createEventStore } from './event-store.svelte.js';
2
+ export type { EventStore } from './event-store.svelte.js';
3
+ export { createViewState } from './view-state.svelte.js';
4
+ export type { ViewState, ViewStateOptions, CalendarViewId, ViewGranularity, DateRange as ViewDateRange, } from './view-state.svelte.js';
5
+ export { createSelection } from './selection.svelte.js';
6
+ export type { Selection } from './selection.svelte.js';
7
+ export { createDragState } from './drag.svelte.js';
8
+ export type { DragState, DragMode, DragPayload } from './drag.svelte.js';
@@ -0,0 +1,5 @@
1
+ // ─── Engine barrel export ───────────────────────────────
2
+ export { createEventStore } from './event-store.svelte.js';
3
+ export { createViewState } from './view-state.svelte.js';
4
+ export { createSelection } from './selection.svelte.js';
5
+ export { createDragState } from './drag.svelte.js';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Reactive selection state — tracks selected and hovered events.
3
+ *
4
+ * Usage:
5
+ * const sel = createSelection();
6
+ * sel.selectedId — currently selected event ID (or null)
7
+ * sel.hoveredId — currently hovered event ID (or null)
8
+ * sel.selectedIds — Set of selected IDs (multi-select)
9
+ * sel.select(id) — select one event (clears multi)
10
+ * sel.toggle(id) — toggle in multi-select
11
+ * sel.clear() — deselect all
12
+ */
13
+ export interface Selection {
14
+ readonly selectedId: string | null;
15
+ readonly hoveredId: string | null;
16
+ readonly selectedIds: ReadonlySet<string>;
17
+ select(id: string): void;
18
+ deselect(): void;
19
+ toggle(id: string): void;
20
+ clear(): void;
21
+ hover(id: string | null): void;
22
+ isSelected(id: string): boolean;
23
+ }
24
+ export declare function createSelection(): Selection;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Reactive selection state — tracks selected and hovered events.
3
+ *
4
+ * Usage:
5
+ * const sel = createSelection();
6
+ * sel.selectedId — currently selected event ID (or null)
7
+ * sel.hoveredId — currently hovered event ID (or null)
8
+ * sel.selectedIds — Set of selected IDs (multi-select)
9
+ * sel.select(id) — select one event (clears multi)
10
+ * sel.toggle(id) — toggle in multi-select
11
+ * sel.clear() — deselect all
12
+ */
13
+ export function createSelection() {
14
+ let selectedId = $state(null);
15
+ let hoveredId = $state(null);
16
+ let selectedIds = $state(new Set());
17
+ return {
18
+ get selectedId() {
19
+ return selectedId;
20
+ },
21
+ get hoveredId() {
22
+ return hoveredId;
23
+ },
24
+ get selectedIds() {
25
+ return selectedIds;
26
+ },
27
+ select(id) {
28
+ selectedId = id;
29
+ selectedIds = new Set([id]);
30
+ },
31
+ deselect() {
32
+ selectedId = null;
33
+ selectedIds = new Set();
34
+ },
35
+ toggle(id) {
36
+ const next = new Set(selectedIds);
37
+ if (next.has(id)) {
38
+ next.delete(id);
39
+ }
40
+ else {
41
+ next.add(id);
42
+ }
43
+ selectedIds = next;
44
+ selectedId = next.size === 1 ? [...next][0] : null;
45
+ },
46
+ clear() {
47
+ selectedId = null;
48
+ hoveredId = null;
49
+ selectedIds = new Set();
50
+ },
51
+ hover(id) {
52
+ hoveredId = id;
53
+ },
54
+ isSelected(id) {
55
+ return selectedIds.has(id);
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,24 @@
1
+ /** All registered view IDs. Add new ones here as variants are created. */
2
+ export type CalendarViewId = 'day-grid' | 'day-agenda' | 'week-grid' | 'week-agenda' | 'week-heatmap';
3
+ export type ViewGranularity = 'day' | 'week';
4
+ export interface ViewStateOptions {
5
+ defaultView?: CalendarViewId;
6
+ mondayStart?: boolean;
7
+ }
8
+ export interface DateRange {
9
+ start: Date;
10
+ end: Date;
11
+ }
12
+ export interface ViewState {
13
+ readonly view: CalendarViewId;
14
+ readonly focusDate: Date;
15
+ readonly range: DateRange;
16
+ readonly granularity: ViewGranularity;
17
+ readonly mondayStart: boolean;
18
+ setView(id: CalendarViewId): void;
19
+ setFocusDate(date: Date): void;
20
+ next(): void;
21
+ prev(): void;
22
+ goToday(): void;
23
+ }
24
+ export declare function createViewState(options?: ViewStateOptions): ViewState;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Reactive view state — tracks which view is active, the current date range,
3
+ * and navigation (prev/next/today).
4
+ *
5
+ * Usage:
6
+ * const vs = createViewState({ defaultView: 'week-terrain' });
7
+ * vs.view — current view id
8
+ * vs.focusDate — the center date
9
+ * vs.range — { start, end } for the current view window
10
+ * vs.next() — advance one period (day/week depending on view)
11
+ * vs.prev() — go back one period
12
+ * vs.goToday() — jump to today
13
+ */
14
+ import { startOfWeek as calcStartOfWeek, addDaysMs, DAY_MS } from '../core/time.js';
15
+ function granularityFor(view) {
16
+ if (view.startsWith('day'))
17
+ return 'day';
18
+ return 'week';
19
+ }
20
+ function computeRange(focus, granularity, mondayStart) {
21
+ if (granularity === 'day') {
22
+ const start = new Date(focus);
23
+ start.setHours(0, 0, 0, 0);
24
+ const end = new Date(start.getTime() + DAY_MS);
25
+ return { start, end };
26
+ }
27
+ // week
28
+ const ws = calcStartOfWeek(focus.getTime(), mondayStart);
29
+ return {
30
+ start: new Date(ws),
31
+ end: new Date(addDaysMs(ws, 7)),
32
+ };
33
+ }
34
+ export function createViewState(options = {}) {
35
+ let view = $state(options.defaultView ?? 'week-grid');
36
+ let focusDate = $state(new Date());
37
+ let mondayStart = $state(options.mondayStart ?? true);
38
+ const granularity = $derived(granularityFor(view));
39
+ const range = $derived(computeRange(focusDate, granularity, mondayStart));
40
+ return {
41
+ get view() {
42
+ return view;
43
+ },
44
+ get focusDate() {
45
+ return focusDate;
46
+ },
47
+ get range() {
48
+ return range;
49
+ },
50
+ get granularity() {
51
+ return granularity;
52
+ },
53
+ get mondayStart() {
54
+ return mondayStart;
55
+ },
56
+ setView(id) {
57
+ view = id;
58
+ },
59
+ setFocusDate(date) {
60
+ focusDate = date;
61
+ },
62
+ next() {
63
+ const days = granularity === 'day' ? 1 : 7;
64
+ focusDate = new Date(addDaysMs(focusDate.getTime(), days));
65
+ },
66
+ prev() {
67
+ const days = granularity === 'day' ? -1 : -7;
68
+ focusDate = new Date(addDaysMs(focusDate.getTime(), days));
69
+ },
70
+ goToday() {
71
+ focusDate = new Date();
72
+ },
73
+ };
74
+ }
@@ -0,0 +1,13 @@
1
+ export { DayGrid, DayTimeline, WeekGrid, WeekHeatmap, Agenda, Settings, } from './views/index.js';
2
+ export type { SettingsField } from './views/index.js';
3
+ export { NowIndicator, EventBlock, TimeGutter, DayHeader, EmptySlot, } from './primitives/index.js';
4
+ export { Calendar, Toolbar } from './calendar/index.js';
5
+ export type { CalendarView } from './calendar/index.js';
6
+ export { createEventStore, createViewState, createSelection, createDragState, } from './engine/index.js';
7
+ export type { EventStore, ViewState, ViewStateOptions, CalendarViewId, ViewGranularity, ViewDateRange, Selection, DragState, DragMode, DragPayload, } from './engine/index.js';
8
+ export { createMemoryAdapter, createRestAdapter } from './adapters/index.js';
9
+ export type { CalendarAdapter, DateRange, RestAdapterOptions } from './adapters/index.js';
10
+ export { createClock, DAY_MS, HOUR_MS, HOURS, sod, startOfWeek, addDaysMs, diffDays, pad, fractionalHour, fmtHM, fmtS, dayNum, dayOfWeek, fmtH, weekdayShort, weekdayLong, monthShort, monthLong, dateShort, dateWithWeekday, fmtDay, fmtWeekRange, setDefaultLocale, getDefaultLocale, timeToX, } from './core/index.js';
11
+ export type { Clock, TimelineEvent, WeekTimelineProps, DayTimelineProps, } from './core/index.js';
12
+ export { midnight, parchment, indigo, presets, stageBg } from './theme/index.js';
13
+ export type { PresetName } from './theme/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ // ─── Views ──────────────────────────────────────────────
2
+ export { DayGrid, DayTimeline, WeekGrid, WeekHeatmap, Agenda, Settings, } from './views/index.js';
3
+ // ─── Primitives ─────────────────────────────────────────
4
+ export { NowIndicator, EventBlock, TimeGutter, DayHeader, EmptySlot, } from './primitives/index.js';
5
+ // ─── Calendar shell ─────────────────────────────────────
6
+ export { Calendar, Toolbar } from './calendar/index.js';
7
+ // ─── Engine (reactive state) ────────────────────────────
8
+ export { createEventStore, createViewState, createSelection, createDragState, } from './engine/index.js';
9
+ // ─── Adapters ───────────────────────────────────────────
10
+ export { createMemoryAdapter, createRestAdapter } from './adapters/index.js';
11
+ // ─── Core: clock, time, locale, types ───────────────────
12
+ export { createClock, DAY_MS, HOUR_MS, HOURS, sod, startOfWeek, addDaysMs, diffDays, pad, fractionalHour, fmtHM, fmtS, dayNum, dayOfWeek, fmtH, weekdayShort, weekdayLong, monthShort, monthLong, dateShort, dateWithWeekday, fmtDay, fmtWeekRange, setDefaultLocale, getDefaultLocale, timeToX, } from './core/index.js';
13
+ // ─── Themes ─────────────────────────────────────────────
14
+ export { midnight, parchment, indigo, presets, stageBg } from './theme/index.js';