ape-calendar 0.3.0 → 0.6.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 +90 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +305 -9
- package/dist/index.d.ts +305 -9
- package/dist/index.js +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
4
|
-
import { LocaleInput, EventInput } from '@fullcalendar/core';
|
|
4
|
+
import { LocaleInput, EventInput, BusinessHoursInput } from '@fullcalendar/core';
|
|
5
5
|
import { Locale } from 'react-day-picker';
|
|
6
6
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
|
9
9
|
* Default event status union. Consumers can pass their own string union as a
|
|
10
10
|
* generic parameter to override.
|
|
11
11
|
*/
|
|
12
|
-
type DefaultEventStatus = 'draft' | 'published' | 'scheduled' | 'archived' | 'cancelled';
|
|
12
|
+
type DefaultEventStatus = 'draft' | 'published' | 'scheduled' | 'archived' | 'cancelled' | 'finalizado';
|
|
13
13
|
/**
|
|
14
14
|
* Minimum shape a calendar event must satisfy. Consumers extend this interface
|
|
15
15
|
* with their own domain fields (eventType, modalities, audience, etc.) and pass
|
|
@@ -41,11 +41,36 @@ interface BaseCalendarEvent<Status extends string = DefaultEventStatus> {
|
|
|
41
41
|
durationMinutes?: number;
|
|
42
42
|
isAllDay?: boolean;
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Calendar views. Designs prioritise `list` / `week` / `month`; `day` is kept
|
|
46
|
+
* for consumers that still rely on the single-day time grid.
|
|
47
|
+
*/
|
|
48
|
+
type CalendarView = 'list' | 'day' | 'week' | 'month';
|
|
45
49
|
interface CalendarVisibleRange {
|
|
46
50
|
start: Date;
|
|
47
51
|
end: Date;
|
|
48
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Direction to move the visible range by one step in the current view.
|
|
55
|
+
*/
|
|
56
|
+
type CalendarNavDirection = 'prev' | 'next' | 'today';
|
|
57
|
+
/**
|
|
58
|
+
* Availability ("horario de atención") band rendered as a subtle background in
|
|
59
|
+
* the time-grid views. Shape matches FullCalendar's `businessHours` input so it
|
|
60
|
+
* can be fed straight through `mapAvailabilityToBusinessHours`.
|
|
61
|
+
*
|
|
62
|
+
* Mirror this shape in `ape-calendar-form` (AvailabilityScheduleDialog emits it)
|
|
63
|
+
* — the two packages intentionally do not depend on each other.
|
|
64
|
+
*/
|
|
65
|
+
interface AvailabilitySlot {
|
|
66
|
+
/** Days of week the slot applies to. 0=Sunday … 6=Saturday. */
|
|
67
|
+
daysOfWeek: number[];
|
|
68
|
+
/** Start of the slot, `HH:mm` (24h). */
|
|
69
|
+
startTime: string;
|
|
70
|
+
/** End of the slot, `HH:mm` (24h). */
|
|
71
|
+
endTime: string;
|
|
72
|
+
}
|
|
73
|
+
type AvailabilitySchedule = AvailabilitySlot[];
|
|
49
74
|
type CalendarUpdateSource = 'mini' | 'macro' | 'system';
|
|
50
75
|
interface SlotActionState {
|
|
51
76
|
isOpen: boolean;
|
|
@@ -74,11 +99,76 @@ interface EventTimeChangePayload<E> {
|
|
|
74
99
|
revert: () => void;
|
|
75
100
|
}
|
|
76
101
|
|
|
102
|
+
interface EventListRowMessages {
|
|
103
|
+
edit?: (title: string) => string;
|
|
104
|
+
delete?: (title: string) => string;
|
|
105
|
+
}
|
|
106
|
+
interface EventListRowProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
107
|
+
event: E;
|
|
108
|
+
onEdit: (event: E) => void;
|
|
109
|
+
onDelete: (event: E) => void;
|
|
110
|
+
locale?: string;
|
|
111
|
+
/** Map of status → label override for the EventStatusBadge. */
|
|
112
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
113
|
+
/** Domain-specific meta (event type, modality…). Same contract as MacroCalendar. */
|
|
114
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
115
|
+
messages?: EventListRowMessages;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Single row of the agenda/list view: time chip on the left, title + meta in
|
|
119
|
+
* the middle, status badge + actions on the right — matching the Figma agenda
|
|
120
|
+
* layout. Rendered by `EventAgendaList`; usable standalone.
|
|
121
|
+
*/
|
|
122
|
+
declare const EventListRow: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, renderEventMeta, messages, }: EventListRowProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
123
|
+
|
|
124
|
+
interface EventAgendaListMessages extends EventListRowMessages {
|
|
125
|
+
/** Empty placeholder per day when there are events elsewhere in the range. */
|
|
126
|
+
noEventsForDay?: string;
|
|
127
|
+
/** Global empty state when no events in the entire range. */
|
|
128
|
+
noEvents?: string;
|
|
129
|
+
}
|
|
130
|
+
interface EventAgendaListDayInfo<E> {
|
|
131
|
+
hasEvents: boolean;
|
|
132
|
+
events: E[];
|
|
133
|
+
}
|
|
134
|
+
interface EventAgendaListProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
135
|
+
events: E[];
|
|
136
|
+
/** Half-open `[start, end)` window — all days in between are rendered. */
|
|
137
|
+
range: {
|
|
138
|
+
start: Date;
|
|
139
|
+
end: Date;
|
|
140
|
+
};
|
|
141
|
+
/** BCP-47 locale string. Default: `'es-CO'`. */
|
|
142
|
+
locale?: string;
|
|
143
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
144
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
145
|
+
/**
|
|
146
|
+
* Slot rendered between the day anchor and the event list — used by portals
|
|
147
|
+
* to inject availability pills ("Horario de atención" / "No tenemos atención")
|
|
148
|
+
* or any other per-day header. The library does NOT derive this from the
|
|
149
|
+
* `availability` prop; the portal decides.
|
|
150
|
+
*/
|
|
151
|
+
renderDayHeader?: (date: Date, info: EventAgendaListDayInfo<E>) => ReactNode;
|
|
152
|
+
onEditEvent: (event: E) => void;
|
|
153
|
+
onDeleteEvent: (event: E) => void;
|
|
154
|
+
messages?: EventAgendaListMessages;
|
|
155
|
+
className?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Day-grouped agenda list — the calendar's "list" view. Each day renders a
|
|
159
|
+
* left anchor (number + short month + weekday) and a stack of {@link EventListRow}s.
|
|
160
|
+
* Empty days still render so the consumer can show a "no attention" pill via
|
|
161
|
+
* the `renderDayHeader` slot.
|
|
162
|
+
*/
|
|
163
|
+
declare const EventAgendaList: <Status extends string, E extends BaseCalendarEvent<Status>>({ events, range, locale, statusLabels, renderEventMeta, renderDayHeader, onEditEvent, onDeleteEvent, messages, className, }: EventAgendaListProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
164
|
+
|
|
77
165
|
interface MacroCalendarMessages {
|
|
78
166
|
/** `+N more` link. String form interpolates `{count}`; function form receives the count. */
|
|
79
167
|
moreLink?: string | ((count: number) => string);
|
|
80
168
|
allDayText?: string;
|
|
81
169
|
todayHeaderAria?: string;
|
|
170
|
+
/** Empty-state text shown by the list view when there are no events in range. */
|
|
171
|
+
noEvents?: string;
|
|
82
172
|
}
|
|
83
173
|
interface MacroCalendarProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
84
174
|
events: E[];
|
|
@@ -102,12 +192,20 @@ interface MacroCalendarProps<Status extends string, E extends BaseCalendarEvent<
|
|
|
102
192
|
fullCalendarLocale?: LocaleInput;
|
|
103
193
|
/** First day of the week (0=Sunday, 1=Monday, etc.). Default: 1. */
|
|
104
194
|
firstDay?: number;
|
|
195
|
+
/** Availability ("horario de atención") band painted as a subtle time-grid background. */
|
|
196
|
+
availability?: AvailabilitySchedule;
|
|
105
197
|
statusLabels?: Partial<Record<Status, string>>;
|
|
106
198
|
renderEventMeta?: (event: E) => ReactNode;
|
|
107
199
|
/** Custom render for a day-column header. Falls back to the built-in header when omitted. */
|
|
108
200
|
renderDayHeader?: (date: Date, info: {
|
|
109
201
|
isToday: boolean;
|
|
110
202
|
}) => ReactNode;
|
|
203
|
+
/**
|
|
204
|
+
* Per-day header slot for the agenda/list view (e.g. "Horario de atención"
|
|
205
|
+
* pill, "No tenemos atención"…). The library does not derive this from the
|
|
206
|
+
* `availability` prop — the portal decides.
|
|
207
|
+
*/
|
|
208
|
+
renderAgendaDayHeader?: (date: Date, info: EventAgendaListDayInfo<E>) => ReactNode;
|
|
111
209
|
messages?: MacroCalendarMessages;
|
|
112
210
|
/** Status values that cannot be dragged. Default: `['archived']`. */
|
|
113
211
|
immutableStatuses?: Status[];
|
|
@@ -117,9 +215,16 @@ interface MacroCalendarProps<Status extends string, E extends BaseCalendarEvent<
|
|
|
117
215
|
height?: number | string;
|
|
118
216
|
/** Duration of the just-created/moved highlight flash, in ms. Default: `650`. */
|
|
119
217
|
highlightDurationMs?: number;
|
|
218
|
+
/** Time-grid row height as `HH:mm:ss`. Default: `'00:30:00'`. */
|
|
219
|
+
slotDuration?: string;
|
|
220
|
+
/**
|
|
221
|
+
* Drag/resize granularity as `HH:mm:ss`. Default: `'00:15:00'`. Values below
|
|
222
|
+
* 5 min may feel nervous when dragging.
|
|
223
|
+
*/
|
|
224
|
+
snapDuration?: string;
|
|
120
225
|
className?: string;
|
|
121
226
|
}
|
|
122
|
-
declare const MacroCalendar: <Status extends string, E extends BaseCalendarEvent<Status>>({ events, activeView, selectedDate, highlightEventIds, onDeleteEvent, onEditEvent, onEventTimeChange, onDateClick, onDateSelected, onVisibleRangeChange, onSwitchToDay, locale, fullCalendarLocale, firstDay, statusLabels, renderEventMeta, renderDayHeader, messages, immutableStatuses, eventAllow, height, highlightDurationMs, className, }: MacroCalendarProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
227
|
+
declare const MacroCalendar: <Status extends string, E extends BaseCalendarEvent<Status>>({ events, activeView, selectedDate, highlightEventIds, onDeleteEvent, onEditEvent, onEventTimeChange, onDateClick, onDateSelected, onVisibleRangeChange, onSwitchToDay, locale, fullCalendarLocale, firstDay, availability, statusLabels, renderEventMeta, renderDayHeader, renderAgendaDayHeader, messages, immutableStatuses, eventAllow, height, highlightDurationMs, slotDuration, snapDuration, className, }: MacroCalendarProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
123
228
|
|
|
124
229
|
interface MiniMonthCalendarMessages {
|
|
125
230
|
previousMonth?: string;
|
|
@@ -143,23 +248,55 @@ interface MiniMonthCalendarProps<Status extends string = string> {
|
|
|
143
248
|
messages?: MiniMonthCalendarMessages;
|
|
144
249
|
/** Optional map of status → CSS color override. Falls back to CSS vars. */
|
|
145
250
|
statusColors?: Partial<Record<Status, string>>;
|
|
251
|
+
/**
|
|
252
|
+
* Visual variant. `'card'` (default) renders each day as a boxed cell on a
|
|
253
|
+
* subtle surface — the original look. `'flat'` renders plain days on a white
|
|
254
|
+
* surface (agenda sidebar design). Opt-in: existing consumers are unaffected.
|
|
255
|
+
*/
|
|
256
|
+
variant?: 'card' | 'flat';
|
|
257
|
+
/**
|
|
258
|
+
* When set, the week row containing this date is highlighted with a rounded
|
|
259
|
+
* band (typically the consumer's `selectedDate`). Off when omitted.
|
|
260
|
+
*/
|
|
261
|
+
highlightWeekOf?: Date;
|
|
262
|
+
/** First day of the week for the highlighted band (0=Sunday … 6=Saturday). Default: `1`. */
|
|
263
|
+
firstDay?: number;
|
|
264
|
+
/** Show the leading/trailing days of adjacent months. Default: `false`. */
|
|
265
|
+
showOutsideDays?: boolean;
|
|
146
266
|
className?: string;
|
|
147
267
|
}
|
|
148
|
-
declare const MiniMonthCalendar: <Status extends string = string>({ selectedDate, visibleMonth, eventDayStatuses, onSelectDate, onMonthChange, locale, pickerLocale, messages, statusColors, className, }: MiniMonthCalendarProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
268
|
+
declare const MiniMonthCalendar: <Status extends string = string>({ selectedDate, visibleMonth, eventDayStatuses, onSelectDate, onMonthChange, locale, pickerLocale, messages, statusColors, variant, highlightWeekOf, firstDay, showOutsideDays, className, }: MiniMonthCalendarProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
149
269
|
|
|
150
270
|
interface CalendarToolbarMessages {
|
|
151
271
|
groupAriaLabel?: string;
|
|
152
272
|
newEvent?: string;
|
|
273
|
+
today?: string;
|
|
274
|
+
previous?: string;
|
|
275
|
+
next?: string;
|
|
153
276
|
views?: Partial<Record<CalendarView, string>>;
|
|
154
277
|
}
|
|
155
278
|
interface CalendarToolbarProps {
|
|
156
279
|
activeView: CalendarView;
|
|
157
280
|
onChangeView: (view: CalendarView) => void;
|
|
281
|
+
/**
|
|
282
|
+
* View buttons to show, in order. Default: `['month', 'week', 'list']`. The
|
|
283
|
+
* `week` button represents the day/week time grid (it stays active in `day`
|
|
284
|
+
* view too); `day` itself is reached via the "Hoy" control, not a button.
|
|
285
|
+
*/
|
|
286
|
+
views?: CalendarView[];
|
|
287
|
+
/** Emits a navigation intent. Wire with `shiftDate(selectedDate, activeView, dir)`. */
|
|
288
|
+
onNavigate?: (direction: CalendarNavDirection) => void;
|
|
289
|
+
/** Highlights the "Hoy" button as active (e.g. day view focused on today). */
|
|
290
|
+
todayActive?: boolean;
|
|
291
|
+
/** Current period label (e.g. "Mayo 2026") rendered next to the nav controls. */
|
|
292
|
+
periodLabel?: ReactNode;
|
|
293
|
+
/** Slot for consumer-owned filters (status, regional…). Rendered between nav and views. */
|
|
294
|
+
filtersSlot?: ReactNode;
|
|
158
295
|
onNewEvent?: () => void;
|
|
159
296
|
messages?: CalendarToolbarMessages;
|
|
160
297
|
className?: string;
|
|
161
298
|
}
|
|
162
|
-
declare const CalendarToolbar: ({ activeView, onChangeView, onNewEvent, messages, className, }: CalendarToolbarProps) => react_jsx_runtime.JSX.Element;
|
|
299
|
+
declare const CalendarToolbar: ({ activeView, onChangeView, views, onNavigate, todayActive, periodLabel, filtersSlot, onNewEvent, messages, className, }: CalendarToolbarProps) => react_jsx_runtime.JSX.Element;
|
|
163
300
|
|
|
164
301
|
interface EventChipPopoverMessages {
|
|
165
302
|
edit?: string;
|
|
@@ -212,6 +349,53 @@ interface EventBlockContentProps<Status extends string, E extends BaseCalendarEv
|
|
|
212
349
|
}
|
|
213
350
|
declare const EventBlockContent: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, messages, }: EventBlockContentProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
214
351
|
|
|
352
|
+
interface EventTypeFilterItem {
|
|
353
|
+
id: string;
|
|
354
|
+
label: string;
|
|
355
|
+
/** Optional leading icon. When omitted, a colored dot is shown. */
|
|
356
|
+
icon?: ReactNode;
|
|
357
|
+
/** Optional dot color (any CSS color). Used when `icon` is absent. */
|
|
358
|
+
color?: string;
|
|
359
|
+
/** Optional count shown on the right (e.g. number of events of this type). */
|
|
360
|
+
count?: number;
|
|
361
|
+
}
|
|
362
|
+
interface EventTypeFilterListProps {
|
|
363
|
+
items: EventTypeFilterItem[];
|
|
364
|
+
/** Currently selected item ids. An empty array means "all". */
|
|
365
|
+
selectedIds: string[];
|
|
366
|
+
onToggle: (id: string) => void;
|
|
367
|
+
className?: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Sidebar list to filter events by type, with optional counts (as in the
|
|
371
|
+
* agenda designs). A building block — not a layout wrapper. The consumer owns
|
|
372
|
+
* the actual filtering and the surrounding sidebar.
|
|
373
|
+
*/
|
|
374
|
+
declare const EventTypeFilterList: ({ items, selectedIds, onToggle, className, }: EventTypeFilterListProps) => react_jsx_runtime.JSX.Element;
|
|
375
|
+
|
|
376
|
+
interface StatusFilterOption<Status extends string> {
|
|
377
|
+
status: Status;
|
|
378
|
+
label: string;
|
|
379
|
+
/** Optional dot color (any CSS color). */
|
|
380
|
+
color?: string;
|
|
381
|
+
}
|
|
382
|
+
interface StatusFilterSelectProps<Status extends string> {
|
|
383
|
+
options: StatusFilterOption<Status>[];
|
|
384
|
+
/** Currently selected statuses. An empty array means "all". */
|
|
385
|
+
selected: Status[];
|
|
386
|
+
onToggle: (status: Status) => void;
|
|
387
|
+
/** Always-visible trigger label. Default: `"Estado del evento"`. */
|
|
388
|
+
placeholder?: string;
|
|
389
|
+
className?: string;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Multi-select dropdown to filter events by status (the "Estado del evento"
|
|
393
|
+
* control in the toolbar). The placeholder stays visible at all times; a count
|
|
394
|
+
* badge reflects how many statuses are active. Generic over the consumer's
|
|
395
|
+
* status union — emits toggle intents, the consumer owns the filtering.
|
|
396
|
+
*/
|
|
397
|
+
declare const StatusFilterSelect: <Status extends string>({ options, selected, onToggle, placeholder, className, }: StatusFilterSelectProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
398
|
+
|
|
215
399
|
interface MoreEventsPopoverMessages {
|
|
216
400
|
header?: (count: number) => string;
|
|
217
401
|
editAria?: (title: string) => string;
|
|
@@ -280,9 +464,13 @@ declare const EventStatusBadge: <Status extends string = string>({ status, label
|
|
|
280
464
|
interface EventTypeChipProps {
|
|
281
465
|
label: string;
|
|
282
466
|
icon?: ReactNode;
|
|
467
|
+
/** When provided, renders a ✕ button that fires this callback (e.g. clear the filter). */
|
|
468
|
+
onRemove?: () => void;
|
|
469
|
+
/** Accessible label for the remove button. Default: `"Remove"`. */
|
|
470
|
+
removeLabel?: string;
|
|
283
471
|
className?: string;
|
|
284
472
|
}
|
|
285
|
-
declare const EventTypeChip: ({ label, icon, className }: EventTypeChipProps) => react_jsx_runtime.JSX.Element;
|
|
473
|
+
declare const EventTypeChip: ({ label, icon, onRemove, removeLabel, className, }: EventTypeChipProps) => react_jsx_runtime.JSX.Element;
|
|
286
474
|
|
|
287
475
|
interface EmptyEventsStateProps {
|
|
288
476
|
title?: string;
|
|
@@ -299,7 +487,7 @@ declare const PopoverPortal: react.FC<PopoverPrimitive.PopoverPortalProps>;
|
|
|
299
487
|
declare const PopoverClose: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
300
488
|
declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
301
489
|
|
|
302
|
-
type ButtonVariant = 'primary' | 'secondary' | 'ghost';
|
|
490
|
+
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
|
|
303
491
|
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
304
492
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
305
493
|
variant?: ButtonVariant;
|
|
@@ -310,8 +498,86 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
310
498
|
}
|
|
311
499
|
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
312
500
|
|
|
501
|
+
interface SelectOption<T extends string> {
|
|
502
|
+
value: T;
|
|
503
|
+
label: string;
|
|
504
|
+
/** Optional dot color (any CSS color). Used when `icon` is absent. */
|
|
505
|
+
color?: string;
|
|
506
|
+
/** Optional leading icon. Takes precedence over `color`. */
|
|
507
|
+
icon?: ReactNode;
|
|
508
|
+
}
|
|
509
|
+
interface SelectBaseProps<T extends string> {
|
|
510
|
+
/** Always-visible label on the trigger (never replaced by the selection). */
|
|
511
|
+
placeholder: string;
|
|
512
|
+
options: SelectOption<T>[];
|
|
513
|
+
align?: 'start' | 'center' | 'end';
|
|
514
|
+
className?: string;
|
|
515
|
+
'aria-label'?: string;
|
|
516
|
+
}
|
|
517
|
+
interface SelectSingleProps<T extends string> extends SelectBaseProps<T> {
|
|
518
|
+
multiple?: false;
|
|
519
|
+
value: T | null;
|
|
520
|
+
onChange: (value: T | null) => void;
|
|
521
|
+
/** Re-clicking the active option clears it. Default: `true`. */
|
|
522
|
+
clearable?: boolean;
|
|
523
|
+
}
|
|
524
|
+
interface SelectMultipleProps<T extends string> extends SelectBaseProps<T> {
|
|
525
|
+
multiple: true;
|
|
526
|
+
/** Selected values. Empty means "all" — the consumer owns the filtering. */
|
|
527
|
+
value: T[];
|
|
528
|
+
onToggle: (value: T) => void;
|
|
529
|
+
}
|
|
530
|
+
type SelectProps<T extends string> = SelectSingleProps<T> | SelectMultipleProps<T>;
|
|
531
|
+
/**
|
|
532
|
+
* Popover-backed listbox dropdown. The trigger keeps `placeholder` visible at
|
|
533
|
+
* all times; multi mode shows a count badge, single mode appends the chosen
|
|
534
|
+
* label. Built on the {@link Popover} primitive (no extra Radix deps). Generic
|
|
535
|
+
* over the consumer's value union — emits intents, never owns selection state.
|
|
536
|
+
*/
|
|
537
|
+
declare const Select: <T extends string>(props: SelectProps<T>) => react_jsx_runtime.JSX.Element;
|
|
538
|
+
|
|
313
539
|
declare const APE_CALENDAR_ROOT_CLASS = "ape-calendar";
|
|
314
540
|
|
|
541
|
+
interface UseCalendarControllerOptions {
|
|
542
|
+
/** View the calendar starts on. Default: `'week'`. */
|
|
543
|
+
initialView?: CalendarView;
|
|
544
|
+
/** Date the calendar starts on. Default: now. */
|
|
545
|
+
initialDate?: Date;
|
|
546
|
+
/** First day of the week (0=Sunday … 6=Saturday). Default: `1`. */
|
|
547
|
+
firstDay?: number;
|
|
548
|
+
/** BCP-47 locale used to build {@link CalendarController.periodLabel}. Default: `'es-CO'`. */
|
|
549
|
+
locale?: string;
|
|
550
|
+
}
|
|
551
|
+
interface CalendarController {
|
|
552
|
+
activeView: CalendarView;
|
|
553
|
+
selectedDate: Date;
|
|
554
|
+
/** Last range reported by the calendar (kept in sync via `onVisibleRangeChange`). */
|
|
555
|
+
visibleRange: CalendarVisibleRange;
|
|
556
|
+
/** Localized label for the current period — spread onto `CalendarToolbar.periodLabel`. */
|
|
557
|
+
periodLabel: string;
|
|
558
|
+
/** True when the "Hoy" control is the active state (day view on today). */
|
|
559
|
+
todayActive: boolean;
|
|
560
|
+
onChangeView: (view: CalendarView) => void;
|
|
561
|
+
onNavigate: (direction: CalendarNavDirection) => void;
|
|
562
|
+
onSelectDate: (date: Date) => void;
|
|
563
|
+
onVisibleRangeChange: (start: Date, end: Date) => void;
|
|
564
|
+
onToday: () => void;
|
|
565
|
+
setActiveView: (view: CalendarView) => void;
|
|
566
|
+
setSelectedDate: (date: Date) => void;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Encapsulates the calendar's view/date state and the opinionated navigation
|
|
570
|
+
* behavior so every portal behaves identically:
|
|
571
|
+
*
|
|
572
|
+
* - "Hoy" jumps to today in day view (re-pressing it falls back to week).
|
|
573
|
+
* - Picking a day from the month or list view opens that day's week.
|
|
574
|
+
* - prev/next step by the current view (via {@link shiftDate}).
|
|
575
|
+
*
|
|
576
|
+
* The calendar stays fully controlled — this hook owns the consumer-side state
|
|
577
|
+
* and returns handlers to spread onto `CalendarToolbar` and `MacroCalendar`.
|
|
578
|
+
*/
|
|
579
|
+
declare const useCalendarController: ({ initialView, initialDate, firstDay, locale, }?: UseCalendarControllerOptions) => CalendarController;
|
|
580
|
+
|
|
315
581
|
declare const toDayKey: (date: Date) => DayKey;
|
|
316
582
|
declare const isSameDay: (left: Date, right: Date) => boolean;
|
|
317
583
|
/**
|
|
@@ -337,5 +603,35 @@ declare const formatDurationLabel: (durationMinutes: number, messages?: {
|
|
|
337
603
|
min?: string;
|
|
338
604
|
h?: string;
|
|
339
605
|
}) => string;
|
|
606
|
+
/**
|
|
607
|
+
* Maps an {@link AvailabilitySchedule} to FullCalendar's `businessHours` input.
|
|
608
|
+
* Useful when a consumer wants to constrain selection/dragging to the available
|
|
609
|
+
* window. Note: FullCalendar shades the NON-business area when this is set —
|
|
610
|
+
* for the colored "horario de atención" band use {@link mapAvailabilityToBackgroundEvents}.
|
|
611
|
+
*/
|
|
612
|
+
declare const mapAvailabilityToBusinessHours: (schedule: AvailabilitySchedule) => BusinessHoursInput;
|
|
613
|
+
/**
|
|
614
|
+
* Maps an {@link AvailabilitySchedule} to recurring FullCalendar background
|
|
615
|
+
* events, used to paint the colored availability band in time-grid views. The
|
|
616
|
+
* band color is driven by the `cal-availability-band` class (CSS var
|
|
617
|
+
* `--cal-availability-bg`) so it stays themeable.
|
|
618
|
+
*/
|
|
619
|
+
declare const mapAvailabilityToBackgroundEvents: (schedule: AvailabilitySchedule) => EventInput[];
|
|
620
|
+
/**
|
|
621
|
+
* Returns the half-open `[start, end)` range of the week that contains `date`.
|
|
622
|
+
* `firstDay` follows the same convention as FullCalendar (0=Sunday … 6=Saturday).
|
|
623
|
+
* Start is set to midnight of the week's first day; end is midnight 7 days later.
|
|
624
|
+
* Used by the agenda list to derive its visible window from `selectedDate`.
|
|
625
|
+
*/
|
|
626
|
+
declare const getWeekRange: (date: Date, firstDay?: number) => {
|
|
627
|
+
start: Date;
|
|
628
|
+
end: Date;
|
|
629
|
+
};
|
|
630
|
+
/**
|
|
631
|
+
* Returns the date a calendar should jump to when the user navigates one step
|
|
632
|
+
* in the given view. `today` always resolves to now. Used by the toolbar's
|
|
633
|
+
* prev/next/today controls (the calendar is date-controlled by the consumer).
|
|
634
|
+
*/
|
|
635
|
+
declare const shiftDate: (date: Date, view: CalendarView, direction: CalendarNavDirection) => Date;
|
|
340
636
|
|
|
341
|
-
export { APE_CALENDAR_ROOT_CLASS, type BaseCalendarEvent, Button, type ButtonProps, type ButtonSize, type ButtonVariant, CalendarToolbar, type CalendarToolbarMessages, type CalendarToolbarProps, type CalendarUpdateSource, type CalendarView, type CalendarVisibleRange, DayEventDot, type DayEventDotProps, type DayKey, type DefaultEventStatus, EmptyEventsState, type EmptyEventsStateProps, EventBlockContent, type EventBlockContentMessages, type EventBlockContentProps, EventChipMonth, type EventChipMonthProps, EventChipPopover, type EventChipPopoverMessages, type EventChipPopoverProps, EventStatusBadge, type EventStatusBadgeProps, type EventTimeChangePayload, EventTypeChip, type EventTypeChipProps, MacroCalendar, type MacroCalendarMessages, type MacroCalendarProps, MiniMonthCalendar, type MiniMonthCalendarMessages, type MiniMonthCalendarProps, MoreEventsPopover, type MoreEventsPopoverMessages, type MoreEventsPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, type SlotAction, type SlotActionPayload, type SlotActionState, SlotContextActions, type SlotContextActionsMessages, type SlotContextActionsProps, formatDurationLabel, formatHourLabel, getEventDayKeys, getEventDayStatuses, isSameDay, mapEventToCalendarInput, toDayKey };
|
|
637
|
+
export { APE_CALENDAR_ROOT_CLASS, type AvailabilitySchedule, type AvailabilitySlot, type BaseCalendarEvent, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type CalendarController, type CalendarNavDirection, CalendarToolbar, type CalendarToolbarMessages, type CalendarToolbarProps, type CalendarUpdateSource, type CalendarView, type CalendarVisibleRange, DayEventDot, type DayEventDotProps, type DayKey, type DefaultEventStatus, EmptyEventsState, type EmptyEventsStateProps, EventAgendaList, type EventAgendaListDayInfo, type EventAgendaListMessages, type EventAgendaListProps, EventBlockContent, type EventBlockContentMessages, type EventBlockContentProps, EventChipMonth, type EventChipMonthProps, EventChipPopover, type EventChipPopoverMessages, type EventChipPopoverProps, EventListRow, type EventListRowMessages, type EventListRowProps, EventStatusBadge, type EventStatusBadgeProps, type EventTimeChangePayload, EventTypeChip, type EventTypeChipProps, type EventTypeFilterItem, EventTypeFilterList, type EventTypeFilterListProps, MacroCalendar, type MacroCalendarMessages, type MacroCalendarProps, MiniMonthCalendar, type MiniMonthCalendarMessages, type MiniMonthCalendarProps, MoreEventsPopover, type MoreEventsPopoverMessages, type MoreEventsPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, Select, type SelectMultipleProps, type SelectOption, type SelectProps, type SelectSingleProps, type SlotAction, type SlotActionPayload, type SlotActionState, SlotContextActions, type SlotContextActionsMessages, type SlotContextActionsProps, type StatusFilterOption, StatusFilterSelect, type StatusFilterSelectProps, type UseCalendarControllerOptions, formatDurationLabel, formatHourLabel, getEventDayKeys, getEventDayStatuses, getWeekRange, isSameDay, mapAvailabilityToBackgroundEvents, mapAvailabilityToBusinessHours, mapEventToCalendarInput, shiftDate, toDayKey, useCalendarController };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useEffect as Ct,useMemo as O,useRef as lt,useState as _e}from"react";import Me from"@fullcalendar/react";import Ne from"@fullcalendar/daygrid";import Ae from"@fullcalendar/timegrid";import Te from"@fullcalendar/interaction";import ke from"@fullcalendar/core/locales/es";import{useReducedMotion as Le}from"motion/react";import{CalendarDays as we}from"lucide-react";import Re from"clsx";var N=t=>{let o=t.getFullYear(),n=`${t.getMonth()+1}`.padStart(2,"0"),a=`${t.getDate()}`.padStart(2,"0");return`${o}-${n}-${a}`},Vt=(t,o)=>N(t)===N(o),Gt=t=>new Set(t.map(o=>N(o.startDate))),Ut=t=>t.reduce((o,n)=>{if(!n.status)return o;let a=N(n.startDate),r=o.get(a)??[];return r.includes(n.status)||o.set(a,[...r,n.status]),o},new Map),ot=t=>({id:t.id,title:t.title,start:t.startAt,end:t.endAt,allDay:t.isAllDay??!1,extendedProps:{status:t.status,location:t.location,description:t.description,durationMinutes:t.durationMinutes}}),h=(t,o="es-CO",n={hour:"2-digit",minute:"2-digit",hour12:!1})=>t.toLocaleTimeString(o,n),Kt=(t,o={})=>{let n=o.min??"min",a=o.h??"h";if(t<60)return`${t} ${n}`;let r=Math.floor(t/60),s=t%60;return s===0?`${r} ${a}`:`${r} ${a} ${s} ${n}`};var D="ape-calendar";import{createContext as qt,useContext as Wt,useEffect as Yt,useState as Xt}from"react";import{jsx as Qt}from"react/jsx-runtime";var ht=qt(null),ft=()=>Wt(ht);function q({children:t}){let[o,n]=Xt(null);return Yt(()=>{if(typeof document>"u")return;let a=document.createElement("div");return a.className=D,a.dataset.apeCalendarPortalRoot="true",document.body.appendChild(a),n(a),()=>{a.parentNode&&a.parentNode.removeChild(a)}},[]),Qt(ht.Provider,{value:o,children:t})}import{Clock as ne,SquarePen as re,Trash2 as se}from"lucide-react";import{Ban as Jt,CalendarClock as Zt,Rocket as jt}from"lucide-react";import te from"clsx";import{jsx as $,jsxs as ae}from"react/jsx-runtime";var ee={draft:$("span",{className:"cal-status-badge__dot","data-status":"draft"}),published:$(jt,{size:11,"aria-hidden":!0}),scheduled:$(Zt,{size:11,"aria-hidden":!0}),archived:$("span",{className:"cal-status-badge__dot","data-status":"archived"}),cancelled:$(Jt,{size:11,"aria-hidden":!0})},oe=t=>t.charAt(0).toUpperCase()+t.slice(1),V=({status:t,labels:o,icons:n,className:a})=>{let r=o?.[t]??oe(t),s=n?.[t]??ee[t];return ae("span",{className:te("cal-status-badge",a),"data-status":t,children:[s,r]})};import{jsx as A,jsxs as W}from"react/jsx-runtime";var ie={edit:t=>`Edit event ${t}`,delete:t=>`Delete event ${t}`},at=({event:t,onEdit:o,onDelete:n,locale:a="es-CO",statusLabels:r,messages:s})=>{let i={...ie,...s},v=t.status??"";return W("article",{className:"cal-event-block","data-status":v,children:[A("div",{className:"cal-event-block__header",children:t.status&&A(V,{status:t.status,labels:r})}),A("p",{className:"cal-event-block__title",children:t.title}),W("p",{className:"cal-event-block__time",children:[A(ne,{size:10,"aria-hidden":!0}),W("span",{children:[h(t.startDate,a)," - ",h(t.endDate,a)]})]}),W("div",{className:"cal-event-block__actions",children:[A("button",{type:"button","aria-label":i.edit(t.title),onClick:p=>{p.stopPropagation(),o(t)},className:"cal-event-block__action-button",children:A(re,{size:11})}),A("button",{type:"button","aria-label":i.delete(t.title),onClick:p=>{p.stopPropagation(),n(t)},className:"cal-event-block__action-button cal-event-block__action-button--danger",children:A(se,{size:11})})]})]})};import{Clock as me,MapPin as ue,SquarePen as ve,Trash2 as Ee}from"lucide-react";import*as g from"@radix-ui/react-popover";import{forwardRef as le}from"react";import pe from"clsx";import{jsx as yt}from"react/jsx-runtime";var w=g.Root,nt=g.Trigger,G=g.Anchor,ce=g.Portal,de=g.Close,T=le(({className:t,align:o="center",sideOffset:n=4,...a},r)=>{let s=ft();return yt(g.Portal,{container:s??void 0,children:yt(g.Content,{ref:r,align:o,sideOffset:n,className:pe("cal-popover-content",t),...a})})});T.displayName="PopoverContent";import{jsx as f,jsxs as b}from"react/jsx-runtime";var ge={weekday:"long",day:"2-digit",month:"long"},he={edit:"Edit",delete:"Delete",editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},rt=({event:t,onEdit:o,onDelete:n,children:a,locale:r="es-CO",statusLabels:s,renderEventMeta:i,messages:v,dayHeaderOptions:p})=>{let u={...he,...v},P=new Intl.DateTimeFormat(r,p??ge).format(t.startDate),k=`${h(t.startDate,r)} \u2013 ${h(t.endDate,r)}`;return b(w,{children:[f(nt,{asChild:!0,children:a}),b(T,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-chip-popover",onClick:c=>c.stopPropagation(),children:[b("header",{className:"cal-chip-popover__header",children:[b("div",{className:"cal-chip-popover__header-info",children:[f("p",{className:"cal-chip-popover__day",children:P}),f("h3",{className:"cal-chip-popover__title",children:t.title})]}),t.status&&f(V,{status:t.status,labels:s})]}),b("dl",{className:"cal-chip-popover__meta",children:[b("div",{className:"cal-chip-popover__meta-row",children:[f(me,{size:12,"aria-hidden":!0}),f("span",{children:k})]}),i&&f("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--wrap",children:i(t)}),t.location&&b("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--start",children:[f(ue,{size:12,"aria-hidden":!0}),f("span",{className:"cal-chip-popover__clamp-2",children:t.location})]})]}),t.description&&f("p",{className:"cal-chip-popover__description",children:t.description}),b("footer",{className:"cal-chip-popover__footer",children:[b("button",{type:"button","aria-label":u.editAria(t.title),onClick:c=>{c.stopPropagation(),o(t)},className:"cal-chip-popover__action",children:[f(ve,{size:12}),u.edit]}),b("button",{type:"button","aria-label":u.deleteAria(t.title),onClick:c=>{c.stopPropagation(),n(t)},className:"cal-chip-popover__action cal-chip-popover__action--danger",children:[f(Ee,{size:12}),u.delete]})]})]})]})};import{jsx as Y,jsxs as fe}from"react/jsx-runtime";var st=({event:t,onEdit:o,onDelete:n,locale:a="es-CO",statusLabels:r,renderEventMeta:s,messages:i,triggerAria:v=p=>`Show event details ${p}`})=>{let p=h(t.startDate,a),u=t.status??"";return Y(rt,{event:t,onEdit:o,onDelete:n,locale:a,statusLabels:r,renderEventMeta:s,messages:i,children:fe("button",{type:"button","aria-label":v(t.title),onClick:C=>C.stopPropagation(),className:"cal-chip-month","data-status":u,children:[Y("span",{className:"cal-chip-month__dot","aria-hidden":!0}),Y("span",{className:"cal-chip-month__time",children:p}),Y("span",{className:"cal-chip-month__title",children:t.title})]})})};import{useMemo as ye}from"react";import{Clock as Ce,SquarePen as Se,Trash2 as Pe}from"lucide-react";import{jsx as y,jsxs as R}from"react/jsx-runtime";var be={weekday:"long",day:"2-digit",month:"long"},De={header:t=>`${t} events in this slot`,editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},xe=({events:t,anchor:o,open:n,onOpenChange:a,onEdit:r,onDelete:s,locale:i="es-CO",messages:v,dayHeaderOptions:p})=>{let u=ye(()=>({current:o}),[o]),C={...De,...v},k=new Intl.DateTimeFormat(i,p??be).format(t[0].startDate);return R(w,{open:n,onOpenChange:a,children:[y(G,{virtualRef:u}),R(T,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-more-popover",onClick:c=>c.stopPropagation(),children:[R("header",{className:"cal-more-popover__header",children:[y("p",{className:"cal-more-popover__day",children:k}),y("h3",{className:"cal-more-popover__title",children:C.header(t.length)})]}),y("ul",{className:"cal-more-popover__list",children:t.map(c=>R("li",{className:"cal-more-popover__item",children:[y("span",{className:"cal-more-popover__dot","data-status":c.status??"","aria-hidden":!0}),R("div",{className:"cal-more-popover__item-body",children:[y("p",{className:"cal-more-popover__item-title",children:c.title}),R("p",{className:"cal-more-popover__item-time",children:[y(Ce,{size:10,"aria-hidden":!0}),h(c.startDate,i)," \u2013"," ",h(c.endDate,i)]})]}),R("div",{className:"cal-more-popover__item-actions",children:[y("button",{type:"button","aria-label":C.editAria(c.title),onClick:_=>{_.stopPropagation(),a(!1),r(c)},className:"cal-more-popover__action",children:y(Se,{size:12})}),y("button",{type:"button","aria-label":C.deleteAria(c.title),onClick:_=>{_.stopPropagation(),a(!1),s(c)},className:"cal-more-popover__action cal-more-popover__action--danger",children:y(Pe,{size:12})})]})]},c.id))})]})]})},it=t=>!t.anchor||t.events.length===0?null:y(xe,{...t,anchor:t.anchor});import{jsx as S,jsxs as Pt}from"react/jsx-runtime";var St={day:"timeGridDay",week:"timeGridWeek",month:"dayGridMonth"},Be=220,Oe={moreLink:t=>`+${t} more`,allDayText:"All day",todayHeaderAria:"Today"},Ie=({events:t,activeView:o,selectedDate:n,highlightEventIds:a=[],onDeleteEvent:r,onEditEvent:s,onEventTimeChange:i,onDateClick:v,onDateSelected:p,onVisibleRangeChange:u,onSwitchToDay:C,locale:P="es-CO",fullCalendarLocale:k=ke,firstDay:c=1,statusLabels:_,renderEventMeta:J,renderDayHeader:U,messages:d,immutableStatuses:L,eventAllow:B,height:Z="100%",highlightDurationMs:K=650,className:Mt})=>{let vt=lt(null),j=lt(null),Et=lt(!0),[tt,et]=_e(null),gt=Le(),z=O(()=>({...Oe,...d}),[d]),Nt=e=>typeof z.moreLink=="function"?z.moreLink(e):z.moreLink.replace("{count}",String(e)),At=O(()=>new Set(a),[a]),H=O(()=>new Map(t.map(e=>[e.id,e])),[t]),Tt=O(()=>t.map(ot),[t]),kt=O(()=>new Intl.DateTimeFormat(P,{weekday:"short"}),[P]),Lt=O(()=>new Set(L??["archived"]),[L]);Ct(()=>{et(null);let e=vt.current?.getApi();if(!e)return;let l=!1;return queueMicrotask(()=>{if(l)return;let m=St[o];e.view.type!==m&&e.changeView(m),e.getDate().toDateString()!==n.toDateString()&&e.gotoDate(n)}),()=>{l=!0}},[o,n]),Ct(()=>{if(Et.current){Et.current=!1;return}gt||!j.current||j.current.animate([{opacity:.88,transform:"translateY(5px)"},{opacity:1,transform:"translateY(0)"}],{duration:Be,easing:"cubic-bezier(0.22, 1, 0.36, 1)",fill:"both"})},[o,gt]);let wt=e=>u(e.start,e.end),Rt=e=>{p(e.date),v(e.date,{x:e.jsEvent.clientX,y:e.jsEvent.clientY})},Bt=e=>{let l=e.jsEvent?{x:e.jsEvent.clientX,y:e.jsEvent.clientY}:{x:window.innerWidth/2,y:window.innerHeight/2};p(e.start),v(e.start,l)},Ot=e=>{let l=H.get(e.event.id);return l?e.view.type==="dayGridMonth"||e.event.allDay?S(st,{event:l,onEdit:s,onDelete:r,locale:P,statusLabels:_,renderEventMeta:J}):S(at,{event:l,onEdit:s,onDelete:r,locale:P,statusLabels:_}):S("p",{className:"cal-event-fallback",children:e.event.title})},It=e=>{At.has(e.event.id)&&(e.el.style.setProperty("--cal-highlight-duration",`${K}ms`),e.el.classList.add("cal-event-highlight-enter"),window.setTimeout(()=>e.el.classList.remove("cal-event-highlight-enter"),K))},Ft=(e,l,m)=>{if(m)return m.toISOString();let E=new Date(l),M=e.durationMinutes??60;return E.setMinutes(E.getMinutes()+M),E.toISOString()},zt=e=>{let l=H.get(e.event.id),m=e.event.start;if(!l||!m){e.revert();return}i({event:l,startAt:m.toISOString(),endAt:Ft(l,m,e.event.end),revert:e.revert})},Ht=e=>{let l=H.get(e.event.id),m=e.event.start,E=e.event.end;if(!l||!m||!E){e.revert();return}if(E<=m){e.revert();return}i({event:l,startAt:m.toISOString(),endAt:E.toISOString(),revert:e.revert})},$t=({date:e,isToday:l})=>{if(U)return U(e,{isToday:l});let m=kt.format(e).replace(".","");return Pt("div",{className:"cal-day-header",children:[S("span",{className:"cal-day-header__number","data-today":l,"aria-label":l?z.todayHeaderAria:void 0,children:e.getDate()}),S("span",{className:"cal-day-header__weekday",children:m})]})};return S(q,{children:S("div",{className:Re(D,"cal-macro-root",Mt),children:Pt("div",{ref:j,className:"cal-macro-surface",children:[S(we,{className:"cal-macro-corner-icon",size:20,"aria-hidden":!0}),S(Me,{ref:vt,plugins:[Ne,Ae,Te],locale:k,initialView:St[o],height:Z,expandRows:!0,firstDay:c,allDaySlot:!1,allDayText:z.allDayText,selectable:!0,selectMirror:!0,editable:!0,eventStartEditable:!0,eventDurationEditable:!0,eventResizableFromStart:!0,dayMaxEvents:!0,eventMaxStack:3,moreLinkContent:e=>S("span",{className:"cal-more-link",children:Nt(e.num)}),moreLinkClick:e=>{if(e.view.type==="dayGridMonth")return C(e.date),"none";let l=e.allSegs.map(M=>H.get(M.event.id)).filter(M=>!!M),m=e.jsEvent.target,E=m instanceof Element?m.closest(".fc-more-link"):null;return E&&l.length>0&&et({events:l,anchor:E}),"none"},nowIndicator:!0,slotDuration:"01:00:00",slotLabelInterval:"01:00:00",slotLabelFormat:{hour:"2-digit",minute:"2-digit",hour12:!1},slotMinTime:"00:00:00",slotMaxTime:"24:00:00",slotEventOverlap:!1,eventMinHeight:28,eventShortHeight:48,headerToolbar:!1,events:Tt,eventDrop:zt,eventResize:Ht,eventDidMount:It,dragScroll:!0,eventDragMinDistance:8,dragRevertDuration:420,longPressDelay:380,selectLongPressDelay:380,eventAllow:(e,l)=>{if(!l)return!1;let m=l.extendedProps.status,E=typeof m=="string"?!Lt.has(m):!0;if(!E||!B)return E;let M=H.get(l.id);return M?B(M,e.startStr,e.endStr):!0},datesSet:wt,dateClick:Rt,select:Bt,dayHeaderContent:$t,eventContent:Ot}),S(it,{events:tt?.events??[],anchor:tt?.anchor??null,open:!!tt,onOpenChange:e=>{e||et(null)},onEdit:s,onDelete:r,locale:P})]})})})};import{useMemo as ze}from"react";import{DayPicker as He}from"react-day-picker";import{es as $e}from"react-day-picker/locale";import{ChevronLeft as Ve,ChevronRight as Ge}from"lucide-react";import Ue from"clsx";import bt from"clsx";import{jsx as pt,jsxs as Fe}from"react/jsx-runtime";var ct=({statuses:t,isSelected:o=!1,statusColors:n,className:a,maxDots:r=2})=>t.length===0&&!o?pt("span",{className:bt("cal-day-dot-empty",a),"aria-hidden":!0}):Fe("span",{className:bt("cal-day-dot-row",a),"aria-hidden":!0,children:[o&&pt("span",{className:"cal-day-dot cal-day-dot--selected"}),t.slice(0,r).map(s=>{let i=n?.[s];return pt("span",{className:"cal-day-dot","data-status":s,style:i?{backgroundColor:i}:void 0},s)})]});import{jsx as x,jsxs as dt}from"react/jsx-runtime";var Ke={previousMonth:"Previous month",nextMonth:"Next month"},qe=({selectedDate:t,visibleMonth:o,eventDayStatuses:n,onSelectDate:a,onMonthChange:r,locale:s="es-CO",pickerLocale:i=$e,messages:v,statusColors:p,className:u})=>{let C={...Ke,...v},{monthNameFormat:P,yearFormat:k,weekdayFormat:c}=ze(()=>({monthNameFormat:new Intl.DateTimeFormat(s,{month:"long"}),yearFormat:new Intl.DateTimeFormat(s,{year:"numeric"}),weekdayFormat:new Intl.DateTimeFormat(s,{weekday:"short"})}),[s]),_=d=>{let L=P.format(d);return`${L.charAt(0).toUpperCase()+L.slice(1)} ${k.format(d)}`},J=()=>{let d=new Date(o);d.setMonth(d.getMonth()-1),r(d)},U=()=>{let d=new Date(o);d.setMonth(d.getMonth()+1),r(d)};return x(q,{children:dt("div",{className:Ue(D,"cal-mini-root",u),children:[dt("div",{className:"cal-mini-header",children:[x("button",{type:"button","aria-label":C.previousMonth,onClick:J,className:"cal-mini-nav-button",children:x(Ve,{size:14,"aria-hidden":!0})}),x("h2",{className:"cal-mini-caption",children:_(o)}),x("button",{type:"button","aria-label":C.nextMonth,onClick:U,className:"cal-mini-nav-button",children:x(Ge,{size:14,"aria-hidden":!0})})]}),x(He,{mode:"single",locale:i,selected:t,month:o,onMonthChange:r,formatters:{formatWeekdayName:d=>c.format(d).charAt(0).toUpperCase()},onSelect:d=>{d&&a(d)},hideNavigation:!0,captionLayout:"label",className:"cal-mini-grid",classNames:{months:"cal-mini-months",month:"cal-mini-month",month_caption:"cal-mini-month-caption",caption_label:"cal-mini-caption-label",month_grid:"cal-mini-month-grid",weekdays:"cal-mini-weekdays",weekday:"cal-mini-weekday",week:"cal-mini-week",day:"cal-mini-day",day_button:"cal-mini-day-button",outside:"cal-mini-day--outside",today:"cal-mini-day--today"},components:{DayButton:({day:d,...L})=>{let B=N(d.date),Z=n.get(B)??[],K=N(t)===B;return dt("button",{...L,children:[x("span",{children:d.date.getDate()}),x(ct,{statuses:Z,isSelected:K,statusColors:p})]})}}})]})})};import{LayoutGroup as Qe,motion as Je}from"motion/react";import{CalendarDays as Dt}from"lucide-react";import Ze from"clsx";import{forwardRef as We}from"react";import Ye from"clsx";import{jsx as mt,jsxs as Xe}from"react/jsx-runtime";var I=We(({variant:t="primary",size:o="md",rounded:n="md",leftIcon:a,rightIcon:r,className:s,children:i,type:v="button",...p},u)=>Xe("button",{ref:u,type:v,"data-variant":t,"data-size":o,"data-rounded":n,className:Ye("cal-button",s),...p,children:[a&&mt("span",{className:"cal-button__icon",children:a}),i&&mt("span",{className:"cal-button__label",children:i}),r&&mt("span",{className:"cal-button__icon",children:r})]}));I.displayName="Button";import{jsx as F,jsxs as ut}from"react/jsx-runtime";var je={day:"Day",week:"Week",month:"Month"},xt={groupAriaLabel:"Calendar view",newEvent:"New event"},to=["day","week","month"],eo=({activeView:t,onChangeView:o,onNewEvent:n,messages:a,className:r})=>{let s={...je,...a?.views},i=a?.groupAriaLabel??xt.groupAriaLabel,v=a?.newEvent??xt.newEvent;return ut("div",{className:Ze(D,"cal-toolbar",r),children:[F(Qe,{id:"cal-toolbar-view-tabs",children:F("div",{className:"cal-toolbar__tabs",role:"group","aria-label":i,children:to.map(p=>{let u=t===p;return ut("button",{type:"button",onClick:()=>o(p),className:"cal-toolbar__tab","data-active":u,children:[u&&F(Je.span,{layoutId:"cal-toolbar-indicator",className:"cal-toolbar__indicator",transition:{type:"spring",stiffness:380,damping:34}}),ut("span",{className:"cal-toolbar__tab-label",children:[F(Dt,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),s[p]]})]},p)})})}),n&&F(I,{variant:"primary",size:"md",rounded:"full",onClick:n,leftIcon:F(Dt,{size:18,"aria-hidden":!0}),children:v})]})};import{jsx as X,jsxs as _t}from"react/jsx-runtime";var oo={heading:"Event actions"},ao=({state:t,actions:o,onClose:n,onSelectAction:a,messages:r})=>{if(!t.point||!t.date)return null;let s={...oo,...r};return _t(w,{open:t.isOpen,onOpenChange:i=>!i&&n(),children:[X(G,{asChild:!0,children:X("span",{className:"cal-slot-anchor",style:{left:t.point.x,top:t.point.y},"aria-hidden":!0})}),_t(T,{align:"start",sideOffset:8,className:"cal-slot-popover",onEscapeKeyDown:n,children:[X("p",{className:"cal-slot-popover__heading",children:s.heading}),o.map(i=>X(I,{type:"button",variant:"ghost",size:"sm",leftIcon:i.icon,className:"cal-slot-popover__action",onClick:()=>a({type:i.type,date:t.date}),children:i.label},i.type))]})]})};import no from"clsx";import{jsx as so,jsxs as io}from"react/jsx-runtime";var ro=({label:t,icon:o,className:n})=>io("span",{className:no("cal-type-chip",n),children:[o&&so("span",{className:"cal-type-chip__icon",children:o}),t]});import{CalendarDays as lo}from"lucide-react";import po from"clsx";import{jsx as Q,jsxs as mo}from"react/jsx-runtime";var co=({title:t="No events to display",description:o="Adjust filters or create a new event to populate the calendar.",icon:n,className:a})=>mo("div",{className:po("cal-empty-state",a),children:[Q("span",{className:"cal-empty-state__icon","aria-hidden":!0,children:n??Q(lo,{size:20})}),Q("p",{className:"cal-empty-state__title",children:t}),Q("p",{className:"cal-empty-state__description",children:o})]});export{D as APE_CALENDAR_ROOT_CLASS,I as Button,eo as CalendarToolbar,ct as DayEventDot,co as EmptyEventsState,at as EventBlockContent,st as EventChipMonth,rt as EventChipPopover,V as EventStatusBadge,ro as EventTypeChip,Ie as MacroCalendar,qe as MiniMonthCalendar,it as MoreEventsPopover,w as Popover,G as PopoverAnchor,de as PopoverClose,T as PopoverContent,ce as PopoverPortal,nt as PopoverTrigger,ao as SlotContextActions,Kt as formatDurationLabel,h as formatHourLabel,Gt as getEventDayKeys,Ut as getEventDayStatuses,Vt as isSameDay,ot as mapEventToCalendarInput,N as toDayKey};
|
|
1
|
+
import{useEffect as we,useMemo as Y,useRef as Te,useState as la}from"react";import ca from"@fullcalendar/react";import da from"@fullcalendar/daygrid";import pa from"@fullcalendar/timegrid";import ma from"@fullcalendar/interaction";import ua from"@fullcalendar/core/locales/es";import{useReducedMotion as va}from"motion/react";import{CalendarDays as ga}from"lucide-react";import ya from"clsx";var k=e=>{let t=e.getFullYear(),a=`${e.getMonth()+1}`.padStart(2,"0"),o=`${e.getDate()}`.padStart(2,"0");return`${t}-${a}-${o}`},le=(e,t)=>k(e)===k(t),vt=e=>new Set(e.map(t=>k(t.startDate))),gt=e=>e.reduce((t,a)=>{if(!a.status)return t;let o=k(a.startDate),s=t.get(o)??[];return s.includes(a.status)||t.set(o,[...s,a.status]),t},new Map),he=e=>({id:e.id,title:e.title,start:e.startAt,end:e.endAt,allDay:e.isAllDay??!1,extendedProps:{status:e.status,location:e.location,description:e.description,durationMinutes:e.durationMinutes}}),_=(e,t="es-CO",a={hour:"2-digit",minute:"2-digit",hour12:!1})=>e.toLocaleTimeString(t,a),yt=(e,t={})=>{let a=t.min??"min",o=t.h??"h";if(e<60)return`${e} ${a}`;let s=Math.floor(e/60),r=e%60;return r===0?`${s} ${o}`:`${s} ${o} ${r} ${a}`},Et=e=>e.map(t=>({daysOfWeek:t.daysOfWeek,startTime:t.startTime,endTime:t.endTime})),Ce=e=>e.map((t,a)=>({id:`cal-availability-${a}`,daysOfWeek:t.daysOfWeek,startTime:t.startTime,endTime:t.endTime,display:"background",classNames:["cal-availability-band"],editable:!1})),U=(e,t=1)=>{let a=new Date(e);a.setHours(0,0,0,0);let o=(a.getDay()-t+7)%7;a.setDate(a.getDate()-o);let s=new Date(a);return s.setDate(s.getDate()+7),{start:a,end:s}},Se=(e,t,a)=>{if(a==="today")return new Date;let o=new Date(e),s=a==="next"?1:-1;switch(t){case"month":o.setMonth(o.getMonth()+s);break;case"week":case"list":o.setDate(o.getDate()+s*7);break;case"day":o.setDate(o.getDate()+s);break}return o};var A="ape-calendar";import{createContext as ft,useContext as ht,useEffect as Ct,useState as St}from"react";import{jsx as bt}from"react/jsx-runtime";var Ge=ft(null),We=()=>ht(Ge);function ce({children:e}){let[t,a]=St(null);return Ct(()=>{if(typeof document>"u")return;let o=document.createElement("div");return o.className=A,o.dataset.apeCalendarPortalRoot="true",document.body.appendChild(o),a(o),()=>{o.parentNode&&o.parentNode.removeChild(o)}},[]),bt(Ge.Provider,{value:t,children:e})}import{useMemo as te}from"react";import Ke from"clsx";import{CalendarDays as Dt}from"lucide-react";import _t from"clsx";import{jsx as de,jsxs as Pt}from"react/jsx-runtime";var be=({title:e="No events to display",description:t="Adjust filters or create a new event to populate the calendar.",icon:a,className:o})=>Pt("div",{className:_t("cal-empty-state",o),children:[de("span",{className:"cal-empty-state__icon","aria-hidden":!0,children:a??de(Dt,{size:20})}),de("p",{className:"cal-empty-state__title",children:e}),de("p",{className:"cal-empty-state__description",children:t})]});import{Clock as Rt,SquarePen as Bt,Trash2 as Ft}from"lucide-react";import{Ban as xt,CalendarClock as Nt,CircleCheck as At,Rocket as Mt}from"lucide-react";import wt from"clsx";import{jsx as J,jsxs as Lt}from"react/jsx-runtime";var Tt={draft:J("span",{className:"cal-status-badge__dot","data-status":"draft"}),published:J(Mt,{size:11,"aria-hidden":!0}),scheduled:J(Nt,{size:11,"aria-hidden":!0}),archived:J("span",{className:"cal-status-badge__dot","data-status":"archived"}),cancelled:J(xt,{size:11,"aria-hidden":!0}),finalizado:J(At,{size:11,"aria-hidden":!0})},kt=e=>e.charAt(0).toUpperCase()+e.slice(1),K=({status:e,labels:t,icons:a,className:o})=>{let s=t?.[e]??kt(e),r=a?.[e]??Tt[e];return Lt("span",{className:wt("cal-status-badge",o),"data-status":e,children:[r,s]})};import{jsx as G,jsxs as Z}from"react/jsx-runtime";var Ot={edit:e=>`Edit event ${e}`,delete:e=>`Delete event ${e}`},De=({event:e,onEdit:t,onDelete:a,locale:o="es-CO",statusLabels:s,renderEventMeta:r,messages:i})=>{let d={...Ot,...i},l=e.status??"";return Z("div",{className:"cal-list-row","data-status":l,children:[Z("span",{className:"cal-list-row__time-chip","aria-label":"event time",children:[G(Rt,{size:12,"aria-hidden":!0}),Z("span",{children:[_(e.startDate,o)," - ",_(e.endDate,o)]})]}),Z("div",{className:"cal-list-row__body",children:[G("p",{className:"cal-list-row__title",children:e.title}),r&&G("div",{className:"cal-list-row__meta",children:r(e)})]}),Z("div",{className:"cal-list-row__aside",children:[e.status&&G(K,{status:e.status,labels:s}),Z("div",{className:"cal-list-row__actions",children:[G("button",{type:"button","aria-label":d.edit(e.title),onClick:p=>{p.stopPropagation(),t(e)},className:"cal-list-row__action-button",children:G(Bt,{size:13})}),G("button",{type:"button","aria-label":d.delete(e.title),onClick:p=>{p.stopPropagation(),a(e)},className:"cal-list-row__action-button cal-list-row__action-button--danger",children:G(Ft,{size:13})})]})]})]})};import{jsx as L,jsxs as _e}from"react/jsx-runtime";var It={noEvents:"No events to display",noEventsForDay:"No events"},zt=e=>{let t=[],a=new Date(e.start);a.setHours(0,0,0,0);let o=new Date(e.end);for(o.setHours(0,0,0,0);a<o;)t.push(new Date(a)),a.setDate(a.getDate()+1);return t},Pe=({events:e,range:t,locale:a="es-CO",statusLabels:o,renderEventMeta:s,renderDayHeader:r,onEditEvent:i,onDeleteEvent:d,messages:l,className:p})=>{let E=te(()=>zt(t),[t]),c=te(()=>{let y=new Map;for(let v of e){let h=k(v.startDate),x=y.get(h)??[];x.push(v),y.set(h,x)}for(let v of y.values())v.sort((h,x)=>h.startDate.getTime()-x.startDate.getTime());return y},[e]),C=te(()=>new Intl.DateTimeFormat(a,{day:"2-digit"}),[a]),m=te(()=>new Intl.DateTimeFormat(a,{month:"short"}),[a]),b=te(()=>new Intl.DateTimeFormat(a,{weekday:"short"}),[a]),D={...It,...l};return e.length===0&&!r?L("div",{className:Ke(A,"cal-agenda",p),children:L(be,{title:D.noEvents})}):L("div",{className:Ke(A,"cal-agenda",p),children:E.map(y=>{let v=k(y),h=c.get(v)??[],x=h.length>0,H=r?.(y,{hasEvents:x,events:h});return!x&&!H?null:_e("section",{className:"cal-agenda-day",children:[_e("aside",{className:"cal-agenda-day__anchor",children:[L("span",{className:"cal-agenda-day__month",children:m.format(y).replace(".","")}),L("span",{className:"cal-agenda-day__number",children:C.format(y)}),L("span",{className:"cal-agenda-day__weekday",children:b.format(y).replace(".","")})]}),_e("div",{className:"cal-agenda-day__body",children:[H&&L("div",{className:"cal-agenda-day__header",children:H}),x?L("ul",{className:"cal-agenda-day__events",children:h.map(g=>L("li",{className:"cal-agenda-day__event-item",children:L(De,{event:g,onEdit:i,onDelete:d,locale:a,statusLabels:o,renderEventMeta:s,messages:l})},g.id))}):L("p",{className:"cal-agenda-day__empty",children:D.noEventsForDay})]})]},v)})})};import{Clock as Vt,SquarePen as Ht,Trash2 as $t}from"lucide-react";import{jsx as W,jsxs as pe}from"react/jsx-runtime";var Ut={edit:e=>`Edit event ${e}`,delete:e=>`Delete event ${e}`},xe=({event:e,onEdit:t,onDelete:a,locale:o="es-CO",statusLabels:s,messages:r})=>{let i={...Ut,...r},d=e.status??"";return pe("article",{className:"cal-event-block","data-status":d,children:[W("div",{className:"cal-event-block__header",children:e.status&&W(K,{status:e.status,labels:s})}),W("p",{className:"cal-event-block__title",children:e.title}),pe("p",{className:"cal-event-block__time",children:[W(Vt,{size:10,"aria-hidden":!0}),pe("span",{children:[_(e.startDate,o)," - ",_(e.endDate,o)]})]}),pe("div",{className:"cal-event-block__actions",children:[W("button",{type:"button","aria-label":i.edit(e.title),onClick:l=>{l.stopPropagation(),t(e)},className:"cal-event-block__action-button",children:W(Ht,{size:11})}),W("button",{type:"button","aria-label":i.delete(e.title),onClick:l=>{l.stopPropagation(),a(e)},className:"cal-event-block__action-button cal-event-block__action-button--danger",children:W($t,{size:11})})]})]})};import{Clock as Yt,MapPin as Xt,SquarePen as Qt,Trash2 as Jt}from"lucide-react";import*as N from"@radix-ui/react-popover";import{forwardRef as Gt}from"react";import Wt from"clsx";import{jsx as qe}from"react/jsx-runtime";var z=N.Root,ae=N.Trigger,oe=N.Anchor,Kt=N.Portal,qt=N.Close,R=Gt(({className:e,align:t="center",sideOffset:a=4,...o},s)=>{let r=We();return qe(N.Portal,{container:r??void 0,children:qe(N.Content,{ref:s,align:t,sideOffset:a,className:Wt("cal-popover-content",e),...o})})});R.displayName="PopoverContent";import{jsx as M,jsxs as B}from"react/jsx-runtime";var Zt={weekday:"long",day:"2-digit",month:"long"},jt={edit:"Edit",delete:"Delete",editAria:e=>`Edit event ${e}`,deleteAria:e=>`Delete event ${e}`},Ne=({event:e,onEdit:t,onDelete:a,children:o,locale:s="es-CO",statusLabels:r,renderEventMeta:i,messages:d,dayHeaderOptions:l})=>{let p={...jt,...d},c=new Intl.DateTimeFormat(s,l??Zt).format(e.startDate),C=`${_(e.startDate,s)} \u2013 ${_(e.endDate,s)}`;return B(z,{children:[M(ae,{asChild:!0,children:o}),B(R,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-chip-popover",onClick:m=>m.stopPropagation(),children:[B("header",{className:"cal-chip-popover__header",children:[B("div",{className:"cal-chip-popover__header-info",children:[M("p",{className:"cal-chip-popover__day",children:c}),M("h3",{className:"cal-chip-popover__title",children:e.title})]}),e.status&&M(K,{status:e.status,labels:r})]}),B("dl",{className:"cal-chip-popover__meta",children:[B("div",{className:"cal-chip-popover__meta-row",children:[M(Yt,{size:12,"aria-hidden":!0}),M("span",{children:C})]}),i&&M("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--wrap",children:i(e)}),e.location&&B("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--start",children:[M(Xt,{size:12,"aria-hidden":!0}),M("span",{className:"cal-chip-popover__clamp-2",children:e.location})]})]}),e.description&&M("p",{className:"cal-chip-popover__description",children:e.description}),B("footer",{className:"cal-chip-popover__footer",children:[B("button",{type:"button","aria-label":p.editAria(e.title),onClick:m=>{m.stopPropagation(),t(e)},className:"cal-chip-popover__action",children:[M(Qt,{size:12}),p.edit]}),B("button",{type:"button","aria-label":p.deleteAria(e.title),onClick:m=>{m.stopPropagation(),a(e)},className:"cal-chip-popover__action cal-chip-popover__action--danger",children:[M(Jt,{size:12}),p.delete]})]})]})]})};import{jsx as me,jsxs as ea}from"react/jsx-runtime";var Ae=({event:e,onEdit:t,onDelete:a,locale:o="es-CO",statusLabels:s,renderEventMeta:r,messages:i,triggerAria:d=l=>`Show event details ${l}`})=>{let l=_(e.startDate,o),p=e.status??"";return me(Ne,{event:e,onEdit:t,onDelete:a,locale:o,statusLabels:s,renderEventMeta:r,messages:i,children:ea("button",{type:"button","aria-label":d(e.title),onClick:E=>E.stopPropagation(),className:"cal-chip-month","data-status":p,children:[me("span",{className:"cal-chip-month__dot","aria-hidden":!0}),me("span",{className:"cal-chip-month__time",children:l}),me("span",{className:"cal-chip-month__title",children:e.title})]})})};import{useMemo as ta}from"react";import{Clock as aa,SquarePen as oa,Trash2 as na}from"lucide-react";import{jsx as w,jsxs as q}from"react/jsx-runtime";var sa={weekday:"long",day:"2-digit",month:"long"},ra={header:e=>`${e} events in this slot`,editAria:e=>`Edit event ${e}`,deleteAria:e=>`Delete event ${e}`},ia=({events:e,anchor:t,open:a,onOpenChange:o,onEdit:s,onDelete:r,locale:i="es-CO",messages:d,dayHeaderOptions:l})=>{let p=ta(()=>({current:t}),[t]),E={...ra,...d},C=new Intl.DateTimeFormat(i,l??sa).format(e[0].startDate);return q(z,{open:a,onOpenChange:o,children:[w(oe,{virtualRef:p}),q(R,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-more-popover",onClick:m=>m.stopPropagation(),children:[q("header",{className:"cal-more-popover__header",children:[w("p",{className:"cal-more-popover__day",children:C}),w("h3",{className:"cal-more-popover__title",children:E.header(e.length)})]}),w("ul",{className:"cal-more-popover__list",children:e.map(m=>q("li",{className:"cal-more-popover__item",children:[w("span",{className:"cal-more-popover__dot","data-status":m.status??"","aria-hidden":!0}),q("div",{className:"cal-more-popover__item-body",children:[w("p",{className:"cal-more-popover__item-title",children:m.title}),q("p",{className:"cal-more-popover__item-time",children:[w(aa,{size:10,"aria-hidden":!0}),_(m.startDate,i)," \u2013"," ",_(m.endDate,i)]})]}),q("div",{className:"cal-more-popover__item-actions",children:[w("button",{type:"button","aria-label":E.editAria(m.title),onClick:b=>{b.stopPropagation(),o(!1),s(m)},className:"cal-more-popover__action",children:w(oa,{size:12})}),w("button",{type:"button","aria-label":E.deleteAria(m.title),onClick:b=>{b.stopPropagation(),o(!1),r(m)},className:"cal-more-popover__action cal-more-popover__action--danger",children:w(na,{size:12})})]})]},m.id))})]})]})},Me=e=>!e.anchor||e.events.length===0?null:w(ia,{...e,anchor:e.anchor});import{jsx as T,jsxs as Xe}from"react/jsx-runtime";var Ye={day:"timeGridDay",week:"timeGridWeek",month:"dayGridMonth"},Ea=220,fa={moreLink:e=>`+${e} more`,allDayText:"All day",todayHeaderAria:"Today",noEvents:"No events to display"},ha=({events:e,activeView:t,selectedDate:a,highlightEventIds:o=[],onDeleteEvent:s,onEditEvent:r,onEventTimeChange:i,onDateClick:d,onDateSelected:l,onVisibleRangeChange:p,onSwitchToDay:E,locale:c="es-CO",fullCalendarLocale:C=ua,firstDay:m=1,availability:b,statusLabels:D,renderEventMeta:y,renderDayHeader:v,renderAgendaDayHeader:h,messages:x,immutableStatuses:j,eventAllow:H,height:g="100%",highlightDurationMs:O=650,slotDuration:I="00:30:00",snapDuration:ve="00:15:00",className:ge})=>{let He=Te(null),ye=Te(null),$e=Te(!0),[Ee,fe]=la(null),Ue=va(),Q=Y(()=>({...fa,...x}),[x]),et=n=>typeof Q.moreLink=="function"?Q.moreLink(n):Q.moreLink.replace("{count}",String(n)),tt=Y(()=>new Set(o),[o]),ee=Y(()=>new Map(e.map(n=>[n.id,n])),[e]),at=Y(()=>{let n=e.map(he);return b&&(t==="week"||t==="day")?[...n,...Ce(b)]:n},[e,b,t]),ot=Y(()=>new Intl.DateTimeFormat(c,{weekday:"short"}),[c]),nt=Y(()=>new Set(j??["archived"]),[j]);we(()=>{if(fe(null),t==="list")return;let n=He.current?.getApi();if(!n)return;let u=!1;return queueMicrotask(()=>{if(u)return;let f=Ye[t];n.view.type!==f&&n.changeView(f),n.getDate().toDateString()!==a.toDateString()&&n.gotoDate(a)}),()=>{u=!0}},[t,a]);let ie=Y(()=>U(a,m),[a,m]);we(()=>{t==="list"&&p(ie.start,ie.end)},[t,ie]),we(()=>{if($e.current){$e.current=!1;return}Ue||!ye.current||ye.current.animate([{opacity:.88,transform:"translateY(5px)"},{opacity:1,transform:"translateY(0)"}],{duration:Ea,easing:"cubic-bezier(0.22, 1, 0.36, 1)",fill:"both"})},[t,Ue]);let st=n=>p(n.start,n.end),rt=n=>{l(n.date),d(n.date,{x:n.jsEvent.clientX,y:n.jsEvent.clientY})},it=n=>{let u=n.jsEvent?{x:n.jsEvent.clientX,y:n.jsEvent.clientY}:{x:window.innerWidth/2,y:window.innerHeight/2};l(n.start),d(n.start,u)},lt=n=>{let u=ee.get(n.event.id);return u?n.view.type==="dayGridMonth"||n.event.allDay?T(Ae,{event:u,onEdit:r,onDelete:s,locale:c,statusLabels:D,renderEventMeta:y}):T(xe,{event:u,onEdit:r,onDelete:s,locale:c,statusLabels:D}):T("p",{className:"cal-event-fallback",children:n.event.title})},ct=n=>{tt.has(n.event.id)&&(n.el.style.setProperty("--cal-highlight-duration",`${O}ms`),n.el.classList.add("cal-event-highlight-enter"),window.setTimeout(()=>n.el.classList.remove("cal-event-highlight-enter"),O))},dt=(n,u,f)=>{if(f)return f.toISOString();let P=new Date(u),$=n.durationMinutes??60;return P.setMinutes(P.getMinutes()+$),P.toISOString()},pt=n=>{let u=ee.get(n.event.id),f=n.event.start;if(!u||!f){n.revert();return}i({event:u,startAt:f.toISOString(),endAt:dt(u,f,n.event.end),revert:n.revert})},mt=n=>{let u=ee.get(n.event.id),f=n.event.start,P=n.event.end;if(!u||!f||!P){n.revert();return}if(P<=f){n.revert();return}i({event:u,startAt:f.toISOString(),endAt:P.toISOString(),revert:n.revert})},ut=({date:n,isToday:u})=>{if(v)return v(n,{isToday:u});let f=ot.format(n).replace(".","");return Xe("div",{className:"cal-day-header",children:[T("span",{className:"cal-day-header__number","data-today":u,"aria-label":u?Q.todayHeaderAria:void 0,children:n.getDate()}),T("span",{className:"cal-day-header__weekday",children:f})]})};return T(ce,{children:T("div",{className:ya(A,"cal-macro-root",ge),children:Xe("div",{ref:ye,className:"cal-macro-surface",children:[T(ga,{className:"cal-macro-corner-icon",size:20,"aria-hidden":!0}),t==="list"?T(Pe,{events:e,range:ie,locale:c,statusLabels:D,renderEventMeta:y,renderDayHeader:h,onEditEvent:r,onDeleteEvent:s,messages:{noEvents:Q.noEvents}}):T(ca,{ref:He,plugins:[da,pa,ma],locale:C,initialView:Ye[t],height:g,expandRows:!0,firstDay:m,allDaySlot:!1,allDayText:Q.allDayText,selectable:!0,selectMirror:!0,editable:!0,eventStartEditable:!0,eventDurationEditable:!0,eventResizableFromStart:!0,dayMaxEvents:!0,eventMaxStack:3,moreLinkContent:n=>T("span",{className:"cal-more-link",children:et(n.num)}),moreLinkClick:n=>{if(n.view.type==="dayGridMonth")return E(n.date),"none";let u=n.allSegs.map($=>ee.get($.event.id)).filter($=>!!$),f=n.jsEvent.target,P=f instanceof Element?f.closest(".fc-more-link"):null;return P&&u.length>0&&fe({events:u,anchor:P}),"none"},nowIndicator:!0,slotDuration:I,snapDuration:ve,slotLabelInterval:"01:00:00",slotLabelFormat:{hour:"2-digit",minute:"2-digit",hour12:!1},slotMinTime:"00:00:00",slotMaxTime:"24:00:00",slotEventOverlap:!1,eventMinHeight:28,eventShortHeight:48,headerToolbar:!1,events:at,eventDrop:pt,eventResize:mt,eventDidMount:ct,dragScroll:!0,eventDragMinDistance:8,dragRevertDuration:420,longPressDelay:380,selectLongPressDelay:380,eventAllow:(n,u)=>{if(!u)return!1;let f=u.extendedProps.status,P=typeof f=="string"?!nt.has(f):!0;if(!P||!H)return P;let $=ee.get(u.id);return $?H($,n.startStr,n.endStr):!0},datesSet:st,dateClick:rt,select:it,dayHeaderContent:ut,eventContent:lt}),T(Me,{events:Ee?.events??[],anchor:Ee?.anchor??null,open:!!Ee,onOpenChange:n=>{n||fe(null)},onEdit:r,onDelete:s,locale:c})]})})})};import{useMemo as Je}from"react";import{DayPicker as Sa}from"react-day-picker";import{es as ba}from"react-day-picker/locale";import{ChevronLeft as Da,ChevronRight as _a}from"lucide-react";import Pa from"clsx";import Qe from"clsx";import{jsx as ke,jsxs as Ca}from"react/jsx-runtime";var Le=({statuses:e,isSelected:t=!1,statusColors:a,className:o,maxDots:s=2})=>e.length===0&&!t?ke("span",{className:Qe("cal-day-dot-empty",o),"aria-hidden":!0}):Ca("span",{className:Qe("cal-day-dot-row",o),"aria-hidden":!0,children:[t&&ke("span",{className:"cal-day-dot cal-day-dot--selected"}),e.slice(0,s).map(r=>{let i=a?.[r];return ke("span",{className:"cal-day-dot","data-status":r,style:i?{backgroundColor:i}:void 0},r)})]});import{jsx as V,jsxs as Re}from"react/jsx-runtime";var xa={previousMonth:"Previous month",nextMonth:"Next month"},Na=({selectedDate:e,visibleMonth:t,eventDayStatuses:a,onSelectDate:o,onMonthChange:s,locale:r="es-CO",pickerLocale:i=ba,messages:d,statusColors:l,variant:p="card",highlightWeekOf:E,firstDay:c=1,showOutsideDays:C=!1,className:m})=>{let b={...xa,...d},D=Je(()=>{if(!E)return;let{start:g,end:O}=U(E,c),I=new Date(O);return I.setDate(I.getDate()-1),{start:g,last:I}},[E,c]),{monthNameFormat:y,yearFormat:v,weekdayFormat:h}=Je(()=>({monthNameFormat:new Intl.DateTimeFormat(r,{month:"long"}),yearFormat:new Intl.DateTimeFormat(r,{year:"numeric"}),weekdayFormat:new Intl.DateTimeFormat(r,{weekday:"short"})}),[r]),x=g=>{let O=y.format(g);return`${O.charAt(0).toUpperCase()+O.slice(1)} ${v.format(g)}`},j=()=>{let g=new Date(t);g.setMonth(g.getMonth()-1),s(g)},H=()=>{let g=new Date(t);g.setMonth(g.getMonth()+1),s(g)};return V(ce,{children:Re("div",{className:Pa(A,"cal-mini-root",m),"data-variant":p,children:[Re("div",{className:"cal-mini-header",children:[V("button",{type:"button","aria-label":b.previousMonth,onClick:j,className:"cal-mini-nav-button",children:V(Da,{size:14,"aria-hidden":!0})}),V("h2",{className:"cal-mini-caption",children:x(t)}),V("button",{type:"button","aria-label":b.nextMonth,onClick:H,className:"cal-mini-nav-button",children:V(_a,{size:14,"aria-hidden":!0})})]}),V(Sa,{mode:"single",locale:i,selected:e,month:t,onMonthChange:s,formatters:{formatWeekdayName:g=>h.format(g).charAt(0).toUpperCase()},onSelect:g=>{g&&o(g)},hideNavigation:!0,captionLayout:"label",showOutsideDays:C,modifiers:D?{"in-week":{from:D.start,to:D.last},"week-start":D.start,"week-end":D.last}:void 0,modifiersClassNames:{"in-week":"cal-mini-day--in-week","week-start":"cal-mini-day--week-start","week-end":"cal-mini-day--week-end"},className:"cal-mini-grid",classNames:{months:"cal-mini-months",month:"cal-mini-month",month_caption:"cal-mini-month-caption",caption_label:"cal-mini-caption-label",month_grid:"cal-mini-month-grid",weekdays:"cal-mini-weekdays",weekday:"cal-mini-weekday",week:"cal-mini-week",day:"cal-mini-day",day_button:"cal-mini-day-button",outside:"cal-mini-day--outside",today:"cal-mini-day--today"},components:{DayButton:({day:g,...O})=>{let I=k(g.date),ve=a.get(I)??[],ge=k(e)===I;return Re("button",{...O,children:[V("span",{children:g.date.getDate()}),V(Le,{statuses:ve,isSelected:ge,statusColors:l})]})}}})]})})};import{LayoutGroup as Ta,motion as ka}from"motion/react";import{CalendarDays as Ze,ChevronLeft as La,ChevronRight as Ra,Columns3 as Ba,LayoutGrid as Fa,List as Oa}from"lucide-react";import Ia from"clsx";import{forwardRef as Aa}from"react";import Ma from"clsx";import{jsx as Be,jsxs as wa}from"react/jsx-runtime";var X=Aa(({variant:e="primary",size:t="md",rounded:a="md",leftIcon:o,rightIcon:s,className:r,children:i,type:d="button",...l},p)=>wa("button",{ref:p,type:d,"data-variant":e,"data-size":t,"data-rounded":a,className:Ma("cal-button",r),...l,children:[o&&Be("span",{className:"cal-button__icon",children:o}),i&&Be("span",{className:"cal-button__label",children:i}),s&&Be("span",{className:"cal-button__icon",children:s})]}));X.displayName="Button";import{jsx as S,jsxs as Fe}from"react/jsx-runtime";var za={list:"List",day:"Day",week:"Week",month:"Month"},Va={list:S(Oa,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),day:S(Ze,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),week:S(Ba,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),month:S(Fa,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0})},ne={groupAriaLabel:"Calendar view",newEvent:"New event",today:"Today",previous:"Previous",next:"Next"},Ha=["month","week","list"],$a=(e,t)=>e===t||e==="week"&&t==="day",Ua=({activeView:e,onChangeView:t,views:a=Ha,onNavigate:o,todayActive:s=!1,periodLabel:r,filtersSlot:i,onNewEvent:d,messages:l,className:p})=>{let E={...za,...l?.views},c=l?.groupAriaLabel??ne.groupAriaLabel,C=l?.newEvent??ne.newEvent,m=l?.today??ne.today,b=l?.previous??ne.previous,D=l?.next??ne.next;return Fe("div",{className:Ia(A,"cal-toolbar",p),children:[o&&Fe("div",{className:"cal-toolbar__nav",children:[S(X,{variant:"outline",size:"sm",rounded:"full","data-active":s,"aria-pressed":s,onClick:()=>o("today"),children:m}),S("button",{type:"button",className:"cal-toolbar__nav-button","aria-label":b,onClick:()=>o("prev"),children:S(La,{size:18,"aria-hidden":!0})}),S("button",{type:"button",className:"cal-toolbar__nav-button","aria-label":D,onClick:()=>o("next"),children:S(Ra,{size:18,"aria-hidden":!0})}),r&&S("span",{className:"cal-toolbar__period",children:r})]}),i&&S("div",{className:"cal-toolbar__filters",children:i}),S(Ta,{id:"cal-toolbar-view-tabs",children:S("div",{className:"cal-toolbar__tabs",role:"group","aria-label":c,children:a.map(y=>{let v=$a(y,e);return Fe("button",{type:"button",onClick:()=>t(y),className:"cal-toolbar__tab","data-active":v,"aria-label":E[y],"aria-pressed":v,title:E[y],children:[v&&S(ka.span,{layoutId:"cal-toolbar-indicator",className:"cal-toolbar__indicator",transition:{type:"spring",stiffness:380,damping:34}}),S("span",{className:"cal-toolbar__tab-label",children:Va[y]})]},y)})})}),d&&S(X,{variant:"primary",size:"md",rounded:"full",onClick:d,leftIcon:S(Ze,{size:18,"aria-hidden":!0}),children:C})]})};import Ga from"clsx";import{jsx as se,jsxs as Ka}from"react/jsx-runtime";var Wa=({items:e,selectedIds:t,onToggle:a,className:o})=>{let s=new Set(t);return se("div",{className:Ga("cal-type-filter",o),role:"group",children:e.map(r=>{let i=s.has(r.id);return Ka("button",{type:"button",className:"cal-type-filter__item","data-selected":i,"aria-pressed":i,onClick:()=>a(r.id),children:[r.icon?se("span",{className:"cal-type-filter__icon",children:r.icon}):se("span",{className:"cal-type-filter__dot",style:r.color?{backgroundColor:r.color}:void 0}),se("span",{className:"cal-type-filter__label",children:r.label}),typeof r.count=="number"&&se("span",{className:"cal-type-filter__count",children:r.count})]},r.id)})})};import{useState as qa}from"react";import{Check as Ya,ChevronDown as Xa}from"lucide-react";import Qa from"clsx";import{jsx as F,jsxs as Oe}from"react/jsx-runtime";var Ie=e=>{let{placeholder:t,options:a,align:o="start",className:s}=e,[r,i]=qa(!1),d=e.multiple?new Set(e.value):new Set(e.value?[e.value]:[]),l=d.size,p=!e.multiple&&e.value?a.find(c=>c.value===e.value)?.label:void 0,E=c=>{if(e.multiple){e.onToggle(c);return}let C=e.clearable!==!1&&e.value===c?null:c;e.onChange(C),i(!1)};return Oe(z,{open:r,onOpenChange:i,children:[F(ae,{asChild:!0,children:Oe("button",{type:"button",className:Qa("cal-select__trigger",s),"data-open":r,"data-active":l>0,"aria-label":e["aria-label"]??t,children:[F("span",{className:"cal-select__placeholder",children:t}),p&&F("span",{className:"cal-select__value",children:p}),e.multiple&&l>0&&F("span",{className:"cal-select__badge",children:l}),F(Xa,{size:14,className:"cal-select__chevron","aria-hidden":!0})]})}),F(R,{className:"cal-select__panel",align:o,role:"listbox","aria-multiselectable":e.multiple??!1,children:a.map(c=>{let C=d.has(c.value);return Oe("button",{type:"button",role:"option","aria-selected":C,className:"cal-select__option","data-selected":C,onClick:()=>E(c.value),children:[c.icon?F("span",{className:"cal-select__option-icon",children:c.icon}):c.color?F("span",{className:"cal-select__dot",style:{backgroundColor:c.color}}):null,F("span",{className:"cal-select__option-label",children:c.label}),C&&F(Ya,{size:14,className:"cal-select__check","aria-hidden":!0})]},c.value)})})]})};import{jsx as Za}from"react/jsx-runtime";var Ja=({options:e,selected:t,onToggle:a,placeholder:o="Estado del evento",className:s})=>{let r=e.map(i=>({value:i.status,label:i.label,color:i.color}));return Za(Ie,{multiple:!0,placeholder:o,options:r,value:t,onToggle:a,className:s})};import{jsx as ue,jsxs as je}from"react/jsx-runtime";var ja={heading:"Event actions"},eo=({state:e,actions:t,onClose:a,onSelectAction:o,messages:s})=>{if(!e.point||!e.date)return null;let r={...ja,...s};return je(z,{open:e.isOpen,onOpenChange:i=>!i&&a(),children:[ue(oe,{asChild:!0,children:ue("span",{className:"cal-slot-anchor",style:{left:e.point.x,top:e.point.y},"aria-hidden":!0})}),je(R,{align:"start",sideOffset:8,className:"cal-slot-popover",onEscapeKeyDown:a,children:[ue("p",{className:"cal-slot-popover__heading",children:r.heading}),t.map(i=>ue(X,{type:"button",variant:"ghost",size:"sm",leftIcon:i.icon,className:"cal-slot-popover__action",onClick:()=>o({type:i.type,date:e.date}),children:i.label},i.type))]})]})};import{X as to}from"lucide-react";import ao from"clsx";import{jsx as ze,jsxs as no}from"react/jsx-runtime";var oo=({label:e,icon:t,onRemove:a,removeLabel:o="Remove",className:s})=>no("span",{className:ao("cal-type-chip",a&&"cal-type-chip--removable",s),children:[t&&ze("span",{className:"cal-type-chip__icon",children:t}),e,a&&ze("button",{type:"button",className:"cal-type-chip__remove","aria-label":`${o} ${e}`,onClick:a,children:ze(to,{size:12,"aria-hidden":!0})})]});import{useCallback as re,useMemo as so,useState as Ve}from"react";var ro=({initialView:e="week",initialDate:t,firstDay:a=1,locale:o="es-CO"}={})=>{let[s,r]=Ve(e),[i,d]=Ve(()=>t??new Date),[l,p]=Ve(()=>U(t??new Date,a)),E=s==="day"&&le(i,new Date),c=re(()=>{r(v=>v==="day"&&le(i,new Date)?"week":"day"),d(new Date)},[i]),C=re(v=>{if(v==="today"){c();return}d(h=>Se(h,s,v))},[s,c]),m=re(v=>{r(v)},[]),b=re(v=>{d(v),r(h=>h==="month"||h==="list"?"week":h)},[]),D=re((v,h)=>{p({start:v,end:h})},[]),y=so(()=>io(s,i,a,o),[s,i,a,o]);return{activeView:s,selectedDate:i,visibleRange:l,periodLabel:y,todayActive:E,onChangeView:m,onNavigate:C,onSelectDate:b,onVisibleRangeChange:D,onToday:c,setActiveView:r,setSelectedDate:d}},io=(e,t,a,o)=>{if(e==="day")return new Intl.DateTimeFormat(o,{weekday:"long",day:"numeric",month:"long"}).format(t);if(e==="month")return new Intl.DateTimeFormat(o,{month:"long",year:"numeric"}).format(t);let{start:s,end:r}=U(t,a),i=new Date(r);return i.setDate(i.getDate()-1),`${new Intl.DateTimeFormat(o,{day:"numeric",month:"short"}).formatRange(s,i)} ${s.getFullYear()}`};export{A as APE_CALENDAR_ROOT_CLASS,X as Button,Ua as CalendarToolbar,Le as DayEventDot,be as EmptyEventsState,Pe as EventAgendaList,xe as EventBlockContent,Ae as EventChipMonth,Ne as EventChipPopover,De as EventListRow,K as EventStatusBadge,oo as EventTypeChip,Wa as EventTypeFilterList,ha as MacroCalendar,Na as MiniMonthCalendar,Me as MoreEventsPopover,z as Popover,oe as PopoverAnchor,qt as PopoverClose,R as PopoverContent,Kt as PopoverPortal,ae as PopoverTrigger,Ie as Select,eo as SlotContextActions,Ja as StatusFilterSelect,yt as formatDurationLabel,_ as formatHourLabel,vt as getEventDayKeys,gt as getEventDayStatuses,U as getWeekRange,le as isSameDay,Ce as mapAvailabilityToBackgroundEvents,Et as mapAvailabilityToBusinessHours,he as mapEventToCalendarInput,Se as shiftDate,k as toDayKey,ro as useCalendarController};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|