@dreamstack-us/kaal 0.0.1 → 0.0.3

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.
Files changed (136) hide show
  1. package/README.md +165 -0
  2. package/lib/module/components/CalendarGrid/CalendarGrid.js +125 -29
  3. package/lib/module/components/CalendarGrid/CalendarGrid.js.map +1 -1
  4. package/lib/module/components/CalendarGrid/CalendarGrid.styles.js +22 -17
  5. package/lib/module/components/CalendarGrid/CalendarGrid.styles.js.map +1 -1
  6. package/lib/module/components/CalendarGrid/CalendarGrid.web.js +265 -0
  7. package/lib/module/components/CalendarGrid/CalendarGrid.web.js.map +1 -0
  8. package/lib/module/components/CalendarGrid/DayCell.js +77 -53
  9. package/lib/module/components/CalendarGrid/DayCell.js.map +1 -1
  10. package/lib/module/components/CalendarGrid/DayCell.web.js +124 -0
  11. package/lib/module/components/CalendarGrid/DayCell.web.js.map +1 -0
  12. package/lib/module/components/CalendarGrid/index.js +1 -1
  13. package/lib/module/components/CalendarGrid/index.js.map +1 -1
  14. package/lib/module/components/DatePicker/DatePicker.android.js +53 -21
  15. package/lib/module/components/DatePicker/DatePicker.android.js.map +1 -1
  16. package/lib/module/components/DatePicker/DatePicker.ios.js +55 -23
  17. package/lib/module/components/DatePicker/DatePicker.ios.js.map +1 -1
  18. package/lib/module/components/DatePicker/DatePicker.js.map +1 -1
  19. package/lib/module/components/DatePicker/DatePicker.styles.js +19 -20
  20. package/lib/module/components/DatePicker/DatePicker.styles.js.map +1 -1
  21. package/lib/module/components/DatePicker/DatePicker.web.js +59 -21
  22. package/lib/module/components/DatePicker/DatePicker.web.js.map +1 -1
  23. package/lib/module/components/TimePicker/ClockFace.js +27 -7
  24. package/lib/module/components/TimePicker/ClockFace.js.map +1 -1
  25. package/lib/module/components/TimePicker/ClockFace.web.js +253 -0
  26. package/lib/module/components/TimePicker/ClockFace.web.js.map +1 -0
  27. package/lib/module/components/TimePicker/MaterialTimePicker.js +68 -16
  28. package/lib/module/components/TimePicker/MaterialTimePicker.js.map +1 -1
  29. package/lib/module/components/TimePicker/MaterialTimePicker.web.js +231 -0
  30. package/lib/module/components/TimePicker/MaterialTimePicker.web.js.map +1 -0
  31. package/lib/module/components/TimePicker/TimePicker.android.js +13 -6
  32. package/lib/module/components/TimePicker/TimePicker.android.js.map +1 -1
  33. package/lib/module/components/TimePicker/TimePicker.ios.js +14 -7
  34. package/lib/module/components/TimePicker/TimePicker.ios.js.map +1 -1
  35. package/lib/module/components/TimePicker/TimePicker.styles.js +53 -45
  36. package/lib/module/components/TimePicker/TimePicker.styles.js.map +1 -1
  37. package/lib/module/components/TimePicker/TimePicker.web.js +24 -12
  38. package/lib/module/components/TimePicker/TimePicker.web.js.map +1 -1
  39. package/lib/module/components/TimePicker/TimeWheelPicker.js +45 -10
  40. package/lib/module/components/TimePicker/TimeWheelPicker.js.map +1 -1
  41. package/lib/module/components/TimePicker/TimeWheelPicker.web.js +339 -0
  42. package/lib/module/components/TimePicker/TimeWheelPicker.web.js.map +1 -0
  43. package/lib/module/components/TimePicker/index.js +3 -3
  44. package/lib/module/components/TimePicker/index.js.map +1 -1
  45. package/lib/module/components/WheelPicker/WheelPicker.js +21 -2
  46. package/lib/module/components/WheelPicker/WheelPicker.js.map +1 -1
  47. package/lib/module/components/WheelPicker/WheelPicker.styles.js +13 -8
  48. package/lib/module/components/WheelPicker/WheelPicker.styles.js.map +1 -1
  49. package/lib/module/components/WheelPicker/WheelPicker.web.js +146 -57
  50. package/lib/module/components/WheelPicker/WheelPicker.web.js.map +1 -1
  51. package/lib/module/context/ThemeOverrideContext.js +34 -0
  52. package/lib/module/context/ThemeOverrideContext.js.map +1 -0
  53. package/lib/module/index.js +3 -0
  54. package/lib/module/index.js.map +1 -1
  55. package/lib/module/utils/validation.js +74 -34
  56. package/lib/module/utils/validation.js.map +1 -1
  57. package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts +24 -3
  58. package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts.map +1 -1
  59. package/lib/typescript/components/CalendarGrid/CalendarGrid.styles.d.ts +12 -10
  60. package/lib/typescript/components/CalendarGrid/CalendarGrid.styles.d.ts.map +1 -1
  61. package/lib/typescript/components/CalendarGrid/CalendarGrid.web.d.ts +33 -0
  62. package/lib/typescript/components/CalendarGrid/CalendarGrid.web.d.ts.map +1 -0
  63. package/lib/typescript/components/CalendarGrid/DayCell.d.ts +3 -0
  64. package/lib/typescript/components/CalendarGrid/DayCell.d.ts.map +1 -1
  65. package/lib/typescript/components/CalendarGrid/DayCell.web.d.ts +15 -0
  66. package/lib/typescript/components/CalendarGrid/DayCell.web.d.ts.map +1 -0
  67. package/lib/typescript/components/DatePicker/DatePicker.android.d.ts.map +1 -1
  68. package/lib/typescript/components/DatePicker/DatePicker.d.ts +27 -4
  69. package/lib/typescript/components/DatePicker/DatePicker.d.ts.map +1 -1
  70. package/lib/typescript/components/DatePicker/DatePicker.ios.d.ts.map +1 -1
  71. package/lib/typescript/components/DatePicker/DatePicker.styles.d.ts +12 -13
  72. package/lib/typescript/components/DatePicker/DatePicker.styles.d.ts.map +1 -1
  73. package/lib/typescript/components/DatePicker/DatePicker.web.d.ts.map +1 -1
  74. package/lib/typescript/components/TimePicker/ClockFace.d.ts.map +1 -1
  75. package/lib/typescript/components/TimePicker/ClockFace.web.d.ts +12 -0
  76. package/lib/typescript/components/TimePicker/ClockFace.web.d.ts.map +1 -0
  77. package/lib/typescript/components/TimePicker/MaterialTimePicker.d.ts.map +1 -1
  78. package/lib/typescript/components/TimePicker/MaterialTimePicker.web.d.ts +12 -0
  79. package/lib/typescript/components/TimePicker/MaterialTimePicker.web.d.ts.map +1 -0
  80. package/lib/typescript/components/TimePicker/TimePicker.android.d.ts.map +1 -1
  81. package/lib/typescript/components/TimePicker/TimePicker.ios.d.ts.map +1 -1
  82. package/lib/typescript/components/TimePicker/TimePicker.styles.d.ts +29 -25
  83. package/lib/typescript/components/TimePicker/TimePicker.styles.d.ts.map +1 -1
  84. package/lib/typescript/components/TimePicker/TimePicker.web.d.ts.map +1 -1
  85. package/lib/typescript/components/TimePicker/TimeWheelPicker.d.ts.map +1 -1
  86. package/lib/typescript/components/TimePicker/TimeWheelPicker.web.d.ts +11 -0
  87. package/lib/typescript/components/TimePicker/TimeWheelPicker.web.d.ts.map +1 -0
  88. package/lib/typescript/components/WheelPicker/WheelPicker.d.ts +14 -1
  89. package/lib/typescript/components/WheelPicker/WheelPicker.d.ts.map +1 -1
  90. package/lib/typescript/components/WheelPicker/WheelPicker.styles.d.ts +9 -7
  91. package/lib/typescript/components/WheelPicker/WheelPicker.styles.d.ts.map +1 -1
  92. package/lib/typescript/components/WheelPicker/WheelPicker.web.d.ts.map +1 -1
  93. package/lib/typescript/context/ThemeOverrideContext.d.ts +23 -0
  94. package/lib/typescript/context/ThemeOverrideContext.d.ts.map +1 -0
  95. package/lib/typescript/index.d.ts +4 -2
  96. package/lib/typescript/index.d.ts.map +1 -1
  97. package/lib/typescript/types/datepicker.d.ts +78 -3
  98. package/lib/typescript/types/datepicker.d.ts.map +1 -1
  99. package/lib/typescript/types/timepicker.d.ts +62 -0
  100. package/lib/typescript/types/timepicker.d.ts.map +1 -1
  101. package/lib/typescript/utils/validation.d.ts +47 -27
  102. package/lib/typescript/utils/validation.d.ts.map +1 -1
  103. package/package.json +8 -8
  104. package/src/components/CalendarGrid/CalendarGrid.styles.ts +21 -17
  105. package/src/components/CalendarGrid/CalendarGrid.tsx +265 -85
  106. package/src/components/CalendarGrid/CalendarGrid.web.tsx +396 -0
  107. package/src/components/CalendarGrid/DayCell.tsx +122 -61
  108. package/src/components/CalendarGrid/DayCell.web.tsx +171 -0
  109. package/src/components/DatePicker/DatePicker.android.tsx +48 -24
  110. package/src/components/DatePicker/DatePicker.ios.tsx +51 -27
  111. package/src/components/DatePicker/DatePicker.styles.ts +18 -22
  112. package/src/components/DatePicker/DatePicker.tsx +35 -4
  113. package/src/components/DatePicker/DatePicker.web.tsx +55 -23
  114. package/src/components/TimePicker/ClockFace.tsx +34 -8
  115. package/src/components/TimePicker/ClockFace.web.tsx +303 -0
  116. package/src/components/TimePicker/MaterialTimePicker.tsx +144 -13
  117. package/src/components/TimePicker/MaterialTimePicker.web.tsx +271 -0
  118. package/src/components/TimePicker/TimePicker.android.tsx +9 -1
  119. package/src/components/TimePicker/TimePicker.ios.tsx +10 -6
  120. package/src/components/TimePicker/TimePicker.styles.ts +52 -45
  121. package/src/components/TimePicker/TimePicker.web.tsx +17 -7
  122. package/src/components/TimePicker/TimeWheelPicker.tsx +60 -6
  123. package/src/components/TimePicker/TimeWheelPicker.web.tsx +401 -0
  124. package/src/components/WheelPicker/WheelPicker.styles.ts +12 -8
  125. package/src/components/WheelPicker/WheelPicker.tsx +24 -2
  126. package/src/components/WheelPicker/WheelPicker.web.tsx +153 -57
  127. package/src/context/ThemeOverrideContext.tsx +38 -0
  128. package/src/index.ts +13 -0
  129. package/src/types/datepicker.ts +87 -3
  130. package/src/types/timepicker.ts +74 -0
  131. package/src/utils/validation.ts +111 -55
  132. package/lib/module/unistyles.js +0 -9
  133. package/lib/module/unistyles.js.map +0 -1
  134. package/lib/typescript/unistyles.d.ts +0 -3
  135. package/lib/typescript/unistyles.d.ts.map +0 -1
  136. package/src/unistyles.ts +0 -6
