• Stars
    star
    142
  • Rank 258,495 (Top 6 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 3 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple and flexible events calendar written in React

React Calendar

100% test coverage, responsive, and flexible event calendar for React.

See In Action

Backstory: After using react-big-calendar for years, I decided to create my own that is simpler to use, allows for easy customization, and uses modern React (no deprecated methods).

npm install @zach.codes/react-calendar date-fns

Basic Usage

See this code in action

import { format, subHours, startOfMonth } from 'date-fns';
import {
  MonthlyBody,
  MonthlyDay,
  MonthlyCalendar,
  MonthlyNav,
  DefaultMonthlyEventItem,
} from '@zach.codes/react-calendar';

export const MyMonthlyCalendar = () => {
  let [currentMonth, setCurrentMonth] = useState<Date>(
    startOfMonth(new Date())
  );

  return (
    <MonthlyCalendar
      currentMonth={currentMonth}
      onCurrentMonthChange={date => setCurrentMonth(date)}
    >
      <MonthlyNav />
      <MonthlyBody
        events={[
          { title: 'Call John', date: subHours(new Date(), 2) },
          { title: 'Call John', date: subHours(new Date(), 1) },
          { title: 'Meeting with Bob', date: new Date() },
        ]}
      >
        <MonthlyDay<EventType>
          renderDay={data =>
            data.map((item, index) => (
              <DefaultMonthlyEventItem
                key={index}
                title={item.title}
                // Format the date here to be in the format you prefer
                date={format(item.date, 'k:mm')}
              />
            ))
          }
        />
      </MonthlyBody>
    </MonthlyCalendar>
  );
};

This renders a monthly calendar view in its simplest form. Whenever a user presses next or previous on the <MonthlyNav /> the onCurrentMonthChange callback will be invoked, and it's up to you to control the state.

This approach gives you full flexibilty to do anything you want. In my applications, I will refetch a graphql query anytime the month changes, and load events for that month.

The events get passed into MonthlyBody and then renderDay is called for every day on the calendar that has events. You can render any React component you wish, giving you as much freedom as possible.

Styling

This library uses Tailwind. This gives you two options for including the necessary CSS for the components.

I'm already using Tailwind

Awesome! You need to add node_modules/@zach.codes/react-calendar/dist/**/*.js to your tailwind.config.js to ensure the required classes aren't purged on your production build.

I'm not using Tailwind

No problem! The library includes the minimal CSS required to render the components. Somewhere in your app, you need to import our CSS:

import '@zach.codes/react-calendar/dist/calendar-tailwind.css';

If you already have a CSS reset in your app, you can import from:

import '@zach.codes/react-calendar/dist/calendar-tailwind-no-reset.css';

But some styles may not look the same as storybook. You can take the resets you want from the main file and put them into your app to get the styling you prefer.

MonthlyCalendar

This is a monthly view similar to react-big-calendar or a Calendar application. It makes it easy to load events 1 month at a time, and render custom elements on each day.

See in action

Props

MonthlyCalendar

  • currentMonth this must be a Date instance representing the first of the month you wish to view
  • onCurrentMonthChange is called any time the month is changing from the Navigation area

MonthlyNav

No props at this time

MonthlyBody

  • omitDays lets you hide certain days from the calendar, for instance, hide Saturday and Sunday. Days are represented as 0-6, as seen in the date-fns documentation. Hiding Monday would be omitDays={[1]} Hiding the weekend would be omitDays={[0, 6]}
  • events this is an array of events, the only thing required inside each object is a date field with a Date object representing the exact time of the event

MonthlyDay

  • renderDay callback function that is passed an array of events for each day displayed, letting you render the events for the day

WeeklyCalendar

View 1 week at a time, useful for scheduling appointments, or rendering events in a smaller area of the screen

See in action

<WeeklyCalendar week={new Date()}>
  <WeeklyContainer>
    <WeeklyDays />
    <WeeklyBody
      events={[{ title: 'Jane doe', date: new Date() }]}
      renderItem={({ item, showingFullWeek }) => (
        <DefaultWeeklyEventItem
          key={item.date.toISOString()}
          title={item.title}
          date={
            showingFullWeek
              ? format(item.date, 'MMM do k:mm')
              : format(item.date, 'k:mm')
          }
        />
      )}
    />
  </WeeklyContainer>
</WeeklyCalendar>

This code renders an event for the current date. When you are in the week view, it displays the day and time. When you drill into a single day, it displays the time only.

Props

WeeklyCalendar

  • week a date object to initialize for the weekly view

WeeklyContainer

A view only component to flex the buttons and content area

WeeklyDays

Renders the buttons to view an individual day

  • omitDays, same as the MonthlyBody prop

WeeklyBody

  • style optional style info for setting the container height
  • events array of events with a date field, and anything else you want.
  • renderItem callback to render individual items on the side.

Full Control

This library has very few props to understand. It takes a component-first approach instead of endless prop options.

Building a calendar is highly opinionated. This library lets you easily customize any piece of it. Let's take a look at the MonthlyNav component:

import { useMonthlyCalendar } from '@zach.codes/react-calendar';

export const MonthlyNav = () => {
  let { currentMonth, onCurrentMonthChange } = useMonthlyCalendar();

  return (
    <div className="flex justify-end mb-4">
      <button
        onClick={() => onCurrentMonthChange(subMonths(currentMonth, 1))}
        className="cursor-pointer"
      >
        Previous
      </button>
      <div className="ml-4 mr-4 w-32 text-center">
        {format(
          currentMonth,
          getYear(currentMonth) === getYear(new Date()) ? 'LLLL' : 'LLLL yyyy'
        )}
      </div>
      <button
        onClick={() => onCurrentMonthChange(addMonths(currentMonth, 1))}
        className="cursor-pointer"
      >
        Next
      </button>
    </div>
  );
};

It's rendering some button elements, and then the current month. If it's not the current year, it renders the year as well.

You can copy / paste this component into your own repo. The magic piece is useMonthlyCalendar. This hook will let you access anything from the calendar context.

With this in mind, you can fully replace any of the default components to have custom behavior for your own app.

More Repositories

1

validify

Simple-as-possible React form validation
TypeScript
281
star
2

cli.rs

use {yourproject}.cli.rs!
275
star
3

gutenblock

The easiest way to develop and release Gutenberg blocks (components) for WordPress
JavaScript
239
star
4

react-router-async-routing

react router v4 async routing
JavaScript
127
star
5

reactview

reactview lets you instantly view (and hot reload) any react component in your browser
JavaScript
96
star
6

react-native-autofocus

Autofocus the next input field on enter in React Native
JavaScript
86
star
7

use-upload

Framework agnostic library handling file uploads with progress, direct to AWS / GCP, and other locations
TypeScript
77
star
8

match

a port of Rust's match in JS
JavaScript
77
star
9

formjs

A form generator for Reactjs "Alpachajs for React" Open the inspector on the demo page:
JavaScript
49
star
10

react-slug

A React component that will turn any input into a URL friendly slug!
JavaScript
23
star
11

graphql-course

Code from ultimatecourses
JavaScript
17
star
12

moovite

TypeScript
15
star
13

Simpler

A simple react / angular clone. Well, that's the end goal anyway. Just an experiment.
JavaScript
11
star
14

react-runner

build react apps with minimal setup WIP
JavaScript
10
star
15

Spot

a horribly coded thingy using contenteditable attributes
PHP
9
star
16

stock-api

get latest stock price data using puppeteer and google
JavaScript
8
star
17

redux-restore

Handles storage in React Native
JavaScript
8
star
18

flydb

nosql, in memory database for json documents
Rust
6
star
19

nexus-prisma-boilerplate

Get started with Nexus and Prisma quickly
TypeScript
6
star
20

legit.js

a lightweight javascript framework for modifying the DOM / CSS
JavaScript
6
star
21

passwordless

[Beta] Open source webauthn hardware key implementation for Node + JS
TypeScript
5
star
22

nodechat

working on making a full on live chatroom with node.js and socket.io
JavaScript
4
star
23

reason-apollo-server

Set of bindings for Apollo Server in ReasonML
OCaml
4
star
24

restor

simpler-than-redux react state management
JavaScript
3
star
25

React-Generator

quickly create components and get to coding!
JavaScript
3
star
26

vscode-sort-by-length

Sort imports by line length in VS Code!
TypeScript
3
star
27

render-placement-loader

Add React.render to your component automatically (used in reactview)
JavaScript
2
star
28

webpack-force-hash-plugin

Only changes the vendor hash if needed
JavaScript
2
star
29

react-easy-test

need a better name... scroll down and see what this is!
JavaScript
2
star
30

memeify

A slack bot that generates memes from photos you choose!
JavaScript
2
star
31

suspense-fetch

experimental useFetch with suspense concurrent mode
JavaScript
1
star
32

action.js

a mini library for turning form requests into ajax
JavaScript
1
star
33

stream

a simple node / react app for displaying live streams
JavaScript
1
star
34

iBlog

a PHP project I made back when I was 15 (5 years ago) woah....
PHP
1
star
35

hmr-apollo-server

Apollo server 2 with hot module replacement
JavaScript
1
star
36

homie

iOS app that turns on Philips Hue lights using iBeacons (WIP)
Swift
1
star
37

huetron

a desktop app for managing your hue lights
JavaScript
1
star
38

class

js / node coding course
JavaScript
1
star
39

react-suspendable

a function that can wrap any async action and make it compatible with suspense
TypeScript
1
star
40

WProgress

Reading progress bar and other readability enhancements for your Wordpress blog
JavaScript
1
star
41

react-state-management

Created with StackBlitz ⚑️
JavaScript
1
star