@super-calendar/native 2.0.0 → 2.1.2
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 +75 -0
- package/dist/{DefaultMonthEvent-86XCNCge.d.ts → DefaultMonthEvent-D2s0x2Bn.d.mts} +79 -6
- package/dist/{DefaultMonthEvent-CpRoOloh.d.mts → DefaultMonthEvent-DaTEIcRs.d.ts} +79 -6
- package/dist/{MonthList-CyrEJ_U6.mjs → MonthList-DXvjxiyu.mjs} +59 -0
- package/dist/{MonthList-BCfN-UGz.js → MonthList-oXiArmbu.js} +59 -0
- package/dist/index.d.mts +55 -6
- package/dist/index.d.ts +55 -6
- package/dist/index.js +57 -8
- package/dist/index.mjs +57 -8
- package/dist/picker.d.mts +1 -1
- package/dist/picker.d.ts +1 -1
- package/dist/picker.js +1 -1
- package/dist/picker.mjs +1 -1
- package/package.json +5 -5
- package/src/components/Agenda.tsx +3 -2
- package/src/components/Calendar.tsx +29 -2
- package/src/components/DefaultEvent.tsx +2 -1
- package/src/components/DefaultMonthEvent.tsx +2 -1
- package/src/components/MonthList.tsx +21 -2
- package/src/components/MonthPager.tsx +21 -2
- package/src/components/MonthView.tsx +19 -2
- package/src/components/TimeGrid.tsx +42 -10
- package/src/index.tsx +22 -0
- package/src/picker.tsx +17 -4
- package/src/theme.ts +16 -3
- package/src/types.ts +5 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
1
2
|
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
2
3
|
import { useCalendarTheme } from "../theme";
|
|
3
4
|
import type { RenderEventArgs } from "../types";
|
|
@@ -26,7 +27,7 @@ export function DefaultMonthEvent<T>({
|
|
|
26
27
|
cellStyle,
|
|
27
28
|
onPress,
|
|
28
29
|
onLongPress,
|
|
29
|
-
}: RenderEventArgs<T>) {
|
|
30
|
+
}: RenderEventArgs<T>): ReactElement {
|
|
30
31
|
const theme = useCalendarTheme();
|
|
31
32
|
const isAllDayEvent = isAllDay ?? false;
|
|
32
33
|
const timeLabel = eventTimeLabel({
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type Locale,
|
|
13
13
|
startOfMonth,
|
|
14
14
|
} from "date-fns";
|
|
15
|
-
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
15
|
+
import { memo, type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
16
16
|
import {
|
|
17
17
|
type LayoutChangeEvent,
|
|
18
18
|
type NativeScrollEvent,
|
|
@@ -69,6 +69,7 @@ const noop = () => {};
|
|
|
69
69
|
const defaultKeyExtractor: EventKeyExtractor<unknown> = (event) =>
|
|
70
70
|
`${event.start.toISOString()}|${event.end.toISOString()}|${event.title ?? ""}`;
|
|
71
71
|
|
|
72
|
+
/** Props for {@link MonthList}, the vertically scrolling list of months. */
|
|
72
73
|
export type MonthListProps<T> = {
|
|
73
74
|
/** The month scrolled to on mount. */
|
|
74
75
|
date: Date;
|
|
@@ -155,7 +156,7 @@ function MonthListInner<T>({
|
|
|
155
156
|
onSelectDrag,
|
|
156
157
|
onChangeVisibleMonth,
|
|
157
158
|
renderMonthHeader,
|
|
158
|
-
}: MonthListProps<T>) {
|
|
159
|
+
}: MonthListProps<T>): ReactElement {
|
|
159
160
|
const theme = useCalendarTheme();
|
|
160
161
|
const listRef = useRef<LegendListRef>(null);
|
|
161
162
|
|
|
@@ -553,6 +554,24 @@ function MonthBlock({
|
|
|
553
554
|
);
|
|
554
555
|
}
|
|
555
556
|
|
|
557
|
+
/**
|
|
558
|
+
* A vertically scrolling, virtualized list of month grids. It doubles as the
|
|
559
|
+
* date picker: pass `selectedRange`/`selectedDates` and selection handlers to
|
|
560
|
+
* turn it into a single-date or range picker. Free of Reanimated, so the
|
|
561
|
+
* `/picker` entry point can ship it without the timetable views.
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* ```tsx
|
|
565
|
+
* import { MonthList } from "react-native-super-calendar/picker";
|
|
566
|
+
*
|
|
567
|
+
* <MonthList
|
|
568
|
+
* date={new Date()}
|
|
569
|
+
* weekStartsOn={0}
|
|
570
|
+
* selectedRange={range}
|
|
571
|
+
* onPressDay={handlePressDay}
|
|
572
|
+
* />
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
556
575
|
export const MonthList = memo(MonthListInner) as typeof MonthListInner;
|
|
557
576
|
|
|
558
577
|
const styles = StyleSheet.create({
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type OnViewableItemsChangedInfo,
|
|
6
6
|
} from "@legendapp/list/react-native";
|
|
7
7
|
import { addMonths, differenceInCalendarMonths, format, type Locale, startOfMonth } from "date-fns";
|
|
8
|
-
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { memo, type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
9
9
|
import {
|
|
10
10
|
Platform,
|
|
11
11
|
StyleSheet,
|
|
@@ -34,6 +34,7 @@ const PAGE_WINDOW = 60;
|
|
|
34
34
|
// paging commits once per settle rather than mid-swipe.
|
|
35
35
|
const PAGE_VIEWABILITY = { itemVisiblePercentThreshold: 90 };
|
|
36
36
|
|
|
37
|
+
/** Props for {@link MonthPager}, the horizontally swipeable month carousel. */
|
|
37
38
|
export type MonthPagerProps<T> = {
|
|
38
39
|
date: Date;
|
|
39
40
|
events: CalendarEvent<T>[];
|
|
@@ -90,7 +91,7 @@ function MonthPagerInner<T>({
|
|
|
90
91
|
activeDate,
|
|
91
92
|
renderHeaderForMonthView,
|
|
92
93
|
renderCustomDateForMonth,
|
|
93
|
-
}: MonthPagerProps<T>) {
|
|
94
|
+
}: MonthPagerProps<T>): ReactElement {
|
|
94
95
|
const theme = useCalendarTheme();
|
|
95
96
|
const { width, height } = useWindowDimensions();
|
|
96
97
|
const listRef = useRef<LegendListRef>(null);
|
|
@@ -318,6 +319,24 @@ function MonthPagerInner<T>({
|
|
|
318
319
|
);
|
|
319
320
|
}
|
|
320
321
|
|
|
322
|
+
/**
|
|
323
|
+
* A horizontally swipeable month carousel. Swipe left/right to page between
|
|
324
|
+
* months; the committed month is reported through `onChangeDate`. It is the
|
|
325
|
+
* Reanimated-driven month view that `Calendar` uses in month mode.
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```tsx
|
|
329
|
+
* import { MonthPager } from "react-native-super-calendar";
|
|
330
|
+
*
|
|
331
|
+
* <MonthPager
|
|
332
|
+
* date={date}
|
|
333
|
+
* events={events}
|
|
334
|
+
* weekStartsOn={0}
|
|
335
|
+
* onChangeDate={setDate}
|
|
336
|
+
* onPressEvent={(e) => console.log(e.title)}
|
|
337
|
+
* />
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
321
340
|
export const MonthPager = memo(MonthPagerInner) as typeof MonthPagerInner;
|
|
322
341
|
|
|
323
342
|
type MonthWeekdayHeaderProps = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { format, type Locale, isSameMonth, startOfDay } from "date-fns";
|
|
2
|
-
import { memo, useMemo, useState } from "react";
|
|
2
|
+
import { memo, type ReactElement, useMemo, useState } from "react";
|
|
3
3
|
import {
|
|
4
4
|
type LayoutChangeEvent,
|
|
5
5
|
Platform,
|
|
@@ -42,6 +42,7 @@ const FALLBACK_VISIBLE_COUNT = 3;
|
|
|
42
42
|
const numericStyle = (value: number | string | undefined, fallback: number) =>
|
|
43
43
|
typeof value === "number" ? value : fallback;
|
|
44
44
|
|
|
45
|
+
/** Props for {@link MonthView}, the single-month grid. */
|
|
45
46
|
export type MonthViewProps<T> = {
|
|
46
47
|
date: Date;
|
|
47
48
|
events: CalendarEvent<T>[];
|
|
@@ -139,7 +140,7 @@ function MonthViewInner<T>({
|
|
|
139
140
|
renderCustomDateForMonth,
|
|
140
141
|
onDayPointerDown,
|
|
141
142
|
onDayPointerEnter,
|
|
142
|
-
}: MonthViewProps<T>) {
|
|
143
|
+
}: MonthViewProps<T>): ReactElement {
|
|
143
144
|
const theme = useCalendarTheme();
|
|
144
145
|
// Selection comes from context (so cached pages still repaint), but explicit
|
|
145
146
|
// props win for direct/standalone use of MonthView.
|
|
@@ -454,6 +455,22 @@ function MonthViewInner<T>({
|
|
|
454
455
|
);
|
|
455
456
|
}
|
|
456
457
|
|
|
458
|
+
/**
|
|
459
|
+
* A single month rendered as a 7-column grid of day cells, each showing its
|
|
460
|
+
* event chips with a "+N more" overflow. Render it on its own for a static
|
|
461
|
+
* month, or let `MonthList`/`Calendar` page through months for you.
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```tsx
|
|
465
|
+
* import { MonthView, type CalendarEvent } from "react-native-super-calendar";
|
|
466
|
+
*
|
|
467
|
+
* <MonthView
|
|
468
|
+
* date={new Date()}
|
|
469
|
+
* events={events}
|
|
470
|
+
* onPressDay={(day) => console.log(day)}
|
|
471
|
+
* />
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
457
474
|
export const MonthView = memo(MonthViewInner) as typeof MonthViewInner;
|
|
458
475
|
|
|
459
476
|
const styles = StyleSheet.create({
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
startOfDay,
|
|
16
16
|
startOfWeek,
|
|
17
17
|
} from "date-fns";
|
|
18
|
-
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
18
|
+
import { memo, type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
19
19
|
import {
|
|
20
20
|
type GestureResponderEvent,
|
|
21
21
|
Platform,
|
|
@@ -90,6 +90,7 @@ const PAGE_WINDOW = 180;
|
|
|
90
90
|
const PAGE_VIEWABILITY = { itemVisiblePercentThreshold: 90 };
|
|
91
91
|
|
|
92
92
|
// Matches the dom renderer's default so both grids start at the same density.
|
|
93
|
+
/** Default height in pixels of one hour row on the time grid. */
|
|
93
94
|
export const DEFAULT_HOUR_HEIGHT = 48;
|
|
94
95
|
const DEFAULT_MIN_HOUR_HEIGHT = 32;
|
|
95
96
|
const DEFAULT_MAX_HOUR_HEIGHT = 160;
|
|
@@ -206,23 +207,30 @@ function AnimatedEventBox<T>({
|
|
|
206
207
|
const moveOffsetX = useSharedValue(0);
|
|
207
208
|
const resizeDelta = useSharedValue(0);
|
|
208
209
|
|
|
210
|
+
// Pull the geometry out as primitives so the worklets below close over plain
|
|
211
|
+
// numbers, not `positioned` itself. Referencing `positioned.*` inside a
|
|
212
|
+
// worklet captures the whole object, and `positioned.event` holds `Date`s,
|
|
213
|
+
// which react-native-worklets >=0.10 refuses to copy to the UI thread
|
|
214
|
+
// ("Cannot copy value of type `Date`").
|
|
215
|
+
const startHours = positioned.startHours;
|
|
216
|
+
const durationHours = positioned.durationHours;
|
|
217
|
+
|
|
209
218
|
// Live pixel height of the box, driven on the UI thread by the shared
|
|
210
219
|
// cellHeight (plus any in-progress resize). Handed to renderEvent so custom
|
|
211
220
|
// renderers can reveal detail progressively as the grid zooms, without
|
|
212
221
|
// re-rendering. Explicit deps so the worklet re-captures the event's geometry.
|
|
213
222
|
const boxHeight = useDerivedValue(
|
|
214
|
-
() =>
|
|
215
|
-
|
|
216
|
-
[positioned.durationHours],
|
|
223
|
+
() => Math.max(durationHours * cellHeight.value + resizeDelta.value, MIN_EVENT_HEIGHT),
|
|
224
|
+
[durationHours],
|
|
217
225
|
);
|
|
218
226
|
|
|
219
227
|
const boxStyle = useAnimatedStyle(
|
|
220
228
|
() => ({
|
|
221
|
-
top: (
|
|
229
|
+
top: (startHours - minHour) * cellHeight.value + moveOffset.value,
|
|
222
230
|
height: boxHeight.value,
|
|
223
231
|
transform: [{ translateX: moveOffsetX.value }],
|
|
224
232
|
}),
|
|
225
|
-
[
|
|
233
|
+
[startHours, durationHours, minHour],
|
|
226
234
|
);
|
|
227
235
|
|
|
228
236
|
// Clear the drag preview once the committed change re-renders this box at its
|
|
@@ -730,7 +738,11 @@ function TimetablePageInner<T>({
|
|
|
730
738
|
[mode, date, weekStartsOn, numberOfDays, isRTL, weekEndsOn],
|
|
731
739
|
);
|
|
732
740
|
|
|
733
|
-
|
|
741
|
+
// Plain number for worklets to close over: reading `days.length` inside a
|
|
742
|
+
// gesture worklet would capture the whole `days` array (of `Date`s), which
|
|
743
|
+
// react-native-worklets >=0.10 refuses to copy to the UI thread.
|
|
744
|
+
const dayCount = days.length;
|
|
745
|
+
const dayWidth = (width - hourColumnWidth) / dayCount;
|
|
734
746
|
const dayLeft = (dayIndex: number) => hourColumnWidth + dayIndex * dayWidth;
|
|
735
747
|
|
|
736
748
|
const dayLayouts = useMemo(() => days.map((day) => layoutDayEvents(events, day)), [days, events]);
|
|
@@ -848,7 +860,7 @@ function TimetablePageInner<T>({
|
|
|
848
860
|
const pan = Gesture.Pan()
|
|
849
861
|
.enabled(createEnabled)
|
|
850
862
|
.onStart((event) => {
|
|
851
|
-
const idx =
|
|
863
|
+
const idx = dayCount === 1 ? 0 : Math.floor(event.x / dayWidth);
|
|
852
864
|
createDayIndex.value = idx;
|
|
853
865
|
createStartY.value = event.y;
|
|
854
866
|
createLeft.value = hourColumnWidth + idx * dayWidth;
|
|
@@ -884,7 +896,7 @@ function TimetablePageInner<T>({
|
|
|
884
896
|
: pan.activateAfterLongPress(DRAG_ACTIVATE_MS);
|
|
885
897
|
}, [
|
|
886
898
|
createEnabled,
|
|
887
|
-
|
|
899
|
+
dayCount,
|
|
888
900
|
dayWidth,
|
|
889
901
|
hourColumnWidth,
|
|
890
902
|
heightSource,
|
|
@@ -1150,6 +1162,7 @@ function TimetablePageInner<T>({
|
|
|
1150
1162
|
|
|
1151
1163
|
const TimetablePage = memo(TimetablePageInner) as typeof TimetablePageInner;
|
|
1152
1164
|
|
|
1165
|
+
/** Props for {@link TimeGrid}, the day/week timetable view. */
|
|
1153
1166
|
export type TimeGridProps<T> = {
|
|
1154
1167
|
mode: TimeGridMode;
|
|
1155
1168
|
/** Day columns to show in `custom` mode. Ignored by day/3days/week. Default 1. */
|
|
@@ -1284,7 +1297,7 @@ function TimeGridInner<T>({
|
|
|
1284
1297
|
onPressDateHeader,
|
|
1285
1298
|
onChangeDate,
|
|
1286
1299
|
renderHeader,
|
|
1287
|
-
}: TimeGridProps<T>) {
|
|
1300
|
+
}: TimeGridProps<T>): ReactElement {
|
|
1288
1301
|
// Guard against an inverted/out-of-range window so the grid never collapses.
|
|
1289
1302
|
const clampedMinHour = Math.max(0, Math.min(minHour, HOURS_PER_DAY - 1));
|
|
1290
1303
|
const clampedMaxHour = Math.max(clampedMinHour + 1, Math.min(maxHour, HOURS_PER_DAY));
|
|
@@ -1706,6 +1719,25 @@ function TimeGridInner<T>({
|
|
|
1706
1719
|
);
|
|
1707
1720
|
}
|
|
1708
1721
|
|
|
1722
|
+
/**
|
|
1723
|
+
* The timetable view used in day, 3days, week, and custom modes: an
|
|
1724
|
+
* hour-by-hour grid with positioned event boxes, an all-day lane, pinch-to-zoom
|
|
1725
|
+
* density, and optional drag-to-move/resize/create. Pages horizontally between
|
|
1726
|
+
* date ranges, reporting the committed range through `onChangeDate`.
|
|
1727
|
+
*
|
|
1728
|
+
* @example
|
|
1729
|
+
* ```tsx
|
|
1730
|
+
* import { TimeGrid } from "react-native-super-calendar";
|
|
1731
|
+
*
|
|
1732
|
+
* <TimeGrid
|
|
1733
|
+
* mode="week"
|
|
1734
|
+
* date={date}
|
|
1735
|
+
* events={events}
|
|
1736
|
+
* onChangeDate={setDate}
|
|
1737
|
+
* onPressEvent={(e) => console.log(e.title)}
|
|
1738
|
+
* />
|
|
1739
|
+
* ```
|
|
1740
|
+
*/
|
|
1709
1741
|
export const TimeGrid = memo(TimeGridInner) as typeof TimeGridInner;
|
|
1710
1742
|
|
|
1711
1743
|
type DefaultHeaderProps = {
|
package/src/index.tsx
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The React Native renderer for super-calendar: gesture-driven, virtualized
|
|
3
|
+
* month, week, and day views, plus the agenda and date picker. Runs on native
|
|
4
|
+
* and on the web through react-native-web.
|
|
5
|
+
*
|
|
6
|
+
* Built on the headless core, Legend List, Gesture Handler, and Reanimated. For
|
|
7
|
+
* a picker-only bundle that does not pull in Reanimated, import from
|
|
8
|
+
* `@super-calendar/native/picker` instead.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { Calendar } from "@super-calendar/native";
|
|
13
|
+
*
|
|
14
|
+
* export function App() {
|
|
15
|
+
* return <Calendar mode="month" />;
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @see https://super-calendar.afonsojramos.me
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
*/
|
|
1
23
|
export { Calendar, type CalendarProps } from "./components/Calendar";
|
|
2
24
|
export { Agenda, type AgendaProps } from "./components/Agenda";
|
|
3
25
|
export { MonthView, type MonthViewProps } from "./components/MonthView";
|
package/src/picker.tsx
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The picker-only entry point for `@super-calendar/native`: the month grid,
|
|
3
|
+
* selection, and the headless grid, with no dependency on the timetable views or
|
|
4
|
+
* Reanimated.
|
|
5
|
+
*
|
|
6
|
+
* Import from `@super-calendar/native/picker` for a lighter bundle that does not
|
|
7
|
+
* require react-native-reanimated. The main entry re-exports everything here.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { MonthView } from "@super-calendar/native/picker";
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @see https://super-calendar.afonsojramos.me
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
5
18
|
export { MonthView, type MonthViewProps } from "./components/MonthView";
|
|
6
19
|
export { MonthPager, type MonthPagerProps } from "./components/MonthPager";
|
|
7
20
|
export { MonthList, type MonthListProps } from "./components/MonthList";
|
package/src/theme.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CalendarColors, darkColors, lightColors } from "@super-calendar/core";
|
|
2
|
-
import { createContext, useContext } from "react";
|
|
2
|
+
import { type Context, createContext, useContext } from "react";
|
|
3
3
|
import type { TextStyle } from "react-native";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,6 +10,7 @@ import type { TextStyle } from "react-native";
|
|
|
10
10
|
export interface CalendarTheme {
|
|
11
11
|
/** The shared colour palette (sourced from `@super-calendar/core`). */
|
|
12
12
|
colors: CalendarColors;
|
|
13
|
+
/** Text styles for the calendar's labels and the built-in event box. */
|
|
13
14
|
text: {
|
|
14
15
|
/** Large day number in the week/day header. */
|
|
15
16
|
dayNumber: TextStyle;
|
|
@@ -33,6 +34,7 @@ export interface CalendarTheme {
|
|
|
33
34
|
rangeBandHeight: number;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
/** The default light theme. Every key the calendar reads falls back to this. */
|
|
36
38
|
export const defaultTheme: CalendarTheme = {
|
|
37
39
|
colors: lightColors,
|
|
38
40
|
text: {
|
|
@@ -72,6 +74,11 @@ export function mergeTheme(theme?: PartialCalendarTheme): CalendarTheme {
|
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
/**
|
|
78
|
+
* A theme with every key optional. Pass this to `<Calendar theme={...} />` to
|
|
79
|
+
* override only the colours, text styles, or metrics you care about; the rest
|
|
80
|
+
* come from {@link defaultTheme}.
|
|
81
|
+
*/
|
|
75
82
|
export type PartialCalendarTheme = {
|
|
76
83
|
colors?: Partial<CalendarTheme["colors"]>;
|
|
77
84
|
text?: Partial<CalendarTheme["text"]>;
|
|
@@ -79,8 +86,14 @@ export type PartialCalendarTheme = {
|
|
|
79
86
|
rangeBandHeight?: number;
|
|
80
87
|
};
|
|
81
88
|
|
|
82
|
-
const CalendarThemeContext = createContext<CalendarTheme>(defaultTheme);
|
|
89
|
+
const CalendarThemeContext: Context<CalendarTheme> = createContext<CalendarTheme>(defaultTheme);
|
|
83
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Context provider that supplies the active {@link CalendarTheme} to descendants.
|
|
93
|
+
* `<Calendar>` wraps its subtree in this; use it directly only to theme custom
|
|
94
|
+
* components rendered outside a `<Calendar>`.
|
|
95
|
+
*/
|
|
84
96
|
export const CalendarThemeProvider = CalendarThemeContext.Provider;
|
|
85
97
|
|
|
86
|
-
|
|
98
|
+
/** Read the active {@link CalendarTheme} from context. Useful inside custom renderers. */
|
|
99
|
+
export const useCalendarTheme = (): CalendarTheme => useContext(CalendarThemeContext);
|
package/src/types.ts
CHANGED
|
@@ -20,6 +20,11 @@ export type {
|
|
|
20
20
|
// The React Native render contract lives here, not in core: it references
|
|
21
21
|
// Reanimated (`SharedValue`) and React Native (`ViewStyle`) types, which must
|
|
22
22
|
// not leak into the platform-free core.
|
|
23
|
+
/**
|
|
24
|
+
* Props passed to a {@link RenderEvent} component for one event. Carries the
|
|
25
|
+
* event, the current mode, press handlers, and built-in renderer hints such as
|
|
26
|
+
* `boxHeight`, `continuesBefore`/`continuesAfter`, and `isAllDay`.
|
|
27
|
+
*/
|
|
23
28
|
export type RenderEventArgs<T = unknown> = {
|
|
24
29
|
event: CalendarEvent<T>;
|
|
25
30
|
mode: CalendarMode;
|