@nomideusz/svelte-calendar 0.2.2 → 0.3.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.
- package/README.md +207 -6
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +1 -0
- package/dist/adapters/memory.d.ts +7 -1
- package/dist/adapters/memory.js +35 -4
- package/dist/adapters/recurring.d.ts +39 -0
- package/dist/adapters/recurring.js +117 -0
- package/dist/calendar/Calendar.svelte +20 -5
- package/dist/calendar/Calendar.svelte.d.ts +4 -0
- package/dist/core/types.d.ts +4 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/primitives/EmptySlot.svelte +2 -2
- package/dist/primitives/EventBlock.svelte +75 -14
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/presets.d.ts +10 -15
- package/dist/theme/presets.js +5 -11
- package/dist/views/agenda/Agenda.svelte +3 -3
- package/dist/views/day/DayGrid.svelte +5 -0
- package/dist/views/day/DayGrid.svelte.d.ts +5 -0
- package/dist/views/index.d.ts +1 -0
- package/dist/views/index.js +1 -0
- package/dist/views/schedule/WeekSchedule.svelte +133 -0
- package/dist/views/schedule/WeekSchedule.svelte.d.ts +38 -0
- package/dist/views/schedule/index.d.ts +1 -0
- package/dist/views/schedule/index.js +2 -0
- package/dist/views/settings/Settings.svelte +6 -2
- package/dist/views/week/WeekGrid.svelte +7 -2
- package/dist/views/week/WeekGrid.svelte.d.ts +3 -0
- package/dist/views/week/WeekHeatmap.svelte +12 -5
- package/dist/views/week/WeekHeatmap.svelte.d.ts +5 -1
- package/dist/widget/CalendarWidget.svelte +138 -0
- package/dist/widget/CalendarWidget.svelte.d.ts +23 -0
- package/dist/widget/index.d.ts +1 -0
- package/dist/widget/index.js +1 -0
- package/dist/widget/widget.d.ts +7 -0
- package/dist/widget/widget.js +9 -0
- package/package.json +5 -2
- package/widget/widget.js +260 -0
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
|
|
63
63
|
const accentColor = $derived(event.color || 'var(--dt-accent, #ef4444)');
|
|
64
64
|
|
|
65
|
-
const ariaLabel = $derived(() => {
|
|
65
|
+
const ariaLabel = $derived.by(() => {
|
|
66
66
|
const t = event.title;
|
|
67
67
|
const time = `${fmtTime(event.start)} to ${fmtTime(event.end)}`;
|
|
68
68
|
const dur = fmtDuration(event.start, event.end);
|
|
@@ -78,19 +78,7 @@
|
|
|
78
78
|
}
|
|
79
79
|
</script>
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
class="eb eb-{variant}"
|
|
83
|
-
class:eb-active={active}
|
|
84
|
-
class:eb-past={past}
|
|
85
|
-
class:eb-editable={editable}
|
|
86
|
-
style="--eb-color: {accentColor}"
|
|
87
|
-
role={onclick ? 'button' : 'article'}
|
|
88
|
-
tabindex={onclick ? 0 : -1}
|
|
89
|
-
aria-label={ariaLabel()}
|
|
90
|
-
aria-current={active ? 'true' : undefined}
|
|
91
|
-
onclick={() => onclick?.(event)}
|
|
92
|
-
onkeydown={handleKeydown}
|
|
93
|
-
>
|
|
81
|
+
{#snippet content()}
|
|
94
82
|
{#if children}
|
|
95
83
|
{@render children(event)}
|
|
96
84
|
{:else if variant === 'chip'}
|
|
@@ -101,12 +89,22 @@
|
|
|
101
89
|
<div class="eb-stripe"></div>
|
|
102
90
|
<div class="eb-body">
|
|
103
91
|
<span class="eb-title">{event.title}</span>
|
|
92
|
+
{#if event.subtitle}
|
|
93
|
+
<span class="eb-subtitle">{event.subtitle}</span>
|
|
94
|
+
{/if}
|
|
104
95
|
{#if showTime}
|
|
105
96
|
<span class="eb-time">{fmtTime(event.start)} – {fmtTime(event.end)}</span>
|
|
106
97
|
{/if}
|
|
107
98
|
{#if showDuration}
|
|
108
99
|
<span class="eb-dur">{fmtDuration(event.start, event.end)}</span>
|
|
109
100
|
{/if}
|
|
101
|
+
{#if event.tags && event.tags.length > 0}
|
|
102
|
+
<div class="eb-tags">
|
|
103
|
+
{#each event.tags as tag}
|
|
104
|
+
<span class="eb-tag">{tag}</span>
|
|
105
|
+
{/each}
|
|
106
|
+
</div>
|
|
107
|
+
{/if}
|
|
110
108
|
{#if active}<span class="eb-live-badge">now</span>{/if}
|
|
111
109
|
</div>
|
|
112
110
|
{:else}
|
|
@@ -114,12 +112,53 @@
|
|
|
114
112
|
<span class="eb-stripe"></span>
|
|
115
113
|
<span class="eb-time">{fmtTime(event.start)} – {fmtTime(event.end)}</span>
|
|
116
114
|
<span class="eb-title">{event.title}</span>
|
|
115
|
+
{#if event.subtitle}
|
|
116
|
+
<span class="eb-subtitle">{event.subtitle}</span>
|
|
117
|
+
{/if}
|
|
117
118
|
{#if showDuration}
|
|
118
119
|
<span class="eb-dur">{fmtDuration(event.start, event.end)}</span>
|
|
119
120
|
{/if}
|
|
121
|
+
{#if event.tags && event.tags.length > 0}
|
|
122
|
+
<span class="eb-tags">
|
|
123
|
+
{#each event.tags as tag}
|
|
124
|
+
<span class="eb-tag">{tag}</span>
|
|
125
|
+
{/each}
|
|
126
|
+
</span>
|
|
127
|
+
{/if}
|
|
120
128
|
{#if active}<span class="eb-live-badge">now</span>{/if}
|
|
121
129
|
{/if}
|
|
130
|
+
{/snippet}
|
|
131
|
+
|
|
132
|
+
{#if onclick}
|
|
133
|
+
<div
|
|
134
|
+
class="eb eb-{variant}"
|
|
135
|
+
class:eb-active={active}
|
|
136
|
+
class:eb-past={past}
|
|
137
|
+
class:eb-editable={editable}
|
|
138
|
+
style="--eb-color: {accentColor}"
|
|
139
|
+
role="button"
|
|
140
|
+
tabindex="0"
|
|
141
|
+
aria-label={ariaLabel}
|
|
142
|
+
aria-current={active ? 'true' : undefined}
|
|
143
|
+
onclick={() => onclick?.(event)}
|
|
144
|
+
onkeydown={handleKeydown}
|
|
145
|
+
>
|
|
146
|
+
{@render content()}
|
|
147
|
+
</div>
|
|
148
|
+
{:else}
|
|
149
|
+
<div
|
|
150
|
+
class="eb eb-{variant}"
|
|
151
|
+
class:eb-active={active}
|
|
152
|
+
class:eb-past={past}
|
|
153
|
+
class:eb-editable={editable}
|
|
154
|
+
style="--eb-color: {accentColor}"
|
|
155
|
+
role="article"
|
|
156
|
+
aria-label={ariaLabel}
|
|
157
|
+
aria-current={active ? 'true' : undefined}
|
|
158
|
+
>
|
|
159
|
+
{@render content()}
|
|
122
160
|
</div>
|
|
161
|
+
{/if}
|
|
123
162
|
|
|
124
163
|
<style>
|
|
125
164
|
.eb {
|
|
@@ -243,6 +282,28 @@
|
|
|
243
282
|
}
|
|
244
283
|
|
|
245
284
|
/* ── Shared ── */
|
|
285
|
+
.eb-subtitle {
|
|
286
|
+
font: 400 10px / 1.2 var(--dt-sans, 'Outfit', system-ui, sans-serif);
|
|
287
|
+
color: var(--dt-text-2, rgba(148, 163, 184, 0.65));
|
|
288
|
+
overflow: hidden;
|
|
289
|
+
text-overflow: ellipsis;
|
|
290
|
+
white-space: nowrap;
|
|
291
|
+
}
|
|
292
|
+
.eb-tags {
|
|
293
|
+
display: inline-flex;
|
|
294
|
+
flex-wrap: wrap;
|
|
295
|
+
gap: 3px;
|
|
296
|
+
}
|
|
297
|
+
.eb-tag {
|
|
298
|
+
display: inline-block;
|
|
299
|
+
font: 500 8px / 1 var(--dt-sans, 'Outfit', system-ui, sans-serif);
|
|
300
|
+
letter-spacing: 0.04em;
|
|
301
|
+
text-transform: uppercase;
|
|
302
|
+
padding: 2px 5px;
|
|
303
|
+
border-radius: 3px;
|
|
304
|
+
background: color-mix(in srgb, var(--_color) 18%, transparent);
|
|
305
|
+
color: var(--_color);
|
|
306
|
+
}
|
|
246
307
|
.eb-live-badge {
|
|
247
308
|
display: inline-flex;
|
|
248
309
|
align-items: center;
|
package/dist/theme/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { midnight, parchment, indigo, neutral, bare, presets,
|
|
1
|
+
export { midnight, parchment, indigo, neutral, bare, presets, } from './presets.js';
|
|
2
2
|
export type { PresetName } from './presets.js';
|
package/dist/theme/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// ─── Theme barrel export ────────────────────────────────
|
|
2
|
-
export { midnight, parchment, indigo, neutral, bare, presets,
|
|
2
|
+
export { midnight, parchment, indigo, neutral, bare, presets, } from './presets.js';
|
package/dist/theme/presets.d.ts
CHANGED
|
@@ -5,33 +5,28 @@
|
|
|
5
5
|
* Pass to the `style` prop of any timeline component.
|
|
6
6
|
*/
|
|
7
7
|
/** Midnight Industrial — dark charcoal + red accent, tech monitoring */
|
|
8
|
-
export declare const midnight = "\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: rgba(239, 68, 68, 0.02);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-hm-empty: rgba(80, 80, 120, 0.06);\n\t--dt-hm-low: rgba(239, 68, 68, 0.15);\n\t--dt-hm-mid: rgba(239, 68, 68, 0.3);\n\t--dt-hm-high: rgba(239, 68, 68, 0.5);\n\t--dt-hm-max: rgba(239, 68, 68, 0.72);\n";
|
|
8
|
+
export declare const midnight = "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: rgba(239, 68, 68, 0.02);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-hm-empty: rgba(80, 80, 120, 0.06);\n\t--dt-hm-low: rgba(239, 68, 68, 0.15);\n\t--dt-hm-mid: rgba(239, 68, 68, 0.3);\n\t--dt-hm-high: rgba(239, 68, 68, 0.5);\n\t--dt-hm-max: rgba(239, 68, 68, 0.72);\n";
|
|
9
9
|
/** Desert Parchment — warm analog planner, burnt sienna on aged paper */
|
|
10
|
-
export declare const parchment = "\n\t--dt-bg: #f0e9dd;\n\t--dt-surface: #e8dfd0;\n\t--dt-border: rgba(139, 110, 70, 0.12);\n\t--dt-border-day: rgba(139, 110, 70, 0.22);\n\t--dt-text: rgba(55, 40, 22, 0.88);\n\t--dt-text-2: rgba(110, 85, 52, 0.62);\n\t--dt-text-3: rgba(139, 110, 70, 0.42);\n\t--dt-accent: #b85c2f;\n\t--dt-accent-dim: rgba(184, 92, 47, 0.14);\n\t--dt-glow: rgba(184, 92, 47, 0.25);\n\t--dt-today-bg: rgba(184, 92, 47, 0.04);\n\t--dt-btn-text: #fdf6ee;\n\t--dt-scrollbar: rgba(139, 110, 70, 0.15);\n\t--dt-success: rgba(76, 153, 76, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-mono: 'Courier New', 'Courier', monospace;\n\t--dt-sans: 'Outfit', Georgia, serif;\n\t--dt-hm-empty: rgba(139, 110, 70, 0.06);\n\t--dt-hm-low: rgba(184, 92, 47, 0.15);\n\t--dt-hm-mid: rgba(184, 92, 47, 0.3);\n\t--dt-hm-high: rgba(184, 92, 47, 0.5);\n\t--dt-hm-max: rgba(184, 92, 47, 0.72);\n";
|
|
10
|
+
export declare const parchment = "\n\t--dt-stage-bg: #e4dace;\n\t--dt-bg: #f0e9dd;\n\t--dt-surface: #e8dfd0;\n\t--dt-border: rgba(139, 110, 70, 0.12);\n\t--dt-border-day: rgba(139, 110, 70, 0.22);\n\t--dt-text: rgba(55, 40, 22, 0.88);\n\t--dt-text-2: rgba(110, 85, 52, 0.62);\n\t--dt-text-3: rgba(139, 110, 70, 0.42);\n\t--dt-accent: #b85c2f;\n\t--dt-accent-dim: rgba(184, 92, 47, 0.14);\n\t--dt-glow: rgba(184, 92, 47, 0.25);\n\t--dt-today-bg: rgba(184, 92, 47, 0.04);\n\t--dt-btn-text: #fdf6ee;\n\t--dt-scrollbar: rgba(139, 110, 70, 0.15);\n\t--dt-success: rgba(76, 153, 76, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-mono: 'Courier New', 'Courier', monospace;\n\t--dt-sans: 'Outfit', Georgia, serif;\n\t--dt-hm-empty: rgba(139, 110, 70, 0.06);\n\t--dt-hm-low: rgba(184, 92, 47, 0.15);\n\t--dt-hm-mid: rgba(184, 92, 47, 0.3);\n\t--dt-hm-high: rgba(184, 92, 47, 0.5);\n\t--dt-hm-max: rgba(184, 92, 47, 0.72);\n";
|
|
11
11
|
/** Soft Indigo — calm productivity, muted lavender with indigo markers */
|
|
12
|
-
export declare const indigo = "\n\t--dt-bg: #f7f6fc;\n\t--dt-surface: #eeedf8;\n\t--dt-border: rgba(99, 102, 241, 0.08);\n\t--dt-border-day: rgba(99, 102, 241, 0.14);\n\t--dt-text: rgba(30, 27, 55, 0.82);\n\t--dt-text-2: rgba(75, 70, 120, 0.55);\n\t--dt-text-3: rgba(99, 102, 241, 0.3);\n\t--dt-accent: #6366f1;\n\t--dt-accent-dim: rgba(99, 102, 241, 0.12);\n\t--dt-glow: rgba(99, 102, 241, 0.25);\n\t--dt-today-bg: rgba(99, 102, 241, 0.03);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(99, 102, 241, 0.1);\n\t--dt-success: rgba(34, 197, 94, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-sans: 'Outfit', system-ui, sans-serif;\n\t--dt-hm-empty: rgba(99, 102, 241, 0.04);\n\t--dt-hm-low: rgba(99, 102, 241, 0.12);\n\t--dt-hm-mid: rgba(99, 102, 241, 0.28);\n\t--dt-hm-high: rgba(99, 102, 241, 0.48);\n\t--dt-hm-max: rgba(99, 102, 241, 0.7);\n";
|
|
12
|
+
export declare const indigo = "\n\t--dt-stage-bg: #efedf8;\n\t--dt-bg: #f7f6fc;\n\t--dt-surface: #eeedf8;\n\t--dt-border: rgba(99, 102, 241, 0.08);\n\t--dt-border-day: rgba(99, 102, 241, 0.14);\n\t--dt-text: rgba(30, 27, 55, 0.82);\n\t--dt-text-2: rgba(75, 70, 120, 0.55);\n\t--dt-text-3: rgba(99, 102, 241, 0.3);\n\t--dt-accent: #6366f1;\n\t--dt-accent-dim: rgba(99, 102, 241, 0.12);\n\t--dt-glow: rgba(99, 102, 241, 0.25);\n\t--dt-today-bg: rgba(99, 102, 241, 0.03);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(99, 102, 241, 0.1);\n\t--dt-success: rgba(34, 197, 94, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-sans: 'Outfit', system-ui, sans-serif;\n\t--dt-hm-empty: rgba(99, 102, 241, 0.04);\n\t--dt-hm-low: rgba(99, 102, 241, 0.12);\n\t--dt-hm-mid: rgba(99, 102, 241, 0.28);\n\t--dt-hm-high: rgba(99, 102, 241, 0.48);\n\t--dt-hm-max: rgba(99, 102, 241, 0.7);\n";
|
|
13
13
|
/**
|
|
14
14
|
* Neutral — inherits fonts from host page, uses standard grays + safe blue accent.
|
|
15
15
|
* Drop-in preset that blends into any website without fighting its design.
|
|
16
16
|
*/
|
|
17
|
-
export declare const neutral = "\n\t--dt-bg: #ffffff;\n\t--dt-surface: #f9fafb;\n\t--dt-border: rgba(0, 0, 0, 0.08);\n\t--dt-border-day: rgba(0, 0, 0, 0.14);\n\t--dt-text: rgba(0, 0, 0, 0.87);\n\t--dt-text-2: rgba(0, 0, 0, 0.54);\n\t--dt-text-3: rgba(0, 0, 0, 0.38);\n\t--dt-accent: #2563eb;\n\t--dt-accent-dim: rgba(37, 99, 235, 0.12);\n\t--dt-glow: rgba(37, 99, 235, 0.25);\n\t--dt-today-bg: rgba(37, 99, 235, 0.04);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(0, 0, 0, 0.1);\n\t--dt-success: rgba(22, 163, 74, 0.7);\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n\t--dt-hm-empty: rgba(0, 0, 0, 0.03);\n\t--dt-hm-low: rgba(37, 99, 235, 0.12);\n\t--dt-hm-mid: rgba(37, 99, 235, 0.28);\n\t--dt-hm-high: rgba(37, 99, 235, 0.48);\n\t--dt-hm-max: rgba(37, 99, 235, 0.7);\n";
|
|
17
|
+
export declare const neutral = "\n\t--dt-stage-bg: #ffffff;\n\t--dt-bg: #ffffff;\n\t--dt-surface: #f9fafb;\n\t--dt-border: rgba(0, 0, 0, 0.08);\n\t--dt-border-day: rgba(0, 0, 0, 0.14);\n\t--dt-text: rgba(0, 0, 0, 0.87);\n\t--dt-text-2: rgba(0, 0, 0, 0.54);\n\t--dt-text-3: rgba(0, 0, 0, 0.38);\n\t--dt-accent: #2563eb;\n\t--dt-accent-dim: rgba(37, 99, 235, 0.12);\n\t--dt-glow: rgba(37, 99, 235, 0.25);\n\t--dt-today-bg: rgba(37, 99, 235, 0.04);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(0, 0, 0, 0.1);\n\t--dt-success: rgba(22, 163, 74, 0.7);\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n\t--dt-hm-empty: rgba(0, 0, 0, 0.03);\n\t--dt-hm-low: rgba(37, 99, 235, 0.12);\n\t--dt-hm-mid: rgba(37, 99, 235, 0.28);\n\t--dt-hm-high: rgba(37, 99, 235, 0.48);\n\t--dt-hm-max: rgba(37, 99, 235, 0.7);\n";
|
|
18
18
|
/**
|
|
19
19
|
* Bare — transparent skeleton that inherits everything from the host page.
|
|
20
20
|
* All colors use currentColor/transparent/inherit so the calendar fully absorbs
|
|
21
21
|
* the parent site's design. Override individual --dt-* tokens as needed.
|
|
22
22
|
*/
|
|
23
|
-
export declare const bare = "\n\t--dt-bg: transparent;\n\t--dt-surface: transparent;\n\t--dt-border: currentColor;\n\t--dt-border-day: currentColor;\n\t--dt-text: inherit;\n\t--dt-text-2: inherit;\n\t--dt-text-3: inherit;\n\t--dt-accent: currentColor;\n\t--dt-accent-dim: transparent;\n\t--dt-glow: transparent;\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: inherit;\n\t--dt-scrollbar: currentColor;\n\t--dt-success: currentColor;\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: inherit;\n\t--dt-hm-empty: transparent;\n\t--dt-hm-low: currentColor;\n\t--dt-hm-mid: currentColor;\n\t--dt-hm-high: currentColor;\n\t--dt-hm-max: currentColor;\n";
|
|
23
|
+
export declare const bare = "\n\t--dt-stage-bg: transparent;\n\t--dt-bg: transparent;\n\t--dt-surface: transparent;\n\t--dt-border: currentColor;\n\t--dt-border-day: currentColor;\n\t--dt-text: inherit;\n\t--dt-text-2: inherit;\n\t--dt-text-3: inherit;\n\t--dt-accent: currentColor;\n\t--dt-accent-dim: transparent;\n\t--dt-glow: transparent;\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: inherit;\n\t--dt-scrollbar: currentColor;\n\t--dt-success: currentColor;\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: inherit;\n\t--dt-hm-empty: transparent;\n\t--dt-hm-low: currentColor;\n\t--dt-hm-mid: currentColor;\n\t--dt-hm-high: currentColor;\n\t--dt-hm-max: currentColor;\n";
|
|
24
24
|
/** All available presets keyed by name */
|
|
25
25
|
export declare const presets: {
|
|
26
|
-
readonly midnight: "\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: rgba(239, 68, 68, 0.02);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-hm-empty: rgba(80, 80, 120, 0.06);\n\t--dt-hm-low: rgba(239, 68, 68, 0.15);\n\t--dt-hm-mid: rgba(239, 68, 68, 0.3);\n\t--dt-hm-high: rgba(239, 68, 68, 0.5);\n\t--dt-hm-max: rgba(239, 68, 68, 0.72);\n";
|
|
27
|
-
readonly parchment: "\n\t--dt-bg: #f0e9dd;\n\t--dt-surface: #e8dfd0;\n\t--dt-border: rgba(139, 110, 70, 0.12);\n\t--dt-border-day: rgba(139, 110, 70, 0.22);\n\t--dt-text: rgba(55, 40, 22, 0.88);\n\t--dt-text-2: rgba(110, 85, 52, 0.62);\n\t--dt-text-3: rgba(139, 110, 70, 0.42);\n\t--dt-accent: #b85c2f;\n\t--dt-accent-dim: rgba(184, 92, 47, 0.14);\n\t--dt-glow: rgba(184, 92, 47, 0.25);\n\t--dt-today-bg: rgba(184, 92, 47, 0.04);\n\t--dt-btn-text: #fdf6ee;\n\t--dt-scrollbar: rgba(139, 110, 70, 0.15);\n\t--dt-success: rgba(76, 153, 76, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-mono: 'Courier New', 'Courier', monospace;\n\t--dt-sans: 'Outfit', Georgia, serif;\n\t--dt-hm-empty: rgba(139, 110, 70, 0.06);\n\t--dt-hm-low: rgba(184, 92, 47, 0.15);\n\t--dt-hm-mid: rgba(184, 92, 47, 0.3);\n\t--dt-hm-high: rgba(184, 92, 47, 0.5);\n\t--dt-hm-max: rgba(184, 92, 47, 0.72);\n";
|
|
28
|
-
readonly indigo: "\n\t--dt-bg: #f7f6fc;\n\t--dt-surface: #eeedf8;\n\t--dt-border: rgba(99, 102, 241, 0.08);\n\t--dt-border-day: rgba(99, 102, 241, 0.14);\n\t--dt-text: rgba(30, 27, 55, 0.82);\n\t--dt-text-2: rgba(75, 70, 120, 0.55);\n\t--dt-text-3: rgba(99, 102, 241, 0.3);\n\t--dt-accent: #6366f1;\n\t--dt-accent-dim: rgba(99, 102, 241, 0.12);\n\t--dt-glow: rgba(99, 102, 241, 0.25);\n\t--dt-today-bg: rgba(99, 102, 241, 0.03);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(99, 102, 241, 0.1);\n\t--dt-success: rgba(34, 197, 94, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-sans: 'Outfit', system-ui, sans-serif;\n\t--dt-hm-empty: rgba(99, 102, 241, 0.04);\n\t--dt-hm-low: rgba(99, 102, 241, 0.12);\n\t--dt-hm-mid: rgba(99, 102, 241, 0.28);\n\t--dt-hm-high: rgba(99, 102, 241, 0.48);\n\t--dt-hm-max: rgba(99, 102, 241, 0.7);\n";
|
|
29
|
-
readonly neutral: "\n\t--dt-bg: #ffffff;\n\t--dt-surface: #f9fafb;\n\t--dt-border: rgba(0, 0, 0, 0.08);\n\t--dt-border-day: rgba(0, 0, 0, 0.14);\n\t--dt-text: rgba(0, 0, 0, 0.87);\n\t--dt-text-2: rgba(0, 0, 0, 0.54);\n\t--dt-text-3: rgba(0, 0, 0, 0.38);\n\t--dt-accent: #2563eb;\n\t--dt-accent-dim: rgba(37, 99, 235, 0.12);\n\t--dt-glow: rgba(37, 99, 235, 0.25);\n\t--dt-today-bg: rgba(37, 99, 235, 0.04);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(0, 0, 0, 0.1);\n\t--dt-success: rgba(22, 163, 74, 0.7);\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n\t--dt-hm-empty: rgba(0, 0, 0, 0.03);\n\t--dt-hm-low: rgba(37, 99, 235, 0.12);\n\t--dt-hm-mid: rgba(37, 99, 235, 0.28);\n\t--dt-hm-high: rgba(37, 99, 235, 0.48);\n\t--dt-hm-max: rgba(37, 99, 235, 0.7);\n";
|
|
30
|
-
readonly bare: "\n\t--dt-bg: transparent;\n\t--dt-surface: transparent;\n\t--dt-border: currentColor;\n\t--dt-border-day: currentColor;\n\t--dt-text: inherit;\n\t--dt-text-2: inherit;\n\t--dt-text-3: inherit;\n\t--dt-accent: currentColor;\n\t--dt-accent-dim: transparent;\n\t--dt-glow: transparent;\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: inherit;\n\t--dt-scrollbar: currentColor;\n\t--dt-success: currentColor;\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: inherit;\n\t--dt-hm-empty: transparent;\n\t--dt-hm-low: currentColor;\n\t--dt-hm-mid: currentColor;\n\t--dt-hm-high: currentColor;\n\t--dt-hm-max: currentColor;\n";
|
|
26
|
+
readonly midnight: "\n\t--dt-stage-bg: #080a0f;\n\t--dt-bg: #0b0e14;\n\t--dt-surface: #10141c;\n\t--dt-border: rgba(148, 163, 184, 0.07);\n\t--dt-border-day: rgba(148, 163, 184, 0.14);\n\t--dt-text: rgba(226, 232, 240, 0.85);\n\t--dt-text-2: rgba(148, 163, 184, 0.55);\n\t--dt-text-3: rgba(100, 116, 139, 0.55);\n\t--dt-accent: #ef4444;\n\t--dt-accent-dim: rgba(239, 68, 68, 0.18);\n\t--dt-glow: rgba(239, 68, 68, 0.35);\n\t--dt-today-bg: rgba(239, 68, 68, 0.02);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(148, 163, 184, 0.12);\n\t--dt-success: rgba(74, 222, 128, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-hm-empty: rgba(80, 80, 120, 0.06);\n\t--dt-hm-low: rgba(239, 68, 68, 0.15);\n\t--dt-hm-mid: rgba(239, 68, 68, 0.3);\n\t--dt-hm-high: rgba(239, 68, 68, 0.5);\n\t--dt-hm-max: rgba(239, 68, 68, 0.72);\n";
|
|
27
|
+
readonly parchment: "\n\t--dt-stage-bg: #e4dace;\n\t--dt-bg: #f0e9dd;\n\t--dt-surface: #e8dfd0;\n\t--dt-border: rgba(139, 110, 70, 0.12);\n\t--dt-border-day: rgba(139, 110, 70, 0.22);\n\t--dt-text: rgba(55, 40, 22, 0.88);\n\t--dt-text-2: rgba(110, 85, 52, 0.62);\n\t--dt-text-3: rgba(139, 110, 70, 0.42);\n\t--dt-accent: #b85c2f;\n\t--dt-accent-dim: rgba(184, 92, 47, 0.14);\n\t--dt-glow: rgba(184, 92, 47, 0.25);\n\t--dt-today-bg: rgba(184, 92, 47, 0.04);\n\t--dt-btn-text: #fdf6ee;\n\t--dt-scrollbar: rgba(139, 110, 70, 0.15);\n\t--dt-success: rgba(76, 153, 76, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-mono: 'Courier New', 'Courier', monospace;\n\t--dt-sans: 'Outfit', Georgia, serif;\n\t--dt-hm-empty: rgba(139, 110, 70, 0.06);\n\t--dt-hm-low: rgba(184, 92, 47, 0.15);\n\t--dt-hm-mid: rgba(184, 92, 47, 0.3);\n\t--dt-hm-high: rgba(184, 92, 47, 0.5);\n\t--dt-hm-max: rgba(184, 92, 47, 0.72);\n";
|
|
28
|
+
readonly indigo: "\n\t--dt-stage-bg: #efedf8;\n\t--dt-bg: #f7f6fc;\n\t--dt-surface: #eeedf8;\n\t--dt-border: rgba(99, 102, 241, 0.08);\n\t--dt-border-day: rgba(99, 102, 241, 0.14);\n\t--dt-text: rgba(30, 27, 55, 0.82);\n\t--dt-text-2: rgba(75, 70, 120, 0.55);\n\t--dt-text-3: rgba(99, 102, 241, 0.3);\n\t--dt-accent: #6366f1;\n\t--dt-accent-dim: rgba(99, 102, 241, 0.12);\n\t--dt-glow: rgba(99, 102, 241, 0.25);\n\t--dt-today-bg: rgba(99, 102, 241, 0.03);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(99, 102, 241, 0.1);\n\t--dt-success: rgba(34, 197, 94, 0.7);\n\t--dt-serif: Georgia, 'Times New Roman', serif;\n\t--dt-sans: 'Outfit', system-ui, sans-serif;\n\t--dt-hm-empty: rgba(99, 102, 241, 0.04);\n\t--dt-hm-low: rgba(99, 102, 241, 0.12);\n\t--dt-hm-mid: rgba(99, 102, 241, 0.28);\n\t--dt-hm-high: rgba(99, 102, 241, 0.48);\n\t--dt-hm-max: rgba(99, 102, 241, 0.7);\n";
|
|
29
|
+
readonly neutral: "\n\t--dt-stage-bg: #ffffff;\n\t--dt-bg: #ffffff;\n\t--dt-surface: #f9fafb;\n\t--dt-border: rgba(0, 0, 0, 0.08);\n\t--dt-border-day: rgba(0, 0, 0, 0.14);\n\t--dt-text: rgba(0, 0, 0, 0.87);\n\t--dt-text-2: rgba(0, 0, 0, 0.54);\n\t--dt-text-3: rgba(0, 0, 0, 0.38);\n\t--dt-accent: #2563eb;\n\t--dt-accent-dim: rgba(37, 99, 235, 0.12);\n\t--dt-glow: rgba(37, 99, 235, 0.25);\n\t--dt-today-bg: rgba(37, 99, 235, 0.04);\n\t--dt-btn-text: #fff;\n\t--dt-scrollbar: rgba(0, 0, 0, 0.1);\n\t--dt-success: rgba(22, 163, 74, 0.7);\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: ui-monospace, 'SFMono-Regular', monospace;\n\t--dt-hm-empty: rgba(0, 0, 0, 0.03);\n\t--dt-hm-low: rgba(37, 99, 235, 0.12);\n\t--dt-hm-mid: rgba(37, 99, 235, 0.28);\n\t--dt-hm-high: rgba(37, 99, 235, 0.48);\n\t--dt-hm-max: rgba(37, 99, 235, 0.7);\n";
|
|
30
|
+
readonly bare: "\n\t--dt-stage-bg: transparent;\n\t--dt-bg: transparent;\n\t--dt-surface: transparent;\n\t--dt-border: currentColor;\n\t--dt-border-day: currentColor;\n\t--dt-text: inherit;\n\t--dt-text-2: inherit;\n\t--dt-text-3: inherit;\n\t--dt-accent: currentColor;\n\t--dt-accent-dim: transparent;\n\t--dt-glow: transparent;\n\t--dt-today-bg: transparent;\n\t--dt-btn-text: inherit;\n\t--dt-scrollbar: currentColor;\n\t--dt-success: currentColor;\n\t--dt-serif: inherit;\n\t--dt-sans: inherit;\n\t--dt-mono: inherit;\n\t--dt-hm-empty: transparent;\n\t--dt-hm-low: currentColor;\n\t--dt-hm-mid: currentColor;\n\t--dt-hm-high: currentColor;\n\t--dt-hm-max: currentColor;\n";
|
|
31
31
|
};
|
|
32
32
|
export type PresetName = keyof typeof presets;
|
|
33
|
-
/**
|
|
34
|
-
* Stage background color matching each theme.
|
|
35
|
-
* Useful for the container behind the timeline component.
|
|
36
|
-
*/
|
|
37
|
-
export declare const stageBg: Record<PresetName, string>;
|
package/dist/theme/presets.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
/** Midnight Industrial — dark charcoal + red accent, tech monitoring */
|
|
8
8
|
export const midnight = `
|
|
9
|
+
--dt-stage-bg: #080a0f;
|
|
9
10
|
--dt-bg: #0b0e14;
|
|
10
11
|
--dt-surface: #10141c;
|
|
11
12
|
--dt-border: rgba(148, 163, 184, 0.07);
|
|
@@ -29,6 +30,7 @@ export const midnight = `
|
|
|
29
30
|
`;
|
|
30
31
|
/** Desert Parchment — warm analog planner, burnt sienna on aged paper */
|
|
31
32
|
export const parchment = `
|
|
33
|
+
--dt-stage-bg: #e4dace;
|
|
32
34
|
--dt-bg: #f0e9dd;
|
|
33
35
|
--dt-surface: #e8dfd0;
|
|
34
36
|
--dt-border: rgba(139, 110, 70, 0.12);
|
|
@@ -54,6 +56,7 @@ export const parchment = `
|
|
|
54
56
|
`;
|
|
55
57
|
/** Soft Indigo — calm productivity, muted lavender with indigo markers */
|
|
56
58
|
export const indigo = `
|
|
59
|
+
--dt-stage-bg: #efedf8;
|
|
57
60
|
--dt-bg: #f7f6fc;
|
|
58
61
|
--dt-surface: #eeedf8;
|
|
59
62
|
--dt-border: rgba(99, 102, 241, 0.08);
|
|
@@ -81,6 +84,7 @@ export const indigo = `
|
|
|
81
84
|
* Drop-in preset that blends into any website without fighting its design.
|
|
82
85
|
*/
|
|
83
86
|
export const neutral = `
|
|
87
|
+
--dt-stage-bg: #ffffff;
|
|
84
88
|
--dt-bg: #ffffff;
|
|
85
89
|
--dt-surface: #f9fafb;
|
|
86
90
|
--dt-border: rgba(0, 0, 0, 0.08);
|
|
@@ -110,6 +114,7 @@ export const neutral = `
|
|
|
110
114
|
* the parent site's design. Override individual --dt-* tokens as needed.
|
|
111
115
|
*/
|
|
112
116
|
export const bare = `
|
|
117
|
+
--dt-stage-bg: transparent;
|
|
113
118
|
--dt-bg: transparent;
|
|
114
119
|
--dt-surface: transparent;
|
|
115
120
|
--dt-border: currentColor;
|
|
@@ -135,14 +140,3 @@ export const bare = `
|
|
|
135
140
|
`;
|
|
136
141
|
/** All available presets keyed by name */
|
|
137
142
|
export const presets = { midnight, parchment, indigo, neutral, bare };
|
|
138
|
-
/**
|
|
139
|
-
* Stage background color matching each theme.
|
|
140
|
-
* Useful for the container behind the timeline component.
|
|
141
|
-
*/
|
|
142
|
-
export const stageBg = {
|
|
143
|
-
midnight: '#080a0f',
|
|
144
|
-
parchment: '#e4dace',
|
|
145
|
-
indigo: '#efedf8',
|
|
146
|
-
neutral: '#ffffff',
|
|
147
|
-
bare: 'transparent',
|
|
148
|
-
};
|
|
@@ -754,7 +754,7 @@
|
|
|
754
754
|
transition: width 1s linear;
|
|
755
755
|
}
|
|
756
756
|
|
|
757
|
-
.ag-empty {
|
|
757
|
+
:global(.ag-empty) {
|
|
758
758
|
display: flex;
|
|
759
759
|
align-items: center;
|
|
760
760
|
justify-content: center;
|
|
@@ -880,7 +880,7 @@
|
|
|
880
880
|
color: var(--dt-text-3, rgba(255, 255, 255, 0.25));
|
|
881
881
|
margin-bottom: 2px;
|
|
882
882
|
}
|
|
883
|
-
.ag-q-free-next {
|
|
883
|
+
:global(.ag-q-free-next) {
|
|
884
884
|
font-size: 10px;
|
|
885
885
|
font-weight: 500;
|
|
886
886
|
line-height: 1.2;
|
|
@@ -890,7 +890,7 @@
|
|
|
890
890
|
text-overflow: ellipsis;
|
|
891
891
|
margin-bottom: 2px;
|
|
892
892
|
}
|
|
893
|
-
.ag-q-free-until {
|
|
893
|
+
:global(.ag-q-free-until) {
|
|
894
894
|
font-size: 9px;
|
|
895
895
|
font-family: var(--dt-mono, monospace);
|
|
896
896
|
color: var(--dt-accent, #ff6b4a);
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
selectedEventId?: string | null;
|
|
44
44
|
/** Start weeks on Monday */
|
|
45
45
|
mondayStart?: boolean;
|
|
46
|
+
/** Read-only mode */
|
|
47
|
+
readOnly?: boolean;
|
|
48
|
+
/** Visible hour range [startHour, endHour) — adjusts night collapse */
|
|
49
|
+
visibleHours?: [number, number];
|
|
50
|
+
[key: string]: unknown;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
let {
|
|
@@ -27,6 +27,11 @@ interface Props {
|
|
|
27
27
|
selectedEventId?: string | null;
|
|
28
28
|
/** Start weeks on Monday */
|
|
29
29
|
mondayStart?: boolean;
|
|
30
|
+
/** Read-only mode */
|
|
31
|
+
readOnly?: boolean;
|
|
32
|
+
/** Visible hour range [startHour, endHour) — adjusts night collapse */
|
|
33
|
+
visibleHours?: [number, number];
|
|
34
|
+
[key: string]: unknown;
|
|
30
35
|
}
|
|
31
36
|
declare const DayGrid: import("svelte").Component<Props, {}, "">;
|
|
32
37
|
type DayGrid = ReturnType<typeof DayGrid>;
|
package/dist/views/index.d.ts
CHANGED
package/dist/views/index.js
CHANGED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
WeekSchedule — zero-config weekly schedule display.
|
|
3
|
+
|
|
4
|
+
A convenience wrapper that pre-wires Calendar + WeekGrid + Agenda
|
|
5
|
+
so consumers can render a read-only weekly schedule with a single import.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
<WeekSchedule
|
|
9
|
+
events={events}
|
|
10
|
+
theme={neutral}
|
|
11
|
+
locale="pl-PL"
|
|
12
|
+
height={560}
|
|
13
|
+
readOnly
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
Or with a recurring adapter:
|
|
17
|
+
<WeekSchedule
|
|
18
|
+
schedule={weeklyClasses}
|
|
19
|
+
theme={neutral}
|
|
20
|
+
readOnly
|
|
21
|
+
/>
|
|
22
|
+
-->
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import type { TimelineEvent } from '../../core/types.js';
|
|
25
|
+
import type { RecurringEvent } from '../../adapters/recurring.js';
|
|
26
|
+
import type { MemoryAdapterOptions } from '../../adapters/memory.js';
|
|
27
|
+
import { createMemoryAdapter } from '../../adapters/memory.js';
|
|
28
|
+
import { createRecurringAdapter, type RecurringAdapterOptions } from '../../adapters/recurring.js';
|
|
29
|
+
import Calendar from '../../calendar/Calendar.svelte';
|
|
30
|
+
import type { CalendarView } from '../../calendar/Calendar.svelte';
|
|
31
|
+
import { WeekGrid } from '../week/index.js';
|
|
32
|
+
import { Agenda } from '../agenda/index.js';
|
|
33
|
+
|
|
34
|
+
interface Props {
|
|
35
|
+
/** Concrete events (mutually exclusive with `schedule`) */
|
|
36
|
+
events?: TimelineEvent[];
|
|
37
|
+
/** Recurring weekly schedule (mutually exclusive with `events`) */
|
|
38
|
+
schedule?: RecurringEvent[];
|
|
39
|
+
/** CSS theme string */
|
|
40
|
+
theme?: string;
|
|
41
|
+
/** BCP 47 locale */
|
|
42
|
+
locale?: string;
|
|
43
|
+
/** Total height */
|
|
44
|
+
height?: number;
|
|
45
|
+
/** Start week on Monday */
|
|
46
|
+
mondayStart?: boolean;
|
|
47
|
+
/** Read-only mode (default: true for schedule display) */
|
|
48
|
+
readOnly?: boolean;
|
|
49
|
+
/** Visible hour range [startHour, endHour) */
|
|
50
|
+
visibleHours?: [number, number];
|
|
51
|
+
/** Show toolbar */
|
|
52
|
+
showToolbar?: boolean;
|
|
53
|
+
/** Show agenda view toggle */
|
|
54
|
+
showAgenda?: boolean;
|
|
55
|
+
/** Map of category/title to color */
|
|
56
|
+
colorMap?: Record<string, string>;
|
|
57
|
+
/** Auto-assign colors */
|
|
58
|
+
autoColor?: boolean;
|
|
59
|
+
/** Event click handler */
|
|
60
|
+
oneventclick?: (event: TimelineEvent) => void;
|
|
61
|
+
/** Event create handler (only works when readOnly is false) */
|
|
62
|
+
oneventcreate?: (range: { start: Date; end: Date }) => void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let {
|
|
66
|
+
events,
|
|
67
|
+
schedule,
|
|
68
|
+
theme = '',
|
|
69
|
+
locale,
|
|
70
|
+
height = 560,
|
|
71
|
+
mondayStart = true,
|
|
72
|
+
readOnly = true,
|
|
73
|
+
visibleHours,
|
|
74
|
+
showToolbar = true,
|
|
75
|
+
showAgenda = true,
|
|
76
|
+
colorMap,
|
|
77
|
+
autoColor,
|
|
78
|
+
oneventclick,
|
|
79
|
+
oneventcreate,
|
|
80
|
+
}: Props = $props();
|
|
81
|
+
|
|
82
|
+
// Auto-create the adapter from events or schedule
|
|
83
|
+
const adapter = $derived.by(() => {
|
|
84
|
+
if (schedule) {
|
|
85
|
+
return createRecurringAdapter(schedule, {
|
|
86
|
+
mondayStart,
|
|
87
|
+
colorMap,
|
|
88
|
+
autoColor,
|
|
89
|
+
} satisfies RecurringAdapterOptions);
|
|
90
|
+
}
|
|
91
|
+
return createMemoryAdapter(events ?? [], {
|
|
92
|
+
colorMap,
|
|
93
|
+
autoColor,
|
|
94
|
+
} satisfies MemoryAdapterOptions);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Pre-wired views
|
|
98
|
+
const views = $derived.by((): CalendarView[] => {
|
|
99
|
+
const v: CalendarView[] = [
|
|
100
|
+
{
|
|
101
|
+
id: 'week-grid',
|
|
102
|
+
label: 'Week',
|
|
103
|
+
granularity: 'week',
|
|
104
|
+
component: WeekGrid,
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
if (showAgenda) {
|
|
108
|
+
v.push({
|
|
109
|
+
id: 'agenda',
|
|
110
|
+
label: 'Agenda',
|
|
111
|
+
granularity: 'week',
|
|
112
|
+
component: Agenda,
|
|
113
|
+
props: { mode: 'week' },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return v;
|
|
117
|
+
});
|
|
118
|
+
</script>
|
|
119
|
+
|
|
120
|
+
<Calendar
|
|
121
|
+
{adapter}
|
|
122
|
+
{views}
|
|
123
|
+
defaultView="week-grid"
|
|
124
|
+
{theme}
|
|
125
|
+
{locale}
|
|
126
|
+
{height}
|
|
127
|
+
{mondayStart}
|
|
128
|
+
{readOnly}
|
|
129
|
+
{visibleHours}
|
|
130
|
+
{showToolbar}
|
|
131
|
+
{oneventclick}
|
|
132
|
+
oneventcreate={readOnly ? undefined : oneventcreate}
|
|
133
|
+
/>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TimelineEvent } from '../../core/types.js';
|
|
2
|
+
import type { RecurringEvent } from '../../adapters/recurring.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Concrete events (mutually exclusive with `schedule`) */
|
|
5
|
+
events?: TimelineEvent[];
|
|
6
|
+
/** Recurring weekly schedule (mutually exclusive with `events`) */
|
|
7
|
+
schedule?: RecurringEvent[];
|
|
8
|
+
/** CSS theme string */
|
|
9
|
+
theme?: string;
|
|
10
|
+
/** BCP 47 locale */
|
|
11
|
+
locale?: string;
|
|
12
|
+
/** Total height */
|
|
13
|
+
height?: number;
|
|
14
|
+
/** Start week on Monday */
|
|
15
|
+
mondayStart?: boolean;
|
|
16
|
+
/** Read-only mode (default: true for schedule display) */
|
|
17
|
+
readOnly?: boolean;
|
|
18
|
+
/** Visible hour range [startHour, endHour) */
|
|
19
|
+
visibleHours?: [number, number];
|
|
20
|
+
/** Show toolbar */
|
|
21
|
+
showToolbar?: boolean;
|
|
22
|
+
/** Show agenda view toggle */
|
|
23
|
+
showAgenda?: boolean;
|
|
24
|
+
/** Map of category/title to color */
|
|
25
|
+
colorMap?: Record<string, string>;
|
|
26
|
+
/** Auto-assign colors */
|
|
27
|
+
autoColor?: boolean;
|
|
28
|
+
/** Event click handler */
|
|
29
|
+
oneventclick?: (event: TimelineEvent) => void;
|
|
30
|
+
/** Event create handler (only works when readOnly is false) */
|
|
31
|
+
oneventcreate?: (range: {
|
|
32
|
+
start: Date;
|
|
33
|
+
end: Date;
|
|
34
|
+
}) => void;
|
|
35
|
+
}
|
|
36
|
+
declare const WeekSchedule: import("svelte").Component<Props, {}, "">;
|
|
37
|
+
type WeekSchedule = ReturnType<typeof WeekSchedule>;
|
|
38
|
+
export default WeekSchedule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as WeekSchedule } from './WeekSchedule.svelte';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { slide } from 'svelte/transition';
|
|
3
3
|
import type { PresetName } from '../../theme/presets.js';
|
|
4
|
-
import { presets
|
|
4
|
+
import { presets } from '../../theme/presets.js';
|
|
5
5
|
|
|
6
6
|
/* ─── Field definition types ─────────────────────── */
|
|
7
7
|
type RangeField = {
|
|
@@ -30,16 +30,20 @@
|
|
|
30
30
|
|
|
31
31
|
let { fields, values = $bindable(), theme = $bindable() }: Props = $props();
|
|
32
32
|
|
|
33
|
-
const themeKeys: PresetName[] = ['midnight', 'parchment', 'indigo'];
|
|
33
|
+
const themeKeys: PresetName[] = ['midnight', 'parchment', 'indigo', 'neutral', 'bare'];
|
|
34
34
|
const themeLabels: Record<PresetName, string> = {
|
|
35
35
|
midnight: 'Midnight',
|
|
36
36
|
parchment: 'Parchment',
|
|
37
37
|
indigo: 'Indigo',
|
|
38
|
+
neutral: 'Neutral',
|
|
39
|
+
bare: 'Bare',
|
|
38
40
|
};
|
|
39
41
|
const themeAccents: Record<PresetName, string> = {
|
|
40
42
|
midnight: '#ef4444',
|
|
41
43
|
parchment: '#b85c2f',
|
|
42
44
|
indigo: '#6366f1',
|
|
45
|
+
neutral: '#94a0b4',
|
|
46
|
+
bare: '#94a0b4',
|
|
43
47
|
};
|
|
44
48
|
|
|
45
49
|
let open = $state(true);
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
oneventclick?: (event: TimelineEvent) => void;
|
|
31
31
|
oneventcreate?: (range: { start: Date; end: Date }) => void;
|
|
32
32
|
selectedEventId?: string | null;
|
|
33
|
+
readOnly?: boolean;
|
|
34
|
+
visibleHours?: [number, number];
|
|
35
|
+
[key: string]: unknown;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
let {
|
|
@@ -41,6 +44,8 @@
|
|
|
41
44
|
oneventclick,
|
|
42
45
|
oneventcreate,
|
|
43
46
|
selectedEventId = null,
|
|
47
|
+
readOnly = false,
|
|
48
|
+
...rest
|
|
44
49
|
}: Props = $props();
|
|
45
50
|
|
|
46
51
|
// ── Drag support (available when inside Calendar) ──
|
|
@@ -162,7 +167,7 @@
|
|
|
162
167
|
function handleDayCellClick(ms: number, e: Event) {
|
|
163
168
|
const target = e.target as HTMLElement;
|
|
164
169
|
if (target.closest('.wg-ev')) return;
|
|
165
|
-
if (!oneventcreate) return;
|
|
170
|
+
if (readOnly || !oneventcreate) return;
|
|
166
171
|
const start = new Date(ms + 9 * 3_600_000);
|
|
167
172
|
const end = new Date(ms + 10 * 3_600_000);
|
|
168
173
|
oneventcreate({ start, end });
|
|
@@ -182,7 +187,7 @@
|
|
|
182
187
|
}
|
|
183
188
|
|
|
184
189
|
function onEventPointerDown(e: PointerEvent, ev: TimelineEvent) {
|
|
185
|
-
if (e.button !== 0 || !drag) return;
|
|
190
|
+
if (e.button !== 0 || !drag || readOnly) return;
|
|
186
191
|
e.stopPropagation();
|
|
187
192
|
evDragStartX = e.clientX;
|
|
188
193
|
evDragStarted = false;
|
|
@@ -15,6 +15,9 @@ interface Props {
|
|
|
15
15
|
end: Date;
|
|
16
16
|
}) => void;
|
|
17
17
|
selectedEventId?: string | null;
|
|
18
|
+
readOnly?: boolean;
|
|
19
|
+
visibleHours?: [number, number];
|
|
20
|
+
[key: string]: unknown;
|
|
18
21
|
}
|
|
19
22
|
declare const WeekGrid: import("svelte").Component<Props, {}, "">;
|
|
20
23
|
type WeekGrid = ReturnType<typeof WeekGrid>;
|
|
@@ -27,7 +27,13 @@
|
|
|
27
27
|
focusDate,
|
|
28
28
|
oneventclick,
|
|
29
29
|
selectedEventId = null,
|
|
30
|
-
|
|
30
|
+
visibleHours,
|
|
31
|
+
...rest
|
|
32
|
+
}: WeekTimelineProps & { visibleHours?: [number, number]; [key: string]: unknown } = $props();
|
|
33
|
+
|
|
34
|
+
const startHour = $derived(visibleHours?.[0] ?? 0);
|
|
35
|
+
const endHour = $derived(visibleHours?.[1] ?? 24);
|
|
36
|
+
const visibleHourCount = $derived(endHour - startHour);
|
|
31
37
|
|
|
32
38
|
const clock = createClock();
|
|
33
39
|
|
|
@@ -66,7 +72,7 @@
|
|
|
66
72
|
const isToday = ms === clock.today;
|
|
67
73
|
|
|
68
74
|
const cells: HeatCell[] = [];
|
|
69
|
-
for (let h =
|
|
75
|
+
for (let h = startHour; h < endHour; h++) {
|
|
70
76
|
const cellStart = ms + h * 3600000;
|
|
71
77
|
const cellEnd = cellStart + 3600000;
|
|
72
78
|
const overlaps = events.filter((ev) => ev.start.getTime() < cellEnd && ev.end.getTime() > cellStart);
|
|
@@ -179,9 +185,10 @@
|
|
|
179
185
|
<!-- Hour labels row -->
|
|
180
186
|
<div class="hm-hours-row">
|
|
181
187
|
<div class="hm-row-label"></div>
|
|
182
|
-
{#each Array(
|
|
183
|
-
{
|
|
184
|
-
|
|
188
|
+
{#each Array(visibleHourCount) as _, idx}
|
|
189
|
+
{@const h = startHour + idx}
|
|
190
|
+
{#if (h - startHour) % 3 === 0}
|
|
191
|
+
<span class="hm-hour-mark" style:left="calc({idx} * (100% / {visibleHourCount}))">{fmtH(h)}</span>
|
|
185
192
|
{/if}
|
|
186
193
|
{/each}
|
|
187
194
|
</div>
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { WeekTimelineProps } from '../../core/types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = WeekTimelineProps & {
|
|
3
|
+
visibleHours?: [number, number];
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
};
|
|
6
|
+
declare const WeekHeatmap: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
7
|
type WeekHeatmap = ReturnType<typeof WeekHeatmap>;
|
|
4
8
|
export default WeekHeatmap;
|