react-native-ll-calendar 0.16.0 → 0.17.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,174 @@
1
+ import React, { useState, type ReactNode } from 'react';
2
+ import {
3
+ FlatList,
4
+ useWindowDimensions,
5
+ type TextStyle,
6
+ type ViewStyle,
7
+ } from 'react-native';
8
+ import dayjs from 'dayjs';
9
+ import type { WeekStartsOn } from '../../types/month-calendar';
10
+ import type {
11
+ CalendarResource,
12
+ CalendarEvent,
13
+ } from '../../types/resources-calendar';
14
+ import { WeekPanel } from './WeekPanel';
15
+
16
+ const HALF_PANEL_LENGTH = 120;
17
+
18
+ type WeekResourcesCalendarProps = {
19
+ defaultDate: Date;
20
+ weekStartsOn?: WeekStartsOn;
21
+ onChangeDate?: (date: Date) => void;
22
+ resources: CalendarResource[];
23
+ events: CalendarEvent[];
24
+ eventHeight?: number;
25
+ onPressCell?: (resource: CalendarResource, date: Date) => void;
26
+ onLongPressCell?: (resource: CalendarResource, date: Date) => void;
27
+ delayLongPressCell?: number;
28
+ onPressEvent?: (event: CalendarEvent) => void;
29
+ onLongPressEvent?: (event: CalendarEvent) => void;
30
+ delayLongPressEvent?: number;
31
+ /**
32
+ * When true, a transparent layer is placed above events in each cell so
33
+ * `onPressCell` / `onLongPressCell` receive touches for the full cell area.
34
+ * Event taps are disabled while this is on (overlay captures the gesture).
35
+ */
36
+ prioritizeCellInteraction?: boolean;
37
+ eventTextStyle?: (event: CalendarEvent) => TextStyle;
38
+ eventEllipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
39
+ allowFontScaling?: boolean;
40
+ renderEventOverlay?: (event: CalendarEvent) => ReactNode;
41
+ dateCellContainerStyle?: (date: Date) => ViewStyle;
42
+ cellContainerStyle?: (resource: CalendarResource, date: Date) => ViewStyle;
43
+ renderDateLabel?: (date: Date) => React.JSX.Element;
44
+ renderResourceNameLabel?: (resource: CalendarResource) => React.JSX.Element;
45
+ onRefresh?: () => void;
46
+ refreshing?: boolean;
47
+ bottomSpacing?: number;
48
+ fixedRowCount?: number;
49
+ };
50
+
51
+ function getWeekStart(date: Date, weekStartsOn: WeekStartsOn): dayjs.Dayjs {
52
+ const djs = dayjs(date);
53
+ if (weekStartsOn === 0) {
54
+ return djs.startOf('week');
55
+ }
56
+ const day = djs.day();
57
+ if (day === 0) {
58
+ return djs.subtract(6, 'day').startOf('day');
59
+ }
60
+ return djs.subtract(day - 1, 'day').startOf('day');
61
+ }
62
+
63
+ export const WeekResourcesCalendar = ({
64
+ defaultDate,
65
+ weekStartsOn = 0,
66
+ onChangeDate,
67
+ resources,
68
+ events,
69
+ eventHeight,
70
+ onPressCell,
71
+ onLongPressCell,
72
+ delayLongPressCell,
73
+ onPressEvent,
74
+ onLongPressEvent,
75
+ delayLongPressEvent,
76
+ prioritizeCellInteraction,
77
+ eventTextStyle,
78
+ eventEllipsizeMode,
79
+ allowFontScaling,
80
+ renderEventOverlay,
81
+ dateCellContainerStyle,
82
+ cellContainerStyle,
83
+ renderDateLabel,
84
+ renderResourceNameLabel,
85
+ onRefresh,
86
+ refreshing,
87
+ bottomSpacing,
88
+ fixedRowCount,
89
+ }: WeekResourcesCalendarProps) => {
90
+ const [_activeIndex, setActiveIndex] = useState(HALF_PANEL_LENGTH);
91
+ const { width } = useWindowDimensions();
92
+
93
+ const startOfDefaultWeek = getWeekStart(defaultDate, weekStartsOn);
94
+
95
+ const prevPanels: string[] = Array.from(
96
+ { length: HALF_PANEL_LENGTH },
97
+ (_, i) => {
98
+ return startOfDefaultWeek
99
+ .subtract(HALF_PANEL_LENGTH - i, 'week')
100
+ .format('YYYY-MM-DD');
101
+ }
102
+ );
103
+
104
+ const nextPanels: string[] = Array.from(
105
+ { length: HALF_PANEL_LENGTH },
106
+ (_, i) => {
107
+ return startOfDefaultWeek.add(i + 1, 'week').format('YYYY-MM-DD');
108
+ }
109
+ );
110
+
111
+ const panels: string[] = [
112
+ ...prevPanels,
113
+ startOfDefaultWeek.format('YYYY-MM-DD'),
114
+ ...nextPanels,
115
+ ];
116
+
117
+ return (
118
+ <FlatList
119
+ horizontal
120
+ pagingEnabled
121
+ data={panels}
122
+ keyExtractor={(item) => item}
123
+ initialScrollIndex={HALF_PANEL_LENGTH}
124
+ getItemLayout={(_data, index) => ({
125
+ length: width,
126
+ offset: width * index,
127
+ index,
128
+ })}
129
+ renderItem={({ item }) => (
130
+ <WeekPanel
131
+ weekKey={item}
132
+ width={width}
133
+ resources={resources}
134
+ events={events}
135
+ eventHeight={eventHeight}
136
+ onPressCell={onPressCell}
137
+ onLongPressCell={onLongPressCell}
138
+ delayLongPressCell={delayLongPressCell}
139
+ onPressEvent={onPressEvent}
140
+ onLongPressEvent={onLongPressEvent}
141
+ delayLongPressEvent={delayLongPressEvent}
142
+ prioritizeCellInteraction={prioritizeCellInteraction}
143
+ eventTextStyle={eventTextStyle}
144
+ eventEllipsizeMode={eventEllipsizeMode}
145
+ allowFontScaling={allowFontScaling}
146
+ renderEventOverlay={renderEventOverlay}
147
+ dateCellContainerStyle={dateCellContainerStyle}
148
+ cellContainerStyle={cellContainerStyle}
149
+ renderDateLabel={renderDateLabel}
150
+ renderResourceNameLabel={renderResourceNameLabel}
151
+ onRefresh={onRefresh}
152
+ refreshing={refreshing}
153
+ bottomSpacing={bottomSpacing}
154
+ fixedRowCount={fixedRowCount}
155
+ />
156
+ )}
157
+ onMomentumScrollEnd={(e) => {
158
+ const scrollX = e.nativeEvent.contentOffset.x;
159
+ const newIndex = Math.round(scrollX / width);
160
+ setActiveIndex(newIndex);
161
+ const weekKey = panels[newIndex];
162
+ if (weekKey) {
163
+ onChangeDate?.(dayjs(weekKey).toDate());
164
+ }
165
+ }}
166
+ showsHorizontalScrollIndicator={false}
167
+ decelerationRate="fast"
168
+ windowSize={5}
169
+ initialNumToRender={5}
170
+ maxToRenderPerBatch={5}
171
+ removeClippedSubviews={false}
172
+ />
173
+ );
174
+ };
package/src/index.tsx CHANGED
@@ -9,3 +9,5 @@ export type {
9
9
  CalendarEvent as ResourcesCalendarEvent,
10
10
  CalendarResource,
11
11
  } from './types/resources-calendar';
12
+
13
+ export { WeekResourcesCalendar } from './calendar/week-resources-calendar/WeekResourcesCalendar';