@pearpages/heatmap 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.css CHANGED
@@ -1,5 +1,7 @@
1
1
  /* src/ContributionHeatmap/index.scss */
2
2
  .contribution-heatmap {
3
+ color: var(--color-text-muted);
4
+ font-size: 8px;
3
5
  --day-size: 12px;
4
6
  --day-gap: 2px;
5
7
  --border-radius: 6px;
@@ -38,8 +40,23 @@
38
40
  max-width: 100%;
39
41
  overflow-x: auto;
40
42
  }
43
+ .contribution-heatmap__table {
44
+ table-layout: fixed;
45
+ width: 100%;
46
+ border-collapse: separate;
47
+ border-spacing: var(--day-gap);
48
+ }
41
49
  .contribution-heatmap__month-header {
42
- color: var(--color-text-muted);
50
+ font-weight: 500;
51
+ text-align: left;
52
+ padding: 0;
53
+ border: none;
54
+ background: none;
55
+ }
56
+ .contribution-heatmap__day-header {
57
+ padding: 0;
58
+ border: none;
59
+ background: none;
43
60
  }
44
61
  .contribution-heatmap:hover {
45
62
  box-shadow: 0 4px 16px var(--shadow-color);
@@ -70,139 +87,6 @@
70
87
  margin-bottom: 12px;
71
88
  }
72
89
  }
73
- .contribution-heatmap__title {
74
- color: var(--color-text);
75
- font-size: 18px;
76
- font-weight: 600;
77
- margin: 0 0 4px 0;
78
- letter-spacing: -0.2px;
79
- }
80
- @media (max-width: 768px) {
81
- .contribution-heatmap__title {
82
- font-size: 16px;
83
- }
84
- }
85
- .contribution-heatmap__subtitle {
86
- color: var(--color-text-muted);
87
- font-size: 14px;
88
- margin: 0;
89
- font-weight: 400;
90
- }
91
- @media (max-width: 768px) {
92
- .contribution-heatmap__subtitle {
93
- font-size: 12px;
94
- }
95
- }
96
- .contribution-heatmap__container {
97
- display: grid;
98
- gap: 8px;
99
- padding: 16px;
100
- background: var(--color-bg);
101
- border-radius: calc(var(--border-radius) - 2px);
102
- position: relative;
103
- grid-template-areas: ". months" "days grid";
104
- grid-template-columns: 30px 1fr;
105
- grid-template-rows: auto 1fr;
106
- }
107
- @media (max-width: 768px) {
108
- .contribution-heatmap__container {
109
- padding: 8px;
110
- gap: 6px;
111
- grid-template-columns: 20px 1fr;
112
- }
113
- }
114
- .contribution-heatmap__months {
115
- grid-area: months;
116
- display: flex;
117
- gap: var(--day-gap);
118
- margin-bottom: 4px;
119
- }
120
- @media (max-width: 768px) {
121
- .contribution-heatmap__months {
122
- margin-bottom: 2px;
123
- }
124
- }
125
- .contribution-heatmap__month {
126
- color: var(--color-text-muted);
127
- font-size: 12px;
128
- font-weight: 500;
129
- text-align: left;
130
- padding: 0 2px;
131
- flex-grow: 0;
132
- flex-shrink: 0;
133
- }
134
- @media (max-width: 768px) {
135
- .contribution-heatmap__month {
136
- font-size: 10px;
137
- }
138
- }
139
- @media (max-width: 480px) {
140
- .contribution-heatmap__month {
141
- font-size: 8px;
142
- }
143
- }
144
- .contribution-heatmap__days {
145
- grid-area: days;
146
- display: flex;
147
- flex-direction: column;
148
- gap: var(--day-gap);
149
- align-items: flex-end;
150
- justify-content: flex-start;
151
- padding-right: 4px;
152
- }
153
- @media (max-width: 768px) {
154
- .contribution-heatmap__days {
155
- padding-right: 2px;
156
- }
157
- }
158
- .contribution-heatmap__day-label {
159
- color: var(--color-text-muted);
160
- font-size: 10px;
161
- font-weight: 500;
162
- height: var(--day-size);
163
- display: flex;
164
- align-items: center;
165
- width: 24px;
166
- }
167
- @media (max-width: 768px) {
168
- .contribution-heatmap__day-label {
169
- font-size: 8px;
170
- width: 16px;
171
- }
172
- }
173
- @media (max-width: 480px) {
174
- .contribution-heatmap__day-label {
175
- font-size: 7px;
176
- width: 12px;
177
- }
178
- }
179
- .contribution-heatmap__grid {
180
- grid-area: grid;
181
- display: flex;
182
- gap: var(--day-gap);
183
- overflow-x: auto;
184
- scroll-behavior: smooth;
185
- }
186
- .contribution-heatmap__grid::-webkit-scrollbar {
187
- height: 4px;
188
- }
189
- .contribution-heatmap__grid::-webkit-scrollbar-track {
190
- background: var(--color-border);
191
- border-radius: 2px;
192
- }
193
- .contribution-heatmap__grid::-webkit-scrollbar-thumb {
194
- background: var(--color-level-2);
195
- border-radius: 2px;
196
- }
197
- .contribution-heatmap__grid::-webkit-scrollbar-thumb:hover {
198
- background: var(--color-level-3);
199
- }
200
- .contribution-heatmap__week {
201
- display: flex;
202
- flex-direction: column;
203
- gap: var(--day-gap);
204
- min-width: var(--day-size);
205
- }
206
90
  .contribution-heatmap__day {
207
91
  width: var(--day-size);
208
92
  height: var(--day-size);
@@ -211,6 +95,10 @@
211
95
  transition: var(--transition);
212
96
  position: relative;
213
97
  border: 1px solid transparent;
98
+ padding: 0;
99
+ box-sizing: border-box;
100
+ min-width: var(--day-size);
101
+ max-width: var(--day-size);
214
102
  }
