@super-calendar/native 2.5.0 → 2.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/dist/index.d.mts +53 -4
- package/dist/index.d.ts +53 -4
- package/dist/index.js +179 -3
- package/dist/index.mjs +181 -6
- package/dist/picker.js +1 -1
- package/dist/picker.mjs +1 -1
- package/package.json +2 -2
- package/src/components/Calendar.tsx +32 -2
- package/src/components/YearView.tsx +276 -0
- package/src/index.tsx +1 -0
- package/dist/{MonthList-zPLklHAY.mjs → MonthList-CMzYn9T0.mjs} +1 -1
- package/dist/{MonthList-Aczb2RSY.js → MonthList-Gu6p64fE.js} +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -4,6 +4,53 @@ import { ComponentType, ReactElement } from "react";
|
|
|
4
4
|
import { SharedValue, useSharedValue } from "react-native-reanimated";
|
|
5
5
|
import { CalendarEvent as CalendarEvent$1, DateRange, DateSelectionConstraints, DaySelectionState, EventAccessibilityLabeler as EventAccessibilityLabeler$1, ICalEvent, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, PositionedEvent, ToICalendarOptions, UseDateRangeOptions, UseMonthGridOptions, WeekdayFormat as WeekdayFormat$1, buildMonthGrid, buildMonthWeeks, daySelectionState, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useDateRange, useMonthGrid, weekdayFormatToken } from "@super-calendar/core";
|
|
6
6
|
import { StyleProp, ViewStyle } from "react-native";
|
|
7
|
+
//#region src/components/YearView.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* The styleable parts of {@link YearView}. `dayText` and `eventDot` are the
|
|
10
|
+
* text/marker inside a day cell (React Native text colour doesn't inherit).
|
|
11
|
+
*/
|
|
12
|
+
type YearViewSlot = "grid" | "month" | "monthTitle" | "weekdays" | "weekday" | "week" | "day" | "dayText" | "eventDot";
|
|
13
|
+
/** Props for {@link YearView}, the twelve mini-month year grid. */
|
|
14
|
+
type YearViewProps<T = unknown> = SlotStyleProps<YearViewSlot> & {
|
|
15
|
+
/** Any date inside the year to render. */
|
|
16
|
+
date: Date;
|
|
17
|
+
/** Days holding at least one event get a dot. Omit for a plain year. */
|
|
18
|
+
events?: CalendarEvent<T>[];
|
|
19
|
+
weekStartsOn: WeekStartsOn;
|
|
20
|
+
locale?: Locale;
|
|
21
|
+
/** Highlight this date instead of the real "today". */
|
|
22
|
+
activeDate?: Date;
|
|
23
|
+
/**
|
|
24
|
+
* Smallest width a mini month may take before the grid drops a column
|
|
25
|
+
* (default 150). The grid fits 2–4 columns from the measured width.
|
|
26
|
+
*/
|
|
27
|
+
minMonthWidth?: number;
|
|
28
|
+
/** Tap a day cell (e.g. to drill into the day or month view). */
|
|
29
|
+
onPressDay?: (date: Date) => void;
|
|
30
|
+
/** Tap a month's title (e.g. to jump to that month's view). */
|
|
31
|
+
onPressMonth?: (month: Date) => void;
|
|
32
|
+
};
|
|
33
|
+
declare function YearViewInner<T>({ date, events, weekStartsOn, locale, activeDate, minMonthWidth, onPressDay, onPressMonth, classNames, styles: styleOverrides }: YearViewProps<T>): ReactElement;
|
|
34
|
+
/**
|
|
35
|
+
* A year at a glance: the twelve months as compact mini grids, with today
|
|
36
|
+
* highlighted and a dot under days that hold events. Tap a day or a month
|
|
37
|
+
* title to drill into a denser view. It's the view `Calendar` renders for
|
|
38
|
+
* `mode="year"`.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* import { YearView } from "@super-calendar/native";
|
|
43
|
+
*
|
|
44
|
+
* <YearView
|
|
45
|
+
* date={new Date()}
|
|
46
|
+
* events={events}
|
|
47
|
+
* weekStartsOn={1}
|
|
48
|
+
* onPressDay={(day) => console.log(day)}
|
|
49
|
+
* />
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare const YearView: typeof YearViewInner;
|
|
53
|
+
//#endregion
|
|
7
54
|
//#region src/components/Agenda.d.ts
|
|
8
55
|
/**
|
|
9
56
|
* The styleable parts of {@link Agenda}. Mirrors the dom renderer's slot names;
|
|
@@ -182,7 +229,7 @@ declare const TimeGrid: typeof TimeGridInner;
|
|
|
182
229
|
* month pager, the grid slots reach the time grid, and the agenda slots reach
|
|
183
230
|
* the schedule view; slots for views that aren't rendered are ignored.
|
|
184
231
|
*/
|
|
185
|
-
type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot;
|
|
232
|
+
type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot | YearViewSlot;
|
|
186
233
|
/** Props for the {@link Calendar} component. */
|
|
187
234
|
type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
188
235
|
events: CalendarEvent<T>[];
|
|
@@ -217,8 +264,10 @@ type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
|
217
264
|
* drag-to-move and drag-to-resize working while hiding the visible indicator.
|
|
218
265
|
*/
|
|
219
266
|
showDragHandle?: boolean;
|
|
220
|
-
/** Tap a day cell (month
|
|
267
|
+
/** Tap a day cell (month and year modes) — e.g. drill into the day view. */
|
|
221
268
|
onPressDay?: (date: Date) => void;
|
|
269
|
+
/** Tap a month's title in the year view — e.g. jump to that month. */
|
|
270
|
+
onPressMonth?: (month: Date) => void;
|
|
222
271
|
/** Long-press a day cell (month mode). */
|
|
223
272
|
onLongPressDay?: (date: Date) => void;
|
|
224
273
|
/** Tap the "+N more" overflow label in a month cell. */
|
|
@@ -397,7 +446,7 @@ type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
|
397
446
|
* }
|
|
398
447
|
* ```
|
|
399
448
|
*/
|
|
400
|
-
declare function Calendar<T>({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn, weekdayFormat, numberOfDays, weekEndsOn, renderEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor, theme, cellHeight: cellHeightProp, hourHeight, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }: CalendarProps<T>): ReactElement;
|
|
449
|
+
declare function Calendar<T>({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onPressMonth, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn, weekdayFormat, numberOfDays, weekEndsOn, renderEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor, theme, cellHeight: cellHeightProp, hourHeight, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }: CalendarProps<T>): ReactElement;
|
|
401
450
|
//#endregion
|
|
402
451
|
//#region src/components/DefaultEvent.d.ts
|
|
403
452
|
/**
|
|
@@ -520,4 +569,4 @@ interface ResourceTimelineProps<T = unknown> {
|
|
|
520
569
|
*/
|
|
521
570
|
declare function ResourceTimeline<T = unknown>({ date, orientation, resources, events, resourceId, startHour, endHour, hourWidth, hourHeight, rowHeight, labelWidth, ampm, renderEvent, onPressEvent, onLongPressEvent, onDragEvent, onPressCell, onLongPressCell, onCreateEvent, businessHours, dragStepMinutes }: ResourceTimelineProps<T>): ReactElement;
|
|
522
571
|
//#endregion
|
|
523
|
-
export { Agenda, type AgendaProps, type AgendaSlot, type BusinessHours, Calendar, type CalendarEvent, type CalendarMode, type CalendarProps, type CalendarSlot, type CalendarTheme, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultEvent, DefaultMonthEvent, type EventAccessibilityLabelContext, type EventAccessibilityLabeler, type EventDragHandler, type EventDragStartHandler, type EventKeyExtractor, type HourRenderer, type ICalEvent, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, type MonthListSlot, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type MonthViewSlot, type PartialCalendarTheme, type PositionedEvent, type RecurrenceFrequency, type RecurrenceRule, type RenderEvent, type RenderEventArgs, type ResolvedSlot, type Resource, type ResourceEventArgs, ResourceTimeline, type ResourceTimelineProps, type SlotDefault, type SlotStyleProps, TimeGrid, type TimeGridMode, type TimeGridProps, type TimeGridSlot, type ToICalendarOptions, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, type WeekdayFormat, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
|
572
|
+
export { Agenda, type AgendaProps, type AgendaSlot, type BusinessHours, Calendar, type CalendarEvent, type CalendarMode, type CalendarProps, type CalendarSlot, type CalendarTheme, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultEvent, DefaultMonthEvent, type EventAccessibilityLabelContext, type EventAccessibilityLabeler, type EventDragHandler, type EventDragStartHandler, type EventKeyExtractor, type HourRenderer, type ICalEvent, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, type MonthListSlot, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type MonthViewSlot, type PartialCalendarTheme, type PositionedEvent, type RecurrenceFrequency, type RecurrenceRule, type RenderEvent, type RenderEventArgs, type ResolvedSlot, type Resource, type ResourceEventArgs, ResourceTimeline, type ResourceTimelineProps, type SlotDefault, type SlotStyleProps, TimeGrid, type TimeGridMode, type TimeGridProps, type TimeGridSlot, type ToICalendarOptions, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, type WeekdayFormat, YearView, type YearViewProps, type YearViewSlot, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,53 @@ import { ComponentType, ReactElement } from "react";
|
|
|
4
4
|
import { StyleProp, ViewStyle } from "react-native";
|
|
5
5
|
import { SharedValue, useSharedValue } from "react-native-reanimated";
|
|
6
6
|
import { CalendarEvent as CalendarEvent$1, DateRange, DateSelectionConstraints, DaySelectionState, EventAccessibilityLabeler as EventAccessibilityLabeler$1, ICalEvent, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, PositionedEvent, ToICalendarOptions, UseDateRangeOptions, UseMonthGridOptions, WeekdayFormat as WeekdayFormat$1, buildMonthGrid, buildMonthWeeks, daySelectionState, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useDateRange, useMonthGrid, weekdayFormatToken } from "@super-calendar/core";
|
|
7
|
+
//#region src/components/YearView.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* The styleable parts of {@link YearView}. `dayText` and `eventDot` are the
|
|
10
|
+
* text/marker inside a day cell (React Native text colour doesn't inherit).
|
|
11
|
+
*/
|
|
12
|
+
type YearViewSlot = "grid" | "month" | "monthTitle" | "weekdays" | "weekday" | "week" | "day" | "dayText" | "eventDot";
|
|
13
|
+
/** Props for {@link YearView}, the twelve mini-month year grid. */
|
|
14
|
+
type YearViewProps<T = unknown> = SlotStyleProps<YearViewSlot> & {
|
|
15
|
+
/** Any date inside the year to render. */
|
|
16
|
+
date: Date;
|
|
17
|
+
/** Days holding at least one event get a dot. Omit for a plain year. */
|
|
18
|
+
events?: CalendarEvent<T>[];
|
|
19
|
+
weekStartsOn: WeekStartsOn;
|
|
20
|
+
locale?: Locale;
|
|
21
|
+
/** Highlight this date instead of the real "today". */
|
|
22
|
+
activeDate?: Date;
|
|
23
|
+
/**
|
|
24
|
+
* Smallest width a mini month may take before the grid drops a column
|
|
25
|
+
* (default 150). The grid fits 2–4 columns from the measured width.
|
|
26
|
+
*/
|
|
27
|
+
minMonthWidth?: number;
|
|
28
|
+
/** Tap a day cell (e.g. to drill into the day or month view). */
|
|
29
|
+
onPressDay?: (date: Date) => void;
|
|
30
|
+
/** Tap a month's title (e.g. to jump to that month's view). */
|
|
31
|
+
onPressMonth?: (month: Date) => void;
|
|
32
|
+
};
|
|
33
|
+
declare function YearViewInner<T>({ date, events, weekStartsOn, locale, activeDate, minMonthWidth, onPressDay, onPressMonth, classNames, styles: styleOverrides }: YearViewProps<T>): ReactElement;
|
|
34
|
+
/**
|
|
35
|
+
* A year at a glance: the twelve months as compact mini grids, with today
|
|
36
|
+
* highlighted and a dot under days that hold events. Tap a day or a month
|
|
37
|
+
* title to drill into a denser view. It's the view `Calendar` renders for
|
|
38
|
+
* `mode="year"`.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* import { YearView } from "@super-calendar/native";
|
|
43
|
+
*
|
|
44
|
+
* <YearView
|
|
45
|
+
* date={new Date()}
|
|
46
|
+
* events={events}
|
|
47
|
+
* weekStartsOn={1}
|
|
48
|
+
* onPressDay={(day) => console.log(day)}
|
|
49
|
+
* />
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare const YearView: typeof YearViewInner;
|
|
53
|
+
//#endregion
|
|
7
54
|
//#region src/components/Agenda.d.ts
|
|
8
55
|
/**
|
|
9
56
|
* The styleable parts of {@link Agenda}. Mirrors the dom renderer's slot names;
|
|
@@ -182,7 +229,7 @@ declare const TimeGrid: typeof TimeGridInner;
|
|
|
182
229
|
* month pager, the grid slots reach the time grid, and the agenda slots reach
|
|
183
230
|
* the schedule view; slots for views that aren't rendered are ignored.
|
|
184
231
|
*/
|
|
185
|
-
type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot;
|
|
232
|
+
type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot | YearViewSlot;
|
|
186
233
|
/** Props for the {@link Calendar} component. */
|
|
187
234
|
type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
188
235
|
events: CalendarEvent<T>[];
|
|
@@ -217,8 +264,10 @@ type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
|
217
264
|
* drag-to-move and drag-to-resize working while hiding the visible indicator.
|
|
218
265
|
*/
|
|
219
266
|
showDragHandle?: boolean;
|
|
220
|
-
/** Tap a day cell (month
|
|
267
|
+
/** Tap a day cell (month and year modes) — e.g. drill into the day view. */
|
|
221
268
|
onPressDay?: (date: Date) => void;
|
|
269
|
+
/** Tap a month's title in the year view — e.g. jump to that month. */
|
|
270
|
+
onPressMonth?: (month: Date) => void;
|
|
222
271
|
/** Long-press a day cell (month mode). */
|
|
223
272
|
onLongPressDay?: (date: Date) => void;
|
|
224
273
|
/** Tap the "+N more" overflow label in a month cell. */
|
|
@@ -397,7 +446,7 @@ type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
|
397
446
|
* }
|
|
398
447
|
* ```
|
|
399
448
|
*/
|
|
400
|
-
declare function Calendar<T>({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn, weekdayFormat, numberOfDays, weekEndsOn, renderEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor, theme, cellHeight: cellHeightProp, hourHeight, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }: CalendarProps<T>): ReactElement;
|
|
449
|
+
declare function Calendar<T>({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onPressMonth, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn, weekdayFormat, numberOfDays, weekEndsOn, renderEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor, theme, cellHeight: cellHeightProp, hourHeight, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }: CalendarProps<T>): ReactElement;
|
|
401
450
|
//#endregion
|
|
402
451
|
//#region src/components/DefaultEvent.d.ts
|
|
403
452
|
/**
|
|
@@ -520,4 +569,4 @@ interface ResourceTimelineProps<T = unknown> {
|
|
|
520
569
|
*/
|
|
521
570
|
declare function ResourceTimeline<T = unknown>({ date, orientation, resources, events, resourceId, startHour, endHour, hourWidth, hourHeight, rowHeight, labelWidth, ampm, renderEvent, onPressEvent, onLongPressEvent, onDragEvent, onPressCell, onLongPressCell, onCreateEvent, businessHours, dragStepMinutes }: ResourceTimelineProps<T>): ReactElement;
|
|
522
571
|
//#endregion
|
|
523
|
-
export { Agenda, type AgendaProps, type AgendaSlot, type BusinessHours, Calendar, type CalendarEvent, type CalendarMode, type CalendarProps, type CalendarSlot, type CalendarTheme, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultEvent, DefaultMonthEvent, type EventAccessibilityLabelContext, type EventAccessibilityLabeler, type EventDragHandler, type EventDragStartHandler, type EventKeyExtractor, type HourRenderer, type ICalEvent, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, type MonthListSlot, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type MonthViewSlot, type PartialCalendarTheme, type PositionedEvent, type RecurrenceFrequency, type RecurrenceRule, type RenderEvent, type RenderEventArgs, type ResolvedSlot, type Resource, type ResourceEventArgs, ResourceTimeline, type ResourceTimelineProps, type SlotDefault, type SlotStyleProps, TimeGrid, type TimeGridMode, type TimeGridProps, type TimeGridSlot, type ToICalendarOptions, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, type WeekdayFormat, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
|
572
|
+
export { Agenda, type AgendaProps, type AgendaSlot, type BusinessHours, Calendar, type CalendarEvent, type CalendarMode, type CalendarProps, type CalendarSlot, type CalendarTheme, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultEvent, DefaultMonthEvent, type EventAccessibilityLabelContext, type EventAccessibilityLabeler, type EventDragHandler, type EventDragStartHandler, type EventKeyExtractor, type HourRenderer, type ICalEvent, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, type MonthListSlot, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type MonthViewSlot, type PartialCalendarTheme, type PositionedEvent, type RecurrenceFrequency, type RecurrenceRule, type RenderEvent, type RenderEventArgs, type ResolvedSlot, type Resource, type ResourceEventArgs, ResourceTimeline, type ResourceTimelineProps, type SlotDefault, type SlotStyleProps, TimeGrid, type TimeGridMode, type TimeGridProps, type TimeGridSlot, type ToICalendarOptions, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, type WeekdayFormat, YearView, type YearViewProps, type YearViewSlot, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
package/dist/index.js
CHANGED
|
@@ -21,16 +21,179 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
const require_MonthList = require("./MonthList-
|
|
24
|
+
const require_MonthList = require("./MonthList-Gu6p64fE.js");
|
|
25
25
|
let date_fns = require("date-fns");
|
|
26
26
|
let react = require("react");
|
|
27
27
|
let react_native_reanimated = require("react-native-reanimated");
|
|
28
28
|
react_native_reanimated = __toESM(react_native_reanimated);
|
|
29
29
|
let _super_calendar_core = require("@super-calendar/core");
|
|
30
|
-
let _legendapp_list_react_native = require("@legendapp/list/react-native");
|
|
31
30
|
let react_native = require("react-native");
|
|
32
31
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
32
|
+
let _legendapp_list_react_native = require("@legendapp/list/react-native");
|
|
33
33
|
let react_native_gesture_handler = require("react-native-gesture-handler");
|
|
34
|
+
//#region src/components/YearView.tsx
|
|
35
|
+
const FALLBACK_COLUMNS = 3;
|
|
36
|
+
function YearViewInner({ date, events, weekStartsOn, locale, activeDate, minMonthWidth = 150, onPressDay, onPressMonth, classNames, styles: styleOverrides }) {
|
|
37
|
+
const theme = require_MonthList.useCalendarTheme();
|
|
38
|
+
const slot = require_MonthList.createSlots({
|
|
39
|
+
classNames,
|
|
40
|
+
styles: styleOverrides
|
|
41
|
+
});
|
|
42
|
+
const [columns, setColumns] = (0, react.useState)(FALLBACK_COLUMNS);
|
|
43
|
+
const handleLayout = (event) => {
|
|
44
|
+
const width = event.nativeEvent.layout.width;
|
|
45
|
+
if (width <= 0) return;
|
|
46
|
+
setColumns(Math.max(2, Math.min(4, Math.floor(width / minMonthWidth))));
|
|
47
|
+
};
|
|
48
|
+
const months = (0, react.useMemo)(() => (0, _super_calendar_core.getYearMonths)(date), [date]);
|
|
49
|
+
const weekdayLabels = (0, react.useMemo)(() => (0, _super_calendar_core.getWeekDays)(date, weekStartsOn).map((d) => (0, date_fns.format)(d, (0, _super_calendar_core.weekdayFormatToken)("narrow"), { locale })), [
|
|
50
|
+
date,
|
|
51
|
+
weekStartsOn,
|
|
52
|
+
locale
|
|
53
|
+
]);
|
|
54
|
+
const eventDays = (0, react.useMemo)(() => new Set(events && events.length > 0 ? (0, _super_calendar_core.groupEventsByDay)(events).keys() : []), [events]);
|
|
55
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
|
|
56
|
+
onLayout: handleLayout,
|
|
57
|
+
showsVerticalScrollIndicator: true,
|
|
58
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
59
|
+
...slot("grid", { base: styles$5.grid }),
|
|
60
|
+
children: months.map((month) => {
|
|
61
|
+
const weeks = (0, _super_calendar_core.buildMonthWeeks)(month, weekStartsOn);
|
|
62
|
+
const title = (0, date_fns.format)(month, "MMMM", { locale });
|
|
63
|
+
const monthLabel = (0, date_fns.format)(month, "MMMM yyyy", { locale });
|
|
64
|
+
const titleText = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
65
|
+
...slot("monthTitle", {
|
|
66
|
+
base: styles$5.monthTitle,
|
|
67
|
+
themed: [styles$5.monthTitleText, { color: theme.colors.todayBackground }]
|
|
68
|
+
}),
|
|
69
|
+
allowFontScaling: false,
|
|
70
|
+
children: title
|
|
71
|
+
});
|
|
72
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
|
|
73
|
+
...slot("month", { base: [styles$5.month, { width: `${100 / columns}%` }] }),
|
|
74
|
+
children: [
|
|
75
|
+
onPressMonth ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
|
|
76
|
+
onPress: () => onPressMonth(month),
|
|
77
|
+
accessibilityRole: "button",
|
|
78
|
+
accessibilityLabel: monthLabel,
|
|
79
|
+
children: titleText
|
|
80
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
81
|
+
accessible: true,
|
|
82
|
+
accessibilityRole: "header",
|
|
83
|
+
accessibilityLabel: monthLabel,
|
|
84
|
+
children: titleText
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
87
|
+
...slot("weekdays", { base: styles$5.weekdays }),
|
|
88
|
+
accessibilityElementsHidden: true,
|
|
89
|
+
importantForAccessibility: "no-hide-descendants",
|
|
90
|
+
children: weekdayLabels.map((label, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
91
|
+
...slot("weekday", {
|
|
92
|
+
base: styles$5.weekday,
|
|
93
|
+
themed: [styles$5.weekdayText, { color: theme.colors.textMuted }]
|
|
94
|
+
}),
|
|
95
|
+
allowFontScaling: false,
|
|
96
|
+
children: label
|
|
97
|
+
}, i))
|
|
98
|
+
}),
|
|
99
|
+
weeks.map((week) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
100
|
+
...slot("week", { base: styles$5.week }),
|
|
101
|
+
children: week.map((day) => {
|
|
102
|
+
if (day.getMonth() !== month.getMonth()) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: styles$5.day }, day.toISOString());
|
|
103
|
+
const isHighlighted = activeDate ? (0, _super_calendar_core.isSameCalendarDay)(day, activeDate) : (0, _super_calendar_core.getIsToday)(day);
|
|
104
|
+
const hasEvents = eventDays.has((0, date_fns.startOfDay)(day).toISOString());
|
|
105
|
+
const label = `${(0, date_fns.format)(day, "EEEE, d LLLL yyyy", { locale })}${(0, _super_calendar_core.getIsToday)(day) ? ", today" : ""}${hasEvents ? ", has events" : ""}`;
|
|
106
|
+
const daySlot = slot("day", {
|
|
107
|
+
base: styles$5.day,
|
|
108
|
+
themed: isHighlighted ? {
|
|
109
|
+
backgroundColor: theme.colors.todayBackground,
|
|
110
|
+
borderRadius: theme.todayBadgeRadius
|
|
111
|
+
} : void 0
|
|
112
|
+
});
|
|
113
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
114
|
+
...slot("dayText", { themed: [styles$5.dayText, { color: isHighlighted ? theme.colors.todayText : theme.colors.text }] }),
|
|
115
|
+
allowFontScaling: false,
|
|
116
|
+
children: day.getDate()
|
|
117
|
+
}), hasEvents ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { ...slot("eventDot", {
|
|
118
|
+
base: styles$5.eventDot,
|
|
119
|
+
themed: { backgroundColor: isHighlighted ? theme.colors.todayText : theme.colors.todayBackground }
|
|
120
|
+
}) }) : null] });
|
|
121
|
+
return onPressDay ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
|
|
122
|
+
onPress: () => onPressDay(day),
|
|
123
|
+
accessibilityRole: "button",
|
|
124
|
+
accessibilityLabel: label,
|
|
125
|
+
...daySlot,
|
|
126
|
+
children: content
|
|
127
|
+
}, day.toISOString()) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
128
|
+
accessible: true,
|
|
129
|
+
accessibilityLabel: label,
|
|
130
|
+
...daySlot,
|
|
131
|
+
children: content
|
|
132
|
+
}, day.toISOString());
|
|
133
|
+
})
|
|
134
|
+
}, week[0].toISOString()))
|
|
135
|
+
]
|
|
136
|
+
}, month.toISOString());
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A year at a glance: the twelve months as compact mini grids, with today
|
|
143
|
+
* highlighted and a dot under days that hold events. Tap a day or a month
|
|
144
|
+
* title to drill into a denser view. It's the view `Calendar` renders for
|
|
145
|
+
* `mode="year"`.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```tsx
|
|
149
|
+
* import { YearView } from "@super-calendar/native";
|
|
150
|
+
*
|
|
151
|
+
* <YearView
|
|
152
|
+
* date={new Date()}
|
|
153
|
+
* events={events}
|
|
154
|
+
* weekStartsOn={1}
|
|
155
|
+
* onPressDay={(day) => console.log(day)}
|
|
156
|
+
* />
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
const YearView = (0, react.memo)(YearViewInner);
|
|
160
|
+
const styles$5 = react_native.StyleSheet.create({
|
|
161
|
+
grid: {
|
|
162
|
+
flexDirection: "row",
|
|
163
|
+
flexWrap: "wrap"
|
|
164
|
+
},
|
|
165
|
+
month: { padding: 8 },
|
|
166
|
+
monthTitle: { paddingBottom: 4 },
|
|
167
|
+
monthTitleText: {
|
|
168
|
+
fontSize: 13,
|
|
169
|
+
fontWeight: "700"
|
|
170
|
+
},
|
|
171
|
+
weekdays: { flexDirection: "row" },
|
|
172
|
+
weekday: {
|
|
173
|
+
flex: 1,
|
|
174
|
+
textAlign: "center"
|
|
175
|
+
},
|
|
176
|
+
weekdayText: {
|
|
177
|
+
fontSize: 9,
|
|
178
|
+
fontWeight: "600"
|
|
179
|
+
},
|
|
180
|
+
week: { flexDirection: "row" },
|
|
181
|
+
day: {
|
|
182
|
+
flex: 1,
|
|
183
|
+
aspectRatio: 1,
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
justifyContent: "center"
|
|
186
|
+
},
|
|
187
|
+
dayText: { fontSize: 11 },
|
|
188
|
+
eventDot: {
|
|
189
|
+
position: "absolute",
|
|
190
|
+
bottom: 1,
|
|
191
|
+
width: 3,
|
|
192
|
+
height: 3,
|
|
193
|
+
borderRadius: 2
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
//#endregion
|
|
34
197
|
//#region src/components/Agenda.tsx
|
|
35
198
|
/**
|
|
36
199
|
* A vertical, day-grouped list of events (no time grid). Events are sorted by
|
|
@@ -1589,11 +1752,13 @@ const styles$1 = react_native.StyleSheet.create({
|
|
|
1589
1752
|
const defaultKeyExtractor = (event) => `${event.start.toISOString()}|${event.end.toISOString()}|${event.title ?? ""}`;
|
|
1590
1753
|
function visibleRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
1591
1754
|
if (mode === "month") return [(0, date_fns.startOfWeek)((0, date_fns.startOfMonth)(date), { weekStartsOn }), (0, date_fns.endOfWeek)((0, date_fns.endOfMonth)(date), { weekStartsOn })];
|
|
1755
|
+
if (mode === "year") return [(0, date_fns.startOfWeek)((0, date_fns.startOfYear)(date), { weekStartsOn }), (0, date_fns.endOfWeek)((0, date_fns.endOfYear)(date), { weekStartsOn })];
|
|
1592
1756
|
const days = (0, _super_calendar_core.getViewDays)(mode, date, weekStartsOn, numberOfDays, false, weekEndsOn);
|
|
1593
1757
|
return [(0, date_fns.startOfDay)(days[0]), (0, date_fns.endOfDay)(days[days.length - 1])];
|
|
1594
1758
|
}
|
|
1595
1759
|
function expansionRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
1596
1760
|
if (mode === "month") return [(0, date_fns.startOfWeek)((0, date_fns.startOfMonth)((0, date_fns.addMonths)(date, -1)), { weekStartsOn }), (0, date_fns.addWeeks)((0, date_fns.endOfWeek)((0, date_fns.endOfMonth)((0, date_fns.addMonths)(date, 1)), { weekStartsOn }), 1)];
|
|
1761
|
+
if (mode === "year") return [(0, date_fns.startOfWeek)((0, date_fns.startOfYear)(date), { weekStartsOn }), (0, date_fns.endOfWeek)((0, date_fns.endOfYear)(date), { weekStartsOn })];
|
|
1597
1762
|
if (mode === "schedule") return [(0, date_fns.startOfDay)(date), (0, date_fns.endOfDay)((0, date_fns.addMonths)(date, 3))];
|
|
1598
1763
|
const days = (0, _super_calendar_core.getViewDays)(mode, date, weekStartsOn, numberOfDays, false, weekEndsOn);
|
|
1599
1764
|
const span = days.length;
|
|
@@ -1625,7 +1790,7 @@ function expansionRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
|
1625
1790
|
* }
|
|
1626
1791
|
* ```
|
|
1627
1792
|
*/
|
|
1628
|
-
function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn = 0, weekdayFormat, numberOfDays, weekEndsOn, renderEvent = DefaultEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor = defaultKeyExtractor, theme, cellHeight: cellHeightProp, hourHeight = 48, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }) {
|
|
1793
|
+
function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onPressMonth, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn = 0, weekdayFormat, numberOfDays, weekEndsOn, renderEvent = DefaultEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor = defaultKeyExtractor, theme, cellHeight: cellHeightProp, hourHeight = 48, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }) {
|
|
1629
1794
|
const mergedTheme = (0, react.useMemo)(() => require_MonthList.mergeTheme(theme), [theme]);
|
|
1630
1795
|
const internalCellHeight = (0, react_native_reanimated.useSharedValue)(hourHeight);
|
|
1631
1796
|
const cellHeight = cellHeightProp ?? internalCellHeight;
|
|
@@ -1726,6 +1891,16 @@ function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPress
|
|
|
1726
1891
|
swipeEnabled,
|
|
1727
1892
|
classNames,
|
|
1728
1893
|
styles: styleOverrides
|
|
1894
|
+
}) : mode === "year" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(YearView, {
|
|
1895
|
+
date,
|
|
1896
|
+
events: displayEvents,
|
|
1897
|
+
weekStartsOn,
|
|
1898
|
+
locale,
|
|
1899
|
+
activeDate,
|
|
1900
|
+
onPressDay,
|
|
1901
|
+
onPressMonth,
|
|
1902
|
+
classNames,
|
|
1903
|
+
styles: styleOverrides
|
|
1729
1904
|
}) : mode === "schedule" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Agenda, {
|
|
1730
1905
|
events: displayEvents,
|
|
1731
1906
|
locale,
|
|
@@ -2506,6 +2681,7 @@ exports.MonthPager = require_MonthList.MonthPager;
|
|
|
2506
2681
|
exports.MonthView = require_MonthList.MonthView;
|
|
2507
2682
|
exports.ResourceTimeline = ResourceTimeline;
|
|
2508
2683
|
exports.TimeGrid = TimeGrid;
|
|
2684
|
+
exports.YearView = YearView;
|
|
2509
2685
|
Object.defineProperty(exports, "buildMonthGrid", {
|
|
2510
2686
|
enumerable: true,
|
|
2511
2687
|
get: function() {
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,175 @@
|
|
|
1
|
-
import { a as withEventAccessibilityLabel, c as createSlots, d as darkTheme, f as defaultTheme, i as MonthView, l as useSlots, m as useCalendarTheme, n as DefaultMonthEvent, o as useWebPagerKeys, p as mergeTheme, r as MonthPager, s as SlotStylesProvider, t as MonthList, u as CalendarThemeProvider } from "./MonthList-
|
|
2
|
-
import { addDays, addMonths, addWeeks, differenceInCalendarDays, endOfDay, endOfMonth, endOfWeek, format, getHours, getISOWeek, getMinutes, isSameDay, startOfDay, startOfMonth, startOfWeek } from "date-fns";
|
|
1
|
+
import { a as withEventAccessibilityLabel, c as createSlots, d as darkTheme, f as defaultTheme, i as MonthView, l as useSlots, m as useCalendarTheme, n as DefaultMonthEvent, o as useWebPagerKeys, p as mergeTheme, r as MonthPager, s as SlotStylesProvider, t as MonthList, u as CalendarThemeProvider } from "./MonthList-CMzYn9T0.mjs";
|
|
2
|
+
import { addDays, addMonths, addWeeks, differenceInCalendarDays, endOfDay, endOfMonth, endOfWeek, endOfYear, format, getHours, getISOWeek, getMinutes, isSameDay, startOfDay, startOfMonth, startOfWeek, startOfYear } from "date-fns";
|
|
3
3
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import Animated, { runOnJS, scrollTo, useAnimatedReaction, useAnimatedRef, useAnimatedScrollHandler, useAnimatedStyle, useDerivedValue, useReducedMotion, useSharedValue } from "react-native-reanimated";
|
|
5
|
-
import { buildMonthGrid, buildMonthWeeks, cellRangeFromDrag, closedHourBands, daySelectionState, eventAccessibilityLabel, eventChipLayout, eventTimeLabel, eventsInTimeZone, eventsInTimeZone as eventsInTimeZone$1, expandRecurringEvents, expandRecurringEvents as expandRecurringEvents$1, formatHour, getIsToday, getIsToday as getIsToday$1, getViewDays, getViewDays as getViewDays$1, getWeekDays, isAllDayEvent, isAllDayEvent as isAllDayEvent$1, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isSameCalendarDay as isSameCalendarDay$1, isWeekend, isWeekend as isWeekend$1, isWithinDateRange, layoutDayEvents, layoutDayEvents as layoutDayEvents$1, minutesIntoDay, nextDateRange, parseICalendar, resolveDraggedBounds, snapDeltaMinutes, titleEllipsizeMode, titleNumberOfLines, toICalendar, toZonedTime, useDateRange, useMonthGrid, viewDayCount, weekdayFormatToken, weekdayFormatToken as weekdayFormatToken$1 } from "@super-calendar/core";
|
|
6
|
-
import { LegendList } from "@legendapp/list/react-native";
|
|
5
|
+
import { buildMonthGrid, buildMonthWeeks, buildMonthWeeks as buildMonthWeeks$1, cellRangeFromDrag, closedHourBands, daySelectionState, eventAccessibilityLabel, eventChipLayout, eventTimeLabel, eventsInTimeZone, eventsInTimeZone as eventsInTimeZone$1, expandRecurringEvents, expandRecurringEvents as expandRecurringEvents$1, formatHour, getIsToday, getIsToday as getIsToday$1, getViewDays, getViewDays as getViewDays$1, getWeekDays, getWeekDays as getWeekDays$1, getYearMonths, groupEventsByDay, isAllDayEvent, isAllDayEvent as isAllDayEvent$1, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isSameCalendarDay as isSameCalendarDay$1, isWeekend, isWeekend as isWeekend$1, isWithinDateRange, layoutDayEvents, layoutDayEvents as layoutDayEvents$1, minutesIntoDay, nextDateRange, parseICalendar, resolveDraggedBounds, snapDeltaMinutes, titleEllipsizeMode, titleNumberOfLines, toICalendar, toZonedTime, useDateRange, useMonthGrid, viewDayCount, weekdayFormatToken, weekdayFormatToken as weekdayFormatToken$1 } from "@super-calendar/core";
|
|
7
6
|
import { Platform, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View, useWindowDimensions } from "react-native";
|
|
8
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { LegendList } from "@legendapp/list/react-native";
|
|
9
9
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
10
|
+
//#region src/components/YearView.tsx
|
|
11
|
+
const FALLBACK_COLUMNS = 3;
|
|
12
|
+
function YearViewInner({ date, events, weekStartsOn, locale, activeDate, minMonthWidth = 150, onPressDay, onPressMonth, classNames, styles: styleOverrides }) {
|
|
13
|
+
const theme = useCalendarTheme();
|
|
14
|
+
const slot = createSlots({
|
|
15
|
+
classNames,
|
|
16
|
+
styles: styleOverrides
|
|
17
|
+
});
|
|
18
|
+
const [columns, setColumns] = useState(FALLBACK_COLUMNS);
|
|
19
|
+
const handleLayout = (event) => {
|
|
20
|
+
const width = event.nativeEvent.layout.width;
|
|
21
|
+
if (width <= 0) return;
|
|
22
|
+
setColumns(Math.max(2, Math.min(4, Math.floor(width / minMonthWidth))));
|
|
23
|
+
};
|
|
24
|
+
const months = useMemo(() => getYearMonths(date), [date]);
|
|
25
|
+
const weekdayLabels = useMemo(() => getWeekDays$1(date, weekStartsOn).map((d) => format(d, weekdayFormatToken$1("narrow"), { locale })), [
|
|
26
|
+
date,
|
|
27
|
+
weekStartsOn,
|
|
28
|
+
locale
|
|
29
|
+
]);
|
|
30
|
+
const eventDays = useMemo(() => new Set(events && events.length > 0 ? groupEventsByDay(events).keys() : []), [events]);
|
|
31
|
+
return /* @__PURE__ */ jsx(ScrollView, {
|
|
32
|
+
onLayout: handleLayout,
|
|
33
|
+
showsVerticalScrollIndicator: true,
|
|
34
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
35
|
+
...slot("grid", { base: styles$5.grid }),
|
|
36
|
+
children: months.map((month) => {
|
|
37
|
+
const weeks = buildMonthWeeks$1(month, weekStartsOn);
|
|
38
|
+
const title = format(month, "MMMM", { locale });
|
|
39
|
+
const monthLabel = format(month, "MMMM yyyy", { locale });
|
|
40
|
+
const titleText = /* @__PURE__ */ jsx(Text, {
|
|
41
|
+
...slot("monthTitle", {
|
|
42
|
+
base: styles$5.monthTitle,
|
|
43
|
+
themed: [styles$5.monthTitleText, { color: theme.colors.todayBackground }]
|
|
44
|
+
}),
|
|
45
|
+
allowFontScaling: false,
|
|
46
|
+
children: title
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
49
|
+
...slot("month", { base: [styles$5.month, { width: `${100 / columns}%` }] }),
|
|
50
|
+
children: [
|
|
51
|
+
onPressMonth ? /* @__PURE__ */ jsx(Pressable, {
|
|
52
|
+
onPress: () => onPressMonth(month),
|
|
53
|
+
accessibilityRole: "button",
|
|
54
|
+
accessibilityLabel: monthLabel,
|
|
55
|
+
children: titleText
|
|
56
|
+
}) : /* @__PURE__ */ jsx(View, {
|
|
57
|
+
accessible: true,
|
|
58
|
+
accessibilityRole: "header",
|
|
59
|
+
accessibilityLabel: monthLabel,
|
|
60
|
+
children: titleText
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ jsx(View, {
|
|
63
|
+
...slot("weekdays", { base: styles$5.weekdays }),
|
|
64
|
+
accessibilityElementsHidden: true,
|
|
65
|
+
importantForAccessibility: "no-hide-descendants",
|
|
66
|
+
children: weekdayLabels.map((label, i) => /* @__PURE__ */ jsx(Text, {
|
|
67
|
+
...slot("weekday", {
|
|
68
|
+
base: styles$5.weekday,
|
|
69
|
+
themed: [styles$5.weekdayText, { color: theme.colors.textMuted }]
|
|
70
|
+
}),
|
|
71
|
+
allowFontScaling: false,
|
|
72
|
+
children: label
|
|
73
|
+
}, i))
|
|
74
|
+
}),
|
|
75
|
+
weeks.map((week) => /* @__PURE__ */ jsx(View, {
|
|
76
|
+
...slot("week", { base: styles$5.week }),
|
|
77
|
+
children: week.map((day) => {
|
|
78
|
+
if (day.getMonth() !== month.getMonth()) return /* @__PURE__ */ jsx(View, { style: styles$5.day }, day.toISOString());
|
|
79
|
+
const isHighlighted = activeDate ? isSameCalendarDay$1(day, activeDate) : getIsToday$1(day);
|
|
80
|
+
const hasEvents = eventDays.has(startOfDay(day).toISOString());
|
|
81
|
+
const label = `${format(day, "EEEE, d LLLL yyyy", { locale })}${getIsToday$1(day) ? ", today" : ""}${hasEvents ? ", has events" : ""}`;
|
|
82
|
+
const daySlot = slot("day", {
|
|
83
|
+
base: styles$5.day,
|
|
84
|
+
themed: isHighlighted ? {
|
|
85
|
+
backgroundColor: theme.colors.todayBackground,
|
|
86
|
+
borderRadius: theme.todayBadgeRadius
|
|
87
|
+
} : void 0
|
|
88
|
+
});
|
|
89
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, {
|
|
90
|
+
...slot("dayText", { themed: [styles$5.dayText, { color: isHighlighted ? theme.colors.todayText : theme.colors.text }] }),
|
|
91
|
+
allowFontScaling: false,
|
|
92
|
+
children: day.getDate()
|
|
93
|
+
}), hasEvents ? /* @__PURE__ */ jsx(View, { ...slot("eventDot", {
|
|
94
|
+
base: styles$5.eventDot,
|
|
95
|
+
themed: { backgroundColor: isHighlighted ? theme.colors.todayText : theme.colors.todayBackground }
|
|
96
|
+
}) }) : null] });
|
|
97
|
+
return onPressDay ? /* @__PURE__ */ jsx(Pressable, {
|
|
98
|
+
onPress: () => onPressDay(day),
|
|
99
|
+
accessibilityRole: "button",
|
|
100
|
+
accessibilityLabel: label,
|
|
101
|
+
...daySlot,
|
|
102
|
+
children: content
|
|
103
|
+
}, day.toISOString()) : /* @__PURE__ */ jsx(View, {
|
|
104
|
+
accessible: true,
|
|
105
|
+
accessibilityLabel: label,
|
|
106
|
+
...daySlot,
|
|
107
|
+
children: content
|
|
108
|
+
}, day.toISOString());
|
|
109
|
+
})
|
|
110
|
+
}, week[0].toISOString()))
|
|
111
|
+
]
|
|
112
|
+
}, month.toISOString());
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A year at a glance: the twelve months as compact mini grids, with today
|
|
119
|
+
* highlighted and a dot under days that hold events. Tap a day or a month
|
|
120
|
+
* title to drill into a denser view. It's the view `Calendar` renders for
|
|
121
|
+
* `mode="year"`.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* import { YearView } from "@super-calendar/native";
|
|
126
|
+
*
|
|
127
|
+
* <YearView
|
|
128
|
+
* date={new Date()}
|
|
129
|
+
* events={events}
|
|
130
|
+
* weekStartsOn={1}
|
|
131
|
+
* onPressDay={(day) => console.log(day)}
|
|
132
|
+
* />
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
const YearView = memo(YearViewInner);
|
|
136
|
+
const styles$5 = StyleSheet.create({
|
|
137
|
+
grid: {
|
|
138
|
+
flexDirection: "row",
|
|
139
|
+
flexWrap: "wrap"
|
|
140
|
+
},
|
|
141
|
+
month: { padding: 8 },
|
|
142
|
+
monthTitle: { paddingBottom: 4 },
|
|
143
|
+
monthTitleText: {
|
|
144
|
+
fontSize: 13,
|
|
145
|
+
fontWeight: "700"
|
|
146
|
+
},
|
|
147
|
+
weekdays: { flexDirection: "row" },
|
|
148
|
+
weekday: {
|
|
149
|
+
flex: 1,
|
|
150
|
+
textAlign: "center"
|
|
151
|
+
},
|
|
152
|
+
weekdayText: {
|
|
153
|
+
fontSize: 9,
|
|
154
|
+
fontWeight: "600"
|
|
155
|
+
},
|
|
156
|
+
week: { flexDirection: "row" },
|
|
157
|
+
day: {
|
|
158
|
+
flex: 1,
|
|
159
|
+
aspectRatio: 1,
|
|
160
|
+
alignItems: "center",
|
|
161
|
+
justifyContent: "center"
|
|
162
|
+
},
|
|
163
|
+
dayText: { fontSize: 11 },
|
|
164
|
+
eventDot: {
|
|
165
|
+
position: "absolute",
|
|
166
|
+
bottom: 1,
|
|
167
|
+
width: 3,
|
|
168
|
+
height: 3,
|
|
169
|
+
borderRadius: 2
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
//#endregion
|
|
10
173
|
//#region src/components/Agenda.tsx
|
|
11
174
|
/**
|
|
12
175
|
* A vertical, day-grouped list of events (no time grid). Events are sorted by
|
|
@@ -1565,11 +1728,13 @@ const styles$1 = StyleSheet.create({
|
|
|
1565
1728
|
const defaultKeyExtractor = (event) => `${event.start.toISOString()}|${event.end.toISOString()}|${event.title ?? ""}`;
|
|
1566
1729
|
function visibleRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
1567
1730
|
if (mode === "month") return [startOfWeek(startOfMonth(date), { weekStartsOn }), endOfWeek(endOfMonth(date), { weekStartsOn })];
|
|
1731
|
+
if (mode === "year") return [startOfWeek(startOfYear(date), { weekStartsOn }), endOfWeek(endOfYear(date), { weekStartsOn })];
|
|
1568
1732
|
const days = getViewDays$1(mode, date, weekStartsOn, numberOfDays, false, weekEndsOn);
|
|
1569
1733
|
return [startOfDay(days[0]), endOfDay(days[days.length - 1])];
|
|
1570
1734
|
}
|
|
1571
1735
|
function expansionRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
1572
1736
|
if (mode === "month") return [startOfWeek(startOfMonth(addMonths(date, -1)), { weekStartsOn }), addWeeks(endOfWeek(endOfMonth(addMonths(date, 1)), { weekStartsOn }), 1)];
|
|
1737
|
+
if (mode === "year") return [startOfWeek(startOfYear(date), { weekStartsOn }), endOfWeek(endOfYear(date), { weekStartsOn })];
|
|
1573
1738
|
if (mode === "schedule") return [startOfDay(date), endOfDay(addMonths(date, 3))];
|
|
1574
1739
|
const days = getViewDays$1(mode, date, weekStartsOn, numberOfDays, false, weekEndsOn);
|
|
1575
1740
|
const span = days.length;
|
|
@@ -1601,7 +1766,7 @@ function expansionRange(mode, date, weekStartsOn, numberOfDays, weekEndsOn) {
|
|
|
1601
1766
|
* }
|
|
1602
1767
|
* ```
|
|
1603
1768
|
*/
|
|
1604
|
-
function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn = 0, weekdayFormat, numberOfDays, weekEndsOn, renderEvent = DefaultEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor = defaultKeyExtractor, theme, cellHeight: cellHeightProp, hourHeight = 48, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }) {
|
|
1769
|
+
function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPressEvent, onLongPressEvent, onDragEvent, onDragStart, dragStepMinutes, showDragHandle, onPressDay, onPressMonth, onLongPressDay, onPressMore, onPressCell, resetPageOnPressCell, onLongPressCell, onCreateEvent, onPressDateHeader, maxVisibleEventCount, sortedMonthView, moreLabel, showAdjacentMonths, disableMonthEventCellPress, weekStartsOn = 0, weekdayFormat, numberOfDays, weekEndsOn, renderEvent = DefaultEvent, eventAccessibilityLabel, eventCellStyle, calendarCellStyle, businessHours, keyExtractor = defaultKeyExtractor, theme, cellHeight: cellHeightProp, hourHeight = 48, minHourHeight, maxHourHeight, hourColumnWidth, hideHours, timeslots, showAllDayEventCell, showWeekNumber, weekNumberPrefix, hourComponent, showSixWeeks, swipeEnabled, showVerticalScrollIndicator, verticalScrollEnabled, headerComponent, minHour, maxHour, ampm, showTime, ellipsizeTitle, allDayLabel, scrollOffsetMinutes, showNowIndicator, locale, timeZone, activeDate, isRTL, freeSwipe, renderTimeGridHeader, renderHeaderForMonthView, renderCustomDateForMonth, itemSeparatorComponent, classNames, styles: styleOverrides }) {
|
|
1605
1770
|
const mergedTheme = useMemo(() => mergeTheme(theme), [theme]);
|
|
1606
1771
|
const internalCellHeight = useSharedValue(hourHeight);
|
|
1607
1772
|
const cellHeight = cellHeightProp ?? internalCellHeight;
|
|
@@ -1702,6 +1867,16 @@ function Calendar({ events, mode, date, onChangeDate, onChangeDateRange, onPress
|
|
|
1702
1867
|
swipeEnabled,
|
|
1703
1868
|
classNames,
|
|
1704
1869
|
styles: styleOverrides
|
|
1870
|
+
}) : mode === "year" ? /* @__PURE__ */ jsx(YearView, {
|
|
1871
|
+
date,
|
|
1872
|
+
events: displayEvents,
|
|
1873
|
+
weekStartsOn,
|
|
1874
|
+
locale,
|
|
1875
|
+
activeDate,
|
|
1876
|
+
onPressDay,
|
|
1877
|
+
onPressMonth,
|
|
1878
|
+
classNames,
|
|
1879
|
+
styles: styleOverrides
|
|
1705
1880
|
}) : mode === "schedule" ? /* @__PURE__ */ jsx(Agenda, {
|
|
1706
1881
|
events: displayEvents,
|
|
1707
1882
|
locale,
|
|
@@ -2471,4 +2646,4 @@ const styles = StyleSheet.create({
|
|
|
2471
2646
|
}
|
|
2472
2647
|
});
|
|
2473
2648
|
//#endregion
|
|
2474
|
-
export { Agenda, Calendar, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, DefaultEvent, DefaultMonthEvent, MonthList, MonthPager, MonthView, ResourceTimeline, TimeGrid, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
|
2649
|
+
export { Agenda, Calendar, CalendarThemeProvider, DEFAULT_HOUR_HEIGHT, DefaultEvent, DefaultMonthEvent, MonthList, MonthPager, MonthView, ResourceTimeline, TimeGrid, YearView, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, eventsInTimeZone, expandRecurringEvents, getIsToday, getViewDays, getWeekDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, mergeTheme, minutesIntoDay, nextDateRange, parseICalendar, toICalendar, toZonedTime, useCalendarTheme, useDateRange, useMonthGrid, weekdayFormatToken };
|
package/dist/picker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_MonthList = require("./MonthList-
|
|
2
|
+
const require_MonthList = require("./MonthList-Gu6p64fE.js");
|
|
3
3
|
let _super_calendar_core = require("@super-calendar/core");
|
|
4
4
|
exports.CalendarThemeProvider = require_MonthList.CalendarThemeProvider;
|
|
5
5
|
exports.DefaultMonthEvent = require_MonthList.DefaultMonthEvent;
|
package/dist/picker.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { d as darkTheme, f as defaultTheme, i as MonthView, m as useCalendarTheme, n as DefaultMonthEvent, p as mergeTheme, r as MonthPager, t as MonthList, u as CalendarThemeProvider } from "./MonthList-
|
|
1
|
+
import { d as darkTheme, f as defaultTheme, i as MonthView, m as useCalendarTheme, n as DefaultMonthEvent, p as mergeTheme, r as MonthPager, t as MonthList, u as CalendarThemeProvider } from "./MonthList-CMzYn9T0.mjs";
|
|
2
2
|
import { buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
|
|
3
3
|
export { CalendarThemeProvider, DefaultMonthEvent, MonthList, MonthPager, MonthView, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@super-calendar/native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Gesture-driven, virtualized month / week / day calendar and date picker for React Native (and web via react-native-web).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agenda",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@super-calendar/core": "2.
|
|
67
|
+
"@super-calendar/core": "2.6.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@legendapp/list": ">=3",
|
|
@@ -5,10 +5,12 @@ import {
|
|
|
5
5
|
endOfDay,
|
|
6
6
|
endOfMonth,
|
|
7
7
|
endOfWeek,
|
|
8
|
+
endOfYear,
|
|
8
9
|
type Locale,
|
|
9
10
|
startOfDay,
|
|
10
11
|
startOfMonth,
|
|
11
12
|
startOfWeek,
|
|
13
|
+
startOfYear,
|
|
12
14
|
} from "date-fns";
|
|
13
15
|
import { type ReactElement, useCallback, useMemo } from "react";
|
|
14
16
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
getViewDays,
|
|
32
34
|
} from "@super-calendar/core";
|
|
33
35
|
import { type SlotStyleProps } from "../utils/slots";
|
|
36
|
+
import { YearView, type YearViewSlot } from "./YearView";
|
|
34
37
|
import { Agenda, type AgendaSlot } from "./Agenda";
|
|
35
38
|
import { DefaultEvent } from "./DefaultEvent";
|
|
36
39
|
import { MonthPager } from "./MonthPager";
|
|
@@ -49,7 +52,7 @@ import {
|
|
|
49
52
|
* month pager, the grid slots reach the time grid, and the agenda slots reach
|
|
50
53
|
* the schedule view; slots for views that aren't rendered are ignored.
|
|
51
54
|
*/
|
|
52
|
-
export type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot;
|
|
55
|
+
export type CalendarSlot = MonthViewSlot | TimeGridSlot | AgendaSlot | YearViewSlot;
|
|
53
56
|
|
|
54
57
|
/** Props for the {@link Calendar} component. */
|
|
55
58
|
export type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
@@ -85,8 +88,10 @@ export type CalendarProps<T> = SlotStyleProps<CalendarSlot> & {
|
|
|
85
88
|
* drag-to-move and drag-to-resize working while hiding the visible indicator.
|
|
86
89
|
*/
|
|
87
90
|
showDragHandle?: boolean;
|
|
88
|
-
/** Tap a day cell (month
|
|
91
|
+
/** Tap a day cell (month and year modes) — e.g. drill into the day view. */
|
|
89
92
|
onPressDay?: (date: Date) => void;
|
|
93
|
+
/** Tap a month's title in the year view — e.g. jump to that month. */
|
|
94
|
+
onPressMonth?: (month: Date) => void;
|
|
90
95
|
/** Long-press a day cell (month mode). */
|
|
91
96
|
onLongPressDay?: (date: Date) => void;
|
|
92
97
|
/** Tap the "+N more" overflow label in a month cell. */
|
|
@@ -261,6 +266,12 @@ function visibleRange(
|
|
|
261
266
|
endOfWeek(endOfMonth(date), { weekStartsOn }),
|
|
262
267
|
];
|
|
263
268
|
}
|
|
269
|
+
if (mode === "year") {
|
|
270
|
+
return [
|
|
271
|
+
startOfWeek(startOfYear(date), { weekStartsOn }),
|
|
272
|
+
endOfWeek(endOfYear(date), { weekStartsOn }),
|
|
273
|
+
];
|
|
274
|
+
}
|
|
264
275
|
const days = getViewDays(mode, date, weekStartsOn, numberOfDays, false, weekEndsOn);
|
|
265
276
|
return [startOfDay(days[0]), endOfDay(days[days.length - 1])];
|
|
266
277
|
}
|
|
@@ -283,6 +294,12 @@ function expansionRange(
|
|
|
283
294
|
addWeeks(endOfWeek(endOfMonth(addMonths(date, 1)), { weekStartsOn }), 1),
|
|
284
295
|
];
|
|
285
296
|
}
|
|
297
|
+
if (mode === "year") {
|
|
298
|
+
return [
|
|
299
|
+
startOfWeek(startOfYear(date), { weekStartsOn }),
|
|
300
|
+
endOfWeek(endOfYear(date), { weekStartsOn }),
|
|
301
|
+
];
|
|
302
|
+
}
|
|
286
303
|
if (mode === "schedule") {
|
|
287
304
|
// The agenda lists forward from the anchor date; three months is a sensible
|
|
288
305
|
// default look-ahead. Pre-expand for a different window.
|
|
@@ -332,6 +349,7 @@ export function Calendar<T>({
|
|
|
332
349
|
dragStepMinutes,
|
|
333
350
|
showDragHandle,
|
|
334
351
|
onPressDay,
|
|
352
|
+
onPressMonth,
|
|
335
353
|
onLongPressDay,
|
|
336
354
|
onPressMore,
|
|
337
355
|
onPressCell,
|
|
@@ -523,6 +541,18 @@ export function Calendar<T>({
|
|
|
523
541
|
classNames={classNames}
|
|
524
542
|
styles={styleOverrides}
|
|
525
543
|
/>
|
|
544
|
+
) : mode === "year" ? (
|
|
545
|
+
<YearView
|
|
546
|
+
date={date}
|
|
547
|
+
events={displayEvents}
|
|
548
|
+
weekStartsOn={weekStartsOn}
|
|
549
|
+
locale={locale}
|
|
550
|
+
activeDate={activeDate}
|
|
551
|
+
onPressDay={onPressDay}
|
|
552
|
+
onPressMonth={onPressMonth}
|
|
553
|
+
classNames={classNames}
|
|
554
|
+
styles={styleOverrides}
|
|
555
|
+
/>
|
|
526
556
|
) : mode === "schedule" ? (
|
|
527
557
|
<Agenda
|
|
528
558
|
events={displayEvents}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { format, startOfDay, type Locale } from "date-fns";
|
|
2
|
+
import { memo, type ReactElement, useMemo, useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
type LayoutChangeEvent,
|
|
5
|
+
Pressable,
|
|
6
|
+
ScrollView,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
Text,
|
|
9
|
+
View,
|
|
10
|
+
} from "react-native";
|
|
11
|
+
import { useCalendarTheme } from "../theme";
|
|
12
|
+
import type { CalendarEvent, WeekStartsOn } from "../types";
|
|
13
|
+
import { createSlots, type SlotStyleProps } from "../utils/slots";
|
|
14
|
+
import {
|
|
15
|
+
buildMonthWeeks,
|
|
16
|
+
getIsToday,
|
|
17
|
+
getWeekDays,
|
|
18
|
+
getYearMonths,
|
|
19
|
+
groupEventsByDay,
|
|
20
|
+
isSameCalendarDay,
|
|
21
|
+
weekdayFormatToken,
|
|
22
|
+
} from "@super-calendar/core";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The styleable parts of {@link YearView}. `dayText` and `eventDot` are the
|
|
26
|
+
* text/marker inside a day cell (React Native text colour doesn't inherit).
|
|
27
|
+
*/
|
|
28
|
+
export type YearViewSlot =
|
|
29
|
+
| "grid"
|
|
30
|
+
| "month"
|
|
31
|
+
| "monthTitle"
|
|
32
|
+
| "weekdays"
|
|
33
|
+
| "weekday"
|
|
34
|
+
| "week"
|
|
35
|
+
| "day"
|
|
36
|
+
| "dayText"
|
|
37
|
+
| "eventDot";
|
|
38
|
+
|
|
39
|
+
/** Props for {@link YearView}, the twelve mini-month year grid. */
|
|
40
|
+
export type YearViewProps<T = unknown> = SlotStyleProps<YearViewSlot> & {
|
|
41
|
+
/** Any date inside the year to render. */
|
|
42
|
+
date: Date;
|
|
43
|
+
/** Days holding at least one event get a dot. Omit for a plain year. */
|
|
44
|
+
events?: CalendarEvent<T>[];
|
|
45
|
+
weekStartsOn: WeekStartsOn;
|
|
46
|
+
locale?: Locale;
|
|
47
|
+
/** Highlight this date instead of the real "today". */
|
|
48
|
+
activeDate?: Date;
|
|
49
|
+
/**
|
|
50
|
+
* Smallest width a mini month may take before the grid drops a column
|
|
51
|
+
* (default 150). The grid fits 2–4 columns from the measured width.
|
|
52
|
+
*/
|
|
53
|
+
minMonthWidth?: number;
|
|
54
|
+
/** Tap a day cell (e.g. to drill into the day or month view). */
|
|
55
|
+
onPressDay?: (date: Date) => void;
|
|
56
|
+
/** Tap a month's title (e.g. to jump to that month's view). */
|
|
57
|
+
onPressMonth?: (month: Date) => void;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Seed before the first layout pass so the grid renders immediately (and in
|
|
61
|
+
// tests, where onLayout never fires).
|
|
62
|
+
const FALLBACK_COLUMNS = 3;
|
|
63
|
+
|
|
64
|
+
function YearViewInner<T>({
|
|
65
|
+
date,
|
|
66
|
+
events,
|
|
67
|
+
weekStartsOn,
|
|
68
|
+
locale,
|
|
69
|
+
activeDate,
|
|
70
|
+
minMonthWidth = 150,
|
|
71
|
+
onPressDay,
|
|
72
|
+
onPressMonth,
|
|
73
|
+
classNames,
|
|
74
|
+
styles: styleOverrides,
|
|
75
|
+
}: YearViewProps<T>): ReactElement {
|
|
76
|
+
const theme = useCalendarTheme();
|
|
77
|
+
const slot = createSlots<YearViewSlot>({ classNames, styles: styleOverrides });
|
|
78
|
+
|
|
79
|
+
const [columns, setColumns] = useState(FALLBACK_COLUMNS);
|
|
80
|
+
const handleLayout = (event: LayoutChangeEvent) => {
|
|
81
|
+
const width = event.nativeEvent.layout.width;
|
|
82
|
+
if (width <= 0) return;
|
|
83
|
+
setColumns(Math.max(2, Math.min(4, Math.floor(width / minMonthWidth))));
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const months = useMemo(() => getYearMonths(date), [date]);
|
|
87
|
+
// Weekday initials for one shared header per mini month.
|
|
88
|
+
const weekdayLabels = useMemo(
|
|
89
|
+
() =>
|
|
90
|
+
getWeekDays(date, weekStartsOn).map((d) =>
|
|
91
|
+
format(d, weekdayFormatToken("narrow"), { locale }),
|
|
92
|
+
),
|
|
93
|
+
[date, weekStartsOn, locale],
|
|
94
|
+
);
|
|
95
|
+
// Days that hold at least one event, keyed like `groupEventsByDay`.
|
|
96
|
+
const eventDays = useMemo(
|
|
97
|
+
() => new Set(events && events.length > 0 ? groupEventsByDay(events).keys() : []),
|
|
98
|
+
[events],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<ScrollView onLayout={handleLayout} showsVerticalScrollIndicator>
|
|
103
|
+
<View {...slot("grid", { base: styles.grid })}>
|
|
104
|
+
{months.map((month) => {
|
|
105
|
+
const weeks = buildMonthWeeks(month, weekStartsOn);
|
|
106
|
+
const title = format(month, "MMMM", { locale });
|
|
107
|
+
const monthLabel = format(month, "MMMM yyyy", { locale });
|
|
108
|
+
const titleText = (
|
|
109
|
+
<Text
|
|
110
|
+
{...slot("monthTitle", {
|
|
111
|
+
base: styles.monthTitle,
|
|
112
|
+
themed: [styles.monthTitleText, { color: theme.colors.todayBackground }],
|
|
113
|
+
})}
|
|
114
|
+
allowFontScaling={false}
|
|
115
|
+
>
|
|
116
|
+
{title}
|
|
117
|
+
</Text>
|
|
118
|
+
);
|
|
119
|
+
return (
|
|
120
|
+
<View
|
|
121
|
+
key={month.toISOString()}
|
|
122
|
+
{...slot("month", { base: [styles.month, { width: `${100 / columns}%` }] })}
|
|
123
|
+
>
|
|
124
|
+
{onPressMonth ? (
|
|
125
|
+
<Pressable
|
|
126
|
+
onPress={() => onPressMonth(month)}
|
|
127
|
+
accessibilityRole="button"
|
|
128
|
+
accessibilityLabel={monthLabel}
|
|
129
|
+
>
|
|
130
|
+
{titleText}
|
|
131
|
+
</Pressable>
|
|
132
|
+
) : (
|
|
133
|
+
<View accessible accessibilityRole="header" accessibilityLabel={monthLabel}>
|
|
134
|
+
{titleText}
|
|
135
|
+
</View>
|
|
136
|
+
)}
|
|
137
|
+
{/* Decorative initials: repeating 84 single letters across the twelve
|
|
138
|
+
mini months would drown a screen reader, so hide the rows (the
|
|
139
|
+
day cells carry full date labels). */}
|
|
140
|
+
<View
|
|
141
|
+
{...slot("weekdays", { base: styles.weekdays })}
|
|
142
|
+
accessibilityElementsHidden
|
|
143
|
+
importantForAccessibility="no-hide-descendants"
|
|
144
|
+
>
|
|
145
|
+
{weekdayLabels.map((label, i) => (
|
|
146
|
+
<Text
|
|
147
|
+
key={i}
|
|
148
|
+
{...slot("weekday", {
|
|
149
|
+
base: styles.weekday,
|
|
150
|
+
themed: [styles.weekdayText, { color: theme.colors.textMuted }],
|
|
151
|
+
})}
|
|
152
|
+
allowFontScaling={false}
|
|
153
|
+
>
|
|
154
|
+
{label}
|
|
155
|
+
</Text>
|
|
156
|
+
))}
|
|
157
|
+
</View>
|
|
158
|
+
{weeks.map((week) => (
|
|
159
|
+
<View key={week[0].toISOString()} {...slot("week", { base: styles.week })}>
|
|
160
|
+
{week.map((day) => {
|
|
161
|
+
// Adjacent-month days keep the grid shape but stay blank,
|
|
162
|
+
// like the mini months of other year views.
|
|
163
|
+
if (day.getMonth() !== month.getMonth()) {
|
|
164
|
+
return <View key={day.toISOString()} style={styles.day} />;
|
|
165
|
+
}
|
|
166
|
+
const isHighlighted = activeDate
|
|
167
|
+
? isSameCalendarDay(day, activeDate)
|
|
168
|
+
: getIsToday(day);
|
|
169
|
+
const hasEvents = eventDays.has(startOfDay(day).toISOString());
|
|
170
|
+
const label = `${format(day, "EEEE, d LLLL yyyy", { locale })}${
|
|
171
|
+
getIsToday(day) ? ", today" : ""
|
|
172
|
+
}${hasEvents ? ", has events" : ""}`;
|
|
173
|
+
const daySlot = slot("day", {
|
|
174
|
+
base: styles.day,
|
|
175
|
+
themed: isHighlighted
|
|
176
|
+
? {
|
|
177
|
+
backgroundColor: theme.colors.todayBackground,
|
|
178
|
+
borderRadius: theme.todayBadgeRadius,
|
|
179
|
+
}
|
|
180
|
+
: undefined,
|
|
181
|
+
});
|
|
182
|
+
const content = (
|
|
183
|
+
<>
|
|
184
|
+
<Text
|
|
185
|
+
{...slot("dayText", {
|
|
186
|
+
themed: [
|
|
187
|
+
styles.dayText,
|
|
188
|
+
{
|
|
189
|
+
color: isHighlighted ? theme.colors.todayText : theme.colors.text,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
})}
|
|
193
|
+
allowFontScaling={false}
|
|
194
|
+
>
|
|
195
|
+
{day.getDate()}
|
|
196
|
+
</Text>
|
|
197
|
+
{hasEvents ? (
|
|
198
|
+
<View
|
|
199
|
+
{...slot("eventDot", {
|
|
200
|
+
base: styles.eventDot,
|
|
201
|
+
themed: {
|
|
202
|
+
backgroundColor: isHighlighted
|
|
203
|
+
? theme.colors.todayText
|
|
204
|
+
: theme.colors.todayBackground,
|
|
205
|
+
},
|
|
206
|
+
})}
|
|
207
|
+
/>
|
|
208
|
+
) : null}
|
|
209
|
+
</>
|
|
210
|
+
);
|
|
211
|
+
return onPressDay ? (
|
|
212
|
+
<Pressable
|
|
213
|
+
key={day.toISOString()}
|
|
214
|
+
onPress={() => onPressDay(day)}
|
|
215
|
+
accessibilityRole="button"
|
|
216
|
+
accessibilityLabel={label}
|
|
217
|
+
{...daySlot}
|
|
218
|
+
>
|
|
219
|
+
{content}
|
|
220
|
+
</Pressable>
|
|
221
|
+
) : (
|
|
222
|
+
<View
|
|
223
|
+
key={day.toISOString()}
|
|
224
|
+
accessible
|
|
225
|
+
accessibilityLabel={label}
|
|
226
|
+
{...daySlot}
|
|
227
|
+
>
|
|
228
|
+
{content}
|
|
229
|
+
</View>
|
|
230
|
+
);
|
|
231
|
+
})}
|
|
232
|
+
</View>
|
|
233
|
+
))}
|
|
234
|
+
</View>
|
|
235
|
+
);
|
|
236
|
+
})}
|
|
237
|
+
</View>
|
|
238
|
+
</ScrollView>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A year at a glance: the twelve months as compact mini grids, with today
|
|
244
|
+
* highlighted and a dot under days that hold events. Tap a day or a month
|
|
245
|
+
* title to drill into a denser view. It's the view `Calendar` renders for
|
|
246
|
+
* `mode="year"`.
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```tsx
|
|
250
|
+
* import { YearView } from "@super-calendar/native";
|
|
251
|
+
*
|
|
252
|
+
* <YearView
|
|
253
|
+
* date={new Date()}
|
|
254
|
+
* events={events}
|
|
255
|
+
* weekStartsOn={1}
|
|
256
|
+
* onPressDay={(day) => console.log(day)}
|
|
257
|
+
* />
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export const YearView = memo(YearViewInner) as typeof YearViewInner;
|
|
261
|
+
|
|
262
|
+
const styles = StyleSheet.create({
|
|
263
|
+
grid: { flexDirection: "row", flexWrap: "wrap" },
|
|
264
|
+
month: { padding: 8 },
|
|
265
|
+
// Structural layout / themed typography split per slot, so a slot class can
|
|
266
|
+
// replace the look without breaking the layout.
|
|
267
|
+
monthTitle: { paddingBottom: 4 },
|
|
268
|
+
monthTitleText: { fontSize: 13, fontWeight: "700" },
|
|
269
|
+
weekdays: { flexDirection: "row" },
|
|
270
|
+
weekday: { flex: 1, textAlign: "center" },
|
|
271
|
+
weekdayText: { fontSize: 9, fontWeight: "600" },
|
|
272
|
+
week: { flexDirection: "row" },
|
|
273
|
+
day: { flex: 1, aspectRatio: 1, alignItems: "center", justifyContent: "center" },
|
|
274
|
+
dayText: { fontSize: 11 },
|
|
275
|
+
eventDot: { position: "absolute", bottom: 1, width: 3, height: 3, borderRadius: 2 },
|
|
276
|
+
});
|
package/src/index.tsx
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
export { Calendar, type CalendarProps, type CalendarSlot } from "./components/Calendar";
|
|
24
24
|
export { Agenda, type AgendaProps, type AgendaSlot } from "./components/Agenda";
|
|
25
25
|
export { MonthView, type MonthViewProps, type MonthViewSlot } from "./components/MonthView";
|
|
26
|
+
export { YearView, type YearViewProps, type YearViewSlot } from "./components/YearView";
|
|
26
27
|
export { type ResolvedSlot, type SlotDefault, type SlotStyleProps } from "./utils/slots";
|
|
27
28
|
export { MonthPager, type MonthPagerProps } from "./components/MonthPager";
|
|
28
29
|
export { MonthList, type MonthListProps, type MonthListSlot } from "./components/MonthList";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { addMonths, differenceInCalendarMonths, format, isSameMonth, startOfDay, startOfMonth } from "date-fns";
|
|
2
2
|
import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { CalendarSelectionProvider, buildMonthWeeks, compareDayEvents, darkColors, dayBadgeKind, daySelectionState, eventAccessibilityLabel, eventTimeLabel, getIsToday, getWeekDays, groupEventsByDay, isAllDayEvent, isDateSelectable, isSameCalendarDay, isWeekend, lightColors, monthEventCapacity, monthVisibleCount, rangeBandKind, titleEllipsizeMode, titleNumberOfLines, useCalendarSelection, weekdayFormatToken } from "@super-calendar/core";
|
|
4
|
-
import { LegendList } from "@legendapp/list/react-native";
|
|
5
4
|
import { Platform, StyleSheet, Text, TouchableOpacity, View, useWindowDimensions } from "react-native";
|
|
6
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { LegendList } from "@legendapp/list/react-native";
|
|
7
7
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
8
8
|
//#region src/theme.ts
|
|
9
9
|
/** The default light theme. Every key the calendar reads falls back to this. */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
let date_fns = require("date-fns");
|
|
2
2
|
let react = require("react");
|
|
3
3
|
let _super_calendar_core = require("@super-calendar/core");
|
|
4
|
-
let _legendapp_list_react_native = require("@legendapp/list/react-native");
|
|
5
4
|
let react_native = require("react-native");
|
|
6
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
let _legendapp_list_react_native = require("@legendapp/list/react-native");
|
|
7
7
|
let react_native_gesture_handler = require("react-native-gesture-handler");
|
|
8
8
|
//#region src/theme.ts
|
|
9
9
|
/** The default light theme. Every key the calendar reads falls back to this. */
|