Giter Site home page Giter Site logo

clauderic / react-infinite-calendar Goto Github PK

View Code? Open in Web Editor NEW
4.0K 50.0 401.0 4.01 MB

✨ Infinite scrolling date-picker built with React, with localization, range selection, themes, keyboard support, and more.

Home Page: http://clauderic.github.io/react-infinite-calendar/

License: MIT License

JavaScript 69.83% CSS 30.17%
react calendar datepicker infinite infinite-scroll component date range

react-infinite-calendar's Introduction

React Infinite Calendar

Currently looking for maintainers to help maintain this project, please reach out if you would be interested

npm version downloads license Gitter

Features

  • Infinite scroll – Just keep scrollin', just keep scrollin'
  • Flexible – Min/max date, disabled dates, disabled days, etc.
  • Extensible – Add date range-selection, multiple date selection, or create your own HOC!
  • Localization and translation – En français, s'il vous plaît!
  • Customizeable – Customize and theme to your heart's content.
  • Year selection – For rapidly jumping from year to year
  • Keyboard support – ⬆️ ⬇️ ⬆️ ⬇️ ⬅️ ➡️ ⬅️ ➡️ ↩️
  • Events and callbacks – beforeSelect, onSelect, onScroll, etc.
  • Mobile-friendly – Silky smooth scrolling on mobile

Getting Started

Using npm:

npm install react-infinite-calendar --save

ES6, CommonJS, and UMD builds are available with each distribution. For example:

import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css'; // Make sure to import the default stylesheet

You can also use a global-friendly UMD build:

<link rel="stylesheet" href="react-infinite-calendar/styles.css">
<script src="react-infinite-calendar/umd/react-infinite-calendar.js"></script>
<script>
var InfiniteCalendar = window.InfiniteCalendar.default;
...
</script>

Usage

Basic Example

import React from 'react';
import { render } from 'react-dom';
import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css'; // only needs to be imported once

// Render the Calendar
var today = new Date();
var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);

render(
  <InfiniteCalendar
    width={400}
    height={600}
    selected={today}
    disabledDays={[0,6]}
    minDate={lastWeek}
  />,
  document.getElementById('root')
);

For more usage examples, see http://clauderic.github.io/react-infinite-calendar/ or check out some code examples.

Prop Types

Property Type Default Description
selected Date or Boolean new Date() Value of the date that appears to be selected. Set to false if you don't wish to have a date initially selected.
width Number 400 Width of the calendar, in pixels
height Number 600 Height of the calendar, in pixels
min Date new Date(1980, 0, 1) The minimum month that can be scrolled to.
max Date new Date(2050, 11, 31) The maximum month that can be scrolled to.
minDate Date new Date(1980, 0, 1) The minimum date that is selectable.
maxDate Date new Date(2050, 11, 31) The maximum date that is selectable.
disabledDays Array Array of days of the week that should be disabled. For example, to disable Monday and Sunday: [0, 6]
disabledDates Array Array of dates that should be disabled. For example: [new Date(2017, 1, 8), new Date(), new Date(2017, 5, 17)]
display String 'days' Whether to display the years or days view.
displayOptions Object See default displayOptions See display options section for more details.
locale Object See default locale By default, React Infinite Calendar comes with the English locale. You can use this to change the language, or change the first day of the week. See date-fns documentation for more details
theme Object See default theme Basic customization of the colors
className String Optional CSS class name to append to the root InfiniteCalendar element.
onSelect Function Callback invoked after beforeSelect() returns true, but before the state of the calendar updates
onScroll Function Callback invoked when the scroll offset changes. function (scrollTop: number) {}
onScrollEnd Function Callback invoked 150ms after the last onScroll event is triggered. function (scrollTop: number) {}
rowHeight Number 56 Height of each row in the calendar (each week is considered a row)
autoFocus Boolean true Whether the Calendar root should be auto-focused when it mounts. This is useful when keyboardSupport is enabled (the calendar must be focused to listen for keyboard events)
tabIndex Number 1 Tab-index of the calendar

Display Options

