@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
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Temporal } from '@js-temporal/polyfill';
|
|
2
|
+
/**
|
|
3
|
+
* A single scheduled item.
|
|
4
|
+
*
|
|
5
|
+
* `start` (and the matching `end`) discriminates the event shape:
|
|
6
|
+
* - `Temporal.ZonedDateTime` — timed event
|
|
7
|
+
* - `Temporal.PlainDate` — all-day event
|
|
8
|
+
*
|
|
9
|
+
* Recurring events are stored as rules (`rrule` + `rdate` +
|
|
10
|
+
* `exdate`) and expanded only for the visible window. A modified
|
|
11
|
+
* single occurrence is stored as a separate event with `parentId`
|
|
12
|
+
* and `recurrenceId` pointing at the original.
|
|
13
|
+
*/
|
|
14
|
+
export interface CalendarEvent<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
15
|
+
/**
|
|
16
|
+
* Stable identifier. For occurrences of a recurring event, this is
|
|
17
|
+
* the SERIES id — every expanded occurrence carries the same id.
|
|
18
|
+
* Distinguish individual occurrences by `recurrenceId`.
|
|
19
|
+
*/
|
|
20
|
+
id: string;
|
|
21
|
+
/**
|
|
22
|
+
* Start of the event.
|
|
23
|
+
* - `Temporal.ZonedDateTime` — timed event (carries local + IANA zone).
|
|
24
|
+
* - `Temporal.PlainDate` — all-day event.
|
|
25
|
+
*
|
|
26
|
+
* No other shapes accepted. Floating `PlainDateTime` throws because
|
|
27
|
+
* "local with no zone" is ambiguous; pass a `ZonedDateTime` with the
|
|
28
|
+
* intended source zone.
|
|
29
|
+
*/
|
|
30
|
+
start: Temporal.ZonedDateTime | Temporal.PlainDate;
|
|
31
|
+
/**
|
|
32
|
+
* End of the event, EXCLUSIVE. Must match `start`'s shape:
|
|
33
|
+
* - `start: ZonedDateTime` → `end?: ZonedDateTime` (any zone)
|
|
34
|
+
* - `start: PlainDate` → `end?: PlainDate`
|
|
35
|
+
*
|
|
36
|
+
* Cross-zone is allowed: `start.timeZoneId !== end.timeZoneId` is
|
|
37
|
+
* fine. The calendar renders in `builder.timezone()` (display zone)
|
|
38
|
+
* regardless.
|
|
39
|
+
*
|
|
40
|
+
* Defaults applied at index-insert if missing:
|
|
41
|
+
* - timed → `start.add({ minutes: 30 })`
|
|
42
|
+
* - all-day → `start.add({ days: 1 })`
|
|
43
|
+
*/
|
|
44
|
+
end?: Temporal.ZonedDateTime | Temporal.PlainDate;
|
|
45
|
+
/**
|
|
46
|
+
* Anything the consumer needs in their renderer. The default
|
|
47
|
+
* event card reads:
|
|
48
|
+
* - `meta.title?: string`
|
|
49
|
+
* - `meta.color?: string` — CSS color or token
|
|
50
|
+
* - `meta.icon?: string` — CoarIcon name
|
|
51
|
+
* Consumers needing more shape replace via the `#event` slot.
|
|
52
|
+
*/
|
|
53
|
+
meta?: TMeta;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `true` when the event is timed (`start` is a `ZonedDateTime`).
|
|
57
|
+
*
|
|
58
|
+
* Duck-checks `'timeZoneId'` on the start value rather than using
|
|
59
|
+
* `instanceof` — survives realm boundaries (workers, iframes) and
|
|
60
|
+
* stays cheap in hot loops.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isTimedEvent<T extends Record<string, unknown>>(e: CalendarEvent<T>): e is CalendarEvent<T> & {
|
|
63
|
+
start: Temporal.ZonedDateTime;
|
|
64
|
+
end?: Temporal.ZonedDateTime;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* `true` when the event is all-day (`start` is a `PlainDate`).
|
|
68
|
+
*/
|
|
69
|
+
export declare function isAllDayEvent<T extends Record<string, unknown>>(e: CalendarEvent<T>): e is CalendarEvent<T> & {
|
|
70
|
+
start: Temporal.PlainDate;
|
|
71
|
+
end?: Temporal.PlainDate;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Throws if `event` violates the article-4 contract.
|
|
75
|
+
*
|
|
76
|
+
* Called by `EventIndex.insert` / `replaceAll` — consumers don't
|
|
77
|
+
* call this directly, but the error message names the offending id
|
|
78
|
+
* so it surfaces fast in dev.
|
|
79
|
+
*
|
|
80
|
+
* Reject reasons:
|
|
81
|
+
* - `start` is not `ZonedDateTime` or `PlainDate` (catches strings,
|
|
82
|
+
* `Date`, floating `PlainDateTime`, `Instant`, `PlainTime`,
|
|
83
|
+
* `null`, `undefined`, arrays, etc.)
|
|
84
|
+
* - `end` shape doesn't match `start`'s shape (mixed timed + all-day)
|
|
85
|
+
* - `end` is not strictly after `start`
|
|
86
|
+
*
|
|
87
|
+
* Recurrence fields (`rrule` / `rdate` / `exdate` / `recurrenceId` /
|
|
88
|
+
* `parentId`) were removed in Phase 8.8e; if the consumer's `meta`
|
|
89
|
+
* carries `rrule` / `rdate`, a one-shot dev-mode warn fires telling
|
|
90
|
+
* them the engine isn't yet wired (Phase 4 will return the feature).
|
|
91
|
+
*/
|
|
92
|
+
export declare function validateCalendarEvent(event: CalendarEvent): void;
|
|
93
|
+
/** Built-in view modes. Values stay as string literals so they
|
|
94
|
+
* serialize cleanly in URLs / state. */
|
|
95
|
+
export type CalendarView = 'month' | 'week' | 'day' | 'agenda' | 'timeline' | 'year';
|
|
96
|
+
/**
|
|
97
|
+
* A visible date range bounded to a single view mode.
|
|
98
|
+
*
|
|
99
|
+
* `start` is inclusive, `end` is exclusive. Both are ISO-8601
|
|
100
|
+
* strings. For all-day-aware views (month, week, day, agenda) the
|
|
101
|
+
* bounds are date-only (`'2026-04-13'`); for time-grid views with
|
|
102
|
+
* subhour granularity, datetimes (`'2026-04-13T00:00:00'`) keep
|
|
103
|
+
* the math clean.
|
|
104
|
+
*/
|
|
105
|
+
export interface ViewWindow {
|
|
106
|
+
view: CalendarView;
|
|
107
|
+
/** ISO date (or datetime) — first visible boundary, inclusive. */
|
|
108
|
+
start: string;
|
|
109
|
+
/** ISO date (or datetime) — last boundary, exclusive. */
|
|
110
|
+
end: string;
|
|
111
|
+
/**
|
|
112
|
+
* IANA display timezone the window is anchored to. Required by
|
|
113
|
+
* `eventsLoader` callbacks so they can construct an instant range
|
|
114
|
+
* for backend queries — without this, the same `'2026-04-13'`
|
|
115
|
+
* means a different 24h slice in `Pacific/Kiritimati` (UTC+14) and
|
|
116
|
+
* `America/Los_Angeles` (UTC-8), and a "show in my zone" toggle
|
|
117
|
+
* would silently fetch the wrong events. Article 4: a date is not
|
|
118
|
+
* a point in time; pin the date+zone before deriving the instant.
|
|
119
|
+
*/
|
|
120
|
+
timezone: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Recurrence rule for a `RecurringSeries`. The string form is an
|
|
124
|
+
* iCalendar RRULE (RFC 5545), e.g. `'FREQ=WEEKLY;BYDAY=MO,WE,FR'`.
|
|
125
|
+
*
|
|
126
|
+
* Stored as a plain string so the type contract doesn't lock the
|
|
127
|
+
* library into a specific RRULE parser. The engine (`core/recurrence.ts`)
|
|
128
|
+
* parses it at expansion time.
|
|
129
|
+
*/
|
|
130
|
+
export type RecurrencePattern = string;
|
|
131
|
+
/**
|
|
132
|
+
* A recurring series — generates `CalendarEvent` occurrences within
|
|
133
|
+
* a visible window via `expandSeries(series, window, dstPolicy)`.
|
|
134
|
+
*
|
|
135
|
+
* **Article 5 alignment.** Recurring events MUST be local-time +
|
|
136
|
+
* IANA zone, never UTC. The `dtstart` field carries the local intent
|
|
137
|
+
* (`ZonedDateTime` for timed series, `PlainDate` for all-day series);
|
|
138
|
+
* the engine applies the same `DstPolicy` (C4) that governs drag/drop
|
|
139
|
+
* to gap/overlap occurrences.
|
|
140
|
+
*
|
|
141
|
+
* **C8 — separate from `CalendarEvent`.** This type does NOT appear
|
|
142
|
+
* as `event.meta.rrule` or any other event-level field.
|
|
143
|
+
* `validateCalendarEvent` dev-warns if a consumer tries that, telling
|
|
144
|
+
* them to use `RecurringSeries` instead.
|
|
145
|
+
*
|
|
146
|
+
* **Engine status (Session 2 stub).** `expandSeries` throws
|
|
147
|
+
* `not implemented yet — Phase 4` from `recurrence-public.ts`. The
|
|
148
|
+
* engine integration ships in Phase 4. Type contract exists so
|
|
149
|
+
* consumers can build their data layer against it from day one.
|
|
150
|
+
*/
|
|
151
|
+
export interface RecurringSeries<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
152
|
+
/** Stable series identifier — every expanded occurrence carries
|
|
153
|
+
* this same id (distinguish occurrences via their `start` value). */
|
|
154
|
+
id: string;
|
|
155
|
+
/** RFC 5545 RRULE string. */
|
|
156
|
+
rrule: RecurrencePattern;
|
|
157
|
+
/**
|
|
158
|
+
* Start of the FIRST occurrence — Article 5 "store local intent".
|
|
159
|
+
* - `ZonedDateTime` — timed series (carries source IANA zone).
|
|
160
|
+
* - `PlainDate` — all-day series.
|
|
161
|
+
*/
|
|
162
|
+
dtstart: Temporal.ZonedDateTime | Temporal.PlainDate;
|
|
163
|
+
/**
|
|
164
|
+
* Optional duration applied to each generated occurrence's start
|
|
165
|
+
* to compute its end. **Day-count duration only (D2)** — no
|
|
166
|
+
* `Period` semantics. "+1 month" is permanently not supported for
|
|
167
|
+
* recurring occurrences because spans must be DST-stable.
|
|
168
|
+
* - For timed series: `{ minutes: number }` and/or `{ hours: number }`.
|
|
169
|
+
* - For all-day series: `{ days: number }`.
|
|
170
|
+
*/
|
|
171
|
+
duration?: {
|
|
172
|
+
minutes?: number;
|
|
173
|
+
hours?: number;
|
|
174
|
+
days?: number;
|
|
175
|
+
};
|
|
176
|
+
/** Explicit additional dates the rule didn't generate (RDATE). */
|
|
177
|
+
rdate?: ReadonlyArray<Temporal.ZonedDateTime | Temporal.PlainDate>;
|
|
178
|
+
/** Explicit dates to exclude from rule output (EXDATE). */
|
|
179
|
+
exdate?: ReadonlyArray<Temporal.ZonedDateTime | Temporal.PlainDate>;
|
|
180
|
+
/** Per-series metadata, copied onto every expanded occurrence. */
|
|
181
|
+
meta?: TMeta;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Window for `expandSeries` — the visible range to generate
|
|
185
|
+
* occurrences for. Bounds are inclusive-start / exclusive-end (same
|
|
186
|
+
* convention as `ViewWindow`).
|
|
187
|
+
*/
|
|
188
|
+
export interface RecurrenceExpansionWindow {
|
|
189
|
+
/** Inclusive start of the visible range. */
|
|
190
|
+
start: Temporal.ZonedDateTime;
|
|
191
|
+
/** Exclusive end of the visible range. */
|
|
192
|
+
end: Temporal.ZonedDateTime;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Resolved locale + timezone context the calendar uses for rendering.
|
|
196
|
+
*
|
|
197
|
+
* Resolved (not just "locale: 'de-AT'") because the calendar applies
|
|
198
|
+
* many small formatting decisions in tight loops and recomputing
|
|
199
|
+
* the resolution per render is wasteful. Build once, pass down.
|
|
200
|
+
*/
|
|
201
|
+
export interface ResolvedLocale {
|
|
202
|
+
/** BCP-47 language tag, e.g. `'de-AT'`. */
|
|
203
|
+
language: string;
|
|
204
|
+
/** 0 = Sun, 1 = Mon (ISO), …, 6 = Sat. */
|
|
205
|
+
firstDayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
206
|
+
/** IANA timezone, e.g. `'Europe/Vienna'`. */
|
|
207
|
+
timezone: string;
|
|
208
|
+
/** Derived from Intl — true for 12-hour locales, false for 24-hour. */
|
|
209
|
+
hour12: boolean;
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Temporal } from '@js-temporal/polyfill';
|
|
2
|
+
import { DayOfWeek } from './temporal';
|
|
3
|
+
import { CalendarView, ViewWindow } from './types';
|
|
4
|
+
export interface ViewWindowOptions {
|
|
5
|
+
view: CalendarView;
|
|
6
|
+
/** Cursor date — the date the user is "looking at". */
|
|
7
|
+
cursor: Temporal.PlainDate;
|
|
8
|
+
/** Used for week-aligned views (month, week). 0 = Sun … 6 = Sat. */
|
|
9
|
+
firstDayOfWeek: DayOfWeek;
|
|
10
|
+
/**
|
|
11
|
+
* Agenda-view length in days. Default 30 (about a month forward).
|
|
12
|
+
* Ignored for non-agenda views.
|
|
13
|
+
*/
|
|
14
|
+
agendaLengthDays?: number;
|
|
15
|
+
/**
|
|
16
|
+
* IANA display timezone — written through to `ViewWindow.timezone`
|
|
17
|
+
* so loaders can derive the correct instant range.
|
|
18
|
+
*/
|
|
19
|
+
timezone: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compute the visible date range for a calendar view.
|
|
23
|
+
*
|
|
24
|
+
* @returns ViewWindow with `start` inclusive and `end` exclusive,
|
|
25
|
+
* both as `YYYY-MM-DD` strings.
|
|
26
|
+
*/
|
|
27
|
+
export declare function computeViewWindow(opts: ViewWindowOptions): ViewWindow;
|
|
28
|
+
/**
|
|
29
|
+
* Iterate the days inside a window (inclusive start, exclusive end).
|
|
30
|
+
*
|
|
31
|
+
* Useful for views that render per-day (agenda groups, week columns).
|
|
32
|
+
*/
|
|
33
|
+
export declare function daysInWindow(window: ViewWindow): Generator<Temporal.PlainDate>;
|
|
34
|
+
/**
|
|
35
|
+
* Number of days in the window (always integer; end-start in days).
|
|
36
|
+
*/
|
|
37
|
+
export declare function windowDayCount(window: ViewWindow): number;
|
|
38
|
+
/**
|
|
39
|
+
* True when `date` falls inside `window` (inclusive start, exclusive end).
|
|
40
|
+
*/
|
|
41
|
+
export declare function windowContainsDate(window: ViewWindow, date: Temporal.PlainDate): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Navigate forward / backward by one logical "page" in the view.
|
|
44
|
+
*
|
|
45
|
+
* - day: ±1 day
|
|
46
|
+
* - week: ±7 days
|
|
47
|
+
* - month: ±1 month (from the cursor's calendar month)
|
|
48
|
+
* - agenda: ± agendaLengthDays
|
|
49
|
+
*
|
|
50
|
+
* Returns the new cursor for the next computeViewWindow call.
|
|
51
|
+
*/
|
|
52
|
+
export declare function navigateCursor(view: CalendarView, cursor: Temporal.PlainDate, direction: 'prev' | 'next', agendaLengthDays?: number): Temporal.PlainDate;
|
|
53
|
+
//# sourceMappingURL=viewWindow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewWindow.d.ts","sourceRoot":"","sources":["../../src/core/viewWindow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,uDAAuD;IACvD,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC;IAC3B,oEAAoE;IACpE,cAAc,EAAE,SAAS,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAiErE;AAID;;;;GAIG;AACH,wBAAiB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAO/E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAIzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,GAAG,OAAO,CAOxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,QAAQ,CAAC,SAAS,EAC1B,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,gBAAgB,SAAK,GACpB,QAAQ,CAAC,SAAS,CAyBpB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { MeasurementCache } from './measurementCache';
|
|
2
|
+
export interface Range1D {
|
|
3
|
+
/** Index of the first item to render (inclusive). */
|
|
4
|
+
startIndex: number;
|
|
5
|
+
/** Index just past the last item to render (exclusive). */
|
|
6
|
+
endIndex: number;
|
|
7
|
+
/**
|
|
8
|
+
* Pixels to translate the rendered window's first item by. Equals
|
|
9
|
+
* `prefixSum(startIndex)`. The component subtracts the scroll offset
|
|
10
|
+
* from this when applying the actual transform.
|
|
11
|
+
*/
|
|
12
|
+
offset: number;
|
|
13
|
+
/**
|
|
14
|
+
* Total pixels of all items. Used to size the scroll spacer so the
|
|
15
|
+
* native scrollbar tracks the full virtual length.
|
|
16
|
+
*/
|
|
17
|
+
totalSize: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compute which items should be in the rendered window for a given scroll
|
|
21
|
+
* position.
|
|
22
|
+
*
|
|
23
|
+
* @param measurements size cache (also encodes `itemCount`)
|
|
24
|
+
* @param scrollOffset current scroll position in pixels (0 = top)
|
|
25
|
+
* @param viewportSize visible viewport size in pixels
|
|
26
|
+
* @param overscan number of extra items to render beyond the visible
|
|
27
|
+
* window in each direction (default 3)
|
|
28
|
+
*
|
|
29
|
+
* Invariants (proven in tests):
|
|
30
|
+
* - 0 ≤ startIndex ≤ endIndex ≤ itemCount
|
|
31
|
+
* - offset === prefixSum(startIndex)
|
|
32
|
+
* - totalSize === prefixSum(itemCount)
|
|
33
|
+
* - Every pixel in `[scrollOffset, scrollOffset + viewportSize)` that
|
|
34
|
+
* intersects an item is covered by the rendered range
|
|
35
|
+
* `[startIndex, endIndex)`
|
|
36
|
+
* - Empty surface (itemCount === 0) returns `{ 0, 0, 0, 0 }`
|
|
37
|
+
*/
|
|
38
|
+
export declare function getVisibleRange1D(measurements: MeasurementCache, scrollOffset: number, viewportSize: number, overscan?: number): Range1D;
|
|
39
|
+
/**
|
|
40
|
+
* 2D visible range — produced by composing two 1D ranges, one per axis.
|
|
41
|
+
*
|
|
42
|
+
* 2D virtualization is, at the math layer, nothing more than two
|
|
43
|
+
* independent 1D ranges side-by-side. There is no shared state between
|
|
44
|
+
* the axes; this `Range2D` type is just the natural pair shape returned
|
|
45
|
+
* by `getVisibleRange2D` for consumers that want both ranges at once.
|
|
46
|
+
*
|
|
47
|
+
* The Vue 2D surface component (`<VirtualizedSurface2D>`) renders the
|
|
48
|
+
* Cartesian product of `x` and `y` as absolutely-positioned cells.
|
|
49
|
+
*/
|
|
50
|
+
export interface Range2D {
|
|
51
|
+
x: Range1D;
|
|
52
|
+
y: Range1D;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compose two `getVisibleRange1D` calls into a 2D range.
|
|
56
|
+
*
|
|
57
|
+
* The 2D surface's responsibility is just to render the Cartesian
|
|
58
|
+
* product of `[x.startIndex, x.endIndex)` × `[y.startIndex, y.endIndex)`
|
|
59
|
+
* with each cell positioned at `(prefixSum_x(cx), prefixSum_y(cy))`.
|
|
60
|
+
*
|
|
61
|
+
* Provided as a thin convenience so the 2D component doesn't need to
|
|
62
|
+
* manage two separate range computations directly. Same overscan, same
|
|
63
|
+
* input validation rules as the 1D function, applied per axis.
|
|
64
|
+
*/
|
|
65
|
+
export declare function getVisibleRange2D(measurementsX: MeasurementCache, measurementsY: MeasurementCache, scrollX: number, scrollY: number, viewportWidth: number, viewportHeight: number, overscanX?: number, overscanY?: number): Range2D;
|
|
66
|
+
/**
|
|
67
|
+
* When item sizes change (new measurements, items inserted/removed above
|
|
68
|
+
* the viewport), the scroll offset must be adjusted so the user-visible
|
|
69
|
+
* content stays where it is. This function returns the **delta** to add
|
|
70
|
+
* to `scrollOffset` to keep `anchorIndex`'s viewport position constant.
|
|
71
|
+
*
|
|
72
|
+
* The math is deliberately one-line:
|
|
73
|
+
*
|
|
74
|
+
* viewportPos(item) = prefixSum(item) - scrollOffset
|
|
75
|
+
*
|
|
76
|
+
* We want: newPrefixSum(anchor) - newScroll = oldPrefixSum(anchor) - oldScroll
|
|
77
|
+
* => newScroll - oldScroll = newPrefixSum(anchor) - oldPrefixSum(anchor)
|
|
78
|
+
* => delta = newPrefixSum(anchor) - oldPrefixSum(anchor)
|
|
79
|
+
*
|
|
80
|
+
* The function does NOT mutate scroll. The caller (the component) decides
|
|
81
|
+
* whether to apply the delta — it may want to animate, debounce, or skip
|
|
82
|
+
* if the user is actively scrolling.
|
|
83
|
+
*
|
|
84
|
+
* @param oldMeasurements cache state BEFORE the size change
|
|
85
|
+
* @param newMeasurements cache state AFTER the size change
|
|
86
|
+
* @param anchorIndex the item we want to keep visually stable
|
|
87
|
+
* @returns pixels to add to scroll offset (positive = scroll
|
|
88
|
+
* further down to compensate for items growing)
|
|
89
|
+
*/
|
|
90
|
+
export declare function computeAnchorAdjustment(oldMeasurements: MeasurementCache, newMeasurements: MeasurementCache, anchorIndex: number): number;
|
|
91
|
+
//# sourceMappingURL=virtualScroll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtualScroll.d.ts","sourceRoot":"","sources":["../../src/core/virtualScroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,OAAO;IACtB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,SAAI,GACX,OAAO,CAwCT;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;CACZ;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,gBAAgB,EAC/B,aAAa,EAAE,gBAAgB,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,SAAS,SAAI,EACb,SAAS,SAAI,GACZ,OAAO,CAKT;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,gBAAgB,EACjC,eAAe,EAAE,gBAAgB,EACjC,WAAW,EAAE,MAAM,GAClB,MAAM,CAUR"}
|