@nomideusz/svelte-calendar 0.3.1 → 0.5.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.
Files changed (75) hide show
  1. package/README.md +193 -406
  2. package/dist/adapters/recurring.d.ts +45 -8
  3. package/dist/adapters/recurring.js +227 -49
  4. package/dist/adapters/rest.js +6 -1
  5. package/dist/calendar/Calendar.svelte +137 -29
  6. package/dist/calendar/Calendar.svelte.d.ts +10 -8
  7. package/dist/calendar/index.d.ts +0 -1
  8. package/dist/calendar/index.js +0 -1
  9. package/dist/core/index.d.ts +5 -4
  10. package/dist/core/index.js +2 -3
  11. package/dist/core/locale.d.ts +74 -0
  12. package/dist/core/locale.js +96 -4
  13. package/dist/core/time.d.ts +30 -0
  14. package/dist/core/time.js +42 -0
  15. package/dist/core/types.d.ts +1 -72
  16. package/dist/core/types.js +1 -8
  17. package/dist/engine/event-store.svelte.js +2 -2
  18. package/dist/engine/index.d.ts +1 -1
  19. package/dist/engine/view-state.svelte.d.ts +12 -6
  20. package/dist/engine/view-state.svelte.js +8 -4
  21. package/dist/index.d.ts +6 -7
  22. package/dist/index.js +4 -4
  23. package/dist/primitives/EmptySlot.svelte +6 -16
  24. package/dist/primitives/EventBlock.svelte +6 -19
  25. package/dist/primitives/NowIndicator.svelte +7 -4
  26. package/dist/primitives/TimeGutter.svelte +1 -1
  27. package/dist/theme/index.d.ts +1 -1
  28. package/dist/theme/index.js +1 -1
  29. package/dist/theme/presets.d.ts +11 -19
  30. package/dist/theme/presets.js +25 -111
  31. package/dist/views/agenda/Agenda.svelte +17 -1514
  32. package/dist/views/agenda/Agenda.svelte.d.ts +0 -13
  33. package/dist/views/agenda/AgendaDay.svelte +976 -0
  34. package/dist/views/agenda/AgendaDay.svelte.d.ts +14 -0
  35. package/dist/views/agenda/AgendaWeek.svelte +775 -0
  36. package/dist/views/agenda/AgendaWeek.svelte.d.ts +15 -0
  37. package/dist/views/agenda/index.d.ts +2 -0
  38. package/dist/views/agenda/index.js +2 -0
  39. package/dist/views/index.d.ts +2 -6
  40. package/dist/views/index.js +2 -6
  41. package/dist/views/planner/Planner.svelte +17 -0
  42. package/dist/views/planner/Planner.svelte.d.ts +7 -0
  43. package/dist/views/planner/PlannerDay.svelte +957 -0
  44. package/dist/views/{day/DayGrid.svelte.d.ts → planner/PlannerDay.svelte.d.ts} +8 -16
  45. package/dist/views/planner/PlannerWeek.svelte +826 -0
  46. package/dist/views/{week/WeekGrid.svelte.d.ts → planner/PlannerWeek.svelte.d.ts} +5 -9
  47. package/dist/views/planner/index.d.ts +1 -0
  48. package/dist/views/planner/index.js +1 -0
  49. package/dist/widget/CalendarWidget.svelte +54 -35
  50. package/dist/widget/CalendarWidget.svelte.d.ts +1 -1
  51. package/dist/widget/widget.d.ts +1 -7
  52. package/dist/widget/widget.js +44 -3
  53. package/package.json +5 -2
  54. package/widget/svelte-calendar.css +1 -0
  55. package/widget/widget.js +6 -144
  56. package/dist/calendar/Toolbar.svelte +0 -241
  57. package/dist/calendar/Toolbar.svelte.d.ts +0 -19
  58. package/dist/views/day/DayGrid.svelte +0 -1101
  59. package/dist/views/day/DayTimeline.svelte +0 -532
  60. package/dist/views/day/DayTimeline.svelte.d.ts +0 -4
  61. package/dist/views/day/index.d.ts +0 -2
  62. package/dist/views/day/index.js +0 -2
  63. package/dist/views/schedule/WeekSchedule.svelte +0 -133
  64. package/dist/views/schedule/WeekSchedule.svelte.d.ts +0 -38
  65. package/dist/views/schedule/index.d.ts +0 -1
  66. package/dist/views/schedule/index.js +0 -2
  67. package/dist/views/settings/Settings.svelte +0 -307
  68. package/dist/views/settings/Settings.svelte.d.ts +0 -23
  69. package/dist/views/settings/index.d.ts +0 -2
  70. package/dist/views/settings/index.js +0 -1
  71. package/dist/views/week/WeekGrid.svelte +0 -631
  72. package/dist/views/week/WeekHeatmap.svelte +0 -460
  73. package/dist/views/week/WeekHeatmap.svelte.d.ts +0 -8
  74. package/dist/views/week/index.d.ts +0 -2
  75. package/dist/views/week/index.js +0 -2
