@symbiot.dev/react-native-timegrid v0.2.4
A powerful and flexible time grid and calendar component for React Native, designed to work seamlessly across iOS, Android, Web, Expo, and Expo Go. Built for performance and customization, react-native-timegrid enables developers to implement rich, interactive calendar views for a wide range of scheduling and planning needs.
๐ฑ Demo
โจ Key Features
๐ Time-Based Grid Layout โ Intuitive hourly/daily layout ideal for agenda, schedule, or shift views.
๐จ Fully Customizable โ Modify headers, time slots, event appearance, and grid styling to fit any design system.
๐ง Lightweight โ Minimal dependencies and optimized bundle size for faster load times and efficient performance.
๐ Cross-Platform Compatibility โ Works out of the box with:
- React Native CLI
- Expo
- Expo Go
- React Native Web for browser support
โ๏ธ Optimized Performance โ Supports virtual scrolling and large datasets with smooth interactions.
โ Interactive Features โ Tap, drag, and dynamic updates for real-time scheduling apps.
๐ฑ Responsive Design โ Adapts to various screen sizes and device orientations.
๐งฉ Modular Integration โ Use as a standalone calendar or integrate into more complex scheduling systems.
๐ Ideal For
- ๐ Personal or team calendars
- ๐๏ธ Booking and reservation systems (salons, gyms, clinics)
- ๐ฅ Employee shift and availability planners
- ๐ Event timeline visualizations
- ๐งโ๐ซ Class schedules and academic timetables
- ๐ง Task and time management tools
- ๐ฅ Appointment scheduling for healthcare or therapy
- ๐ฆ Delivery or logistics scheduling
- ๐ผ Project planning dashboards with time allocation
- ๐ Maintenance or service job assignment trackers
- ๐ Student agendas or learning planners
- ๐ค Conference session planners and expo booth schedules
- ๐ฅ and more ...
Whether you're building a cross-platform scheduling app or integrating a responsive calendar view into an existing project, react-native-timegrid provides a modern, customizable, and performant solution for all major platforms.
๐ฉ๐ฟโ๐ป Installation
npm install @symbiot.dev/react-native-timegrid react-native-reanimated react-native-gesture-handler date-fns
# or
yarn add @symbiot.dev/react-native-timegrid react-native-reanimated react-native-gesture-handler date-fns
# for web support
npm i react-native-web
# or
yarn add react-native-web
# to support recurring events
npm i rrule
# or
yarn add rrule
import { TimeGrid } from '@symbiot.dev/react-native-timegrid';
// ... and voilร ๐ซ
<TimeGrid />
Just import it and boom โ youโve got a slick, cross-platform calendar view. Fast setup, full control, and zero headaches. ๐ช๐ป๐ฅ
๐จ TimeGridThemeProps
โ Theming & Appearance
Customize the look and feel of the TimeGrid
with flexible styling options. You can define global styles, override them based on theme (light
or dark
), or combine both approaches.
๐งฉ Structure
The TimeGridThemeProps
type supports three layers:
- Global Styling (applies to all schemes unless overridden)
- Per-scheme Overrides โ Use
light
anddark
keys to define specific values - Theme Scheme Selector โ Control active theme using
scheme
type TimeGridThemeProps = TimeGridStyling & {
scheme?: 'light' | 'dark'; // system default
light?: TimeGridStyling;
dark?: TimeGridStyling;
};
๐งฑ Available Styling Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
backgroundColor | Main background color of the grid view | โ | โ | โ | light: #FFFFFF , dark: #000000 |
dayHeaderBackgroundColor | Background for the day-of-week header bar | โ | โ | โ | light: #FFFFFF , dark: #000000 |
dayHeaderTextColor | Text color for day-of-week labels | โ | โ | โ | light: #000000 , dark: #FFFFFF |
headerSafeAreaBackgroundColor | Background for top safe area (e.g., notch spacing) | โ | โ | โ | light: #FFFFFF , dark: #000000 |
allDayEventsSafeAreaBackgroundColor | Background for all-day events safe area | โ | โ | โ | light: #FFFFFF , dark: #000000 |
allDayEventsSafeAreaTextColor | Text color for all-day events safe area | โ | โ | โ | light: #000000 , dark: #FFFFFF |
timelineBackgroundColor | Background color for timeline column | โ | โ | โ | light: #FFFFFF , dark: #000000 |
timelineTextColor | Text color for hour/time labels | โ | โ | โ | light: #A9A9A9 , dark: #A9A9A9 |
verticalLineColor | Color of vertical time slot dividers | โ | โ | โ | light: #F1F1F1 , dark: #303030 |
horizontalLineColor | Color of horizontal grid lines | โ | โ | โ | light: #F1F1F1 , dark: #303030 |
nowIndicatorColor | Color of the โnowโ line showing current time | โ | โ | โ | #FF6F61 |
unavailableTimeBackgroundColor | Color for visually marking unavailable time blocks | โ | โ | โ | light: #F1F1F170 , dark: #30303070 |
dropZoneBackgroundColor | Background for areas that accept dragged events | โ | โ | โ | transparent |
eventBackgroundColor | Default background for event blocks | โ | โ | โ | light: #D8E4F1 , dark: #475867 |
eventTextColor | Text color used in event blocks | โ | โ | โ | light: #000000 , dark: #FFFFFF |
eventBorderColor | Border color for events | โ | โ | โ | light: #FFFFFF , dark: #000000 |
<TimeGrid
//...
theme={{
backgroundColor: '#f0f0f0', // for light and dark mode
}}
/>
// ----
<TimeGrid
//...
theme={{
backgroundColor: '#f0f0f0', // only applies to light mode
eventTextColor: '#323232', // only applies to dark mode
dark: {
backgroundColor: '#020202',
},
light: {
eventTextColor: '#505050',
}
}}
/>
๐ TimeGridDimensionsProps
โ Layout & Dimensions
Control the physical dimensions of key areas inside the TimeGrid
. All values are in pixels and optional โ sensible defaults are provided.
๐งฑ Available Dimension Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
width | TimeGrid width | โ | โ | โ | system |
dayHeaderHeight | Height of the day header (weekday labels) | โ | โ | โ | 50 |
allDayEventHeight | Height for all-day events | โ | โ | โ | 25 |
timelineWidth | Width of the left-side timeline area | โ | โ | โ | 58 |
horizontalLineSize | Height of horizontal divider lines | โ | โ | โ | 0.5 |
nowIndicatorHeight | Thickness of the โnowโ line | โ | โ | โ | 0.5 |
gridVerticalPadding | Defines the vertical spacing (top and bottom padding) | โ | โ | โ | 0 |
eventBorderWidth | Width of the border around an event element | โ | โ | โ | 1 |
eventBorderRadius | Radius of the border corners for an event element | โ | โ | โ | 5 |
<TimeGrid
//...
timelineWidth={60}
/>
๐
TimeGridDatetimeProps
โ Date & Time Configuration
Set the visible time range, number of days, start date, timezone, and other calendar-related behaviors.
These props give you precise control over how the TimeGrid
renders days and time slots.
๐งฑ Available Datetime Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
startDate | The starting datetime for the visible grid (defaults to current date) | โ | โ | โ | new Date() |
weekStartsOn | Day the week starts on (0=Sun, 1=Mon, etc.) | โ | โ | โ | 0 (Sunday) |
hiddenDays | Days of the week to hide (e.g., [0, 6] to hide Sun & Sat) | โ | โ | โ | [] |
numberOfDays | Number of days to render in the view | โ | โ | โ | 1 |
timeFrom | Start of the visible time range (in minutes, e.g., 480 = 8:00 AM) | โ | โ | โ | 0 |
timeTo | End of the visible time range (in minutes, e.g., 1200 = 8:00 PM) | โ | โ | โ | 1440 |
timeInterval | Minutes between each horizontal time line | โ | โ | โ | 60 |
timeStep | Time rounding when placing events (in minutes) | โ | โ | โ | 15 |
minDate | Earliest date to allow navigation | โ | โ | โ | โ |
maxDate | Latest date to allow navigation | โ | โ | โ | โ |
timezone | Timezone name (e.g., 'America/New_York', '+02:00' ) for offset handling | โ | โ | โ | local |
<TimeGrid
//...
weekStartsOn={1} // starts on Monday
numberOfDays={3}
hiddenDays={[0, 6]} // exclude weekends (Sun,Sut)
/>
๐๏ธ TimeGridEventsProps
โ Events, Rendering & Recurrence
Configure how events appear and behave inside the calendar. Supports custom colors, recurring events, readonly mode, and timezone-specific scheduling.
๐ฆ๐จ Overlapping Events
Events that share time ranges are fully supported out-of-the-box.
The grid will automatically stack or split them side-by-side depending on layout space.
๐งฑ Available Event Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
createEventDuration | Duration (in minutes) to assign when user creates a new event. | โ | โ | โ | 60 |
allDayEventsSafeAreaText | Placeholder for all-day events safe area | โ | โ | โ | All-day |
events | Array of TimeGridEvent to render inside the time grid | โ | โ | โ | [] |
TimeGridEvent
Field Name | Description | Type | Required | Default |
---|---|---|---|---|
id | Unique identifier for the event | string | โ | โ |
start | Start datetime of the event | Date \| string \| number | โ | โ |
end | End datetime of the event | Date \| string \| number | โ | โ |
text | Event title or description | string | optional | datetime |
backgroundColor | Override default event background color | string | optional | theme |
textColor | Override text color inside the event | string | optional | theme |
timezone | IANA timezone name for localized event handling | string | optional | grid-level |
readonly | Prevent this event from being dragged | boolean | optional | false |
rrule | RRULE string (e.g., 'RRULE:FREQ=DAILY' ) | string | optional | โ |
โน๏ธ Need help creating a recurrence rule?
Use the visual generator at rrule.js playground to quickly create and test valid RRULE strings.
<TimeGrid
//...
createEventDuration={30} // new created events equals 30 mins
events={[
//...
{
id: 'timestamp',
start: '2025-04-25T18:00:00.500Z',
end: '2025-04-25T19:00:00.800Z',
backgroundColor: '#DDDDDD',
textColor: '#000000',
readonly: true // prevent from being dragged
}
]}
/>
๐ซ TimeGridUnavailableTimeProps
โ Blocking Unavailable Times
Mark specific time ranges as unavailable โ either for a specific date or recurring on weekdays.
These periods can block event creation, display with a distinct background and could be used with a different combinations.
export type TimeGridUnavailableTime = {
from: number; // in minutes (e.g. 480 = 8:00 AM)
to: number; // in minutes (e.g. 1020 = 5:00 PM)
start?: Date | string;
end?: Date | string;
} & (
| {
weekday?: Day; // 0 (Sunday) to 6 (Saturday)
date?: never;
}
| {
date?: Date | string;
weekday?: never;
}
);
export type TimeGridUnavailableTimeProps = {
unavailableTime?: TimeGridUnavailableTime[];
};
๐งฑ Available Unavailable Time Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
unavailableTime | Array of time rules (by weekday or specific date). Uses from /to in minutes; Priority: date, weekday; | โ | โ | โ | [] |
<TimeGrid
//...
unavailableTime={[
{ from: 0, to: 480 } // everyday 00:00 (12:00 AM) -> 08:00 AM
]}
/>
// ----
<TimeGrid
//...
unavailableTime={[
{ from: 0, to: 480, start: '2025-04-25T18:00:00.500Z' } // daily, starting April 25
]}
/>
// ----
<TimeGrid
//...
unavailableTime={[
{ from: 0, to: 480, start: '2025-04-25T00:00:00.500Z', end: '2025-04-26T00:00:00.500Z' } // only 2 days - April 25 and 26
]}
/>
// ----
// Priority behaviour
<TimeGrid
//...
unavailableTime={[
{ from: 0, to: 480 }, // daily
{ from: 1020, to: 1440, weekday: 1 }, // ignore the first element of the array and apply every Monday
{ from: 480, to: 900, date: '2025-04-28T18:00:00.500Z' } // ignore the first and second rules for Monday, April 28th
]}
/>
// ----
// Save behaviour
<TimeGrid
//...
unavailableTime={[
{ from: 0, to: 480 }, // daily
{ from: 0, to: 480, date: '2025-04-28T18:00:00.500Z' }, // save the daily rule for April 28
{ from: 480, to: 900, date: '2025-04-28T18:00:00.500Z' } // ignore the first and second rules for Monday, April 28th
]}
/>
๐ฎ TimeGridControllerProps
โ Interaction & Display Toggles
Control user interaction features like swiping, dragging, snapping, and visibility of UI components like the timeline, all-day events etc.
๐งฑ Available Controller Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
lazy | Enable to improve performance on the slow devices | โ | โ | โ | true |
swipeable | Enable swiping between days or weeks | โ | โ | โ | false |
snappable | Snap scroll/drag to the nearest date | โ | โ | โ | false |
draggable | Allow dragging events to create/reschedule them | โ | โ | โ | true |
debounceable | Delays date change handler to avoid rapid successive triggers. | โ | โ | โ | false |
rtl | Enable right-to-left layout (for RTL languages) | โ | โ | โ | false |
isDayHeaderVisible | Toggle visibility of the top day-of-week header | โ | โ | โ | true |
isTimelineVisible | Toggle visibility of the left-side timeline | โ | โ | โ | true |
isNowIndicatorVisible | Show/hide the "now" indicator line | โ | โ | โ | true |
isAllDayEventsEnabled | Enable support for all-day events | โ | โ | โ | true |
isAllDayEventsVisible | Toggle visibility of the all-day events | โ | โ | โ | true |
<TimeGrid
//...
swipeable // swipe actions turned on
draggable // user can drag events
snappable // date snapping enabled
/>
โฑ TimeGridFormatterProps
โ Text Formatting
Customize how dates and times appear within the TimeGrid component using format strings (e.g., dd
, HH:mm
, EEE
).
These follow date-fns formatting syntax.
๐งฑ Available Formatter Props
Prop Name | Description | iOS | Android | Web | Default Value |
---|---|---|---|---|---|
dayHeaderTextFormat | Format for the day header labels (e.g., Mon , Apr 20 ) | โ | โ | โ | EEEEEE dd |
timelineTextFormat | Format for the left-side time labels (e.g., 08:00 ) | โ | โ | โ | p |
locale | Locale object from date-fns for internationalized formatting | โ | โ | โ | en |
import { zhCN } from 'date-fns/locale/zh-CN';
<TimeGrid
//...
locale={zhCN} // Chinese localization
/>
๐ฏ TimeGridActionsProps
โ User Interaction Callbacks
Listen and respond to interactions like taps, long presses, event edits, and grid context menus.
๐งฑ Available Action Callbacks
Prop Name | Description | iOS | Android | Web |
---|---|---|---|---|
onChangeDate | Called when the grid's date range changes | โ | โ | โ |
onHeaderSafeAreaPress | Triggered when the top header area is tapped | โ | โ | โ |
onAllDayEventsSafeAreaPress | Triggered when the all-day events header area is tapped | โ | โ | โ |
onDayHeaderPress | Called when a specific day header is pressed | โ | โ | โ |
onLoad | Called once the grid is initialized and ready | โ | โ | โ |
onUnavailableTimePress | Fired on tap inside an unavailable time block | โ | โ | โ |
onUnavailableTimeLongPress | Fired on long press inside an unavailable time block | โ | โ | โ |
onDatetimeContextMenu | Right-click/context menu trigger at specific date/time (with x/y coords) | ๐ซ | ๐ซ | โ |
onDatetimePress | Triggered on a tap inside an available time cell | โ | โ | โ |
onDatetimeLongPress | Triggered on long press inside an available time cell | โ | โ | โ |
onEventPress | Called when an event is tapped | โ | โ | โ |
onEventLongPress | Called when an event is long-pressed | โ | โ | โ |
onEventUpdated | Triggered when an event is changed (drag); return false to keep updating, reject to cancel | โ | โ | โ |
onEventCreated | Triggered when a new event is created by the user | โ | โ | โ |
import { useState } from 'react';
const [selectedDate, setSelectedDate] = useState(new Date());
<TimeGrid
//...
onChangeDate={setSelectedDate} // selectedDate updated
/>
๐ง TimeGridRef
โ Imperative Control API
Control and interact with the TimeGrid instance programmatically using a React ref.
Great for custom toolbars, buttons, or dynamic navigation.
๐งฑ Available Ref Methods
Method | Description | Returns |
---|---|---|
getPrevDate() | Returns the previous valid date range (optionally ignoring minDate /maxDate ) | Date \| undefined |
getNextDate() | Returns the next valid date range (optionally ignoring minDate /maxDate ) | Date \| undefined |
prevDate() | Navigate to the previous available date | void |
nextDate() | Navigate to the next available date | void |
back() | Navigate backward through a specified number of days (numberOfDays ) | void |
forward() | Navigate forward through a specified number of days (numberOfDays ) | void |
toDatetime() | Scroll or jump to a specific date/time | void |
createEvent() | Programmatically create a new event at a given datetime | void |
import { useRef } from 'react';
import { TimeGrid, TimeGridRef } from '@symbiot.dev/react-native-timegrid';
const timeGridRef = useRef<TimeGridRef>(null);
<TimeGrid
//...
ref={timeGridRef}
onDatetimeLongPress={(params) => timeGridRef.current?.createEvent(params)}
/>
๐ Platform Support
- โ iOS
- โ Android
- โ Web
- โ Expo & Expo Go
๐ฆ Bundle Size
Lightweight and fast โ see actual size on Bundlephobia.
๐ฌ Contributing
Contributions welcome! Feel free to open issues, discussions, or suggestions.
๐ Who's Using This?
Using react-native-timegrid
in your app or product?
Feel free to share your project โ it might be featured in this section!
โ๏ธ Open pull request, or reach out directly to get included.
๐ Got Ideas or Gaps to Fill?
Know of existing libraries or functionality that could be improved?
Have an idea for something completely new?
Symbiot is ready to take on the challenge โ feedback, feature requests, or collaboration ideas are always welcome!
๐ง Letโs build better tools together. Start the conversation or contact via email.
๐งพ License
MIT โ Made with โค๏ธ by Symbiot