NASA Proceeds to Mars

    okami

    0.2.5 • Public • Published

    Okami

    Primitives React Components to build a Calendar

    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

    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
        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

    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
     
    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

    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 => 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 :

    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 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

    Install

    npm i okami

    DownloadsWeekly Downloads

    30

    Version

    0.2.5

    License

    MIT

    Unpacked Size

    127 kB

    Total Files

    6

    Last publish

    Collaborators

    • lelvamos
    • kilix_user
    • alefevre19
    • shegunmb
    • wcastand