@umituz/react-native-design-system 2.3.13 → 2.3.15
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/package.json +32 -13
- package/src/index.ts +116 -0
- package/src/layouts/ScreenLayout/ScreenLayout.example.tsx +2 -2
- package/src/layouts/ScreenLayout/ScreenLayout.tsx +1 -1
- package/src/molecules/animation/core/AnimationCore.ts +29 -0
- package/src/molecules/animation/domain/entities/Animation.ts +81 -0
- package/src/molecules/animation/domain/entities/Fireworks.ts +44 -0
- package/src/molecules/animation/domain/entities/Theme.ts +76 -0
- package/src/molecules/animation/index.ts +146 -0
- package/src/molecules/animation/infrastructure/services/AnimationConfigService.ts +35 -0
- package/src/molecules/animation/infrastructure/services/SpringAnimationConfigService.ts +67 -0
- package/src/molecules/animation/infrastructure/services/TimingAnimationConfigService.ts +57 -0
- package/src/molecules/animation/infrastructure/services/__tests__/SpringAnimationConfigService.test.ts +114 -0
- package/src/molecules/animation/infrastructure/services/__tests__/TimingAnimationConfigService.test.ts +105 -0
- package/src/molecules/animation/presentation/components/Fireworks.tsx +126 -0
- package/src/molecules/animation/presentation/components/__tests__/Fireworks.test.tsx +189 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useAnimation.integration.test.ts +216 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useFireworks.test.ts +242 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useGesture.test.ts +111 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useSpringAnimation.test.ts +131 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useTimingAnimation.test.ts +175 -0
- package/src/molecules/animation/presentation/hooks/__tests__/useTransformAnimation.test.ts +137 -0
- package/src/molecules/animation/presentation/hooks/useAnimation.ts +77 -0
- package/src/molecules/animation/presentation/hooks/useFireworks.ts +141 -0
- package/src/molecules/animation/presentation/hooks/useGesture.ts +61 -0
- package/src/molecules/animation/presentation/hooks/useGestureCreators.ts +163 -0
- package/src/molecules/animation/presentation/hooks/useGestureState.ts +53 -0
- package/src/molecules/animation/presentation/hooks/useIconAnimations.ts +119 -0
- package/src/molecules/animation/presentation/hooks/useModalAnimations.ts +124 -0
- package/src/molecules/animation/presentation/hooks/useReanimatedReady.ts +60 -0
- package/src/molecules/animation/presentation/hooks/useSpringAnimation.ts +69 -0
- package/src/molecules/animation/presentation/hooks/useTimingAnimation.ts +111 -0
- package/src/molecules/animation/presentation/hooks/useTransformAnimation.ts +57 -0
- package/src/molecules/animation/presentation/providers/AnimationThemeProvider.tsx +62 -0
- package/src/molecules/animation/presentation/providers/__tests__/AnimationThemeProvider.test.tsx +165 -0
- package/src/molecules/animation/types/global.d.ts +97 -0
- package/src/molecules/calendar/domain/entities/CalendarDay.entity.ts +115 -0
- package/src/molecules/calendar/domain/entities/CalendarEvent.entity.ts +202 -0
- package/src/molecules/calendar/domain/repositories/ICalendarRepository.ts +120 -0
- package/src/molecules/calendar/index.ts +98 -0
- package/src/molecules/calendar/infrastructure/services/CalendarEvents.ts +196 -0
- package/src/molecules/calendar/infrastructure/services/CalendarGeneration.ts +172 -0
- package/src/molecules/calendar/infrastructure/services/CalendarPermissions.ts +92 -0
- package/src/molecules/calendar/infrastructure/services/CalendarService.ts +161 -0
- package/src/molecules/calendar/infrastructure/services/CalendarSync.ts +205 -0
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts +307 -0
- package/src/molecules/calendar/infrastructure/utils/DateUtilities.ts +128 -0
- package/src/molecules/calendar/presentation/components/AtomicCalendar.tsx +279 -0
- package/src/molecules/calendar/presentation/hooks/useCalendar.ts +356 -0
- package/src/molecules/celebration/domain/entities/CelebrationConfig.ts +17 -0
- package/src/molecules/celebration/domain/entities/FireworksConfig.ts +32 -0
- package/src/molecules/celebration/index.ts +93 -0
- package/src/molecules/celebration/infrastructure/services/FireworksConfigService.ts +49 -0
- package/src/molecules/celebration/presentation/components/CelebrationFireworksOverlay.tsx +33 -0
- package/src/molecules/celebration/presentation/components/CelebrationModal.tsx +78 -0
- package/src/molecules/celebration/presentation/components/CelebrationModalContent.tsx +90 -0
- package/src/molecules/celebration/presentation/hooks/useCelebrationModalAnimation.ts +49 -0
- package/src/molecules/celebration/presentation/hooks/useCelebrationState.ts +45 -0
- package/src/molecules/celebration/presentation/styles/CelebrationModalStyles.ts +65 -0
- package/src/molecules/countdown/components/Countdown.tsx +128 -0
- package/src/molecules/countdown/components/CountdownHeader.tsx +84 -0
- package/src/molecules/countdown/components/TimeUnit.tsx +73 -0
- package/src/molecules/countdown/hooks/useCountdown.ts +107 -0
- package/src/molecules/countdown/index.ts +25 -0
- package/src/molecules/countdown/types/CountdownTypes.ts +31 -0
- package/src/molecules/countdown/utils/TimeCalculator.ts +46 -0
- package/src/molecules/emoji/domain/entities/Emoji.ts +129 -0
- package/src/molecules/emoji/index.ts +177 -0
- package/src/molecules/emoji/presentation/components/EmojiPicker.tsx +102 -0
- package/src/molecules/emoji/presentation/hooks/useEmojiPicker.ts +171 -0
- package/src/molecules/index.ts +24 -0
- package/src/molecules/long-press-menu/domain/entities/MenuAction.ts +37 -0
- package/src/molecules/long-press-menu/index.ts +16 -0
- package/src/molecules/navigation/StackNavigator.tsx +75 -0
- package/src/molecules/navigation/TabsNavigator.tsx +94 -0
- package/src/molecules/navigation/components/FabButton.tsx +45 -0
- package/src/molecules/navigation/components/TabLabel.tsx +47 -0
- package/src/molecules/navigation/createStackNavigator.ts +20 -0
- package/src/molecules/navigation/createTabNavigator.ts +20 -0
- package/src/molecules/navigation/hooks/useTabBarStyles.ts +54 -0
- package/src/molecules/navigation/index.ts +37 -0
- package/src/molecules/navigation/types.ts +118 -0
- package/src/molecules/navigation/utils/AppNavigation.ts +101 -0
- package/src/molecules/navigation/utils/IconRenderer.ts +50 -0
- package/src/molecules/navigation/utils/LabelProcessor.ts +70 -0
- package/src/molecules/navigation/utils/NavigationCleanup.ts +62 -0
- package/src/molecules/navigation/utils/NavigationTheme.ts +21 -0
- package/src/molecules/navigation/utils/NavigationValidator.ts +61 -0
- package/src/molecules/navigation/utils/ScreenFactory.ts +115 -0
- package/src/molecules/navigation/utils/__tests__/IconRenderer.getIconName.test.ts +109 -0
- package/src/molecules/navigation/utils/__tests__/IconRenderer.renderIcon.test.ts +116 -0
- package/src/molecules/navigation/utils/__tests__/LabelProcessor.processLabel.test.ts +116 -0
- package/src/molecules/navigation/utils/__tests__/LabelProcessor.processTitle.test.ts +59 -0
- package/src/molecules/navigation/utils/__tests__/NavigationCleanup.test.ts +271 -0
- package/src/molecules/navigation/utils/__tests__/NavigationValidator.test.ts +252 -0
- package/src/molecules/swipe-actions/domain/entities/SwipeAction.ts +194 -0
- package/src/molecules/swipe-actions/index.ts +6 -0
- package/src/molecules/swipe-actions/presentation/components/SwipeActionButton.tsx +131 -0
- package/src/theme/hooks/useResponsiveDesignTokens.ts +1 -1
- package/src/utilities/clipboard/ClipboardUtils.ts +71 -0
- package/src/utilities/clipboard/index.ts +5 -0
- package/src/utilities/index.ts +6 -0
- package/src/utilities/sharing/domain/entities/Share.ts +210 -0
- package/src/utilities/sharing/index.ts +205 -0
- package/src/utilities/sharing/infrastructure/services/SharingService.ts +165 -0
- package/src/utilities/sharing/presentation/hooks/useSharing.ts +154 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date Utilities
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for date operations and formatting.
|
|
5
|
+
* No side effects, timezone-aware operations.
|
|
6
|
+
*
|
|
7
|
+
* SOLID: Single Responsibility - Only date operations
|
|
8
|
+
* DRY: Reusable date utility functions
|
|
9
|
+
* KISS: Simple, focused functions
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export class DateUtilities {
|
|
13
|
+
/**
|
|
14
|
+
* Format date to string (YYYY-MM-DD)
|
|
15
|
+
*/
|
|
16
|
+
static formatDateToString(date: Date): string {
|
|
17
|
+
return date.toISOString().split('T')[0];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Check if two dates are the same day
|
|
22
|
+
*/
|
|
23
|
+
static isSameDay(date1: Date, date2: Date): boolean {
|
|
24
|
+
return this.formatDateToString(date1) === this.formatDateToString(date2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Add days to a date
|
|
29
|
+
*/
|
|
30
|
+
static addDays(date: Date, days: number): Date {
|
|
31
|
+
const result = new Date(date);
|
|
32
|
+
result.setDate(result.getDate() + days);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if date is today
|
|
38
|
+
*/
|
|
39
|
+
static isToday(date: Date): boolean {
|
|
40
|
+
return this.isSameDay(date, new Date());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get current timezone
|
|
45
|
+
*/
|
|
46
|
+
static getCurrentTimezone(): string {
|
|
47
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get start of month
|
|
52
|
+
*/
|
|
53
|
+
static getStartOfMonth(date: Date): Date {
|
|
54
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get end of month
|
|
59
|
+
*/
|
|
60
|
+
static getEndOfMonth(date: Date): Date {
|
|
61
|
+
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get number of days in month
|
|
66
|
+
*/
|
|
67
|
+
static getDaysInMonth(date: Date): number {
|
|
68
|
+
return this.getEndOfMonth(date).getDate();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get start of week (Sunday)
|
|
73
|
+
*/
|
|
74
|
+
static getStartOfWeek(date: Date): Date {
|
|
75
|
+
const result = new Date(date);
|
|
76
|
+
const day = result.getDay();
|
|
77
|
+
const diff = result.getDate() - day;
|
|
78
|
+
return new Date(result.setDate(diff));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get end of week (Saturday)
|
|
83
|
+
*/
|
|
84
|
+
static getEndOfWeek(date: Date): Date {
|
|
85
|
+
const result = this.getStartOfWeek(date);
|
|
86
|
+
result.setDate(result.getDate() + 6);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Parse date from string (YYYY-MM-DD)
|
|
92
|
+
*/
|
|
93
|
+
static parseDate(dateString: string): Date {
|
|
94
|
+
const [year, month, day] = dateString.split('-').map(Number);
|
|
95
|
+
return new Date(year, month - 1, day);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Format time to string (HH:MM)
|
|
100
|
+
*/
|
|
101
|
+
static formatTimeToString(date: Date): string {
|
|
102
|
+
return date.toTimeString().slice(0, 5);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check if date is in the past
|
|
107
|
+
*/
|
|
108
|
+
static isPast(date: Date): boolean {
|
|
109
|
+
return date < new Date();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Check if date is in the future
|
|
114
|
+
*/
|
|
115
|
+
static isFuture(date: Date): boolean {
|
|
116
|
+
return date > new Date();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AtomicCalendar Component
|
|
3
|
+
*
|
|
4
|
+
* Generic, reusable calendar component with month view.
|
|
5
|
+
* Works with any type of events (workouts, habits, tasks, etc.)
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Monthly grid view (42 days = 6 weeks)
|
|
9
|
+
* - Timezone-aware via calendar service
|
|
10
|
+
* - Event indicators (colored dots)
|
|
11
|
+
* - Customizable styling
|
|
12
|
+
* - Accessible
|
|
13
|
+
* - Theme-aware
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```tsx
|
|
17
|
+
* import { AtomicCalendar, useCalendar } from '@umituz/react-native-calendar';
|
|
18
|
+
*
|
|
19
|
+
* const MyScreen = () => {
|
|
20
|
+
* const { days, selectedDate, actions } = useCalendar();
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <AtomicCalendar
|
|
24
|
+
* days={days}
|
|
25
|
+
* selectedDate={selectedDate}
|
|
26
|
+
* onDateSelect={actions.setSelectedDate}
|
|
27
|
+
* />
|
|
28
|
+
* );
|
|
29
|
+
* };
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import React from 'react';
|
|
34
|
+
import { View, TouchableOpacity, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
|
35
|
+
import { useAppDesignTokens, AtomicText } from '../../../../index';
|
|
36
|
+
import type { CalendarDay } from '../../domain/entities/CalendarDay.entity';
|
|
37
|
+
import { CalendarService } from '../../infrastructure/services/CalendarService';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* AtomicCalendar Props
|
|
41
|
+
*/
|
|
42
|
+
export interface AtomicCalendarProps {
|
|
43
|
+
/**
|
|
44
|
+
* Calendar days to display (42 days for 6-week grid)
|
|
45
|
+
*/
|
|
46
|
+
days: CalendarDay[];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Currently selected date
|
|
50
|
+
*/
|
|
51
|
+
selectedDate: Date;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Callback when a date is selected
|
|
55
|
+
*/
|
|
56
|
+
onDateSelect: (date: Date) => void;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Whether to show weekday headers
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
showWeekdayHeaders?: boolean;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Maximum number of event indicators to show per day
|
|
66
|
+
* @default 3
|
|
67
|
+
*/
|
|
68
|
+
maxEventIndicators?: number;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Custom container style
|
|
72
|
+
*/
|
|
73
|
+
style?: StyleProp<ViewStyle>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Custom day cell style
|
|
77
|
+
*/
|
|
78
|
+
dayStyle?: StyleProp<ViewStyle>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Whether to show event count when exceeds max indicators
|
|
82
|
+
* @default true
|
|
83
|
+
*/
|
|
84
|
+
showEventCount?: boolean;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Test ID for testing
|
|
88
|
+
*/
|
|
89
|
+
testID?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* AtomicCalendar Component
|
|
94
|
+
*/
|
|
95
|
+
export const AtomicCalendar: React.FC<AtomicCalendarProps> = ({
|
|
96
|
+
days,
|
|
97
|
+
selectedDate,
|
|
98
|
+
onDateSelect,
|
|
99
|
+
showWeekdayHeaders = true,
|
|
100
|
+
maxEventIndicators = 3,
|
|
101
|
+
style,
|
|
102
|
+
dayStyle,
|
|
103
|
+
showEventCount = true,
|
|
104
|
+
testID,
|
|
105
|
+
}) => {
|
|
106
|
+
const tokens = useAppDesignTokens();
|
|
107
|
+
|
|
108
|
+
// Get weekday names (localized)
|
|
109
|
+
const weekdayNames = CalendarService.getWeekdayNames();
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<View style={[styles.container, { backgroundColor: tokens.colors.surface }, style]} testID={testID}>
|
|
113
|
+
{/* Weekday Headers */}
|
|
114
|
+
{showWeekdayHeaders && (
|
|
115
|
+
<View style={styles.weekdayHeader}>
|
|
116
|
+
{weekdayNames.map((day, index) => (
|
|
117
|
+
<View key={index} style={styles.weekdayCell}>
|
|
118
|
+
<AtomicText
|
|
119
|
+
type="bodySmall"
|
|
120
|
+
color="secondary"
|
|
121
|
+
style={styles.weekdayText}
|
|
122
|
+
>
|
|
123
|
+
{day}
|
|
124
|
+
</AtomicText>
|
|
125
|
+
</View>
|
|
126
|
+
))}
|
|
127
|
+
</View>
|
|
128
|
+
)}
|
|
129
|
+
|
|
130
|
+
{/* Calendar Grid */}
|
|
131
|
+
<View style={styles.grid}>
|
|
132
|
+
{days.map((day, index) => {
|
|
133
|
+
const isSelected = CalendarService.isSameDay(day.date, selectedDate);
|
|
134
|
+
const eventCount = day.events.length;
|
|
135
|
+
const visibleEvents = day.events.slice(0, maxEventIndicators);
|
|
136
|
+
const hiddenEventCount = Math.max(0, eventCount - maxEventIndicators);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<TouchableOpacity
|
|
140
|
+
key={index}
|
|
141
|
+
style={[
|
|
142
|
+
styles.dayCell,
|
|
143
|
+
{
|
|
144
|
+
backgroundColor: isSelected
|
|
145
|
+
? tokens.colors.primary
|
|
146
|
+
: 'transparent',
|
|
147
|
+
borderColor: isSelected
|
|
148
|
+
? tokens.colors.primary
|
|
149
|
+
: day.isToday
|
|
150
|
+
? tokens.colors.primary
|
|
151
|
+
: tokens.colors.border,
|
|
152
|
+
borderWidth: isSelected ? 2 : day.isToday ? 2 : 1,
|
|
153
|
+
opacity: day.isDisabled ? 0.4 : 1,
|
|
154
|
+
},
|
|
155
|
+
dayStyle,
|
|
156
|
+
]}
|
|
157
|
+
onPress={() => !day.isDisabled && onDateSelect(day.date)}
|
|
158
|
+
disabled={day.isDisabled}
|
|
159
|
+
testID={testID ? `${testID}-day-${index}` : undefined}
|
|
160
|
+
accessibilityLabel={`${day.date.toLocaleDateString()}, ${eventCount} events`}
|
|
161
|
+
accessibilityRole="button"
|
|
162
|
+
accessibilityState={{ disabled: day.isDisabled, selected: isSelected }}
|
|
163
|
+
>
|
|
164
|
+
{/* Day Number */}
|
|
165
|
+
<AtomicText
|
|
166
|
+
type="bodyMedium"
|
|
167
|
+
color={
|
|
168
|
+
isSelected
|
|
169
|
+
? 'inverse'
|
|
170
|
+
: day.isCurrentMonth
|
|
171
|
+
? 'primary'
|
|
172
|
+
: 'secondary'
|
|
173
|
+
}
|
|
174
|
+
style={[
|
|
175
|
+
styles.dayText,
|
|
176
|
+
day.isToday && !isSelected && { fontWeight: 'bold' },
|
|
177
|
+
]}
|
|
178
|
+
>
|
|
179
|
+
{day.date.getDate()}
|
|
180
|
+
</AtomicText>
|
|
181
|
+
|
|
182
|
+
{/* Event Indicators */}
|
|
183
|
+
<View style={styles.eventIndicators}>
|
|
184
|
+
{/* Today indicator (if today and has no events) */}
|
|
185
|
+
{day.isToday && eventCount === 0 && (
|
|
186
|
+
<View
|
|
187
|
+
style={[
|
|
188
|
+
styles.eventDot,
|
|
189
|
+
{ backgroundColor: tokens.colors.success },
|
|
190
|
+
]}
|
|
191
|
+
/>
|
|
192
|
+
)}
|
|
193
|
+
|
|
194
|
+
{/* Event dots */}
|
|
195
|
+
{visibleEvents.map((event, eventIndex) => (
|
|
196
|
+
<View
|
|
197
|
+
key={eventIndex}
|
|
198
|
+
style={[
|
|
199
|
+
styles.eventDot,
|
|
200
|
+
{
|
|
201
|
+
backgroundColor: event.color
|
|
202
|
+
? event.color
|
|
203
|
+
: event.isCompleted
|
|
204
|
+
? tokens.colors.success
|
|
205
|
+
: tokens.colors.primary,
|
|
206
|
+
},
|
|
207
|
+
]}
|
|
208
|
+
/>
|
|
209
|
+
))}
|
|
210
|
+
|
|
211
|
+
{/* More events count */}
|
|
212
|
+
{showEventCount && hiddenEventCount > 0 && (
|
|
213
|
+
<AtomicText
|
|
214
|
+
type="bodySmall"
|
|
215
|
+
color="secondary"
|
|
216
|
+
style={styles.moreEventsText}
|
|
217
|
+
>
|
|
218
|
+
+{hiddenEventCount}
|
|
219
|
+
</AtomicText>
|
|
220
|
+
)}
|
|
221
|
+
</View>
|
|
222
|
+
</TouchableOpacity>
|
|
223
|
+
);
|
|
224
|
+
})}
|
|
225
|
+
</View>
|
|
226
|
+
</View>
|
|
227
|
+
);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const styles = StyleSheet.create({
|
|
231
|
+
container: {
|
|
232
|
+
borderRadius: 12,
|
|
233
|
+
padding: 16,
|
|
234
|
+
},
|
|
235
|
+
weekdayHeader: {
|
|
236
|
+
flexDirection: 'row',
|
|
237
|
+
marginBottom: 12,
|
|
238
|
+
},
|
|
239
|
+
weekdayCell: {
|
|
240
|
+
flex: 1,
|
|
241
|
+
alignItems: 'center',
|
|
242
|
+
},
|
|
243
|
+
weekdayText: {
|
|
244
|
+
textAlign: 'center',
|
|
245
|
+
},
|
|
246
|
+
grid: {
|
|
247
|
+
flexDirection: 'row',
|
|
248
|
+
flexWrap: 'wrap',
|
|
249
|
+
},
|
|
250
|
+
dayCell: {
|
|
251
|
+
width: `${100 / 7}%`,
|
|
252
|
+
aspectRatio: 1,
|
|
253
|
+
justifyContent: 'center',
|
|
254
|
+
alignItems: 'center',
|
|
255
|
+
borderRadius: 8,
|
|
256
|
+
marginBottom: 4,
|
|
257
|
+
padding: 4,
|
|
258
|
+
},
|
|
259
|
+
dayText: {
|
|
260
|
+
textAlign: 'center',
|
|
261
|
+
},
|
|
262
|
+
eventIndicators: {
|
|
263
|
+
flexDirection: 'row',
|
|
264
|
+
alignItems: 'center',
|
|
265
|
+
justifyContent: 'center',
|
|
266
|
+
marginTop: 4,
|
|
267
|
+
gap: 2,
|
|
268
|
+
flexWrap: 'wrap',
|
|
269
|
+
},
|
|
270
|
+
eventDot: {
|
|
271
|
+
width: 4,
|
|
272
|
+
height: 4,
|
|
273
|
+
borderRadius: 2,
|
|
274
|
+
},
|
|
275
|
+
moreEventsText: {
|
|
276
|
+
fontSize: 8,
|
|
277
|
+
marginLeft: 2,
|
|
278
|
+
},
|
|
279
|
+
});
|