Property Type Default Description
layout String 'portrait' Layout of the calendar. Should be one of 'portrait' or 'landscape'
showHeader Boolean true Show/hide the header
shouldHeaderAnimate Boolean true Enable/Disable the header animation
showOverlay Boolean true Show/hide the month overlay when scrolling
showTodayHelper Boolean true Show/hide the floating back to Today helper
showWeekdays Boolean true Show/hide the weekdays in the header
hideYearsOnSelect Boolean true Whether to automatically hide the years view on select.
overscanMonthCount Number 4 Number of months to render above/below the visible months. Tweaking this can help reduce flickering during scrolling on certain browers/devices.
todayHelperRowOffset Number 4 This controls the number of rows to scroll past before the Today helper appears

Example usage of display options:

<InfiniteCalendar
  displayOptions={{
    layout: 'landscape',
    showOverlay: false,
    shouldHeaderAnimate: false
  }}
/>

Dependencies

React Infinite Calendar has very few dependencies. It relies on react-tiny-virtual-list for virtualization and date-fns for handling date manipulation. It also uses recompose for extending the default functionality. It also has the following peerDependencies: react, and react-transition-group.

Reporting Issues

If you find an issue, please report it along with any relevant details to reproduce it. The easiest way to do so is to fork this sandbox on CodeSandbox.

Contributions

Yes please! Feature requests / pull requests are welcome. Learn how to contribute

Have a suggestion or just want to say hello? Come chat on Gitter!

License

react-infinite-calendar is available under the MIT License.

react-infinite-calendar's People

Contributors

clauderic avatar lulzaugusto avatar nicolasleger avatar offsky avatar peggyrayzis avatar syko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-infinite-calendar's Issues

Click on today helper not work.

import React from 'react';
import ReactDOM from 'react-dom';
import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css';

ReactDOM.render(
  <InfiniteCalendar />,
  document.querySelector('.appContainer')
);

This is my code, nothing special. I traced down the source code, found out that I got undefined scrollEl every time. Please help.
20160803111103

have no response sometimes when i click and scroll

it like a static picture sometimes and have no response when i click and scroll it. i just imported and rendered this component , maybe it's slow? and how to get the value of the onSelect event , i mean that i just wanna the date like 2016-10-23, not Wed Oct 26 2016 00:00:00 GMT+0800.

cannot fork and install this repo

Hey Clauderic,

Just an FYI - it is not possible to fork this repo and then install your fork via npm without trouble. I have seen similar problems before.

Essentially, if it doesn't come from the npm registry, you get this:

➜  ✗ ls node_modules/react-infinite-calendar 
CHANGELOG.md LICENSE      README.md    node_modules package.json styles.css

Missing all of the important stuff.

I tried adding bin/postinstall like so:

#!/bin/bash

node -e "require('fs').stat('dist', function (e, s) { process.exit(e || !s.isDirectory() ? 1 : 0) })" || npm run build

chmod 755 bin/postinstall

and adding to package.json

...
    "codecov": "cat coverage/*/lcov.info | codecov",
    "postinstall": "./bin/postinstall"
  },
...

But I think crossenv devDependency is giving some trouble there.

Any thoughts on this?

Error: addComponentAsRefTo(...)

I'm trying to use react-infinite-calendar in an existing react app. These are my steps:

  1. because our webpack config excludes node_modules, webpack wouldn't run the loaders needed by react-infinite-calendar, therefore I created 2 new loaders in our webpack config:

        {
            test: /\.jsx?$/,
            loaders: ['babel'],
            include: /react-infinite-calendar/
        },
        {
            test: /(\.scss|\.css)$/,
            loaders: ['style', 'css?sourceMap&modules&importLoaders=1&localIdentName=Cal__[name]__[local]!postcss!sass?sourceMap'],
            include: /react-infinite-calendar/
        }
    
  2. when I run the application i get the following error

invariant.js:38 Uncaught (in promise) Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).(…)

The calendar does not render successfully as a result of the exception:
screen shot 2016-08-04 at 16 19 35

Numbered badges for particular days

I needed small colored number badges to show up on particular days, so I built this for myself. Id be happy to clean up my code and create a pull request if this was functionality that you wanted in your project.

screen shot 2016-07-07 at 11 41 25 am

suggest

I think this calendar will be very nice, if it can select local language and give us a unpkg adress.

Error when including the css

