react-native-resource-calendar 1.0.9 → 1.0.11
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 +48 -24
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Expo compatibility.
|
|
|
7
7
|
|
|
8
8
|
## ✨ Features
|
|
9
9
|
|
|
10
|
-
- ✅ Multi-resource timeline layout
|
|
10
|
+
- ✅ Multi-resource/multi-days timeline layout
|
|
11
11
|
- 🎨 Customizable event slots (Body, TopRight)
|
|
12
12
|
- 📱 Smooth Reanimated drag-and-drop
|
|
13
13
|
- ⏰ Timezone-aware time labels
|
|
@@ -18,6 +18,7 @@ Expo compatibility.
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
## 🎬 Demo
|
|
21
|
+
|
|
21
22
|
https://github.com/user-attachments/assets/68fe0283-73ce-4689-8241-6587b817ecbd
|
|
22
23
|
|
|
23
24
|
---
|
|
@@ -75,10 +76,10 @@ import {StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
|
75
76
|
import {Calendar, DraggedEventDraft, Event, LayoutMode, useCalendarBinding} from "react-native-resource-calendar";
|
|
76
77
|
import {SafeAreaView} from "react-native-safe-area-context";
|
|
77
78
|
import {ThemedText} from "@/components/ThemedText";
|
|
78
|
-
import {resourceData} from "@/app/(tabs)/fakeData";
|
|
79
79
|
import EventTopRight from "@/components/EventTopRight";
|
|
80
80
|
import {FontAwesome} from "@expo/vector-icons";
|
|
81
81
|
import {statusColor} from "@/utilities/helpers";
|
|
82
|
+
import {resourceData} from "@/assets/fakeData";
|
|
82
83
|
|
|
83
84
|
export default function App() {
|
|
84
85
|
const {
|
|
@@ -98,27 +99,34 @@ export default function App() {
|
|
|
98
99
|
const updateResourcesOnDrag = React.useCallback(
|
|
99
100
|
(draft: DraggedEventDraft) => {
|
|
100
101
|
setResources((prev: any) => {
|
|
101
|
-
const {event, from, to, resourceId} = draft;
|
|
102
|
+
const {event, from, to, resourceId, date} = draft;
|
|
102
103
|
|
|
103
104
|
return prev.map((res: any) => {
|
|
105
|
+
// ✅ if this is the new target resource
|
|
104
106
|
if (res.id === resourceId) {
|
|
107
|
+
// was the event originally in a different resource?
|
|
105
108
|
const wasDifferentResource = event.resourceId !== resourceId;
|
|
106
109
|
|
|
110
|
+
// clone event with new times and resourceId
|
|
107
111
|
const updatedEvent = {
|
|
108
112
|
...event,
|
|
109
113
|
from,
|
|
110
114
|
to,
|
|
111
115
|
resourceId,
|
|
116
|
+
date
|
|
112
117
|
};
|
|
113
118
|
|
|
114
119
|
return {
|
|
115
120
|
...res,
|
|
116
121
|
events: wasDifferentResource
|
|
122
|
+
// if moved from another resource, append it here
|
|
117
123
|
? [...res.events, updatedEvent]
|
|
124
|
+
// else update it in place
|
|
118
125
|
: res.events.map((e: any) => (e.id === event.id ? updatedEvent : e)),
|
|
119
126
|
};
|
|
120
127
|
}
|
|
121
128
|
|
|
129
|
+
// ✅ if this is the old resource and event moved away
|
|
122
130
|
if (res.id === event.resourceId && event.resourceId !== resourceId) {
|
|
123
131
|
return {
|
|
124
132
|
...res,
|
|
@@ -126,6 +134,7 @@ export default function App() {
|
|
|
126
134
|
};
|
|
127
135
|
}
|
|
128
136
|
|
|
137
|
+
// ✅ untouched resources
|
|
129
138
|
return res;
|
|
130
139
|
});
|
|
131
140
|
});
|
|
@@ -145,10 +154,17 @@ export default function App() {
|
|
|
145
154
|
setNumberOfColumns(randomNumberOfColumns);
|
|
146
155
|
setLayoutMode(layoutMode === 'stacked' ? 'columns' : 'stacked');
|
|
147
156
|
}
|
|
148
|
-
|
|
157
|
+
|
|
158
|
+
const addDays = (days: number) => {
|
|
159
|
+
const newDate = new Date(date);
|
|
160
|
+
newDate.setDate(newDate.getDate() + days);
|
|
161
|
+
setDate(newDate);
|
|
162
|
+
};
|
|
163
|
+
|
|
149
164
|
return (
|
|
150
165
|
<SafeAreaView style={{backgroundColor: "#fff", flex: 1}} edges={["top"]}>
|
|
151
166
|
<Calendar
|
|
167
|
+
// mode={'week'}
|
|
152
168
|
theme={{
|
|
153
169
|
typography: {
|
|
154
170
|
fontFamily: 'NunitoSans',
|
|
@@ -238,26 +254,28 @@ export default function App() {
|
|
|
238
254
|
|
|
239
255
|
The `Calendar` component accepts a flexible set of props for customizing layout, theme, and interactivity.
|
|
240
256
|
|
|
241
|
-
| Prop | Type | Default
|
|
242
|
-
|
|
243
|
-
| **`date`** | `Date` | `new Date()`
|
|
244
|
-
| **`
|
|
245
|
-
| **`
|
|
246
|
-
| **`
|
|
247
|
-
| **`
|
|
248
|
-
| **`
|
|
249
|
-
| **`
|
|
250
|
-
| **`
|
|
251
|
-
| **`
|
|
252
|
-
| **`
|
|
253
|
-
| **`
|
|
254
|
-
| **`
|
|
255
|
-
| **`
|
|
256
|
-
| **`
|
|
257
|
-
| **`
|
|
258
|
-
| **`
|
|
259
|
-
| **`
|
|
260
|
-
| **`
|
|
257
|
+
| Prop | Type | Default | Description |
|
|
258
|
+
|-----------------------------|------------------------------------------------------------------------------------------------------------------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
259
|
+
| **`date`** | `Date` | `new Date()` | The anchor day shown in the timeline. In multi-day modes this is the **first** visible day. |
|
|
260
|
+
| **`mode`** | `CalendarMode` (`'day' \| '3days' \| 'week'`) | `'day'` | Controls the column semantics. **day** = many resources for one day. **3days/week** = several days for one resource. |
|
|
261
|
+
| **`activeResourceId`** | `number` | first `resources[0].id` | When `mode !== 'day'`, columns represent days for **this** resource. |
|
|
262
|
+
| **`resources`** | `Array<Resource & { events: Event[]; disabledBlocks?: DisabledBlock[]; disableIntervals?: DisabledInterval[] }>` | **required** | Resource columns. Each resource includes its day’s `events`, optional `disabledBlocks` (finite ranges), and `disableIntervals` (open/recurring ranges). |
|
|
263
|
+
| **`timezone`** | `string` | device time zone | Used for time labels and converting block taps to a `Date`. |
|
|
264
|
+
| **`startMinutes`** | `number` | `0` | Start of visible timeline in minutes after midnight (e.g. `8 * 60` = 08:00). |
|
|
265
|
+
| **`numberOfColumns`** | `number` | `3` | **Day mode only.** How many resource columns to show side-by-side. (In multi-day modes, the column count is fixed by the mode: 3 or 7.) |
|
|
266
|
+
| **`hourHeight`** | `number` | `120` | Vertical density, px per hour. Affects drag/resize and scroll snap. |
|
|
267
|
+
| **`snapIntervalInMinutes`** | `number` | `5` | Drag/resize snapping granularity (in minutes). |
|
|
268
|
+
| **`overLappingLayoutMode`** | `LayoutMode` (`'stacked' \| 'columns'`) | `'stacked'` | Strategy to lay out overlapping events inside a column. |
|
|
269
|
+
| **`theme`** | `CalendarTheme` | — | Typography & palette overrides. |
|
|
270
|
+
| **`eventSlots`** | `EventSlots` | — | Slot renderers to customize event content (e.g. `{ Body, TopRight }`). |
|
|
271
|
+
| **`eventStyleOverrides`** | `StyleOverrides \| ((event: Event) => StyleOverrides \| undefined)` | — | Per-event style override (object or function). |
|
|
272
|
+
| **`isEventSelected`** | `(event: Event) => boolean` | `() => false` | Marks which events are currently selected. |
|
|
273
|
+
| **`isEventDisabled`** | `(event: Event) => boolean` | `() => false` | Marks events as disabled (non-interactive). |
|
|
274
|
+
| **`onResourcePress`** | `(resource: Resource) => void` | — | Invoked when a resource header is pressed. |
|
|
275
|
+
| **`onBlockLongPress`** | `(resource: Resource, date: Date) => void` | — | Long-press on an empty block (grid). |
|
|
276
|
+
| **`onDisabledBlockPress`** | `(block: DisabledBlock) => void` | — | Tap on a disabled block (e.g., lunch). |
|
|
277
|
+
| **`onEventPress`** | `(event: Event) => void` | — | Tap on an event. |
|
|
278
|
+
| **`onEventLongPress`** | `(event: Event) => void` | — | Long-press on an event. The calendar also preps internal drag state here. |
|
|
261
279
|
|
|
262
280
|
---
|
|
263
281
|
|
|
@@ -269,6 +287,7 @@ type ResourceId = number;
|
|
|
269
287
|
type Event = {
|
|
270
288
|
id: number;
|
|
271
289
|
resourceId: ResourceId;
|
|
290
|
+
date: string; // 'yyyy-MM-dd' eg. '2025-11-09'
|
|
272
291
|
from: number;
|
|
273
292
|
to: number;
|
|
274
293
|
title?: string;
|
|
@@ -281,6 +300,7 @@ type Event = {
|
|
|
281
300
|
type DisabledBlock = {
|
|
282
301
|
id: number;
|
|
283
302
|
resourceId: ResourceId;
|
|
303
|
+
date: string; // 'yyyy-MM-dd' eg. '2025-11-09'
|
|
284
304
|
from: number;
|
|
285
305
|
to: number;
|
|
286
306
|
title?: string;
|
|
@@ -288,6 +308,7 @@ type DisabledBlock = {
|
|
|
288
308
|
|
|
289
309
|
type DisabledInterval = {
|
|
290
310
|
resourceId: ResourceId;
|
|
311
|
+
date: string; // 'yyyy-MM-dd' eg. '2025-11-09'
|
|
291
312
|
from: number;
|
|
292
313
|
to: number;
|
|
293
314
|
};
|
|
@@ -300,6 +321,7 @@ type Resource = {
|
|
|
300
321
|
|
|
301
322
|
type DraggedEventDraft = {
|
|
302
323
|
event: Event,
|
|
324
|
+
date: string; // 'yyyy-MM-dd' eg. '2025-11-09'
|
|
303
325
|
from: number,
|
|
304
326
|
to: number,
|
|
305
327
|
resourceId: ResourceId
|
|
@@ -310,6 +332,8 @@ type CalendarTheme = {
|
|
|
310
332
|
fontFamily?: string;
|
|
311
333
|
};
|
|
312
334
|
};
|
|
335
|
+
|
|
336
|
+
type CalendarMode = 'day' | '3days' | 'week';
|
|
313
337
|
```
|
|
314
338
|
|
|
315
339
|
---
|
package/dist/index.d.mts
CHANGED
|
@@ -35,8 +35,8 @@ type Resource = {
|
|
|
35
35
|
};
|
|
36
36
|
type DraggedEventDraft = {
|
|
37
37
|
event: Event;
|
|
38
|
-
from: number;
|
|
39
38
|
date: string;
|
|
39
|
+
from: number;
|
|
40
40
|
to: number;
|
|
41
41
|
resourceId: ResourceId;
|
|
42
42
|
};
|
|
@@ -129,4 +129,4 @@ declare const CalendarBindingProvider: React$1.FC<{
|
|
|
129
129
|
children: React$1.ReactNode;
|
|
130
130
|
}>;
|
|
131
131
|
|
|
132
|
-
export { Calendar, CalendarBindingProvider, type CalendarTheme, type DisabledBlock, type DisabledInterval, type DraggedEventDraft, type Event, type EventRenderContext, type LayoutMode, type Resource, useCalendarBinding };
|
|
132
|
+
export { Calendar, CalendarBindingProvider, type CalendarMode, type CalendarTheme, type DisabledBlock, type DisabledInterval, type DraggedEventDraft, type Event, type EventRenderContext, type LayoutMode, type Resource, useCalendarBinding };
|
package/dist/index.d.ts
CHANGED
|
@@ -35,8 +35,8 @@ type Resource = {
|
|
|
35
35
|
};
|
|
36
36
|
type DraggedEventDraft = {
|
|
37
37
|
event: Event;
|
|
38
|
-
from: number;
|
|
39
38
|
date: string;
|
|
39
|
+
from: number;
|
|
40
40
|
to: number;
|
|
41
41
|
resourceId: ResourceId;
|
|
42
42
|
};
|
|
@@ -129,4 +129,4 @@ declare const CalendarBindingProvider: React$1.FC<{
|
|
|
129
129
|
children: React$1.ReactNode;
|
|
130
130
|
}>;
|
|
131
131
|
|
|
132
|
-
export { Calendar, CalendarBindingProvider, type CalendarTheme, type DisabledBlock, type DisabledInterval, type DraggedEventDraft, type Event, type EventRenderContext, type LayoutMode, type Resource, useCalendarBinding };
|
|
132
|
+
export { Calendar, CalendarBindingProvider, type CalendarMode, type CalendarTheme, type DisabledBlock, type DisabledInterval, type DraggedEventDraft, type Event, type EventRenderContext, type LayoutMode, type Resource, useCalendarBinding };
|
package/dist/index.js
CHANGED
|
@@ -1455,6 +1455,9 @@ var CalendarInner = (props) => {
|
|
|
1455
1455
|
setDraggedEventDraft(null);
|
|
1456
1456
|
}
|
|
1457
1457
|
}, [selectedEvent]);
|
|
1458
|
+
React19.useEffect(() => {
|
|
1459
|
+
scrollX.value = 0;
|
|
1460
|
+
}, [mode]);
|
|
1458
1461
|
const verticalScrollViewRef = Animated2.useAnimatedRef();
|
|
1459
1462
|
const headerScrollViewRef = Animated2.useAnimatedRef();
|
|
1460
1463
|
const flashListRef = React19.useRef(null);
|