Back to Components

Solid Calendar

Calendars
3 months ago

About

Calendar

A sophisticated React Native calendar component with infinite scrolling, pinch-to-zoom functionality, and real-time event management. Built with React Native Reanimated for smooth animations and optimized performance.

๐Ÿš€ Features

  • Infinite Scrolling: Seamlessly navigate through dates with edge loading
  • Pinch-to-Zoom: Adjust time scale from 0.5x to 3x with smooth animations
  • Real-time Current Time Indicator: Shows current time with live updates
  • Event Management: Display events with custom colors and time ranges
  • Month Picker Modal: Quick date selection with month/year navigation
  • Responsive Design: Adapts to different screen sizes and orientations
  • Performance Optimized: Uses React.memo, useCallback, and efficient re-renders
  • TypeScript Support: Full type safety with comprehensive interfaces

๐Ÿ“ Project Structure

booking-planner/ โ”œโ”€โ”€ components/ โ”‚ โ”œโ”€โ”€ DayColumn.tsx # Individual day column component โ”‚ โ”œโ”€โ”€ EventBlock.tsx # Event display component โ”‚ โ”œโ”€โ”€ HourGridRow.tsx # Hour grid row component โ”‚ โ”œโ”€โ”€ MonthPicker.tsx # Month picker modal โ”‚ โ””โ”€โ”€ TimeLabel.tsx # Time label component โ”œโ”€โ”€ constants/ โ”‚ โ””โ”€โ”€ index.ts # App constants and sample events โ”œโ”€โ”€ hooks/ โ”‚ โ””โ”€โ”€ useCalendarData.ts # Calendar data management hook โ”œโ”€โ”€ types/ โ”‚ โ””โ”€โ”€ index.ts # TypeScript interfaces โ”œโ”€โ”€ utils/ โ”‚ โ””โ”€โ”€ index.ts # Utility functions โ”œโ”€โ”€ _layout.tsx # Navigation layout โ”œโ”€โ”€ index.tsx # Main calendar component โ””โ”€โ”€ README.md

๐Ÿ› ๏ธ Setup Instructions

1. Prerequisites

Ensure you have the following dependencies in your package.json:

json
{ "dependencies": { "react-native-reanimated": "^3.0.0", "react-native-gesture-handler": "^2.0.0", "@expo/vector-icons": "^13.0.0", "@react-navigation/drawer": "^6.0.0" } }

2. Context Setup

Wrap your app with the CalendarProvider:

tsx
// App.tsx or your root component import { CalendarProvider } from '@/contexts/CalendarContext'; export default function App() { return ( <CalendarProvider> {/* Your app components */} </CalendarProvider> ); }

3. Navigation Integration

Add the calendar to your navigation stack:

tsx
// In your navigation configuration import BookingPlanner from '@/app/booking-planner/index'; // Add to your stack navigator <Stack.Screen name="booking-planner" component={BookingPlanner} />

Or navigate to the route directly:

tsx
// Navigate to the booking planner navigation.navigate('booking-planner');

4. Gesture Handler Setup

Ensure GestureHandlerRootView wraps your app:

tsx
import { GestureHandlerRootView } from 'react-native-gesture-handler'; export default function App() { return ( <GestureHandlerRootView style={{ flex: 1 }}> <CalendarProvider> {/* Your app */} </CalendarProvider> </GestureHandlerRootView> ); }

๐ŸŽฏ Core Components

Main Calendar (index.tsx)

The main calendar component that orchestrates all functionality:

  • Infinite Scrolling: Loads days dynamically as user scrolls
  • Pinch Gesture: Handles zoom functionality with Gesture.Pinch()
  • Synchronized Scrolling: Keeps header and body in sync
  • Current Time Indicator: Shows live current time position

Event Management

Events are defined with the following interface:

tsx
interface EventItem { id: string; title: string; date: string; // YYYY-MM-DD format start: string; // HH:mm format end: string; // HH:mm format color: string; // Hex color code }

Data Hook (useCalendarData.ts)

Manages calendar state and data loading:

  • Day Generation: Creates date ranges for infinite scrolling
  • Event Filtering: Filters events by date
  • Loading States: Handles future/past day loading
  • Date Selection: Manages selected and viewing dates

๐ŸŽจ Customization

Constants Configuration

Modify constants/index.ts to customize:

tsx
export const DEFAULT_CELL_HEIGHT = 60; // Default hour height export const MIN_SCALE = 0.5; // Minimum zoom level export const MAX_SCALE = 3; // Maximum zoom level export const TIME_COLUMN_WIDTH = 60; // Time column width export const ALL_DAY_HEIGHT = 40; // All-day section height

Event Colors

Update the SAMPLE_EVENTS array in constants/index.ts:

tsx
export const SAMPLE_EVENTS = [ { id: '1', title: 'Meeting', date: '2025-01-15', start: '09:00', end: '10:00', color: '#FFDAD2', // Custom color }, // ... more events ];

Styling

Customize component styles in their respective files:

  • EventBlock.tsx: Event appearance and layout
  • TimeLabel.tsx: Time label styling
  • DayColumn.tsx: Day column appearance
  • MonthPicker.tsx: Month picker modal styling

๐Ÿ”ง Advanced Usage

Custom Event Rendering

Override the default event rendering:

tsx
// In your calendar component const renderEvent = useCallback((event: EventItem) => ( <CustomEventBlock event={event} cellHeightSV={cellHeight} /> ), [cellHeight]);

Custom Data Source

Replace the sample events with your data source:

tsx
// In useCalendarData.ts const getEventsByDayCallback = useCallback( (d: Date) => getEventsByDay(YOUR_EVENTS_DATA, d), [] );

Calendar Context Integration

Access calendar state from anywhere:

tsx
import { useCalendar } from '@/contexts/CalendarContext'; function MyComponent() { const { numberOfDays, setNumberOfDays } = useCalendar(); // Change view (1, 3, 7 days) const changeView = (days: number) => { setNumberOfDays(days); }; }

๐ŸŽฎ User Interactions

Navigation

  • Horizontal Swipe: Navigate between days
  • Pinch Gesture: Zoom in/out of time scale
  • Tap Events: Select events (customize in EventBlock)
  • Month Picker: Tap header date to open month picker

Gestures

  • Pinch: Adjust time scale (0.5x - 3x)
  • Scroll: Infinite day navigation
  • Tap: Event selection and date picking

๐Ÿ“ฑ Performance Optimizations

React.memo Usage

All components are wrapped with React.memo for efficient re-renders.

Shared Values

Uses useSharedValue for smooth animations:

  • cellHeight: Controls zoom level
  • minutesSV: Tracks current time
  • baseScale: Manages pinch gesture

Efficient Rendering

  • FlatList with getItemLayout for predictable scrolling
  • initialNumToRender and maxToRenderPerBatch optimization
  • removeClippedSubviews for memory management

๐Ÿ” Troubleshooting

Common Issues

  1. Gesture Handler Not Working

    • Ensure GestureHandlerRootView wraps your app
    • Check gesture handler installation
  2. Animations Not Smooth

    • Verify Reanimated 3.x installation
    • Check for conflicting gesture handlers
  3. Events Not Displaying

    • Verify event date format (YYYY-MM-DD)
    • Check time format (HH:mm)
    • Ensure events array is properly structured
  4. Performance Issues

    • Implement virtual scrolling for large datasets
    • Use React.memo for custom components

Debug Mode

Enable debug logging by adding console logs in key functions:

tsx
// In useCalendarData.ts const loadDaysAround = useCallback((anchor: Date) => { console.log('Loading days around:', anchor); // ... existing code }, []);

๐Ÿ“„ License

This component is part of the landingcomponents.com library.

Posted by

E

eren

@eren