@super-calendar/native 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import { C as defaultTheme, S as darkTheme, T as useCalendarTheme, a as MonthPagerProps, b as CalendarThemeProvider, d as EventKeyExtractor, f as ICalendarEvent, g as RenderEventArgs, h as RenderEvent, i as MonthPager, l as CalendarEvent, n as MonthList, o as MonthView, r as MonthListProps, s as MonthViewProps, t as DefaultMonthEvent, u as CalendarMode, v as WeekStartsOn, w as mergeTheme, x as PartialCalendarTheme, y as CalendarTheme } from "./DefaultMonthEvent-CpRoOloh.mjs";
2
+ import { DateRange, DateSelectionConstraints, DaySelectionState, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, UseDateRangeOptions, UseMonthGridOptions, buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
3
+ export { type CalendarEvent, type CalendarMode, type CalendarTheme, CalendarThemeProvider, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultMonthEvent, type EventKeyExtractor, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type PartialCalendarTheme, type RenderEvent, type RenderEventArgs, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
@@ -0,0 +1,3 @@
1
+ import { C as defaultTheme, S as darkTheme, T as useCalendarTheme, a as MonthPagerProps, b as CalendarThemeProvider, d as EventKeyExtractor, f as ICalendarEvent, g as RenderEventArgs, h as RenderEvent, i as MonthPager, l as CalendarEvent, n as MonthList, o as MonthView, r as MonthListProps, s as MonthViewProps, t as DefaultMonthEvent, u as CalendarMode, v as WeekStartsOn, w as mergeTheme, x as PartialCalendarTheme, y as CalendarTheme } from "./DefaultMonthEvent-86XCNCge.js";
2
+ import { DateRange, DateSelectionConstraints, DaySelectionState, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, UseDateRangeOptions, UseMonthGridOptions, buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
3
+ export { type CalendarEvent, type CalendarMode, type CalendarTheme, CalendarThemeProvider, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultMonthEvent, type EventKeyExtractor, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type PartialCalendarTheme, type RenderEvent, type RenderEventArgs, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
package/dist/picker.js ADDED
@@ -0,0 +1,96 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_MonthList = require("./MonthList-BCfN-UGz.js");
3
+ let _super_calendar_core = require("@super-calendar/core");
4
+ exports.CalendarThemeProvider = require_MonthList.CalendarThemeProvider;
5
+ exports.DefaultMonthEvent = require_MonthList.DefaultMonthEvent;
6
+ exports.MonthList = require_MonthList.MonthList;
7
+ exports.MonthPager = require_MonthList.MonthPager;
8
+ exports.MonthView = require_MonthList.MonthView;
9
+ Object.defineProperty(exports, "buildMonthGrid", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return _super_calendar_core.buildMonthGrid;
13
+ }
14
+ });
15
+ Object.defineProperty(exports, "buildMonthWeeks", {
16
+ enumerable: true,
17
+ get: function() {
18
+ return _super_calendar_core.buildMonthWeeks;
19
+ }
20
+ });
21
+ exports.darkTheme = require_MonthList.darkTheme;
22
+ Object.defineProperty(exports, "daySelectionState", {
23
+ enumerable: true,
24
+ get: function() {
25
+ return _super_calendar_core.daySelectionState;
26
+ }
27
+ });
28
+ exports.defaultTheme = require_MonthList.defaultTheme;
29
+ Object.defineProperty(exports, "getIsToday", {
30
+ enumerable: true,
31
+ get: function() {
32
+ return _super_calendar_core.getIsToday;
33
+ }
34
+ });
35
+ Object.defineProperty(exports, "getWeekDays", {
36
+ enumerable: true,
37
+ get: function() {
38
+ return _super_calendar_core.getWeekDays;
39
+ }
40
+ });
41
+ Object.defineProperty(exports, "isDateSelectable", {
42
+ enumerable: true,
43
+ get: function() {
44
+ return _super_calendar_core.isDateSelectable;
45
+ }
46
+ });
47
+ Object.defineProperty(exports, "isRangeEndpoint", {
48
+ enumerable: true,
49
+ get: function() {
50
+ return _super_calendar_core.isRangeEndpoint;
51
+ }
52
+ });
53
+ Object.defineProperty(exports, "isSameCalendarDay", {
54
+ enumerable: true,
55
+ get: function() {
56
+ return _super_calendar_core.isSameCalendarDay;
57
+ }
58
+ });
59
+ Object.defineProperty(exports, "isWeekend", {
60
+ enumerable: true,
61
+ get: function() {
62
+ return _super_calendar_core.isWeekend;
63
+ }
64
+ });
65
+ Object.defineProperty(exports, "isWithinDateRange", {
66
+ enumerable: true,
67
+ get: function() {
68
+ return _super_calendar_core.isWithinDateRange;
69
+ }
70
+ });
71
+ exports.mergeTheme = require_MonthList.mergeTheme;
72
+ Object.defineProperty(exports, "minutesIntoDay", {
73
+ enumerable: true,
74
+ get: function() {
75
+ return _super_calendar_core.minutesIntoDay;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, "nextDateRange", {
79
+ enumerable: true,
80
+ get: function() {
81
+ return _super_calendar_core.nextDateRange;
82
+ }
83
+ });
84
+ exports.useCalendarTheme = require_MonthList.useCalendarTheme;
85
+ Object.defineProperty(exports, "useDateRange", {
86
+ enumerable: true,
87
+ get: function() {
88
+ return _super_calendar_core.useDateRange;
89
+ }
90
+ });
91
+ Object.defineProperty(exports, "useMonthGrid", {
92
+ enumerable: true,
93
+ get: function() {
94
+ return _super_calendar_core.useMonthGrid;
95
+ }
96
+ });
@@ -0,0 +1,3 @@
1
+ import { c as defaultTheme, i as MonthView, l as mergeTheme, n as DefaultMonthEvent, o as CalendarThemeProvider, r as MonthPager, s as darkTheme, t as MonthList, u as useCalendarTheme } from "./MonthList-CyrEJ_U6.mjs";
2
+ import { buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
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 ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@super-calendar/native",
3
+ "version": "2.0.0",
4
+ "description": "Gesture-driven, virtualized month / week / day calendar and date picker for React Native (and web via react-native-web).",
5
+ "keywords": [
6
+ "agenda",
7
+ "calendar",
8
+ "date-picker",
9
+ "expo",
10
+ "month-view",
11
+ "range-picker",
12
+ "react-native",
13
+ "reanimated",
14
+ "timetable",
15
+ "week-view"
16
+ ],
17
+ "homepage": "https://github.com/afonsojramos/react-native-super-calendar#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/afonsojramos/react-native-super-calendar/issues"
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/afonsojramos/react-native-super-calendar.git",
25
+ "directory": "packages/native"
26
+ },
27
+ "source": "./src/index.tsx",
28
+ "files": [
29
+ "dist",
30
+ "src",
31
+ "!**/__tests__"
32
+ ],
33
+ "sideEffects": false,
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.mjs",
36
+ "types": "./dist/index.d.ts",
37
+ "react-native": "./src/index.tsx",
38
+ "exports": {
39
+ ".": {
40
+ "react-native": "./src/index.tsx",
41
+ "import": {
42
+ "types": "./dist/index.d.mts",
43
+ "default": "./dist/index.mjs"
44
+ },
45
+ "require": {
46
+ "types": "./dist/index.d.ts",
47
+ "default": "./dist/index.js"
48
+ }
49
+ },
50
+ "./picker": {
51
+ "react-native": "./src/picker.tsx",
52
+ "import": {
53
+ "types": "./dist/picker.d.mts",
54
+ "default": "./dist/picker.mjs"
55
+ },
56
+ "require": {
57
+ "types": "./dist/picker.d.ts",
58
+ "default": "./dist/picker.js"
59
+ }
60
+ },
61
+ "./package.json": "./package.json"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public"
65
+ },
66
+ "dependencies": {
67
+ "@super-calendar/core": "2.0.0"
68
+ },
69
+ "peerDependencies": {
70
+ "@legendapp/list": ">=3",
71
+ "date-fns": ">=3",
72
+ "react": ">=18",
73
+ "react-native": ">=0.74",
74
+ "react-native-gesture-handler": ">=2.16",
75
+ "react-native-reanimated": ">=4.0.0 <5",
76
+ "react-native-worklets": ">=0.5"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "react-native-gesture-handler": {
80
+ "optional": true
81
+ },
82
+ "react-native-reanimated": {
83
+ "optional": true
84
+ },
85
+ "react-native-worklets": {
86
+ "optional": true
87
+ }
88
+ },
89
+ "scripts": {
90
+ "build": "tsdown"
91
+ }
92
+ }
@@ -0,0 +1,133 @@
1
+ import { LegendList, type LegendListRenderItemProps } from "@legendapp/list/react-native";
2
+ import { format, isSameDay, type Locale, startOfDay } from "date-fns";
3
+ import { type ComponentType, useCallback, useMemo } from "react";
4
+ import { StyleSheet, Text, View } from "react-native";
5
+ import { useCalendarTheme } from "../theme";
6
+ import type { CalendarEvent, EventKeyExtractor, RenderEvent } from "../types";
7
+ import { getIsToday } from "@super-calendar/core";
8
+ import { isAllDayEvent } from "@super-calendar/core";
9
+
10
+ export type AgendaProps<T> = {
11
+ events: CalendarEvent<T>[];
12
+ locale?: Locale;
13
+ renderEvent: RenderEvent<T>;
14
+ keyExtractor: EventKeyExtractor<T>;
15
+ onPressEvent: (event: CalendarEvent<T>) => void;
16
+ onLongPressEvent?: (event: CalendarEvent<T>) => void;
17
+ onPressDay?: (date: Date) => void;
18
+ /** Highlight this date's header instead of the real "today". */
19
+ activeDate?: Date;
20
+ /** Drawn between rows of the agenda list. */
21
+ itemSeparatorComponent?: ComponentType<unknown> | null;
22
+ };
23
+
24
+ type Row<T> =
25
+ | { kind: "header"; date: Date; key: string }
26
+ | { kind: "event"; event: CalendarEvent<T>; index: number; key: string };
27
+
28
+ /**
29
+ * A vertical, day-grouped list of events (no time grid). Events are sorted by
30
+ * start, grouped under a date header per day. The consumer controls which
31
+ * events (and therefore which date range) are shown.
32
+ */
33
+ export function Agenda<T>({
34
+ events,
35
+ locale,
36
+ renderEvent,
37
+ keyExtractor,
38
+ onPressEvent,
39
+ onLongPressEvent,
40
+ onPressDay,
41
+ activeDate,
42
+ itemSeparatorComponent,
43
+ }: AgendaProps<T>) {
44
+ const theme = useCalendarTheme();
45
+ const RenderEventComponent = renderEvent;
46
+
47
+ const rows = useMemo<Row<T>[]>(() => {
48
+ const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
49
+ const out: Row<T>[] = [];
50
+ let currentDay: Date | null = null;
51
+ sorted.forEach((event, index) => {
52
+ if (!currentDay || !isSameDay(event.start, currentDay)) {
53
+ currentDay = startOfDay(event.start);
54
+ out.push({ kind: "header", date: currentDay, key: `h-${currentDay.toISOString()}` });
55
+ }
56
+ out.push({ kind: "event", event, index, key: `e-${keyExtractor(event, index)}` });
57
+ });
58
+ return out;
59
+ }, [events, keyExtractor]);
60
+
61
+ const keyExtractorRow = useCallback((row: Row<T>) => row.key, []);
62
+ const renderItem = useCallback(
63
+ ({ item }: LegendListRenderItemProps<Row<T>>) => {
64
+ if (item.kind === "header") {
65
+ const isHighlighted = activeDate ? isSameDay(item.date, activeDate) : getIsToday(item.date);
66
+ return (
67
+ <Text
68
+ style={[
69
+ styles.header,
70
+ { color: isHighlighted ? theme.colors.todayBackground : theme.colors.textMuted },
71
+ ]}
72
+ onPress={onPressDay ? () => onPressDay(item.date) : undefined}
73
+ accessibilityRole={onPressDay ? "button" : "header"}
74
+ >
75
+ {format(item.date, "EEEE, d LLLL", { locale })}
76
+ </Text>
77
+ );
78
+ }
79
+ return (
80
+ <View style={styles.eventRow}>
81
+ <RenderEventComponent
82
+ event={item.event}
83
+ mode="schedule"
84
+ isAllDay={isAllDayEvent(item.event)}
85
+ onPress={() => onPressEvent(item.event)}
86
+ onLongPress={onLongPressEvent ? () => onLongPressEvent(item.event) : undefined}
87
+ />
88
+ </View>
89
+ );
90
+ },
91
+ [theme, locale, activeDate, onPressDay, onPressEvent, onLongPressEvent, RenderEventComponent],
92
+ );
93
+
94
+ if (rows.length === 0) {
95
+ return <Text style={[styles.empty, { color: theme.colors.textMuted }]}>No events</Text>;
96
+ }
97
+
98
+ return (
99
+ <LegendList
100
+ style={styles.list}
101
+ data={rows}
102
+ keyExtractor={keyExtractorRow}
103
+ renderItem={renderItem}
104
+ // The public prop is data-agnostic; LegendList types the separator by row.
105
+ ItemSeparatorComponent={
106
+ (itemSeparatorComponent ?? undefined) as ComponentType<{ leadingItem: Row<T> }> | undefined
107
+ }
108
+ recycleItems={false}
109
+ />
110
+ );
111
+ }
112
+
113
+ const styles = StyleSheet.create({
114
+ list: {
115
+ flex: 1,
116
+ },
117
+ header: {
118
+ fontSize: 13,
119
+ fontWeight: "600",
120
+ paddingTop: 12,
121
+ paddingBottom: 4,
122
+ paddingHorizontal: 12,
123
+ },
124
+ eventRow: {
125
+ paddingHorizontal: 12,
126
+ paddingVertical: 2,
127
+ },
128
+ empty: {
129
+ fontSize: 14,
130
+ paddingVertical: 16,
131
+ paddingHorizontal: 12,
132
+ },
133
+ });
@@ -0,0 +1,98 @@
1
+ import { addDays, startOfDay } from "date-fns";
2
+ import { StyleSheet, Text, View } from "react-native";
3
+ import { useCalendarTheme } from "../theme";
4
+ import type { CalendarEvent, CalendarMode, EventKeyExtractor, RenderEvent } from "../types";
5
+ import { isAllDayEvent } from "@super-calendar/core";
6
+
7
+ type AllDayLaneProps<T> = {
8
+ days: Date[];
9
+ events: CalendarEvent<T>[];
10
+ mode: CalendarMode;
11
+ hourColumnWidth: number;
12
+ dayWidth: number;
13
+ renderEvent: RenderEvent<T>;
14
+ keyExtractor: EventKeyExtractor<T>;
15
+ onPressEvent: (event: CalendarEvent<T>) => void;
16
+ onLongPressEvent?: (event: CalendarEvent<T>) => void;
17
+ };
18
+
19
+ /**
20
+ * The all-day lane that sits above the scrolling time grid. All-day events are
21
+ * excluded from the timed columns (see `layoutDayEvents`) and shown here,
22
+ * stacked under their day(s). Renders nothing when no day has an all-day event,
23
+ * so timed-only calendars are unaffected.
24
+ */
25
+ export function AllDayLane<T>({
26
+ days,
27
+ events,
28
+ mode,
29
+ hourColumnWidth,
30
+ dayWidth,
31
+ renderEvent,
32
+ keyExtractor,
33
+ onPressEvent,
34
+ onLongPressEvent,
35
+ }: AllDayLaneProps<T>) {
36
+ const theme = useCalendarTheme();
37
+ const RenderEventComponent = renderEvent;
38
+
39
+ const allDay = events.filter(isAllDayEvent);
40
+ const perDay = days.map((day) => {
41
+ const start = startOfDay(day);
42
+ const next = addDays(start, 1);
43
+ return allDay.filter((event) => event.start < next && event.end > start);
44
+ });
45
+
46
+ if (perDay.every((list) => list.length === 0)) return null;
47
+
48
+ return (
49
+ <View style={[styles.lane, { borderBottomColor: theme.colors.gridLine }]}>
50
+ <View style={[styles.gutter, { width: hourColumnWidth }]}>
51
+ {/* The "all-day" gutter label, mirroring the dom renderer: small, muted,
52
+ and right-aligned against the timed columns. Centered vertically so it
53
+ lines up with the chips whether the lane holds one event or several. */}
54
+ <Text style={[styles.label, { color: theme.colors.textMuted }]} allowFontScaling={false}>
55
+ all-day
56
+ </Text>
57
+ </View>
58
+ {days.map((day, dayIndex) => (
59
+ <View key={day.toISOString()} style={[styles.column, { width: dayWidth }]}>
60
+ {perDay[dayIndex].map((event, index) => (
61
+ <View key={keyExtractor(event, index)} style={styles.chip}>
62
+ <RenderEventComponent
63
+ event={event}
64
+ mode={mode}
65
+ isAllDay
66
+ onPress={() => onPressEvent(event)}
67
+ onLongPress={onLongPressEvent ? () => onLongPressEvent(event) : undefined}
68
+ />
69
+ </View>
70
+ ))}
71
+ </View>
72
+ ))}
73
+ </View>
74
+ );
75
+ }
76
+
77
+ const styles = StyleSheet.create({
78
+ lane: {
79
+ flexDirection: "row",
80
+ borderBottomWidth: StyleSheet.hairlineWidth,
81
+ },
82
+ gutter: {
83
+ justifyContent: "center",
84
+ },
85
+ label: {
86
+ fontSize: 10,
87
+ textAlign: "right",
88
+ paddingRight: 6,
89
+ },
90
+ column: {
91
+ paddingVertical: 2,
92
+ paddingHorizontal: 1,
93
+ gap: 2,
94
+ },
95
+ chip: {
96
+ minHeight: 18,
97
+ },
98
+ });