In what circumstances is import 'react-infinite-calendar/styles.css'; expected to work? I'm using browserify/babelify and I get an "Unexpected Token" error when trying to build - I don't think importing css files in js source files will work without some kind of transform, at least with browserify (and I haven't had any luck with the browserify-css transform). Any suggestions?

new selectedDate on every render does not center

When you re-render passing in a different selectedDate each time (where selected date is bound to state of container component), the component will not properly center on the selected date. The behavior can be seen by clicking around on different dates (usually the ones at the top or bottom of the calendar, because these need to be scrolled). This example is loosely based on Flexible Size example:

import React from 'react';
import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css';
import moment from 'moment';

export default class extends React.Component {
  constructor (props) {
    super(props);

    this.state = {
      selectedDate: moment()
    };
  }

  render () {
    let selectedDate = this.state.selectedDate;

    return (
      <InfiniteCalendar
        width={(window.innerWidth <= 650) ? window.innerWidth : 650}
        height={window.innerHeight - 250}
        rowHeight={70}
        selectedDate={selectedDate}
        afterSelect={(date) => {
          this.setState((prevState, currProps) => {
            return {
              selectedDate: date
            };
          });
        }}
      />
    );
  }
}

This is even more problematic when you have a short calendar, like so:

import React from 'react';
import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css';
import moment from 'moment';

export default class extends React.Component {
  constructor (props) {
    super(props);

    this.state = {
      selectedDate: moment()
    };
  }

  render () {
    let selectedDate = this.state.selectedDate;

    return (
      <InfiniteCalendar
        width={280}
        height={156}
        rowHeight={62}
        selectedDate={selectedDate}
        afterSelect={(date) => {
          this.setState((prevState, currProps) => {
            return {
              selectedDate: date
            };
          });
        }}
      />
    );
  }
}

You will notice that when you load the component, the selectedDate is not visible.

Multi datepicker

Would it be within the scope of this component to allow for the selection of one or more dates?

Moment Dependency Concern

I've been using this component in my application and we're getting ready to deploy. However as we have been optimizing the size of out application we began using webpack dependency graph to visualize what is taking up the most size in our application. Turns out it's moment.js which is coming from react-infinite-calendar is taking up 20% of the application size. Is there anyway you guys could some how remove this dependency or extrapolate the functionality that you are using out from moment.js?

Not sure if moment offers but some modules like lodash, and react-bootstrap allow you to cherry pick the functionality you need from them in order to shed some size of your application.

please let me know.

How to configure locale?

i want to change the English to Chinese or number like October to 10月 , and the header change to 2016-10-22 . How can i do ?

Floating Today Helper not reliable

Ive noticed some bugs with the floating today helper. My interpretation of the helper is that if "today" is not visible on the screen, then the helper appears.

  1. If you scroll all the way to the top, it hides. I think it should stay visible.
  2. When scrolling back in time, the helper does not appear until "today" is several weeks below the fold.
  3. When scrolling forwards in time, the helper does not appear until "today" is several months above the fold.

I think it would be more convenient if the today helper was always visible if "today" was not visible.

For these screenshots, today is June 24th.

screen shot 2016-06-24 at 11 57 28 am
screen shot 2016-06-24 at 11 59 54 am

Click events

Click events have sort of strange names, it took me a while to realize what are they doing.
beforeSelect -> onClick, that stops event propagation
onSelect -> onSelect,
afterSelect -> onSelected.

Also when I define beforeSelect then onSelect and afterSelect will not be called. I think
this should be decided by user.

Calendar Events

Is it possible to add Events to the calendar? Like say programmatically load in upcoming events and have them highlighted?

year selection

hi, I love your calendar. Is there any way to easily select a year? I.e. 1950

Doesn't render while using the UMD build

I'm using the UMD build by just adding the single script react-infinite-calendar.js and then I'm using the example code on your page.
But it gives this React error (I'm using React version 0.15):
React.createElement: type should not be null, undefined, boolean, or number.

Warning on selecting date from the infinte calender

Warning: Failed propType: Invalid prop shouldHeaderAnimate of type string supplied to Header, expected boolean. Check the render method of InfiniteCalendar.

Object { selectedDate: Object, shouldHeaderAnimate: ".0.0.1.0.0.0.0.0.2.0.0.0.0.2.0.0.1.1.1.0.$3-0.$Month-3.0.$Row-1.$day-6", layout: "portrait", theme: Object, locale: Object, scrollToDate: InfiniteCalendar/_this.scrollToDate(), setDisplay: InfiniteCalendar/_this.setDisplay(), display: "days" }

about i18N

how to internationalization the calendar?

Server rendering?

I am building an univers app. I tried to use RIC but it seems that it doesn't work for server rendering? Or maybe I got wrong on something?

Custom components/renderers as props

I haven't checked out the code yet, so can't tell if it would be easy or not, but one thing I've done on other components is to be able to pass components or function renderers as props, like < InfiniteCalendar header={<MyCustomCalendarHeader />} />. This allows for much more sophisticated theming/customizations, displaying dates differently, having custom "cells" for days, etc.

If others are interested I can start working on it later this week and see how it could work.

The beginning and end of a month rendered in a strange way.

Hi, have no idea why it happens, attached a few screenshots.
image
image
image

Styles are imported,
Usage:

<InfiniteCalendar afterSelect={(e) => this.updateDate(e)} selectedDate={false} disabledDates={bookedDates} minDate={moment().startOf('day')} />

Even when left still the same issue.
Your calendar looks good and I'd like to use it in my project, what could be the issue?

invalid number of rows

when
min=05.2016
minDate=05.31.2016
locale={{week: { dow: 1, doy: 4 }}}

first row of june overlaps first row of may

Display issue in days or years panel on page load until scroll is initiated

Kind of a newbie here but did not see this issue mentioned anywhere.

On page load and reload, when display="days", the days' panel is blank or half-filled when the min date is more than a few months apart than the selectedDate (even in the basic configuration).
Same as when display="years" but the min and selectedDate need to be about 20 years apart.

The '.Grid__cell' divs seem to be pushed down past the ' .Grid__innerScrollContainer'.

When you start scrolling, it starts displaying from the min date. It seems like the display does not get positioned to the selectedDate. It also considers selectedDate="null" as the default date in this behavior.

Here are some screenshots:
infinite_calendar_issue
infinite_calendar_issue_years

Locale does not apply to dates created in util.js

When applying locale like so:

const locale = {
            name: 'nl',
            todayLabel: {
                long: 'Vandaag'
            },
            week: {
                dow: 0 // week starts on sunday
            },
            months : "januari_februari_maart_april_mei_juni_juli_testing_september_oktober_november_december".split("_"),
            monthsShort : "jan_feb_mar_apr_mei_jun_jul_tst_sep_okt_nov_dec".split("_"),
            weekdays : "Zondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrijdag_Zaterdag".split("_"),
            weekdaysShort : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_")
        };

        return (
            <div>
                <InfiniteCalendar
                    ...
                    locale={locale}
                />
            </div>

(I've changed "August" to "testing" and "Aug" to "tst")

The labels of the days of the week get translated correctly. However, the months do not:

screen shot 2016-08-12 at 15 16 16

(Note that the multiple dates come from my own fork with support for this, note that I didn't change anything related to locales)

When debugging your library I found that the locale is set correctly to moment.js. E.g.:

index.js

updateLocale(locale) {
    locale = this.getLocale(locale);
    moment.updateLocale(locale.name, locale);
    moment.locale(locale.name);

    console.log('logging date format at init');
    const date = moment();
    console.log(date.format('MMM'));
}

will correctly output tst

But inside List/index.js:

renderMonth = ({index, isScrolling}) => {
    let {...} = this.props;
    let {date, rows} = this.memoize(months[index]);

    console.log('logging date format at list render month');
    const date2 = moment();
    console.log(date.format('MMM'));
    console.log(date2.format('MMM'));

Date2 (the newly created moment) is correct: tst. However, the original date coming from this.memoize will be English (Aug).

I believe this is because this date comes from another instance of moment.js inside util.js

utils.js

export function getMonth(monthDate) {
    let rows = {};
    let daysInMonth = monthDate.daysInMonth();
    let year = monthDate.year();
    let month = monthDate.month();

    let week, date, lastWeekVal;
    let weekIndex = -1;

    for (let i = 0; i < daysInMonth; i++) {
        date = moment(new Date(year,month,i+1)); //this moment.js does not have locale applied
                ....

But I have no apparent solution for now. What do you think is the cause of these different instances of moment? Do we need to re-apply locale every time moment.js is imported?

react-infinite-calendar not rendering properly

Hi, so I'm attempting to render a full-size react-infinite-calendar within a material-ui dialog, and the calendar does not appear to be rendering properly. The default configuration calendar also does not render correctly. I have attached an image of what it looks like.

screen shot 2016-08-16 at 4 48 24 pm

disabledDates could handle functions ?

disabledDates could be enhanced to also take a function rather than just an array.

The change would be pretty simple, something like (untested)

isDisabled = (
    minDate && date.yyyymmdd < minDate.yyyymmdd ||
    maxDate && date.yyyymmdd > maxDate.yyyymmdd ||
    disabledDays && disabledDays.length && disabledDays.indexOf(date.date.day()) !== -1 ||
    disabledDates && disabledDates.length && disabledDates.indexOf(date.yyyymmdd) !== -1 ||
    disabledDates && (typeof disabledDates === 'function') && disabledDates(date.date)
);

This would allow passing a function to disable days depending on some random rules, like "first monday of the month".

add examples from clauderic.github.io to repo

Do you also think it would be very helpful if there was an examples/ dir that contains the examples at http://clauderic.github.io/react-infinite-calendar/#/basic-settings/basic-configuration?_k=g8hyyp

This would allow developers working on this project to be able to run a local comparison side-by-side against expected behaviors from the given examples.

Ideally this would include a simple npm run dev or npm start command, with a simple server, that will run the examples dir.

Option to show week number?

Hello,
I had a look at the API and couldn't see an option to show week numbers. I would love to use this component but most of our customers in Europe require the week number of the year (from 1 to 53), using a standard ISO calculation (https://en.wikipedia.org/wiki/ISO_week_date).

Should I create a Pull Request to add the extra column?

Thanks,
Bren

Specifying Width/Height in %

Hello,

I have encountered following issue: http://prntscr.com/be6h27
Seems that specifying width and height in % is not possible despite documentation saying so?

Component used as:

import Calendar from 'react-infinite-calendar';

<Calendar
  width={'100%'}
  display={display}
  theme={CALENDAR_THEME}
  selectedDate={selectedDate}
  onSelect={this.onDateSelectHandler}
/>

Some parts are not provided for brevity.

Thanks,

[Request] Callback on arrow keyPress

Hi there,
I've found a missing logic for keyboard support. Which is to have a callback every time user press arrow key and have the current date as param

thank you!

Prop type error every time I select a new day

The calendar component renders as expected, the problem is every time I select a new day, I get a lot of errors in the console.

My render function:

  render() {
    var today = new Date();
    var minDate = Number(new Date()) - (24 * 60 * 60 * 1000) * 7;

    return (
      <InfiniteCalendar
        selectedDate={today}
        minDate={minDate}
        keyboardSupport={true}
        onSelect={ date => {
          console.log("DATE", date);
        }}
      />
    );
  }

Every time I click in a new day I get a lot of errors in the console:

warning.js:36 Warning: Failed prop type: Invalid prop `shouldHeaderAnimate` of type `object` supplied to `Header`, expected `boolean`
...
warning.js:36 Warning: Failed prop type: Invalid prop `transitionEnter` of type `object` supplied to `ReactCSSTransitionGroup`, expected `boolean`
...
warning.js:36 Warning: Failed prop type: Invalid prop `transitionLeave` of type `object` supplied to `ReactCSSTransitionGroup`, expected `boolean`.
...
warning.js:36 Warning: Failed prop type: Invalid prop `enter` of type `object` supplied to `ReactCSSTransitionGroupChild`, expected `boolean`.
    in ReactCSSTransitionGroupChild (created by ReactTransitionGroup)
...
warning.js:36 Warning: Failed prop type: Invalid prop `leave` of type `object` supplied to `ReactCSSTransitionGroupChild`, expected `boolean`.
    in ReactCSSTransitionGroupChild (created by ReactTransitionGroup)

Any thoughts how to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.