Skip to content

Conversation

@anton-patrushev
Copy link

@anton-patrushev anton-patrushev commented Nov 28, 2025

Summary

This PR implements dual-axis scrolling for resource view mode, enabling users to scroll through dates (horizontally) while simultaneously navigating through resources with per-resource snapping. Previously, calendar users faced a limiting constraint: they could either (1) scroll by days and render all resources at once, or (2) render a subset of resources with pagination but lose the ability to navigate by date. This dichotomy created a poor UX for applications with many resources.

This feature is a critical requirement from our product management and design teams, essential for delivering the intended user experience in our production application.

The implementation fundamentally changes how the resource view handles scrolling and rendering:

  • Scroll by day while viewing a paginated subset of resources
  • Resource snapping at each resource position within the visible day
  • Intelligent snap positioning that ensures resources remain within day boundaries
  • Full event rendering across all visible days and resource columns to eliminate UI jumping
  • Complete calendar ref API support for programmatic navigation (goToDate, goToNextPage, goToPrevPage, goToNextResource, goToPrevResource)
  • Drag-n-Drop features support for resources view specifically (both drag-to-create and drag-to-edit)

Changes

Core Architecture Changes

CalendarContainer (packages/react-native-calendar-kit/src/CalendarContainer.tsx:184-509)

  • Modified numberOfDays calculation to support multi-day rendering in resource mode when enableResourceScroll is enabled
  • Implemented day-based scroll offset calculation for resource mode that accounts for resource width
  • Enhanced goToDate to properly navigate to specific dates in resource scroll mode with automatic offset calculation
  • Updated goToNextPage and goToPrevPage to handle date changes in resource mode with proper scroll synchronization
  • Refactored goToNextResource and goToPrevResource to support both per-resource and per-page navigation with proper bounds checking

ResourceListView (packages/react-native-calendar-kit/src/components/Resource/ResourceListView.tsx:24-179)

  • Introduced dual-axis mode via new DateResourceItem interface combining date and resource data
  • Added support for snapToOffsets array for intelligent snap positioning
  • Implemented onScrollOffsetChange callback for scroll state tracking
  • Enhanced visible range calculations to support both item-based and page-based rendering
  • Added initialOffset support for proper scroll position restoration

ResourceBoard (packages/react-native-calendar-kit/src/components/Resource/ResourceBoard.tsx)

  • Integrated snap offset calculation algorithm
  • Connected scroll offset tracking to parent container

ResourceContainers (packages/react-native-calendar-kit/src/components/Resource/ResourceContainers.tsx)

  • Updated to generate date-resource item combinations for dual-axis rendering
  • Enhanced layout calculations for multi-day resource grids

Event Rendering Improvements

EventsProvider (packages/react-native-calendar-kit/src/context/EventsProvider.tsx)

  • Modified event filtering to render events for all visible days and resource columns
  • Eliminates event jumping during scroll by pre-rendering events in adjacent positions

EventItem (packages/react-native-calendar-kit/src/components/EventItem.tsx)

  • Updated position calculations to account for resource mode with date scrolling
  • Enhanced event layout logic for multi-day resource grids

DragEventProvider (packages/react-native-calendar-kit/src/context/DragEventProvider.tsx:98)

  • Fixed drag-and-drop positioning for dual-axis scrolling
  • Updated event creation/editing to work correctly in both regular and resource view modes
  • Adjusted animations and gesture handling for drag-n-drop to support resources view and automatically scroll per resources columns.

Supporting Changes

UnavailableHoursByResource (packages/react-native-calendar-kit/src/components/Resource/UnavailableHoursByResource.tsx)

  • Fixed unavailable hours rendering to prevent UI jumping
  • Corrected position calculations for resource columns

BodyResourceItem, BodyItem, DraggableEvent, DraggingEvent

  • Updated positioning and rendering logic to support dual-axis scrolling
  • Enhanced coordinate calculations for multi-day resource layouts

CalendarProvider, CalendarHeader, CalendarBody

  • Propagated resource scroll state and configuration
  • Updated header rendering for multi-day resource view

Example App (apps/example/app/(drawer)/index.tsx:2)

  • Reduced test resource count from 50 to 10 for better demo performance

Technical Highlights

Intelligent Snap Algorithm

The implementation includes a sophisticated snapping system that:

  • Snaps to the start of each day when all resources fit on one page
  • Snaps at every resource position that keeps all visible resources within the current day boundary
  • Positions the last valid snap point where the last resource of the day aligns with the right edge
  • Prevents resources from spanning across day boundaries during scroll

Performance Optimizations

  • Virtualized rendering with configurable draw distance
  • Throttled scroll offset updates (16ms)
  • Efficient visible range calculations
  • Pre-rendering of events in visible viewport to eliminate jumping

API Completeness

All calendar ref methods now fully support resource scroll mode:

  • goToDate() - Navigate to specific date with resource context
  • goToNextPage() / goToPrevPage() - Day-based navigation
  • goToNextResource() / goToPrevResource() - Resource-based navigation with 'resource' or 'page' granularity

Demo Videos

Android

Screen_Recording_20251128_233143_Expo.Go.mp4
Screen_Recording_20251128_233248_Expo.Go.mp4

iOS

ScreenRecording_11-29-2025.00-43-19_1.MP4
ScreenRecording_11-29-2025.00-40-15_1.MP4

Testing

  • ✅ Tested with 10 resources across 7 days
  • ✅ Verified smooth scrolling and snapping behavior
  • ✅ Confirmed event rendering without jumps
  • ✅ Validated drag-and-drop functionality in resource mode
  • ✅ Tested all calendar ref API methods
  • ✅ Verified unavailable hours rendering
  • ✅ Tested on both iOS and Android (if applicable)

Breaking Changes

None ✅ . This feature is fully backward compatible and opt-in via the existing enableResourceScroll prop.

- snap each resource
- has some bugs with working/unavailable hours
- If all resources fit in one page, only snap at the start of the day
- Snap at every resource position that keeps all visible resources within the current day
- Last valid snap position is where the last resource of the day is at the right edge
…dered in both resources and regular view modes
…all visible days and resource columns

- this avoids jumping UI
- goToDate
- goToNextPage
- goToPrevPage
- goToNextResource
- goToPrevResource
- add drag to create support
- add drag to edti support
@anton-patrushev anton-patrushev marked this pull request as ready for review November 28, 2025 23:53
@anton-patrushev
Copy link
Author

@howljs ptal

would appreciate an asap review so I can quickly iterate. on something if needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant