Skip to content

Commit 42df576

Browse files
authored
feat: Month component (#671)
* Add Month component (WIP) * Support start/end that do not align on year boundaries (ex. last 90 days) * Refactor Month component to remove unused rangeMonths and enhance month label generation * Update monthLabelHeight calculation to conditionally account for label visibility * Update Month component to use current date as end date instead of last day of year * cleanup examples * remove old Month docs * Remove `optimizeDeps.include` from vite.config.js (not needed anymore for "optimized dependencies changed. reloading" issues
1 parent 5ae89bb commit 42df576

53 files changed

Lines changed: 1115 additions & 61 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/plain-rings-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'layerchart': patch
3+
---
4+
5+
feat: Add Month component

docs/src/content/components/Calendar.md

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,9 @@
22
description: Marking component which highlights specific dates or time periods on a chart to emphasize events, milestones, or temporal patterns.
33
category: marks
44
layers: [svg, canvas, html]
5-
related: []
5+
related: [Month]
66
---
77

88
## Usage
99

1010
:example{ name="basic" showCode }
11-
12-
<!-- ## Examples
13-
14-
### Responsive cell size (default)
15-
16-
:example{ name="responsive-cell-size-default" showCode }
17-
18-
### Fixed cell size
19-
20-
:example{ name="fixed-cell-size" showCode }
21-
22-
### Multiple Years
23-
24-
:example{ name="multiple-years" showCode }
25-
26-
### Rounded cells
27-
28-
:example{ name="rounded-cells" showCode }
29-
30-
### Html with padding
31-
32-
:example{ name="html-with-padding" showCode }
33-
34-
### Last month
35-
36-
:example{ name="last-month" showCode }
37-
38-
### 90 days
39-
40-
:example{ name="90-days" showCode } -->
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
description: Month-based calendar grid visualization for displaying daily data across months with customizable cell sizes, labels, and tooltips.
3+
category: marks
4+
layers: [svg, canvas, html]
5+
related: [Calendar]
6+
---
7+
8+
## Usage
9+
10+
:example{ name="basic" showCode }

docs/src/examples/catalog/Chart.json

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2651,6 +2651,48 @@
26512651
"lineNumber": 32,
26522652
"line": "<Chart {data} x=\"x\" y=\"y\" height={200}>"
26532653
},
2654+
{
2655+
"example": "90-days",
2656+
"component": "Month",
2657+
"path": "/docs/components/Month/90-days",
2658+
"lineNumber": 22,
2659+
"line": "<Chart"
2660+
},
2661+
{
2662+
"example": "basic",
2663+
"component": "Month",
2664+
"path": "/docs/components/Month/basic",
2665+
"lineNumber": 24,
2666+
"line": "<Chart"
2667+
},
2668+
{
2669+
"example": "custom-cell-size",
2670+
"component": "Month",
2671+
"path": "/docs/components/Month/custom-cell-size",
2672+
"lineNumber": 24,
2673+
"line": "<Chart"
2674+
},
2675+
{
2676+
"example": "multiple-years",
2677+
"component": "Month",
2678+
"path": "/docs/components/Month/multiple-years",
2679+
"lineNumber": 22,
2680+
"line": "<Chart"
2681+
},
2682+
{
2683+
"example": "without-day-numbers",
2684+
"component": "Month",
2685+
"path": "/docs/components/Month/without-day-numbers",
2686+
"lineNumber": 23,
2687+
"line": "<Chart"
2688+
},
2689+
{
2690+
"example": "without-month-labels",
2691+
"component": "Month",
2692+
"path": "/docs/components/Month/without-month-labels",
2693+
"lineNumber": 23,
2694+
"line": "<Chart"
2695+
},
26542696
{
26552697
"example": "repeat-indefinitely",
26562698
"component": "MotionPath",
@@ -3933,5 +3975,5 @@
39333975
"line": "<Chart {data} x=\"x\" y=\"y\" height={400}>"
39343976
}
39353977
],
3936-
"updatedAt": "2026-04-01T13:16:17.567Z"
3978+
"updatedAt": "2026-04-01T16:49:30.210Z"
39373979
}

