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