@ilamy/calendar 1.8.1 → 2.0.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/dist/index.d.ts CHANGED
@@ -1,27 +1,5 @@
1
- import { Weekday } from "rrule";
2
- import { RRule } from "rrule";
3
- import { Options } from "rrule";
4
- import { Dayjs } from "dayjs";
5
- /**
6
- * Re-rrule.js Options with practical TypeScript interface.
7
- * Makes all properties optional except freq and dtstart (which are required by RFC 5545).
8
- * This allows clean object creation without needing explicit null values.
9
- *
10
- * @see https://tools.ietf.org/html/rfc5545 - RFC 5545 iCalendar specification
11
- * @see https://github.com/jakubroztocil/rrule - rrule.js library documentation
12
- */
13
- type RRuleOptions = {
14
- /**
15
- * The frequency of the event. Must be one of the following: DAILY, WEEKLY, MONTHLY, etc.
16
- */
17
- freq: Options["freq"];
18
- /**
19
- * The start date of the recurrence rule. This defines when the recurrence pattern begins.
20
- * Required for proper RRULE functionality according to RFC 5545.
21
- * @important Same as the event start date.
22
- */
23
- dtstart: Date;
24
- } & Partial<Omit<Options, "freq" | "dtstart">>;
1
+ import { ComponentType, ReactNode as ReactNode2 } from "react";
2
+ import { Dayjs as Dayjs2, ManipulateType as ManipulateType2 } from "dayjs";
25
3
  /**
26
4
  * Core calendar event interface representing a single calendar event.
27
5
  * This is the primary data structure for calendar events.
@@ -32,9 +10,9 @@ interface CalendarEvent {
32
10
  /** Display title of the event */
33
11
  title: string;
34
12
  /** Start date and time of the event */
35
- start: Dayjs;
13
+ start: Dayjs2;
36
14
  /** End date and time of the event */
37
- end: Dayjs;
15
+ end: Dayjs2;
38
16
  /**
39
17
  * Color for the event (supports CSS color values, hex, rgb, hsl, or CSS class names)
40
18
  * @example "#3b82f6", "blue-500", "rgb(59, 130, 246)"
@@ -55,29 +33,6 @@ interface CalendarEvent {
55
33
  */
56
34
  allDay?: boolean;
57
35
  /**
58
- * Recurrence rule for recurring events (RFC 5545 standard)
59
- *
60
- * Uses TypeScript interface for better readability, type safety, and IDE support
61
- * compared to RRULE string format. Converted to rrule.js format internally.
62
- *
63
- * @example { freq: 'WEEKLY', interval: 1, byweekday: ['MO', 'WE', 'FR'] }
64
- * @example { freq: 'DAILY', interval: 1, count: 10 }
65
- * @example { freq: 'MONTHLY', interval: 1, until: new Date('2025-12-31') }
66
- */
67
- rrule?: RRuleOptions;
68
- /**
69
- * Exception dates (EXDATE) - dates to exclude from recurrence
70
- * Uses ISO string format for storage and transmission
71
- * @example ['2025-01-15T09:00:00.000Z', '2025-01-22T09:00:00.000Z']
72
- */
73
- exdates?: string[];
74
- /**
75
- * Recurrence ID (RECURRENCE-ID) - identifies modified instances
76
- * Points to the original occurrence date this event modifies
77
- * Used for events that are modifications of recurring instances
78
- */
79
- recurrenceId?: string;
80
- /**
81
36
  * UID for iCalendar compatibility
82
37
  * Unique identifier across calendar systems
83
38
  */
@@ -91,7 +46,7 @@ interface CalendarEvent {
91
46
  * Use this to store additional metadata specific to your application
92
47
  * @example { meetingType: 'standup', attendees: ['john', 'jane'] }
93
48
  */
94
- data?: Record<string, any>;
49
+ data?: Record<string, unknown>;
95
50
  }
96
51
  /**
97
52
  * Supported days of the week for calendar configuration.
@@ -119,50 +74,6 @@ interface BusinessHours {
119
74
  */
120
75
  endTime?: number;
121
76
  }
122
- interface EventFormProps {
123
- open?: boolean;
124
- selectedEvent?: CalendarEvent | null;
125
- onAdd?: (event: CalendarEvent) => void;
126
- onUpdate?: (event: CalendarEvent) => void;
127
- onDelete?: (event: CalendarEvent) => void;
128
- onClose: () => void;
129
- }
130
- import React4 from "react";
131
- import React3 from "react";
132
- /**
133
- * Public-facing resource calendar event interface with flexible date types.
134
- * Similar to IlamyCalendarPropEvent but with resource assignment fields.
135
- * Dates can be provided as Dayjs, Date, or string and will be normalized internally.
136
- *
137
- * @interface IlamyResourceCalendarPropEvent
138
- * @extends {IlamyCalendarPropEvent}
139
- */
140
- interface IlamyResourceCalendarPropEvent extends IlamyCalendarPropEvent {
141
- /** Single resource assignment */
142
- resourceId?: string | number;
143
- /** Multiple resource assignment (cross-resource events) */
144
- resourceIds?: (string | number)[];
145
- }
146
- interface IlamyResourceCalendarProps extends Omit<IlamyCalendarProps, "events"> {
147
- /** Array of events to display */
148
- events?: IlamyResourceCalendarPropEvent[];
149
- /** Array of resources */
150
- resources?: Resource[];
151
- /** Custom render function for resources */
152
- renderResource?: (resource: Resource) => React.ReactNode;
153
- /**
154
- * Orientation of the resource view.
155
- * - "horizontal": Resources are rows, time is columns (default)
156
- * - "vertical": Resources are columns, time is rows
157
- */
158
- orientation?: "horizontal" | "vertical";
159
- /**
160
- * Granularity of time slots in the week view.
161
- * - "hourly": Time slots are 1 hour (default)
162
- * - "daily": Time slots are 1 day
163
- */
164
- weekViewGranularity?: "hourly" | "daily";
165
- }
166
77
  /**
167
78
  * Resource interface representing a calendar resource (person, room, equipment, etc.)
168
79
  */
