0.2.5 • Published 6 years ago

okami v0.2.5

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

Build Status Code Coverage version MIT License

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 = props =>
  <div style={{ display: 'flex', alignItems: 'stretch', justifyContent: 'center'}} {...props} />

const CalendarContainer = props =>
  <div style={{ display: 'flex', alignItems: 'stretch', justifyContent: 'flex-start', width: '100%' }} {...props} />

export default props => (
  <Calendar
    data={data}
    startingDay="monday"
    dateFormat="ddd DD/MM"
    hourFormat="HH"
    startHour="PT3H"
    endHour="PT22H"
    locale={frLocale}
  >
    <DailyCalendar showNow {...props}>
      {({calendar, dayEvents, rowHeight}) => (
        <div style={{display: 'flex', flexDirection:'column'}}>
          <div style={{display:'flex'}}>
            <Navigation dateFormat="ddd DD MMMM">
              {({next, prev, today, currentDate}) => (
                <div style={{display:'flex'}}>
                  <button onClick={today}>Today</button>
                  <button onClick={prev}>Prev day</button>
                  <button onClick={next}>Next day</button>
                  <span>{currentDate}</span>
                </div>
              )}
            </Navigation>
          </div>
          <Container>
            <div style={{paddingTop: rowHeight * (dayEvents.length + 1)}}>
              <HoursLabels renderChild={props => <span style={{height: rowHeight}} {...props} />} />
            </div>
            <CalendarContainer style={{flexDirection: 'column'}}>
              {dayEvents.map(props => <Event {...props} />)}
              {calendar.events.map(props => <Event {...props} />)}
            </CalendarContainer>
          </Container>
        </div>
      )}
    </DailyCalendar>
  </Calendar>
)

Documentation

Props Calendar

propertytyperequireddefaultdescription
dataarrayyes-List of events
startHourstringnoPT0HHour to start the calendar
endHourstringnoPT24HHour to end the calendar
dateFormatstringnoMM/DD/YYYYFormat of the date string
hourFormatstringnoHH:mmFormat of the hour string
startingDaystringnosundayStarting day of the week
localeobjectnoenLocal from date-fns
rowHeightnumberno30Height 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
    data={data}
    startingDay="monday"
    dateFormat="ddd DD/MM"
    hourFormat="HH"
    startHour="PT3H"
    endHour="PT22H"
  >
    <MonthlyCalendar>{...}</MonthlyCalendar>
    <DailyCalendar dateFormat="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

propertytypedefaultdescription
startDatenew Date()Day to show
showNowbooleanfalseSend props to show the time of day

Child Callback Function

propertytypedescription
calendarObjectevents, label and date of the day
startDatedate of the day
showNowPropsObjectif showNow is true, props to the showNow container (postion)
hoursArrayArray of formatted string for hours labels
rowHeightNumberHeight of the row
dayEventsArrayArray of the events that last more than a day of the all day

calendar

propertytype
dateDate
eventsArray

dayEvents

propertytype
keyevent.id
eventObject
styleObject

The style object is passed only if the getColumnProp is called and we have a ref available.

methodsdescription
nextDayGo to next day
prevDayGo to previous day
gotoTodayGo to today
dateLabelget the date formatted
getColumnPropsget 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

propertytypedefaultdescription
startDatenew Date()Day of the week to show
showNowbooleanfalseSend props to show the time of day

Child Callback Function

propertytypedescription
calendarArraylist of day for the week
endDateend of the week
startDatestart of the week
showNowPropsObjectif showNow is true, props to the showNow container (postion)
hoursArrayArray of formatted string for hours labels
rowHeightNumberHeight of the row
weekEventsArrayArray of the events that last more than a day of the all week

weekEvents

propertytype
keyevent.id
eventObject
styleObject

The style object is passed only if the getContainerProps is called and we have a ref available.

methodsdescription
nextWeekGo to next week
prevWeekGo to previous week
gotoTodayGo to today
dateLabelget the date formatted
getContainerPropsget 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

propertytypedefaultdescription
startDatenew Date()Date of the curent month

Child Callback Function

propertytypedescription
calendarArrayList of first day of the week for the month
endDateend of the month
startDatestart of the month
weeksArrayList of the first day of week for the month
rowHeightNumberHeight of the row
methodsdescription
nextMonthGo to next month
prevMonthGo to previous month
gotoTodayGo to today
dateLabelget 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

propertytypedescription
dateFormatstringformat of the date

Child Callback Function

propertytypedescription
typestringType of calendar ('monthly', 'weekly', 'daily')
currentDatestringFormatted date based on type
methodsdescription
nextGo to next based on type
prevGo to previous based on type
todayGo to today
toggleWeekendshow/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

toggleWeekend() // showWeekend = false
toggleWeekend(true) // showWeekend = true
toggleWeekend(true) // showWeekend = true
toggleWeekend(false) // 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

propertytype
renderChildElement|Component

Child Callback Function

DaysLabels

propertytypedescription
weeksarrayArray of the formatted day labels

HoursLabels

propertytypedescription
hoursarrayArray of the formatted hour labels
  <HoursLabels>
    { hours => hours.map(h => <span>{h}</span>} }
  </HoursLabels>

renderChild prop

props from the HoursLabels/DaysLabels are passed down to the container and the labels are rendered with the component from renderChild.

  <HoursLabels renderChild={props => <span {...props} />} />

The default render function

props from the HoursLabels/DaysLabels are passed down to the container.

<HoursLabels />

This is the render function used :

<div {...props}>
  {formattedDays.map((h, idx) => (
    <div key={`day_label_${idx}`} style={{height: rowHeight}}>
      {h}
    </div>
  ))}
</div>

Data structure

data is an array of objects, the object requires a few properties :

propertytypedescription
idIDIdentifier of the event
titlestringTitle of the event
allDayboolean | DateDetermine the type of event
startDateBeggining of the event
endDateEnd of the event

allDay has 3 states :

  • true, the event is on multiple days
  • false, the event is no longer than a day
  • Date, 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

0.2.5

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.8

6 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago

0.0.7

7 years ago

0.0.6

7 years ago

0.0.5

7 years ago

0.0.4

7 years ago

0.0.3

7 years ago

0.0.2

7 years ago

0.0.1

7 years ago