@bimetal/calendar-svelte-components 0.29.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/LICENSE +129 -0
- package/dist/binding/config.d.ts +6 -0
- package/dist/binding/config.d.ts.map +1 -0
- package/dist/binding/config.js +5 -0
- package/dist/binding/context.d.ts +31 -0
- package/dist/binding/context.d.ts.map +1 -0
- package/dist/binding/context.js +55 -0
- package/dist/binding/controller.d.ts +24 -0
- package/dist/binding/controller.d.ts.map +1 -0
- package/dist/binding/controller.js +9 -0
- package/dist/binding/index.d.ts +23 -0
- package/dist/binding/index.d.ts.map +1 -0
- package/dist/binding/index.js +24 -0
- package/dist/binding/types.d.ts +95 -0
- package/dist/binding/types.d.ts.map +1 -0
- package/dist/binding/types.js +11 -0
- package/dist/binding/view-configs.d.ts +6 -0
- package/dist/binding/view-configs.d.ts.map +1 -0
- package/dist/binding/view-configs.js +5 -0
- package/dist/components/Calendar.svelte +263 -0
- package/dist/components/Calendar.svelte.d.ts +24 -0
- package/dist/components/Calendar.svelte.d.ts.map +1 -0
- package/dist/components/CalendarHeader.svelte +47 -0
- package/dist/components/CalendarHeader.svelte.d.ts +15 -0
- package/dist/components/CalendarHeader.svelte.d.ts.map +1 -0
- package/dist/components/CategoryFilter.svelte +29 -0
- package/dist/components/CategoryFilter.svelte.d.ts +10 -0
- package/dist/components/CategoryFilter.svelte.d.ts.map +1 -0
- package/dist/components/EventBar.svelte +187 -0
- package/dist/components/EventBar.svelte.d.ts +10 -0
- package/dist/components/EventBar.svelte.d.ts.map +1 -0
- package/dist/components/EventDialog.svelte +312 -0
- package/dist/components/EventDialog.svelte.d.ts +15 -0
- package/dist/components/EventDialog.svelte.d.ts.map +1 -0
- package/dist/components/EventHistory.svelte +89 -0
- package/dist/components/EventHistory.svelte.d.ts +10 -0
- package/dist/components/EventHistory.svelte.d.ts.map +1 -0
- package/dist/components/ResourceFilter.svelte +28 -0
- package/dist/components/ResourceFilter.svelte.d.ts +10 -0
- package/dist/components/ResourceFilter.svelte.d.ts.map +1 -0
- package/dist/components/UndoToast.svelte +47 -0
- package/dist/components/UndoToast.svelte.d.ts +4 -0
- package/dist/components/UndoToast.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/styles/index.css +1 -0
- package/dist/views/agenda/AgendaEvent.svelte +55 -0
- package/dist/views/agenda/AgendaEvent.svelte.d.ts +14 -0
- package/dist/views/agenda/AgendaEvent.svelte.d.ts.map +1 -0
- package/dist/views/agenda/AgendaView.svelte +155 -0
- package/dist/views/agenda/AgendaView.svelte.d.ts +8 -0
- package/dist/views/agenda/AgendaView.svelte.d.ts.map +1 -0
- package/dist/views/day/AllDayEvent.svelte +49 -0
- package/dist/views/day/AllDayEvent.svelte.d.ts +12 -0
- package/dist/views/day/AllDayEvent.svelte.d.ts.map +1 -0
- package/dist/views/day/DayView.svelte +252 -0
- package/dist/views/day/DayView.svelte.d.ts +8 -0
- package/dist/views/day/DayView.svelte.d.ts.map +1 -0
- package/dist/views/month/MonthView.svelte +66 -0
- package/dist/views/month/MonthView.svelte.d.ts +8 -0
- package/dist/views/month/MonthView.svelte.d.ts.map +1 -0
- package/dist/views/month/TimedEntry.svelte +51 -0
- package/dist/views/month/TimedEntry.svelte.d.ts +12 -0
- package/dist/views/month/TimedEntry.svelte.d.ts.map +1 -0
- package/dist/views/month/WeekRow.svelte +224 -0
- package/dist/views/month/WeekRow.svelte.d.ts +12 -0
- package/dist/views/month/WeekRow.svelte.d.ts.map +1 -0
- package/dist/views/resource/ResourceView.svelte +227 -0
- package/dist/views/resource/ResourceView.svelte.d.ts +11 -0
- package/dist/views/resource/ResourceView.svelte.d.ts.map +1 -0
- package/dist/views/timeline/TimelineView.svelte +178 -0
- package/dist/views/timeline/TimelineView.svelte.d.ts +12 -0
- package/dist/views/timeline/TimelineView.svelte.d.ts.map +1 -0
- package/dist/views/week/AllDayRow.svelte +74 -0
- package/dist/views/week/AllDayRow.svelte.d.ts +9 -0
- package/dist/views/week/AllDayRow.svelte.d.ts.map +1 -0
- package/dist/views/week/TimeEvent.svelte +192 -0
- package/dist/views/week/TimeEvent.svelte.d.ts +25 -0
- package/dist/views/week/TimeEvent.svelte.d.ts.map +1 -0
- package/dist/views/week/WeekView.svelte +232 -0
- package/dist/views/week/WeekView.svelte.d.ts +8 -0
- package/dist/views/week/WeekView.svelte.d.ts.map +1 -0
- package/dist/views/year/YearView.svelte +92 -0
- package/dist/views/year/YearView.svelte.d.ts +8 -0
- package/dist/views/year/YearView.svelte.d.ts.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CalendarDateTime } from '@bimetal/core';
|
|
3
|
+
import { getYear, getMonth } from '@bimetal/core';
|
|
4
|
+
import type { CalendarStore } from '@bimetal/calendar-data';
|
|
5
|
+
import type { CalendarRule } from '@bimetal/calendar-rules';
|
|
6
|
+
import { parseDragInfo } from '@bimetal/calendar-headless';
|
|
7
|
+
import {
|
|
8
|
+
setCalendarContext,
|
|
9
|
+
setCalendarConfig,
|
|
10
|
+
createCalendarControllerBinding,
|
|
11
|
+
} from '../binding/index.js';
|
|
12
|
+
import type {
|
|
13
|
+
CalendarConfig, CalendarConfigInput, CustomViewDefinition, EventDialogMode, RenderEventFn, AnchorRect,
|
|
14
|
+
} from '../binding/index.js';
|
|
15
|
+
import { onDestroy, untrack } from 'svelte';
|
|
16
|
+
import CalendarHeader from './CalendarHeader.svelte';
|
|
17
|
+
import EventDialog from './EventDialog.svelte';
|
|
18
|
+
import UndoToast from './UndoToast.svelte';
|
|
19
|
+
import MonthView from '../views/month/MonthView.svelte';
|
|
20
|
+
import WeekView from '../views/week/WeekView.svelte';
|
|
21
|
+
import DayView from '../views/day/DayView.svelte';
|
|
22
|
+
import AgendaView from '../views/agenda/AgendaView.svelte';
|
|
23
|
+
import YearView from '../views/year/YearView.svelte';
|
|
24
|
+
import CategoryFilter from './CategoryFilter.svelte';
|
|
25
|
+
import ResourceFilter from './ResourceFilter.svelte';
|
|
26
|
+
import ResourceView from '../views/resource/ResourceView.svelte';
|
|
27
|
+
import TimelineView from '../views/timeline/TimelineView.svelte';
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
store,
|
|
31
|
+
rules = undefined,
|
|
32
|
+
config: configInput = undefined,
|
|
33
|
+
darkMode = false,
|
|
34
|
+
showCategoryFilter = false,
|
|
35
|
+
showResourceFilter = false,
|
|
36
|
+
customViews = undefined,
|
|
37
|
+
eventDialog = { kind: 'builtin' },
|
|
38
|
+
onEventClick: consumerOnEventClick = undefined,
|
|
39
|
+
onNewEventRequested: consumerOnNewEventRequested = undefined,
|
|
40
|
+
renderEvent = undefined,
|
|
41
|
+
onError = undefined,
|
|
42
|
+
}: {
|
|
43
|
+
store: CalendarStore;
|
|
44
|
+
rules?: CalendarRule[];
|
|
45
|
+
config?: CalendarConfigInput;
|
|
46
|
+
darkMode?: boolean;
|
|
47
|
+
showCategoryFilter?: boolean;
|
|
48
|
+
showResourceFilter?: boolean;
|
|
49
|
+
customViews?: readonly CustomViewDefinition[];
|
|
50
|
+
eventDialog?: EventDialogMode;
|
|
51
|
+
onEventClick?: (eventId: string, anchorRect: AnchorRect, instanceDate?: number) => void;
|
|
52
|
+
onNewEventRequested?: (defaultDate: CalendarDateTime, anchorRect: AnchorRect, defaultResourceId?: string) => void;
|
|
53
|
+
renderEvent?: RenderEventFn;
|
|
54
|
+
/** Controller error channel: domain rejections surface as toasts; any other
|
|
55
|
+
* error (e.g. ConcurrencyError) is passed here instead of rejecting. */
|
|
56
|
+
onError?: (err: unknown) => void;
|
|
57
|
+
} = $props();
|
|
58
|
+
|
|
59
|
+
// ── Canonical controller binding ──────────────────────────────
|
|
60
|
+
// The controller owns ALL interaction state and semantics. This component is
|
|
61
|
+
// a thin bridge: it subscribes to the snapshot, forwards intents, and parses
|
|
62
|
+
// DOM events into DragInfo. The controller is created ONCE (under `untrack`):
|
|
63
|
+
// `store` is immutable after mount — runes + `untrack` deliberately do NOT
|
|
64
|
+
// recreate it when the `store` prop changes; remount the component (e.g. via
|
|
65
|
+
// `{#key store}`) to switch stores. config/rules/customViews/eventDialog are
|
|
66
|
+
// captured here only as the initial value and then pushed reactively via the
|
|
67
|
+
// `$effect`s below, so the initial-value reads are deliberate.
|
|
68
|
+
const binding = untrack(() => createCalendarControllerBinding({
|
|
69
|
+
store,
|
|
70
|
+
config: configInput,
|
|
71
|
+
rules,
|
|
72
|
+
customViews,
|
|
73
|
+
eventDialogKind: eventDialog.kind,
|
|
74
|
+
// The consumer's `none`-mode callbacks are read fresh on each fire, so they
|
|
75
|
+
// never go stale even though the controller is created once.
|
|
76
|
+
onEventClickExternal: (id, rect, inst) => consumerOnEventClick?.(id, rect, inst),
|
|
77
|
+
onNewEventRequestedExternal: (date, rect, rid) => consumerOnNewEventRequested?.(date, rect, rid),
|
|
78
|
+
onError: (err) => onError?.(err),
|
|
79
|
+
}));
|
|
80
|
+
const ctrl = binding.ctrl;
|
|
81
|
+
|
|
82
|
+
// `$binding` auto-subscribes via the store contract; the snapshot is
|
|
83
|
+
// identity-stable until an intent changes something.
|
|
84
|
+
const snapshot = $derived($binding);
|
|
85
|
+
|
|
86
|
+
// ── Reactive option updates (config is reactive, not mount-captured) ──
|
|
87
|
+
$effect(() => { ctrl.setConfig(configInput); });
|
|
88
|
+
$effect(() => { ctrl.setRules(rules); });
|
|
89
|
+
$effect(() => { ctrl.setCustomViews(customViews); });
|
|
90
|
+
// F8: dialog mode is a dynamic prop — keep the controller in sync after mount.
|
|
91
|
+
$effect(() => { ctrl.setEventDialogKind(eventDialog.kind); });
|
|
92
|
+
|
|
93
|
+
onDestroy(() => binding.destroy());
|
|
94
|
+
|
|
95
|
+
// ── v0.29 Tastatur: root-scoped keydown → controller (Ctrl/Cmd+Z undo, Escape
|
|
96
|
+
// clears selection). Bound on the `.calendar` root below (onkeydown) — NOT a window
|
|
97
|
+
// listener (no document-level routing). Semantics live in the controller. ──
|
|
98
|
+
function onKey(e: KeyboardEvent) {
|
|
99
|
+
ctrl.handleKeydown(e);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ── DOM-event → controller-intent bindings (the only place DOM is parsed) ──
|
|
103
|
+
function handleDropEvent(e: DragEvent, dropDate: CalendarDateTime) {
|
|
104
|
+
const info = parseDragInfo(e.dataTransfer);
|
|
105
|
+
if (info) void ctrl.dropAllDay(info, dropDate);
|
|
106
|
+
}
|
|
107
|
+
function handleDropTimedEvent(e: DragEvent, dropDate: CalendarDateTime, dropTime: string) {
|
|
108
|
+
const info = parseDragInfo(e.dataTransfer);
|
|
109
|
+
if (info) void ctrl.dropTimed(info, dropDate, dropTime);
|
|
110
|
+
}
|
|
111
|
+
function handleResourceDrop(e: DragEvent, dropDate: CalendarDateTime, dropTime: string, resourceId: string) {
|
|
112
|
+
const info = parseDragInfo(e.dataTransfer);
|
|
113
|
+
if (info) void ctrl.dropResource(info, dropDate, dropTime, resourceId);
|
|
114
|
+
}
|
|
115
|
+
function handleTimelineDrop(e: DragEvent, dropDate: CalendarDateTime, targetResourceId: string) {
|
|
116
|
+
const info = parseDragInfo(e.dataTransfer);
|
|
117
|
+
if (info) void ctrl.dropTimeline(info, dropDate, targetResourceId);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function handleResourceCellClick(date: CalendarDateTime, time: string, resourceId: string, anchorRect: AnchorRect) {
|
|
121
|
+
ctrl.openCreateFromResourceCell(date, time, resourceId, anchorRect);
|
|
122
|
+
}
|
|
123
|
+
function handleTimelineCellClick(date: CalendarDateTime, resourceId: string, anchorRect: AnchorRect) {
|
|
124
|
+
ctrl.openCreate(date, anchorRect, resourceId);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Calendar context (shape UNCHANGED so child views need no changes) ──
|
|
128
|
+
// Getters read straight off the reactive snapshot, so views stay live.
|
|
129
|
+
// F9: config is provided via a reactive `$state` holder kept in sync with the
|
|
130
|
+
// snapshot. Child views hold a stable reference (`getCalendarConfig()`) and
|
|
131
|
+
// read its properties in their templates, so a post-mount `setConfig`
|
|
132
|
+
// (locale/timezone/granularity) now propagates — matching React/Vue, instead
|
|
133
|
+
// of freezing the mount-time value under `untrack`.
|
|
134
|
+
const configHolder = $state<CalendarConfig>(untrack(() => ({ ...snapshot.config })));
|
|
135
|
+
$effect(() => { Object.assign(configHolder, snapshot.config); });
|
|
136
|
+
setCalendarConfig(configHolder);
|
|
137
|
+
setCalendarContext({
|
|
138
|
+
get events() { return [...snapshot.events]; },
|
|
139
|
+
get view() { return snapshot.currentView; },
|
|
140
|
+
// B-CAL-1: das gezogene Event mit bereits neu gebautem timeRange. Views
|
|
141
|
+
// tauschen es per id ein, rekonstruieren nichts. `null` ohne Drag.
|
|
142
|
+
get previewEvent() { return snapshot.previewEvent; },
|
|
143
|
+
// B-CAL-3: die hover-expandierte Monatszelle (Tag-epochMs) + ihre Intents,
|
|
144
|
+
// Eigentum des Controllers — das Binding hält KEIN expand-`$state`.
|
|
145
|
+
get expandedMonthDay() { return snapshot.expandedMonthDay; },
|
|
146
|
+
onExpandMonthCell: (dayEpochMs: number) => ctrl.expandMonthCell(dayEpochMs),
|
|
147
|
+
onCollapseMonthCell: () => ctrl.collapseMonthCell(),
|
|
148
|
+
onEventClick: (eventId: string, anchorRect: AnchorRect, instanceDate?: number) => ctrl.openEdit(eventId, anchorRect, instanceDate),
|
|
149
|
+
onDayCellClick: (date: CalendarDateTime, anchorRect: AnchorRect) => ctrl.openCreate(date, anchorRect),
|
|
150
|
+
onDropEvent: handleDropEvent,
|
|
151
|
+
onDropTimedEvent: handleDropTimedEvent,
|
|
152
|
+
onDragOverDate: (date: CalendarDateTime) => ctrl.updatePreview(date),
|
|
153
|
+
onDragOverDateTime: (date: CalendarDateTime, time: string) => ctrl.updateTimedPreview(date, time),
|
|
154
|
+
onDragStart: ctrl.startDrag,
|
|
155
|
+
onHidePreview: () => ctrl.hidePreview(),
|
|
156
|
+
onDragEnd: () => ctrl.endDrag(),
|
|
157
|
+
get selectedEventId() { return snapshot.selection?.eventId ?? null; },
|
|
158
|
+
get selectedInstanceDate() { return snapshot.selection?.instanceDate; },
|
|
159
|
+
onSelectEvent: (eventId: string, instanceDate?: number) => ctrl.selectEvent(eventId, instanceDate),
|
|
160
|
+
onClearSelection: () => ctrl.clearSelection(),
|
|
161
|
+
onUndo: (entityId: string) => ctrl.undo(entityId),
|
|
162
|
+
getHistory: (entityId: string) => ctrl.getHistory(entityId),
|
|
163
|
+
get lastAction() { return snapshot.lastAction; },
|
|
164
|
+
dismissUndo: () => ctrl.dismissUndo(),
|
|
165
|
+
get renderEvent() { return renderEvent; },
|
|
166
|
+
});
|
|
167
|
+
</script>
|
|
168
|
+
|
|
169
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
170
|
+
<div class="calendar" class:dark={darkMode} onkeydown={onKey}>
|
|
171
|
+
<CalendarHeader
|
|
172
|
+
title={snapshot.title}
|
|
173
|
+
currentView={snapshot.currentView}
|
|
174
|
+
viewConfigs={[...snapshot.viewConfigList]}
|
|
175
|
+
onPrev={() => ctrl.prev()}
|
|
176
|
+
onNext={() => ctrl.next()}
|
|
177
|
+
onToday={() => ctrl.today()}
|
|
178
|
+
onViewChange={(v) => ctrl.setView(v)}
|
|
179
|
+
/>
|
|
180
|
+
|
|
181
|
+
{#if showCategoryFilter && snapshot.config.categories.length > 0}
|
|
182
|
+
<CategoryFilter
|
|
183
|
+
categories={snapshot.config.categories}
|
|
184
|
+
hiddenCategories={snapshot.hiddenCategories}
|
|
185
|
+
onToggle={(name) => ctrl.toggleCategory(name)}
|
|
186
|
+
/>
|
|
187
|
+
{/if}
|
|
188
|
+
|
|
189
|
+
{#if showResourceFilter && snapshot.config.resources.length > 0}
|
|
190
|
+
<ResourceFilter
|
|
191
|
+
resources={snapshot.config.resources}
|
|
192
|
+
hiddenResources={snapshot.hiddenResources}
|
|
193
|
+
onToggle={(id) => ctrl.toggleResource(id)}
|
|
194
|
+
/>
|
|
195
|
+
{/if}
|
|
196
|
+
|
|
197
|
+
{#if snapshot.currentView === 'year'}
|
|
198
|
+
<YearView year={getYear(snapshot.currentDate)} onMonthClick={(y, m) => ctrl.goToMonth(y, m)} />
|
|
199
|
+
{:else if snapshot.currentView === 'month'}
|
|
200
|
+
<MonthView year={getYear(snapshot.currentDate)} month={getMonth(snapshot.currentDate)} />
|
|
201
|
+
{:else if snapshot.currentView === 'week'}
|
|
202
|
+
<WeekView currentDate={snapshot.currentDate} />
|
|
203
|
+
{:else if snapshot.currentView === 'day'}
|
|
204
|
+
<DayView currentDate={snapshot.currentDate} />
|
|
205
|
+
{:else if snapshot.currentView === 'agenda'}
|
|
206
|
+
<AgendaView currentDate={snapshot.currentDate} />
|
|
207
|
+
{:else if snapshot.currentView === 'resource'}
|
|
208
|
+
<ResourceView
|
|
209
|
+
currentDate={snapshot.currentDate}
|
|
210
|
+
visibleResources={snapshot.visibleResources}
|
|
211
|
+
onResourceCellClick={handleResourceCellClick}
|
|
212
|
+
onResourceDrop={handleResourceDrop}
|
|
213
|
+
/>
|
|
214
|
+
{:else if snapshot.currentView === 'timeline'}
|
|
215
|
+
<TimelineView
|
|
216
|
+
currentDate={snapshot.currentDate}
|
|
217
|
+
days={snapshot.config.core.timelineDays ?? 7}
|
|
218
|
+
visibleResources={snapshot.visibleResources}
|
|
219
|
+
onTimelineCellClick={handleTimelineCellClick}
|
|
220
|
+
onTimelineDrop={handleTimelineDrop}
|
|
221
|
+
/>
|
|
222
|
+
{:else if customViews && customViews.find(v => v.id === snapshot.currentView)}
|
|
223
|
+
{@const custom = customViews.find(v => v.id === snapshot.currentView)!}
|
|
224
|
+
{@const CustomComp = custom.component}
|
|
225
|
+
<CustomComp
|
|
226
|
+
currentDate={snapshot.currentDate}
|
|
227
|
+
events={snapshot.events}
|
|
228
|
+
config={snapshot.config}
|
|
229
|
+
onNewEvent={(d, anchorRect) => ctrl.openCreate(d, anchorRect ?? new DOMRect(0, 0, 0, 0))}
|
|
230
|
+
onEventClick={(eventId, anchorRect, instanceDate) => ctrl.openEdit(eventId, anchorRect, instanceDate)}
|
|
231
|
+
selectedEventId={snapshot.selection?.eventId ?? null}
|
|
232
|
+
selectedInstanceDate={snapshot.selection?.instanceDate}
|
|
233
|
+
onSelectEvent={(eventId, instanceDate) => ctrl.selectEvent(eventId, instanceDate)}
|
|
234
|
+
onClearSelection={() => ctrl.clearSelection()}
|
|
235
|
+
/>
|
|
236
|
+
{/if}
|
|
237
|
+
|
|
238
|
+
{#if snapshot.dialog && eventDialog.kind === 'builtin'}
|
|
239
|
+
<EventDialog
|
|
240
|
+
dialog={snapshot.dialog}
|
|
241
|
+
setDraft={(patch) => ctrl.setDraft(patch)}
|
|
242
|
+
onSave={() => void ctrl.saveDialogFromInput()}
|
|
243
|
+
onDelete={(id) => ctrl.deleteDialog(id)}
|
|
244
|
+
onClose={() => ctrl.closeDialog()}
|
|
245
|
+
/>
|
|
246
|
+
{/if}
|
|
247
|
+
|
|
248
|
+
{#if snapshot.dialog && eventDialog.kind === 'custom'}
|
|
249
|
+
{@const CustomDialog = eventDialog.component}
|
|
250
|
+
<CustomDialog
|
|
251
|
+
event={snapshot.dialog.event}
|
|
252
|
+
defaultDate={snapshot.dialog.defaultDate}
|
|
253
|
+
anchorRect={snapshot.dialog.anchorRect}
|
|
254
|
+
defaultResourceId={snapshot.dialog.defaultResourceId}
|
|
255
|
+
config={snapshot.config}
|
|
256
|
+
onSave={(evt) => ctrl.saveDialog(evt)}
|
|
257
|
+
onDelete={(id) => ctrl.deleteDialog(id)}
|
|
258
|
+
onClose={() => ctrl.closeDialog()}
|
|
259
|
+
/>
|
|
260
|
+
{/if}
|
|
261
|
+
|
|
262
|
+
<UndoToast />
|
|
263
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CalendarDateTime } from '@bimetal/core';
|
|
2
|
+
import type { CalendarStore } from '@bimetal/calendar-data';
|
|
3
|
+
import type { CalendarRule } from '@bimetal/calendar-rules';
|
|
4
|
+
import type { CalendarConfigInput, CustomViewDefinition, EventDialogMode, RenderEventFn, AnchorRect } from '../binding/index.js';
|
|
5
|
+
type $$ComponentProps = {
|
|
6
|
+
store: CalendarStore;
|
|
7
|
+
rules?: CalendarRule[];
|
|
8
|
+
config?: CalendarConfigInput;
|
|
9
|
+
darkMode?: boolean;
|
|
10
|
+
showCategoryFilter?: boolean;
|
|
11
|
+
showResourceFilter?: boolean;
|
|
12
|
+
customViews?: readonly CustomViewDefinition[];
|
|
13
|
+
eventDialog?: EventDialogMode;
|
|
14
|
+
onEventClick?: (eventId: string, anchorRect: AnchorRect, instanceDate?: number) => void;
|
|
15
|
+
onNewEventRequested?: (defaultDate: CalendarDateTime, anchorRect: AnchorRect, defaultResourceId?: string) => void;
|
|
16
|
+
renderEvent?: RenderEventFn;
|
|
17
|
+
/** Controller error channel: domain rejections surface as toasts; any other
|
|
18
|
+
* error (e.g. ConcurrencyError) is passed here instead of rejecting. */
|
|
19
|
+
onError?: (err: unknown) => void;
|
|
20
|
+
};
|
|
21
|
+
declare const Calendar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
22
|
+
type Calendar = ReturnType<typeof Calendar>;
|
|
23
|
+
export default Calendar;
|
|
24
|
+
//# sourceMappingURL=Calendar.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Calendar.svelte.d.ts","sourceRoot":"","sources":["../../src/components/Calendar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAO5D,OAAO,KAAK,EACQ,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EACtG,MAAM,qBAAqB,CAAC;AAe9B,KAAK,gBAAgB,GAAI;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC9C,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxF,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClH,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B;6EACyE;IACzE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC,CAAC;AAkMJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ViewType } from '@bimetal/calendar-core';
|
|
3
|
+
import type { ViewConfig } from '../binding/index.js';
|
|
4
|
+
import { getCalendarConfig } from '../binding/index.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
title,
|
|
8
|
+
currentView,
|
|
9
|
+
viewConfigs,
|
|
10
|
+
onPrev,
|
|
11
|
+
onNext,
|
|
12
|
+
onToday,
|
|
13
|
+
onViewChange,
|
|
14
|
+
}: {
|
|
15
|
+
title: string;
|
|
16
|
+
currentView: ViewType;
|
|
17
|
+
viewConfigs: ViewConfig[];
|
|
18
|
+
onPrev: () => void;
|
|
19
|
+
onNext: () => void;
|
|
20
|
+
onToday: () => void;
|
|
21
|
+
onViewChange: (view: ViewType) => void;
|
|
22
|
+
} = $props();
|
|
23
|
+
|
|
24
|
+
const config = getCalendarConfig();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<div class="calendar-header">
|
|
28
|
+
<h1 class="month-title">{title}</h1>
|
|
29
|
+
<div class="header-controls">
|
|
30
|
+
<div class="view-switcher">
|
|
31
|
+
{#each viewConfigs as vc (vc.type)}
|
|
32
|
+
<button
|
|
33
|
+
class="view-btn"
|
|
34
|
+
class:view-btn--active={currentView === vc.type}
|
|
35
|
+
onclick={() => onViewChange(vc.type)}
|
|
36
|
+
>
|
|
37
|
+
{vc.label}
|
|
38
|
+
</button>
|
|
39
|
+
{/each}
|
|
40
|
+
</div>
|
|
41
|
+
<div class="nav-controls">
|
|
42
|
+
<button class="nav-btn" aria-label={config.locale.prev} onclick={onPrev}>‹</button>
|
|
43
|
+
<button class="today-btn" onclick={onToday}>{config.locale.today}</button>
|
|
44
|
+
<button class="nav-btn" aria-label={config.locale.next} onclick={onNext}>›</button>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ViewType } from '@bimetal/calendar-core';
|
|
2
|
+
import type { ViewConfig } from '../binding/index.js';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
title: string;
|
|
5
|
+
currentView: ViewType;
|
|
6
|
+
viewConfigs: ViewConfig[];
|
|
7
|
+
onPrev: () => void;
|
|
8
|
+
onNext: () => void;
|
|
9
|
+
onToday: () => void;
|
|
10
|
+
onViewChange: (view: ViewType) => void;
|
|
11
|
+
};
|
|
12
|
+
declare const CalendarHeader: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type CalendarHeader = ReturnType<typeof CalendarHeader>;
|
|
14
|
+
export default CalendarHeader;
|
|
15
|
+
//# sourceMappingURL=CalendarHeader.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarHeader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/CalendarHeader.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGrD,KAAK,gBAAgB,GAAI;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,QAAQ,CAAC;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;CACxC,CAAC;AAuCJ,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Category } from '../binding/index.js';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
categories,
|
|
6
|
+
hiddenCategories,
|
|
7
|
+
onToggle,
|
|
8
|
+
}: {
|
|
9
|
+
categories: Category[];
|
|
10
|
+
hiddenCategories: ReadonlySet<string>;
|
|
11
|
+
onToggle: (name: string) => void;
|
|
12
|
+
} = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#if categories.length > 0}
|
|
16
|
+
<div class="category-filter">
|
|
17
|
+
{#each categories as cat (cat.name)}
|
|
18
|
+
{@const isHidden = hiddenCategories.has(cat.name)}
|
|
19
|
+
<button
|
|
20
|
+
class="category-filter__pill{isHidden ? ' category-filter__pill--hidden' : ''}"
|
|
21
|
+
style:background-color={cat.color}
|
|
22
|
+
onclick={() => onToggle(cat.name)}
|
|
23
|
+
type="button"
|
|
24
|
+
>
|
|
25
|
+
{cat.name}
|
|
26
|
+
</button>
|
|
27
|
+
{/each}
|
|
28
|
+
</div>
|
|
29
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Category } from '../binding/index.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
categories: Category[];
|
|
4
|
+
hiddenCategories: ReadonlySet<string>;
|
|
5
|
+
onToggle: (name: string) => void;
|
|
6
|
+
};
|
|
7
|
+
declare const CategoryFilter: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type CategoryFilter = ReturnType<typeof CategoryFilter>;
|
|
9
|
+
export default CategoryFilter;
|
|
10
|
+
//# sourceMappingURL=CategoryFilter.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategoryFilter.svelte.d.ts","sourceRoot":"","sources":["../../src/components/CategoryFilter.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEnD,KAAK,gBAAgB,GAAI;IACtB,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAwBJ,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CalendarDateTime, LayoutItem } from '@bimetal/calendar-core';
|
|
3
|
+
import { daysBetween, getRecurrenceInstanceMetadata, isExpandedRecurrenceInstance } from '@bimetal/calendar-core';
|
|
4
|
+
import { getCalendarContext, getCalendarConfig, buildDragInfo, getEventSlots, toTimeStr } from '../binding/index.js';
|
|
5
|
+
import type { DragInfo } from '../binding/index.js';
|
|
6
|
+
import { createClickIntent, writeCalendarDragData, installTransparentDragImage, eventBarWantsDarkText } from '@bimetal/calendar-headless';
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
item,
|
|
10
|
+
weekDates,
|
|
11
|
+
ghost = false,
|
|
12
|
+
}: {
|
|
13
|
+
item: LayoutItem;
|
|
14
|
+
weekDates: CalendarDateTime[];
|
|
15
|
+
ghost?: boolean;
|
|
16
|
+
} = $props();
|
|
17
|
+
|
|
18
|
+
const ctx = getCalendarContext<{
|
|
19
|
+
onEventClick: (eventId: string, anchorRect: DOMRect, instanceDate?: number) => void;
|
|
20
|
+
onSelectEvent: (eventId: string, instanceDate?: number) => void;
|
|
21
|
+
selectedEventId: string | null;
|
|
22
|
+
selectedInstanceDate: number | undefined;
|
|
23
|
+
onDragStart: (info: DragInfo) => void;
|
|
24
|
+
onDragEnd: () => void;
|
|
25
|
+
}>();
|
|
26
|
+
const config = getCalendarConfig();
|
|
27
|
+
|
|
28
|
+
const click = createClickIntent();
|
|
29
|
+
|
|
30
|
+
function handleMouseDown() {
|
|
31
|
+
click.markMouseDown();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function handleDragStart(e: DragEvent) {
|
|
35
|
+
click.markDragged();
|
|
36
|
+
const { segment, dayIndex, daySpan } = item;
|
|
37
|
+
const { event } = segment;
|
|
38
|
+
const bar = e.currentTarget as HTMLElement;
|
|
39
|
+
const barRect = bar.getBoundingClientRect();
|
|
40
|
+
const colWidth = barRect.width / daySpan;
|
|
41
|
+
const grabColInBar = Math.min(
|
|
42
|
+
Math.max(0, Math.floor((e.clientX - barRect.left) / colWidth)),
|
|
43
|
+
daySpan - 1,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const grabbedDate = weekDates[dayIndex + grabColInBar];
|
|
47
|
+
const offset = daysBetween(event.timeRange.start, grabbedDate);
|
|
48
|
+
|
|
49
|
+
const info = buildDragInfo(event, 'move', { dayOffset: offset });
|
|
50
|
+
writeCalendarDragData(e.dataTransfer!, info);
|
|
51
|
+
ctx.onDragStart(info);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function handleResizeDragStart(e: DragEvent, edge: 'start' | 'end') {
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
click.markDragged();
|
|
57
|
+
installTransparentDragImage(e.dataTransfer!);
|
|
58
|
+
const { event } = item.segment;
|
|
59
|
+
const info = buildDragInfo(event, 'resize', { edge });
|
|
60
|
+
writeCalendarDragData(e.dataTransfer!, info);
|
|
61
|
+
ctx.onDragStart(info);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function handleClick(e: MouseEvent) {
|
|
65
|
+
e.stopPropagation();
|
|
66
|
+
if (!click.accept(config.clickThresholdMs)) return;
|
|
67
|
+
const instanceDate = getRecurrenceInstanceMetadata(item.segment.event)?.instanceDate;
|
|
68
|
+
ctx.onSelectEvent(item.segment.event.id, instanceDate);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function handleDoubleClick(e: MouseEvent) {
|
|
72
|
+
e.stopPropagation();
|
|
73
|
+
if (!click.accept(config.clickThresholdMs)) return;
|
|
74
|
+
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
75
|
+
const instanceDate = getRecurrenceInstanceMetadata(item.segment.event)?.instanceDate;
|
|
76
|
+
ctx.onEventClick(item.segment.event.id, rect, instanceDate);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const segment = $derived(item.segment);
|
|
80
|
+
const event = $derived(segment.event);
|
|
81
|
+
const isStart = $derived(segment.isStart);
|
|
82
|
+
const isEnd = $derived(segment.isEnd);
|
|
83
|
+
const startCol = $derived(item.dayIndex);
|
|
84
|
+
const span = $derived(item.daySpan);
|
|
85
|
+
const lane = $derived(item.column);
|
|
86
|
+
const isCompact = $derived(span === 1 && isStart && isEnd && !event.allDay);
|
|
87
|
+
const isBar = $derived(!isCompact);
|
|
88
|
+
const color = $derived(event.metadata.color ?? '#007AFF');
|
|
89
|
+
const isRecurring = $derived(isExpandedRecurrenceInstance(event) || !!event.recurrence);
|
|
90
|
+
const ghostClass = $derived(ghost ? ' event-bar--ghost' : '');
|
|
91
|
+
const instanceDate = $derived(getRecurrenceInstanceMetadata(event)?.instanceDate);
|
|
92
|
+
const isSelected = $derived(ctx.selectedEventId === event.id && ctx.selectedInstanceDate === instanceDate);
|
|
93
|
+
const selectedClass = $derived(isSelected ? ' event-bar--selected' : '');
|
|
94
|
+
|
|
95
|
+
const gridStyle = $derived(`grid-column: ${startCol + 1} / span ${span}; grid-row: ${lane + 1};`);
|
|
96
|
+
const barStyle = $derived(
|
|
97
|
+
isCompact
|
|
98
|
+
? gridStyle
|
|
99
|
+
: `${gridStyle} background-color: ${color}; border-radius: ${isStart ? 4 : 0}px ${isEnd ? 4 : 0}px ${isEnd ? 4 : 0}px ${isStart ? 4 : 0}px;`
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const timeStr = $derived(toTimeStr(event.timeRange.start));
|
|
103
|
+
|
|
104
|
+
const slots = $derived(getEventSlots(event));
|
|
105
|
+
const renderedTitle = $derived(slots.title ?? event.title);
|
|
106
|
+
const extraClass = $derived(slots.className ? ' ' + slots.className : '');
|
|
107
|
+
const slotStyle = $derived(slots.style
|
|
108
|
+
? Object.entries(slots.style).map(([k, v]) => `${k.replace(/[A-Z]/g, m => '-' + m.toLowerCase())}: ${v}`).join('; ')
|
|
109
|
+
: '');
|
|
110
|
+
const fullStyle = $derived(slotStyle ? `${barStyle} ${slotStyle}` : barStyle);
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
{#if isCompact}
|
|
114
|
+
<div
|
|
115
|
+
class="event-bar event-bar--single{ghostClass}{selectedClass}{extraClass}"
|
|
116
|
+
style={fullStyle}
|
|
117
|
+
draggable={!ghost}
|
|
118
|
+
role="button"
|
|
119
|
+
tabindex="0"
|
|
120
|
+
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') handleClick(e as any); }}
|
|
121
|
+
onmousedown={handleMouseDown}
|
|
122
|
+
ondragstart={handleDragStart}
|
|
123
|
+
ondragend={ctx.onDragEnd}
|
|
124
|
+
onclick={handleClick}
|
|
125
|
+
ondblclick={handleDoubleClick}
|
|
126
|
+
title={renderedTitle}
|
|
127
|
+
>
|
|
128
|
+
{#if slots.content}
|
|
129
|
+
{#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
|
|
130
|
+
{:else}
|
|
131
|
+
<span class="event-dot" style:background-color={color}></span>
|
|
132
|
+
<span class="event-time">{timeStr}</span>
|
|
133
|
+
<span class="event-title event-title--dark">{isRecurring ? '↻ ' : ''}{renderedTitle}</span>
|
|
134
|
+
{/if}
|
|
135
|
+
{#if slots.badges}
|
|
136
|
+
{#if typeof slots.badges === 'string'}{slots.badges}{:else}{@render slots.badges()}{/if}
|
|
137
|
+
{/if}
|
|
138
|
+
</div>
|
|
139
|
+
{:else}
|
|
140
|
+
<div
|
|
141
|
+
class="event-bar event-bar--multi{ghostClass}{selectedClass}{extraClass}"
|
|
142
|
+
style={fullStyle}
|
|
143
|
+
draggable={!ghost}
|
|
144
|
+
role="button"
|
|
145
|
+
tabindex="0"
|
|
146
|
+
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') handleClick(e as any); }}
|
|
147
|
+
onmousedown={handleMouseDown}
|
|
148
|
+
ondragstart={handleDragStart}
|
|
149
|
+
ondragend={ctx.onDragEnd}
|
|
150
|
+
onclick={handleClick}
|
|
151
|
+
ondblclick={handleDoubleClick}
|
|
152
|
+
title={renderedTitle}
|
|
153
|
+
>
|
|
154
|
+
{#if isBar && isStart && !ghost}
|
|
155
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
|
|
156
|
+
<div
|
|
157
|
+
class="resize-handle resize-handle--start"
|
|
158
|
+
role="separator"
|
|
159
|
+
aria-label="Resize start"
|
|
160
|
+
draggable={true}
|
|
161
|
+
ondragstart={(e) => handleResizeDragStart(e, 'start')}
|
|
162
|
+
ondragend={ctx.onDragEnd}
|
|
163
|
+
onmousedown={(e) => e.stopPropagation()}
|
|
164
|
+
></div>
|
|
165
|
+
{/if}
|
|
166
|
+
{#if slots.content}
|
|
167
|
+
{#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
|
|
168
|
+
{:else}
|
|
169
|
+
<span class="event-title{eventBarWantsDarkText(color) ? ' event-title--on-light' : ''}">{isRecurring ? '↻ ' : ''}{renderedTitle}</span>
|
|
170
|
+
{/if}
|
|
171
|
+
{#if slots.badges}
|
|
172
|
+
{#if typeof slots.badges === 'string'}{slots.badges}{:else}{@render slots.badges()}{/if}
|
|
173
|
+
{/if}
|
|
174
|
+
{#if isBar && isEnd && !ghost}
|
|
175
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
|
|
176
|
+
<div
|
|
177
|
+
class="resize-handle resize-handle--end"
|
|
178
|
+
role="separator"
|
|
179
|
+
aria-label="Resize end"
|
|
180
|
+
draggable={true}
|
|
181
|
+
ondragstart={(e) => handleResizeDragStart(e, 'end')}
|
|
182
|
+
ondragend={ctx.onDragEnd}
|
|
183
|
+
onmousedown={(e) => e.stopPropagation()}
|
|
184
|
+
></div>
|
|
185
|
+
{/if}
|
|
186
|
+
</div>
|
|
187
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CalendarDateTime, LayoutItem } from '@bimetal/calendar-core';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
item: LayoutItem;
|
|
4
|
+
weekDates: CalendarDateTime[];
|
|
5
|
+
ghost?: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare const EventBar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type EventBar = ReturnType<typeof EventBar>;
|
|
9
|
+
export default EventBar;
|
|
10
|
+
//# sourceMappingURL=EventBar.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBar.svelte.d.ts","sourceRoot":"","sources":["../../src/components/EventBar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAM1E,KAAK,gBAAgB,GAAI;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAiJJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|