@@ -1,241 +0,0 @@
1
- <!--
2
- Toolbar — navigation + granularity toggle + concept switcher.
3
-
4
- Layout: [← Today →] date-label [links] [Day | Week] [concept pills]
5
- -->
6
- <script lang="ts">
7
- import type { CalendarViewId, ViewState } from '../engine/view-state.svelte.js';
8
- import { fmtDay, fmtWeekRange, weekdayLong } from '../core/locale.js';
9
-
10
- interface ViewOption {
11
- id: CalendarViewId;
12
- label: string;
13
- granularity: 'day' | 'week';
14
- }
15
-
16
- interface Props {
17
- viewState: ViewState;
18
- /** All registered views */
19
- views?: ViewOption[];
20
- /** Links to show in the toolbar */
21
- links?: { href: string; label: string }[];
22
- }
23
-
24
- let {
25
- viewState,
26
- views = [],
27
- links = [],
28
- }: Props = $props();
29
-
30
- const dateLabel = $derived(() => {
31
- if (viewState.granularity === 'day') {
32
- return `${weekdayLong(viewState.focusDate.getTime())}, ${fmtDay(viewState.focusDate.getTime(), Date.now())}`;
33
- }
34
- const ws = viewState.range.start.getTime();
35
- return fmtWeekRange(ws);
36
- });
37
-
38
- // Which granularities are available?
39
- const granularities = $derived(() => {
40
- const g = new Set(views.map((v) => v.granularity));
41
- return [...g] as ('day' | 'week')[];
42
- });
43
-
44
- // Concepts available for current granularity
45
- const concepts = $derived(
46
- views.filter((v) => v.granularity === viewState.granularity),
47
- );
48
- </script>
49
-
50
- <nav class="tb" aria-label="Calendar navigation">
51
- <!-- Nav: ← Today → -->
52
- <div class="tb-nav">
53
- <button class="tb-btn" onclick={() => viewState.prev()} aria-label="Previous">
54
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
55
- <path d="M10 3L5 8L10 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
56
- </svg>
57
- </button>
58
- <button class="tb-btn tb-today" onclick={() => viewState.goToday()}>Today</button>
59
- <button class="tb-btn" onclick={() => viewState.next()} aria-label="Next">
60
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
61
- <path d="M6 3L11 8L6 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
62
- </svg>
63
- </button>
64
- </div>
65
-
66
- <!-- Date label -->
67
- <span class="tb-label">{dateLabel()}</span>
68
-
69
- <!-- Links -->
70
- {#if links.length > 0}
71
- <div class="tb-links">
72
- {#each links as link}
73
- <a class="tb-link" href={link.href}>{link.label}</a>
74
- {/each}
75
- </div>
76
- {/if}
77
-
78
- <!-- Granularity toggle: Day / Week -->
79
- {#if granularities().length > 1}
80
- <div class="tb-group">
81
- {#each granularities() as g}
82
- <button
83
- class="tb-seg"
84
- class:tb-seg-active={viewState.granularity === g}
85
- onclick={() => {
86
- // Preserve concept: find the view in target granularity with same label
87
- const currentLabel = views.find((v) => v.id === viewState.view)?.label;
88
- const match = views.find((v) => v.granularity === g && v.label === currentLabel);
89
- const fallback = views.find((v) => v.granularity === g);
90
- const target = match ?? fallback;
91
- if (target) viewState.setView(target.id);
92
- }}
93
- >
94
- {g === 'day' ? 'Day' : 'Week'}
95
- </button>
96
- {/each}
97
- </div>
98
- {/if}
99
-
100
- <!-- Concept pills -->
101
- {#if concepts.length > 1}
102
- <div class="tb-concepts">
103
- {#each concepts as c}
104
- <button
105
- class="tb-pill"
106
- class:tb-pill-active={viewState.view === c.id}
107
- onclick={() => viewState.setView(c.id)}
108
- >
109
- {c.label}
110
- </button>
111
- {/each}
112
- </div>
113
- {/if}
114
- </nav>
115
-
116
- <style>
117
- .tb {
118
- display: flex;
119
- align-items: center;
120
- gap: 10px;
121
- padding: 8px 12px;
122
- background: var(--dt-surface, #10141c);
123
- border-bottom: 1px solid var(--dt-border, rgba(148, 163, 184, 0.07));
124
- border-radius: 10px 10px 0 0;
125
- flex-wrap: wrap;
126
- }
127
-
128
- .tb-nav {
129
- display: flex;
130
- align-items: center;
131
- gap: 4px;
132
- }
133
-
134
- .tb-btn {
135
- display: flex;
136
- align-items: center;
137
- justify-content: center;
138
- border: none;
139
- background: transparent;
140
- color: var(--dt-text-2, rgba(148, 163, 184, 0.55));
141
- cursor: pointer;
142
- padding: 4px 6px;
143
- border-radius: 6px;
144
- font: 500 11px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
145
- transition: background 100ms, color 100ms;
146
- }
147
- .tb-btn:hover {
148
- background: var(--dt-accent-dim, rgba(239, 68, 68, 0.18));
149
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
150
- }
151
-
152
- .tb-today {
153
- padding: 4px 10px;
154
- border: 1px solid var(--dt-border, rgba(148, 163, 184, 0.07));
155
- }
156
-
157
- .tb-label {
158
- font: 500 13px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
159
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
160
- letter-spacing: 0.01em;
161
- flex: 1;
162
- min-width: 0;
163
- }
164
-
165
- /* ── Links ── */
166
- .tb-links {
167
- display: flex;
168
- gap: 6px;
169
- }
170
- .tb-link {
171
- font: 400 10px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
172
- color: var(--dt-text-2, rgba(148, 163, 184, 0.55));
173
- border: 1px solid var(--dt-border, rgba(148, 163, 184, 0.07));
174
- padding: 4px 8px;
175
- border-radius: 5px;
176
- text-decoration: none;
177
- transition: color 100ms, border-color 100ms;
178
- }
179
- .tb-link:hover {
180
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
181
- border-color: var(--dt-text-2, rgba(148, 163, 184, 0.25));
182
- }
183
-
184
- /* ── Granularity toggle ── */
185
- .tb-group {
186
- display: flex;
187
- gap: 2px;
188
- background: var(--dt-bg, #0b0e14);
189
- border-radius: 6px;
190
- padding: 2px;
191
- }
192
-
193
- .tb-seg {
194
- border: none;
195
- background: transparent;
196
- color: var(--dt-text-2, rgba(148, 163, 184, 0.55));
197
- cursor: pointer;
198
- font: 600 10px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
199
- padding: 5px 12px;
200
- border-radius: 4px;
201
- letter-spacing: 0.04em;
202
- text-transform: uppercase;
203
- transition: background 100ms, color 100ms;
204
- }
205
- .tb-seg:hover {
206
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
207
- }
208
- .tb-seg-active {
209
- background: var(--dt-accent, #ef4444);
210
- color: var(--dt-btn-text, #fff);
211
- }
212
-
213
- /* ── Concept pills ── */
214
- .tb-concepts {
215
- display: flex;
216
- gap: 3px;
217
- background: var(--dt-bg, #0b0e14);
218
- border-radius: 6px;
219
- padding: 2px;
220
- }
221
-
222
- .tb-pill {
223
- border: none;
224
- background: transparent;
225
- color: var(--dt-text-2, rgba(148, 163, 184, 0.55));
226
- cursor: pointer;
227
- font: 400 10px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
228
- padding: 4px 9px;
229
- border-radius: 4px;
230
- letter-spacing: 0.02em;
231
- transition: background 100ms, color 100ms;
232
- white-space: nowrap;
233
- }
234
- .tb-pill:hover {
235
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
236
- }
237
- .tb-pill-active {
238
- background: var(--dt-surface, #10141c);
239
- color: var(--dt-text, rgba(226, 232, 240, 0.85));
240
- }
241
- </style>
@@ -1,19 +0,0 @@
1
- import type { CalendarViewId, ViewState } from '../engine/view-state.svelte.js';
2
- interface ViewOption {
3
- id: CalendarViewId;
4
- label: string;
5
- granularity: 'day' | 'week';
6
- }
7
- interface Props {
8
- viewState: ViewState;
9
- /** All registered views */
10
- views?: ViewOption[];
11
- /** Links to show in the toolbar */
12
- links?: {
13
- href: string;
14
- label: string;
15
- }[];
16
- }
17
- declare const Toolbar: import("svelte").Component<Props, {}, "">;
18
- type Toolbar = ReturnType<typeof Toolbar>;
19
- export default Toolbar;