@cocoar/vue-calendar 1.16.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 +257 -0
- package/dist/__test-utils__/event-fixtures.d.ts +4 -0
- package/dist/__test-utils__/event-fixtures.d.ts.map +1 -0
- package/dist/builders/calendar-builder-internals.d.ts +14 -0
- package/dist/builders/calendar-builder-internals.d.ts.map +1 -0
- package/dist/builders/calendar-builder.d.ts +296 -0
- package/dist/builders/calendar-builder.d.ts.map +1 -0
- package/dist/builders/event-zone-hints.d.ts +20 -0
- package/dist/builders/event-zone-hints.d.ts.map +1 -0
- package/dist/builders/render-helpers.d.ts +19 -0
- package/dist/builders/render-helpers.d.ts.map +1 -0
- package/dist/builders/types.d.ts +175 -0
- package/dist/builders/types.d.ts.map +1 -0
- package/dist/components/CoarCalendar.vue.d.ts +150 -0
- package/dist/components/CoarCalendar.vue.d.ts.map +1 -0
- package/dist/components/CoarDisplayZoneSwitcher.vue.d.ts +28 -0
- package/dist/components/CoarDisplayZoneSwitcher.vue.d.ts.map +1 -0
- package/dist/components/VirtualizedSurface1DY.vue.d.ts +90 -0
- package/dist/components/VirtualizedSurface1DY.vue.d.ts.map +1 -0
- package/dist/components/VirtualizedSurface2D.vue.d.ts +71 -0
- package/dist/components/VirtualizedSurface2D.vue.d.ts.map +1 -0
- package/dist/components/internal/CoarEventDecorations.vue.d.ts +13 -0
- package/dist/components/internal/CoarEventDecorations.vue.d.ts.map +1 -0
- package/dist/components/internal/RenderEventFallback.d.ts +17 -0
- package/dist/components/internal/RenderEventFallback.d.ts.map +1 -0
- package/dist/components/internal/agenda/CoarAgendaDayHeader.vue.d.ts +54 -0
- package/dist/components/internal/agenda/CoarAgendaDayHeader.vue.d.ts.map +1 -0
- package/dist/components/internal/month/CoarMonthBar.vue.d.ts +80 -0
- package/dist/components/internal/month/CoarMonthBar.vue.d.ts.map +1 -0
- package/dist/components/internal/month/CoarMonthCell.vue.d.ts +74 -0
- package/dist/components/internal/month/CoarMonthCell.vue.d.ts.map +1 -0
- package/dist/components/internal/month/CoarMonthGrid.vue.d.ts +50 -0
- package/dist/components/internal/month/CoarMonthGrid.vue.d.ts.map +1 -0
- package/dist/components/internal/month/CoarMonthPill.vue.d.ts +83 -0
- package/dist/components/internal/month/CoarMonthPill.vue.d.ts.map +1 -0
- package/dist/components/internal/month/CoarMonthRow.vue.d.ts +44 -0
- package/dist/components/internal/month/CoarMonthRow.vue.d.ts.map +1 -0
- package/dist/components/internal/time-grid/CoarTimeGridAllDayBand.vue.d.ts +39 -0
- package/dist/components/internal/time-grid/CoarTimeGridAllDayBand.vue.d.ts.map +1 -0
- package/dist/components/internal/time-grid/CoarTimeGridColumn.vue.d.ts +44 -0
- package/dist/components/internal/time-grid/CoarTimeGridColumn.vue.d.ts.map +1 -0
- package/dist/components/internal/time-grid/CoarTimeGridHeader.vue.d.ts +44 -0
- package/dist/components/internal/time-grid/CoarTimeGridHeader.vue.d.ts.map +1 -0
- package/dist/components/internal/time-grid/CoarTimeGridNowMarker.vue.d.ts +18 -0
- package/dist/components/internal/time-grid/CoarTimeGridNowMarker.vue.d.ts.map +1 -0
- package/dist/composables/useA11yAnnouncer.d.ts +9 -0
- package/dist/composables/useA11yAnnouncer.d.ts.map +1 -0
- package/dist/composables/useCalendarDnd.d.ts +212 -0
- package/dist/composables/useCalendarDnd.d.ts.map +1 -0
- package/dist/composables/useCoarDrag.d.ts +97 -0
- package/dist/composables/useCoarDrag.d.ts.map +1 -0
- package/dist/composables/useMonthDnd.d.ts +89 -0
- package/dist/composables/useMonthDnd.d.ts.map +1 -0
- package/dist/composables/useMonthExpansion.d.ts +35 -0
- package/dist/composables/useMonthExpansion.d.ts.map +1 -0
- package/dist/composables/useTimeGridDnd.d.ts +104 -0
- package/dist/composables/useTimeGridDnd.d.ts.map +1 -0
- package/dist/composables/useViewWindow.d.ts +14 -0
- package/dist/composables/useViewWindow.d.ts.map +1 -0
- package/dist/core/agendaLayout.d.ts +47 -0
- package/dist/core/agendaLayout.d.ts.map +1 -0
- package/dist/core/dnd/move-math.d.ts +136 -0
- package/dist/core/dnd/move-math.d.ts.map +1 -0
- package/dist/core/dragHitTest.d.ts +74 -0
- package/dist/core/dragHitTest.d.ts.map +1 -0
- package/dist/core/eventIndex.d.ts +106 -0
- package/dist/core/eventIndex.d.ts.map +1 -0
- package/dist/core/index.d.ts +32 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/measurementCache.d.ts +87 -0
- package/dist/core/measurementCache.d.ts.map +1 -0
- package/dist/core/monthGridLayout.d.ts +68 -0
- package/dist/core/monthGridLayout.d.ts.map +1 -0
- package/dist/core/overlapLayout.d.ts +88 -0
- package/dist/core/overlapLayout.d.ts.map +1 -0
- package/dist/core/recurrence-public.d.ts +59 -0
- package/dist/core/recurrence-public.d.ts.map +1 -0
- package/dist/core/recurrence.d.ts +112 -0
- package/dist/core/recurrence.d.ts.map +1 -0
- package/dist/core/recurrenceWorker.d.ts +62 -0
- package/dist/core/recurrenceWorker.d.ts.map +1 -0
- package/dist/core/temporal.d.ts +214 -0
- package/dist/core/temporal.d.ts.map +1 -0
- package/dist/core/timeGridLayout.d.ts +109 -0
- package/dist/core/timeGridLayout.d.ts.map +1 -0
- package/dist/core/types.d.ts +211 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/viewWindow.d.ts +53 -0
- package/dist/core/viewWindow.d.ts.map +1 -0
- package/dist/core/virtualScroll.d.ts +91 -0
- package/dist/core/virtualScroll.d.ts.map +1 -0
- package/dist/core-DK63eHat.js +959 -0
- package/dist/core.js +2 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4221 -0
- package/dist/useAgendaView.d.ts +6 -0
- package/dist/useAgendaView.d.ts.map +1 -0
- package/dist/useCalendar.d.ts +6 -0
- package/dist/useCalendar.d.ts.map +1 -0
- package/dist/useDayView.d.ts +6 -0
- package/dist/useDayView.d.ts.map +1 -0
- package/dist/useMonthView.d.ts +6 -0
- package/dist/useMonthView.d.ts.map +1 -0
- package/dist/useWeekView.d.ts +6 -0
- package/dist/useWeekView.d.ts.map +1 -0
- package/dist/vue-calendar.css +2 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# @cocoar/vue-calendar
|
|
2
|
+
|
|
3
|
+
> **Vue 3 calendar component built around `Temporal`.** Day / Week /
|
|
4
|
+
> Month / Agenda views, drag-and-drop with cross-zone safety, and an
|
|
5
|
+
> 8-invariant architecture (C1–C8) drawn from the
|
|
6
|
+
> ["Time in Software, Done Right"][articles] article series.
|
|
7
|
+
|
|
8
|
+
[articles]: https://dev.to/bwi/why-a-date-is-not-a-point-in-time-ad8
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @cocoar/vue-calendar
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Peer deps: `vue ^3.5`, `@cocoar/vue-ui workspace:*`,
|
|
17
|
+
`@cocoar/vue-localization workspace:*`. Direct dep:
|
|
18
|
+
`@js-temporal/polyfill ^0.5` (re-exported as `Temporal`).
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
import { ref } from 'vue';
|
|
25
|
+
import {
|
|
26
|
+
CoarCalendar,
|
|
27
|
+
Temporal,
|
|
28
|
+
useCalendar,
|
|
29
|
+
type CalendarEvent,
|
|
30
|
+
} from '@cocoar/vue-calendar';
|
|
31
|
+
|
|
32
|
+
// Events are Temporal-typed (C1) — never strings, Date,
|
|
33
|
+
// PlainDateTime, or Instant on the public surface. The library
|
|
34
|
+
// throws at the boundary if you try.
|
|
35
|
+
const events = ref<CalendarEvent[]>([
|
|
36
|
+
{
|
|
37
|
+
id: 'standup',
|
|
38
|
+
start: Temporal.ZonedDateTime.from('2026-06-15T09:00:00[Europe/Vienna]'),
|
|
39
|
+
end: Temporal.ZonedDateTime.from('2026-06-15T09:30:00[Europe/Vienna]'),
|
|
40
|
+
meta: { title: 'Daily Standup' },
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'vacation',
|
|
44
|
+
start: Temporal.PlainDate.from('2026-06-22'), // all-day → PlainDate
|
|
45
|
+
end: Temporal.PlainDate.from('2026-06-27'),
|
|
46
|
+
meta: { title: 'Vacation' },
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
const { builder, api } = useCalendar();
|
|
51
|
+
builder
|
|
52
|
+
.events(events)
|
|
53
|
+
.timezone('Europe/Vienna') // C5 display zone — REQUIRED
|
|
54
|
+
.locale('de-AT') // C6 (independent of timeStyle / hour12)
|
|
55
|
+
.firstDayOfWeek(1) // 0 = Sun, 1 = Mon, …
|
|
56
|
+
.view('week')
|
|
57
|
+
.date(Temporal.PlainDate.from('2026-06-15'))
|
|
58
|
+
.dstPolicy('compatible') // C4 — explicit DST policy
|
|
59
|
+
.onEventDrop(({ event, next, target }) => {
|
|
60
|
+
// C3: next.start / next.end keep their per-endpoint source zones.
|
|
61
|
+
// For a Tokyo→Vienna flight, next.start.timeZoneId stays
|
|
62
|
+
// 'Asia/Tokyo' even when displayed in Vienna.
|
|
63
|
+
// C5: target.displayZone is the zone the user's eyes saw at drop.
|
|
64
|
+
// C4: target.disambiguation is 'gap' | 'overlap' | null (DST outcome).
|
|
65
|
+
saveEvent({ id: event.id, start: next.start, end: next.end });
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template>
|
|
70
|
+
<CoarCalendar :builder="builder" />
|
|
71
|
+
</template>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That's it. Drag events, switch views, navigate dates — all wired.
|
|
75
|
+
|
|
76
|
+
## API contract for backends (Article 8)
|
|
77
|
+
|
|
78
|
+
The library ships two helpers that mirror Article 8's recommended
|
|
79
|
+
wire shape (`{ local, timeZoneId }`):
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import {
|
|
83
|
+
parseScheduledTime,
|
|
84
|
+
formatScheduledTime,
|
|
85
|
+
} from '@cocoar/vue-calendar';
|
|
86
|
+
|
|
87
|
+
// Wire → Temporal (use this when deserialising backend payloads):
|
|
88
|
+
const start = parseScheduledTime({
|
|
89
|
+
local: '2026-06-15T09:00:00',
|
|
90
|
+
timeZoneId: 'Europe/Vienna',
|
|
91
|
+
dstPolicy: 'compatible', // optional, default
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Temporal → wire (use this when shipping back to the backend):
|
|
95
|
+
const wire = formatScheduledTime(event.start);
|
|
96
|
+
// → { local: '2026-06-15T09:00:00', timeZoneId: 'Europe/Vienna' }
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The shape is stable across:
|
|
100
|
+
|
|
101
|
+
- Frontend pickers (Article 8 — "DateTimePickers that don't lie")
|
|
102
|
+
- .NET / NodaTime backends (Article 6 — `LocalDateTime + TimeZoneId`)
|
|
103
|
+
- PostgreSQL storage (Article 7 — `local_start text + time_zone_id text`)
|
|
104
|
+
|
|
105
|
+
## The 8 invariants (C1–C8)
|
|
106
|
+
|
|
107
|
+
| Article basis | Invariant | What it means |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| 1, 2, 4, 8 | **C1** Temporal-only public surface | Strings / `Date` / `PlainDateTime` / `Instant` rejected at the boundary by `validateCalendarEvent`. |
|
|
110
|
+
| 4, 5 | **C2** Single drop pipeline | Exactly one function (`applyMoveToEvent`) converts a UI drop → new endpoints. Mouse, keyboard, touch all reach it once. |
|
|
111
|
+
| 4 | **C3** Source zone preserved per-endpoint | Cross-zone events are first-class. A Tokyo→Vienna flight keeps both endpoints in their source zones across every drag. |
|
|
112
|
+
| 5 | **C4** DST disambiguation explicit | `DstPolicy` is a required arg of every wall-time → instant conversion. No silent default. |
|
|
113
|
+
| 3, 4 | **C5** Display zone vs source zone separate | `EventDropPayload.target.displayZone` (what the user saw) and `next.start.timeZoneId` (where the event lives) are distinct fields. |
|
|
114
|
+
| 9 | **C6** Three independent display decisions | `locale`, `dateStyle`, `timeStyle`, `hour12` are independent setters. `buildFormatOptions` is the only `Intl` merge point. |
|
|
115
|
+
| spirit | **C7** Reactivity by reads | Every consumer function (`canDrop`, `eventsLoader`, `eventRenderer`) is read on every invocation, never captured at setup. |
|
|
116
|
+
| 5 | **C8** Recurrence is a first-class type | `RecurringSeries` lives separately from `CalendarEvent`. `expandSeries` ships as a throwing stub until Phase 4. |
|
|
117
|
+
|
|
118
|
+
The conformance test suite at `src/core/__tests__/timezone/` pins
|
|
119
|
+
every invariant.
|
|
120
|
+
|
|
121
|
+
## What's NOT in the public surface (intentional)
|
|
122
|
+
|
|
123
|
+
- **`EventIndex`** — bucketing utility kept private. Consumers wanting
|
|
124
|
+
a sidebar / minimap will get a public composable in Phase 4+ (otherwise
|
|
125
|
+
misuse silently drifts from the actual grid).
|
|
126
|
+
- **ISO strings on event start/end** — would re-introduce the
|
|
127
|
+
Article-1 "guess the zone" failure mode. Use `Temporal.ZonedDateTime`
|
|
128
|
+
or `Temporal.PlainDate`. The wire helpers above handle deserialisation.
|
|
129
|
+
- **`Date` / `PlainDateTime` / `Instant`** — same reason. Throws at
|
|
130
|
+
the events-source watch with the offending event id named.
|
|
131
|
+
- **`'EST'` / `'CET'` / `'GMT'` abbreviations** — Article 2 calls these
|
|
132
|
+
out as ambiguous. Use full IANA zones (`Europe/Vienna`,
|
|
133
|
+
`America/New_York`, etc.). Temporal's polyfill resolves abbreviations
|
|
134
|
+
to fixed-offset zones, but consumers are encouraged not to.
|
|
135
|
+
|
|
136
|
+
## Cross-zone events — what "preserve source zone" actually means
|
|
137
|
+
|
|
138
|
+
A flight Tokyo → Vienna stored as
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
{
|
|
142
|
+
id: 'flight',
|
|
143
|
+
start: Temporal.ZonedDateTime.from('2026-06-15T22:00:00[Asia/Tokyo]'),
|
|
144
|
+
end: Temporal.ZonedDateTime.from('2026-06-16T06:00:00[Europe/Vienna]'),
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
renders correctly in any display zone — the calendar always shows the
|
|
149
|
+
right wall-clock per the user's display zone. When the user **drags
|
|
150
|
+
the start handle** to a new slot in the Vienna-rendered calendar:
|
|
151
|
+
|
|
152
|
+
- **C3 means the event's `start.timeZoneId` stays `'Asia/Tokyo'`** in
|
|
153
|
+
the drop payload. The stored intent is preserved.
|
|
154
|
+
- This means `next.start.toString()` reports a **Tokyo wall-time** —
|
|
155
|
+
which is *not* the Vienna wall-time the user clicked. If the user
|
|
156
|
+
clicked 14:00 Vienna in summer, `next.start` is the Tokyo wall-time
|
|
157
|
+
of that same instant (≈ 21:00 Tokyo).
|
|
158
|
+
- The drop payload's `target.date` + `target.minutes` + `target.displayZone`
|
|
159
|
+
capture what the user's eyes saw (Article 3 — fairness contract).
|
|
160
|
+
- If a consumer needs the Vienna wall-time directly, they can compute
|
|
161
|
+
`next.start.withTimeZone('Europe/Vienna').toPlainTime()` on the spot.
|
|
162
|
+
|
|
163
|
+
**Why this design:** Article 4 is explicit — store intent, derive math.
|
|
164
|
+
A flight scheduled in Tokyo means "depart at this wall-clock in Tokyo";
|
|
165
|
+
re-anchoring start to Vienna would silently destroy that intent the
|
|
166
|
+
moment a user (or admin) drags the event in a different display zone.
|
|
167
|
+
The trade-off is that consumers reading `next.start.toString()` see
|
|
168
|
+
the source-zone wall-time, not the click-zone wall-time.
|
|
169
|
+
|
|
170
|
+
For a meeting that should **be re-anchored to the click-zone** (a
|
|
171
|
+
local meeting that just happens to be viewed from somewhere else), set
|
|
172
|
+
`event.start.timeZoneId === builder.timezone()` — when source and
|
|
173
|
+
display zone match, click-zone and source-zone wall-times are identical.
|
|
174
|
+
|
|
175
|
+
## Standalone sub-views
|
|
176
|
+
|
|
177
|
+
Each sub-view works without the `<CoarCalendar>` shell — useful for
|
|
178
|
+
sidebars, widgets, embedded month-pickers. The flat `CalendarBuilder`
|
|
179
|
+
carries every view's config, so a sub-view consumes the SAME builder
|
|
180
|
+
type the shell does:
|
|
181
|
+
|
|
182
|
+
```vue
|
|
183
|
+
<script setup lang="ts">
|
|
184
|
+
import { CoarMonthView, useMonthView, Temporal } from '@cocoar/vue-calendar';
|
|
185
|
+
|
|
186
|
+
const { builder } = useMonthView(); // pre-locks view + availableViews
|
|
187
|
+
builder.timezone('Europe/Vienna').date(Temporal.PlainDate.from('2026-06-15'));
|
|
188
|
+
</script>
|
|
189
|
+
|
|
190
|
+
<template>
|
|
191
|
+
<CoarMonthView :builder="builder" />
|
|
192
|
+
</template>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
When mounted standalone, the sub-view sets `state.view` to its
|
|
196
|
+
intended value and mounts its own `useViewWindow` (single writer per
|
|
197
|
+
the C5 invariant).
|
|
198
|
+
|
|
199
|
+
## Known scope cuts (post-2.0.0)
|
|
200
|
+
|
|
201
|
+
- **Recurrence engine** — `expandSeries(...)` is a typed throwing stub.
|
|
202
|
+
The contract (`RecurringSeries` shape, `dstPolicy` argument) is stable,
|
|
203
|
+
but the engine wires up in Phase 4. Consumers porting from FullCalendar /
|
|
204
|
+
ICS feeds should construct concrete events in their data layer for now.
|
|
205
|
+
- **Global-event type** — Article 5's "global events" (same instant
|
|
206
|
+
worldwide — product launches, livestreams) have no first-class
|
|
207
|
+
`event.kind === 'global'` discriminator. Consumers model them as
|
|
208
|
+
`Temporal.ZonedDateTime` in `'UTC'` and accept that the calendar
|
|
209
|
+
re-renders them in the display zone (which is the conceptually correct
|
|
210
|
+
behaviour, just not the typed-vocabulary the article recommends).
|
|
211
|
+
- **Tzdb update / future-event recalc** — Article 4 § "What Happens When
|
|
212
|
+
Rules Change" is a consumer concern. The library stores
|
|
213
|
+
`Temporal.ZonedDateTime` (which contains the IANA zone, not a baked-in
|
|
214
|
+
offset), so re-rendering after a tzdb update is automatic. Recalculating
|
|
215
|
+
cached `instantUtc` values in your data layer is consumer code, not
|
|
216
|
+
calendar code.
|
|
217
|
+
- **Timezone abbreviations (`'EST'`, `'CET'`, etc.)** — the underlying
|
|
218
|
+
Temporal polyfill resolves these to fixed-offset zones rather than
|
|
219
|
+
rejecting them. The calendar accepts whatever Temporal accepts.
|
|
220
|
+
- **`onMoreClick`** — typed setter exists, but the "+N more" overflow
|
|
221
|
+
surface in `<CoarMonthView>` is a post-2.0 visual-polish item. Setting
|
|
222
|
+
the handler today emits a one-shot dev-warn; the handler starts firing
|
|
223
|
+
once the overflow surface ships.
|
|
224
|
+
|
|
225
|
+
## Architecture decisions (locked)
|
|
226
|
+
|
|
227
|
+
In short:
|
|
228
|
+
|
|
229
|
+
- **D1** — `RecurringSeries` is a first-class type from day one;
|
|
230
|
+
`expandSeries` throws informatively until Phase 4 wires the engine.
|
|
231
|
+
- **D2** — All-day drops preserve **day-count duration only**.
|
|
232
|
+
Calendar UIs don't have a "+1 month" gesture; spans are always
|
|
233
|
+
preserved as day-counts (May 5–10 → drag onto June 5 → June 5–10).
|
|
234
|
+
- **D3** — `parseScheduledTime` / `formatScheduledTime` /
|
|
235
|
+
`parsePlainDate` are public helpers (the wire-contract surface).
|
|
236
|
+
- **D4** — `canDrop` runs on every hit-test. If you have expensive
|
|
237
|
+
validation logic, memoize it consumer-side; the library reading fresh
|
|
238
|
+
state is the correct behaviour.
|
|
239
|
+
- **D5** — One `dstPolicy` per builder. Per-operation policies are a
|
|
240
|
+
YAGNI for now.
|
|
241
|
+
|
|
242
|
+
## Status
|
|
243
|
+
|
|
244
|
+
Feature-complete for the initial release (Temporal-only public API,
|
|
245
|
+
C1–C8 invariants, all four views, drag-and-drop, virtualization). The
|
|
246
|
+
repo's release version is calculated by GitVersion at publish time, so
|
|
247
|
+
this package's `package.json` carries a placeholder `0.0.1` like
|
|
248
|
+
everything else in the workspace — the actual semver number lives in
|
|
249
|
+
CI.
|
|
250
|
+
|
|
251
|
+
Post-launch backlog: recurrence engine (`expandSeries` is a typed
|
|
252
|
+
throwing stub today), Ctrl+C / Ctrl+V copy-paste, "+ N more" overflow
|
|
253
|
+
signal in `<CoarMonthView>`, preemptive DST-gap visual marker.
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
Apache-2.0. Same as the rest of the Cocoar UI Vue suite.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-fixtures.d.ts","sourceRoot":"","sources":["../../src/__test-utils__/event-fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,aAAY,KAAG,QAAQ,CAAC,aAKxD,CAAC;AAEF,eAAO,MAAM,EAAE,GAAI,KAAK,MAAM,KAAG,QAAQ,CAAC,SACZ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViewWindow } from '../core';
|
|
2
|
+
/** Privileged method symbol — see `CalendarBuilder` for the impl. */
|
|
3
|
+
export declare const SET_VISIBLE_RANGE: unique symbol;
|
|
4
|
+
/** Privileged method symbol — see `CalendarBuilder` for the impl. */
|
|
5
|
+
export declare const INVALIDATE_LOADER_CACHE: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Type-narrowed surface a `CalendarBuilder` exposes to internal
|
|
8
|
+
* composables (only `useViewWindow` today).
|
|
9
|
+
*/
|
|
10
|
+
export interface PrivilegedBuilder {
|
|
11
|
+
[SET_VISIBLE_RANGE](window: ViewWindow | null): void;
|
|
12
|
+
[INVALIDATE_LOADER_CACHE](): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=calendar-builder-internals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-builder-internals.d.ts","sourceRoot":"","sources":["../../src/builders/calendar-builder-internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,OAAO,MAAkD,CAAC;AAE1F,qEAAqE;AACrE,eAAO,MAAM,uBAAuB,EAAE,OAAO,MAE5C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IACrD,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC;CACnC"}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { MaybeRefOrGetter, Ref, ShallowRef } from 'vue';
|
|
2
|
+
import { CalendarEvent, CalendarView, DayOfWeek, ViewWindow, Temporal } from '../core';
|
|
3
|
+
import { SET_VISIBLE_RANGE, INVALIDATE_LOADER_CACHE } from './calendar-builder-internals';
|
|
4
|
+
import { CalendarDensity, CanDropFn, DateClickHandler, DayHeaderRenderer, DstPolicy, EventClickHandler, EventDoubleClickHandler, EventDropHandler, EventRenderer, EventsLoader, MoreClickHandler, RangeChangeHandler, TimeClickHandler, TimeRange } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Reactive state owned by a `CalendarBuilder`. All reads go through
|
|
7
|
+
* `toValue()` for `MaybeRefOrGetter<T>` fields and `.value` for
|
|
8
|
+
* `Ref<T>` fields. Function fields (canDrop / handlers / renderers)
|
|
9
|
+
* are stored verbatim and called at the read site.
|
|
10
|
+
*/
|
|
11
|
+
export interface CalendarBuilderState<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
12
|
+
events: MaybeRefOrGetter<CalendarEvent<TMeta>[]> | null;
|
|
13
|
+
eventsLoader: EventsLoader<TMeta> | null;
|
|
14
|
+
/** Display zone (C5). Defaults to the browser's IANA zone. */
|
|
15
|
+
timezone: MaybeRefOrGetter<string>;
|
|
16
|
+
locale: MaybeRefOrGetter<string>;
|
|
17
|
+
/** Locale-derived when undefined (Article 9 — defaults are not decisions). */
|
|
18
|
+
firstDayOfWeek: MaybeRefOrGetter<DayOfWeek | undefined>;
|
|
19
|
+
density: MaybeRefOrGetter<CalendarDensity>;
|
|
20
|
+
/** Intl date style (C6 — independent of timeStyle / hour12).
|
|
21
|
+
* Locale-derived when undefined (Article 9). */
|
|
22
|
+
dateStyle: MaybeRefOrGetter<'short' | 'medium' | 'long' | 'full' | undefined>;
|
|
23
|
+
/** Intl time style (C6). */
|
|
24
|
+
/** Intl time style (C6). Locale-derived when undefined (Article 9). */
|
|
25
|
+
timeStyle: MaybeRefOrGetter<'short' | 'medium' | 'long' | undefined>;
|
|
26
|
+
/** 12h vs 24h clock (C6 — independent of locale). */
|
|
27
|
+
hour12: MaybeRefOrGetter<boolean | undefined>;
|
|
28
|
+
/** DST disambiguation policy (C4). Default `'compatible'`. */
|
|
29
|
+
dstPolicy: MaybeRefOrGetter<DstPolicy>;
|
|
30
|
+
/** Subset of CalendarView the view-switcher offers. */
|
|
31
|
+
availableViews: MaybeRefOrGetter<readonly CalendarView[]>;
|
|
32
|
+
timeRange: MaybeRefOrGetter<TimeRange>;
|
|
33
|
+
slotDuration: MaybeRefOrGetter<number>;
|
|
34
|
+
pixelsPerHour: MaybeRefOrGetter<number>;
|
|
35
|
+
maxEventsPerCell: MaybeRefOrGetter<number>;
|
|
36
|
+
agendaLengthDays: MaybeRefOrGetter<number>;
|
|
37
|
+
showEmptyDays: MaybeRefOrGetter<boolean>;
|
|
38
|
+
/** Active view. Held as Ref so api.setView can write back. */
|
|
39
|
+
view: Ref<CalendarView>;
|
|
40
|
+
/** Cursor date. Held as Ref so api.next/prev/goTo can write back. */
|
|
41
|
+
date: Ref<Temporal.PlainDate>;
|
|
42
|
+
canDrop: CanDropFn<TMeta> | null;
|
|
43
|
+
eventRenderer: EventRenderer<TMeta> | null;
|
|
44
|
+
dayHeaderRenderer: DayHeaderRenderer | null;
|
|
45
|
+
onEventClick: EventClickHandler<TMeta> | null;
|
|
46
|
+
onEventDoubleClick: EventDoubleClickHandler<TMeta> | null;
|
|
47
|
+
onEventDrop: EventDropHandler<TMeta> | null;
|
|
48
|
+
onDateClick: DateClickHandler | null;
|
|
49
|
+
onTimeClick: TimeClickHandler | null;
|
|
50
|
+
onMoreClick: MoreClickHandler<TMeta> | null;
|
|
51
|
+
onRangeChange: RangeChangeHandler | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Imperative + reactive surface returned alongside the builder.
|
|
55
|
+
*/
|
|
56
|
+
export interface CalendarApi<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
57
|
+
/** `true` while at least one `eventsLoader` invocation is in flight. */
|
|
58
|
+
readonly loading: Readonly<Ref<boolean>>;
|
|
59
|
+
/** Currently rendered window. `null` before first paint. */
|
|
60
|
+
readonly visibleRange: Readonly<ShallowRef<ViewWindow | null>>;
|
|
61
|
+
/** `true` once the active view's grid has reported ready. */
|
|
62
|
+
readonly gridReady: Readonly<Ref<boolean>>;
|
|
63
|
+
goTo(date: Temporal.PlainDate): void;
|
|
64
|
+
goToToday(): void;
|
|
65
|
+
next(): void;
|
|
66
|
+
prev(): void;
|
|
67
|
+
setView(view: CalendarView): void;
|
|
68
|
+
/** Wired in Session 3 (component-side). No-op until then. */
|
|
69
|
+
scrollToTime(time: Temporal.PlainTime): void;
|
|
70
|
+
/** Wired in Session 3 (component-side). No-op until then. */
|
|
71
|
+
scrollToDate(date: Temporal.PlainDate): void;
|
|
72
|
+
/** Invalidate the entire loader cache and re-fetch the current window. */
|
|
73
|
+
refresh(): void;
|
|
74
|
+
/** Invalidate any cached entries that intersect `window` and re-fetch
|
|
75
|
+
* if the current window intersects. */
|
|
76
|
+
refreshRange(window: ViewWindow): void;
|
|
77
|
+
/** Synchronous read of the current window. `null` before first paint. */
|
|
78
|
+
getVisibleRange(): ViewWindow | null;
|
|
79
|
+
/** Snapshot of events visible in the current window — from
|
|
80
|
+
* `events()` source if set, else the loader cache (or empty if no
|
|
81
|
+
* cache hit yet). */
|
|
82
|
+
getVisibleEvents(): CalendarEvent<TMeta>[];
|
|
83
|
+
}
|
|
84
|
+
export declare class CalendarBuilder<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
85
|
+
/** Reactive state — single source of truth (C7 read site). */
|
|
86
|
+
readonly state: CalendarBuilderState<TMeta>;
|
|
87
|
+
/** Imperative + reactive surface. */
|
|
88
|
+
readonly api: CalendarApi<TMeta>;
|
|
89
|
+
private readonly _loading;
|
|
90
|
+
private readonly _visibleRange;
|
|
91
|
+
private readonly _gridReady;
|
|
92
|
+
/** Active view's scroll-to-time delegate. View registers on mount
|
|
93
|
+
* via `_setScrollToTime(fn)` and clears on unmount. */
|
|
94
|
+
private _scrollToTimeImpl;
|
|
95
|
+
/** Active view's scroll-to-date delegate. */
|
|
96
|
+
private _scrollToDateImpl;
|
|
97
|
+
/** Map<windowKey, events>. Wrapped in shallowRef so cache swaps
|
|
98
|
+
* trigger reactivity for `getVisibleEvents`. */
|
|
99
|
+
private readonly _loaderCache;
|
|
100
|
+
/** In-flight loader counter — `loading.value = (counter > 0)`.
|
|
101
|
+
* Counter (not boolean) so concurrent fetches don't race the flag. */
|
|
102
|
+
private _inFlight;
|
|
103
|
+
/** Pending debounced loader handle — cleared on subsequent
|
|
104
|
+
* `_setVisibleRange` calls within the debounce window. */
|
|
105
|
+
private _debounceHandle;
|
|
106
|
+
/**
|
|
107
|
+
* Generation counter — bumped on `refresh()` so an in-flight loader
|
|
108
|
+
* whose result arrives AFTER an invalidation is discarded instead
|
|
109
|
+
* of poisoning the cache.
|
|
110
|
+
*/
|
|
111
|
+
private _generation;
|
|
112
|
+
/** Effect scope for builder-owned watchers (audit fix #1 — events
|
|
113
|
+
* source watcher). Cleaned up if/when a `.dispose()` is added in
|
|
114
|
+
* Phase 4+; currently builders live for the page lifetime. */
|
|
115
|
+
private readonly _scope;
|
|
116
|
+
/** Tracks event-array references already validated, so re-renders
|
|
117
|
+
* don't re-walk them. Per-event-object validation; consumers who
|
|
118
|
+
* recreate event objects on every render pay the validation cost
|
|
119
|
+
* every render (cheap — a few `instanceof` checks). */
|
|
120
|
+
private readonly _validatedEventObjects;
|
|
121
|
+
private constructor();
|
|
122
|
+
/** Factory — keep `new` private so the only entry point is
|
|
123
|
+
* `useCalendar()`. */
|
|
124
|
+
static create<TMeta extends Record<string, unknown> = Record<string, unknown>>(): CalendarBuilder<TMeta>;
|
|
125
|
+
/**
|
|
126
|
+
* Bind the event source. Mutually exclusive with `eventsLoader()`
|
|
127
|
+
* — calling this clears any previously-set loader and drops the
|
|
128
|
+
* cache (cache only makes sense for loader mode).
|
|
129
|
+
*
|
|
130
|
+
* The library accepts ONLY `Temporal.ZonedDateTime` (timed) or
|
|
131
|
+
* `Temporal.PlainDate` (all-day) on event start/end. Strings,
|
|
132
|
+
* `Date`, floating `PlainDateTime` etc. throw at index-insert via
|
|
133
|
+
* `validateCalendarEvent` (C1).
|
|
134
|
+
*/
|
|
135
|
+
events(source: MaybeRefOrGetter<CalendarEvent<TMeta>[]>): this;
|
|
136
|
+
/**
|
|
137
|
+
* Bind a calendar-managed loader. Called whenever the visible
|
|
138
|
+
* window changes; results cached per `(view, timezone, start, end)`
|
|
139
|
+
* so navigation back to a previously-seen window doesn't re-fetch.
|
|
140
|
+
* Mutually exclusive with `events()`.
|
|
141
|
+
*/
|
|
142
|
+
eventsLoader(loader: EventsLoader<TMeta>): this;
|
|
143
|
+
/** C5 — Display zone (IANA). Source zones on individual events
|
|
144
|
+
* remain independent and per-endpoint preserved (C3). */
|
|
145
|
+
timezone(tz: MaybeRefOrGetter<string>): this;
|
|
146
|
+
locale(loc: MaybeRefOrGetter<string>): this;
|
|
147
|
+
firstDayOfWeek(d: MaybeRefOrGetter<DayOfWeek>): this;
|
|
148
|
+
density(d: MaybeRefOrGetter<CalendarDensity>): this;
|
|
149
|
+
/** C6 — independent of timeStyle / hour12. */
|
|
150
|
+
dateStyle(s: MaybeRefOrGetter<'short' | 'medium' | 'long' | 'full'>): this;
|
|
151
|
+
/** C6 — independent of dateStyle / hour12. */
|
|
152
|
+
timeStyle(s: MaybeRefOrGetter<'short' | 'medium' | 'long'>): this;
|
|
153
|
+
/**
|
|
154
|
+
* C6 — independent of locale. `undefined` lets Intl derive from
|
|
155
|
+
* locale (default); `true` / `false` overrides explicitly.
|
|
156
|
+
*/
|
|
157
|
+
hour12(h: MaybeRefOrGetter<boolean | undefined>): this;
|
|
158
|
+
/**
|
|
159
|
+
* C4 — DST disambiguation policy. Read by every wall-time → instant
|
|
160
|
+
* conversion in the drop pipeline. Default `'compatible'`.
|
|
161
|
+
*/
|
|
162
|
+
dstPolicy(p: MaybeRefOrGetter<DstPolicy>): this;
|
|
163
|
+
/**
|
|
164
|
+
* Active view. Setter accepts a `Ref<CalendarView>` (two-way
|
|
165
|
+
* binding) or a plain value (wrapped into an internal ref).
|
|
166
|
+
* Function-getters are rejected — `api.setView` must be able to
|
|
167
|
+
* write back.
|
|
168
|
+
*/
|
|
169
|
+
view(v: Ref<CalendarView> | CalendarView): this;
|
|
170
|
+
availableViews(views: MaybeRefOrGetter<readonly CalendarView[]>): this;
|
|
171
|
+
/**
|
|
172
|
+
* Cursor date. Setter accepts a `Ref<PlainDate>` or a plain
|
|
173
|
+
* `PlainDate`; function-getters rejected (api.next/prev/goTo
|
|
174
|
+
* must write).
|
|
175
|
+
*/
|
|
176
|
+
date(d: Ref<Temporal.PlainDate> | Temporal.PlainDate): this;
|
|
177
|
+
/** Time-grid view setting (`day` / `week`). */
|
|
178
|
+
timeRange(r: MaybeRefOrGetter<TimeRange>): this;
|
|
179
|
+
slotDuration(minutes: MaybeRefOrGetter<number>): this;
|
|
180
|
+
pixelsPerHour(px: MaybeRefOrGetter<number>): this;
|
|
181
|
+
/** Month view setting — pills before "+N more". */
|
|
182
|
+
maxEventsPerCell(n: MaybeRefOrGetter<number>): this;
|
|
183
|
+
/** Agenda view setting — number of days the linear list covers. */
|
|
184
|
+
agendaLengthDays(n: MaybeRefOrGetter<number>): this;
|
|
185
|
+
/** Agenda view setting — show day headers even when no events. */
|
|
186
|
+
showEmptyDays(b: MaybeRefOrGetter<boolean>): this;
|
|
187
|
+
/**
|
|
188
|
+
* Drop validator. Read on EVERY hit-test (C7 + D4 — no library-
|
|
189
|
+
* side memoization). If you do expensive work in here, memoize
|
|
190
|
+
* client-side; the library reading fresh state is the correct
|
|
191
|
+
* behaviour and intentionally not cached.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* // Consumer-side memoization for expensive checks:
|
|
196
|
+
* const memoized = computed(() => {
|
|
197
|
+
* const rules = expensivelyCompiledRules.value;
|
|
198
|
+
* return (event, target) => rules.matches(event, target);
|
|
199
|
+
* });
|
|
200
|
+
* builder.canDrop(memoized.value);
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
canDrop(fn: CanDropFn<TMeta>): this;
|
|
204
|
+
eventRenderer(r: EventRenderer<TMeta>): this;
|
|
205
|
+
dayHeaderRenderer(r: DayHeaderRenderer): this;
|
|
206
|
+
onEventClick(h: EventClickHandler<TMeta>): this;
|
|
207
|
+
onEventDoubleClick(h: EventDoubleClickHandler<TMeta>): this;
|
|
208
|
+
onEventDrop(h: EventDropHandler<TMeta>): this;
|
|
209
|
+
onDateClick(h: DateClickHandler): this;
|
|
210
|
+
onTimeClick(h: TimeClickHandler): this;
|
|
211
|
+
/**
|
|
212
|
+
* Audit Session 5 N1 — `onMoreClick` is wired by month-view's
|
|
213
|
+
* "+N more" overflow surface, which is a Session 3.5+ visual
|
|
214
|
+
* polish item. The setter is honoured today (handler stored on
|
|
215
|
+
* state, read-on-fire), but the overflow trigger is not yet
|
|
216
|
+
* implemented in `<CoarMonthView>`. A one-shot dev-warn surfaces
|
|
217
|
+
* the gap so consumers don't ship features that never fire.
|
|
218
|
+
*/
|
|
219
|
+
onMoreClick(h: MoreClickHandler<TMeta>): this;
|
|
220
|
+
onRangeChange(h: RangeChangeHandler): this;
|
|
221
|
+
private _goTo;
|
|
222
|
+
private _goToToday;
|
|
223
|
+
private _navigate;
|
|
224
|
+
private _setView;
|
|
225
|
+
/**
|
|
226
|
+
* SOLE writer of `_visibleRange`. Called by `useViewWindow` only.
|
|
227
|
+
*
|
|
228
|
+
* **Audit fix #2 (Session 2):** symbol-keyed instead of
|
|
229
|
+
* underscore-prefixed-public so consumers cannot forge windows by
|
|
230
|
+
* calling `builder._setVisibleRange(...)` from outside. The symbol
|
|
231
|
+
* is exported from `calendar-builder-internals.ts` which is
|
|
232
|
+
* intentionally NOT in `index.ts`'s public surface.
|
|
233
|
+
*
|
|
234
|
+
* Side effects:
|
|
235
|
+
* 1. Updates the readonly `api.visibleRange` ref.
|
|
236
|
+
* 2. Fires the consumer's `onRangeChange` handler (deduped via
|
|
237
|
+
* window-equality check — no-op if the window didn't change).
|
|
238
|
+
* 3. Schedules a debounced loader call if `eventsLoader` is set
|
|
239
|
+
* and the cache doesn't already have this window.
|
|
240
|
+
*
|
|
241
|
+
* @internal symbol-keyed; reachable only via the internal symbol.
|
|
242
|
+
*/
|
|
243
|
+
[SET_VISIBLE_RANGE](window: ViewWindow | null): void;
|
|
244
|
+
/**
|
|
245
|
+
* Invalidate the entire loader cache. Called by `api.refresh()`.
|
|
246
|
+
* Bumps the generation counter so any in-flight loader resolves
|
|
247
|
+
* into the void instead of poisoning fresh data.
|
|
248
|
+
*
|
|
249
|
+
* @internal symbol-keyed; reachable only via the internal symbol.
|
|
250
|
+
*/
|
|
251
|
+
[INVALIDATE_LOADER_CACHE](): void;
|
|
252
|
+
private _maybeScheduleLoad;
|
|
253
|
+
private _runLoader;
|
|
254
|
+
/**
|
|
255
|
+
* Audit fix #1 — validate every event in `events` against C1 at the
|
|
256
|
+
* runtime boundary. WeakSet-memoized per-event-object so repeated
|
|
257
|
+
* renders of the same array don't pay the cost.
|
|
258
|
+
*
|
|
259
|
+
* Throws on the first bad event with `validateCalendarEvent`'s
|
|
260
|
+
* error (which names the event id). Loader path catches this in
|
|
261
|
+
* the `.catch` and logs without caching; events-source path lets
|
|
262
|
+
* it propagate so the consumer's render fails loudly (Article 9 —
|
|
263
|
+
* silent partial-render hiding bad data is the worse outcome).
|
|
264
|
+
*/
|
|
265
|
+
private _validateEvents;
|
|
266
|
+
private _warnedScrollMethods;
|
|
267
|
+
/**
|
|
268
|
+
* Audit fix #16 — `scrollTo*` is wired by component mount in
|
|
269
|
+
* Session 3. Until then, calling it is a no-op; in dev we log
|
|
270
|
+
* once-per-method so consumer e2e tests don't false-pass.
|
|
271
|
+
*/
|
|
272
|
+
private _warnScrollNotWired;
|
|
273
|
+
private _refresh;
|
|
274
|
+
private _refreshRange;
|
|
275
|
+
private _getVisibleEvents;
|
|
276
|
+
/**
|
|
277
|
+
* Snapshot of the loader cache keys for diagnostics / tests.
|
|
278
|
+
* Not part of the public API surface.
|
|
279
|
+
*
|
|
280
|
+
* @internal
|
|
281
|
+
*/
|
|
282
|
+
_debug_cacheKeys(): string[];
|
|
283
|
+
/**
|
|
284
|
+
* Current in-flight counter for diagnostics / tests.
|
|
285
|
+
*
|
|
286
|
+
* @internal
|
|
287
|
+
*/
|
|
288
|
+
_debug_inFlight(): number;
|
|
289
|
+
/** @internal */
|
|
290
|
+
_setScrollToTime(fn: ((time: Temporal.PlainTime) => void) | undefined): void;
|
|
291
|
+
/** @internal */
|
|
292
|
+
_setScrollToDate(fn: ((date: Temporal.PlainDate) => void) | undefined): void;
|
|
293
|
+
/** @internal */
|
|
294
|
+
_setGridReady(ready: boolean): void;
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=calendar-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-builder.d.ts","sourceRoot":"","sources":["../../src/builders/calendar-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CalendarEvent } from '../core';
|
|
2
|
+
export interface EventZoneHints {
|
|
3
|
+
/** True when the timed event's source zone is `'UTC'`. */
|
|
4
|
+
isUtcAnchored: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* The event's source `timeZoneId` IF it differs from the display
|
|
7
|
+
* zone AND the event is NOT UTC-anchored (UTC-anchored gets its own
|
|
8
|
+
* "global" hint, separate semantic). `null` otherwise.
|
|
9
|
+
*/
|
|
10
|
+
sourceZone: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute zone-hint flags for the calendar's default decoration layer.
|
|
14
|
+
*
|
|
15
|
+
* All-day events (`start instanceof Temporal.PlainDate`) have no zone
|
|
16
|
+
* by definition — they return `NO_HINTS` so callers can short-circuit
|
|
17
|
+
* before rendering any decoration.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getEventZoneHints(event: CalendarEvent, displayZone: string | undefined): EventZoneHints;
|
|
20
|
+
//# sourceMappingURL=event-zone-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-zone-hints.d.ts","sourceRoot":"","sources":["../../src/builders/event-zone-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,aAAa,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,cAAc,CAMhB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FunctionalComponent } from 'vue';
|
|
2
|
+
import { Temporal } from '../core';
|
|
3
|
+
import { DayHeaderRenderer, EventRenderer, EventRendererCtx } from './types';
|
|
4
|
+
export interface RenderEventProps {
|
|
5
|
+
renderer: EventRenderer;
|
|
6
|
+
ctx: EventRendererCtx;
|
|
7
|
+
}
|
|
8
|
+
export declare const RenderEvent: FunctionalComponent<RenderEventProps>;
|
|
9
|
+
export interface DayHeaderCtx {
|
|
10
|
+
date: Temporal.PlainDate;
|
|
11
|
+
isToday: boolean;
|
|
12
|
+
isWeekend: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface RenderDayHeaderProps {
|
|
15
|
+
renderer: DayHeaderRenderer;
|
|
16
|
+
ctx: DayHeaderCtx;
|
|
17
|
+
}
|
|
18
|
+
export declare const RenderDayHeader: FunctionalComponent<RenderDayHeaderProps>;
|
|
19
|
+
//# sourceMappingURL=render-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-helpers.d.ts","sourceRoot":"","sources":["../../src/builders/render-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAkB,KAAK,mBAAmB,EAA0B,MAAM,KAAK,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAElF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,aAAa,CAAC;IACxB,GAAG,EAAE,gBAAgB,CAAC;CACvB;AAED,eAAO,MAAM,WAAW,EAAE,mBAAmB,CAAC,gBAAgB,CAa7D,CAAC;AAIF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,GAAG,EAAE,YAAY,CAAC;CACnB;AAED,eAAO,MAAM,eAAe,EAAE,mBAAmB,CAAC,oBAAoB,CAQrE,CAAC"}
|