npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@knightburton/react-interval-calendar

v3.1.0

Published

Infinite scrolling based calendar for interval dates built with React.

Downloads

53

Readme

react-interval-calendar

Build Workflow npm npm

Infinite scrolling based calendar for interval dates built with React.

  • no additional dependencies
  • no additional date library
  • customizable
  • lightweight

Table of Contents

Getting Started

Compatibility

Your project needs to use React.js 16.8 or later.

React-Interval-Calendar uses modern web technologies. It's only supports modern web browser with internationalization API. In legacy browsers you have to use additional polyfill for internationalization to be able to use this library.

Installation

$ npm i @knightburton/react-interval-calendar

or

yarn add @knightburton/react-interval-calendar

Usage

Here's an example of basic usage:

import React from 'react';
import IntervalCalendar from '@knightburton/react-interval-calendar';

const App = () => (
  <IntervalCalendar
    weekStartsOn={1}
    start={new Date(2021, 1, 1)}
    end={new Date(2021, 6, 31)}
    slotProps={{ bodyCell: { onClick: (event, data) => console.log(event, data) } }}
  />
);

export default App;

For more detailed example check the example directory.

Prop-Types

| Prop name | Type | Default value | Description | | --- | --- | --- | --- | | start | Date | undefined | The beginning of the calendar that should displayed. The calendar will display the whole month of the start date. | | end | Date | undefined | The end of the calendar that should displayed. The calendar will display the whole month of the end date. | | locale | string | default | Locale that should be used to format and display the days and months. Can be an IETF language tag. | | numberOfRowsFirstRender | number | 8 | Number of weeks to render below the visible weeks on the first render. | | numberOfRowsPreRender | number | 4 | Number of weeks to render below the visible weeks. Tweaking this can help reduce flickering during scrolling on certain browsers/devices. | | startRenderOnCurrentWeek | boolean | false | Wether the render of weeks should start at the current week or the start od the given calendar interval. | | weekStartsOn | number | 0 | The index of the day that the week should starts on. Can be 0, 1, 2, 3, 4, 5 or 6. | | slots | Slots | undefined | The components used for each slot inside. | | slotProps | Slot Props | undefined | The extra props for the slot components. You can override the existing props or add new ones. Check the Prop Overrides section for further information. |

Slots

type Slots = {
  root?: React.ElementType;
  header?: React.ElementType;
  headerCell?: React.ElementType;
  headerCellContent?: React.ElementType;
  body?: React.ElementType;
  bodyRow?: React.ElementType;
  bodyCell?: React.ElementType;
  bodyCellContent?: React.ElementType;
  empty?: React.ElementType;
};

Slot Props

type SlotProps = {
  root?: Partial<React.ComponentPropsWithoutRef<'div'>>;
  header?: Partial<React.ComponentPropsWithoutRef<'ul'>> & { disabled?: boolean };
  headerCell?: Partial<React.ComponentPropsWithoutRef<'li'>>;
  headerCellContent?: Partial<React.ComponentPropsWithoutRef<'div'>> & { data: HeaderCellData };
  body?: Partial<React.ComponentPropsWithoutRef<'div'>>;
  bodyRow?: Partial<React.ComponentPropsWithRef<'ul'>>;
  bodyCell?: Omit<Partial<React.ComponentPropsWithoutRef<'li'>>, 'onClick'> & {
    onClick?: (event: React.MouseEvent<HTMLLIElement>, data: BodyCellData) => void;
  };
  bodyCellContent?: Partial<React.ComponentPropsWithoutRef<'div'>> & { data: BodyCellData; locale?: string };
  empty?: Partial<React.ComponentPropsWithoutRef<'div'>> & { label?: string };
};

Header Cell Data

| Prop name | Type | Description | | --- | --- | --- | | key | number | Identifier that created from the day of the week. | | short | string | Day of the week formatted with the provided locale prop as short weekday. | | long | string | Day of the week formatted with the provided locale prop as long weekday. | | narrow | string | Day of the week formatted with the provided locale prop as narrow weekday. |

Body Cell Data

| Prop name | Type | Description | | --- | --- | --- | | key | string | Identifier that created from the number of week and day of the week. | | date | Date | Actual Date object. | | day | string | Day of the month formatted with the provided locale prop as 2-digit day. | | month | string | Month from the actual date formatted with the provided locale prop as short month. | | year | string | Year from the actual date formatted with the provided locale prop as numeric year. | | isFirstDayOfYear | boolean | Describes whether the day is the first day of the year or not. | | isMonthEven | boolean | Describes whether the month of the actual date is even or not. | | isFirstDayOfMonth | boolean | Describes whether the actual date is the first day of the month or not. | | isLastDayOfMonth | boolean | Describes whether the actual date is the last day of the month or not. | | isToday | boolean | Describes whether the actual date is the same date as today or not. | | isWeekend | boolean | Describes whether the actual date is on weekend or not. |

