Skip to main content
Examples use the React Native Calendar; most props are shared with the dom renderer, and the dom vs native comparison lists what differs per renderer.
mode="week", day, 3days, and custom all render the time grid: one column per day, hours down the side, events as positioned boxes, and an all-day lane on top. On React Native the day header and the all-day lane page with the columns while the hour column stays fixed on the left, so the whole grid moves as one when you swipe. week pages by the calendar week (set weekStartsOn: 0 = Sunday, 1 = Monday, and so on); day and 3days page by their column count; custom renders any slice you choose.
scrollOffsetMinutes is applied on mount and again whenever its value changes, at the current zoom. Keep it stable rather than deriving it from the clock on every render: re-rendering with the same value leaves the user’s scroll position alone, while a new value scrolls.

Scroll to a time

To scroll on demand, such as from a “now” button, attach a ref to Calendar (or TimeGrid) and call scrollToTime with minutes from midnight. Unlike scrollOffsetMinutes, it scrolls every time you call it, even to the same time. The scroll animates unless you pass { animated: false } or the OS asks to reduce motion, and it does nothing while a month, year, or schedule view is showing.

The hour axis

  • minHour / maxHour — clamp the visible window (e.g. 7–20) instead of the full day.
  • hourHeight — initial pixels per hour.
  • Zooming rescales it between minHourHeight and maxHourHeight: pinch on native, Ctrl/⌘ + wheel on the web.
  • timeslots — sub-hour divider lines per hour (e.g. 2 for half-hours).
  • ampm — 12-hour labels; hourComponent replaces the label entirely.
  • hideHours — collapse the hour gutter (the grid lines stay).
  • The hour column is a single column beside the day columns, in the same scroll view, so it scrolls and zooms with them and holds still while you swipe between pages. Style it through the hourGutter slot.
  • showWeekNumber / weekNumberPrefix — ISO week number in the header gutter.
  • hiddenDays — weekdays (0=Sunday…6=Saturday) dropped from the view, e.g. [0, 6] for a Monday–Friday business week. Count-based views keep their column count by skipping hidden days.

Event boxes

A timed event’s box is sized to its duration, with two guards you can tune:
  • minEventHeight — the floor on a box’s pixel height, so a 5-minute event stays legible and tappable. It is also the floor of the boxHeight passed to your renderEvent. Default 32 on native, 14 on the dom renderer. Pass 0 to size every box strictly by its duration.
  • eventGap — the inset in pixels between a box and its slot on each side, so adjacent boxes and column edges get some breathing room. Default 2 on native, 1 on the dom renderer. Pass 0 to let events fill the full slot.

Pull to refresh

On React Native, refreshControl takes a RefreshControl element and wraps the grid’s vertical scroll view, so a pull from the top can reload the events. The pull is only reachable with the grid scrolled to its very top, which the default scrollOffsetMinutes starts you away from. On Android that same layout also catches a page swipe with a downward component while sitting at the top, so it refreshes instead of paging.

The all-day lane

All-day events (flagged allDay, or spanning midnight-to-midnight) leave the timed columns and stack in a lane above the grid, which both renderers drop entirely for a week with no all-day events. On React Native the lane pages with the day columns and stays pinned above the hours while you scroll, and its height follows the week under it as you swipe. The “all-day” text label is off by default so the lane can come and go without a stranded label; set showAllDayLabel to bring it back. Turn the lane off entirely with showAllDayEventCell={false}.

Now line and business hours

The red current-time line follows the wall clock (showNowIndicator, on by default). businessHours shades the closed hours per day; return null for a fully closed day (see Theming for the shade colour). Return an array of windows to leave a closed gap between them, such as a lunch break:
To put your own content in the closed region (a label, an icon, a striped pattern), add renderBusinessHours. The grid keeps positioning each band and calls you with { date, start, end } (fractional hours, clamped to the visible window); the themed tint is dropped so your output owns the look. The band is decorative: it stays non-interactive and hidden from assistive tech, so return visuals, not buttons or announced text:
Saturday and Sunday columns are tinted with the weekend background by default. Pass highlightWeekends={false} to treat them like any other day (or recolour the tint via the weekendBackground theme token).

Interaction

Tap handlers: onPressCell / onLongPressCell (empty grid space), onPressEvent / onLongPressEvent, and onPressDateHeader (the day-column headers). Drag-to-move, resize, and drag-to-create are covered in Dragging & creating; keyboard and screen-reader support in Accessibility. Style parts of the grid with per-slot classes, or recolour it via the theme.

Custom header (React Native)

Three Calendar props customize the area above the grid; all are native-only (the dom renderer styles its header through the header / columnHeader* slots instead).
  • renderTimeGridHeader={(days: Date[]) => ReactNode} replaces the built-in day-header row with a single fixed header above the grid (it does not page). The week-number gutter and the tappable weekday/date buttons disappear, and your element renders full-width in their place. days is the visible page’s dates in column order. The all-day lane and the grid itself stay. To line your columns up with the grid’s, leave a leading spacer as wide as the hour gutter (hourColumnWidth, default 56, or 0 with hideHours). The built-in header, by contrast, pages with the columns.
  • headerComponent={<YourToolbar />} inserts an element, unchanged, above the grid. It takes no arguments and replaces nothing, and it doesn’t scroll with the hours. The built-in day header now pages with the columns, so headerComponent sits above that paged weekday/date row. Use it for a filter row, an avatar strip, or your own toolbar.
  • renderHeaderForMonthView={(weekDays: Date[]) => ReactNode} is the month-grid equivalent of renderTimeGridHeader: it replaces the weekday-label header; return null to hide it.