Cross-platform gcal/outlook like calendar component for React Native.
- Cross Platform: Runs on the Web, iOS, Android with the power of React
- Type-safe: Fully written in TypeScript
- Customizable: Adjust styles of components
- Lightweight: ~37.4KB, dependency is
dayjs
andcalendarize
npm install --save react-native-big-calendar
Or if you use Yarn:
yarn add react-native-big-calendar
Please ensure peer dependencies are installed.
npm install react react-native
If you use TypeScript ensure @types/react
and @types/react-native
is installed. react-native-big-calendar
internally uses them.
npm install --save-dev @types/react @types/react-native
If you are using this module on the Web, please install react-native-web
.
npm install react-native-web
If you are using Create React App, you are ready to go 🎉
For more details, please refer to the official react-native-web installation guide.
https://github.com/necolas/react-native-web
import { Calendar } from 'react-native-big-calendar'
const events = [
{
title: 'Meeting',
start: new Date(2020, 1, 11, 10, 0),
end: new Date(2020, 1, 11, 10, 30),
},
{
title: 'Coffee break',
start: new Date(2020, 1, 11, 15, 45),
end: new Date(2020, 1, 11, 16, 30),
},
]
function App() {
return <Calendar events={events} height={600} />
}
Summary
export interface CalendarProps<T> {
events: ICalendarEvent<T>[]
height: number
overlapOffset?: number
ampm?: boolean
date?: Date
eventCellStyle?: EventCellStyle<T>
renderEvent?: (
event: ICalendarEvent<T>,
touchableOpacityProps: CalendarTouchableOpacityProps,
) => ReactElement | null
locale?: string
hideNowIndicator?: boolean
mode?: Mode
scrollOffsetMinutes?: number
showTime?: boolean
style?: ViewStyle
swipeEnabled?: boolean
weekStartsOn?: WeekNum
weekEndsOn?: WeekNum
isRTL?: boolean
onChangeDate?: DateRangeHandler
onPressCell?: (date: Date) => void
onPressDateHeader?: (date: Date) => void
onPressEvent?: (event: ICalendarEvent<T>) => void
}
<Calendar />
Props are:
name | required | type | description |
---|---|---|---|
events |
yes | ICalendarEvent<T>[] |
The events which will be rendered on the calendar. You can extend the type ICalendarEvent by providing a value to generic type T (see ./stories/events.tsx for an example). with optional children to display custom components inside the event, and optional event renderer function to take complete control over the rendered event (advanced feature). Events that occur during the same time range will be layered, offset, and given a unique color. |
height |
yes | number |
Calendar height. |
hideNowIndicator |
no | boolean |
Hides the indicator for the current time. By default the now indicator is shown. |
onPressEvent |
no | (event: ICalendarEvent<T>) => void |
Event handler which will be fired when the user clicks an event. |
onChangeDate |
no | ([start: Date, end: Date]) => void |
Event handler which will be fired when the current date range changed. |
onPressCell |
no | (date: Date) => void |
Event handler which will be fired when the current date cell is clicked. The minute set to 0. |
onPressDateHeader |
no | (date: Date) => void |
Event handler which will be fired when the user clicks a date from the header. |
mode |
no | 'month' | 'week' | '3days' | 'day' | 'custom' |
|
style |
no | import('react-native').ViewStyle |
|
eventCellStyle |
no | ViewStyle | (event: ICalendarEvent<T>) => ViewStyle |
The style of Event cell. Accepts either style object (static) or function (dynamic). |
scrollOffsetMinutes |
no | number |
Scroll to specific minutes in a day. e.g.) set 480 to scroll to 8am when the calendar rendered. |
date |
no | Date |
Initial date. Defualts to Date |
swipeEnabled |
no | boolean |
|
showTime |
no | boolean |
|
ampm |
no | boolean |
Use 12 hours time format instead of 24 hours. |
weekStartsOn |
no | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Which day the week starts on. Sunday is 0 . |
weekEndsOn |
no | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Which day the week ends on. Sunday is 0 . |
locale |
no | string |
Custom locale. See I18n section |
overlapOffset |
no | number |
Adjusts the indentation of events that occur during the same time period. Defaults to 20 on web and 8 on mobile. |
isRTL |
no | boolean |
Switches the direction of the layout for use with RTL languages. Defaults to false. |
renderEvent |
no | EventRenderer |
Custom event renderer. See below type definition. |
type EventRenderer<T> = (
event: ICalendarEvent<T>,
touchableOpacityProps: CalendarTouchableOpacityProps,
) => ReactElement | null
For more information, see Storybook
interface ICalendarEventBase<T> {
start: Date
end: Date
title: string
children?: ReactElement | null
}
export type ICalendarEvent<T = any> = ICalendarEventBase<T> & T
You can specify custom event render function which receives the calculated TouchableOpacity
prop and event
.
- The function
renderEvent
must return aReactElement
. - The component should be wrapped inside a
TouchableOpacity
or any DOM element which accepts positioning and click events (onPress
, ...).
export interface MyCustomEventType {
color: string
}
const renderEvent = (
event: ICalendarEvent<MyCustomEventType>,
touchableOpacityProps: CalendarTouchableOpacityProps,
) => (
<TouchableOpacity {...touchableOpacityProps}>
<Text>{`My custom event: ${event.title} with a color: ${event.color}`}</Text>
</TouchableOpacity>
)
<Calendar renderEvent={renderEvent} />
Your events can contain a prop children
An example can be found here.
const eventNotes = useMemo(
() => (
<View style={{ marginTop: 3 }}>
<Text style={{ fontSize: 10, color: 'white' }}> Phone number: 555-123-4567 </Text>
<Text style={{ fontSize: 10, color: 'white' }}> Arrive 15 minutes early </Text>
</View>
),
[],
)
export const myEvents: ICalendarEvent[] = [
{
title: 'Custom reminder',
start: dayjs().set('hour', 16).set('minute', 0).toDate(),
end: dayjs().set('hour', 17).set('minute', 0).toDate(),
children: eventNotes,
},
]
Please specity your locale via locale
prop and import day.js locale file:
import 'dayjs/locale/ja'
<Calendar
locale="ja"
{/* ... */}
/>
You can find your dayjs locale here:
https://github.com/iamkun/dayjs/tree/dev/src/locale
If you are using this library, please send a PR to add your organization!
First, thank you for your interest in this project. As this library is getting famous, lots of people are requesting features they need. I would like to respond all of them as possible, but there are limited hours I'm working on this. To be a full-time open sourcer and make this project sustainable, I've decided to add the enterprise support.
Enterprise customers are able to obtain:
- Full customization like colors, logos, images, and more.
- Priority response and development.
- Consultancy for React, TypeScript, and React Native application.
Note that Enterprise features will be distributed to the OSS version.
If you are interested in those features, please send an email to: ketsume0211@gmail.com