https://github.com/patrick-kw-chiu/activity-calendar-widget
A GitHub Activity Calendar built on Mitosis, which generates React, Vue, Svelte, and other components
https://github.com/patrick-kw-chiu/activity-calendar-widget
github-calendar javascript mitosis react reactjs svelte vue vuejs
Last synced: about 2 months ago
JSON representation
A GitHub Activity Calendar built on Mitosis, which generates React, Vue, Svelte, and other components
- Host: GitHub
- URL: https://github.com/patrick-kw-chiu/activity-calendar-widget
- Owner: patrick-kw-chiu
- License: mit
- Created: 2023-04-07T05:40:32.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-17T15:25:58.000Z (5 months ago)
- Last Synced: 2025-04-13T07:49:05.145Z (about 2 months ago)
- Topics: github-calendar, javascript, mitosis, react, reactjs, svelte, vue, vuejs
- Language: TypeScript
- Homepage: https://betterprogramming.pub/write-components-once-compile-to-every-framework-with-mitosis-9330411d21e4
- Size: 1.41 MB
- Stars: 21
- Watchers: 1
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Activity Calendar Widget
Interactive code demo (React)
[Stackblitz link](https://stackblitz.com/edit/vitejs-vite-aa5ew9?embed=1&file=README.md&view=preview)
https://github.com/user-attachments/assets/36ac25aa-dd02-44c5-9ef2-b8031f7558fa
A "GitHub Contribution/Activity" like calendar widget, that can be used as native components of [React](https://stackblitz.com/edit/react-ts-pjkx7k), [Vue](https://stackblitz.com/edit/vitejs-vite-zwsqz2?file=src), [Svelte](https://stackblitz.com/edit/vitejs-vite-r7rxjt?terminal=dev), [Solid](https://stackblitz.com/edit/solidjs-templates-mjote1) and [Qwik](https://stackblitz.com/edit/qwik-starter-due4dq). You can used it with the [GitHub activity API](https://docs.github.com/en/rest/activity/events?apiVersion=2022-11-28#list-public-events-for-a-user) or to display any activity data.
![]()
![]()
## About
**Activity Calendar Widget** is built with [Mitosis](https://github.com/BuilderIO/mitosis) (with a little modifications), which aims to "Write components once, compile to every framework". Interested to learn more? Here is a [walkthrough of building a "simplied" Activity Calendar Widget](https://medium.com/@patrick-kw-chiu/write-components-once-compile-to-every-framework-with-mitosis-9330411d21e4).
_Credits: The API of **Activity Calendar Widget** is highly influenced by [React Activity Calendar](https://github.com/grubersjoe/react-activity-calendar). React Activity Calendar is a great component library, which provides more granular options in certain areas._
## Installation
`npm i activity-calendar-widget`
It can then be imported in various frameworks like...
```javascript
// React
import ActivityCalendarWidget from 'activity-calendar-widget/react';// Vue
import ActivityCalendarWidget from 'activity-calendar-widget/vue';// Svelte
import ActivityCalendarWidget from 'activity-calendar-widget/svelte';// Solid
import ActivityCalendarWidget from 'activity-calendar-widget/solid';// Qwik
import ActivityCalendarWidget from 'activity-calendar-widget/qwik';
```### Basic Usage
```
```
## API
### Props
| Props name | Type | Default | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | array of [`Data`](https://github.com/patrick-kw-chiu/activity-calendar-widget/edit/main/README.md#data) | [] | The activity `data` array. It accepts the `date` and `activities` fields. |
| clickHandler | Function
`(dateInfo: `[`DateInfo`](https://github.com/patrick-kw-chiu/activity-calendar-widget/edit/main/README.md#dateinfo)`) => {}` | undefined | The activity `data` array. It accepts the `date` and `activities` fields. |
| daysToRender | number | 365 (+ 0 to 6 days more). See more the description | When `daysToRender` isn't specified, at least 365 days from today will be rendered, while the leftmost (oldest) column will also be filled up entirely.
When `daysToRender` is specified, `activity-calendar-widget` will render the exact number of `daysToRender` from today. |
| mode | string | `'day'` | Options: `'day'` / `'week'` / `'month'`.
**Note: Only `day` is supported currently.** See roadmap for more info. |
| showSummary | boolean | true | If set to `true`, a summary of "26 activities in this period" will be displayed in the bottom left of the component. |
| summaryText | string | `'{{count}} activities in this period'` | The customized summary text with placeholder `{{count}}` |
| showLevels | boolean | true | If set to `true`, a level legend will be displayed in the bottom right of the component. |
| levelColorMode | string | `'light'` | Options: `'light'` / `'dark'`. It changes the color palette of the level legend, like the screenshots at the top.
If `levelColorMode` is used together with `levelColors`, `levelColorMode` will be ignored and **ONLY** `levelColor` will be used. |
| levelColors | array of string | `undefined` | If `levelColors` is used together with `levelColorMode`, `levelColorMode` will be ignored and **ONLY** `levelColor` will be used. E.g. `['white', 'rgba(0, 0, 0, 0.2'), '#a6a6a6']` |
| levelLabelLess | string | `'Less'` | The "Less" label of the level legend |
| levelLabelMore | string | `'More'` | The "More" label of the level legend |
| showTooltip | boolean | true | If set to `true`, when users hover the date box, a tooltip of "2 activities on Apr 11, 2023" will be displayed. |
| tooltipBgColor | string | `'rgba(0, 0, 0, 0.8)'` | The tooltip background color |
| tooltipTextColor | string | `'#e4e8ec'` | The tooltip text color |
| weekStart | number | 0 | Options: `0` / `1` / `2` / `3` / `4` / `5` / `6`
The week start with:
`0`: Sun
`1`: Mon
`2`: Tue
`3`: Wed
`4`: Thu
`5`: Fri
`6`: Sat |
| showWeekdayLabels | boolean | true | If set to `true`, the left weekday labels will be displayed. |
| weekdayLabel | [`WeekdayLabel`](https://github.com/patrick-kw-chiu/activity-calendar-widget/edit/main/README.md#weekdaylabel) | {} | By default, the widget only displays `Mon`, `Wed` and `Fri`. If the allowed keys in `weekdayLabel` is provided e.g. `{ 0: '日曜日' }`, the week value will be overwritten.
**Note**: To provide custom value for **Sunday**, provide value to **`0`** e.g. `{ 0: '日曜日' }`. |
| showMonthLabels | boolean | true | If set to `true`, the top month labels will be displayed. |
| monthLabel | [`MonthLabel`](https://github.com/patrick-kw-chiu/activity-calendar-widget/edit/main/README.md#monthlabel) | {} | By default, all months will be displayed. If the allowed keys in `monthLabel` is provided e.g. `{ 1: '1월' }`, the month value will be overwritten. |## Event Handlers
### clickHandler(dateInfo: DateInfo)
#### DateInfo
| Fields | Type | Format | Description |
| ---------------- | -------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id | string | `yyyy-MM-dd` | The date being clicked |
| year | number | `yyyy` | The year of the date box being clicked |
| month | number | `MM` | The month of the date box being clicked |
| day | number | `dd` | The day of the date box being clicked |
| dayOfWeek | number | `0-6` | The day of week of the date box being clicked
`0`: Sun
`1`: Mon
`2`: Tue
`3`: Wed
`4`: Thu
`5`: Fri
`6`: Sat |
| dayDiffFromToday | number | `>= 0` | Numebrs of days from today |
| activities | array of `any` | `[]` | Each item inside the `activities` array will count as 1 activity. The format is arbitary here. You can pass `{ "type": "PushEvent" }` or `'PullRequestEvent'` or **anything**. |
| level | number | `>= 0` | If no custom `levelColors` is passed, level will be `0-4`. `0` means no activities and `4` means the tier of having the most activities.
If custom `levelColors` is passed, level will be `0` to `length of levelColors - 1`. |#### Usage
```JSX
console.log({ dateInfo })}
/>
```#### DateInfo Example
```json
{
"id": "2023-04-16",
"year": 2023,
"month": 4,
"day": 16,
"dayOfWeek": 0,
"dayDiffFromToday": 0,
"activities": [
...
],
"level": 2
}
```## Types
### Data
| Field | Type | Format | Description |
| ---------- | -------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| date | string | `yyyy-MM-dd` | The date which contains 0 or more activities.
E.g. `'2023-04-05'` |
| activities | array of `any` | `[]` | Each item inside the `activities` array will count as 1 activity. The format is arbitary here. You can pass `{ "type": "PushEvent" }` or `'PullRequestEvent'` or **anything**.
If you pass a `clickHandler` and you clicked the date box, the `clickHandler` callback will be executed with the `activities`. |#### Example
```
[
{ date: '2023-04-05', activities: [{}, {}, {}, {}] },
{ date: '2023-04-07', activities: [{}] },
{ date: '2023-04-08', activities: [{}, {}, {}] }
]
```### WeekdayLabel
```typescript
type WeekdayKey = 0 | 1 | 2 | 3 | 4 | 5 | 6;
export type WeekdayLabel = Record;
```#### Example:
```
{
0: '日曜日',
1: '月曜日',
2: '火曜日',
3: '水曜日',
4: '木曜日',
5: '金曜日',
6: '土曜日',
}
```### MonthLabel
```typescript
type MonthKey = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
export type MonthLabel = Record;
```#### Example:
```
{
1: '1월',
2: '2월',
3: '3월',
// ...
10: '10월',
11: '11월',
12: '12월',
}
```## Roadmap
- Support `mode={'month'}`

- Support `mode={'week'}`
## Development
0. (One off) Install dependencies of the Mitosis component and the test app
```
npm installcd test-app
npm install
```1. In the root directory, watch and re-build changes in `/src`.
```
npm run start
```2. In another terminal, run the test-app (an Astro app that have `react`, `solid`, `svelte` and `vue` baked in)
```
cd test-app
npm run start
```