215
103
  .contribution-heatmap__day--level-0 {
216
104
  background-color: var(--color-level-0);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.scss","../src/index.scss","../src/controlGroups.scss"],"sourcesContent":["// ContributionHeatmap.scss\n// GitHub-style contribution heatmap with BEM methodology\n\n.contribution-heatmap {\n // Component variables\n --day-size: 12px;\n --day-gap: 2px;\n --border-radius: 6px;\n --transition: all 0.2s ease;\n --shadow-color: rgba(0, 0, 0, 0.1);\n \n // Color scheme - GitHub-inspired\n --color-bg: #ffffff;\n --color-border: #e1e4e8;\n --color-text: #24292f;\n --color-text-muted: #656d76;\n --color-level-0: #ebedf0;\n --color-level-1: #9be9a8;\n --color-level-2: #40c463;\n --color-level-3: #30a14e;\n --color-level-4: #216e39;\n \n // Dark mode support\n @media (prefers-color-scheme: dark) {\n --color-bg: #0d1117;\n --color-border: #30363d;\n --color-text: #f0f6fc;\n --color-text-muted: #8b949e;\n --color-level-0: #161b22;\n --color-level-1: #0e4429;\n --color-level-2: #006d32;\n --color-level-3: #26a641;\n --color-level-4: #39d353;\n }\n \n background: var(--color-bg);\n border-radius: var(--border-radius);\n padding: 20px;\n box-shadow: 0 2px 8px var(--shadow-color);\n border: 1px solid var(--color-border);\n transition: var(--transition);\n max-width: 100%;\n overflow-x: auto;\n\n &__month-header {\n color: var(--color-text-muted);\n }\n\n // Hover effect for the entire component\n &:hover {\n box-shadow: 0 4px 16px var(--shadow-color);\n }\n\n // Mobile responsiveness\n @media (max-width: 768px) {\n --day-size: 10px;\n --day-gap: 1px;\n padding: 15px;\n \n // Reduce padding on mobile\n &__container {\n padding: 0;\n }\n }\n\n @media (max-width: 480px) {\n --day-size: 8px;\n --day-gap: 1px;\n padding: 10px;\n }\n\n // Header section\n &__header {\n margin-bottom: 16px;\n text-align: center;\n \n @media (max-width: 768px) {\n margin-bottom: 12px;\n }\n }\n\n &__title {\n color: var(--color-text);\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 4px 0;\n letter-spacing: -0.2px;\n \n @media (max-width: 768px) {\n font-size: 16px;\n }\n }\n\n &__subtitle {\n color: var(--color-text-muted);\n font-size: 14px;\n margin: 0;\n font-weight: 400;\n \n @media (max-width: 768px) {\n font-size: 12px;\n }\n }\n\n // Main container\n &__container {\n display: grid;\n gap: 8px;\n padding: 16px;\n background: var(--color-bg);\n border-radius: calc(var(--border-radius) - 2px);\n position: relative;\n grid-template-areas: \n \". months\"\n \"days grid\";\n grid-template-columns: 30px 1fr;\n grid-template-rows: auto 1fr;\n \n @media (max-width: 768px) {\n padding: 8px;\n gap: 6px;\n grid-template-columns: 20px 1fr;\n }\n }\n\n // Month labels\n &__months {\n grid-area: months;\n display: flex;\n gap: var(--day-gap);\n margin-bottom: 4px;\n \n @media (max-width: 768px) {\n margin-bottom: 2px;\n }\n }\n\n &__month {\n color: var(--color-text-muted);\n font-size: 12px;\n font-weight: 500;\n text-align: left;\n padding: 0 2px;\n flex-grow: 0;\n flex-shrink: 0;\n \n @media (max-width: 768px) {\n font-size: 10px;\n }\n \n @media (max-width: 480px) {\n font-size: 8px;\n }\n }\n\n // Day labels (Mon, Tue, etc.)\n &__days {\n grid-area: days;\n display: flex;\n flex-direction: column;\n gap: var(--day-gap);\n align-items: flex-end;\n justify-content: flex-start;\n padding-right: 4px;\n \n @media (max-width: 768px) {\n padding-right: 2px;\n }\n }\n\n &__day-label {\n color: var(--color-text-muted);\n font-size: 10px;\n font-weight: 500;\n height: var(--day-size);\n display: flex;\n align-items: center;\n width: 24px;\n \n @media (max-width: 768px) {\n font-size: 8px;\n width: 16px;\n }\n \n @media (max-width: 480px) {\n font-size: 7px;\n width: 12px;\n }\n }\n\n // Main grid\n &__grid {\n grid-area: grid;\n display: flex;\n gap: var(--day-gap);\n overflow-x: auto;\n scroll-behavior: smooth;\n \n // Custom scrollbar\n &::-webkit-scrollbar {\n height: 4px;\n }\n \n &::-webkit-scrollbar-track {\n background: var(--color-border);\n border-radius: 2px;\n }\n \n &::-webkit-scrollbar-thumb {\n background: var(--color-level-2);\n border-radius: 2px;\n \n &:hover {\n background: var(--color-level-3);\n }\n }\n }\n\n // Week column\n &__week {\n display: flex;\n flex-direction: column;\n gap: var(--day-gap);\n min-width: var(--day-size);\n }\n\n // Individual day square\n &__day {\n width: var(--day-size);\n height: var(--day-size);\n border-radius: 2px;\n cursor: pointer;\n transition: var(--transition);\n position: relative;\n border: 1px solid transparent;\n \n // Contribution levels\n &--level-0 {\n background-color: var(--color-level-0);\n \n &:hover {\n background-color: var(--color-level-1);\n border-color: var(--color-level-2);\n }\n }\n \n &--level-1 {\n background-color: var(--color-level-1);\n \n &:hover {\n background-color: var(--color-level-2);\n border-color: var(--color-level-3);\n }\n }\n \n &--level-2 {\n background-color: var(--color-level-2);\n \n &:hover {\n background-color: var(--color-level-3);\n border-color: var(--color-level-4);\n }\n }\n \n &--level-3 {\n background-color: var(--color-level-3);\n \n &:hover {\n background-color: var(--color-level-4);\n border-color: var(--color-level-4);\n }\n }\n \n &--level-4 {\n background-color: var(--color-level-4);\n \n &:hover {\n filter: brightness(1.1);\n border-color: var(--color-level-4);\n }\n }\n \n // Hover effects\n &:hover {\n transform: scale(1.2);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n z-index: 10;\n border-radius: 3px;\n }\n \n // Focus styles for accessibility\n &:focus-visible {\n outline: 2px solid var(--color-level-3);\n outline-offset: 2px;\n }\n }\n\n // Legend\n &__legend {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n margin-top: 12px;\n flex-wrap: wrap;\n \n @media (max-width: 768px) {\n gap: 3px;\n margin-top: 8px;\n }\n }\n\n &__legend-text {\n color: var(--color-text-muted);\n font-size: 12px;\n font-weight: 500;\n margin: 0 4px;\n \n @media (max-width: 768px) {\n font-size: 10px;\n margin: 0 2px;\n }\n }\n\n &__legend-item {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n cursor: help;\n transition: var(--transition);\n border: 1px solid var(--color-border);\n \n @media (max-width: 768px) {\n width: 10px;\n height: 10px;\n }\n \n &:hover {\n transform: scale(1.2);\n border-color: var(--color-text-muted);\n }\n \n &--level-0 { background-color: var(--color-level-0); }\n &--level-1 { background-color: var(--color-level-1); }\n &--level-2 { background-color: var(--color-level-2); }\n &--level-3 { background-color: var(--color-level-3); }\n &--level-4 { background-color: var(--color-level-4); }\n }\n}\n\n// Animation for initial load\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.contribution-heatmap {\n animation: fadeInUp 0.6s ease-out;\n \n &__day {\n animation: fadeInUp 0.3s ease-out;\n animation-delay: var(--animation-delay, 0s);\n animation-fill-mode: both;\n }\n}\n\n// Utilities for different themes\n.contribution-heatmap {\n // Ocean theme\n &--ocean {\n --color-level-0: #e6f3ff;\n --color-level-1: #b3daff;\n --color-level-2: #66b3ff;\n --color-level-3: #1a8cff;\n --color-level-4: #0066cc;\n }\n \n // Sunset theme\n &--sunset {\n --color-level-0: #fff2e6;\n --color-level-1: #ffcc99;\n --color-level-2: #ff9933;\n --color-level-3: #ff6600;\n --color-level-4: #cc3300;\n }\n \n // Purple theme\n &--purple {\n --color-level-0: #f3e6ff;\n --color-level-1: #d9b3ff;\n --color-level-2: #b366ff;\n --color-level-3: #8a1aff;\n --color-level-4: #6600cc;\n }\n}\n",".example {\n &__controls {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n padding: 24px;\n border-radius: 16px;\n margin-bottom: 30px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);\n border: 1px solid rgba(255, 255, 255, 0.2);\n\n @media (max-width: 768px) {\n padding: 20px;\n margin-bottom: 20px;\n border-radius: 12px;\n }\n }\n\n &__heatmap {\n margin-bottom: 40px;\n\n @media (max-width: 768px) {\n margin-bottom: 30px;\n }\n }\n}\n","// Control groups\n.control-group {\n margin-bottom: 24px;\n\n &:last-child {\n margin-bottom: 0;\n }\n\n &__label {\n display: block;\n font-weight: 600;\n color: #333;\n margin-bottom: 12px;\n font-size: 1rem;\n\n @media (max-width: 768px) {\n font-size: 0.9rem;\n margin-bottom: 10px;\n }\n }\n\n &__buttons {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n gap: 8px;\n }\n }\n\n &__checkbox {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 1rem;\n color: #555;\n margin: 0;\n\n @media (max-width: 768px) {\n font-size: 0.9rem;\n }\n\n input[type='checkbox'] {\n width: 18px;\n height: 18px;\n accent-color: #667eea;\n cursor: pointer;\n\n @media (max-width: 768px) {\n width: 16px;\n height: 16px;\n }\n }\n\n &:hover {\n color: #333;\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.scss","../src/index.scss","../src/controlGroups.scss"],"sourcesContent":["// ContributionHeatmap.scss\n// GitHub-style contribution heatmap with BEM methodology\n\n.contribution-heatmap {\n color: var(--color-text-muted);\n font-size: 8px;\n // Component variables\n --day-size: 12px;\n --day-gap: 2px;\n --border-radius: 6px;\n --transition: all 0.2s ease;\n --shadow-color: rgba(0, 0, 0, 0.1);\n\n // Color scheme - GitHub-inspired\n --color-bg: #ffffff;\n --color-border: #e1e4e8;\n --color-text: #24292f;\n --color-text-muted: #656d76;\n --color-level-0: #ebedf0;\n --color-level-1: #9be9a8;\n --color-level-2: #40c463;\n --color-level-3: #30a14e;\n --color-level-4: #216e39;\n\n // Dark mode support\n @media (prefers-color-scheme: dark) {\n --color-bg: #0d1117;\n --color-border: #30363d;\n --color-text: #f0f6fc;\n --color-text-muted: #8b949e;\n --color-level-0: #161b22;\n --color-level-1: #0e4429;\n --color-level-2: #006d32;\n --color-level-3: #26a641;\n --color-level-4: #39d353;\n }\n\n background: var(--color-bg);\n border-radius: var(--border-radius);\n padding: 20px;\n box-shadow: 0 2px 8px var(--shadow-color);\n border: 1px solid var(--color-border);\n transition: var(--transition);\n max-width: 100%;\n overflow-x: auto;\n\n // Table-specific styles\n &__table {\n table-layout: fixed;\n width: 100%;\n border-collapse: separate;\n border-spacing: var(--day-gap);\n }\n\n &__month-header {\n font-weight: 500;\n text-align: left;\n padding: 0;\n border: none;\n background: none;\n }\n\n &__day-header {\n padding: 0;\n border: none;\n background: none;\n }\n\n // Hover effect for the entire component\n &:hover {\n box-shadow: 0 4px 16px var(--shadow-color);\n }\n\n // Mobile responsiveness\n @media (max-width: 768px) {\n \n --day-size: 10px;\n --day-gap: 1px;\n padding: 15px;\n\n // Reduce padding on mobile\n &__container {\n padding: 0;\n }\n }\n\n @media (max-width: 480px) {\n \n --day-size: 8px;\n --day-gap: 1px;\n padding: 10px;\n }\n\n // Header section\n &__header {\n margin-bottom: 16px;\n text-align: center;\n\n @media (max-width: 768px) {\n margin-bottom: 12px;\n }\n }\n\n // Individual day square\n &__day {\n width: var(--day-size);\n height: var(--day-size);\n border-radius: 2px;\n cursor: pointer;\n transition: var(--transition);\n position: relative;\n border: 1px solid transparent;\n padding: 0;\n box-sizing: border-box;\n\n // Ensure consistent sizing in table\n min-width: var(--day-size);\n max-width: var(--day-size);\n\n // Contribution levels\n &--level-0 {\n background-color: var(--color-level-0);\n\n &:hover {\n background-color: var(--color-level-1);\n border-color: var(--color-level-2);\n }\n }\n\n &--level-1 {\n background-color: var(--color-level-1);\n\n &:hover {\n background-color: var(--color-level-2);\n border-color: var(--color-level-3);\n }\n }\n\n &--level-2 {\n background-color: var(--color-level-2);\n\n &:hover {\n background-color: var(--color-level-3);\n border-color: var(--color-level-4);\n }\n }\n\n &--level-3 {\n background-color: var(--color-level-3);\n\n &:hover {\n background-color: var(--color-level-4);\n border-color: var(--color-level-4);\n }\n }\n\n &--level-4 {\n background-color: var(--color-level-4);\n\n &:hover {\n filter: brightness(1.1);\n border-color: var(--color-level-4);\n }\n }\n\n // Hover effects\n &:hover {\n transform: scale(1.2);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n z-index: 10;\n border-radius: 3px;\n }\n\n // Focus styles for accessibility\n &:focus-visible {\n outline: 2px solid var(--color-level-3);\n outline-offset: 2px;\n }\n }\n\n // Legend\n &__legend {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n margin-top: 12px;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n gap: 3px;\n margin-top: 8px;\n }\n }\n\n &__legend-text {\n color: var(--color-text-muted);\n font-size: 12px;\n font-weight: 500;\n margin: 0 4px;\n\n @media (max-width: 768px) {\n font-size: 10px;\n margin: 0 2px;\n }\n }\n\n &__legend-item {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n cursor: help;\n transition: var(--transition);\n border: 1px solid var(--color-border);\n\n @media (max-width: 768px) {\n width: 10px;\n height: 10px;\n }\n\n &:hover {\n transform: scale(1.2);\n border-color: var(--color-text-muted);\n }\n\n &--level-0 {\n background-color: var(--color-level-0);\n }\n &--level-1 {\n background-color: var(--color-level-1);\n }\n &--level-2 {\n background-color: var(--color-level-2);\n }\n &--level-3 {\n background-color: var(--color-level-3);\n }\n &--level-4 {\n background-color: var(--color-level-4);\n }\n }\n}\n\n// Animation for initial load\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.contribution-heatmap {\n animation: fadeInUp 0.6s ease-out;\n\n &__day {\n animation: fadeInUp 0.3s ease-out;\n animation-delay: var(--animation-delay, 0s);\n animation-fill-mode: both;\n }\n}\n\n// Utilities for different themes\n.contribution-heatmap {\n // Ocean theme\n &--ocean {\n --color-level-0: #e6f3ff;\n --color-level-1: #b3daff;\n --color-level-2: #66b3ff;\n --color-level-3: #1a8cff;\n --color-level-4: #0066cc;\n }\n\n // Sunset theme\n &--sunset {\n --color-level-0: #fff2e6;\n --color-level-1: #ffcc99;\n --color-level-2: #ff9933;\n --color-level-3: #ff6600;\n --color-level-4: #cc3300;\n }\n\n // Purple theme\n &--purple {\n --color-level-0: #f3e6ff;\n --color-level-1: #d9b3ff;\n --color-level-2: #b366ff;\n --color-level-3: #8a1aff;\n --color-level-4: #6600cc;\n }\n}\n",".example {\n &__controls {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n padding: 24px;\n border-radius: 16px;\n margin-bottom: 30px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);\n border: 1px solid rgba(255, 255, 255, 0.2);\n\n @media (max-width: 768px) {\n padding: 20px;\n margin-bottom: 20px;\n border-radius: 12px;\n }\n }\n\n &__heatmap {\n margin-bottom: 40px;\n\n @media (max-width: 768px) {\n margin-bottom: 30px;\n }\n }\n}\n","// Control groups\n.control-group {\n margin-bottom: 24px;\n\n &:last-child {\n margin-bottom: 0;\n }\n\n &__label {\n display: block;\n font-weight: 600;\n color: #333;\n margin-bottom: 12px;\n font-size: 1rem;\n\n @media (max-width: 768px) {\n font-size: 0.9rem;\n margin-bottom: 10px;\n }\n }\n\n &__buttons {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n gap: 8px;\n }\n }\n\n &__checkbox {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 1rem;\n color: #555;\n margin: 0;\n\n @media (max-width: 768px) {\n font-size: 0.9rem;\n }\n\n input[type='checkbox'] {\n width: 18px;\n height: 18px;\n accent-color: #667eea;\n cursor: pointer;\n\n @media (max-width: 768px) {\n width: 16px;\n height: 16px;\n }\n }\n\n &:hover {\n color: #333;\n }\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -26,8 +26,9 @@ interface ContributionHeatmapProps {
26
26
  weeks: Week[];
27
27
  };
