https://github.com/kilix/okami
Primitives react component for calendar
https://github.com/kilix/okami
calendar composable primitives react
Last synced: 6 months ago
JSON representation
Primitives react component for calendar
- Host: GitHub
- URL: https://github.com/kilix/okami
- Owner: Kilix
- License: mit
- Created: 2017-08-18T14:16:23.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-09-19T07:51:42.000Z (about 7 years ago)
- Last Synced: 2025-04-10T03:39:22.808Z (6 months ago)
- Topics: calendar, composable, primitives, react
- Language: JavaScript
- Homepage: https://okami-website-jaltwitsba.now.sh/
- Size: 2.35 MB
- Stars: 19
- Watchers: 3
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
Okami
Primitives React Components to build a Calendar
[![Build Status][build-badge]][build]
[![Code Coverage][coverage-badge]][coverage]
[![version][version-badge]][package]
[![MIT License][license-badge]][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](https://github.com/paypal/downshift) or [selectless](https://github.com/Kilix/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](https://date-fns.org/).
## Install
```yarn add okami```
```npm install --save okami```## Basic Usage
For more examples, look at the storybook :)
```jsx
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 =>
const CalendarContainer = props =>
export default props => (
{({calendar, dayEvents, rowHeight}) => (
{({next, prev, today, currentDate}) => (
Today
Prev day
Next day
{currentDate}
)}
} />
{dayEvents.map(props => )}
{calendar.events.map(props => )}
)}
)```
## 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](https://fr.wikipedia.org/wiki/ISO_8601) format for durations.Every prop passed to Calendar can be overwritten as the sub component level.
```jsx
{...}
{...}
```
This will use the `dateFormat` from `` in `` but `` 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](https://date-fns.org/v1.28.5/docs/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](https://date-fns.org/v1.28.5/docs/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](https://date-fns.org/v1.28.5/docs/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.```javascript
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 |```jsx
{ hours => hours.map(h => {h}} }
```#### `renderChild` prop
props from the HoursLabels/DaysLabels are passed down to the container and the labels are rendered with the component from `renderChild`.
```jsx
} />
```#### The default render function
props from the HoursLabels/DaysLabels are passed down to the container.
``````
This is the render function used :
```jsx
{formattedDays.map((h, idx) => (
{h}
))}
```
---### 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 dayif `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`.```javascript
// 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
[build-badge]: https://img.shields.io/travis/Kilix/okami.svg?style=flat-square
[build]: https://travis-ci.org/Kilix/okami
[coverage-badge]: https://img.shields.io/codecov/c/github/Kilix/okami.svg?style=flat-square
[coverage]: https://codecov.io/github/Kilix/okami
[version-badge]: https://img.shields.io/npm/v/okami.svg?style=flat-square
[package]: https://www.npmjs.com/package/okami
[license-badge]: https://img.shields.io/npm/l/okami.svg?style=flat-square
[license]: https://github.com/paypal/okami/blob/master/LICENSE