Prop Overrides

You can override each and every slotProps type. With this you can pass custom properties into each slotProps with a simple module augmentation. This will allow you to have custom properties that is available both on slotProps definition and component prop as well.

Most of the component props are available to override. Look for exported interfaces with the name of the component that you want to augment and Overrides suffix.

Define your custom types like the following:

declare module '@knightburton/react-interval-calendar' {
  interface ContainerPropsOverrides {
    something?: boolean;
  }
}

// In your component, you can define the value like the this
<IntervalCalendar
  weekStartsOn={1}
  start={new Date(2021, 1, 1)}
  end={new Date(2021, 6, 31)}
  slotProps={{ root: { something: true } }}
/>

// Also, this will be available on component props as well
const Root = ({ children, something }: ContainerProps): JSX.Element => <></>;

Migration Guides

From v2 to v3

There are three breaking changes in v3, mainly prop changes.

  1. There are no standalone props for internal components override anymore. All the internal components are still replaceable through the slots prop. In order to migrate the component overrides from v2, move your components inside the slots prop.

    <IntervalCalendar
      start={new Date(2021, 1, 1)}
      end={new Date(2021, 6, 31)}
    - containerComponent={MyContainer}
    - headerContainerComponent={MyHeaderContainer}
    - headerCellContentComponent={MyHeaderCellContent}
    - bodyContainerComponent={MyBodyContainer}
    - bodyCellContentComponent={MyBodyCellContent}
    - emptyComponent={MyEmpty}
    + slots={{
    +   root: MyContainer,
    +   header: MyHeaderContainer,
    +   headerCellContent: MyHeaderCellContent,
    +   body: MyBodyContainer,
    +   bodyCellContent: MyBodyCellContent,
    +   empty: MyEmpty;
    + }}
    />

    Note that, there are a couple new components that can be replaced with any slots. Check the Slots prop definition.

  2. There are no standalone props to provide additional className to any internal or replaced components anymore. All the components can get a className through the new slotProps prop. In order to migrate the given values, move those into the slotProps to each component.

    <IntervalCalendar
      start={new Date(2021, 1, 1)}
      end={new Date(2021, 6, 31)}
    - containerClassName="my-container"
    - headerContainerClassName="my-header-container"
    - headerRowClassName="my-header-row"
    - headerCellClassName="my-header-cell"
    - headerCellContentClassName="my-header-cell-content"
    - bodyContainerClassName="my-body-container"
    - bodyRowClassName="my-body-row"
    - bodyCellClassName="my-body-cell"
    - bodyCellContentClassName="my-body-cell-content"
    - emptyClassName="my-empty"
    + slotProps={{
    +   root: { className: 'my-container' },
    +   header: { className: 'my-header-row' },
    +   headerCell: { className: 'my-header-cell' },
    +   headerCellContent: { className: 'my-header-cell-content' },
    +   body: { className: 'my-body-container' },
    +   bodyRow: { className: 'my-body-row' },
    +   bodyCell: { className: 'my-body-cell' },
    +   bodyCellContent: { className: 'my-body-cell-content' },
    +   empty: { className: 'my-empty' },
    + }}
    />

    Note that, there is no headerContainerClassName anymore, because there is no header container component anymore. That component got merged with header.

  3. There are no standalone emptyLabel, height, onCellClick and showHeader prop anymore. All of these moved into the slotProps prop under the associated component key. In order to migrate the props, move them into the slotProps.

    <IntervalCalendar
      start={new Date(2021, 1, 1)}
      end={new Date(2021, 6, 31)}
    - emptyLabel="Meh..."
    - height={500}
    - onCellClick={(data) => console.log(data)}
    - showHeader={false}
    + slotProps={{
    +   root: { style: { height: 500 } },
    +   header: { enabled: false },
    +   bodyCell: { onClick: (event, data) => console.log(event, data) },
    +   empty: { label: 'Meh...' },
    + }}
    />

    Where the height just part of the style prop alongside with all the other style attributes.

    Where the onCellClick changed and replaced by a regular onClick prop where the first argument is the actual event that got fired from HTMLLIElement click and the second argument is the actual Body Cell Data.

Development

First of all, you will need to use node v20, best way to start with nvm. Local development is broken into two parts (ideally using two terminal tabs).

First, run rollup to watch your src/ module and automatically recompile it into dist/ whenever you make changes.

# Assume that you are in the project main folder
$ npm i
$ npm start

The second part will be running the example/ create-react-app that's linked to the local version of your module.

# Assume that you are in the project main folder
$ cd example
$ npm i
$ npm start

Contributing

First off all, thanks for taking the time to contribute! :muscle:

Before any action, please visit the Code of Conduct and Contributing guideline for more information.

License

React Interval Calendar is Open Source software under the MIT license. Complete license and copyright information can be found within the license.