Okami
Primitives React Components to build a Calendar
Project status
Okami is used in production, we consider evolving its API, but it works as expected!
Introduction
It's a set of Primitives React Components to build a Calendar. Handle the logic so you can focus on UI/UX. Similar to downshift or selectless.
We use composition to construct the calendar, which simply means:
- A monthly calendar is composed of weekly calendar.
- A weekly calendar is composed of daily calendar.
This allow to have a lot fo flexibility without repeating the logic and avoid complexity.
We strongly recommend to use okami
with date-fns.
Install
yarn add okami
npm install --save okami
Basic Usage
For more examples, look at the storybook :)
import React from 'react'import frLocale from 'date-fns/locale/fr'import Calendar DailyCalendar Navigation HoursLabels from 'okami' import data from './stories/data' const Container = <div = /> const CalendarContainer = <div = /> <Calendar = ="monday" ="ddd DD/MM" ="HH" ="PT3H" ="PT22H" = > <DailyCalendar > calendar dayEvents rowHeight <div => <div => <Navigation ="ddd DD MMMM"> next prev today currentDate <div => <button =>Today</button> <button =>Prev day</button> <button =>Next day</button> <span>currentDate</span> </div> </Navigation> </div> <Container> <div => <HoursLabels = /> </div> <CalendarContainer => dayEvents calendarevents </CalendarContainer> </Container> </div> </DailyCalendar> </Calendar>
Documentation
Props Calendar
property | type | required | default | description |
---|---|---|---|---|
data |
array |
yes | - | List of events |
startHour |
string |
no | PT0H | Hour to start the calendar |
endHour |
string |
no | PT24H | Hour to end the calendar |
dateFormat |
string |
no | MM/DD/YYYY | Format of the date string |
hourFormat |
string |
no | HH:mm | Format of the hour string |
startingDay |
string |
no | sunday | Starting day of the week |
locale |
object |
no | en | Local from date-fns |
rowHeight |
number |
no | 30 | Height of a row |
To define property that will be use as duration like startHours
or endHour
.
We use ISO-8601 format for durations.
Every prop passed to Calendar can be overwritten as the sub component level.
<Calendar = ="monday" ="ddd DD/MM" ="HH" ="PT3H" ="PT22H" > <MonthlyCalendar>...</MonthlyCalendar> <DailyCalendar ="DD-MM-YYYY">...</DailyCalendar> </Calendar>
This will use the dateFormat
from <Calendar>
in <MonthlyCalendar>
but <DailyCalendar>
will use his custom dateFormat
when it renders.
Daily Calendar
Render a day.
Props
property | type | default | description |
---|---|---|---|
start |
Date |
new Date() |
Day to show |
showNow |
boolean |
false |
Send props to show the time of day |
Child Callback Function
property | type | description |
---|---|---|
calendar |
Object |
events, label and date of the day |
start |
Date |
date of the day |
showNowProps |
Object |
if showNow is true, props to the showNow container (postion) |
hours |
Array |
Array of formatted string for hours labels |
rowHeight |
Number |
Height of the row |
dayEvents |
Array |
Array of the events that last more than a day of the all day |
calendar
property | type |
---|---|
date |
Date |
events |
Array |
dayEvents
property | type |
---|---|
key |
event.id |
event |
Object |
style |
Object |
The style object is passed only if the getColumnProp
is called and we have a ref available.
methods | description |
---|---|
nextDay |
Go to next day |
prevDay |
Go to previous day |
gotoToday |
Go to today |
dateLabel |
get the date formatted |
getColumnProps |
get the props for the container of the events |
dateLabel
Allow you to render the current day with a special format.
- dateFormat: use the convention from
date-fns
format
getColumnProps
Allow to get the ref to your column element for calculation of the events position.
- refKey: if you're rendering a composite component, that component will need to accept a prop which it forwards to the root DOM element. Commonly, folks call this innerRef. So you'd call: getRootProps({refKey: 'innerRef'}) and your composite component would forward like: . By default, it will use the react default ref key
Weekly Calendar
Render a week.
Props
property | type | default | description |
---|---|---|---|
start |
Date |
new Date() |
Day of the week to show |
showNow |
boolean |
false |
Send props to show the time of day |
Child Callback Function
property | type | description |
---|---|---|
calendar |
Array |
list of day for the week |
end |
Date |
end of the week |
start |
Date |
start of the week |
showNowProps |
Object |
if showNow is true, props to the showNow container (postion) |
hours |
Array |
Array of formatted string for hours labels |
rowHeight |
Number |
Height of the row |
weekEvents |
Array |
Array of the events that last more than a day of the all week |
weekEvents
property | type |
---|---|
key |
event.id |
event |
Object |
style |
Object |
The style object is passed only if the getContainerProps
is called and we have a ref available.
methods | description |
---|---|
nextWeek |
Go to next week |
prevWeek |
Go to previous week |
gotoToday |
Go to today |
dateLabel |
get the date formatted |
getContainerProps |
get the props for the container of the events |
dateLabel
Allow you to render the current week with a special format.
- dateFormat: use the convention from
date-fns
format
getContainerProps
Allow to get the ref to your column element for calculation of the events position.
- refKey: if you're rendering a composite component, that component will need to accept a prop which it forwards to the root DOM element. Commonly, folks call this innerRef. So you'd call: getRootProps({refKey: 'innerRef'}) and your composite component would forward like: . By default, it will use the react default ref key.
Monthly Calendar
Render a month.
Props
property | type | default | description |
---|---|---|---|
start |
Date |
new Date() |
Date of the curent month |
Child Callback Function
property | type | description |
---|---|---|
calendar |
Array |
List of first day of the week for the month |
end |
Date |
end of the month |
start |
Date |
start of the month |
weeks |
Array |
List of the first day of week for the month |
rowHeight |
Number |
Height of the row |
methods | description |
---|---|
nextMonth |
Go to next month |
prevMonth |
Go to previous month |
gotoToday |
Go to today |
dateLabel |
get the date formatted |
dateLabel
Allow you to render the current month with a special format.
- dateFormat: use the convention from
date-fns
format
Navigation
render the navigation for the calendar and the current label. The navigation and label are based on the type.
If you use this in a DailyCalendar
, next()
will jump to the next day but if you use it in MonthlyCalendar
, it will jump to the next month.
You also get access to the function to toggle weekends on the calendar.
If you force showWeekend on a sub component, don't forget to update manually this props.
Props
property | type | description |
---|---|---|
dateFormat |
string |
format of the date |
Child Callback Function
property | type | description |
---|---|---|
type |
string |
Type of calendar ('monthly', 'weekly', 'daily') |
currentDate |
string |
Formatted date based on type |
methods | description |
---|---|
next |
Go to next based on type |
prev |
Go to previous based on type |
today |
Go to today |
toggleWeekend |
show/hide weekend on calendar |
toggleWeekend
Let you toggle the weekend in the calendar. If you don't pass a pamarater, it will toggle the prop. If you pass a boolean, it will force the value.
const showWeekend = true // showWeekend = false // showWeekend = true // showWeekend = true // showWeekend = false...
DaysLabels / HoursLabels
render the days/hours labels for the calendar. You have 3 options to render those components:
- Child Callback function : allow full control
renderChild
props: pass a component that receive pre formatted props- The default render that let you style the
div
container.
Props
property | type |
---|---|
renderChild |
Element|Component |
Child Callback Function
DaysLabels
property | type | description |
---|---|---|
weeks |
array |
Array of the formatted day labels |
HoursLabels
property | type | description |
---|---|---|
hours |
array |
Array of the formatted hour labels |
<HoursLabels> hours
renderChild
prop
props from the HoursLabels/DaysLabels are passed down to the container and the labels are rendered with the component from renderChild
.
<HoursLabels = />
The default render function
props from the HoursLabels/DaysLabels are passed down to the container.
<HoursLabels />
This is the render function used :
<div > formattedDays</div>
Data structure
data
is an array of objects, the object requires a few properties :
property | type | description |
---|---|---|
id |
ID |
Identifier of the event |
title |
string |
Title of the event |
allDay |
boolean | Date |
Determine the type of event |
start |
Date |
Beggining of the event |
end |
Date |
End of the event |
allDay
has 3 states :
true
, the event is on multiple daysfalse
, the event is no longer than a dayDate
, the event last all day
if allDay
is a boolean, you need to provide a start
and end
properties.
If you want to create an event for the all day, you just put the date in allDay
.
// Event of 2 hours: id: 0 title: 'Diner' allDay: false start : 'Wed Sep 06 2017 12:07:52 GMT+0200 (CEST)' end: 'Wed Sep 06 2017 14:07:52 GMT+0200 (CEST)' // Event of all day: id: 0 title: 'Diner' allDay: 'Wed Sep 06 2017 12:07:52 GMT+0200 (CEST)' // Event of 2 days: id: 0 title: 'Diner' allDay: true start : 'Wed Sep 06 2017 12:07:52 GMT+0200 (CEST)' end: 'Wed Sep 08 2017 14:07:52 GMT+0200 (CEST)'
LICENSE
MIT