How stephy/calendarpicker works
1. What this repo is
- This is a React Native component library that exports a single calendar/date-picker widget, CalendarPicker.
- The repo is split into the reusable library code, a test suite, and two sample apps (example and example_typescript) that demonstrate integration.
2. Public API boundary
- The library’s entrypoint is CalendarPicker/index.js.
- Consumers import the component and configure it entirely through props: selection mode, date bounds, labels, localization, styling, and initial view.
- The component also exposes a small imperative API through refs, such as moving between months, selecting a date programmatically, clearing selections, and jumping to a date.
3. Core rendering model
- The widget is built from a hierarchy of view components under CalendarPicker/.
- The main picker orchestrates which subview is shown: days, months, or years.
- This makes the architecture state-driven: the current date/view state determines whether the user sees a month grid, month selector, year selector, or the day grid.
4. Day-selection subsystem
- Day rendering and selection live in the day-oriented components:
- Day.js for an individual day cell
- DaysGridView.js for the month’s day grid
- EmptyDay.js for leading/trailing placeholder slots
- Weekdays.js for weekday headers
- These components translate calendar state into selectable cells, disabled cells, today highlighting, and range-selection styling.
5. Month and year navigation subsystem
- Month.js, MonthSelector.js, MonthsGridView.js, and MonthsHeader.js handle month browsing and selection.
- Year.js, YearSelector.js, YearsGridView.js, and YearsHeader.js do the same for years.
- The picker can start in any of these views via initialView, so view switching is a first-class part of the component architecture, not an afterthought.
6. Navigation controls and scroller
- Controls.js and HeaderControls.js implement previous/next navigation and header UI.
- Scroller.js supports the scrollable mode described in the README, where months are recycled in an infinite bidirectional scroll pattern.
- This creates two navigation paths:
- button/header-driven month changes
- scroll-driven month changes in scrollable mode
7. Date logic and constraints
- Utils.js holds shared date computations and helper logic.
- The calendar’s behavior is constrained by props such as minDate, maxDate, disabledDates, allowRangeSelection, and allowBackwardRangeSelect.
- Data flow is: incoming props and current selection state are normalized into per-day affordances, then each cell decides whether it is selectable, disabled, or part of a range.
8. Styling and customization boundary
- makeStyles.js centralizes style generation from props.
- localPropTypes.js defines the component’s prop contract.
- The README’s customization options map to this layer: selected/today styling, custom date styles, weekday header styles, text styles, shapes, and container styles.
- This architecture keeps the visual customization surface outside the calendar logic itself.
9. Callbacks and external interaction
- User interactions flow outward through callbacks like onDateChange and onMonthChange.
- Internally, a tap on a day or a navigation action updates component state, then emits the appropriate callback to the host app.
- For range selection, the callback distinguishes start vs. end selection, which is why the public API returns a second parameter such as START_DATE or END_DATE.
10. Testing
- There is a focused unit test suite in CalendarPicker/__tests__/CalendarPicker-test.js.
- This suggests the library’s core behavior is validated at the component boundary rather than through broad end-to-end coverage.
11. Example applications
- example/example is an Expo sample app in JavaScript.
- example/example_typescript is a parallel Expo sample in TypeScript, with its own app shell plus demo components under src/components.
- These apps are integration sandboxes, not part of the published library runtime.
12. TypeScript and sample app structure
- The TypeScript example wraps the calendar demo in a small app-level component tree, including a configurable CalendarView, Button, and shared color constants.
- This demonstrates how the library is consumed in a typed app, while keeping the actual picker implementation in the root library package.
13. Tooling and repo boundaries
- The repo uses Babel, Flow, ESLint, and Travis CI for library development and validation.
- A pre-commit hook and lint config indicate the project is maintained as a publishable package with code quality checks.
- The README notes that sample app source is copied from the root into example, reinforcing the separation between the distributable component and the demo app.
14. High-level diagram summary
- Think of the architecture as:
- Consumer app calls into CalendarPicker public API
- CalendarPicker container/state computes current view, selection, and constraints
- Day/Month/Year subcomponents render the appropriate calendar UI
- Utils + makeStyles provide date calculations and visual mapping
- Callbacks/ref methods send changes back to the consumer
- Example apps show the integration boundary, not core logic
Main entry points: index.js CalendarPicker · DaysGridView.js Days grid · MonthSelector.js Month selector · YearSelector.js Year selector
Components 27
Library
Published CalendarPicker component and its internal view/state modules.
- CalendarPicker · Library entrypoint and exported component surface.
CalendarPicker/index.js - Day cell · Individual selectable day rendering and state styling.
CalendarPicker/Day.js - Days grid · Month day grid and day-selection layout.
CalendarPicker/DaysGridView.js - Empty day · Leading and trailing placeholder cells in the month grid.
CalendarPicker/EmptyDay.js - Weekdays · Weekday labels above the day grid.
CalendarPicker/Weekdays.js - Month cell · Single month item used in month browsing and selection.
CalendarPicker/Month.js - Month selector · Month selection view and switching logic.
CalendarPicker/MonthSelector.js - Months grid · Grid layout for browsing months.
CalendarPicker/MonthsGridView.js - Months header · Header controls for month view navigation.
CalendarPicker/MonthsHeader.js - Year cell · Single year item used in year browsing and selection.
CalendarPicker/Year.js - Year selector · Year selection view and switching logic.
CalendarPicker/YearSelector.js - Years grid · Grid layout for browsing years.
CalendarPicker/YearsGridView.js - Years header · Header controls for year view navigation.
CalendarPicker/YearsHeader.js - Controls · Previous/next navigation actions for the picker.
CalendarPicker/Controls.js - Header controls · Header-level navigation UI and action wiring.
CalendarPicker/HeaderControls.js - Scroller · Scrollable infinite month navigation mode.
CalendarPicker/Scroller.js - Utils · Shared date computations, bounds checks, and selection helpers.
CalendarPicker/Utils.js - Styles · Style generation from props and customization inputs.
CalendarPicker/makeStyles.js - Prop types · Component prop contract and validation shape.
CalendarPicker/localPropTypes.js - Component tests · Focused unit tests at the CalendarPicker boundary.
CalendarPicker/__tests__/CalendarPicker-test.js
Examples
Expo sample apps that demonstrate library integration in JavaScript and TypeScript.
- Example app · JavaScript Expo sample demonstrating library usage.
example/example/App.js - TS app · TypeScript Expo sample app shell for the picker demo.
example/example_typescript/App.tsx - Calendar view · Typed demo wrapper that configures and renders the picker.
example/example_typescript/src/components/CalendarView/index.tsx - Button · Shared button used by the TypeScript demo UI.
example/example_typescript/src/components/Button/index.tsx - Colors · Shared palette values for the TypeScript sample app.
example/example_typescript/src/global/colors.ts
Tooling
Repository validation, linting, and package-level configuration.
- Package config · Repository package metadata and entry configuration.
package.json - Build & lint · Babel, Flow, ESLint, and CI configuration for development validation.
Connections 29
- CalendarPicker → Day cell: renders · Public component delegates day-cell rendering to the day subsystem.
- CalendarPicker → Days grid: shows · Main picker renders the day grid in month view.
- CalendarPicker → Month selector: switches to · Picker can enter month selection mode.
- CalendarPicker → Year selector: switches to · Picker can enter year selection mode.
- CalendarPicker → Controls: navigates · Picker exposes button-driven navigation actions.
- CalendarPicker → Scroller: optional mode · Scrollable mode replaces button navigation with recycled month scrolling.
- CalendarPicker → Utils: uses · Date normalization and constraint logic feed the component state.
- CalendarPicker → Styles: styles via · Customization props are transformed into style objects.
- CalendarPicker → Prop types: validated by · Component API is defined by local prop contracts.
- Days grid → Empty day: fills · Grid uses placeholders for leading and trailing slots.
- Days grid → Weekdays: labels · Day grid is aligned with weekday headers.
- Days grid → Utils: computes · Grid state depends on date math and selection constraints.
- Days grid → Styles: styles via · Cell appearance is derived from style generation.
- Month selector → Month cell: lists · Month selector is built from month cells.
- Month selector → Months grid: lays out · Month browsing uses a grid view.
- Month selector → Months header: headed by · Month selector uses its header controls.
- Year selector → Year cell: lists · Year selector is built from year cells.
- Year selector → Years grid: lays out · Year browsing uses a grid view.
- Year selector → Years header: headed by · Year selector uses its header controls.
- Controls → Header controls: wraps · Navigation controls drive header UI interactions.
- Scroller → Utils: advances dates · Scrollable navigation depends on date calculations.
- Example app → CalendarPicker: consumes · JavaScript sample imports and renders the library component.
- TS app → Calendar view: hosts · TypeScript app mounts the calendar demo component.
- Calendar view → CalendarPicker: consumes · Typed demo wrapper configures the library picker.
- Calendar view → Button: uses · Demo UI includes reusable buttons.
- Calendar view → Colors: styles from · Demo styling depends on shared color constants.
- Package config → CalendarPicker: publishes · Package metadata points to the library entry surface.
- Build & lint → CalendarPicker: validates · Tooling checks the library source during development and CI.
- Component tests → CalendarPicker: tests · Unit tests cover the component boundary behavior.