@@ -181,8 +92,6 @@ interface Resource {
181
92
  * @example "#dbeafe", "blue-100", "rgba(59, 130, 246, 0.1)"
182
93
  */
183
94
  backgroundColor?: string;
184
- /** Optional position for resource display */
185
- position?: number;
186
95
  /**
187
96
  * Configuration for resource-specific business hours.
188
97
  * If provided, these will be used instead of the global business hours for this resource.
@@ -193,9 +102,266 @@ interface Resource {
193
102
  * Use this to store additional metadata specific to your application
194
103
  * @example { avatar: 'https://example.com/avatar.png', role: 'admin' }
195
104
  */
196
- data?: Record<string, any>;
105
+ data?: Record<string, unknown>;
106
+ }
107
+ interface PluginDateRange {
108
+ start: Dayjs2;
109
+ end: Dayjs2;
110
+ }
111
+ interface PluginMutationArgs {
112
+ event: CalendarEvent;
113
+ updates?: Partial<CalendarEvent>;
114
+ currentEvents: CalendarEvent[];
115
+ scope: unknown;
116
+ }
117
+ /** Structured result from `applyEdit` when a mutation updates multiple stored rows. */
118
+ interface PluginMutationResult {
119
+ events: CalendarEvent[];
120
+ /** Existing rows to persist via `onEventUpdate`. */
121
+ updated: CalendarEvent[];
122
+ /** New rows to persist via `onEventAdd`. */
123
+ added: CalendarEvent[];
124
+ /** Existing rows to persist via `onEventDelete`. */
125
+ deleted: CalendarEvent[];
126
+ }
127
+ /**
128
+ * Calendar configuration handed to a view's `columns()`/`renderHeader()`.
129
+ * Carries the resource axis (`resources`, `orientation`) so a resource-capable
130
+ * view can compose both arrangements. `range()` receives only the
131
+ * `firstDayOfWeek` slice (see its own signature).
132
+ */
133
+ interface ViewConfig {
134
+ firstDayOfWeek: number;
135
+ hiddenDays?: Set<number>;
136
+ businessHours?: BusinessHours | BusinessHours[];
137
+ hideNonBusinessHours?: boolean;
138
+ /** The resource axis. Set only when the calendar renders resources. */
139
+ resources?: Resource[];
140
+ /**
141
+ * The calendar-level resource arrangement (the user's choice): where the
142
+ * resource axis goes. Only meaningful when `resources` is set.
143
+ */
144
+ orientation?: "vertical" | "horizontal";
145
+ /**
146
+ * Week-view granularity when `resources` is set: 'hourly' (default) nests
147
+ * hour slots under each day; 'daily' shows one cell per day.
148
+ */
149
+ weekViewGranularity?: "hourly" | "daily";
150
+ }
151
+ /**
152
+ * One column of a 'vertical' view (time flows down the column).
153
+ * Formalizes the calendar's existing VerticalGrid column input.
154
+ */
155
+ interface VerticalColumnSpec {
156
+ /** Stable column id; drives testids and React keys. */
157
+ id: string;
158
+ /** The date this column represents; gutter/label columns leave it unset. */
159
+ day?: Dayjs2;
160
+ /** The cells of the column: hour slots (gridType 'hour') or dates ('day'). */
161
+ days: Dayjs2[];
162
+ gridType?: "day" | "hour";
163
+ className?: string;
164
+ /** Label-only column (e.g. the time gutter): renders no events. */
165
+ noEvents?: boolean;
166
+ renderCell?: (date: Dayjs2) => ReactNode2;
167
+ /**
168
+ * Resource-axis identity when the column belongs to one resource. The
169
+ * single carrier: consumers derive the id from `resource.id`.
170
+ */
171
+ resource?: Resource;
172
+ }
173
+ /** One cell of a 'horizontal' row. */
174
+ interface HorizontalCellSpec {
175
+ id: string;
176
+ day?: Dayjs2;
177
+ /** A grouped cell spanning several dates (nested-axis arrangements). */
178
+ days?: Dayjs2[];
179
+ gridType: "day" | "hour";
180
+ className?: string;
181
+ }
182
+ /**
183
+ * One row of a 'horizontal' view (date cells flow across the row).
184
+ * Formalizes the calendar's existing HorizontalGrid row input.
185
+ */
186
+ interface HorizontalRowSpec {
187
+ /** Stable row id; drives testids and React keys (matches VerticalColumnSpec.id). */
188
+ id: string;
189
+ columns?: HorizontalCellSpec[];
190
+ className?: string;
191
+ showDayNumber?: boolean;
192
+ /** Resource-axis identity when the row belongs to one resource. */
193
+ resource?: Resource;
194
+ }
195
+ /** What a view's `columns()` returns; `layout` picks which engine consumes it. */
196
+ type ColumnSpec = VerticalColumnSpec | HorizontalRowSpec;
197
+ /** Context passed to a view's `renderHeader`. */
198
+ interface ViewHeaderContext {
199
+ date: Dayjs2;
200
+ config: ViewConfig;
201
+ }
202
+ /**
203
+ * Describes a view type — contributed by a plugin or built into the calendar
204
+ * core (the four built-ins are themselves `PluginView` entries). A view either
205
+ * declares `columns` + `layout` and renders through the shared grid engines,
206
+ * or renders entirely through `component` (the escape hatch).
207
+ */
208
+ interface PluginView {
209
+ /** Unique view id, e.g. 'resource-week'. */
210
+ name: string;
211
+ /** View-switcher label (or a translation key; unknown keys render as-is). */
212
+ label?: string;
213
+ /**
214
+ * View-switcher icon (a component taking `className`, e.g. a lucide icon).
215
+ * Always shown in the switcher; the label appears beside it only when the
216
+ * view is selected, and as a hover tooltip otherwise.
217
+ */
218
+ icon: ComponentType<{
219
+ className?: string;
220
+ }>;
221
+ /**
222
+ * The escape hatch: renders the whole view when `columns`/`layout` are
223
+ * absent. Spec-driven views omit it. A view with neither renders nothing
224
+ * (dev builds log a warning).
225
+ */
226
+ component?: ComponentType;
227
+ /** How far prev/next steps when `navigationStep` is absent ('week', 'month', …). */
228
+ navigationUnit?: ManipulateType2;
229
+ /**
230
+ * How far prev/next jumps; defaults to one `navigationUnit`. Custom-duration
231
+ * views (a 40-day grid, a 4-day vertical view) set `{ amount: 40, unit: 'day' }`
232
+ * so navigation moves a full window.
233
+ *
234
+ * This also selects the header title/date-picker form (the core derives it
235
+ * generically, never by view name): a single `day`/`week`/`month`/`year` step
236
+ * borrows that grid's picker and title; any other step (amount > 1, or a custom
237
+ * unit) shows the day picker over the view's `range`. A third-party view gets
238
+ * the right picker for free just by declaring how it navigates.
239
+ */
240
+ navigationStep?: {
241
+ amount: number;
242
+ unit: ManipulateType2;
243
+ };
244
+ /**
245
+ * Visible range for navigation callbacks and the event pipeline. Views
246
+ * without `range` fall back to the month 6x7 grid range. Receives only the
247
+ * `firstDayOfWeek` slice of the config; the full axis config reaches
248
+ * `columns()`/`renderHeader()`.
249
+ */
250
+ range?: (date: Dayjs2, config: Pick<ViewConfig, "firstDayOfWeek">) => {
251
+ start: Dayjs2;
252
+ end: Dayjs2;
253
+ };
254
+ /**
255
+ * Column/row specs for the shared renderer. Return `VerticalColumnSpec[]`
256
+ * when `layout` is 'vertical', `HorizontalRowSpec[]` when 'horizontal'.
257
+ * Omit (together with `layout`) to render `component` instead.
258
+ */
259
+ columns?: (date: Dayjs2, config: ViewConfig) => VerticalColumnSpec[] | HorizontalRowSpec[];
260
+ /**
261
+ * The view's intrinsic shape (the author's choice): which engine renders it
262
+ * when the calendar has NO resources. 'vertical' = time flows down;
263
+ * 'horizontal' = date cells flow across in stacked rows. With resources on
264
+ * a resource-capable view, the calendar-level `orientation` wins instead:
265
+ * `engine = resources && supportsResources ? orientation : layout`.
266
+ */
267
+ layout?: "vertical" | "horizontal";
268
+ /** Header row content rendered above the grid by the shared renderer. */
269
+ renderHeader?: (ctx: ViewHeaderContext) => ReactNode2;
270
+ /**
271
+ * Whether `columns()` composes the resource axis when `config.resources`
272
+ * is set. Defaults to false; the view switcher hides resource-incapable
273
+ * views on a resource calendar.
274
+ */
275
+ supportsResources?: boolean;
276
+ }
277
+ /**
278
+ * A calendar plugin contributes optional behavior and UI through generic hooks
279
+ * named after pipeline moments and mount points, never after a feature. The
280
+ * core stays agnostic of any specific plugin (e.g. recurrence).
281
+ *
282
+ * Hooks follow the Rollup/Vite execution kinds:
283
+ * - `transformEvents` is sequential: each plugin receives the previous
284
+ * plugin's output, forming a transform chain.
285
+ * - `managesEvent` is first-match: the first plugin whose managesEvent returns
286
+ * true owns its scoped mutations.
287
+ * - `renderSlot` is additive: every plugin may contribute to a mount point.
288
+ *
289
+ * `slotName` is an opaque string identifier and `context` is opaque to the
290
+ * core. The built-in slot names and their context shapes live in the calendar
291
+ * core, which this contract does NOT depend on, so adding a slot never changes
292
+ * this interface. A plugin narrows `context` by `slotName` at its boundary.
293
+ *
294
+ * `scope` is opaque to the core: the owner produces it (via the mutation-scope
295
+ * slot) and consumes it in `applyEdit` / `applyDelete`. A plugin that provides
296
+ * `applyEdit` / `applyDelete` should also render the mutation-scope slot so the
297
+ * core can gather that scope before mutating.
298
+ */
299
+ interface IlamyPlugin {
300
+ name: string;
301
+ transformEvents?: (events: CalendarEvent[], range: PluginDateRange) => CalendarEvent[];
302
+ managesEvent?: (event: CalendarEvent) => boolean;
303
+ applyEdit?: (args: PluginMutationArgs) => CalendarEvent[] | PluginMutationResult;
304
+ applyDelete?: (args: PluginMutationArgs) => CalendarEvent[] | PluginMutationResult;
305
+ renderSlot?: (slotName: string, context: unknown) => ReactNode2;
306
+ /**
307
+ * Contributes arbitrary data to a named point. Additive: all plugins may
308
+ * contribute to the same point; the runtime aggregates all results via
309
+ * `collect`. Parallel to `renderSlot` but for data rather than UI nodes.
310
+ */
311
+ contribute?: (point: string, context: unknown) => unknown[];
312
+ /**
313
+ * Registers new view types that the calendar can switch to. Each entry in
314
+ * the array describes one view (id, component, navigation unit, …).
315
+ */
316
+ views?: PluginView[];
317
+ /**
318
+ * Wraps the calendar subtree so the plugin's own React context is available
319
+ * to its views, slots, and components. Rendered as the outermost wrapper
320
+ * among all plugin providers.
321
+ */
322
+ provider?: ComponentType<{
323
+ children: ReactNode2;
324
+ }>;
325
+ }
326
+ /** Context passed to the `event-form` slot (inside the create/edit form). */
327
+ interface EventFormSlotContext {
328
+ event: CalendarEvent;
329
+ onChange: (updates: Partial<CalendarEvent>) => void;
330
+ }
331
+ /**
332
+ * Context passed to the `event-mutation-scope` slot. The owning plugin renders
333
+ * UI to gather its opaque `scope`, then calls `resolve(scope)` (or `cancel`).
334
+ */
335
+ interface EventMutationScopeSlotContext {
336
+ event: CalendarEvent;
337
+ operation: "edit" | "delete";
338
+ resolve: (scope: unknown) => void;
339
+ cancel: () => void;
197
340
  }
