@softium/calendar 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/index.cjs +3312 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +443 -0
- package/dist/index.d.ts +443 -0
- package/dist/index.js +3275 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +1732 -0
- package/package.json +71 -0
- package/src/styles/calendar.css +1347 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* softium-ui Calendar — core types.
|
|
6
|
+
*
|
|
7
|
+
* Ported from the calendary project into softium-ui's token-CSS conventions.
|
|
8
|
+
* Server / Google-Calendar / today-task concerns are intentionally dropped —
|
|
9
|
+
* this is a pure UI component driven by local state (or host-provided state).
|
|
10
|
+
*/
|
|
11
|
+
type ViewType = 'day' | 'week' | 'month' | 'year';
|
|
12
|
+
type RecurrenceFreq = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
|
13
|
+
interface Recurrence {
|
|
14
|
+
freq: RecurrenceFreq;
|
|
15
|
+
/** every N periods (1 = every period) */
|
|
16
|
+
interval: number;
|
|
17
|
+
/** weekly only — weekdays as Mon=0 … Sun=6 (matches the recurrence editor) */
|
|
18
|
+
byweekday?: number[];
|
|
19
|
+
/** repeat until this date (inclusive) */
|
|
20
|
+
until?: Date;
|
|
21
|
+
/** repeat this many occurrences */
|
|
22
|
+
count?: number;
|
|
23
|
+
}
|
|
24
|
+
interface Category {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
/** hex color, e.g. "#E30000" */
|
|
28
|
+
color: string;
|
|
29
|
+
}
|
|
30
|
+
/** a single day's holiday/observance label, shown in the month view's date header */
|
|
31
|
+
interface Holiday {
|
|
32
|
+
date: Date;
|
|
33
|
+
name: string;
|
|
34
|
+
}
|
|
35
|
+
interface CalendarEvent {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
/** start date (time-of-day carried separately in startTime) */
|
|
39
|
+
date: Date;
|
|
40
|
+
/** end date for multi-day / period events */
|
|
41
|
+
endDate?: Date;
|
|
42
|
+
/** "HH:MM" */
|
|
43
|
+
startTime?: string;
|
|
44
|
+
/** "HH:MM" */
|
|
45
|
+
endTime?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
categoryId?: string;
|
|
48
|
+
recurrence?: Recurrence;
|
|
49
|
+
/** dates excluded from a recurring series */
|
|
50
|
+
exdate?: Date[];
|
|
51
|
+
/** true for a generated occurrence of a recurring series (never persisted) */
|
|
52
|
+
isRecurringInstance?: boolean;
|
|
53
|
+
/** id of the master event a recurring instance came from */
|
|
54
|
+
recurringEventId?: string;
|
|
55
|
+
}
|
|
56
|
+
/** the working draft shown in an event's time-grid position while editing */
|
|
57
|
+
interface PreviewEvent {
|
|
58
|
+
title: string;
|
|
59
|
+
startTime: string;
|
|
60
|
+
endTime: string;
|
|
61
|
+
description: string;
|
|
62
|
+
categoryId: string;
|
|
63
|
+
startDate?: Date;
|
|
64
|
+
endDate?: Date;
|
|
65
|
+
isPeriod?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface UseCalendarOptions {
|
|
69
|
+
initialEvents?: CalendarEvent[];
|
|
70
|
+
initialCategories?: Category[];
|
|
71
|
+
}
|
|
72
|
+
interface CalendarController {
|
|
73
|
+
events: CalendarEvent[];
|
|
74
|
+
setEvents: React.Dispatch<React.SetStateAction<CalendarEvent[]>>;
|
|
75
|
+
addEvent: (data: Omit<CalendarEvent, 'id'>) => CalendarEvent;
|
|
76
|
+
updateEvent: (id: string, data: Partial<CalendarEvent>) => void;
|
|
77
|
+
deleteEvent: (id: string) => void;
|
|
78
|
+
/** undo/redo over event add/update/delete/move (see setEvents) */
|
|
79
|
+
canUndo: boolean;
|
|
80
|
+
canRedo: boolean;
|
|
81
|
+
undo: () => void;
|
|
82
|
+
redo: () => void;
|
|
83
|
+
categories: Category[];
|
|
84
|
+
setCategories: React.Dispatch<React.SetStateAction<Category[]>>;
|
|
85
|
+
addCategory: (data: {
|
|
86
|
+
name: string;
|
|
87
|
+
color: string;
|
|
88
|
+
}) => string;
|
|
89
|
+
updateCategory: (id: string, data: Partial<Category>) => void;
|
|
90
|
+
deleteCategory: (id: string) => void;
|
|
91
|
+
reorderCategories: (from: number, to: number) => void;
|
|
92
|
+
selectedCategoryIds: string[];
|
|
93
|
+
toggleCategory: (id: string) => void;
|
|
94
|
+
setSelectedCategoryIds: React.Dispatch<React.SetStateAction<string[]>>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* useCalendar — self-contained local state for events + categories + the
|
|
98
|
+
* category filter selection. No server/Google concerns; this is the state a
|
|
99
|
+
* host would otherwise wire to its own backend.
|
|
100
|
+
*/
|
|
101
|
+
declare function useCalendar(options?: UseCalendarOptions): CalendarController;
|
|
102
|
+
|
|
103
|
+
interface CalendarProps {
|
|
104
|
+
/** UI language for the calendar's own strings. Default 'ko'. */
|
|
105
|
+
language?: string;
|
|
106
|
+
/** an external controller (from useCalendar); one is created internally if omitted */
|
|
107
|
+
controller?: CalendarController;
|
|
108
|
+
initialEvents?: CalendarEvent[];
|
|
109
|
+
initialCategories?: Category[];
|
|
110
|
+
initialDate?: Date;
|
|
111
|
+
initialView?: ViewType;
|
|
112
|
+
/** holidays/observances shown as a label in the month view's date header */
|
|
113
|
+
holidays?: Holiday[];
|
|
114
|
+
className?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Calendar — the full calendar UI: a toolbar (title, prev/next/today, search,
|
|
118
|
+
* category filter, view switcher) over month/week/day/year views, with an
|
|
119
|
+
* event create/edit modal. Ported from the calendary project into softium
|
|
120
|
+
* token CSS; server / Google-Calendar / today-task concerns removed. Runs off
|
|
121
|
+
* local state (or a host-provided controller).
|
|
122
|
+
*/
|
|
123
|
+
declare function Calendar({ language, controller, initialEvents, initialCategories, initialDate, initialView, holidays, className, }: CalendarProps): ReactNode;
|
|
124
|
+
|
|
125
|
+
interface MonthViewProps {
|
|
126
|
+
currentDate: Date;
|
|
127
|
+
events: CalendarEvent[];
|
|
128
|
+
selectedCategoryIds: string[];
|
|
129
|
+
categories: Category[];
|
|
130
|
+
language: string;
|
|
131
|
+
/** holidays/observances shown as a label next to the date number */
|
|
132
|
+
holidays?: Holiday[];
|
|
133
|
+
selectedEvent: CalendarEvent | null;
|
|
134
|
+
previewEvent: PreviewEvent | null;
|
|
135
|
+
expandedRows: Set<number>;
|
|
136
|
+
setExpandedRows: (updater: (prev: Set<number>) => Set<number>) => void;
|
|
137
|
+
onEventClick: (event: CalendarEvent, element?: HTMLElement) => void;
|
|
138
|
+
/** open the create modal for a single day (the "+ new" hover button) */
|
|
139
|
+
onAddEventClick: (date: Date, x?: number, y?: number) => void;
|
|
140
|
+
/** open the create modal for a dragged multi-day range */
|
|
141
|
+
onRangeSelect: (start: Date, end: Date, x: number, y: number) => void;
|
|
142
|
+
/** drag an event chip/bar onto another day to move it — for a recurring
|
|
143
|
+
* event, the host is expected to resolve a "this/following/all" scope
|
|
144
|
+
* (e.g. via a dialog) before actually committing the move */
|
|
145
|
+
onEventMove: (event: CalendarEvent, newDate: Date) => void;
|
|
146
|
+
/** drag a non-recurring period bar's start/end edge onto another day to resize it */
|
|
147
|
+
onEventResize: (event: CalendarEvent, edge: 'start' | 'end', newDate: Date) => void;
|
|
148
|
+
}
|
|
149
|
+
declare function MonthView({ currentDate, events, selectedCategoryIds, categories, language, holidays, selectedEvent, previewEvent, expandedRows, setExpandedRows, onEventClick, onAddEventClick, onRangeSelect, onEventMove, onEventResize, }: MonthViewProps): react.JSX.Element;
|
|
150
|
+
|
|
151
|
+
interface WeekViewProps {
|
|
152
|
+
currentDate: Date;
|
|
153
|
+
events: CalendarEvent[];
|
|
154
|
+
selectedCategoryIds: string[];
|
|
155
|
+
categories: Category[];
|
|
156
|
+
language: string;
|
|
157
|
+
selectedEvent: CalendarEvent | null;
|
|
158
|
+
previewEvent: PreviewEvent | null;
|
|
159
|
+
onEventClick: (event: CalendarEvent, element?: HTMLElement) => void;
|
|
160
|
+
onAddEventClick: (date: Date, hour?: number, clientX?: number, clientY?: number) => void;
|
|
161
|
+
/** drag an empty time-grid area (snapped to 15 min) to create a timed event */
|
|
162
|
+
onTimeRangeSelect: (date: Date, startMin: number, endMin: number) => void;
|
|
163
|
+
/** drag (any event) or resize (non-recurring only) to a new start/end
|
|
164
|
+
* time; `newDate` is set only when a "move" drag also crossed into a
|
|
165
|
+
* different day column. For a recurring event, the host is expected to
|
|
166
|
+
* resolve a "this/following/all" scope before actually committing */
|
|
167
|
+
onEventTimeChange: (event: CalendarEvent, startMin: number, endMin: number, newDate?: Date) => void;
|
|
168
|
+
}
|
|
169
|
+
/** WeekView — a 7-day × 24-hour time grid with absolutely-positioned event chips. */
|
|
170
|
+
declare function WeekView({ currentDate, events, selectedCategoryIds, categories, language, selectedEvent, previewEvent, onEventClick, onAddEventClick, onTimeRangeSelect, onEventTimeChange, }: WeekViewProps): react.JSX.Element;
|
|
171
|
+
|
|
172
|
+
interface DayViewProps {
|
|
173
|
+
currentDate: Date;
|
|
174
|
+
events: CalendarEvent[];
|
|
175
|
+
selectedCategoryIds: string[];
|
|
176
|
+
categories: Category[];
|
|
177
|
+
language: string;
|
|
178
|
+
selectedEvent: CalendarEvent | null;
|
|
179
|
+
previewEvent: PreviewEvent | null;
|
|
180
|
+
onEventClick: (event: CalendarEvent, element?: HTMLElement) => void;
|
|
181
|
+
onAddEventClick: (date: Date, hour?: number, clientX?: number, clientY?: number) => void;
|
|
182
|
+
/** drag an empty time-grid area (snapped to 15 min) to create a timed event */
|
|
183
|
+
onTimeRangeSelect: (date: Date, startMin: number, endMin: number) => void;
|
|
184
|
+
/** drag (any event) or resize (non-recurring only) to a new start/end
|
|
185
|
+
* time. For a recurring event, the host is expected to resolve a
|
|
186
|
+
* "this/following/all" scope before actually committing */
|
|
187
|
+
onEventTimeChange: (event: CalendarEvent, startMin: number, endMin: number) => void;
|
|
188
|
+
}
|
|
189
|
+
/** DayView — a single-day × 24-hour time grid. */
|
|
190
|
+
declare function DayView({ currentDate, events, selectedCategoryIds, categories, language, selectedEvent, previewEvent, onEventClick, onAddEventClick, onTimeRangeSelect, onEventTimeChange, }: DayViewProps): react.JSX.Element;
|
|
191
|
+
|
|
192
|
+
interface YearViewProps {
|
|
193
|
+
currentDate: Date;
|
|
194
|
+
events: CalendarEvent[];
|
|
195
|
+
selectedCategoryIds: string[];
|
|
196
|
+
categories: Category[];
|
|
197
|
+
language: string;
|
|
198
|
+
onDateClick: (date: Date) => void;
|
|
199
|
+
onViewChange: (view: 'month') => void;
|
|
200
|
+
}
|
|
201
|
+
/** YearView — a 12-up grid of mini month calendars with per-day event dots. */
|
|
202
|
+
declare function YearView({ currentDate, events, selectedCategoryIds, categories, language, onDateClick, onViewChange, }: YearViewProps): react.JSX.Element;
|
|
203
|
+
|
|
204
|
+
type DeleteType = 'this' | 'following' | 'all';
|
|
205
|
+
interface DeleteOptionsDialogProps {
|
|
206
|
+
language: string;
|
|
207
|
+
selectedDeleteType: DeleteType;
|
|
208
|
+
setSelectedDeleteType: (type: DeleteType) => void;
|
|
209
|
+
onCancel: () => void;
|
|
210
|
+
onDelete: () => void;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* DeleteOptionsDialog — the recurring-event delete scope picker (this / this &
|
|
214
|
+
* following / all), shown in a small centered dialog. Ported from calendary.
|
|
215
|
+
*/
|
|
216
|
+
declare function DeleteOptionsDialog({ language, selectedDeleteType, setSelectedDeleteType, onCancel, onDelete, }: DeleteOptionsDialogProps): react.JSX.Element;
|
|
217
|
+
|
|
218
|
+
interface EventSaveData {
|
|
219
|
+
title: string;
|
|
220
|
+
startTime: string;
|
|
221
|
+
endTime: string;
|
|
222
|
+
description: string;
|
|
223
|
+
categoryId: string;
|
|
224
|
+
startDate: Date;
|
|
225
|
+
endDate?: Date;
|
|
226
|
+
recurrence?: Recurrence;
|
|
227
|
+
}
|
|
228
|
+
interface EventModalProps {
|
|
229
|
+
open: boolean;
|
|
230
|
+
onOpenChange: (open: boolean) => void;
|
|
231
|
+
/** the event being edited, or null when creating */
|
|
232
|
+
event?: CalendarEvent | null;
|
|
233
|
+
selectedDate: Date | null;
|
|
234
|
+
selectedEndDate?: Date | null;
|
|
235
|
+
defaultStartTime?: string;
|
|
236
|
+
defaultEndTime?: string;
|
|
237
|
+
categories: Category[];
|
|
238
|
+
selectedCategoryIds: string[];
|
|
239
|
+
language: string;
|
|
240
|
+
onSave: (data: EventSaveData) => void;
|
|
241
|
+
onDelete?: (deleteType: DeleteType) => void;
|
|
242
|
+
/** live preview callback (drives the ghost chip in the views) */
|
|
243
|
+
onChange?: (data: EventSaveData | null) => void;
|
|
244
|
+
onToggleCategory: (id: string) => void;
|
|
245
|
+
onAddCategory: (data: {
|
|
246
|
+
name: string;
|
|
247
|
+
color: string;
|
|
248
|
+
}) => string;
|
|
249
|
+
onUpdateCategory: (id: string, data: {
|
|
250
|
+
name: string;
|
|
251
|
+
color: string;
|
|
252
|
+
}) => void;
|
|
253
|
+
onDeleteCategory: (id: string) => void;
|
|
254
|
+
onReorderCategories: (from: number, to: number) => void;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* EventModal — the create/edit event dialog. Ported from calendary's
|
|
258
|
+
* EventCreatePopover into a centered token-CSS modal: title, start/end date,
|
|
259
|
+
* start/end time (duration-preserving), a category picker with inline add/edit,
|
|
260
|
+
* a description field, and a recurrence editor. Save / Cancel / Delete footer;
|
|
261
|
+
* deleting a recurring event opens the scope picker.
|
|
262
|
+
*/
|
|
263
|
+
declare function EventModal({ open, onOpenChange, event, selectedDate, selectedEndDate, defaultStartTime, defaultEndTime, categories, selectedCategoryIds, language, onSave, onDelete, onChange, onToggleCategory, onAddCategory, onUpdateCategory, onDeleteCategory, onReorderCategories, }: EventModalProps): react.JSX.Element | null;
|
|
264
|
+
|
|
265
|
+
type RecurrenceEndType = 'never' | 'date' | 'count';
|
|
266
|
+
interface RecurrenceSectionProps {
|
|
267
|
+
language: string;
|
|
268
|
+
recurrenceFreq: RecurrenceFreq;
|
|
269
|
+
setRecurrenceFreq: (freq: RecurrenceFreq) => void;
|
|
270
|
+
/** weekdays as Mon=0 … Sun=6 */
|
|
271
|
+
selectedWeekdays: number[];
|
|
272
|
+
setSelectedWeekdays: (weekdays: number[]) => void;
|
|
273
|
+
recurrenceEndType: RecurrenceEndType;
|
|
274
|
+
setRecurrenceEndType: (type: RecurrenceEndType) => void;
|
|
275
|
+
recurrenceCount: string | number;
|
|
276
|
+
setRecurrenceCount: (count: string | number) => void;
|
|
277
|
+
recurrenceEndDate: Date | undefined;
|
|
278
|
+
setRecurrenceEndDate: (date: Date | undefined) => void;
|
|
279
|
+
internalStartDate: Date | undefined;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* RecurrenceSection — frequency segmented tabs, a weekly weekday picker, and an
|
|
283
|
+
* end-condition selector (never / date / count). Ported from calendary. Fully
|
|
284
|
+
* controlled; all state lives in the parent event modal.
|
|
285
|
+
*/
|
|
286
|
+
declare function RecurrenceSection({ language, recurrenceFreq, setRecurrenceFreq, selectedWeekdays, setSelectedWeekdays, recurrenceEndType, setRecurrenceEndType, recurrenceCount, setRecurrenceCount, setRecurrenceEndDate, internalStartDate, }: RecurrenceSectionProps): react.JSX.Element;
|
|
287
|
+
|
|
288
|
+
interface RecurrenceScopeDialogProps {
|
|
289
|
+
language: string;
|
|
290
|
+
selectedScope: DeleteType;
|
|
291
|
+
setSelectedScope: (type: DeleteType) => void;
|
|
292
|
+
onCancel: () => void;
|
|
293
|
+
onConfirm: () => void;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* RecurrenceScopeDialog — the recurring-event drag-move scope picker (this /
|
|
297
|
+
* this & following / all), shown in a small centered dialog. Same shape as
|
|
298
|
+
* DeleteOptionsDialog but a separate component: the confirm action here is
|
|
299
|
+
* "move" (primary button), not "delete" (danger button), and the two flows
|
|
300
|
+
* are independent enough that sharing one component wasn't worth the prop
|
|
301
|
+
* branching.
|
|
302
|
+
*/
|
|
303
|
+
declare function RecurrenceScopeDialog({ language, selectedScope, setSelectedScope, onCancel, onConfirm, }: RecurrenceScopeDialogProps): react.JSX.Element;
|
|
304
|
+
|
|
305
|
+
interface CategoryItemProps {
|
|
306
|
+
cat: Category;
|
|
307
|
+
index: number;
|
|
308
|
+
checked: boolean;
|
|
309
|
+
language: string;
|
|
310
|
+
colorPalette: string[];
|
|
311
|
+
/** whether this row is in inline-edit mode */
|
|
312
|
+
editing: boolean;
|
|
313
|
+
onToggle: (id: string) => void;
|
|
314
|
+
onEditStart: (cat: Category) => void;
|
|
315
|
+
onEditCommit: (id: string, data: {
|
|
316
|
+
name: string;
|
|
317
|
+
color: string;
|
|
318
|
+
}) => void;
|
|
319
|
+
onEditCancel: () => void;
|
|
320
|
+
onDelete: (id: string) => void;
|
|
321
|
+
/** native drag reorder wiring */
|
|
322
|
+
onDragStartRow: (index: number) => void;
|
|
323
|
+
onDragEnterRow: (index: number) => void;
|
|
324
|
+
onDropRow: () => void;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* CategoryItem — one row in the category list: a color-dot checkbox + name, a
|
|
328
|
+
* hover "⋯" menu (edit / delete), an inline edit mode with a color-swatch
|
|
329
|
+
* popover, and native drag-to-reorder. Ported from calendary's
|
|
330
|
+
* DraggableCategoryItem (Google-calendar branches dropped).
|
|
331
|
+
*/
|
|
332
|
+
declare function CategoryItem({ cat, index, checked, language, colorPalette, editing, onToggle, onEditStart, onEditCommit, onEditCancel, onDelete, onDragStartRow, onDragEnterRow, onDropRow, }: CategoryItemProps): react.JSX.Element;
|
|
333
|
+
|
|
334
|
+
interface CategoryFilterProps {
|
|
335
|
+
categories: Category[];
|
|
336
|
+
selectedCategoryIds: string[];
|
|
337
|
+
language: string;
|
|
338
|
+
onToggle: (id: string) => void;
|
|
339
|
+
onAdd: (data: {
|
|
340
|
+
name: string;
|
|
341
|
+
color: string;
|
|
342
|
+
}) => string;
|
|
343
|
+
onUpdate: (id: string, data: {
|
|
344
|
+
name: string;
|
|
345
|
+
color: string;
|
|
346
|
+
}) => void;
|
|
347
|
+
onDelete: (id: string) => void;
|
|
348
|
+
onReorder: (from: number, to: number) => void;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* CategoryFilter — the header's "N selected" popover: the multi-select category
|
|
352
|
+
* list (drag-reorderable) plus an inline add row. Ported from calendary's
|
|
353
|
+
* category dropdown.
|
|
354
|
+
*/
|
|
355
|
+
declare function CategoryFilter({ categories, selectedCategoryIds, language, onToggle, onAdd, onUpdate, onDelete, onReorder, }: CategoryFilterProps): react.JSX.Element;
|
|
356
|
+
|
|
357
|
+
interface SegmentOption<T extends string> {
|
|
358
|
+
value: T;
|
|
359
|
+
label: ReactNode;
|
|
360
|
+
}
|
|
361
|
+
interface SegmentTabsProps<T extends string> {
|
|
362
|
+
value: T;
|
|
363
|
+
onValueChange: (value: T) => void;
|
|
364
|
+
options: SegmentOption<T>[];
|
|
365
|
+
/** each tab grows to fill (used inside grids/rows). Default false. */
|
|
366
|
+
block?: boolean;
|
|
367
|
+
className?: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* SegmentTabs — an iOS-style segmented control: a muted track with a raised
|
|
371
|
+
* white pill on the active tab. Ported from calendary's SegmentTabs.
|
|
372
|
+
*/
|
|
373
|
+
declare function SegmentTabs<T extends string>({ value, onValueChange, options, block, className, }: SegmentTabsProps<T>): react.JSX.Element;
|
|
374
|
+
|
|
375
|
+
/** Apple-style category color presets (ported from calendary). */
|
|
376
|
+
declare const COLOR_PRESETS: string[];
|
|
377
|
+
/** nearest preset to an arbitrary hex, by RGB euclidean distance */
|
|
378
|
+
declare function findClosestPresetColor(hex: string): string;
|
|
379
|
+
/** hex → rgba at the given alpha (used for the event-chip fill tint) */
|
|
380
|
+
declare function withAlpha(color: string | undefined, alpha: number): string;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* All occurrence *dates* of a recurring series that fall in [from, to]
|
|
384
|
+
* (inclusive), honouring interval / byweekday / until / count. No rrule dep —
|
|
385
|
+
* a compact engine covering DAILY / WEEKLY / MONTHLY / YEARLY. Exported for
|
|
386
|
+
* "this and following" recurrence splits (see Calendar.tsx's
|
|
387
|
+
* handleRecurrenceScopeConfirm), which needs to know how many occurrences
|
|
388
|
+
* land before a given split date to carry over a correct remaining `count`.
|
|
389
|
+
*/
|
|
390
|
+
declare function occurrencesInRange(base: Date, rec: Recurrence, from: Date, to: Date): Date[];
|
|
391
|
+
/**
|
|
392
|
+
* Expand every recurring master in `events` into concrete instances that fall
|
|
393
|
+
* inside [startDate, endDate]; non-recurring events pass through unchanged.
|
|
394
|
+
*/
|
|
395
|
+
declare function expandRecurringEvents(events: CalendarEvent[], startDate: Date, endDate: Date): CalendarEvent[];
|
|
396
|
+
/** whether `date` falls inside an event's [date, endDate] span (day-granular) */
|
|
397
|
+
declare function eventCoversDate(event: CalendarEvent, date: Date): boolean;
|
|
398
|
+
/** events on a given date, category-filtered, sorted by start time */
|
|
399
|
+
declare function getEventsForDate(date: Date | null, events: CalendarEvent[], selectedCategoryIds: string[]): CalendarEvent[];
|
|
400
|
+
/** first free hour ("HH:00") on a date, 09:00–23:00, else 09:00 */
|
|
401
|
+
declare function getNextAvailableTime(date: Date | null, events: CalendarEvent[]): string;
|
|
402
|
+
|
|
403
|
+
declare const monthNames: Record<string, string[]>;
|
|
404
|
+
declare const dayNames: Record<string, string[]>;
|
|
405
|
+
/** the month grid, including leading/trailing days from adjacent months */
|
|
406
|
+
declare function getDaysInMonth(date: Date): {
|
|
407
|
+
days: Date[];
|
|
408
|
+
rows: number;
|
|
409
|
+
};
|
|
410
|
+
/** the seven days (Sun→Sat) of the week containing `date` */
|
|
411
|
+
declare function getWeekDays(date: Date): Date[];
|
|
412
|
+
declare function isSameDay(a: Date | null, b: Date | null): boolean;
|
|
413
|
+
declare function isToday(date: Date | null): boolean;
|
|
414
|
+
declare function isCurrentMonth(date: Date | null, currentDate: Date): boolean;
|
|
415
|
+
declare function getPreviousPeriodDate(currentDate: Date, viewType: ViewType): Date;
|
|
416
|
+
declare function getNextPeriodDate(currentDate: Date, viewType: ViewType): Date;
|
|
417
|
+
/** YYYY-MM-DD (local) */
|
|
418
|
+
declare function formatDate(date: Date): string;
|
|
419
|
+
/** clientY inside a time-grid column's bounding rect → minutes-of-day (0–1440), unclamped-snap-ready */
|
|
420
|
+
declare function minutesFromY(clientY: number, rect: {
|
|
421
|
+
top: number;
|
|
422
|
+
height: number;
|
|
423
|
+
}): number;
|
|
424
|
+
/** round to the nearest `step` minutes (default 15) */
|
|
425
|
+
declare function snapMinutes(minutes: number, step?: number): number;
|
|
426
|
+
/** minutes-of-day → "HH:MM", clamped to a valid time */
|
|
427
|
+
declare function minutesToHHMM(minutes: number): string;
|
|
428
|
+
/** "HH:MM" → minutes-of-day */
|
|
429
|
+
declare function hhmmToMinutes(hhmm: string | undefined): number;
|
|
430
|
+
|
|
431
|
+
/** The calendar ships ko/en strings inline (like the source), chosen by `language`. */
|
|
432
|
+
type CalLocale = 'ko' | 'en';
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* @softium/calendar
|
|
436
|
+
*
|
|
437
|
+
* A full calendar UI (month / week / day / year views + an event create/edit
|
|
438
|
+
* modal with categories and recurrence), token-CSS themed. Import the stylesheet
|
|
439
|
+
* once: import '@softium/calendar/styles.css';
|
|
440
|
+
*/
|
|
441
|
+
declare const VERSION = "0.0.0";
|
|
442
|
+
|
|
443
|
+
export { COLOR_PRESETS, type CalLocale, Calendar, type CalendarController, type CalendarEvent, type CalendarProps, type Category, CategoryFilter, type CategoryFilterProps, CategoryItem, type CategoryItemProps, DayView, type DayViewProps, DeleteOptionsDialog, type DeleteOptionsDialogProps, type DeleteType, EventModal, type EventModalProps, type EventSaveData, type Holiday, MonthView, type MonthViewProps, type PreviewEvent, type Recurrence, type RecurrenceEndType, type RecurrenceFreq, RecurrenceScopeDialog, type RecurrenceScopeDialogProps, RecurrenceSection, type RecurrenceSectionProps, type SegmentOption, SegmentTabs, type SegmentTabsProps, type UseCalendarOptions, VERSION, type ViewType, WeekView, type WeekViewProps, YearView, type YearViewProps, dayNames, eventCoversDate, expandRecurringEvents, findClosestPresetColor, formatDate, getDaysInMonth, getEventsForDate, getNextAvailableTime, getNextPeriodDate, getPreviousPeriodDate, getWeekDays, hhmmToMinutes, isCurrentMonth, isSameDay, isToday, minutesFromY, minutesToHHMM, monthNames, occurrencesInRange, snapMinutes, useCalendar, withAlpha };
|