@@ -1,5 +1,6 @@
1
1
  import React, { memo, useCallback, useMemo } from 'react';
2
2
  import { FlatList, Pressable, Text, View } from 'react-native';
3
+ import { useDatePickerOverrides } from '../../context/ThemeOverrideContext';
3
4
  import {
4
5
  addMonths,
5
6
  compareDates,
@@ -13,23 +14,83 @@ import {
13
14
  import { styles } from './CalendarGrid.styles';
14
15
  import { DayCell } from './DayCell';
15
16
 
16
- interface CalendarGridProps {
17
- value: Date;
18
- onChange: (date: Date) => void;
17
+ import type { DateRange } from '../../types/datepicker';
18
+
19
+ interface CalendarGridBaseProps {
19
20
  minDate?: Date;
20
21
  maxDate?: Date;
21
22
  disabledDates?: Date[];
22
23
  themeMode: 'ios' | 'android' | 'custom';
24
+ /**
25
+ * First day of the week: 0 = Sunday, 1 = Monday
26
+ * @default 0 (Sunday)
27
+ */
28
+ weekStartsOn?: 0 | 1;
23
29
  }
24
30
 
31
+ interface CalendarGridSingleProps extends CalendarGridBaseProps {
32
+ selectionMode?: 'single';
33
+ value: Date;
34
+ onChange: (date: Date) => void;
35
+ startDate?: never;
36
+ endDate?: never;
37
+ onRangeChange?: never;
38
+ }
39
+
40
+ interface CalendarGridRangeProps extends CalendarGridBaseProps {
41
+ selectionMode: 'range';
42
+ startDate: Date | null;
43
+ endDate: Date | null;
44
+ onRangeChange: (range: DateRange) => void;
45
+ value?: never;
46
+ onChange?: never;
47
+ }
48
+
49
+ type CalendarGridProps = CalendarGridSingleProps | CalendarGridRangeProps;
50
+
25
51
  const CELL_SIZE = 44;
26
- const WEEK_DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
27
52
 
28
- const generateMonthDays = (currentMonth: Date): (Date | null)[] => {
53
+ // Week day labels starting from Sunday
54
+ const WEEK_DAYS_SUNDAY_START = [
55
+ 'Sun',
56
+ 'Mon',
57
+ 'Tue',
58
+ 'Wed',
59
+ 'Thu',
60
+ 'Fri',
61
+ 'Sat',
62
+ ];
63
+ const WEEK_DAYS_MONDAY_START = [
64
+ 'Mon',
65
+ 'Tue',
66
+ 'Wed',
67
+ 'Thu',
68
+ 'Fri',
69
+ 'Sat',
70
+ 'Sun',
71
+ ];
72
+
73
+ /**
74
+ * Generate padding days for the month grid based on week start day
75
+ * TODO: This logic should be refactored when adding locale support
76
+ */
77
+ const generateMonthDays = (
78
+ currentMonth: Date,
79
+ weekStartsOn: 0 | 1,
80
+ ): (Date | null)[] => {
29
81
  const firstDay = getFirstDayOfMonth(currentMonth);
30
- // getDayOfWeek returns 0 for Sunday, we want Monday = 0
31
- const startOfWeek = getDayOfWeek(firstDay);
32
- const paddingDays = startOfWeek === 0 ? 6 : startOfWeek - 1;
82
+ // getDayOfWeek returns 0 for Sunday, 1 for Monday, etc.
83
+ const dayOfWeek = getDayOfWeek(firstDay);
84
+
85
+ // Calculate padding days based on week start
86
+ let paddingDays: number;
87
+ if (weekStartsOn === 0) {
88
+ // Sunday start: Sunday = 0 padding, Monday = 1, etc.
89
+ paddingDays = dayOfWeek;
90
+ } else {
91
+ // Monday start: Monday = 0 padding, Sunday = 6 padding
92
+ paddingDays = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
93
+ }
33
94
 
34
95
  const days: (Date | null)[] = [];
35
96
 
@@ -55,97 +116,216 @@ const generateMonthDays = (currentMonth: Date): (Date | null)[] => {
55
116
  return days;
56
117
  };
57
118
 
58
- export const CalendarGrid: React.FC<CalendarGridProps> = memo(
59
- ({ value, onChange, minDate, maxDate, disabledDates, themeMode }) => {
60
- const [currentMonth, setCurrentMonth] = React.useState(() =>
61
- getFirstDayOfMonth(value),
62
- );
119
+ export const CalendarGrid: React.FC<CalendarGridProps> = memo((props) => {
120
+ const {
121
+ minDate,
122
+ maxDate,
123
+ disabledDates,
124
+ themeMode,
125
+ weekStartsOn = 0,
126
+ selectionMode = 'single',
127
+ } = props;
128
+
129
+ // Extract mode-specific props
130
+ const singleValue = selectionMode === 'single' ? props.value : null;
131
+ const singleOnChange = selectionMode === 'single' ? props.onChange : null;
132
+ const rangeStart = selectionMode === 'range' ? props.startDate : null;
133
+ const rangeEnd = selectionMode === 'range' ? props.endDate : null;
134
+ const rangeOnChange = selectionMode === 'range' ? props.onRangeChange : null;
63
135
 
64
- const days = useMemo(() => generateMonthDays(currentMonth), [currentMonth]);
136
+ const overrides = useDatePickerOverrides();
137
+ const [currentMonth, setCurrentMonth] = React.useState(() =>
138
+ getFirstDayOfMonth(singleValue ?? rangeStart ?? new Date()),
139
+ );
140
+
141
+ const days = useMemo(
142
+ () => generateMonthDays(currentMonth, weekStartsOn),
143
+ [currentMonth, weekStartsOn],
144
+ );
65
145
 
66
- const todayDate = useMemo(() => today(), []);
146
+ const weekDays =
147
+ weekStartsOn === 0 ? WEEK_DAYS_SUNDAY_START : WEEK_DAYS_MONDAY_START;
67
148
 
68
- const isDisabled = useCallback(
69
- (date: Date | null): boolean => {
70
- if (!date) return true;
71
- if (minDate && compareDates(date, minDate) < 0) return true;
72
- if (maxDate && compareDates(date, maxDate) > 0) return true;
73
- if (disabledDates?.some((d) => isSameDay(date, d))) return true;
149
+ const todayDate = useMemo(() => today(), []);
150
+
151
+ const isDisabled = useCallback(
152
+ (date: Date | null): boolean => {
153
+ if (!date) return true;
154
+ if (minDate && compareDates(date, minDate) < 0) return true;
155
+ if (maxDate && compareDates(date, maxDate) > 0) return true;
156
+ if (disabledDates?.some((d) => isSameDay(date, d))) return true;
157
+ return false;
158
+ },
159
+ [minDate, maxDate, disabledDates],
160
+ );
161
+
162
+ const navigateMonth = useCallback((direction: 1 | -1) => {
163
+ setCurrentMonth((prev) => addMonths(prev, direction));
164
+ }, []);
165
+
166
+ // Handle date press for both single and range modes
167
+ const handleDatePress = useCallback(
168
+ (date: Date) => {
169
+ if (selectionMode === 'single' && singleOnChange) {
170
+ singleOnChange(date);
171
+ } else if (selectionMode === 'range' && rangeOnChange) {
172
+ // Range selection logic:
173
+ // 1. If no start date, set start date
174
+ // 2. If start date but no end date, set end date (if after start)
175
+ // 3. If both dates exist, reset to new start date
176
+ if (!rangeStart || (rangeStart && rangeEnd)) {
177
+ rangeOnChange({ startDate: date, endDate: null });
178
+ } else {
179
+ // Have start but no end
180
+ if (compareDates(date, rangeStart) < 0) {
181
+ // Clicked before start - make this the new start
182
+ rangeOnChange({ startDate: date, endDate: null });
183
+ } else if (isSameDay(date, rangeStart)) {
184
+ // Clicked same day - clear selection
185
+ rangeOnChange({ startDate: date, endDate: null });
186
+ } else {
187
+ // Clicked after start - set as end date
188
+ rangeOnChange({ startDate: rangeStart, endDate: date });
189
+ }
190
+ }
191
+ }
192
+ },
193
+ [selectionMode, singleOnChange, rangeOnChange, rangeStart, rangeEnd],
194
+ );
195
+
196
+ // Check if date is in range (between start and end)
197
+ const isDateInRange = useCallback(
198
+ (date: Date | null): boolean => {
199
+ if (!date || selectionMode !== 'range' || !rangeStart || !rangeEnd) {
74
200
  return false;
75
- },
76
- [minDate, maxDate, disabledDates],
77
- );
201
+ }
202
+ return (
203
+ compareDates(date, rangeStart) > 0 && compareDates(date, rangeEnd) < 0
204
+ );
205
+ },
206
+ [selectionMode, rangeStart, rangeEnd],
207
+ );
78
208
 
79
- const navigateMonth = useCallback((direction: 1 | -1) => {
80
- setCurrentMonth((prev) => addMonths(prev, direction));
81
- }, []);
209
+ const renderDay = useCallback(
210
+ ({ item }: { item: Date | null }) => {
211
+ const isRangeStart =
212
+ selectionMode === 'range' && item && rangeStart
213
+ ? isSameDay(item, rangeStart)
214
+ : false;
215
+ const isRangeEnd =
216
+ selectionMode === 'range' && item && rangeEnd
217
+ ? isSameDay(item, rangeEnd)
218
+ : false;
219
+ const isSelected =
220
+ selectionMode === 'single' && item && singleValue
221
+ ? isSameDay(item, singleValue)
222
+ : false;
82
223
 
83
- const renderDay = useCallback(
84
- ({ item }: { item: Date | null }) => (
224
+ return (
85
225
  <DayCell
86
226
  date={item}
87
- isSelected={item ? isSameDay(item, value) : false}
227
+ isSelected={isSelected}
88
228
  isToday={item ? isSameDay(item, todayDate) : false}
89
229
  isDisabled={isDisabled(item)}
90
230
  isWeekend={
91
231
  item ? getDayOfWeek(item) === 0 || getDayOfWeek(item) === 6 : false
92
232
  }
93
- onPress={item && !isDisabled(item) ? () => onChange(item) : undefined}
94
- />
95
- ),
96
- [value, todayDate, isDisabled, onChange],
97
- );
98
-
99
- const keyExtractor = useCallback(
100
- (item: Date | null, index: number) =>
101
- item?.toISOString() ?? `empty-${index}`,
102
- [],
103
- );
104
-
105
- const getItemLayout = useCallback(
106
- (_data: ArrayLike<Date | null> | null | undefined, index: number) => ({
107
- length: CELL_SIZE,
108
- offset: CELL_SIZE * Math.floor(index / 7),
109
- index,
110
- }),
111
- [],
112
- );
113
-
114
- return (
115
- <View style={styles.container}>
116
- <View style={styles.header}>
117
- <Pressable onPress={() => navigateMonth(-1)} style={styles.navButton}>
118
- <Text style={styles.navText}>‹</Text>
119
- </Pressable>
120
- <Text style={styles.monthTitle}>{formatYearMonth(currentMonth)}</Text>
121
- <Pressable onPress={() => navigateMonth(1)} style={styles.navButton}>
122
- <Text style={styles.navText}>›</Text>
123
- </Pressable>
124
- </View>
125
-
126
- <View style={styles.weekDays}>
127
- {WEEK_DAYS.map((day) => (
128
- <Text key={day} style={styles.weekDayText}>
129
- {day}
130
- </Text>
131
- ))}
132
- </View>
133
-
134
- <FlatList
135
- data={days}
136
- renderItem={renderDay}
137
- keyExtractor={keyExtractor}
138
- getItemLayout={getItemLayout}
139
- numColumns={7}
140
- scrollEnabled={false}
141
- removeClippedSubviews={true}
142
- maxToRenderPerBatch={14}
143
- windowSize={3}
144
- initialNumToRender={42}
233
+ isRangeStart={isRangeStart}
234
+ isRangeEnd={isRangeEnd}
235
+ isInRange={isDateInRange(item)}
236
+ onPress={
237
+ item && !isDisabled(item) ? () => handleDatePress(item) : undefined
238
+ }
145
239
  />
240
+ );
241
+ },
242
+ [
243
+ selectionMode,
244
+ singleValue,
245
+ rangeStart,
246
+ rangeEnd,
247
+ todayDate,
248
+ isDisabled,
249
+ isDateInRange,
250
+ handleDatePress,
251
+ ],
252
+ );
253
+
254
+ const keyExtractor = useCallback(
255
+ (item: Date | null, index: number) =>
256
+ item?.toISOString() ?? `empty-${index}`,
257
+ [],
258
+ );
259
+
260
+ const getItemLayout = useCallback(
261
+ (_data: ArrayLike<Date | null> | null | undefined, index: number) => ({
262
+ length: CELL_SIZE,
263
+ offset: CELL_SIZE * Math.floor(index / 7),
264
+ index,
265
+ }),
266
+ [],
267
+ );
268
+
269
+ // Build override styles from themeOverrides
270
+ const containerStyle = useMemo(
271
+ () => ({
272
+ backgroundColor: overrides?.backgroundColor ?? '#1E1E1E',
273
+ borderRadius: overrides?.borderRadius ?? 16,
274
+ padding: overrides?.padding ?? 16,
275
+ }),
276
+ [overrides],
277
+ );
278
+
279
+ const navTextStyle = useMemo(
280
+ () => ({
281
+ color: overrides?.primaryColor ?? '#4DA6FF',
282
+ }),
283
+ [overrides],
284
+ );
285
+
286
+ const monthTitleStyle = useMemo(
287
+ () => ({
288
+ color: overrides?.textColor ?? '#FFFFFF',
289
+ }),
290
+ [overrides],
291
+ );
292
+
293
+ return (
294
+ <View style={[styles.container, containerStyle]}>
295
+ <View style={styles.header}>
296
+ <Pressable onPress={() => navigateMonth(-1)} style={styles.navButton}>
297
+ <Text style={[styles.navText, navTextStyle]}>‹</Text>
298
+ </Pressable>
299
+ <Text style={[styles.monthTitle, monthTitleStyle]}>
300
+ {formatYearMonth(currentMonth)}
301
+ </Text>
302
+ <Pressable onPress={() => navigateMonth(1)} style={styles.navButton}>
303
+ <Text style={[styles.navText, navTextStyle]}>›</Text>
304
+ </Pressable>
305
+ </View>
306
+
307
+ <View style={styles.weekDays}>
308
+ {weekDays.map((day) => (
309
+ <Text key={day} style={styles.weekDayText}>
310
+ {day}
311
+ </Text>
312
+ ))}
146
313
  </View>
147
- );
148
- },
149
- );
314
+
315
+ <FlatList
316
+ data={days}
317
+ renderItem={renderDay}
318
+ keyExtractor={keyExtractor}
319
+ getItemLayout={getItemLayout}
320
+ numColumns={7}
321
+ scrollEnabled={false}
322
+ removeClippedSubviews={true}
323
+ maxToRenderPerBatch={14}
324
+ windowSize={3}
325
+ initialNumToRender={42}
326
+ />
327
+ </View>
328
+ );
329
+ });
150
330
 
151
331
  CalendarGrid.displayName = 'CalendarGrid';