198
- interface Translations {
341
+ import dayjs from "dayjs";
342
+ type Dayjs3 = dayjs.Dayjs3;
343
+ type ManipulateType3 = dayjs.ManipulateType3;
344
+ declare const _default: typeof dayjs;
345
+ /**
346
+ * The calendar's plugin mount points. These belong to the host (the components
347
+ * that render them: the event form and the drag-and-drop flow), NOT to the
348
+ * plugin kernel and NOT to any individual plugin. The kernel's `renderSlot`
349
+ * takes a plain `slotName: string` and knows nothing about this list; the core
350
+ * renders these named slots and any plugin may fill the ones it cares about.
351
+ */
352
+ declare const SLOT_EVENT_FORM = "event-form";
353
+ declare const SLOT_EVENT_MUTATION_SCOPE = "event-mutation-scope";
354
+ interface EventFormProps {
355
+ open?: boolean;
356
+ selectedEvent?: CalendarEvent | null;
357
+ onAdd?: (event: CalendarEvent) => void;
358
+ onUpdate?: (event: CalendarEvent) => void;
359
+ onDelete?: (event: CalendarEvent) => void;
360
+ onClose: () => void;
361
+ }
362
+ import React4 from "react";
363
+ import React3 from "react";
364
+ declare const defaultTranslations: {
199
365
  today: string;
200
366
  create: string;
201
367
  new: string;
@@ -203,6 +369,8 @@ interface Translations {
203
369
  delete: string;
204
370
  cancel: string;
205
371
  export: string;
372
+ previous: string;
373
+ next: string;
206
374
  event: string;
207
375
  events: string;
208
376
  newEvent: string;
@@ -226,6 +394,16 @@ interface Translations {
226
394
  repeat: string;
227
395
  repeats: string;
228
396
  customRecurrence: string;
397
+ frequency: string;
398
+ everyWeekday: string;
399
+ weeklyOn: string;
400
+ monthlyOnDay: string;
401
+ monthlyOnThe: string;
402
+ first: string;
403
+ second: string;
404
+ third: string;
405
+ fourth: string;
406
+ last: string;
229
407
  daily: string;
230
408
  weekly: string;
231
409
  monthly: string;
@@ -259,20 +437,27 @@ interface Translations {
259
437
  week: string;
260
438
  day: string;
261
439
  year: string;
440
+ agenda: string;
441
+ agendaNoEvents: string;
262
442
  more: string;
263
443
  resources: string;
264
444
  resource: string;
445
+ selectResource: string;
265
446
  time: string;
266
447
  date: string;
267
448
  noResourcesVisible: string;
268
449
  addResourcesOrShowExisting: string;
269
- }
450
+ };
451
+ /** All translation keys, derived from the canonical English dictionary in `default.ts`. */
452
+ type Translations = Record<keyof typeof defaultTranslations, string>;
270
453
  type TranslationKey = keyof Translations;
271
454
  type TranslatorFunction = (key: TranslationKey | string) => string;
272
455
  /**
273
- * Available calendar view types.
456
+ * Available calendar view types. The built-in views (day, week, month, year)
457
+ * are `PluginView` specs in `features/calendar/components/views`; plugins may
458
+ * contribute additional view names, so this is a broad `string`.
274
459
  */
275
- type CalendarView = "month" | "week" | "day" | "year";
460
+ type CalendarView = string;
276
461
  /**
277
462
  * Time format options for displaying times in the calendar.
278
463
  */
@@ -305,38 +490,46 @@ interface CalendarClassesOverride {
305
490
  * @extends {Omit<CalendarEvent, 'start' | 'end'>}
306
491
  */
307
492
  interface IlamyCalendarPropEvent extends Omit<CalendarEvent, "start" | "end"> {
308
- start: Dayjs | Date | string;
309
- end: Dayjs | Date | string;
493
+ start: Dayjs3 | Date | string;
494
+ end: Dayjs3 | Date | string;
310
495
  }
311
496
  /**
312
497
  * Information passed to the onCellClick callback.
313
498
  * Uses named properties for extensibility.
314
499
  */
315
500
  interface DateRange {
316
- start: Dayjs;
317
- end: Dayjs;
501
+ start: Dayjs3;
502
+ end: Dayjs3;
318
503
  }
319
504
  interface CellInfo {
320
505
  /** Start date/time of the cell */
321
- start: Dayjs;
506
+ start: Dayjs3;
322
507
  /** End date/time of the cell */
323
- end: Dayjs;
508
+ end: Dayjs3;
324
509
  /** Full resource object in resource calendars; undefined in a regular calendar */
325
510
  resource?: Resource;
326
511
  /** Whether this is an all-day cell (optional) */
327
512
  allDay?: boolean;
328
513
  }
329
514
  /**
515
+ * Input accepted by `openEventForm`. A partial event, optionally carrying the
516
+ * full resource of the clicked cell (`CellInfo` is assignable as-is). When no
517
+ * explicit `resourceId` is given, the carried resource's id is used.
518
+ */
519
+ type OpenEventFormInput = Partial<CalendarEvent> & {
520
+ resource?: Resource;
521
+ };
522
+ /**
330
523
  * Props passed to the custom render function for the current time indicator.
331
524
  * Allows users to customize how the current time indicator is displayed.
332
525
  */
333
526
  interface RenderCurrentTimeIndicatorProps {
334
527
  /** The current time as a dayjs object */
335
- currentTime: Dayjs;
528
+ currentTime: Dayjs3;
336
529
  /** The start of the visible time range */
337
- rangeStart: Dayjs;
530
+ rangeStart: Dayjs3;
338
531
  /** The end of the visible time range */
339
- rangeEnd: Dayjs;
532
+ rangeEnd: Dayjs3;
340
533
  /** Progress percentage (0-100) representing position in the range */
341
534
  progress: number;
342
535
  /**
@@ -379,7 +572,7 @@ interface IlamyCalendarProps {
379
572
  * The initial date to display when the calendar loads.
380
573
  * If not provided, the calendar will default to today's date.
381
574
  */
382
- initialDate?: Dayjs | Date | string;
575
+ initialDate?: Dayjs3 | Date | string;
383
576
  /**
384
577
  * Custom render function for calendar events.
385
578
  * If provided, it will override the default event rendering.
@@ -404,6 +597,12 @@ interface IlamyCalendarProps {
404
597
  */
405
598
  isCellDisabled?: (info: CellInfo) => boolean;
406
599
  /**
600
+ * Returns extra CSS classes for a cell based on custom logic (unavailability
601
+ * styling, on-call windows, etc.). Unlike `isCellDisabled`, this is purely
602
+ * visual — cells remain clickable and accept drag-drops.
603
+ */
604
+ getCellClassName?: (info: CellInfo) => string;
605
+ /**
407
606
  * Callback when the calendar view changes (month, week, day, year).
408
607
  * Useful for syncing with external state or analytics.
409
608
  */
@@ -427,7 +626,7 @@ interface IlamyCalendarProps {
427
626
  * Callback when the current date changes (navigation).
428
627
  * Provides the new current date and the current visible range.
429
628
  */
430
- onDateChange?: (date: Dayjs, range: DateRange) => void;
629
+ onDateChange?: (date: Dayjs3, range: DateRange) => void;
431
630
  /**
432
631
  * Locale to use for formatting dates and times.
433
632
  * If not provided, the default locale will be used.
@@ -601,7 +800,7 @@ interface IlamyCalendarProps {
601
800
  * Custom render function for the hour labels in the gutter/header.
602
801
  * Receives a Dayjs object for the hour and should return a React node.
603
802
  */
604
- renderHour?: (date: Dayjs) => React3.ReactNode;
803
+ renderHour?: (date: Dayjs3) => React3.ReactNode;
605
804
  /**
606
805
  * Granularity of the time grid in minutes for day, week, and resource hour views.
607
806
  * Quarter-hour increments only: `15`, `30`, or `60`.
@@ -637,32 +836,66 @@ interface IlamyCalendarProps {
637
836
  * ```
638
837
  */
639
838
  scrollTime?: string;
839
+ /**
840
+ * Optional plugins that add behavior/UI (e.g. recurrence). The core ships
841
+ * with no plugins by default — pass `recurrencePlugin()` to enable recurring
842
+ * events.
843
+ */
844
+ plugins?: IlamyPlugin[];
845
+ /**
846
+ * Resources (people, rooms, equipment) to display as a resource axis.
847
+ * When set: events are shown per matching resource (`resourceIds`, falling
848
+ * back to `resourceId`); events with no resource assignment are hidden; the
849
+ * year view is hidden from the view switcher.
850
+ */
851
+ resources?: Resource[];
852
+ /** Custom render function for resource header cells. */
853
+ renderResource?: (resource: Resource) => React3.ReactNode;
854
+ /**
855
+ * How resources are arranged. Only applies when `resources` is set.
856
+ * - "horizontal": resources are rows, time is columns (default)
857
+ * - "vertical": resources are columns, time is rows
858
+ */
859
+ orientation?: "horizontal" | "vertical";
860
+ /**
861
+ * Granularity of week-view time slots when `resources` is set.
862
+ * - "hourly": one column per hour (default)
863
+ * - "daily": one column per day. Note: `hiddenDays` is ignored in daily
864
+ * mode (non-contiguous days would break multi-day event positioning).
865
+ */
866
+ weekViewGranularity?: "hourly" | "daily";
640
867
  }
641
868
  declare const IlamyCalendar: React4.FC<IlamyCalendarProps>;
642
- declare const isRecurringEvent: (event: CalendarEvent) => boolean;
643
- interface GenerateRecurringEventsProps {
644
- event: CalendarEvent;
645
- currentEvents: CalendarEvent[];
646
- startDate: Dayjs;
647
- endDate: Dayjs;
648
- }
649
- declare const generateRecurringEvents: ({ event, currentEvents, startDate, endDate }: GenerateRecurringEventsProps) => CalendarEvent[];
650
869
  import React5 from "react";
870
+ /**
871
+ * @deprecated Since v2.0 `IlamyCalendar` accepts `resources`, `renderResource`,
872
+ * `orientation`, and `weekViewGranularity` directly — use it instead. This
873
+ * alias will be removed in the next major.
874
+ */
875
+ type IlamyResourceCalendarProps = IlamyCalendarProps;
876
+ /** @deprecated Since v2.0 — use `IlamyCalendar` with the `resources` prop. */
651
877
  declare const IlamyResourceCalendar: React5.FC<IlamyResourceCalendarProps>;
878
+ import React6 from "react";
652
879
  /**
653
- * Publicly exposed calendar context properties.
880
+ * The public calendar API surface exposed by useIlamyCalendarContext() — for consumers and plugin
881
+ * components. The full internal context is intentionally not exported.
654
882
  */
655
- interface UseIlamyCalendarContextReturn {
656
- readonly currentDate: Dayjs;
883
+ interface IlamyCalendarApi {
884
+ readonly currentDate: Dayjs3;
885
+ /** The active view's current visible date range (what is on screen). */
886
+ readonly currentRange: DateRange;
657
887
  readonly view: CalendarView;
658
888
  readonly events: CalendarEvent[];
889
+ readonly rawEvents: CalendarEvent[];
659
890
  readonly isEventFormOpen: boolean;
660
891
  readonly selectedEvent: CalendarEvent | null;
661
- readonly selectedDate: Dayjs | null;
892
+ readonly selectedDate: Dayjs3 | null;
662
893
  readonly firstDayOfWeek: number;
663
894
  readonly resources: Resource[];
664
- readonly setCurrentDate: (date: Dayjs) => void;
665
- readonly selectDate: (date: Dayjs) => void;
895
+ /** Axis the views lay out along: 'horizontal' (columns) or 'vertical' (rows). */
896
+ readonly orientation: "horizontal" | "vertical";
897
+ readonly setCurrentDate: (date: Dayjs3) => void;
898
+ readonly selectDate: (date: Dayjs3) => void;
666
899
  readonly setView: (view: CalendarView) => void;
667
900
  readonly nextPeriod: () => void;
668
901
  readonly prevPeriod: () => void;
@@ -670,15 +903,42 @@ interface UseIlamyCalendarContextReturn {
670
903
  readonly addEvent: (event: CalendarEvent) => void;
671
904
  readonly updateEvent: (eventId: string | number, event: Partial<CalendarEvent>) => void;
672
905
  readonly deleteEvent: (eventId: string | number) => void;
673
- readonly openEventForm: (eventData?: Partial<CalendarEvent>) => void;
906
+ readonly openEventForm: (eventData?: OpenEventFormInput) => void;
674
907
  readonly closeEventForm: () => void;
908
+ /**
909
+ * Handle a click on an existing event: runs the consumer's `onEventClick`
910
+ * callback if provided, otherwise opens the event for editing. Lets plugin
911
+ * views (e.g. agenda) handle event clicks identically to the built-in views.
912
+ */
913
+ readonly onEventClick: (event: CalendarEvent) => void;
914
+ /**
915
+ * The consumer's custom current-time-indicator renderer, if provided. Lets
916
+ * plugin views (e.g. agenda) render the indicator consistently with the
917
+ * built-in views via the shared `@ilamy/ui` CurrentTimeIndicator.
918
+ */
919
+ readonly renderCurrentTimeIndicator?: (props: RenderCurrentTimeIndicatorProps) => React6.ReactNode;
920
+ /**
921
+ * Events whose resource membership (`resourceIds`, falling back to
922
+ * `resourceId`) contains the given resource. On a calendar without
923
+ * resources this simply filters by the events' own resource fields.
924
+ */
675
925
  readonly getEventsForResource: (resourceId: string | number) => CalendarEvent[];
676
926
  readonly businessHours?: BusinessHours | BusinessHours[];
927
+ readonly t: TranslatorFunction;
928
+ readonly timeFormat: TimeFormat;
929
+ readonly timezone?: string;
930
+ readonly currentLocale: string;
931
+ readonly getEventsForDateRange: (start: Dayjs3, end: Dayjs3) => CalendarEvent[];
932
+ readonly applyScopedEdit: (event: CalendarEvent, updates: Partial<CalendarEvent>, scope: unknown) => void;
933
+ readonly applyScopedDelete: (event: CalendarEvent, scope: unknown) => void;
934
+ readonly getEventManager: (event: CalendarEvent) => IlamyPlugin | undefined;
935
+ readonly renderSlot: (slotName: string, context: unknown) => React6.ReactNode[];
936
+ readonly collect: (point: string, context: unknown) => unknown[];
937
+ readonly getViews: () => PluginView[];
677
938
  }
678
939
  /**
679
940
  * Public hook exported for library users.
680
941
  * Returns a limited set of commonly used properties and methods.
681
942
  */
682
- declare function useIlamyCalendarContext(): UseIlamyCalendarContextReturn;
683
- declare const defaultTranslations: Translations;
684
- export { useIlamyCalendarContext, isRecurringEvent, generateRecurringEvents, defaultTranslations, Weekday, WeekDays, UseIlamyCalendarContextReturn, TranslatorFunction, Translations, TranslationKey, TimeFormat, SlotDuration, Resource, RenderCurrentTimeIndicatorProps, RRuleOptions, RRule, IlamyResourceCalendarProps, IlamyResourceCalendar, IlamyCalendarProps, IlamyCalendar, EventFormProps, CellInfo, CalendarView, CalendarEvent, BusinessHours };
943
+ declare function useIlamyCalendarContext(): IlamyCalendarApi;
944
+ export { useIlamyCalendarContext, defaultTranslations, _default as dayjs, WeekDays, ViewHeaderContext, ViewConfig, VerticalColumnSpec, TranslatorFunction, Translations, TranslationKey, TimeFormat, SlotDuration, SLOT_EVENT_MUTATION_SCOPE, SLOT_EVENT_FORM, Resource, RenderCurrentTimeIndicatorProps, PluginView, PluginMutationResult, PluginMutationArgs, PluginDateRange, OpenEventFormInput, ManipulateType3 as ManipulateType, IlamyResourceCalendarProps, IlamyResourceCalendar, IlamyPlugin, IlamyCalendarProps, IlamyCalendarApi, IlamyCalendar, HorizontalRowSpec, HorizontalCellSpec, EventMutationScopeSlotContext, EventFormSlotContext, EventFormProps, Dayjs3 as Dayjs, ColumnSpec, CellInfo, CalendarView, CalendarEvent, CalendarClassesOverride, BusinessHours };