{"id":20495785,"url":"https://github.com/knightburton/react-interval-calendar","last_synced_at":"2025-04-13T17:44:33.099Z","repository":{"id":57125155,"uuid":"373926848","full_name":"knightburton/react-interval-calendar","owner":"knightburton","description":"Infinite scrolling based calendar for interval dates built with React.","archived":false,"fork":false,"pushed_at":"2024-01-23T21:30:04.000Z","size":2395,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-24T16:47:53.245Z","etag":null,"topics":["calendar","date","hacktoberfest","headless","infinite-calendar","infinite-scroll","interval-calendar","interval-dates","react","react-hooks","scroll","slots","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knightburton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-04T18:19:36.000Z","updated_at":"2024-03-28T00:49:37.000Z","dependencies_parsed_at":"2023-10-17T03:02:10.897Z","dependency_job_id":"b3288784-cf49-4c99-a419-70c3b193c564","html_url":"https://github.com/knightburton/react-interval-calendar","commit_stats":{"total_commits":222,"total_committers":3,"mean_commits":74.0,"dds":0.04054054054054057,"last_synced_commit":"4a4846837c0c65a831321c2a28aa130a4dfc88f4"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightburton%2Freact-interval-calendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightburton%2Freact-interval-calendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightburton%2Freact-interval-calendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightburton%2Freact-interval-calendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knightburton","download_url":"https://codeload.github.com/knightburton/react-interval-calendar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248756922,"owners_count":21156849,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","date","hacktoberfest","headless","infinite-calendar","infinite-scroll","interval-calendar","interval-dates","react","react-hooks","scroll","slots","typescript"],"created_at":"2024-11-15T17:47:08.209Z","updated_at":"2025-04-13T17:44:33.072Z","avatar_url":"https://github.com/knightburton.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-interval-calendar\n\n[![Build Workflow](https://github.com/knightburton/react-interval-calendar/actions/workflows/build.yml/badge.svg)](https://github.com/knightburton/react-interval-calendar/actions/workflows/build.yml)\n![npm](https://img.shields.io/npm/v/@knightburton/react-interval-calendar)\n![npm](https://img.shields.io/npm/dt/@knightburton/react-interval-calendar)\n\nInfinite scrolling based calendar for interval dates built with React.\n\n- no additional dependencies\n- no additional date library\n- customizable\n- lightweight\n\n# Table of Contents\n- [Getting Start](#getting-started)\n- [Usage](#usage)\n- [Migration Guides](#migration-guides)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n### Getting Started\n#### Compatibility\nYour project needs to use [React.js](https://reactjs.org/) 16.8 or later.\n\nReact-Interval-Calendar uses modern web technologies. It's only supports [modern web browser with internationalization API](https://caniuse.com/internationalization). In legacy browsers you have to use additional polyfill for internationalization to be able to use this library.\n\n#### Installation\n```bash\n$ npm i @knightburton/react-interval-calendar\n```\nor\n```bash\nyarn add @knightburton/react-interval-calendar\n```\n\n### Usage\nHere's an example of basic usage:\n```jsx\nimport React from 'react';\nimport IntervalCalendar from '@knightburton/react-interval-calendar';\n\nconst App = () =\u003e (\n  \u003cIntervalCalendar\n    weekStartsOn={1}\n    start={new Date(2021, 1, 1)}\n    end={new Date(2021, 6, 31)}\n    slotProps={{ bodyCell: { onClick: (event, data) =\u003e console.log(event, data) } }}\n  /\u003e\n);\n\nexport default App;\n```\nFor more detailed example check the [example](./example) directory.\n\n### Prop-Types\n| Prop name | Type | Default value | Description |\n| --- | --- | --- | --- |\n| start | Date | `undefined` | The beginning of the calendar that should displayed. The calendar will display the whole month of the start date. |\n| end | Date | `undefined` | The end of the calendar that should displayed. The calendar will display the whole month of the end date. |\n| locale | string | `default` | Locale that should be used to format and display the days and months. Can be an IETF language tag. |\n| numberOfRowsFirstRender | number | `8` | Number of weeks to render below the visible weeks on the first render. |\n| numberOfRowsPreRender | number | `4` | Number of weeks to render below the visible weeks. Tweaking this can help reduce flickering during scrolling on certain browsers/devices. |\n| startRenderOnCurrentWeek | boolean | `false` | Wether the render of weeks should start at the current week or the start od the given calendar interval. |\n| weekStartsOn | number | `0` | The index of the day that the week should starts on. Can be `0`, `1`, `2`, `3`, `4`, `5` or `6`. |\n| slots | [Slots](#slots) | `undefined` | The components used for each slot inside. |\n| slotProps | [Slot Props](#slot-props) | `undefined` | The extra props for the slot components. You can override the existing props or add new ones. Check the [Prop Overrides](#prop-overrides) section for further information. |\n\n#### Slots\n```ts\ntype Slots = {\n  root?: React.ElementType;\n  header?: React.ElementType;\n  headerCell?: React.ElementType;\n  headerCellContent?: React.ElementType;\n  body?: React.ElementType;\n  bodyRow?: React.ElementType;\n  bodyCell?: React.ElementType;\n  bodyCellContent?: React.ElementType;\n  empty?: React.ElementType;\n};\n```\n\n#### Slot Props\n```ts\ntype SlotProps = {\n  root?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'div'\u003e\u003e;\n  header?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'ul'\u003e\u003e \u0026 { disabled?: boolean };\n  headerCell?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'li'\u003e\u003e;\n  headerCellContent?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'div'\u003e\u003e \u0026 { data: HeaderCellData };\n  body?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'div'\u003e\u003e;\n  bodyRow?: Partial\u003cReact.ComponentPropsWithRef\u003c'ul'\u003e\u003e;\n  bodyCell?: Omit\u003cPartial\u003cReact.ComponentPropsWithoutRef\u003c'li'\u003e\u003e, 'onClick'\u003e \u0026 {\n    onClick?: (event: React.MouseEvent\u003cHTMLLIElement\u003e, data: BodyCellData) =\u003e void;\n  };\n  bodyCellContent?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'div'\u003e\u003e \u0026 { data: BodyCellData; locale?: string };\n  empty?: Partial\u003cReact.ComponentPropsWithoutRef\u003c'div'\u003e\u003e \u0026 { label?: string };\n};\n```\n\n#### Header Cell Data\n| Prop name | Type | Description |\n| --- | --- | --- |\n| key | `number` | Identifier that created from the day of the week. |\n| short | `string` | Day of the week formatted with the provided `locale` prop as `short` weekday. |\n| long | `string` | Day of the week formatted with the provided `locale` prop as `long` weekday. |\n| narrow | `string` | Day of the week formatted with the provided `locale` prop as `narrow` weekday. |\n\n#### Body Cell Data\n| Prop name | Type | Description |\n| --- | --- | --- |\n| key | `string` | Identifier that created from the number of week and day of the week. |\n| date | `Date` | Actual Date object. |\n| day | `string` | Day of the month formatted with the provided `locale` prop as `2-digit` day. |\n| month | `string` | Month from the actual date formatted with the provided `locale` prop as `short` month. |\n| year | `string` | Year from the actual date formatted with the provided `locale` prop as `numeric` year. |\n| isFirstDayOfYear | `boolean` | Describes whether the day is the first day of the year or not. |\n| isMonthEven | `boolean` | Describes whether the month of the actual date is even or not. |\n| isFirstDayOfMonth | `boolean` | Describes whether the actual date is the first day of the month or not. |\n| isLastDayOfMonth | `boolean` | Describes whether the actual date is the last day of the month or not. |\n| isToday | `boolean` | Describes whether the actual date is the same date as today or not. |\n| isWeekend | `boolean` | Describes whether the actual date is on weekend or not. |\n\n#### Prop Overrides\nYou can override each and every `slotProps` type. With this you can pass custom properties into each `slotProps` with a simple module augmentation.\nThis will allow you to have custom properties that is available both on `slotProps` definition and component prop as well.\n\nMost of the component props are available to override.\nLook for exported interfaces with the name of the component that you want to augment and `Overrides` suffix.\n\nDefine your custom types like the following:\n```tsx\ndeclare module '@knightburton/react-interval-calendar' {\n  interface ContainerPropsOverrides {\n    something?: boolean;\n  }\n}\n\n// In your component, you can define the value like the this\n\u003cIntervalCalendar\n  weekStartsOn={1}\n  start={new Date(2021, 1, 1)}\n  end={new Date(2021, 6, 31)}\n  slotProps={{ root: { something: true } }}\n/\u003e\n\n// Also, this will be available on component props as well\nconst Root = ({ children, something }: ContainerProps): JSX.Element =\u003e \u003c\u003e\u003c/\u003e;\n```\n\n### Migration Guides\n#### From v2 to v3\nThere are three breaking changes in v3, mainly prop changes.\n\n1.\n    There are no standalone props for internal components override anymore.\n    All the internal components are still replaceable through the `slots` prop.\n    In order to migrate the component overrides from v2, move your components inside the `slots` prop.\n    ```diff\n    \u003cIntervalCalendar\n      start={new Date(2021, 1, 1)}\n      end={new Date(2021, 6, 31)}\n    - containerComponent={MyContainer}\n    - headerContainerComponent={MyHeaderContainer}\n    - headerCellContentComponent={MyHeaderCellContent}\n    - bodyContainerComponent={MyBodyContainer}\n    - bodyCellContentComponent={MyBodyCellContent}\n    - emptyComponent={MyEmpty}\n    + slots={{\n    +   root: MyContainer,\n    +   header: MyHeaderContainer,\n    +   headerCellContent: MyHeaderCellContent,\n    +   body: MyBodyContainer,\n    +   bodyCellContent: MyBodyCellContent,\n    +   empty: MyEmpty;\n    + }}\n    /\u003e\n    ```\n    *Note that, there are a couple new components that can be replaced with any slots. Check the [Slots](#slots) prop definition.*\n\n2.\n    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.\n    ```diff\n    \u003cIntervalCalendar\n      start={new Date(2021, 1, 1)}\n      end={new Date(2021, 6, 31)}\n    - containerClassName=\"my-container\"\n    - headerContainerClassName=\"my-header-container\"\n    - headerRowClassName=\"my-header-row\"\n    - headerCellClassName=\"my-header-cell\"\n    - headerCellContentClassName=\"my-header-cell-content\"\n    - bodyContainerClassName=\"my-body-container\"\n    - bodyRowClassName=\"my-body-row\"\n    - bodyCellClassName=\"my-body-cell\"\n    - bodyCellContentClassName=\"my-body-cell-content\"\n    - emptyClassName=\"my-empty\"\n    + slotProps={{\n    +   root: { className: 'my-container' },\n    +   header: { className: 'my-header-row' },\n    +   headerCell: { className: 'my-header-cell' },\n    +   headerCellContent: { className: 'my-header-cell-content' },\n    +   body: { className: 'my-body-container' },\n    +   bodyRow: { className: 'my-body-row' },\n    +   bodyCell: { className: 'my-body-cell' },\n    +   bodyCellContent: { className: 'my-body-cell-content' },\n    +   empty: { className: 'my-empty' },\n    + }}\n    /\u003e\n    ```\n\n    *Note that, there is no `headerContainerClassName` anymore, because there is no header container component anymore. That component got merged with `header`.*\n\n3.\n    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`.\n    ```diff\n    \u003cIntervalCalendar\n      start={new Date(2021, 1, 1)}\n      end={new Date(2021, 6, 31)}\n    - emptyLabel=\"Meh...\"\n    - height={500}\n    - onCellClick={(data) =\u003e console.log(data)}\n    - showHeader={false}\n    + slotProps={{\n    +   root: { style: { height: 500 } },\n    +   header: { enabled: false },\n    +   bodyCell: { onClick: (event, data) =\u003e console.log(event, data) },\n    +   empty: { label: 'Meh...' },\n    + }}\n    /\u003e\n    ```\n    Where the `height` just part of the `style` prop alongside with all the other style attributes.\n\n    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](#body-cell-data).\n\n### Development\nFirst of all, you will need to use node v20, best way to start with [nvm](https://github.com/nvm-sh/nvm).\nLocal development is broken into two parts (ideally using two terminal tabs).\n\nFirst, run rollup to watch your `src/` module and automatically recompile it into `dist/` whenever you make changes.\n```bash\n# Assume that you are in the project main folder\n$ npm i\n$ npm start\n```\nThe second part will be running the `example/` create-react-app that's linked to the local version of your module.\n```bash\n# Assume that you are in the project main folder\n$ cd example\n$ npm i\n$ npm start\n```\n\n### Contributing\n\nFirst off all, thanks for taking the time to contribute! :muscle:\n\nBefore any action, please visit the [Code of Conduct](https://github.com/knightburton/react-interval-calendar/blob/main/CODE_OF_CONDUCT.md) and [Contributing guideline](https://github.com/knightburton/react-interval-calendar/blob/main/CONTRIBUTING.md) for more information.\n\n### License\n\nReact Interval Calendar is Open Source software under the MIT license. Complete license and copyright information can be found within the [license](https://github.com/knightburton/react-interval-calendar/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknightburton%2Freact-interval-calendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknightburton%2Freact-interval-calendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknightburton%2Freact-interval-calendar/lists"}