28
28
  className?: string;
29
+ isReverse?: boolean;
29
30
  }
30
- declare function ContributionHeatmap({ data: { period, weeks }, className, }: ContributionHeatmapProps): react_jsx_runtime.JSX.Element;
31
+ declare function ContributionHeatmap({ data: { period, weeks }, className, isReverse, }: ContributionHeatmapProps): react_jsx_runtime.JSX.Element;
31
32
 
32
33
  declare function ContributionHeatmapExample(): react_jsx_runtime.JSX.Element;
33
34
 
package/dist/index.js CHANGED
@@ -28,18 +28,24 @@ function getLastYearPeriod() {
28
28
  const end = /* @__PURE__ */ new Date();
29
29
  return { start, end };
30
30
  }
31
+ function getLastMonthPeriod() {
32
+ const now = /* @__PURE__ */ new Date();
33
+ const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
34
+ const start = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate() + 1);
35
+ return { start, end };
36
+ }
31
37
  var createDateString = (date) => date.toISOString().split("T")[0];
32
38
 
33
39
  // src/ContributionHeatmap/getMonthsForHeader.ts
34
40
  function getMonthsForHeader({
35
41
  weeks,
36
- period: period2
42
+ period
37
43
  }) {
38
44
  const months = [];
39
- const { start, end } = period2;
45
+ const { start, end } = period;
40
46
  let currentMonth = -1;
41
47
  let currentSpan = 0;
42
- weeks.forEach((week) => {
48
+ weeks.forEach((week, weekIndex) => {
43
49
  if (week.length > 0) {
44
50
  let monthToUse = -1;
45
51
  const actualStartDate = new Date(start);
@@ -57,7 +63,7 @@ function getMonthsForHeader({
57
63
  }
58
64
  if (monthToUse !== currentMonth) {
59
65
  if (currentMonth !== -1) {
60
- months.push({ name: monthNames[currentMonth], span: currentSpan });
66
+ months.push({ name: monthNames[currentMonth], span: currentSpan, start: weekIndex - currentSpan });
61
67
  }
62
68
  currentMonth = monthToUse;
63
69
  currentSpan = 1;
@@ -67,7 +73,7 @@ function getMonthsForHeader({
67
73
  }
68
74
  });
69
75
  if (currentMonth !== -1) {
70
- months.push({ name: monthNames[currentMonth], span: currentSpan });
76
+ months.push({ name: monthNames[currentMonth], span: currentSpan, start: weeks.length - currentSpan });
71
77
  }
72
78
  if (months.length > 0 && months[months.length - 1].span === 1) {
73
79
  months[months.length - 1].span = 2;
@@ -109,40 +115,49 @@ function Legend() {
109
115
  /* @__PURE__ */ jsx("span", { className: "contribution-heatmap__legend-text", children: "More" })
110
116
  ] });
111
117
  }
112
-
113
- // src/ContributionHeatmap/addExtraWeekIfNeeded.ts
114
- var createEmptyContribution = (date) => ({
115
- date,
116
- count: 0,
117
- level: 0
118
- });
119
- var createEmptyWeek = (startDate) => {
120
- const week = [];
121
- const currentDate = new Date(startDate);
122
- for (let day = 0; day < 7; day++) {
123
- const dateString = createDateString(currentDate);
124
- week.push(createEmptyContribution(dateString));
125
- currentDate.setDate(currentDate.getDate() + 1);
126
- }
127
- return week;
128
- };
129
- function addExtraWeekIfNeeded(weeks) {
130
- if (weeks.length === 0) return weeks;
131
- const lastWeek = weeks[weeks.length - 1];
132
- const lastDate = new Date(lastWeek[6].date);
133
- const nextWeekStart = new Date(lastDate);
134
- nextWeekStart.setDate(lastDate.getDate() + 1);
135
- const extraWeek = createEmptyWeek(nextWeekStart);
136
- return [...weeks, extraWeek];
137
- }
138
118
  function ContributionHeatmap({
139
- data: { period: period2, weeks },
140
- className = ""
119
+ data: { period, weeks },
120
+ className = "",
121
+ isReverse = false
141
122
  }) {
142
- const adjustedWeeks = addExtraWeekIfNeeded(weeks);
143
- const months = getMonthsForHeader({ weeks: adjustedWeeks, period: period2 });
123
+ const months = getMonthsForHeader({ weeks, period });
144
124
  return /* @__PURE__ */ jsxs("div", { className: `contribution-heatmap ${className}`, children: [
145
- /* @__PURE__ */ jsxs("table", { className: "contribution-heatmap__table", children: [
125
+ /* @__PURE__ */ jsx("table", { className: "contribution-heatmap__table", children: isReverse ? /* @__PURE__ */ jsxs(Fragment, { children: [
126
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
127
+ /* @__PURE__ */ jsx("th", { className: "contribution-heatmap__month-header" }),
128
+ dayNames.map((dayName, dayIndex) => /* @__PURE__ */ jsx("th", { className: "contribution-heatmap__day-header", children: dayName }, dayIndex))
129
+ ] }) }),
130
+ /* @__PURE__ */ jsx("tbody", { children: weeks.map((week, weekIndex) => {
131
+ const month = months.find((m) => weekIndex === m.start);
132
+ const showMonthLabel = !!month;
133
+ return /* @__PURE__ */ jsxs("tr", { children: [
134
+ showMonthLabel && /* @__PURE__ */ jsx(
135
+ "td",
136
+ {
137
+ className: "contribution-heatmap__month-label",
138
+ rowSpan: month.span,
139
+ children: month.name
140
+ }
141
+ ),
142
+ week.map((contribution, dayIndex) => /* @__PURE__ */ jsx(
143
+ "td",
144
+ {
145
+ className: `contribution-heatmap__day contribution-heatmap__day--level-${contribution.level}`,
146
+ title: formatTooltip(contribution, period),
147
+ "aria-label": formatTooltip(contribution, period),
148
+ role: "button",
149
+ tabIndex: 0,
150
+ "data-count": contribution.count,
151
+ "data-date": contribution.date,
152
+ style: {
153
+ "--animation-delay": `${(weekIndex * 7 + dayIndex) * 5e-3}s`
154
+ }
155
+ },
156
+ dayIndex
157
+ ))
158
+ ] }, weekIndex);
159
+ }) })
160
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
146
161
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
147
162
  /* @__PURE__ */ jsx("th", { className: "contribution-heatmap__day-header" }),
148
163
  months.map((month, index) => /* @__PURE__ */ jsx(
@@ -156,15 +171,15 @@ function ContributionHeatmap({
156
171
  ))
157
172
  ] }) }),
158
173
  /* @__PURE__ */ jsx("tbody", { children: dayNames.map((dayName, dayIndex) => /* @__PURE__ */ jsxs("tr", { children: [
159
- /* @__PURE__ */ jsx("td", { className: "contribution-heatmap__day-label", children: window.innerWidth > 768 ? dayName : dayName.charAt(0) }),
160
- adjustedWeeks.map((week, weekIndex) => {
174
+ /* @__PURE__ */ jsx("td", { className: "contribution-heatmap__day-label", children: dayName }),
175
+ weeks.map((week, weekIndex) => {
161
176
  const contribution = week[dayIndex];
162
177
  return /* @__PURE__ */ jsx(
163
178
  "td",
164
179
  {
165
180
  className: `contribution-heatmap__day contribution-heatmap__day--level-${contribution.level}`,
166
- title: formatTooltip(contribution, period2),
167
- "aria-label": formatTooltip(contribution, period2),
181
+ title: formatTooltip(contribution, period),
182
+ "aria-label": formatTooltip(contribution, period),
168
183
  role: "button",
169
184
  tabIndex: 0,
170
185
  "data-count": contribution.count,
@@ -177,22 +192,11 @@ function ContributionHeatmap({
177
192
  );
178
193
  })
179
194
  ] }, dayIndex)) })
180
- ] }),
195
+ ] }) }),
181
196
  /* @__PURE__ */ jsx(Legend, {})
182
197
  ] });
183
198
  }
184
199
 
185
- // src/ContributionHeatmap/getLevel.ts
186
- var getLevel = (count) => {
187
- let level = 0;
188
- if (count === 0) level = 0;
189
- else if (count <= 2) level = 1;
190
- else if (count <= 5) level = 2;
191
- else if (count <= 8) level = 3;
192
- else level = 4;
193
- return level;
194
- };
195
-
196
200
  // src/mocks/createRealisticMockedCount.ts
197
201
  var isSummerMonth = (month) => {
198
202
  return month >= 5 && month <= 7;
@@ -216,11 +220,20 @@ function createRealisticMockedCount(date) {
216
220
  return count;
217
221
  }
218
222
 
219
- // src/mocks/generateMockData.tsx
223
+ // src/mocks/index.tsx
220
224
  var getRandomCount = () => Math.floor(Math.random() * 15);
221
- function getRange(period2) {
222
- if (period2 !== "lastYear") {
223
- return period2;
225
+ var getLevel = (count) => {
226
+ let level = 0;
227
+ if (count === 0) level = 0;
228
+ else if (count <= 2) level = 1;
229
+ else if (count <= 5) level = 2;
230
+ else if (count <= 8) level = 3;
231
+ else level = 4;
232
+ return level;
233
+ };
234
+ function getRange(period) {
235
+ if (period !== "lastYear") {
236
+ return period;
224
237
  }
225
238
  const end = /* @__PURE__ */ new Date();
226
239
  const start = /* @__PURE__ */ new Date();
@@ -228,11 +241,11 @@ function getRange(period2) {
228
241
  return { start, end };
229
242
  }
230
243
  function generateMockData({
231
- period: period2,
244
+ period,
232
245
  isRealistic
233
246
  }) {
234
247
  const data = [];
235
- const { start, end } = getRange(period2);
248
+ const { start, end } = getRange(period);
236
249
  for (let date = new Date(start); date <= end; date.setDate(date.getDate() + 1)) {
237
250
  const count = isRealistic ? createRealisticMockedCount(date) : getRandomCount();
238
251
  data.push({
@@ -350,13 +363,17 @@ function ControlGroups({
350
363
  ] }) })
351
364
  ] });
352
365
  }
353
- var sampleData = generateMockData({ period: "lastYear", isRealistic: true });
354
- var period = getLastYearPeriod();
366
+ var lastYearPeriod = getLastYearPeriod();
367
+ var lastMonthPeriod = getLastMonthPeriod();
355
368
  function ContributionHeatmapExample() {
356
369
  const [theme, setTheme] = useState("");
357
370
  const [hasRealisticData, setHasRealisticData] = useState(false);
358
- const contribution = hasRealisticData ? sampleData : generateMockData({
359
- period,
371
+ const lastYearContribution = hasRealisticData ? generateMockData({ period: lastYearPeriod, isRealistic: true }) : generateMockData({
372
+ period: lastYearPeriod,
373
+ isRealistic: false
374
+ });
375
+ const lastMonthContribution = hasRealisticData ? generateMockData({ period: lastMonthPeriod, isRealistic: true }) : generateMockData({
376
+ period: lastMonthPeriod,
360
377
  isRealistic: false
361
378
  });
362
379
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -371,9 +388,21 @@ function ContributionHeatmapExample() {
371
388
  {
372
389
  className: theme ? `contribution-heatmap--${theme}` : "",
373
390
  data: {
374
- weeks: groupByWeeks(contribution),
375
- contribution,
376
- period
391
+ weeks: groupByWeeks(lastYearContribution),
392
+ contribution: lastYearContribution,
393
+ period: lastYearPeriod
394
+ }
395
+ }
396
+ ) }),
397
+ /* @__PURE__ */ jsx("div", { className: "example__heatmap", children: /* @__PURE__ */ jsx(
398
+ ContributionHeatmap,
399
+ {
400
+ isReverse: true,
401
+ className: theme ? `contribution-heatmap--${theme}` : "",
402
+ data: {
403
+ weeks: groupByWeeks(lastMonthContribution),
404
+ contribution: lastMonthContribution,
405
+ period: lastMonthPeriod
377
406
  }
378
407
  }
379
408
  ) })
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/models.tsx","../src/ContributionHeatmap/getMonthsForHeader.ts","../src/shared/formatTooltip.tsx","../src/shared/Legend.tsx","../src/ContributionHeatmap/addExtraWeekIfNeeded.ts","../src/ContributionHeatmap/index.tsx","../src/ContributionHeatmap/getLevel.ts","../src/mocks/createRealisticMockedCount.ts","../src/mocks/generateMockData.tsx","../src/shared/groupByWeeks.ts","../src/Example/ControlGroups.tsx","../src/Example/index.tsx"],"names":["period","jsxs","jsx","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["type Theme = '' | 'ocean' | 'sunset' | 'purple';\n\ninterface ContributionData {\n date: string;\n count: number;\n level: 0 | 1 | 2 | 3 | 4;\n}\n\ntype Week = [\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n];\n\ntype Period = { start: Date; end: Date };\n\nconst monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n] as const;\nconst dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const;\n\nfunction getLastYearPeriod(): Period {\n const start = new Date(\n new Date().setFullYear(\n new Date().getFullYear() - 1,\n new Date().getMonth(),\n new Date().getDate() + 1,\n ),\n );\n const end = new Date();\n return { start, end };\n}\n\nconst createDateString = (date: Date): string =>\n date.toISOString().split('T')[0];\n\nexport type { ContributionData, Week, Period, Theme };\nexport { monthNames, dayNames, createDateString, getLastYearPeriod };\n","import { monthNames, type Period, type Week } from '@/shared/models';\n\nfunction getMonthsForHeader({\n weeks,\n period,\n}: {\n weeks: Week[];\n period: Period;\n}): {\n name: string;\n span: number;\n}[] {\n const months: { name: string; span: number }[] = [];\n const { start, end } = period;\n let currentMonth = -1;\n let currentSpan = 0;\n\n weeks.forEach((week) => {\n if (week.length > 0) {\n // Find the first day in the week that falls within our actual data range\n let monthToUse = -1;\n const actualStartDate = new Date(start);\n const actualEndDate = new Date(end);\n\n for (const day of week) {\n const dayDate = new Date(day.date);\n if (dayDate >= actualStartDate && dayDate <= actualEndDate) {\n monthToUse = dayDate.getMonth();\n break;\n }\n }\n\n // If no day in the week is in our actual range, use the middle day (Wednesday)\n if (monthToUse === -1) {\n const middleDay = week[3]; // Wednesday (index 3)\n monthToUse = new Date(middleDay.date).getMonth();\n }\n\n if (monthToUse !== currentMonth) {\n if (currentMonth !== -1) {\n months.push({ name: monthNames[currentMonth], span: currentSpan });\n }\n currentMonth = monthToUse;\n currentSpan = 1;\n } else {\n currentSpan++;\n }\n }\n });\n\n if (currentMonth !== -1) {\n months.push({ name: monthNames[currentMonth], span: currentSpan });\n }\n\n // If the last month only has one week, add an extra week for better visual balance\n if (months.length > 0 && months[months.length - 1].span === 1) {\n months[months.length - 1].span = 2;\n }\n\n return months;\n}\n\nexport { getMonthsForHeader };\n","import type { ContributionData, Period } from '@/shared/models';\n\nfunction isInRange(date: Date, { start, end }: Period): boolean {\n const actualStartDate = new Date(start);\n const actualEndDate = new Date(end);\n const contributionDate = new Date(date);\n\n return contributionDate > actualStartDate && contributionDate < actualEndDate;\n}\n\nconst formatTooltip = (\n contribution: ContributionData,\n { start, end }: Period,\n): string => {\n const date = new Date(contribution.date);\n const formattedDate = date.toLocaleDateString('en-US', {\n weekday: 'short',\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n\n if (\n !isInRange(new Date(contribution.date), { start, end }) ||\n contribution.count === 0\n ) {\n return `${formattedDate}: No contributions`;\n }\n\n return `${formattedDate}: ${contribution.count} contribution${contribution.count !== 1 ? 's' : ''}`;\n};\n\nexport { formatTooltip };\n","function Legend(): React.ReactNode {\n return (\n <div className=\"contribution-heatmap__legend\">\n <span className=\"contribution-heatmap__legend-text\">Less</span>\n {[0, 1, 2, 3, 4].map((level) => (\n <div\n key={level}\n className={`contribution-heatmap__legend-item contribution-heatmap__legend-item--level-${level}`}\n title={`Level ${level}`}\n ></div>\n ))}\n <span className=\"contribution-heatmap__legend-text\">More</span>\n </div>\n );\n}\n\nexport { Legend };\n","import { createDateString, type ContributionData, type Week } from '@/shared/models';\n\nconst createEmptyContribution = (date: string): ContributionData => ({\n date,\n count: 0,\n level: 0,\n});\n\nconst createEmptyWeek = (startDate: Date): Week => {\n const week: ContributionData[] = [];\n const currentDate = new Date(startDate);\n \n for (let day = 0; day < 7; day++) {\n const dateString = createDateString(currentDate);\n week.push(createEmptyContribution(dateString));\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return week as Week;\n};\n\n/**\n * Adds an extra empty week if the last month only has one week\n * to match the header span and improve visual balance\n */\nexport function addExtraWeekIfNeeded(weeks: Week[]): Week[] {\n if (weeks.length === 0) return weeks;\n\n // Simple approach: always add an extra week at the end for better balance\n // This ensures the table has an extra column to match the header span\n const lastWeek = weeks[weeks.length - 1];\n const lastDate = new Date(lastWeek[6].date); // Saturday of last week\n const nextWeekStart = new Date(lastDate);\n nextWeekStart.setDate(lastDate.getDate() + 1); // Next Sunday\n \n const extraWeek = createEmptyWeek(nextWeekStart);\n return [...weeks, extraWeek];\n}","import './index.scss';\nimport type { ContributionData, Period, Week as WeekType } from '../shared/models';\nimport { getMonthsForHeader } from './getMonthsForHeader';\nimport { formatTooltip } from '@/shared/formatTooltip';\nimport { dayNames } from '@/shared/models';\nimport { Legend } from '@/shared/Legend';\nimport { addExtraWeekIfNeeded } from './addExtraWeekIfNeeded';\n\ninterface ContributionHeatmapProps {\n data: { contribution: ContributionData[]; period: Period; weeks: WeekType[] };\n className?: string;\n}\n\nfunction ContributionHeatmap({\n data: { period, weeks },\n className = '',\n}: ContributionHeatmapProps) {\n // Add extra week if needed to match header span\n const adjustedWeeks = addExtraWeekIfNeeded(weeks);\n const months = getMonthsForHeader({ weeks: adjustedWeeks, period });\n\n return (\n <div className={`contribution-heatmap ${className}`}>\n <table className=\"contribution-heatmap__table\">\n <thead>\n <tr>\n <th className=\"contribution-heatmap__day-header\"></th>\n {months.map((month, index) => (\n <th\n key={index}\n className=\"contribution-heatmap__month-header\"\n colSpan={month.span}\n >\n {month.name}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {dayNames.map((dayName, dayIndex) => (\n <tr key={dayIndex}>\n <td className=\"contribution-heatmap__day-label\">\n {window.innerWidth > 768 ? dayName : dayName.charAt(0)}\n </td>\n {adjustedWeeks.map((week, weekIndex) => {\n const contribution = week[dayIndex];\n return (\n <td\n key={weekIndex}\n className={`contribution-heatmap__day contribution-heatmap__day--level-${contribution.level}`}\n title={formatTooltip(contribution, period)}\n aria-label={formatTooltip(contribution, period)}\n role=\"button\"\n tabIndex={0}\n data-count={contribution.count}\n data-date={contribution.date}\n style={{ \n '--animation-delay': `${(weekIndex * 7 + dayIndex) * 0.005}s` \n } as React.CSSProperties}\n ></td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n\n <Legend />\n </div>\n );\n}\n\nexport { ContributionHeatmap };\n","import type { ContributionData } from '@/shared/models';\n\nconst getLevel = (count: number): ContributionData['level'] => {\n let level: 0 | 1 | 2 | 3 | 4 = 0;\n if (count === 0) level = 0;\n else if (count <= 2) level = 1;\n else if (count <= 5) level = 2;\n else if (count <= 8) level = 3;\n else level = 4;\n\n return level;\n};\n\nexport { getLevel };\n","import type { ContributionData } from '@/shared/models';\n\nconst isSummerMonth = (month: number) => {\n return month >= 5 && month <= 7;\n};\n\nexport function createRealisticMockedCount(\n date: Date,\n): ContributionData['count'] {\n // Create realistic patterns\n const dayOfWeek = date.getDay();\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\n const month = date.getMonth();\n\n let baseCount = isWeekend ? 2 : 8;\n\n // Lower activity in summer months (June, July, August)\n if (isSummerMonth(month)) {\n baseCount = Math.max(0, baseCount - 3);\n }\n\n // Add some randomness\n const randomFactor = Math.random();\n let count = 0;\n\n if (randomFactor > 0.3) {\n count = Math.floor(Math.random() * baseCount);\n }\n\n // Occasional high activity days\n if (randomFactor > 0.95) {\n count += Math.floor(Math.random() * 10);\n }\n\n return count;\n}\n","import { createDateString, type ContributionData, type Period } from '@/shared/models';\nimport { getLevel } from '@/ContributionHeatmap/getLevel';\nimport { createRealisticMockedCount } from './createRealisticMockedCount';\n\nconst getRandomCount = () => Math.floor(Math.random() * 15);\n\nfunction getRange(period: Period | 'lastYear') {\n if (period !== 'lastYear') {\n return period;\n }\n const end = new Date(); // Today\n const start = new Date();\n start.setFullYear(start.getFullYear() - 1); // One year ago\n return { start, end };\n}\n\nfunction generateMockData({\n period,\n isRealistic,\n}: {\n period: Period | 'lastYear';\n isRealistic: boolean;\n}): ContributionData[] {\n const data: ContributionData[] = [];\n const { start, end } = getRange(period);\n\n for (\n let date = new Date(start);\n date <= end;\n date.setDate(date.getDate() + 1)\n ) {\n const count = isRealistic\n ? createRealisticMockedCount(date)\n : getRandomCount();\n data.push({\n date: createDateString(date),\n count,\n level: getLevel(count),\n });\n }\n\n return data;\n}\n\nexport { generateMockData };\n","import { createDateString, type ContributionData, type Week } from '@/shared/models';\n\nconst createEmpyContribution = (date: string): ContributionData => ({\n date,\n count: 0,\n level: 0,\n});\n\nconst createContributionMap = (\n contributions: ContributionData[],\n): Map<string, ContributionData> => {\n const contributionMap = new Map<string, ContributionData>();\n contributions.forEach((contribution) => {\n contributionMap.set(contribution.date, contribution);\n });\n return contributionMap;\n};\n\nconst getFirstSunday: (firstDate: Date) => Date = (firstDate) => {\n const startOfWeek = new Date(firstDate);\n startOfWeek.setDate(firstDate.getDate() - firstDate.getDay());\n return startOfWeek;\n};\n\nconst getLastSaturday: (lastDate: Date) => Date = (lastDate) => {\n const endOfWeek = new Date(lastDate);\n endOfWeek.setDate(lastDate.getDate() + (6 - lastDate.getDay()));\n return endOfWeek;\n};\n\nconst createWeek = (\n startDate: Date,\n contributionMap: Map<string, ContributionData>,\n): Week => {\n const week: ContributionData[] = [];\n const currentDate = new Date(startDate);\n for (let day = 0; day < 7; day++) {\n const dateString = createDateString(currentDate);\n const contribution = contributionMap.get(dateString);\n\n if (contribution) {\n week.push(contribution);\n } else {\n week.push(createEmpyContribution(dateString));\n }\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return week as Week;\n};\n\nconst groupByWeeks: (contributions: ContributionData[]) => Week[] = (\n contributions,\n) => {\n const weeks: Week[] = [];\n const contributionMap = createContributionMap(contributions);\n\n const firstDay = getFirstSunday(new Date(contributions[0].date));\n const lastDate = getLastSaturday(\n new Date(contributions[contributions.length - 1].date),\n );\n\n const currentDate = new Date(firstDay);\n while (currentDate <= lastDate) {\n weeks.push(createWeek(currentDate, contributionMap));\n currentDate.setDate(currentDate.getDate() + 7);\n }\n\n return weeks;\n};\n\nexport { groupByWeeks };\n","import './controlGroups.scss';\nimport type { Theme } from '@/shared/models';\n\nexport function ControlGroups({\n actions: { theme, setTheme, hasRealisticData, setHasRealisticData },\n}: {\n actions: {\n theme: Theme;\n setTheme: (theme: Theme) => void;\n hasRealisticData: boolean;\n setHasRealisticData: (use: boolean) => void;\n };\n}) {\n return (\n <>\n <div className=\"control-group\">\n <label className=\"control-group__label\">Theme:</label>\n <div className=\"control-group__buttons\">\n <button\n className={`theme-button ${theme === '' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('')}\n >\n GitHub\n </button>\n <button\n className={`theme-button ${theme === 'ocean' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('ocean')}\n >\n Ocean\n </button>\n <button\n className={`theme-button ${theme === 'sunset' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('sunset')}\n >\n Sunset\n </button>\n <button\n className={`theme-button ${theme === 'purple' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('purple')}\n >\n Purple\n </button>\n </div>\n </div>\n <div className=\"control-group\">\n <label className=\"control-group__checkbox\">\n <input\n type=\"checkbox\"\n checked={hasRealisticData}\n onChange={(e) => setHasRealisticData(e.target.checked)}\n />\n Use realistic sample data\n </label>\n </div>\n </>\n );\n}\n","import { useState } from 'react';\nimport { ContributionHeatmap } from '@/ContributionHeatmap';\nimport { generateMockData } from '@/mocks/generateMockData';\nimport { getLastYearPeriod, type Theme } from '@/shared/models';\nimport { groupByWeeks } from '@/shared/groupByWeeks';\nimport './index.scss';\nimport { ControlGroups } from './ControlGroups';\n\nconst sampleData = generateMockData({ period: 'lastYear', isRealistic: true });\nconst period = getLastYearPeriod();\n\nfunction ContributionHeatmapExample() {\n const [theme, setTheme] = useState<Theme>('');\n const [hasRealisticData, setHasRealisticData] = useState(false);\n\n const contribution = hasRealisticData\n ? sampleData\n : generateMockData({\n period,\n isRealistic: false,\n });\n\n return (\n <>\n <div className=\"example__controls\">\n <ControlGroups\n actions={{ theme, setTheme, hasRealisticData, setHasRealisticData }}\n />\n </div>\n\n <div className=\"example__heatmap\">\n <ContributionHeatmap\n className={theme ? `contribution-heatmap--${theme}` : ''}\n data={{\n weeks: groupByWeeks(contribution),\n contribution,\n period,\n }}\n />\n </div>\n </>\n );\n}\n\nexport { ContributionHeatmapExample };\n"]}
1
+ {"version":3,"sources":["../src/shared/models.tsx","../src/ContributionHeatmap/getMonthsForHeader.ts","../src/shared/formatTooltip.tsx","../src/shared/Legend.tsx","../src/ContributionHeatmap/index.tsx","../src/mocks/createRealisticMockedCount.ts","../src/mocks/index.tsx","../src/shared/groupByWeeks.ts","../src/Example/ControlGroups.tsx","../src/Example/index.tsx"],"names":["jsxs","jsx","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["type Theme = '' | 'ocean' | 'sunset' | 'purple';\n\ninterface ContributionData {\n date: string;\n count: number;\n level: 0 | 1 | 2 | 3 | 4;\n}\n\ntype Week = [\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n ContributionData,\n];\n\ntype Period = { start: Date; end: Date };\n\nconst monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n] as const;\nconst dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const;\n\nfunction getLastYearPeriod(): Period {\n const start = new Date(\n new Date().setFullYear(\n new Date().getFullYear() - 1,\n new Date().getMonth(),\n new Date().getDate() + 1,\n ),\n );\n const end = new Date();\n return { start, end };\n}\n\nfunction getLastMonthPeriod(): Period {\n const now = new Date();\n const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const start = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate() + 1);\n return { start, end };\n}\n\nconst createDateString = (date: Date): string =>\n date.toISOString().split('T')[0];\n\nexport type { ContributionData, Week, Period, Theme };\nexport { monthNames, dayNames, createDateString, getLastYearPeriod, getLastMonthPeriod };\n","import { monthNames, type Period, type Week } from '@/shared/models';\n\nfunction getMonthsForHeader({\n weeks,\n period,\n}: {\n weeks: Week[];\n period: Period;\n}): {\n name: string;\n span: number;\n start: number;\n}[] {\n const months: { name: string; span: number; start: number }[] = [];\n const { start, end } = period;\n let currentMonth = -1;\n let currentSpan = 0;\n\n weeks.forEach((week, weekIndex) => {\n if (week.length > 0) {\n // Find the first day in the week that falls within our actual data range\n let monthToUse = -1;\n const actualStartDate = new Date(start);\n const actualEndDate = new Date(end);\n\n for (const day of week) {\n const dayDate = new Date(day.date);\n if (dayDate >= actualStartDate && dayDate <= actualEndDate) {\n monthToUse = dayDate.getMonth();\n break;\n }\n }\n\n // If no day in the week is in our actual range, use the middle day (Wednesday)\n if (monthToUse === -1) {\n const middleDay = week[3]; // Wednesday (index 3)\n monthToUse = new Date(middleDay.date).getMonth();\n }\n\n if (monthToUse !== currentMonth) {\n if (currentMonth !== -1) {\n months.push({ name: monthNames[currentMonth], span: currentSpan, start: weekIndex - currentSpan });\n }\n currentMonth = monthToUse;\n currentSpan = 1;\n } else {\n currentSpan++;\n }\n }\n });\n\n if (currentMonth !== -1) {\n months.push({ name: monthNames[currentMonth], span: currentSpan, start: weeks.length - currentSpan });\n }\n\n // If the last month only has one week, add an extra week for better visual balance\n if (months.length > 0 && months[months.length - 1].span === 1) {\n months[months.length - 1].span = 2;\n }\n\n return months;\n}\n\nexport { getMonthsForHeader };\n","import type { ContributionData, Period } from '@/shared/models';\n\nfunction isInRange(date: Date, { start, end }: Period): boolean {\n const actualStartDate = new Date(start);\n const actualEndDate = new Date(end);\n const contributionDate = new Date(date);\n\n return contributionDate > actualStartDate && contributionDate < actualEndDate;\n}\n\nconst formatTooltip = (\n contribution: ContributionData,\n { start, end }: Period,\n): string => {\n const date = new Date(contribution.date);\n const formattedDate = date.toLocaleDateString('en-US', {\n weekday: 'short',\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n\n if (\n !isInRange(new Date(contribution.date), { start, end }) ||\n contribution.count === 0\n ) {\n return `${formattedDate}: No contributions`;\n }\n\n return `${formattedDate}: ${contribution.count} contribution${contribution.count !== 1 ? 's' : ''}`;\n};\n\nexport { formatTooltip };\n","function Legend(): React.ReactNode {\n return (\n <div className=\"contribution-heatmap__legend\">\n <span className=\"contribution-heatmap__legend-text\">Less</span>\n {[0, 1, 2, 3, 4].map((level) => (\n <div\n key={level}\n className={`contribution-heatmap__legend-item contribution-heatmap__legend-item--level-${level}`}\n title={`Level ${level}`}\n ></div>\n ))}\n <span className=\"contribution-heatmap__legend-text\">More</span>\n </div>\n );\n}\n\nexport { Legend };\n","import './index.scss';\nimport type { ContributionData, Period, Week as WeekType } from '../shared/models';\nimport { getMonthsForHeader } from './getMonthsForHeader';\nimport { formatTooltip } from '@/shared/formatTooltip';\nimport { dayNames } from '@/shared/models';\nimport { Legend } from '@/shared/Legend';\n\n\ninterface ContributionHeatmapProps {\n data: { contribution: ContributionData[]; period: Period; weeks: WeekType[] };\n className?: string;\n isReverse?: boolean;\n}\n\nfunction ContributionHeatmap({\n data: { period, weeks },\n className = '',\n isReverse = false,\n}: ContributionHeatmapProps) {\n // Add extra week if needed to match header span\n \n const months = getMonthsForHeader({ weeks, period });\n\n return (\n <div className={`contribution-heatmap ${className}`}>\n <table className=\"contribution-heatmap__table\">\n {isReverse ? (\n <>\n <thead>\n <tr>\n <th className=\"contribution-heatmap__month-header\"></th>\n {dayNames.map((dayName, dayIndex) => (\n <th key={dayIndex} className=\"contribution-heatmap__day-header\">\n {dayName}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week, weekIndex) => {\n // Find month info for this week\n const month = months.find(m => weekIndex === m.start);\n const showMonthLabel = !!month;\n return (\n <tr key={weekIndex}>\n {showMonthLabel && (\n <td\n className=\"contribution-heatmap__month-label\"\n rowSpan={month.span}\n >\n {month.name}\n </td>\n )}\n {week.map((contribution, dayIndex) => (\n <td\n key={dayIndex}\n className={`contribution-heatmap__day contribution-heatmap__day--level-${contribution.level}`}\n title={formatTooltip(contribution, period)}\n aria-label={formatTooltip(contribution, period)}\n role=\"button\"\n tabIndex={0}\n data-count={contribution.count}\n data-date={contribution.date}\n style={{\n '--animation-delay': `${(weekIndex * 7 + dayIndex) * 0.005}s`\n } as React.CSSProperties}\n ></td>\n ))}\n </tr>\n );\n })}\n </tbody>\n </>\n ) : (\n <>\n <thead>\n <tr>\n <th className=\"contribution-heatmap__day-header\"></th>\n {months.map((month, index) => (\n <th\n key={index}\n className=\"contribution-heatmap__month-header\"\n colSpan={month.span}\n >\n {month.name}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {dayNames.map((dayName, dayIndex) => (\n <tr key={dayIndex}>\n <td className=\"contribution-heatmap__day-label\">\n {dayName}\n </td>\n {weeks.map((week, weekIndex) => {\n const contribution = week[dayIndex];\n return (\n <td\n key={weekIndex}\n className={`contribution-heatmap__day contribution-heatmap__day--level-${contribution.level}`}\n title={formatTooltip(contribution, period)}\n aria-label={formatTooltip(contribution, period)}\n role=\"button\"\n tabIndex={0}\n data-count={contribution.count}\n data-date={contribution.date}\n style={{\n '--animation-delay': `${(weekIndex * 7 + dayIndex) * 0.005}s`\n } as React.CSSProperties}\n ></td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </>\n )}\n </table>\n <Legend />\n </div>\n );\n}\n\nexport { ContributionHeatmap };\n","import type { ContributionData } from '@/shared/models';\n\nconst isSummerMonth = (month: number) => {\n return month >= 5 && month <= 7;\n};\n\nexport function createRealisticMockedCount(\n date: Date,\n): ContributionData['count'] {\n // Create realistic patterns\n const dayOfWeek = date.getDay();\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\n const month = date.getMonth();\n\n let baseCount = isWeekend ? 2 : 8;\n\n // Lower activity in summer months (June, July, August)\n if (isSummerMonth(month)) {\n baseCount = Math.max(0, baseCount - 3);\n }\n\n // Add some randomness\n const randomFactor = Math.random();\n let count = 0;\n\n if (randomFactor > 0.3) {\n count = Math.floor(Math.random() * baseCount);\n }\n\n // Occasional high activity days\n if (randomFactor > 0.95) {\n count += Math.floor(Math.random() * 10);\n }\n\n return count;\n}\n","import { createDateString, type ContributionData, type Period } from '@/shared/models';\nimport { createRealisticMockedCount } from './createRealisticMockedCount';\n\nconst getRandomCount = () => Math.floor(Math.random() * 15);\n\nconst getLevel = (count: number): ContributionData['level'] => {\n let level: 0 | 1 | 2 | 3 | 4 = 0;\n if (count === 0) level = 0;\n else if (count <= 2) level = 1;\n else if (count <= 5) level = 2;\n else if (count <= 8) level = 3;\n else level = 4;\n\n return level;\n};\n\nfunction getRange(period: Period | 'lastYear') {\n if (period !== 'lastYear') {\n return period;\n }\n const end = new Date(); // Today\n const start = new Date();\n start.setFullYear(start.getFullYear() - 1); // One year ago\n return { start, end };\n}\n\nfunction generateMockData({\n period,\n isRealistic,\n}: {\n period: Period | 'lastYear';\n isRealistic: boolean;\n}): ContributionData[] {\n const data: ContributionData[] = [];\n const { start, end } = getRange(period);\n\n for (\n let date = new Date(start);\n date <= end;\n date.setDate(date.getDate() + 1)\n ) {\n const count = isRealistic\n ? createRealisticMockedCount(date)\n : getRandomCount();\n data.push({\n date: createDateString(date),\n count,\n level: getLevel(count),\n });\n }\n\n return data;\n}\n\nexport { generateMockData };\n","import { createDateString, type ContributionData, type Week } from '@/shared/models';\n\nconst createEmpyContribution = (date: string): ContributionData => ({\n date,\n count: 0,\n level: 0,\n});\n\nconst createContributionMap = (\n contributions: ContributionData[],\n): Map<string, ContributionData> => {\n const contributionMap = new Map<string, ContributionData>();\n contributions.forEach((contribution) => {\n contributionMap.set(contribution.date, contribution);\n });\n return contributionMap;\n};\n\nconst getFirstSunday: (firstDate: Date) => Date = (firstDate) => {\n const startOfWeek = new Date(firstDate);\n startOfWeek.setDate(firstDate.getDate() - firstDate.getDay());\n return startOfWeek;\n};\n\nconst getLastSaturday: (lastDate: Date) => Date = (lastDate) => {\n const endOfWeek = new Date(lastDate);\n endOfWeek.setDate(lastDate.getDate() + (6 - lastDate.getDay()));\n return endOfWeek;\n};\n\nconst createWeek = (\n startDate: Date,\n contributionMap: Map<string, ContributionData>,\n): Week => {\n const week: ContributionData[] = [];\n const currentDate = new Date(startDate);\n for (let day = 0; day < 7; day++) {\n const dateString = createDateString(currentDate);\n const contribution = contributionMap.get(dateString);\n\n if (contribution) {\n week.push(contribution);\n } else {\n week.push(createEmpyContribution(dateString));\n }\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return week as Week;\n};\n\nconst groupByWeeks: (contributions: ContributionData[]) => Week[] = (\n contributions,\n) => {\n const weeks: Week[] = [];\n const contributionMap = createContributionMap(contributions);\n\n const firstDay = getFirstSunday(new Date(contributions[0].date));\n const lastDate = getLastSaturday(\n new Date(contributions[contributions.length - 1].date),\n );\n\n const currentDate = new Date(firstDay);\n while (currentDate <= lastDate) {\n weeks.push(createWeek(currentDate, contributionMap));\n currentDate.setDate(currentDate.getDate() + 7);\n }\n\n return weeks;\n};\n\nexport { groupByWeeks };\n","import './controlGroups.scss';\nimport type { Theme } from '@/shared/models';\n\nexport function ControlGroups({\n actions: { theme, setTheme, hasRealisticData, setHasRealisticData },\n}: {\n actions: {\n theme: Theme;\n setTheme: (theme: Theme) => void;\n hasRealisticData: boolean;\n setHasRealisticData: (use: boolean) => void;\n };\n}) {\n return (\n <>\n <div className=\"control-group\">\n <label className=\"control-group__label\">Theme:</label>\n <div className=\"control-group__buttons\">\n <button\n className={`theme-button ${theme === '' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('')}\n >\n GitHub\n </button>\n <button\n className={`theme-button ${theme === 'ocean' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('ocean')}\n >\n Ocean\n </button>\n <button\n className={`theme-button ${theme === 'sunset' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('sunset')}\n >\n Sunset\n </button>\n <button\n className={`theme-button ${theme === 'purple' ? 'theme-button--active' : ''}`}\n onClick={() => setTheme('purple')}\n >\n Purple\n </button>\n </div>\n </div>\n <div className=\"control-group\">\n <label className=\"control-group__checkbox\">\n <input\n type=\"checkbox\"\n checked={hasRealisticData}\n onChange={(e) => setHasRealisticData(e.target.checked)}\n />\n Use realistic sample data\n </label>\n </div>\n </>\n );\n}\n","import { useState } from 'react';\nimport { ContributionHeatmap } from '@/ContributionHeatmap';\nimport { generateMockData } from '@/mocks';\nimport { getLastMonthPeriod, getLastYearPeriod, type Theme } from '@/shared/models';\nimport { groupByWeeks } from '@/shared/groupByWeeks';\nimport './index.scss';\nimport { ControlGroups } from './ControlGroups';\n\nconst lastYearPeriod = getLastYearPeriod();\nconst lastMonthPeriod = getLastMonthPeriod();\n\nfunction ContributionHeatmapExample() {\n const [theme, setTheme] = useState<Theme>('');\n const [hasRealisticData, setHasRealisticData] = useState(false);\n\n const lastYearContribution = hasRealisticData\n ? generateMockData({ period: lastYearPeriod, isRealistic: true })\n : generateMockData({\n period: lastYearPeriod,\n isRealistic: false,\n });\n\n const lastMonthContribution = hasRealisticData\n ? generateMockData({ period: lastMonthPeriod, isRealistic: true })\n : generateMockData({\n period: lastMonthPeriod,\n isRealistic: false,\n });\n\n return (\n <>\n <div className=\"example__controls\">\n <ControlGroups\n actions={{ theme, setTheme, hasRealisticData, setHasRealisticData }}\n />\n </div>\n\n <div className=\"example__heatmap\">\n <ContributionHeatmap\n className={theme ? `contribution-heatmap--${theme}` : ''}\n data={{\n weeks: groupByWeeks(lastYearContribution),\n contribution: lastYearContribution,\n period: lastYearPeriod,\n }}\n />\n </div>\n\n <div className=\"example__heatmap\">\n <ContributionHeatmap\n isReverse\n className={theme ? `contribution-heatmap--${theme}` : ''}\n data={{\n weeks: groupByWeeks(lastMonthContribution),\n contribution: lastMonthContribution,\n period: lastMonthPeriod,\n }}\n />\n </div>\n </>\n \n );\n}\n\nexport { ContributionHeatmapExample };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pearpages/heatmap",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/pearpages/heatmap"