docs/src/examples/catalog/Layer.json

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2543,6 +2543,48 @@
25432543
"lineNumber": 33,
25442544
"line": "<Layer>"
25452545
},
2546+
{
2547+
"example": "90-days",
2548+
"component": "Month",
2549+
"path": "/docs/components/Month/90-days",
2550+
"lineNumber": 37,
2551+
"line": "<Layer>"
2552+
},
2553+
{
2554+
"example": "basic",
2555+
"component": "Month",
2556+
"path": "/docs/components/Month/basic",
2557+
"lineNumber": 39,
2558+
"line": "<Layer>"
2559+
},
2560+
{
2561+
"example": "custom-cell-size",
2562+
"component": "Month",
2563+
"path": "/docs/components/Month/custom-cell-size",
2564+
"lineNumber": 39,
2565+
"line": "<Layer>"
2566+
},
2567+
{
2568+
"example": "multiple-years",
2569+
"component": "Month",
2570+
"path": "/docs/components/Month/multiple-years",
2571+
"lineNumber": 37,
2572+
"line": "<Layer>"
2573+
},
2574+
{
2575+
"example": "without-day-numbers",
2576+
"component": "Month",
2577+
"path": "/docs/components/Month/without-day-numbers",
2578+
"lineNumber": 38,
2579+
"line": "<Layer>"
2580+
},
2581+
{
2582+
"example": "without-month-labels",
2583+
"component": "Month",
2584+
"path": "/docs/components/Month/without-month-labels",
2585+
"lineNumber": 38,
2586+
"line": "<Layer>"
2587+
},
25462588
{
25472589
"example": "repeat-indefinitely",
25482590
"component": "MotionPath",
@@ -3846,5 +3888,5 @@
38463888
"line": "<Layer onpointermove={onPointerMove}>"
38473889
}
38483890
],
3849-
"updatedAt": "2026-04-01T13:16:18.421Z"
3891+
"updatedAt": "2026-04-01T16:49:31.366Z"
38503892
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
{
2+
"component": "Month",
3+
"examples": [
4+
{
5+
"name": "90-days",
6+
"title": "90 days",
7+
"path": "/docs/components/Month/90-days",
8+
"components": [
9+
{
10+
"component": "Chart",
11+
"lineNumber": 22,
12+
"line": "<Chart"
13+
},
14+
{
15+
"component": "Layer",
16+
"lineNumber": 37,
17+
"line": "<Layer>"
18+
},
19+
{
20+
"component": "Month",
21+
"lineNumber": 38,
22+
"line": "<Month start={ninetyDaysAgo} end={now} tooltip />"
23+
},
24+
{
25+
"component": "Tooltip",
26+
"lineNumber": 41,
27+
"line": "<Tooltip.Root>"
28+
}
29+
]
30+
},
31+
{
32+
"name": "basic",
33+
"title": "basic",
34+
"path": "/docs/components/Month/basic",
35+
"components": [
36+
{
37+
"component": "Chart",
38+
"lineNumber": 24,
39+
"line": "<Chart"
40+
},
41+
{
42+
"component": "Layer",
43+
"lineNumber": 39,
44+
"line": "<Layer>"
45+
},
46+
{
47+
"component": "Month",
48+
"lineNumber": 40,
49+
"line": "<Month start={firstDayOfYear} end={lastDayOfYear} tooltip />"
50+
},
51+
{
52+
"component": "Tooltip",
53+
"lineNumber": 43,
54+
"line": "<Tooltip.Root>"
55+
}
56+
]
57+
},
58+
{
59+
"name": "custom-cell-size",
60+
"title": "custom cell size",
61+
"path": "/docs/components/Month/custom-cell-size",
62+
"components": [
63+
{
64+
"component": "Chart",
65+
"lineNumber": 24,
66+
"line": "<Chart"
67+
},
68+
{
69+
"component": "Layer",
70+
"lineNumber": 39,
71+
"line": "<Layer>"
72+
},
73+
{
74+
"component": "Month",
75+
"lineNumber": 40,
76+
"line": "<Month start={firstDayOfYear} end={lastDayOfYear} cellSize={20} tooltip />"
77+
},
78+
{
79+
"component": "Tooltip",
80+
"lineNumber": 43,
81+
"line": "<Tooltip.Root>"
82+
}
83+
]
84+
},
85+
{
86+
"name": "multiple-years",
87+
"title": "multiple years",
88+
"path": "/docs/components/Month/multiple-years",
89+
"components": [
90+
{
91+
"component": "Chart",
92+
"lineNumber": 22,
93+
"line": "<Chart"
94+
},
95+
{
96+
"component": "Layer",
97+
"lineNumber": 37,
98+
"line": "<Layer>"
99+
},
100+
{
101+
"component": "Month",
102+
"lineNumber": 38,
103+
"line": "<Month start={threeYearsAgo} end={now} tooltip />"
104+
},
105+
{
106+
"component": "Tooltip",
107+
"lineNumber": 41,
108+
"line": "<Tooltip.Root>"
109+
}
110+
]
111+
},
112+
{
113+
"name": "without-day-numbers",
114+
"title": "without day numbers",
115+
"path": "/docs/components/Month/without-day-numbers",
116+
"components": [
117+
{
118+
"component": "Chart",
119+
"lineNumber": 23,
120+
"line": "<Chart"
121+
},
122+
{
123+
"component": "Layer",
124+
"lineNumber": 38,
125+
"line": "<Layer>"
126+
},
127+
{
128+
"component": "Month",
129+
"lineNumber": 39,
130+
"line": "<Month start={firstDayOfYear} end={now} showDayNumber={false} tooltip />"
131+
},
132+
{
133+
"component": "Tooltip",
134+
"lineNumber": 42,
135+
"line": "<Tooltip.Root>"
136+
}
137+
]
138+
},
139+
{
140+
"name": "without-month-labels",
141+
"title": "without month labels",
142+
"path": "/docs/components/Month/without-month-labels",
143+
"components": [
144+
{
145+
"component": "Chart",
146+
"lineNumber": 23,
147+
"line": "<Chart"
148+
},
149+
{
150+
"component": "Layer",
151+
"lineNumber": 38,
152+
"line": "<Layer>"
153+
},
154+
{
155+
"component": "Month",
156+
"lineNumber": 39,
157+
"line": "<Month start={firstDayOfYear} end={now} showDayNumber={false} monthLabel={false} tooltip />"
158+
},
159+
{
160+
"component": "Tooltip",
161+
"lineNumber": 42,
162+
"line": "<Tooltip.Root>"
163+
}
164+
]
165+
}
166+
],
167+
"usage": [
168+
{
169+
"example": "90-days",
170+
"component": "Month",
171+
"path": "/docs/components/Month/90-days",
172+
"lineNumber": 38,
173+
"line": "<Month start={ninetyDaysAgo} end={now} tooltip />"
174+
},
175+
{
176+
"example": "basic",
177+
"component": "Month",
178+
"path": "/docs/components/Month/basic",
179+
"lineNumber": 40,
180+
"line": "<Month start={firstDayOfYear} end={lastDayOfYear} tooltip />"
181+
},
182+
{
183+
"example": "custom-cell-size",
184+
"component": "Month",
185+
"path": "/docs/components/Month/custom-cell-size",
186+
"lineNumber": 40,
187+
"line": "<Month start={firstDayOfYear} end={lastDayOfYear} cellSize={20} tooltip />"
188+
},
189+
{
190+
"example": "multiple-years",
191+
"component": "Month",
192+
"path": "/docs/components/Month/multiple-years",
193+
"lineNumber": 38,
194+
"line": "<Month start={threeYearsAgo} end={now} tooltip />"
195+
},
196+
{
197+
"example": "without-day-numbers",
198+
"component": "Month",
199+
"path": "/docs/components/Month/without-day-numbers",
200+
"lineNumber": 39,
201+
"line": "<Month start={firstDayOfYear} end={now} showDayNumber={false} tooltip />"
202+
},
203+
{
204+
"example": "without-month-labels",
205+
"component": "Month",
206+
"path": "/docs/components/Month/without-month-labels",
207+
"lineNumber": 39,
208+
"line": "<Month start={firstDayOfYear} end={now} showDayNumber={false} monthLabel={false} tooltip />"
209+
}
210+
],
211+
"updatedAt": "2026-04-01T16:49:31.660Z"
212+
}

0 commit comments

Comments
 (0)