github-contributions-ui 1.0.5 → 1.0.7

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.cjs CHANGED
@@ -1,4 +1,6 @@
1
+ "use client";
1
2
  "use strict";
3
+ "use client";
2
4
  var __defProp = Object.defineProperty;
3
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -83,9 +85,8 @@ function buildGrid(dayMap, year) {
83
85
  const week = [];
84
86
  for (let d = 0; d < 7; d++) {
85
87
  const iso = cur.toISOString().slice(0, 10);
86
- if (cur > end) {
87
- week.push(null);
88
- } else {
88
+ if (cur > end) week.push(null);
89
+ else {
89
90
  week.push(
90
91
  (_a = dayMap.get(iso)) != null ? _a : {
91
92
  date: iso,
@@ -124,7 +125,7 @@ function Tooltip({ day, x, y }) {
124
125
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
125
126
  "div",
126
127
  {
127
- className: "fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white dark:bg-white dark:text-neutral-900",
128
+ className: "fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white",
128
129
  style: { left: x, top: y - 8 },
129
130
  children: [
130
131
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("b", { children: [
@@ -143,7 +144,7 @@ function Skeleton() {
143
144
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-[3px] animate-pulse opacity-40", children: Array.from({ length: 53 }).map((_, w) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-[3px]", children: Array.from({ length: 7 }).map((_2, d) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
144
145
  "div",
145
146
  {
146
- className: "w-[13px] h-[13px] rounded-[3px] bg-neutral-300 dark:bg-neutral-700"
147
+ className: "w-[13px] h-[13px] rounded-[3px] bg-neutral-700"
147
148
  },
148
149
  d
149
150
  )) }, w)) });
@@ -159,7 +160,7 @@ function YearPill({
159
160
  onClick,
160
161
  className: [
161
162
  "px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150",
162
- active ? "bg-neutral-900 text-white dark:bg-white dark:text-neutral-900" : "bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-700"
163
+ active ? "bg-white text-neutral-900" : "bg-neutral-800 text-neutral-400 hover:bg-neutral-700"
163
164
  ].join(" "),
164
165
  children: label
165
166
  }
@@ -167,89 +168,6 @@ function YearPill({
167
168
  }
168
169
  function GithubActivity({ username, theme = "dark", className }) {
169
170
  var _a;
170
- const STYLES = `
171
- .gcu .relative{position:relative}
172
- .gcu .absolute{position:absolute}
173
- .gcu .fixed{position:fixed}
174
- .gcu .z-50{z-index:50}
175
- .gcu .pointer-events-none{pointer-events:none}
176
- .gcu .flex{display:flex}
177
- .gcu .flex-col{flex-direction:column}
178
- .gcu .flex-wrap{flex-wrap:wrap}
179
- .gcu .items-center{align-items:center}
180
- .gcu .justify-start{justify-content:flex-start}
181
- .gcu .inline-block{display:inline-block}
182
- .gcu .w-full{width:100%}
183
- .gcu .w-\\[10px\\]{width:10px}
184
- .gcu .w-\\[13px\\]{width:13px}
185
- .gcu .h-\\[10px\\]{height:10px}
186
- .gcu .h-\\[13px\\]{height:13px}
187
- .gcu .h-\\[18px\\]{height:18px}
188
- .gcu .gap-\\[3px\\]{gap:3px}
189
- .gcu .gap-1{gap:0.25rem}
190
- .gcu .gap-1\\.5{gap:0.375rem}
191
- .gcu .gap-x-6{column-gap:1.5rem}
192
- .gcu .gap-y-1{row-gap:0.25rem}
193
- .gcu .mb-4{margin-bottom:1rem}
194
- .gcu .mt-3{margin-top:0.75rem}
195
- .gcu .mt-4{margin-top:1rem}
196
- .gcu .mr-1{margin-right:0.25rem}
197
- .gcu .ml-1{margin-left:0.25rem}
198
- .gcu .p-4{padding:1rem}
199
- .gcu .pt-3{padding-top:0.75rem}
200
- .gcu .pt-px{padding-top:1px}
201
- .gcu .pb-1{padding-bottom:0.25rem}
202
- .gcu .pr-1\\.5{padding-right:0.375rem}
203
- .gcu .px-2\\.5{padding-left:0.625rem;padding-right:0.625rem}
204
- .gcu .py-1\\.5{padding-top:0.375rem;padding-bottom:0.375rem}
205
- .gcu .py-0\\.5{padding-top:0.125rem;padding-bottom:0.125rem}
206
- .gcu .rounded-\\[2px\\]{border-radius:2px}
207
- .gcu .rounded-\\[3px\\]{border-radius:3px}
208
- .gcu .rounded-md{border-radius:0.375rem}
209
- .gcu .rounded-full{border-radius:9999px}
210
- .gcu .rounded-xl{border-radius:0.75rem}
211
- .gcu .text-right{text-align:right}
212
- .gcu .text-\\[10px\\]{font-size:10px}
213
- .gcu .text-\\[11px\\]{font-size:11px}
214
- .gcu .text-xs{font-size:0.75rem}
215
- .gcu .text-sm{font-size:0.875rem}
216
- .gcu .font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}
217
- .gcu .font-medium{font-weight:500}
218
- .gcu .font-semibold{font-weight:600}
219
- .gcu .select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}
220
- .gcu .whitespace-nowrap{white-space:nowrap}
221
- .gcu .overflow-x-auto{overflow-x:auto}
222
- .gcu .overflow-y-visible{overflow-y:visible}
223
- .gcu .border{border-width:1px;border-style:solid;border-color:#e5e5e5}
224
- .gcu .border-t{border-top-width:1px;border-top-style:solid;border-top-color:#e5e5e5}
225
- .gcu .transition-transform{transition-property:transform;transition-timing-function:ease;transition-duration:0.1s}
226
- .gcu .transition-colors{transition-property:color,background-color,border-color;transition-timing-function:ease;transition-duration:0.15s}
227
- .gcu .duration-100{transition-duration:0.1s}
228
- .gcu .duration-150{transition-duration:0.15s}
229
- .gcu .hover\\:scale-125:hover{transform:scale(1.25)}
230
- .gcu .text-neutral-500{color:#6b7280}
231
- .gcu .text-neutral-400{color:#9ca3af}
232
- .gcu .text-neutral-700{color:#374151}
233
- .gcu .text-neutral-200{color:#e5e7eb}
234
- .gcu .bg-white{background-color:#fff}
235
- .gcu .bg-neutral-900{background-color:#171717}
236
- .gcu .bg-neutral-950{background-color:#0a0a0a}
237
- .gcu .bg-neutral-300{background-color:#d4d4d4}
238
- .gcu .text-white{color:#fff}
239
- .gcu .border-neutral-200{border-color:#e5e5e5}
240
- .gcu .border-neutral-800{border-color:#262626}
241
- .gcu .border-neutral-100{border-color:#f5f5f5}
242
- .gcu .shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04)}
243
- `;
244
- (0, import_react.useEffect)(() => {
245
- if (typeof document === "undefined") return;
246
- const id = "github-contributions-ui-inline";
247
- if (document.getElementById(id)) return;
248
- const style = document.createElement("style");
249
- style.id = id;
250
- style.textContent = STYLES;
251
- document.head.appendChild(style);
252
- }, []);
253
171
  const [allDays, setAllDays] = (0, import_react.useState)(/* @__PURE__ */ new Map());
254
172
  const [years, setYears] = (0, import_react.useState)([]);
255
173
  const [selectedYear, setSelectedYear] = (0, import_react.useState)("last");
@@ -264,21 +182,17 @@ function GithubActivity({ username, theme = "dark", className }) {
264
182
  (0, import_react.useEffect)(() => {
265
183
  if (!username) return;
266
184
  let mounted = true;
267
- setLoading(true);
268
- setError(false);
269
185
  (async () => {
270
- var _a2;
271
186
  try {
187
+ setLoading(true);
272
188
  const res = await fetch(
273
189
  `https://github-contributions-api.jogruber.de/v4/${username}?y=all`
274
190
  );
275
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
191
+ if (!res.ok) throw new Error();
276
192
  const json = await res.json();
277
- const raw = (_a2 = json.contributions) != null ? _a2 : [];
278
- if (!raw.length) throw new Error("empty data");
279
193
  const map = /* @__PURE__ */ new Map();
280
194
  const yearSet = /* @__PURE__ */ new Set();
281
- raw.forEach((c) => {
195
+ json.contributions.forEach((c) => {
282
196
  map.set(c.date, {
283
197
  date: c.date,
284
198
  count: c.count,
@@ -286,17 +200,14 @@ function GithubActivity({ username, theme = "dark", className }) {
286
200
  });
287
201
  yearSet.add(new Date(c.date).getFullYear());
288
202
  });
289
- if (mounted) {
290
- setAllDays(map);
291
- setYears(Array.from(yearSet).sort((a, b) => b - a));
292
- setLoading(false);
293
- }
294
- } catch (err) {
295
- console.warn("GithubActivity fetch error:", err);
296
- if (mounted) {
297
- setError(true);
298
- setLoading(false);
299
- }
203
+ if (!mounted) return;
204
+ setAllDays(map);
205
+ setYears(Array.from(yearSet).sort((a, b) => b - a));
206
+ setError(false);
207
+ } catch {
208
+ if (mounted) setError(true);
209
+ } finally {
210
+ if (mounted) setLoading(false);
300
211
  }
301
212
  })();
302
213
  return () => {
@@ -313,12 +224,11 @@ function GithubActivity({ username, theme = "dark", className }) {
313
224
  }
314
225
  return new Date(d.date).getFullYear() === selectedYear;
315
226
  });
316
- const sum = entries.reduce((s, d) => s + d.count, 0);
227
+ setTotal(entries.reduce((s, d) => s + d.count, 0));
317
228
  const best = entries.reduce(
318
229
  (b, d) => !b || d.count > b.count ? d : b,
319
230
  null
320
231
  );
321
- setTotal(sum);
322
232
  setBestDay(best && best.count > 0 ? best : null);
323
233
  }, [allDays, selectedYear]);
324
234
  const grid = (0, import_react.useMemo)(
@@ -327,19 +237,9 @@ function GithubActivity({ username, theme = "dark", className }) {
327
237
  );
328
238
  const labels = (0, import_react.useMemo)(() => monthLabels(grid), [grid]);
329
239
  const outlineColor = theme === "light" ? "#333" : "#f0f0f0";
330
- const bestDateLabel = bestDay ? new Date(bestDay.date).toLocaleDateString("en-US", {
331
- month: "short",
332
- day: "numeric",
333
- year: "numeric"
334
- }) : null;
335
- const periodLabel = selectedYear === "last" ? " in the last year" : ` in ${selectedYear}`;
336
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: ["gcu w-full font-mono", className].join(" ").trim(), children: [
337
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-500 dark:text-neutral-400", children: [
338
- loading ? "Loading\u2026" : error ? "Unavailable" : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
339
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-semibold text-neutral-700 dark:text-neutral-200", children: total == null ? void 0 : total.toLocaleString() }),
340
- " contributions",
341
- periodLabel
342
- ] }),
240
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: ["w-full font-mono", className].join(" ").trim(), children: [
241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-400", children: [
242
+ loading ? "Loading\u2026" : error ? "Unavailable" : `${total == null ? void 0 : total.toLocaleString()} contributions ${selectedYear === "last" ? "in the last year" : `in ${selectedYear}`}`,
343
243
  bestDay && !loading && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1.5", children: [
344
244
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
345
245
  "span",
@@ -349,16 +249,11 @@ function GithubActivity({ username, theme = "dark", className }) {
349
249
  }
350
250
  ),
351
251
  "Best day:",
352
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "font-semibold text-neutral-700 dark:text-neutral-200", children: [
353
- bestDay.count,
354
- " contributions"
355
- ] }),
356
- "on ",
357
- bestDateLabel
252
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-neutral-200 font-semibold", children: bestDay.count })
358
253
  ] })
359
254
  ] }),
360
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 bg-white dark:bg-neutral-950", children: error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm italic text-neutral-400", children: "GitHub activity unavailable." }) : loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
361
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-x-auto overflow-y-visible pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border border-neutral-800 rounded-xl p-4 bg-neutral-950", children: error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm italic text-neutral-400", children: "GitHub activity unavailable." }) : loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
362
257
  "div",
363
258
  {
364
259
  className: "relative",
@@ -374,11 +269,11 @@ function GithubActivity({ username, theme = "dark", className }) {
374
269
  children: labels.map(({ label, col }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
375
270
  "span",
376
271
  {
377
- className: "absolute text-[11px] select-none text-neutral-500 dark:text-neutral-400",
272
+ className: "absolute text-[11px] text-neutral-400",
378
273
  style: { left: col * STEP },
379
274
  children: label
380
275
  },
381
- `${label}-${col}`
276
+ label + col
382
277
  ))
383
278
  }
384
279
  ),
@@ -386,14 +281,14 @@ function GithubActivity({ username, theme = "dark", className }) {
386
281
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
387
282
  "div",
388
283
  {
389
- className: "flex flex-col gap-[3px] pt-px shrink-0",
284
+ className: "flex flex-col gap-[3px]",
390
285
  style: { width: DAY_COL_W - GAP },
391
286
  children: Array.from({ length: 7 }).map((_, i) => {
392
287
  var _a2;
393
288
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
394
289
  "div",
395
290
  {
396
- className: "h-[13px] text-[10px] leading-[13px] text-right pr-1.5 select-none text-neutral-500 dark:text-neutral-400",
291
+ className: "h-[13px] text-[10px] text-right pr-1.5 text-neutral-400",
397
292
  children: (_a2 = DAY_LABELS[i]) != null ? _a2 : ""
398
293
  },
399
294
  i
@@ -404,10 +299,9 @@ function GithubActivity({ username, theme = "dark", className }) {
404
299
  grid.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-[3px]", children: week.map((day, di) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
405
300
  "div",
406
301
  {
407
- className: "w-[13px] h-[13px] rounded-[3px] transition-transform duration-100 hover:scale-125",
302
+ className: "w-[13px] h-[13px] rounded-[3px] transition-transform hover:scale-125",
408
303
  style: {
409
304
  backgroundColor: day ? colors[day.level] : "transparent",
410
- cursor: day ? "pointer" : "default",
411
305
  outline: bestDay && (day == null ? void 0 : day.date) === bestDay.date ? `2px solid ${outlineColor}` : "none",
412
306
  outlineOffset: "1px"
413
307
  },
@@ -428,8 +322,8 @@ function GithubActivity({ username, theme = "dark", className }) {
428
322
  ]
429
323
  }
430
324
  ) }),
431
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-start gap-1 mt-3", children: [
432
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] text-neutral-500 dark:text-neutral-400 mr-1", children: "Less" }),
325
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1 mt-3 text-[11px] text-neutral-400", children: [
326
+ "Less",
433
327
  colors.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
434
328
  "div",
435
329
  {
@@ -438,9 +332,9 @@ function GithubActivity({ username, theme = "dark", className }) {
438
332
  },
439
333
  i
440
334
  )),
441
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] text-neutral-500 dark:text-neutral-400 ml-1", children: "More" })
335
+ "More"
442
336
  ] }),
443
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-100 dark:border-neutral-800", children: [
337
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-800", children: [
444
338
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] text-neutral-400 mr-1", children: "Year:" }),
445
339
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
446
340
  YearPill,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/GithubActivity.tsx"],"sourcesContent":["import \"./styles.css\";\r\n\r\nexport { default as GithubActivity } from \"./GithubActivity\";","\"use client\";\r\n\r\nimport { memo, useEffect, useState, useMemo } from \"react\";\r\n\r\ntype Theme = \"light\" | \"dark\" | \"blue\" | \"purple\";\r\n\r\ninterface Day {\r\n date: string;\r\n count: number;\r\n level: 0 | 1 | 2 | 3 | 4;\r\n}\r\n\r\ninterface Props {\r\n username: string;\r\n theme?: Theme;\r\n className?: string;\r\n}\r\n\r\n/* ---------- Constants ---------- */\r\n\r\nconst MONTHS = [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dec\",\r\n];\r\nconst DAY_LABELS: Record<number, string> = { 1: \"Mon\", 3: \"Wed\", 5: \"Fri\" };\r\n\r\nconst CELL = 13;\r\nconst GAP = 3;\r\nconst STEP = CELL + GAP;\r\nconst DAY_COL_W = 30;\r\n\r\n/* ---------- Color Themes ---------- */\r\n\r\nconst LIGHT = [\"#ebedf0\", \"#9be9a8\", \"#40c463\", \"#30a14e\", \"#216e39\"];\r\nconst DARK = [\"#21262d\", \"#0e4429\", \"#006d32\", \"#26a641\", \"#39d353\"];\r\nconst BLUE = [\"#21262d\", \"#a3c9ff\", \"#5fa3ff\", \"#2f7bff\", \"#0b5cff\"];\r\nconst PURPLE = [\"#21262d\", \"#d8b4ff\", \"#c084fc\", \"#a855f7\", \"#7e22ce\"];\r\n\r\nconst COLOR_MAP: Record<Theme, string[]> = {\r\n light: LIGHT,\r\n dark: DARK,\r\n blue: BLUE,\r\n purple: PURPLE,\r\n};\r\n\r\n/* ---------- Utilities ---------- */\r\n\r\nfunction toLevel(count: number): 0 | 1 | 2 | 3 | 4 {\r\n if (count === 0) return 0;\r\n if (count <= 3) return 1;\r\n if (count <= 6) return 2;\r\n if (count <= 9) return 3;\r\n return 4;\r\n}\r\n\r\nfunction buildGrid(\r\n dayMap: Map<string, Day>,\r\n year: number | \"last\",\r\n): (Day | null)[][] {\r\n let start: Date;\r\n let end: Date;\r\n\r\n if (year === \"last\") {\r\n end = new Date();\r\n start = new Date(end);\r\n start.setFullYear(start.getFullYear() - 1);\r\n start.setDate(start.getDate() + 1);\r\n } else {\r\n start = new Date(year, 0, 1);\r\n end =\r\n year === new Date().getFullYear() ? new Date() : new Date(year, 11, 31);\r\n }\r\n\r\n start.setDate(start.getDate() - start.getDay());\r\n\r\n const weeks: (Day | null)[][] = [];\r\n const cur = new Date(start);\r\n\r\n while (cur <= end) {\r\n const week: (Day | null)[] = [];\r\n\r\n for (let d = 0; d < 7; d++) {\r\n const iso = cur.toISOString().slice(0, 10);\r\n\r\n if (cur > end) {\r\n week.push(null);\r\n } else {\r\n week.push(\r\n dayMap.get(iso) ?? {\r\n date: iso,\r\n count: 0,\r\n level: 0,\r\n },\r\n );\r\n }\r\n\r\n cur.setDate(cur.getDate() + 1);\r\n }\r\n\r\n weeks.push(week);\r\n }\r\n\r\n return weeks;\r\n}\r\n\r\nfunction monthLabels(grid: (Day | null)[][]) {\r\n const out: { label: string; col: number }[] = [];\r\n let last = -1;\r\n\r\n grid.forEach((week, i) => {\r\n const first = week.find(Boolean);\r\n if (!first) return;\r\n\r\n const m = new Date(first.date).getMonth();\r\n\r\n if (m !== last) {\r\n out.push({ label: MONTHS[m], col: i });\r\n last = m;\r\n }\r\n });\r\n\r\n return out;\r\n}\r\n\r\n/* ---------- UI Components ---------- */\r\n\r\nfunction Tooltip({ day, x, y }: { day: Day; x: number; y: number }) {\r\n const label = new Date(day.date).toLocaleDateString(\"en-US\", {\r\n weekday: \"long\",\r\n year: \"numeric\",\r\n month: \"long\",\r\n day: \"numeric\",\r\n });\r\n\r\n return (\r\n <div\r\n className=\"fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white dark:bg-white dark:text-neutral-900\"\r\n style={{ left: x, top: y - 8 }}\r\n >\r\n <b>\r\n {day.count} contribution{day.count !== 1 ? \"s\" : \"\"}\r\n </b>{\" \"}\r\n · {label}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Skeleton() {\r\n return (\r\n <div className=\"flex gap-[3px] animate-pulse opacity-40\">\r\n {Array.from({ length: 53 }).map((_, w) => (\r\n <div key={w} className=\"flex flex-col gap-[3px]\">\r\n {Array.from({ length: 7 }).map((_, d) => (\r\n <div\r\n key={d}\r\n className=\"w-[13px] h-[13px] rounded-[3px] bg-neutral-300 dark:bg-neutral-700\"\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction YearPill({\r\n label,\r\n active,\r\n onClick,\r\n}: {\r\n label: string;\r\n active: boolean;\r\n onClick: () => void;\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className={[\r\n \"px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150\",\r\n active\r\n ? \"bg-neutral-900 text-white dark:bg-white dark:text-neutral-900\"\r\n : \"bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-700\",\r\n ].join(\" \")}\r\n >\r\n {label}\r\n </button>\r\n );\r\n}\r\n\r\n/* ---------- Main Component ---------- */\r\n\r\nfunction GithubActivity({ username, theme = \"dark\", className }: Props) {\r\n const STYLES = `\r\n .gcu .relative{position:relative}\r\n .gcu .absolute{position:absolute}\r\n .gcu .fixed{position:fixed}\r\n .gcu .z-50{z-index:50}\r\n .gcu .pointer-events-none{pointer-events:none}\r\n .gcu .flex{display:flex}\r\n .gcu .flex-col{flex-direction:column}\r\n .gcu .flex-wrap{flex-wrap:wrap}\r\n .gcu .items-center{align-items:center}\r\n .gcu .justify-start{justify-content:flex-start}\r\n .gcu .inline-block{display:inline-block}\r\n .gcu .w-full{width:100%}\r\n .gcu .w-\\\\[10px\\\\]{width:10px}\r\n .gcu .w-\\\\[13px\\\\]{width:13px}\r\n .gcu .h-\\\\[10px\\\\]{height:10px}\r\n .gcu .h-\\\\[13px\\\\]{height:13px}\r\n .gcu .h-\\\\[18px\\\\]{height:18px}\r\n .gcu .gap-\\\\[3px\\\\]{gap:3px}\r\n .gcu .gap-1{gap:0.25rem}\r\n .gcu .gap-1\\\\.5{gap:0.375rem}\r\n .gcu .gap-x-6{column-gap:1.5rem}\r\n .gcu .gap-y-1{row-gap:0.25rem}\r\n .gcu .mb-4{margin-bottom:1rem}\r\n .gcu .mt-3{margin-top:0.75rem}\r\n .gcu .mt-4{margin-top:1rem}\r\n .gcu .mr-1{margin-right:0.25rem}\r\n .gcu .ml-1{margin-left:0.25rem}\r\n .gcu .p-4{padding:1rem}\r\n .gcu .pt-3{padding-top:0.75rem}\r\n .gcu .pt-px{padding-top:1px}\r\n .gcu .pb-1{padding-bottom:0.25rem}\r\n .gcu .pr-1\\\\.5{padding-right:0.375rem}\r\n .gcu .px-2\\\\.5{padding-left:0.625rem;padding-right:0.625rem}\r\n .gcu .py-1\\\\.5{padding-top:0.375rem;padding-bottom:0.375rem}\r\n .gcu .py-0\\\\.5{padding-top:0.125rem;padding-bottom:0.125rem}\r\n .gcu .rounded-\\\\[2px\\\\]{border-radius:2px}\r\n .gcu .rounded-\\\\[3px\\\\]{border-radius:3px}\r\n .gcu .rounded-md{border-radius:0.375rem}\r\n .gcu .rounded-full{border-radius:9999px}\r\n .gcu .rounded-xl{border-radius:0.75rem}\r\n .gcu .text-right{text-align:right}\r\n .gcu .text-\\\\[10px\\\\]{font-size:10px}\r\n .gcu .text-\\\\[11px\\\\]{font-size:11px}\r\n .gcu .text-xs{font-size:0.75rem}\r\n .gcu .text-sm{font-size:0.875rem}\r\n .gcu .font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}\r\n .gcu .font-medium{font-weight:500}\r\n .gcu .font-semibold{font-weight:600}\r\n .gcu .select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}\r\n .gcu .whitespace-nowrap{white-space:nowrap}\r\n .gcu .overflow-x-auto{overflow-x:auto}\r\n .gcu .overflow-y-visible{overflow-y:visible}\r\n .gcu .border{border-width:1px;border-style:solid;border-color:#e5e5e5}\r\n .gcu .border-t{border-top-width:1px;border-top-style:solid;border-top-color:#e5e5e5}\r\n .gcu .transition-transform{transition-property:transform;transition-timing-function:ease;transition-duration:0.1s}\r\n .gcu .transition-colors{transition-property:color,background-color,border-color;transition-timing-function:ease;transition-duration:0.15s}\r\n .gcu .duration-100{transition-duration:0.1s}\r\n .gcu .duration-150{transition-duration:0.15s}\r\n .gcu .hover\\\\:scale-125:hover{transform:scale(1.25)}\r\n .gcu .text-neutral-500{color:#6b7280}\r\n .gcu .text-neutral-400{color:#9ca3af}\r\n .gcu .text-neutral-700{color:#374151}\r\n .gcu .text-neutral-200{color:#e5e7eb}\r\n .gcu .bg-white{background-color:#fff}\r\n .gcu .bg-neutral-900{background-color:#171717}\r\n .gcu .bg-neutral-950{background-color:#0a0a0a}\r\n .gcu .bg-neutral-300{background-color:#d4d4d4}\r\n .gcu .text-white{color:#fff}\r\n .gcu .border-neutral-200{border-color:#e5e5e5}\r\n .gcu .border-neutral-800{border-color:#262626}\r\n .gcu .border-neutral-100{border-color:#f5f5f5}\r\n .gcu .shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04)}\r\n `;\r\n\r\n useEffect(() => {\r\n if (typeof document === \"undefined\") return;\r\n const id = \"github-contributions-ui-inline\";\r\n if (document.getElementById(id)) return;\r\n const style = document.createElement(\"style\");\r\n style.id = id;\r\n style.textContent = STYLES;\r\n document.head.appendChild(style);\r\n }, []);\r\n const [allDays, setAllDays] = useState<Map<string, Day>>(new Map());\r\n const [years, setYears] = useState<number[]>([]);\r\n const [selectedYear, setSelectedYear] = useState<number | \"last\">(\"last\");\r\n const [total, setTotal] = useState<number | null>(null);\r\n const [bestDay, setBestDay] = useState<Day | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState(false);\r\n const [tip, setTip] = useState<{ day: Day; x: number; y: number } | null>(\r\n null,\r\n );\r\n\r\n const colors = COLOR_MAP[theme] ?? COLOR_MAP.dark;\r\n\r\n /* Fetch Contributions */\r\n\r\n useEffect(() => {\r\n if (!username) return;\r\n\r\n let mounted = true;\r\n setLoading(true);\r\n setError(false);\r\n\r\n (async () => {\r\n try {\r\n const res = await fetch(\r\n `https://github-contributions-api.jogruber.de/v4/${username}?y=all`,\r\n );\r\n\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n\r\n const json = await res.json();\r\n const raw: { date: string; count: number }[] = json.contributions ?? [];\r\n\r\n if (!raw.length) throw new Error(\"empty data\");\r\n\r\n const map = new Map<string, Day>();\r\n const yearSet = new Set<number>();\r\n\r\n raw.forEach((c) => {\r\n map.set(c.date, {\r\n date: c.date,\r\n count: c.count,\r\n level: toLevel(c.count),\r\n });\r\n\r\n yearSet.add(new Date(c.date).getFullYear());\r\n });\r\n\r\n if (mounted) {\r\n setAllDays(map);\r\n setYears(Array.from(yearSet).sort((a, b) => b - a));\r\n setLoading(false);\r\n }\r\n } catch (err) {\r\n console.warn(\"GithubActivity fetch error:\", err);\r\n\r\n if (mounted) {\r\n setError(true);\r\n setLoading(false);\r\n }\r\n }\r\n })();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [username]);\r\n\r\n /* Stats Calculation */\r\n\r\n useEffect(() => {\r\n if (!allDays.size) return;\r\n\r\n const entries = Array.from(allDays.values()).filter((d) => {\r\n if (selectedYear === \"last\") {\r\n const oneYearAgo = new Date();\r\n oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);\r\n return new Date(d.date) >= oneYearAgo;\r\n }\r\n\r\n return new Date(d.date).getFullYear() === selectedYear;\r\n });\r\n\r\n const sum = entries.reduce((s, d) => s + d.count, 0);\r\n\r\n const best = entries.reduce<Day | null>(\r\n (b, d) => (!b || d.count > b.count ? d : b),\r\n null,\r\n );\r\n\r\n setTotal(sum);\r\n setBestDay(best && best.count > 0 ? best : null);\r\n }, [allDays, selectedYear]);\r\n\r\n /* Rendering Helpers */\r\n\r\n const grid = useMemo(\r\n () => (allDays.size ? buildGrid(allDays, selectedYear) : []),\r\n [allDays, selectedYear],\r\n );\r\n\r\n const labels = useMemo(() => monthLabels(grid), [grid]);\r\n\r\n const outlineColor = theme === \"light\" ? \"#333\" : \"#f0f0f0\";\r\n\r\n const bestDateLabel = bestDay\r\n ? new Date(bestDay.date).toLocaleDateString(\"en-US\", {\r\n month: \"short\",\r\n day: \"numeric\",\r\n year: \"numeric\",\r\n })\r\n : null;\r\n\r\n const periodLabel =\r\n selectedYear === \"last\" ? \" in the last year\" : ` in ${selectedYear}`;\r\n\r\n return (\r\n <section className={[\"gcu w-full font-mono\", className].join(\" \").trim()}>\r\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-500 dark:text-neutral-400\">\r\n {loading ? (\r\n \"Loading…\"\r\n ) : error ? (\r\n \"Unavailable\"\r\n ) : (\r\n <>\r\n <span className=\"font-semibold text-neutral-700 dark:text-neutral-200\">\r\n {total?.toLocaleString()}\r\n </span>\r\n {\" contributions\"}\r\n {periodLabel}\r\n </>\r\n )}\r\n\r\n {bestDay && !loading && (\r\n <span className=\"flex items-center gap-1.5\">\r\n <span\r\n className=\"inline-block w-[10px] h-[10px] rounded-[2px]\"\r\n style={{ backgroundColor: colors[4] }}\r\n />\r\n Best day:\r\n <span className=\"font-semibold text-neutral-700 dark:text-neutral-200\">\r\n {bestDay.count} contributions\r\n </span>\r\n on {bestDateLabel}\r\n </span>\r\n )}\r\n </div>\r\n\r\n <div className=\"border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 bg-white dark:bg-neutral-950\">\r\n {error ? (\r\n <p className=\"text-sm italic text-neutral-400\">\r\n GitHub activity unavailable.\r\n </p>\r\n ) : loading ? (\r\n <Skeleton />\r\n ) : (\r\n <>\r\n <div className=\"overflow-x-auto overflow-y-visible pb-1\">\r\n <div\r\n className=\"relative\"\r\n style={{\r\n minWidth: grid.length * STEP + DAY_COL_W + 8,\r\n }}\r\n >\r\n <div\r\n className=\"relative h-[18px] mb-1\"\r\n style={{ marginLeft: DAY_COL_W }}\r\n >\r\n {labels.map(({ label, col }) => (\r\n <span\r\n key={`${label}-${col}`}\r\n className=\"absolute text-[11px] select-none text-neutral-500 dark:text-neutral-400\"\r\n style={{ left: col * STEP }}\r\n >\r\n {label}\r\n </span>\r\n ))}\r\n </div>\r\n\r\n <div className=\"flex gap-[3px]\">\r\n <div\r\n className=\"flex flex-col gap-[3px] pt-px shrink-0\"\r\n style={{ width: DAY_COL_W - GAP }}\r\n >\r\n {Array.from({ length: 7 }).map((_, i) => (\r\n <div\r\n key={i}\r\n className=\"h-[13px] text-[10px] leading-[13px] text-right pr-1.5 select-none text-neutral-500 dark:text-neutral-400\"\r\n >\r\n {DAY_LABELS[i] ?? \"\"}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {grid.map((week, wi) => (\r\n <div key={wi} className=\"flex flex-col gap-[3px]\">\r\n {week.map((day, di) => (\r\n <div\r\n key={di}\r\n className=\"w-[13px] h-[13px] rounded-[3px] transition-transform duration-100 hover:scale-125\"\r\n style={{\r\n backgroundColor: day\r\n ? colors[day.level]\r\n : \"transparent\",\r\n cursor: day ? \"pointer\" : \"default\",\r\n outline:\r\n bestDay && day?.date === bestDay.date\r\n ? `2px solid ${outlineColor}`\r\n : \"none\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!day) return;\r\n\r\n const r = e.currentTarget.getBoundingClientRect();\r\n\r\n setTip({\r\n day,\r\n x: r.left + r.width / 2,\r\n y: r.top,\r\n });\r\n }}\r\n onMouseLeave={() => setTip(null)}\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-start gap-1 mt-3\">\r\n <span className=\"text-[11px] text-neutral-500 dark:text-neutral-400 mr-1\">\r\n Less\r\n </span>\r\n\r\n {colors.map((c, i) => (\r\n <div\r\n key={i}\r\n className=\"w-[13px] h-[13px] rounded-[3px]\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n\r\n <span className=\"text-[11px] text-neutral-500 dark:text-neutral-400 ml-1\">\r\n More\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-100 dark:border-neutral-800\">\r\n <span className=\"text-[11px] text-neutral-400 mr-1\">Year:</span>\r\n\r\n <YearPill\r\n label=\"Last year\"\r\n active={selectedYear === \"last\"}\r\n onClick={() => setSelectedYear(\"last\")}\r\n />\r\n\r\n {years.map((y) => (\r\n <YearPill\r\n key={y}\r\n label={String(y)}\r\n active={selectedYear === y}\r\n onClick={() => setSelectedYear(y)}\r\n />\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {tip && <Tooltip day={tip.day} x={tip.x} y={tip.y} />}\r\n </section>\r\n );\r\n}\r\n\r\nexport default memo(GithubActivity);\r\n"],"mappings":"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","names":["_","_a"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/GithubActivity.tsx"],"sourcesContent":[" \"use client\";\n export { default as GithubActivity } from \"./GithubActivity\";\n","\"use client\";\r\n\r\nimport { memo, useEffect, useState, useMemo } from \"react\";\r\n\r\ntype Theme = \"light\" | \"dark\" | \"blue\" | \"purple\";\r\n\r\ninterface Day {\r\n date: string;\r\n count: number;\r\n level: 0 | 1 | 2 | 3 | 4;\r\n}\r\n\r\ninterface Props {\r\n username: string;\r\n theme?: Theme;\r\n className?: string;\r\n}\r\n\r\n/* ---------- Constants ---------- */\r\n\r\nconst MONTHS = [\r\n \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\r\n \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\r\n];\r\n\r\nconst DAY_LABELS: Record<number, string> = { 1: \"Mon\", 3: \"Wed\", 5: \"Fri\" };\r\n\r\nconst CELL = 13;\r\nconst GAP = 3;\r\nconst STEP = CELL + GAP;\r\nconst DAY_COL_W = 30;\r\n\r\n/* ---------- Graph Color Themes ---------- */\r\n\r\nconst LIGHT = [\"#ebedf0\", \"#9be9a8\", \"#40c463\", \"#30a14e\", \"#216e39\"];\r\nconst DARK = [\"#21262d\", \"#0e4429\", \"#006d32\", \"#26a641\", \"#39d353\"];\r\nconst BLUE = [\"#21262d\", \"#a3c9ff\", \"#5fa3ff\", \"#2f7bff\", \"#0b5cff\"];\r\nconst PURPLE = [\"#21262d\", \"#d8b4ff\", \"#c084fc\", \"#a855f7\", \"#7e22ce\"];\r\n\r\nconst COLOR_MAP: Record<Theme, string[]> = {\r\n light: LIGHT,\r\n dark: DARK,\r\n blue: BLUE,\r\n purple: PURPLE,\r\n};\r\n\r\n/* ---------- Utilities ---------- */\r\n\r\nfunction toLevel(count: number): 0 | 1 | 2 | 3 | 4 {\r\n if (count === 0) return 0;\r\n if (count <= 3) return 1;\r\n if (count <= 6) return 2;\r\n if (count <= 9) return 3;\r\n return 4;\r\n}\r\n\r\nfunction buildGrid(\r\n dayMap: Map<string, Day>,\r\n year: number | \"last\",\r\n): (Day | null)[][] {\r\n let start: Date;\r\n let end: Date;\r\n\r\n if (year === \"last\") {\r\n end = new Date();\r\n start = new Date(end);\r\n start.setFullYear(start.getFullYear() - 1);\r\n start.setDate(start.getDate() + 1);\r\n } else {\r\n start = new Date(year, 0, 1);\r\n end =\r\n year === new Date().getFullYear()\r\n ? new Date()\r\n : new Date(year, 11, 31);\r\n }\r\n\r\n start.setDate(start.getDate() - start.getDay());\r\n\r\n const weeks: (Day | null)[][] = [];\r\n const cur = new Date(start);\r\n\r\n while (cur <= end) {\r\n const week: (Day | null)[] = [];\r\n\r\n for (let d = 0; d < 7; d++) {\r\n const iso = cur.toISOString().slice(0, 10);\r\n\r\n if (cur > end) week.push(null);\r\n else {\r\n week.push(\r\n dayMap.get(iso) ?? {\r\n date: iso,\r\n count: 0,\r\n level: 0,\r\n },\r\n );\r\n }\r\n\r\n cur.setDate(cur.getDate() + 1);\r\n }\r\n\r\n weeks.push(week);\r\n }\r\n\r\n return weeks;\r\n}\r\n\r\nfunction monthLabels(grid: (Day | null)[][]) {\r\n const out: { label: string; col: number }[] = [];\r\n let last = -1;\r\n\r\n grid.forEach((week, i) => {\r\n const first = week.find(Boolean);\r\n if (!first) return;\r\n\r\n const m = new Date(first.date).getMonth();\r\n\r\n if (m !== last) {\r\n out.push({ label: MONTHS[m], col: i });\r\n last = m;\r\n }\r\n });\r\n\r\n return out;\r\n}\r\n\r\n/* ---------- UI Components ---------- */\r\n\r\nfunction Tooltip({ day, x, y }: { day: Day; x: number; y: number }) {\r\n const label = new Date(day.date).toLocaleDateString(\"en-US\", {\r\n weekday: \"long\",\r\n year: \"numeric\",\r\n month: \"long\",\r\n day: \"numeric\",\r\n });\r\n\r\n return (\r\n <div\r\n className=\"fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white\"\r\n style={{ left: x, top: y - 8 }}\r\n >\r\n <b>\r\n {day.count} contribution{day.count !== 1 ? \"s\" : \"\"}\r\n </b>{\" \"}\r\n · {label}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Skeleton() {\r\n return (\r\n <div className=\"flex gap-[3px] animate-pulse opacity-40\">\r\n {Array.from({ length: 53 }).map((_, w) => (\r\n <div key={w} className=\"flex flex-col gap-[3px]\">\r\n {Array.from({ length: 7 }).map((_, d) => (\r\n <div\r\n key={d}\r\n className=\"w-[13px] h-[13px] rounded-[3px] bg-neutral-700\"\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction YearPill({\r\n label,\r\n active,\r\n onClick,\r\n}: {\r\n label: string;\r\n active: boolean;\r\n onClick: () => void;\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className={[\r\n \"px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150\",\r\n active\r\n ? \"bg-white text-neutral-900\"\r\n : \"bg-neutral-800 text-neutral-400 hover:bg-neutral-700\",\r\n ].join(\" \")}\r\n >\r\n {label}\r\n </button>\r\n );\r\n}\r\n\r\n/* ---------- Main Component ---------- */\r\n\r\nfunction GithubActivity({ username, theme = \"dark\", className }: Props) {\r\n const [allDays, setAllDays] = useState<Map<string, Day>>(new Map());\r\n const [years, setYears] = useState<number[]>([]);\r\n const [selectedYear, setSelectedYear] =\r\n useState<number | \"last\">(\"last\");\r\n\r\n const [total, setTotal] = useState<number | null>(null);\r\n const [bestDay, setBestDay] = useState<Day | null>(null);\r\n\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState(false);\r\n\r\n const [tip, setTip] = useState<{ day: Day; x: number; y: number } | null>(\r\n null,\r\n );\r\n\r\n const colors = COLOR_MAP[theme] ?? COLOR_MAP.dark;\r\n\r\n /* ---------- Fetch ---------- */\r\n\r\n useEffect(() => {\r\n if (!username) return;\r\n\r\n let mounted = true;\r\n\r\n (async () => {\r\n try {\r\n setLoading(true);\r\n const res = await fetch(\r\n `https://github-contributions-api.jogruber.de/v4/${username}?y=all`,\r\n );\r\n\r\n if (!res.ok) throw new Error();\r\n\r\n const json = await res.json();\r\n\r\n const map = new Map<string, Day>();\r\n const yearSet = new Set<number>();\r\n\r\n json.contributions.forEach((c: any) => {\r\n map.set(c.date, {\r\n date: c.date,\r\n count: c.count,\r\n level: toLevel(c.count),\r\n });\r\n\r\n yearSet.add(new Date(c.date).getFullYear());\r\n });\r\n\r\n if (!mounted) return;\r\n\r\n setAllDays(map);\r\n setYears(Array.from(yearSet).sort((a, b) => b - a));\r\n setError(false);\r\n } catch {\r\n if (mounted) setError(true);\r\n } finally {\r\n if (mounted) setLoading(false);\r\n }\r\n })();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [username]);\r\n\r\n /* ---------- Stats ---------- */\r\n\r\n useEffect(() => {\r\n if (!allDays.size) return;\r\n\r\n const entries = Array.from(allDays.values()).filter((d) => {\r\n if (selectedYear === \"last\") {\r\n const oneYearAgo = new Date();\r\n oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);\r\n return new Date(d.date) >= oneYearAgo;\r\n }\r\n return new Date(d.date).getFullYear() === selectedYear;\r\n });\r\n\r\n setTotal(entries.reduce((s, d) => s + d.count, 0));\r\n\r\n const best = entries.reduce<Day | null>(\r\n (b, d) => (!b || d.count > b.count ? d : b),\r\n null,\r\n );\r\n\r\n setBestDay(best && best.count > 0 ? best : null);\r\n }, [allDays, selectedYear]);\r\n\r\n /* ---------- Rendering ---------- */\r\n\r\n const grid = useMemo(\r\n () => (allDays.size ? buildGrid(allDays, selectedYear) : []),\r\n [allDays, selectedYear],\r\n );\r\n\r\n const labels = useMemo(() => monthLabels(grid), [grid]);\r\n\r\n const outlineColor = theme === \"light\" ? \"#333\" : \"#f0f0f0\";\r\n\r\n return (\r\n <section className={[\"w-full font-mono\", className].join(\" \").trim()}>\r\n {/* Stats */}\r\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-400\">\r\n {loading\r\n ? \"Loading…\"\r\n : error\r\n ? \"Unavailable\"\r\n : `${total?.toLocaleString()} contributions ${selectedYear === \"last\"\r\n ? \"in the last year\"\r\n : `in ${selectedYear}`\r\n }`}\r\n\r\n {bestDay && !loading && (\r\n <span className=\"flex items-center gap-1.5\">\r\n <span\r\n className=\"inline-block w-[10px] h-[10px] rounded-[2px]\"\r\n style={{ backgroundColor: colors[4] }}\r\n />\r\n Best day:\r\n <span className=\"text-neutral-200 font-semibold\">\r\n {bestDay.count}\r\n </span>\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Main Card */}\r\n <div className=\"border border-neutral-800 rounded-xl p-4 bg-neutral-950\">\r\n {error ? (\r\n <p className=\"text-sm italic text-neutral-400\">\r\n GitHub activity unavailable.\r\n </p>\r\n ) : loading ? (\r\n <Skeleton />\r\n ) : (\r\n <>\r\n <div className=\"overflow-x-auto pb-1\">\r\n <div\r\n className=\"relative\"\r\n style={{\r\n minWidth: grid.length * STEP + DAY_COL_W + 8,\r\n }}\r\n >\r\n {/* Months */}\r\n <div\r\n className=\"relative h-[18px] mb-1\"\r\n style={{ marginLeft: DAY_COL_W }}\r\n >\r\n {labels.map(({ label, col }) => (\r\n <span\r\n key={label + col}\r\n className=\"absolute text-[11px] text-neutral-400\"\r\n style={{ left: col * STEP }}\r\n >\r\n {label}\r\n </span>\r\n ))}\r\n </div>\r\n\r\n {/* Grid */}\r\n <div className=\"flex gap-[3px]\">\r\n <div\r\n className=\"flex flex-col gap-[3px]\"\r\n style={{ width: DAY_COL_W - GAP }}\r\n >\r\n {Array.from({ length: 7 }).map((_, i) => (\r\n <div\r\n key={i}\r\n className=\"h-[13px] text-[10px] text-right pr-1.5 text-neutral-400\"\r\n >\r\n {DAY_LABELS[i] ?? \"\"}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {grid.map((week, wi) => (\r\n <div key={wi} className=\"flex flex-col gap-[3px]\">\r\n {week.map((day, di) => (\r\n <div\r\n key={di}\r\n className=\"w-[13px] h-[13px] rounded-[3px] transition-transform hover:scale-125\"\r\n style={{\r\n backgroundColor: day\r\n ? colors[day.level]\r\n : \"transparent\",\r\n outline:\r\n bestDay && day?.date === bestDay.date\r\n ? `2px solid ${outlineColor}`\r\n : \"none\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!day) return;\r\n const r =\r\n e.currentTarget.getBoundingClientRect();\r\n setTip({\r\n day,\r\n x: r.left + r.width / 2,\r\n y: r.top,\r\n });\r\n }}\r\n onMouseLeave={() => setTip(null)}\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"flex items-center gap-1 mt-3 text-[11px] text-neutral-400\">\r\n Less\r\n {colors.map((c, i) => (\r\n <div\r\n key={i}\r\n className=\"w-[13px] h-[13px] rounded-[3px]\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n More\r\n </div>\r\n\r\n {/* Years */}\r\n <div className=\"flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-800\">\r\n <span className=\"text-[11px] text-neutral-400 mr-1\">\r\n Year:\r\n </span>\r\n\r\n <YearPill\r\n label=\"Last year\"\r\n active={selectedYear === \"last\"}\r\n onClick={() => setSelectedYear(\"last\")}\r\n />\r\n\r\n {years.map((y) => (\r\n <YearPill\r\n key={y}\r\n label={String(y)}\r\n active={selectedYear === y}\r\n onClick={() => setSelectedYear(y)}\r\n />\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {tip && <Tooltip day={tip.day} x={tip.x} y={tip.y} />}\r\n </section>\r\n );\r\n}\r\n\r\nexport default memo(GithubActivity);"],"mappings":"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","names":["_","_a"]}
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ "use client";
2
+ "use client";
3
+
1
4
  // src/GithubActivity.tsx
2
5
  import { memo, useEffect, useState, useMemo } from "react";
3
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -57,9 +60,8 @@ function buildGrid(dayMap, year) {
57
60
  const week = [];
58
61
  for (let d = 0; d < 7; d++) {
59
62
  const iso = cur.toISOString().slice(0, 10);
60
- if (cur > end) {
61
- week.push(null);
62
- } else {
63
+ if (cur > end) week.push(null);
64
+ else {
63
65
  week.push(
64
66
  (_a = dayMap.get(iso)) != null ? _a : {
65
67
  date: iso,
@@ -98,7 +100,7 @@ function Tooltip({ day, x, y }) {
98
100
  return /* @__PURE__ */ jsxs(
99
101
  "div",
100
102
  {
101
- className: "fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white dark:bg-white dark:text-neutral-900",
103
+ className: "fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white",
102
104
  style: { left: x, top: y - 8 },
103
105
  children: [
104
106
  /* @__PURE__ */ jsxs("b", { children: [
@@ -117,7 +119,7 @@ function Skeleton() {
117
119
  return /* @__PURE__ */ jsx("div", { className: "flex gap-[3px] animate-pulse opacity-40", children: Array.from({ length: 53 }).map((_, w) => /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[3px]", children: Array.from({ length: 7 }).map((_2, d) => /* @__PURE__ */ jsx(
118
120
  "div",
119
121
  {
120
- className: "w-[13px] h-[13px] rounded-[3px] bg-neutral-300 dark:bg-neutral-700"
122
+ className: "w-[13px] h-[13px] rounded-[3px] bg-neutral-700"
121
123
  },
122
124
  d
123
125
  )) }, w)) });
@@ -133,7 +135,7 @@ function YearPill({
133
135
  onClick,
134
136
  className: [
135
137
  "px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150",
136
- active ? "bg-neutral-900 text-white dark:bg-white dark:text-neutral-900" : "bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-700"
138
+ active ? "bg-white text-neutral-900" : "bg-neutral-800 text-neutral-400 hover:bg-neutral-700"
137
139
  ].join(" "),
138
140
  children: label
139
141
  }
@@ -141,89 +143,6 @@ function YearPill({
141
143
  }
142
144
  function GithubActivity({ username, theme = "dark", className }) {
143
145
  var _a;
144
- const STYLES = `
145
- .gcu .relative{position:relative}
146
- .gcu .absolute{position:absolute}
147
- .gcu .fixed{position:fixed}
148
- .gcu .z-50{z-index:50}
149
- .gcu .pointer-events-none{pointer-events:none}
150
- .gcu .flex{display:flex}
151
- .gcu .flex-col{flex-direction:column}
152
- .gcu .flex-wrap{flex-wrap:wrap}
153
- .gcu .items-center{align-items:center}
154
- .gcu .justify-start{justify-content:flex-start}
155
- .gcu .inline-block{display:inline-block}
156
- .gcu .w-full{width:100%}
157
- .gcu .w-\\[10px\\]{width:10px}
158
- .gcu .w-\\[13px\\]{width:13px}
159
- .gcu .h-\\[10px\\]{height:10px}
160
- .gcu .h-\\[13px\\]{height:13px}
161
- .gcu .h-\\[18px\\]{height:18px}
162
- .gcu .gap-\\[3px\\]{gap:3px}
163
- .gcu .gap-1{gap:0.25rem}
164
- .gcu .gap-1\\.5{gap:0.375rem}
165
- .gcu .gap-x-6{column-gap:1.5rem}
166
- .gcu .gap-y-1{row-gap:0.25rem}
167
- .gcu .mb-4{margin-bottom:1rem}
168
- .gcu .mt-3{margin-top:0.75rem}
169
- .gcu .mt-4{margin-top:1rem}
170
- .gcu .mr-1{margin-right:0.25rem}
171
- .gcu .ml-1{margin-left:0.25rem}
172
- .gcu .p-4{padding:1rem}
173
- .gcu .pt-3{padding-top:0.75rem}
174
- .gcu .pt-px{padding-top:1px}
175
- .gcu .pb-1{padding-bottom:0.25rem}
176
- .gcu .pr-1\\.5{padding-right:0.375rem}
177
- .gcu .px-2\\.5{padding-left:0.625rem;padding-right:0.625rem}
178
- .gcu .py-1\\.5{padding-top:0.375rem;padding-bottom:0.375rem}
179
- .gcu .py-0\\.5{padding-top:0.125rem;padding-bottom:0.125rem}
180
- .gcu .rounded-\\[2px\\]{border-radius:2px}
181
- .gcu .rounded-\\[3px\\]{border-radius:3px}
182
- .gcu .rounded-md{border-radius:0.375rem}
183
- .gcu .rounded-full{border-radius:9999px}
184
- .gcu .rounded-xl{border-radius:0.75rem}
185
- .gcu .text-right{text-align:right}
186
- .gcu .text-\\[10px\\]{font-size:10px}
187
- .gcu .text-\\[11px\\]{font-size:11px}
188
- .gcu .text-xs{font-size:0.75rem}
189
- .gcu .text-sm{font-size:0.875rem}
190
- .gcu .font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}
191
- .gcu .font-medium{font-weight:500}
192
- .gcu .font-semibold{font-weight:600}
193
- .gcu .select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}
194
- .gcu .whitespace-nowrap{white-space:nowrap}
195
- .gcu .overflow-x-auto{overflow-x:auto}
196
- .gcu .overflow-y-visible{overflow-y:visible}
197
- .gcu .border{border-width:1px;border-style:solid;border-color:#e5e5e5}
198
- .gcu .border-t{border-top-width:1px;border-top-style:solid;border-top-color:#e5e5e5}
199
- .gcu .transition-transform{transition-property:transform;transition-timing-function:ease;transition-duration:0.1s}
200
- .gcu .transition-colors{transition-property:color,background-color,border-color;transition-timing-function:ease;transition-duration:0.15s}
201
- .gcu .duration-100{transition-duration:0.1s}
202
- .gcu .duration-150{transition-duration:0.15s}
203
- .gcu .hover\\:scale-125:hover{transform:scale(1.25)}
204
- .gcu .text-neutral-500{color:#6b7280}
205
- .gcu .text-neutral-400{color:#9ca3af}
206
- .gcu .text-neutral-700{color:#374151}
207
- .gcu .text-neutral-200{color:#e5e7eb}
208
- .gcu .bg-white{background-color:#fff}
209
- .gcu .bg-neutral-900{background-color:#171717}
210
- .gcu .bg-neutral-950{background-color:#0a0a0a}
211
- .gcu .bg-neutral-300{background-color:#d4d4d4}
212
- .gcu .text-white{color:#fff}
213
- .gcu .border-neutral-200{border-color:#e5e5e5}
214
- .gcu .border-neutral-800{border-color:#262626}
215
- .gcu .border-neutral-100{border-color:#f5f5f5}
216
- .gcu .shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04)}
217
- `;
218
- useEffect(() => {
219
- if (typeof document === "undefined") return;
220
- const id = "github-contributions-ui-inline";
221
- if (document.getElementById(id)) return;
222
- const style = document.createElement("style");
223
- style.id = id;
224
- style.textContent = STYLES;
225
- document.head.appendChild(style);
226
- }, []);
227
146
  const [allDays, setAllDays] = useState(/* @__PURE__ */ new Map());
228
147
  const [years, setYears] = useState([]);
229
148
  const [selectedYear, setSelectedYear] = useState("last");
@@ -238,21 +157,17 @@ function GithubActivity({ username, theme = "dark", className }) {
238
157
  useEffect(() => {
239
158
  if (!username) return;
240
159
  let mounted = true;
241
- setLoading(true);
242
- setError(false);
243
160
  (async () => {
244
- var _a2;
245
161
  try {
162
+ setLoading(true);
246
163
  const res = await fetch(
247
164
  `https://github-contributions-api.jogruber.de/v4/${username}?y=all`
248
165
  );
249
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
166
+ if (!res.ok) throw new Error();
250
167
  const json = await res.json();
251
- const raw = (_a2 = json.contributions) != null ? _a2 : [];
252
- if (!raw.length) throw new Error("empty data");
253
168
  const map = /* @__PURE__ */ new Map();
254
169
  const yearSet = /* @__PURE__ */ new Set();
255
- raw.forEach((c) => {
170
+ json.contributions.forEach((c) => {
256
171
  map.set(c.date, {
257
172
  date: c.date,
258
173
  count: c.count,
@@ -260,17 +175,14 @@ function GithubActivity({ username, theme = "dark", className }) {
260
175
  });
261
176
  yearSet.add(new Date(c.date).getFullYear());
262
177
  });
263
- if (mounted) {
264
- setAllDays(map);
265
- setYears(Array.from(yearSet).sort((a, b) => b - a));
266
- setLoading(false);
267
- }
268
- } catch (err) {
269
- console.warn("GithubActivity fetch error:", err);
270
- if (mounted) {
271
- setError(true);
272
- setLoading(false);
273
- }
178
+ if (!mounted) return;
179
+ setAllDays(map);
180
+ setYears(Array.from(yearSet).sort((a, b) => b - a));
181
+ setError(false);
182
+ } catch {
183
+ if (mounted) setError(true);
184
+ } finally {
185
+ if (mounted) setLoading(false);
274
186
  }
275
187
  })();
276
188
  return () => {
@@ -287,12 +199,11 @@ function GithubActivity({ username, theme = "dark", className }) {
287
199
  }
288
200
  return new Date(d.date).getFullYear() === selectedYear;
289
201
  });
290
- const sum = entries.reduce((s, d) => s + d.count, 0);
202
+ setTotal(entries.reduce((s, d) => s + d.count, 0));
291
203
  const best = entries.reduce(
292
204
  (b, d) => !b || d.count > b.count ? d : b,
293
205
  null
294
206
  );
295
- setTotal(sum);
296
207
  setBestDay(best && best.count > 0 ? best : null);
297
208
  }, [allDays, selectedYear]);
298
209
  const grid = useMemo(
@@ -301,19 +212,9 @@ function GithubActivity({ username, theme = "dark", className }) {
301
212
  );
302
213
  const labels = useMemo(() => monthLabels(grid), [grid]);
303
214
  const outlineColor = theme === "light" ? "#333" : "#f0f0f0";
304
- const bestDateLabel = bestDay ? new Date(bestDay.date).toLocaleDateString("en-US", {
305
- month: "short",
306
- day: "numeric",
307
- year: "numeric"
308
- }) : null;
309
- const periodLabel = selectedYear === "last" ? " in the last year" : ` in ${selectedYear}`;
310
- return /* @__PURE__ */ jsxs("section", { className: ["gcu w-full font-mono", className].join(" ").trim(), children: [
311
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-500 dark:text-neutral-400", children: [
312
- loading ? "Loading\u2026" : error ? "Unavailable" : /* @__PURE__ */ jsxs(Fragment, { children: [
313
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-neutral-700 dark:text-neutral-200", children: total == null ? void 0 : total.toLocaleString() }),
314
- " contributions",
315
- periodLabel
316
- ] }),
215
+ return /* @__PURE__ */ jsxs("section", { className: ["w-full font-mono", className].join(" ").trim(), children: [
216
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-400", children: [
217
+ loading ? "Loading\u2026" : error ? "Unavailable" : `${total == null ? void 0 : total.toLocaleString()} contributions ${selectedYear === "last" ? "in the last year" : `in ${selectedYear}`}`,
317
218
  bestDay && !loading && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
318
219
  /* @__PURE__ */ jsx(
319
220
  "span",
@@ -323,16 +224,11 @@ function GithubActivity({ username, theme = "dark", className }) {
323
224
  }
324
225
  ),
325
226
  "Best day:",
326
- /* @__PURE__ */ jsxs("span", { className: "font-semibold text-neutral-700 dark:text-neutral-200", children: [
327
- bestDay.count,
328
- " contributions"
329
- ] }),
330
- "on ",
331
- bestDateLabel
227
+ /* @__PURE__ */ jsx("span", { className: "text-neutral-200 font-semibold", children: bestDay.count })
332
228
  ] })
333
229
  ] }),
334
- /* @__PURE__ */ jsx("div", { className: "border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 bg-white dark:bg-neutral-950", children: error ? /* @__PURE__ */ jsx("p", { className: "text-sm italic text-neutral-400", children: "GitHub activity unavailable." }) : loading ? /* @__PURE__ */ jsx(Skeleton, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
335
- /* @__PURE__ */ jsx("div", { className: "overflow-x-auto overflow-y-visible pb-1", children: /* @__PURE__ */ jsxs(
230
+ /* @__PURE__ */ jsx("div", { className: "border border-neutral-800 rounded-xl p-4 bg-neutral-950", children: error ? /* @__PURE__ */ jsx("p", { className: "text-sm italic text-neutral-400", children: "GitHub activity unavailable." }) : loading ? /* @__PURE__ */ jsx(Skeleton, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
231
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxs(
336
232
  "div",
337
233
  {
338
234
  className: "relative",
@@ -348,11 +244,11 @@ function GithubActivity({ username, theme = "dark", className }) {
348
244
  children: labels.map(({ label, col }) => /* @__PURE__ */ jsx(
349
245
  "span",
350
246
  {
351
- className: "absolute text-[11px] select-none text-neutral-500 dark:text-neutral-400",
247
+ className: "absolute text-[11px] text-neutral-400",
352
248
  style: { left: col * STEP },
353
249
  children: label
354
250
  },
355
- `${label}-${col}`
251
+ label + col
356
252
  ))
357
253
  }
358
254
  ),
@@ -360,14 +256,14 @@ function GithubActivity({ username, theme = "dark", className }) {
360
256
  /* @__PURE__ */ jsx(
361
257
  "div",
362
258
  {
363
- className: "flex flex-col gap-[3px] pt-px shrink-0",
259
+ className: "flex flex-col gap-[3px]",
364
260
  style: { width: DAY_COL_W - GAP },
365
261
  children: Array.from({ length: 7 }).map((_, i) => {
366
262
  var _a2;
367
263
  return /* @__PURE__ */ jsx(
368
264
  "div",
369
265
  {
370
- className: "h-[13px] text-[10px] leading-[13px] text-right pr-1.5 select-none text-neutral-500 dark:text-neutral-400",
266
+ className: "h-[13px] text-[10px] text-right pr-1.5 text-neutral-400",
371
267
  children: (_a2 = DAY_LABELS[i]) != null ? _a2 : ""
372
268
  },
373
269
  i
@@ -378,10 +274,9 @@ function GithubActivity({ username, theme = "dark", className }) {
378
274
  grid.map((week, wi) => /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[3px]", children: week.map((day, di) => /* @__PURE__ */ jsx(
379
275
  "div",
380
276
  {
381
- className: "w-[13px] h-[13px] rounded-[3px] transition-transform duration-100 hover:scale-125",
277
+ className: "w-[13px] h-[13px] rounded-[3px] transition-transform hover:scale-125",
382
278
  style: {
383
279
  backgroundColor: day ? colors[day.level] : "transparent",
384
- cursor: day ? "pointer" : "default",
385
280
  outline: bestDay && (day == null ? void 0 : day.date) === bestDay.date ? `2px solid ${outlineColor}` : "none",
386
281
  outlineOffset: "1px"
387
282
  },
@@ -402,8 +297,8 @@ function GithubActivity({ username, theme = "dark", className }) {
402
297
  ]
403
298
  }
404
299
  ) }),
405
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-start gap-1 mt-3", children: [
406
- /* @__PURE__ */ jsx("span", { className: "text-[11px] text-neutral-500 dark:text-neutral-400 mr-1", children: "Less" }),
300
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 mt-3 text-[11px] text-neutral-400", children: [
301
+ "Less",
407
302
  colors.map((c, i) => /* @__PURE__ */ jsx(
408
303
  "div",
409
304
  {
@@ -412,9 +307,9 @@ function GithubActivity({ username, theme = "dark", className }) {
412
307
  },
413
308
  i
414
309
  )),
415
- /* @__PURE__ */ jsx("span", { className: "text-[11px] text-neutral-500 dark:text-neutral-400 ml-1", children: "More" })
310
+ "More"
416
311
  ] }),
417
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-100 dark:border-neutral-800", children: [
312
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-800", children: [
418
313
  /* @__PURE__ */ jsx("span", { className: "text-[11px] text-neutral-400 mr-1", children: "Year:" }),
419
314
  /* @__PURE__ */ jsx(
420
315
  YearPill,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/GithubActivity.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { memo, useEffect, useState, useMemo } from \"react\";\r\n\r\ntype Theme = \"light\" | \"dark\" | \"blue\" | \"purple\";\r\n\r\ninterface Day {\r\n date: string;\r\n count: number;\r\n level: 0 | 1 | 2 | 3 | 4;\r\n}\r\n\r\ninterface Props {\r\n username: string;\r\n theme?: Theme;\r\n className?: string;\r\n}\r\n\r\n/* ---------- Constants ---------- */\r\n\r\nconst MONTHS = [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dec\",\r\n];\r\nconst DAY_LABELS: Record<number, string> = { 1: \"Mon\", 3: \"Wed\", 5: \"Fri\" };\r\n\r\nconst CELL = 13;\r\nconst GAP = 3;\r\nconst STEP = CELL + GAP;\r\nconst DAY_COL_W = 30;\r\n\r\n/* ---------- Color Themes ---------- */\r\n\r\nconst LIGHT = [\"#ebedf0\", \"#9be9a8\", \"#40c463\", \"#30a14e\", \"#216e39\"];\r\nconst DARK = [\"#21262d\", \"#0e4429\", \"#006d32\", \"#26a641\", \"#39d353\"];\r\nconst BLUE = [\"#21262d\", \"#a3c9ff\", \"#5fa3ff\", \"#2f7bff\", \"#0b5cff\"];\r\nconst PURPLE = [\"#21262d\", \"#d8b4ff\", \"#c084fc\", \"#a855f7\", \"#7e22ce\"];\r\n\r\nconst COLOR_MAP: Record<Theme, string[]> = {\r\n light: LIGHT,\r\n dark: DARK,\r\n blue: BLUE,\r\n purple: PURPLE,\r\n};\r\n\r\n/* ---------- Utilities ---------- */\r\n\r\nfunction toLevel(count: number): 0 | 1 | 2 | 3 | 4 {\r\n if (count === 0) return 0;\r\n if (count <= 3) return 1;\r\n if (count <= 6) return 2;\r\n if (count <= 9) return 3;\r\n return 4;\r\n}\r\n\r\nfunction buildGrid(\r\n dayMap: Map<string, Day>,\r\n year: number | \"last\",\r\n): (Day | null)[][] {\r\n let start: Date;\r\n let end: Date;\r\n\r\n if (year === \"last\") {\r\n end = new Date();\r\n start = new Date(end);\r\n start.setFullYear(start.getFullYear() - 1);\r\n start.setDate(start.getDate() + 1);\r\n } else {\r\n start = new Date(year, 0, 1);\r\n end =\r\n year === new Date().getFullYear() ? new Date() : new Date(year, 11, 31);\r\n }\r\n\r\n start.setDate(start.getDate() - start.getDay());\r\n\r\n const weeks: (Day | null)[][] = [];\r\n const cur = new Date(start);\r\n\r\n while (cur <= end) {\r\n const week: (Day | null)[] = [];\r\n\r\n for (let d = 0; d < 7; d++) {\r\n const iso = cur.toISOString().slice(0, 10);\r\n\r\n if (cur > end) {\r\n week.push(null);\r\n } else {\r\n week.push(\r\n dayMap.get(iso) ?? {\r\n date: iso,\r\n count: 0,\r\n level: 0,\r\n },\r\n );\r\n }\r\n\r\n cur.setDate(cur.getDate() + 1);\r\n }\r\n\r\n weeks.push(week);\r\n }\r\n\r\n return weeks;\r\n}\r\n\r\nfunction monthLabels(grid: (Day | null)[][]) {\r\n const out: { label: string; col: number }[] = [];\r\n let last = -1;\r\n\r\n grid.forEach((week, i) => {\r\n const first = week.find(Boolean);\r\n if (!first) return;\r\n\r\n const m = new Date(first.date).getMonth();\r\n\r\n if (m !== last) {\r\n out.push({ label: MONTHS[m], col: i });\r\n last = m;\r\n }\r\n });\r\n\r\n return out;\r\n}\r\n\r\n/* ---------- UI Components ---------- */\r\n\r\nfunction Tooltip({ day, x, y }: { day: Day; x: number; y: number }) {\r\n const label = new Date(day.date).toLocaleDateString(\"en-US\", {\r\n weekday: \"long\",\r\n year: \"numeric\",\r\n month: \"long\",\r\n day: \"numeric\",\r\n });\r\n\r\n return (\r\n <div\r\n className=\"fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white dark:bg-white dark:text-neutral-900\"\r\n style={{ left: x, top: y - 8 }}\r\n >\r\n <b>\r\n {day.count} contribution{day.count !== 1 ? \"s\" : \"\"}\r\n </b>{\" \"}\r\n · {label}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Skeleton() {\r\n return (\r\n <div className=\"flex gap-[3px] animate-pulse opacity-40\">\r\n {Array.from({ length: 53 }).map((_, w) => (\r\n <div key={w} className=\"flex flex-col gap-[3px]\">\r\n {Array.from({ length: 7 }).map((_, d) => (\r\n <div\r\n key={d}\r\n className=\"w-[13px] h-[13px] rounded-[3px] bg-neutral-300 dark:bg-neutral-700\"\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction YearPill({\r\n label,\r\n active,\r\n onClick,\r\n}: {\r\n label: string;\r\n active: boolean;\r\n onClick: () => void;\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className={[\r\n \"px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150\",\r\n active\r\n ? \"bg-neutral-900 text-white dark:bg-white dark:text-neutral-900\"\r\n : \"bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-700\",\r\n ].join(\" \")}\r\n >\r\n {label}\r\n </button>\r\n );\r\n}\r\n\r\n/* ---------- Main Component ---------- */\r\n\r\nfunction GithubActivity({ username, theme = \"dark\", className }: Props) {\r\n const STYLES = `\r\n .gcu .relative{position:relative}\r\n .gcu .absolute{position:absolute}\r\n .gcu .fixed{position:fixed}\r\n .gcu .z-50{z-index:50}\r\n .gcu .pointer-events-none{pointer-events:none}\r\n .gcu .flex{display:flex}\r\n .gcu .flex-col{flex-direction:column}\r\n .gcu .flex-wrap{flex-wrap:wrap}\r\n .gcu .items-center{align-items:center}\r\n .gcu .justify-start{justify-content:flex-start}\r\n .gcu .inline-block{display:inline-block}\r\n .gcu .w-full{width:100%}\r\n .gcu .w-\\\\[10px\\\\]{width:10px}\r\n .gcu .w-\\\\[13px\\\\]{width:13px}\r\n .gcu .h-\\\\[10px\\\\]{height:10px}\r\n .gcu .h-\\\\[13px\\\\]{height:13px}\r\n .gcu .h-\\\\[18px\\\\]{height:18px}\r\n .gcu .gap-\\\\[3px\\\\]{gap:3px}\r\n .gcu .gap-1{gap:0.25rem}\r\n .gcu .gap-1\\\\.5{gap:0.375rem}\r\n .gcu .gap-x-6{column-gap:1.5rem}\r\n .gcu .gap-y-1{row-gap:0.25rem}\r\n .gcu .mb-4{margin-bottom:1rem}\r\n .gcu .mt-3{margin-top:0.75rem}\r\n .gcu .mt-4{margin-top:1rem}\r\n .gcu .mr-1{margin-right:0.25rem}\r\n .gcu .ml-1{margin-left:0.25rem}\r\n .gcu .p-4{padding:1rem}\r\n .gcu .pt-3{padding-top:0.75rem}\r\n .gcu .pt-px{padding-top:1px}\r\n .gcu .pb-1{padding-bottom:0.25rem}\r\n .gcu .pr-1\\\\.5{padding-right:0.375rem}\r\n .gcu .px-2\\\\.5{padding-left:0.625rem;padding-right:0.625rem}\r\n .gcu .py-1\\\\.5{padding-top:0.375rem;padding-bottom:0.375rem}\r\n .gcu .py-0\\\\.5{padding-top:0.125rem;padding-bottom:0.125rem}\r\n .gcu .rounded-\\\\[2px\\\\]{border-radius:2px}\r\n .gcu .rounded-\\\\[3px\\\\]{border-radius:3px}\r\n .gcu .rounded-md{border-radius:0.375rem}\r\n .gcu .rounded-full{border-radius:9999px}\r\n .gcu .rounded-xl{border-radius:0.75rem}\r\n .gcu .text-right{text-align:right}\r\n .gcu .text-\\\\[10px\\\\]{font-size:10px}\r\n .gcu .text-\\\\[11px\\\\]{font-size:11px}\r\n .gcu .text-xs{font-size:0.75rem}\r\n .gcu .text-sm{font-size:0.875rem}\r\n .gcu .font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}\r\n .gcu .font-medium{font-weight:500}\r\n .gcu .font-semibold{font-weight:600}\r\n .gcu .select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}\r\n .gcu .whitespace-nowrap{white-space:nowrap}\r\n .gcu .overflow-x-auto{overflow-x:auto}\r\n .gcu .overflow-y-visible{overflow-y:visible}\r\n .gcu .border{border-width:1px;border-style:solid;border-color:#e5e5e5}\r\n .gcu .border-t{border-top-width:1px;border-top-style:solid;border-top-color:#e5e5e5}\r\n .gcu .transition-transform{transition-property:transform;transition-timing-function:ease;transition-duration:0.1s}\r\n .gcu .transition-colors{transition-property:color,background-color,border-color;transition-timing-function:ease;transition-duration:0.15s}\r\n .gcu .duration-100{transition-duration:0.1s}\r\n .gcu .duration-150{transition-duration:0.15s}\r\n .gcu .hover\\\\:scale-125:hover{transform:scale(1.25)}\r\n .gcu .text-neutral-500{color:#6b7280}\r\n .gcu .text-neutral-400{color:#9ca3af}\r\n .gcu .text-neutral-700{color:#374151}\r\n .gcu .text-neutral-200{color:#e5e7eb}\r\n .gcu .bg-white{background-color:#fff}\r\n .gcu .bg-neutral-900{background-color:#171717}\r\n .gcu .bg-neutral-950{background-color:#0a0a0a}\r\n .gcu .bg-neutral-300{background-color:#d4d4d4}\r\n .gcu .text-white{color:#fff}\r\n .gcu .border-neutral-200{border-color:#e5e5e5}\r\n .gcu .border-neutral-800{border-color:#262626}\r\n .gcu .border-neutral-100{border-color:#f5f5f5}\r\n .gcu .shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04)}\r\n `;\r\n\r\n useEffect(() => {\r\n if (typeof document === \"undefined\") return;\r\n const id = \"github-contributions-ui-inline\";\r\n if (document.getElementById(id)) return;\r\n const style = document.createElement(\"style\");\r\n style.id = id;\r\n style.textContent = STYLES;\r\n document.head.appendChild(style);\r\n }, []);\r\n const [allDays, setAllDays] = useState<Map<string, Day>>(new Map());\r\n const [years, setYears] = useState<number[]>([]);\r\n const [selectedYear, setSelectedYear] = useState<number | \"last\">(\"last\");\r\n const [total, setTotal] = useState<number | null>(null);\r\n const [bestDay, setBestDay] = useState<Day | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState(false);\r\n const [tip, setTip] = useState<{ day: Day; x: number; y: number } | null>(\r\n null,\r\n );\r\n\r\n const colors = COLOR_MAP[theme] ?? COLOR_MAP.dark;\r\n\r\n /* Fetch Contributions */\r\n\r\n useEffect(() => {\r\n if (!username) return;\r\n\r\n let mounted = true;\r\n setLoading(true);\r\n setError(false);\r\n\r\n (async () => {\r\n try {\r\n const res = await fetch(\r\n `https://github-contributions-api.jogruber.de/v4/${username}?y=all`,\r\n );\r\n\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n\r\n const json = await res.json();\r\n const raw: { date: string; count: number }[] = json.contributions ?? [];\r\n\r\n if (!raw.length) throw new Error(\"empty data\");\r\n\r\n const map = new Map<string, Day>();\r\n const yearSet = new Set<number>();\r\n\r\n raw.forEach((c) => {\r\n map.set(c.date, {\r\n date: c.date,\r\n count: c.count,\r\n level: toLevel(c.count),\r\n });\r\n\r\n yearSet.add(new Date(c.date).getFullYear());\r\n });\r\n\r\n if (mounted) {\r\n setAllDays(map);\r\n setYears(Array.from(yearSet).sort((a, b) => b - a));\r\n setLoading(false);\r\n }\r\n } catch (err) {\r\n console.warn(\"GithubActivity fetch error:\", err);\r\n\r\n if (mounted) {\r\n setError(true);\r\n setLoading(false);\r\n }\r\n }\r\n })();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [username]);\r\n\r\n /* Stats Calculation */\r\n\r\n useEffect(() => {\r\n if (!allDays.size) return;\r\n\r\n const entries = Array.from(allDays.values()).filter((d) => {\r\n if (selectedYear === \"last\") {\r\n const oneYearAgo = new Date();\r\n oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);\r\n return new Date(d.date) >= oneYearAgo;\r\n }\r\n\r\n return new Date(d.date).getFullYear() === selectedYear;\r\n });\r\n\r\n const sum = entries.reduce((s, d) => s + d.count, 0);\r\n\r\n const best = entries.reduce<Day | null>(\r\n (b, d) => (!b || d.count > b.count ? d : b),\r\n null,\r\n );\r\n\r\n setTotal(sum);\r\n setBestDay(best && best.count > 0 ? best : null);\r\n }, [allDays, selectedYear]);\r\n\r\n /* Rendering Helpers */\r\n\r\n const grid = useMemo(\r\n () => (allDays.size ? buildGrid(allDays, selectedYear) : []),\r\n [allDays, selectedYear],\r\n );\r\n\r\n const labels = useMemo(() => monthLabels(grid), [grid]);\r\n\r\n const outlineColor = theme === \"light\" ? \"#333\" : \"#f0f0f0\";\r\n\r\n const bestDateLabel = bestDay\r\n ? new Date(bestDay.date).toLocaleDateString(\"en-US\", {\r\n month: \"short\",\r\n day: \"numeric\",\r\n year: \"numeric\",\r\n })\r\n : null;\r\n\r\n const periodLabel =\r\n selectedYear === \"last\" ? \" in the last year\" : ` in ${selectedYear}`;\r\n\r\n return (\r\n <section className={[\"gcu w-full font-mono\", className].join(\" \").trim()}>\r\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-500 dark:text-neutral-400\">\r\n {loading ? (\r\n \"Loading…\"\r\n ) : error ? (\r\n \"Unavailable\"\r\n ) : (\r\n <>\r\n <span className=\"font-semibold text-neutral-700 dark:text-neutral-200\">\r\n {total?.toLocaleString()}\r\n </span>\r\n {\" contributions\"}\r\n {periodLabel}\r\n </>\r\n )}\r\n\r\n {bestDay && !loading && (\r\n <span className=\"flex items-center gap-1.5\">\r\n <span\r\n className=\"inline-block w-[10px] h-[10px] rounded-[2px]\"\r\n style={{ backgroundColor: colors[4] }}\r\n />\r\n Best day:\r\n <span className=\"font-semibold text-neutral-700 dark:text-neutral-200\">\r\n {bestDay.count} contributions\r\n </span>\r\n on {bestDateLabel}\r\n </span>\r\n )}\r\n </div>\r\n\r\n <div className=\"border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 bg-white dark:bg-neutral-950\">\r\n {error ? (\r\n <p className=\"text-sm italic text-neutral-400\">\r\n GitHub activity unavailable.\r\n </p>\r\n ) : loading ? (\r\n <Skeleton />\r\n ) : (\r\n <>\r\n <div className=\"overflow-x-auto overflow-y-visible pb-1\">\r\n <div\r\n className=\"relative\"\r\n style={{\r\n minWidth: grid.length * STEP + DAY_COL_W + 8,\r\n }}\r\n >\r\n <div\r\n className=\"relative h-[18px] mb-1\"\r\n style={{ marginLeft: DAY_COL_W }}\r\n >\r\n {labels.map(({ label, col }) => (\r\n <span\r\n key={`${label}-${col}`}\r\n className=\"absolute text-[11px] select-none text-neutral-500 dark:text-neutral-400\"\r\n style={{ left: col * STEP }}\r\n >\r\n {label}\r\n </span>\r\n ))}\r\n </div>\r\n\r\n <div className=\"flex gap-[3px]\">\r\n <div\r\n className=\"flex flex-col gap-[3px] pt-px shrink-0\"\r\n style={{ width: DAY_COL_W - GAP }}\r\n >\r\n {Array.from({ length: 7 }).map((_, i) => (\r\n <div\r\n key={i}\r\n className=\"h-[13px] text-[10px] leading-[13px] text-right pr-1.5 select-none text-neutral-500 dark:text-neutral-400\"\r\n >\r\n {DAY_LABELS[i] ?? \"\"}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {grid.map((week, wi) => (\r\n <div key={wi} className=\"flex flex-col gap-[3px]\">\r\n {week.map((day, di) => (\r\n <div\r\n key={di}\r\n className=\"w-[13px] h-[13px] rounded-[3px] transition-transform duration-100 hover:scale-125\"\r\n style={{\r\n backgroundColor: day\r\n ? colors[day.level]\r\n : \"transparent\",\r\n cursor: day ? \"pointer\" : \"default\",\r\n outline:\r\n bestDay && day?.date === bestDay.date\r\n ? `2px solid ${outlineColor}`\r\n : \"none\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!day) return;\r\n\r\n const r = e.currentTarget.getBoundingClientRect();\r\n\r\n setTip({\r\n day,\r\n x: r.left + r.width / 2,\r\n y: r.top,\r\n });\r\n }}\r\n onMouseLeave={() => setTip(null)}\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-start gap-1 mt-3\">\r\n <span className=\"text-[11px] text-neutral-500 dark:text-neutral-400 mr-1\">\r\n Less\r\n </span>\r\n\r\n {colors.map((c, i) => (\r\n <div\r\n key={i}\r\n className=\"w-[13px] h-[13px] rounded-[3px]\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n\r\n <span className=\"text-[11px] text-neutral-500 dark:text-neutral-400 ml-1\">\r\n More\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-100 dark:border-neutral-800\">\r\n <span className=\"text-[11px] text-neutral-400 mr-1\">Year:</span>\r\n\r\n <YearPill\r\n label=\"Last year\"\r\n active={selectedYear === \"last\"}\r\n onClick={() => setSelectedYear(\"last\")}\r\n />\r\n\r\n {years.map((y) => (\r\n <YearPill\r\n key={y}\r\n label={String(y)}\r\n active={selectedYear === y}\r\n onClick={() => setSelectedYear(y)}\r\n />\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {tip && <Tooltip day={tip.day} x={tip.x} y={tip.y} />}\r\n </section>\r\n );\r\n}\r\n\r\nexport default memo(GithubActivity);\r\n"],"mappings":"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","names":["_","_a"]}
1
+ {"version":3,"sources":["../src/GithubActivity.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { memo, useEffect, useState, useMemo } from \"react\";\r\n\r\ntype Theme = \"light\" | \"dark\" | \"blue\" | \"purple\";\r\n\r\ninterface Day {\r\n date: string;\r\n count: number;\r\n level: 0 | 1 | 2 | 3 | 4;\r\n}\r\n\r\ninterface Props {\r\n username: string;\r\n theme?: Theme;\r\n className?: string;\r\n}\r\n\r\n/* ---------- Constants ---------- */\r\n\r\nconst MONTHS = [\r\n \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\r\n \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\r\n];\r\n\r\nconst DAY_LABELS: Record<number, string> = { 1: \"Mon\", 3: \"Wed\", 5: \"Fri\" };\r\n\r\nconst CELL = 13;\r\nconst GAP = 3;\r\nconst STEP = CELL + GAP;\r\nconst DAY_COL_W = 30;\r\n\r\n/* ---------- Graph Color Themes ---------- */\r\n\r\nconst LIGHT = [\"#ebedf0\", \"#9be9a8\", \"#40c463\", \"#30a14e\", \"#216e39\"];\r\nconst DARK = [\"#21262d\", \"#0e4429\", \"#006d32\", \"#26a641\", \"#39d353\"];\r\nconst BLUE = [\"#21262d\", \"#a3c9ff\", \"#5fa3ff\", \"#2f7bff\", \"#0b5cff\"];\r\nconst PURPLE = [\"#21262d\", \"#d8b4ff\", \"#c084fc\", \"#a855f7\", \"#7e22ce\"];\r\n\r\nconst COLOR_MAP: Record<Theme, string[]> = {\r\n light: LIGHT,\r\n dark: DARK,\r\n blue: BLUE,\r\n purple: PURPLE,\r\n};\r\n\r\n/* ---------- Utilities ---------- */\r\n\r\nfunction toLevel(count: number): 0 | 1 | 2 | 3 | 4 {\r\n if (count === 0) return 0;\r\n if (count <= 3) return 1;\r\n if (count <= 6) return 2;\r\n if (count <= 9) return 3;\r\n return 4;\r\n}\r\n\r\nfunction buildGrid(\r\n dayMap: Map<string, Day>,\r\n year: number | \"last\",\r\n): (Day | null)[][] {\r\n let start: Date;\r\n let end: Date;\r\n\r\n if (year === \"last\") {\r\n end = new Date();\r\n start = new Date(end);\r\n start.setFullYear(start.getFullYear() - 1);\r\n start.setDate(start.getDate() + 1);\r\n } else {\r\n start = new Date(year, 0, 1);\r\n end =\r\n year === new Date().getFullYear()\r\n ? new Date()\r\n : new Date(year, 11, 31);\r\n }\r\n\r\n start.setDate(start.getDate() - start.getDay());\r\n\r\n const weeks: (Day | null)[][] = [];\r\n const cur = new Date(start);\r\n\r\n while (cur <= end) {\r\n const week: (Day | null)[] = [];\r\n\r\n for (let d = 0; d < 7; d++) {\r\n const iso = cur.toISOString().slice(0, 10);\r\n\r\n if (cur > end) week.push(null);\r\n else {\r\n week.push(\r\n dayMap.get(iso) ?? {\r\n date: iso,\r\n count: 0,\r\n level: 0,\r\n },\r\n );\r\n }\r\n\r\n cur.setDate(cur.getDate() + 1);\r\n }\r\n\r\n weeks.push(week);\r\n }\r\n\r\n return weeks;\r\n}\r\n\r\nfunction monthLabels(grid: (Day | null)[][]) {\r\n const out: { label: string; col: number }[] = [];\r\n let last = -1;\r\n\r\n grid.forEach((week, i) => {\r\n const first = week.find(Boolean);\r\n if (!first) return;\r\n\r\n const m = new Date(first.date).getMonth();\r\n\r\n if (m !== last) {\r\n out.push({ label: MONTHS[m], col: i });\r\n last = m;\r\n }\r\n });\r\n\r\n return out;\r\n}\r\n\r\n/* ---------- UI Components ---------- */\r\n\r\nfunction Tooltip({ day, x, y }: { day: Day; x: number; y: number }) {\r\n const label = new Date(day.date).toLocaleDateString(\"en-US\", {\r\n weekday: \"long\",\r\n year: \"numeric\",\r\n month: \"long\",\r\n day: \"numeric\",\r\n });\r\n\r\n return (\r\n <div\r\n className=\"fixed z-50 pointer-events-none -translate-x-1/2 -translate-y-full px-2.5 py-1.5 rounded-md text-xs font-mono whitespace-nowrap shadow-xl bg-neutral-900 text-white\"\r\n style={{ left: x, top: y - 8 }}\r\n >\r\n <b>\r\n {day.count} contribution{day.count !== 1 ? \"s\" : \"\"}\r\n </b>{\" \"}\r\n · {label}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Skeleton() {\r\n return (\r\n <div className=\"flex gap-[3px] animate-pulse opacity-40\">\r\n {Array.from({ length: 53 }).map((_, w) => (\r\n <div key={w} className=\"flex flex-col gap-[3px]\">\r\n {Array.from({ length: 7 }).map((_, d) => (\r\n <div\r\n key={d}\r\n className=\"w-[13px] h-[13px] rounded-[3px] bg-neutral-700\"\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction YearPill({\r\n label,\r\n active,\r\n onClick,\r\n}: {\r\n label: string;\r\n active: boolean;\r\n onClick: () => void;\r\n}) {\r\n return (\r\n <button\r\n onClick={onClick}\r\n className={[\r\n \"px-2.5 py-0.5 rounded-full text-[11px] font-medium transition-colors duration-150\",\r\n active\r\n ? \"bg-white text-neutral-900\"\r\n : \"bg-neutral-800 text-neutral-400 hover:bg-neutral-700\",\r\n ].join(\" \")}\r\n >\r\n {label}\r\n </button>\r\n );\r\n}\r\n\r\n/* ---------- Main Component ---------- */\r\n\r\nfunction GithubActivity({ username, theme = \"dark\", className }: Props) {\r\n const [allDays, setAllDays] = useState<Map<string, Day>>(new Map());\r\n const [years, setYears] = useState<number[]>([]);\r\n const [selectedYear, setSelectedYear] =\r\n useState<number | \"last\">(\"last\");\r\n\r\n const [total, setTotal] = useState<number | null>(null);\r\n const [bestDay, setBestDay] = useState<Day | null>(null);\r\n\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState(false);\r\n\r\n const [tip, setTip] = useState<{ day: Day; x: number; y: number } | null>(\r\n null,\r\n );\r\n\r\n const colors = COLOR_MAP[theme] ?? COLOR_MAP.dark;\r\n\r\n /* ---------- Fetch ---------- */\r\n\r\n useEffect(() => {\r\n if (!username) return;\r\n\r\n let mounted = true;\r\n\r\n (async () => {\r\n try {\r\n setLoading(true);\r\n const res = await fetch(\r\n `https://github-contributions-api.jogruber.de/v4/${username}?y=all`,\r\n );\r\n\r\n if (!res.ok) throw new Error();\r\n\r\n const json = await res.json();\r\n\r\n const map = new Map<string, Day>();\r\n const yearSet = new Set<number>();\r\n\r\n json.contributions.forEach((c: any) => {\r\n map.set(c.date, {\r\n date: c.date,\r\n count: c.count,\r\n level: toLevel(c.count),\r\n });\r\n\r\n yearSet.add(new Date(c.date).getFullYear());\r\n });\r\n\r\n if (!mounted) return;\r\n\r\n setAllDays(map);\r\n setYears(Array.from(yearSet).sort((a, b) => b - a));\r\n setError(false);\r\n } catch {\r\n if (mounted) setError(true);\r\n } finally {\r\n if (mounted) setLoading(false);\r\n }\r\n })();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [username]);\r\n\r\n /* ---------- Stats ---------- */\r\n\r\n useEffect(() => {\r\n if (!allDays.size) return;\r\n\r\n const entries = Array.from(allDays.values()).filter((d) => {\r\n if (selectedYear === \"last\") {\r\n const oneYearAgo = new Date();\r\n oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);\r\n return new Date(d.date) >= oneYearAgo;\r\n }\r\n return new Date(d.date).getFullYear() === selectedYear;\r\n });\r\n\r\n setTotal(entries.reduce((s, d) => s + d.count, 0));\r\n\r\n const best = entries.reduce<Day | null>(\r\n (b, d) => (!b || d.count > b.count ? d : b),\r\n null,\r\n );\r\n\r\n setBestDay(best && best.count > 0 ? best : null);\r\n }, [allDays, selectedYear]);\r\n\r\n /* ---------- Rendering ---------- */\r\n\r\n const grid = useMemo(\r\n () => (allDays.size ? buildGrid(allDays, selectedYear) : []),\r\n [allDays, selectedYear],\r\n );\r\n\r\n const labels = useMemo(() => monthLabels(grid), [grid]);\r\n\r\n const outlineColor = theme === \"light\" ? \"#333\" : \"#f0f0f0\";\r\n\r\n return (\r\n <section className={[\"w-full font-mono\", className].join(\" \").trim()}>\r\n {/* Stats */}\r\n <div className=\"flex flex-wrap items-center gap-x-6 gap-y-1 mb-4 text-xs text-neutral-400\">\r\n {loading\r\n ? \"Loading…\"\r\n : error\r\n ? \"Unavailable\"\r\n : `${total?.toLocaleString()} contributions ${selectedYear === \"last\"\r\n ? \"in the last year\"\r\n : `in ${selectedYear}`\r\n }`}\r\n\r\n {bestDay && !loading && (\r\n <span className=\"flex items-center gap-1.5\">\r\n <span\r\n className=\"inline-block w-[10px] h-[10px] rounded-[2px]\"\r\n style={{ backgroundColor: colors[4] }}\r\n />\r\n Best day:\r\n <span className=\"text-neutral-200 font-semibold\">\r\n {bestDay.count}\r\n </span>\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Main Card */}\r\n <div className=\"border border-neutral-800 rounded-xl p-4 bg-neutral-950\">\r\n {error ? (\r\n <p className=\"text-sm italic text-neutral-400\">\r\n GitHub activity unavailable.\r\n </p>\r\n ) : loading ? (\r\n <Skeleton />\r\n ) : (\r\n <>\r\n <div className=\"overflow-x-auto pb-1\">\r\n <div\r\n className=\"relative\"\r\n style={{\r\n minWidth: grid.length * STEP + DAY_COL_W + 8,\r\n }}\r\n >\r\n {/* Months */}\r\n <div\r\n className=\"relative h-[18px] mb-1\"\r\n style={{ marginLeft: DAY_COL_W }}\r\n >\r\n {labels.map(({ label, col }) => (\r\n <span\r\n key={label + col}\r\n className=\"absolute text-[11px] text-neutral-400\"\r\n style={{ left: col * STEP }}\r\n >\r\n {label}\r\n </span>\r\n ))}\r\n </div>\r\n\r\n {/* Grid */}\r\n <div className=\"flex gap-[3px]\">\r\n <div\r\n className=\"flex flex-col gap-[3px]\"\r\n style={{ width: DAY_COL_W - GAP }}\r\n >\r\n {Array.from({ length: 7 }).map((_, i) => (\r\n <div\r\n key={i}\r\n className=\"h-[13px] text-[10px] text-right pr-1.5 text-neutral-400\"\r\n >\r\n {DAY_LABELS[i] ?? \"\"}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {grid.map((week, wi) => (\r\n <div key={wi} className=\"flex flex-col gap-[3px]\">\r\n {week.map((day, di) => (\r\n <div\r\n key={di}\r\n className=\"w-[13px] h-[13px] rounded-[3px] transition-transform hover:scale-125\"\r\n style={{\r\n backgroundColor: day\r\n ? colors[day.level]\r\n : \"transparent\",\r\n outline:\r\n bestDay && day?.date === bestDay.date\r\n ? `2px solid ${outlineColor}`\r\n : \"none\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!day) return;\r\n const r =\r\n e.currentTarget.getBoundingClientRect();\r\n setTip({\r\n day,\r\n x: r.left + r.width / 2,\r\n y: r.top,\r\n });\r\n }}\r\n onMouseLeave={() => setTip(null)}\r\n />\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"flex items-center gap-1 mt-3 text-[11px] text-neutral-400\">\r\n Less\r\n {colors.map((c, i) => (\r\n <div\r\n key={i}\r\n className=\"w-[13px] h-[13px] rounded-[3px]\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n More\r\n </div>\r\n\r\n {/* Years */}\r\n <div className=\"flex flex-wrap items-center gap-1.5 mt-4 pt-3 border-t border-neutral-800\">\r\n <span className=\"text-[11px] text-neutral-400 mr-1\">\r\n Year:\r\n </span>\r\n\r\n <YearPill\r\n label=\"Last year\"\r\n active={selectedYear === \"last\"}\r\n onClick={() => setSelectedYear(\"last\")}\r\n />\r\n\r\n {years.map((y) => (\r\n <YearPill\r\n key={y}\r\n label={String(y)}\r\n active={selectedYear === y}\r\n onClick={() => setSelectedYear(y)}\r\n />\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {tip && <Tooltip day={tip.day} x={tip.x} y={tip.y} />}\r\n </section>\r\n );\r\n}\r\n\r\nexport default memo(GithubActivity);"],"mappings":"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","names":["_","_a"]}
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-outline-style:solid;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.z-50{z-index:50}.flex{display:flex}.grid{display:grid}.inline-block{display:inline-block}.h-\[10px\]{height:10px}.h-\[13px\]{height:13px}.h-\[18px\]{height:18px}.w-\[10px\]{width:10px}.w-\[13px\]{width:13px}.w-full{width:100%}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.gap-\[3px\]{gap:3px}.overflow-x-auto{overflow-x:auto}.overflow-y-visible{overflow-y:visible}.rounded-\[2px\]{border-radius:2px}.rounded-\[3px\]{border-radius:3px}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.pt-px{padding-top:1px}.text-right{text-align:right}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-\[13px\]{--tw-leading:13px;line-height:13px}.whitespace-nowrap{white-space:nowrap}.italic{font-style:italic}.opacity-40{opacity:.4}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:scale-125:hover{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-outline-style:solid;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.z-50{z-index:50}.flex{display:flex}.grid{display:grid}.inline-block{display:inline-block}.h-\[10px\]{height:10px}.h-\[13px\]{height:13px}.h-\[18px\]{height:18px}.w-\[10px\]{width:10px}.w-\[13px\]{width:13px}.w-full{width:100%}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-\[3px\]{gap:3px}.overflow-x-auto{overflow-x:auto}.rounded-\[2px\]{border-radius:2px}.rounded-\[3px\]{border-radius:3px}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.text-right{text-align:right}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.whitespace-nowrap{white-space:nowrap}.italic{font-style:italic}.opacity-40{opacity:.4}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.duration-150{--tw-duration:.15s;transition-duration:.15s}@media (hover:hover){.hover\:scale-125:hover{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-contributions-ui",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "GitHub contributions graph React component",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/dist/index.css DELETED
@@ -1,200 +0,0 @@
1
- /* src/styles.css */
2
- @layer properties;
3
- .pointer-events-none {
4
- pointer-events: none;
5
- }
6
- .absolute {
7
- position: absolute;
8
- }
9
- .fixed {
10
- position: fixed;
11
- }
12
- .relative {
13
- position: relative;
14
- }
15
- .z-50 {
16
- z-index: 50;
17
- }
18
- .flex {
19
- display: flex;
20
- }
21
- .grid {
22
- display: grid;
23
- }
24
- .inline-block {
25
- display: inline-block;
26
- }
27
- .h-\[10px\] {
28
- height: 10px;
29
- }
30
- .h-\[13px\] {
31
- height: 13px;
32
- }
33
- .h-\[18px\] {
34
- height: 18px;
35
- }
36
- .w-\[10px\] {
37
- width: 10px;
38
- }
39
- .w-\[13px\] {
40
- width: 13px;
41
- }
42
- .w-full {
43
- width: 100%;
44
- }
45
- .shrink-0 {
46
- flex-shrink: 0;
47
- }
48
- .-translate-x-1\/2 {
49
- --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
50
- translate: var(--tw-translate-x) var(--tw-translate-y);
51
- }
52
- .-translate-y-full {
53
- --tw-translate-y: -100%;
54
- translate: var(--tw-translate-x) var(--tw-translate-y);
55
- }
56
- .flex-col {
57
- flex-direction: column;
58
- }
59
- .flex-wrap {
60
- flex-wrap: wrap;
61
- }
62
- .items-center {
63
- align-items: center;
64
- }
65
- .justify-start {
66
- justify-content: flex-start;
67
- }
68
- .gap-\[3px\] {
69
- gap: 3px;
70
- }
71
- .overflow-x-auto {
72
- overflow-x: auto;
73
- }
74
- .overflow-y-visible {
75
- overflow-y: visible;
76
- }
77
- .rounded-\[2px\] {
78
- border-radius: 2px;
79
- }
80
- .rounded-\[3px\] {
81
- border-radius: 3px;
82
- }
83
- .rounded-full {
84
- border-radius: calc(infinity * 1px);
85
- }
86
- .border {
87
- border-style: var(--tw-border-style);
88
- border-width: 1px;
89
- }
90
- .border-t {
91
- border-top-style: var(--tw-border-style);
92
- border-top-width: 1px;
93
- }
94
- .pt-px {
95
- padding-top: 1px;
96
- }
97
- .text-right {
98
- text-align: right;
99
- }
100
- .text-\[10px\] {
101
- font-size: 10px;
102
- }
103
- .text-\[11px\] {
104
- font-size: 11px;
105
- }
106
- .leading-\[13px\] {
107
- --tw-leading: 13px;
108
- line-height: 13px;
109
- }
110
- .whitespace-nowrap {
111
- white-space: nowrap;
112
- }
113
- .italic {
114
- font-style: italic;
115
- }
116
- .opacity-40 {
117
- opacity: 40%;
118
- }
119
- .outline {
120
- outline-style: var(--tw-outline-style);
121
- outline-width: 1px;
122
- }
123
- .transition-colors {
124
- transition-property:
125
- color,
126
- background-color,
127
- border-color,
128
- outline-color,
129
- text-decoration-color,
130
- fill,
131
- stroke,
132
- --tw-gradient-from,
133
- --tw-gradient-via,
134
- --tw-gradient-to;
135
- transition-timing-function: var(--tw-ease, ease);
136
- transition-duration: var(--tw-duration, 0s);
137
- }
138
- .transition-transform {
139
- transition-property:
140
- transform,
141
- translate,
142
- scale,
143
- rotate;
144
- transition-timing-function: var(--tw-ease, ease);
145
- transition-duration: var(--tw-duration, 0s);
146
- }
147
- .duration-100 {
148
- --tw-duration: 100ms;
149
- transition-duration: 100ms;
150
- }
151
- .duration-150 {
152
- --tw-duration: 150ms;
153
- transition-duration: 150ms;
154
- }
155
- .select-none {
156
- -webkit-user-select: none;
157
- -moz-user-select: none;
158
- user-select: none;
159
- }
160
- .hover\:scale-125 {
161
- &:hover {
162
- @media (hover: hover) {
163
- --tw-scale-x: 125%;
164
- --tw-scale-y: 125%;
165
- --tw-scale-z: 125%;
166
- scale: var(--tw-scale-x) var(--tw-scale-y);
167
- }
168
- }
169
- }
170
- @property --tw-translate-x { syntax: "*"; inherits: false; initial-value: 0; }
171
- @property --tw-translate-y { syntax: "*"; inherits: false; initial-value: 0; }
172
- @property --tw-translate-z { syntax: "*"; inherits: false; initial-value: 0; }
173
- @property --tw-border-style { syntax: "*"; inherits: false; initial-value: solid; }
174
- @property --tw-leading { syntax: "*"; inherits: false; }
175
- @property --tw-outline-style { syntax: "*"; inherits: false; initial-value: solid; }
176
- @property --tw-duration { syntax: "*"; inherits: false; }
177
- @property --tw-scale-x { syntax: "*"; inherits: false; initial-value: 1; }
178
- @property --tw-scale-y { syntax: "*"; inherits: false; initial-value: 1; }
179
- @property --tw-scale-z { syntax: "*"; inherits: false; initial-value: 1; }
180
- @layer properties {
181
- @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
182
- *,
183
- ::before,
184
- ::after,
185
- ::backdrop {
186
- --tw-translate-x: 0;
187
- --tw-translate-y: 0;
188
- --tw-translate-z: 0;
189
- --tw-border-style: solid;
190
- --tw-leading: initial;
191
- --tw-outline-style: solid;
192
- --tw-duration: initial;
193
- --tw-scale-x: 1;
194
- --tw-scale-y: 1;
195
- --tw-scale-z: 1;
196
- }
197
- }
198
- }
199
- /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
200
- /*# sourceMappingURL=index.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */\n@layer properties;\n.pointer-events-none {\n pointer-events: none;\n}\n.absolute {\n position: absolute;\n}\n.fixed {\n position: fixed;\n}\n.relative {\n position: relative;\n}\n.z-50 {\n z-index: 50;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.inline-block {\n display: inline-block;\n}\n.h-\\[10px\\] {\n height: 10px;\n}\n.h-\\[13px\\] {\n height: 13px;\n}\n.h-\\[18px\\] {\n height: 18px;\n}\n.w-\\[10px\\] {\n width: 10px;\n}\n.w-\\[13px\\] {\n width: 13px;\n}\n.w-full {\n width: 100%;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.-translate-y-full {\n --tw-translate-y: -100%;\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-wrap {\n flex-wrap: wrap;\n}\n.items-center {\n align-items: center;\n}\n.justify-start {\n justify-content: flex-start;\n}\n.gap-\\[3px\\] {\n gap: 3px;\n}\n.overflow-x-auto {\n overflow-x: auto;\n}\n.overflow-y-visible {\n overflow-y: visible;\n}\n.rounded-\\[2px\\] {\n border-radius: 2px;\n}\n.rounded-\\[3px\\] {\n border-radius: 3px;\n}\n.rounded-full {\n border-radius: calc(infinity * 1px);\n}\n.border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n}\n.border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n}\n.pt-px {\n padding-top: 1px;\n}\n.text-right {\n text-align: right;\n}\n.text-\\[10px\\] {\n font-size: 10px;\n}\n.text-\\[11px\\] {\n font-size: 11px;\n}\n.leading-\\[13px\\] {\n --tw-leading: 13px;\n line-height: 13px;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.italic {\n font-style: italic;\n}\n.opacity-40 {\n opacity: 40%;\n}\n.outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n}\n.transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, ease);\n transition-duration: var(--tw-duration, 0s);\n}\n.transition-transform {\n transition-property: transform, translate, scale, rotate;\n transition-timing-function: var(--tw-ease, ease);\n transition-duration: var(--tw-duration, 0s);\n}\n.duration-100 {\n --tw-duration: 100ms;\n transition-duration: 100ms;\n}\n.duration-150 {\n --tw-duration: 150ms;\n transition-duration: 150ms;\n}\n.select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.hover\\:scale-125 {\n &:hover {\n @media (hover: hover) {\n --tw-scale-x: 125%;\n --tw-scale-y: 125%;\n --tw-scale-z: 125%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n}\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-duration {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-outline-style: solid;\n --tw-duration: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}"],"mappings":";AACA;AACA,CAAC;AACC,kBAAgB;AAClB;AACA,CAAC;AACC,YAAU;AACZ;AACA,CAAC;AACC,YAAU;AACZ;AACA,CAAC;AACC,YAAU;AACZ;AACA,CAAC;AACC,WAAS;AACX;AACA,CAAC;AACC,WAAS;AACX;AACA,CAAC;AACC,WAAS;AACX;AACA,CAAC;AACC,WAAS;AACX;AACA,CAAC;AACC,UAAQ;AACV;AACA,CAAC;AACC,UAAQ;AACV;AACA,CAAC;AACC,UAAQ;AACV;AACA,CAAC;AACC,SAAO;AACT;AACA,CAAC;AACC,SAAO;AACT;AACA,CAAC;AACC,SAAO;AACT;AACA,CAAC;AACC,eAAa;AACf;AACA,CAAC;AACC,oBAAkB,KAAK,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;AAC5C,aAAW,IAAI,kBAAkB,IAAI;AACvC;AACA,CAAC;AACC,oBAAkB;AAClB,aAAW,IAAI,kBAAkB,IAAI;AACvC;AACA,CAAC;AACC,kBAAgB;AAClB;AACA,CAAC;AACC,aAAW;AACb;AACA,CAAC;AACC,eAAa;AACf;AACA,CAAC;AACC,mBAAiB;AACnB;AACA,CAAC;AACC,OAAK;AACP;AACA,CAAC;AACC,cAAY;AACd;AACA,CAAC;AACC,cAAY;AACd;AACA,CAAC;AACC,iBAAe;AACjB;AACA,CAAC;AACC,iBAAe;AACjB;AACA,CAAC;AACC,iBAAe,KAAK,SAAS,EAAE;AACjC;AACA,CAAC;AACC,gBAAc,IAAI;AAClB,gBAAc;AAChB;AACA,CAAC;AACC,oBAAkB,IAAI;AACtB,oBAAkB;AACpB;AACA,CAAC;AACC,eAAa;AACf;AACA,CAAC;AACC,cAAY;AACd;AACA,CAAC;AACC,aAAW;AACb;AACA,CAAC;AACC,aAAW;AACb;AACA,CAAC;AACC,gBAAc;AACd,eAAa;AACf;AACA,CAAC;AACC,eAAa;AACf;AACA,CAAC;AACC,cAAY;AACd;AACA,CAAC;AACC,WAAS;AACX;AACA,CAAC;AACC,iBAAe,IAAI;AACnB,iBAAe;AACjB;AACA,CAAC;AACC;AAAA,IAAqB,KAAK;AAAA,IAAE,gBAAgB;AAAA,IAAE,YAAY;AAAA,IAAE,aAAa;AAAA,IAAE,qBAAqB;AAAA,IAAE,IAAI;AAAA,IAAE,MAAM;AAAA,IAAE,kBAAkB;AAAA,IAAE,iBAAiB;AAAA,IAAE;AACvJ,8BAA4B,IAAI,SAAS,EAAE;AAC3C,uBAAqB,IAAI,aAAa,EAAE;AAC1C;AACA,CAAC;AACC;AAAA,IAAqB,SAAS;AAAA,IAAE,SAAS;AAAA,IAAE,KAAK;AAAA,IAAE;AAClD,8BAA4B,IAAI,SAAS,EAAE;AAC3C,uBAAqB,IAAI,aAAa,EAAE;AAC1C;AACA,CAAC;AACC,iBAAe;AACf,uBAAqB;AACvB;AACA,CAAC;AACC,iBAAe;AACf,uBAAqB;AACvB;AACA,CAAC;AACC,uBAAqB;AACrB,oBAAkB;AACb,eAAa;AACpB;AACA,CAAC;AACC,GAAC;AACC,YAAO,OAAQ;AACb,oBAAc;AACd,oBAAc;AACd,oBAAc;AACd,aAAO,IAAI,cAAc,IAAI;AAC/B;AACF;AACF;AACA,UAAU,iBAAiB,EACzB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB,UAAU,iBAAiB,EACzB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB,UAAU,iBAAiB,EACzB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB,UAAU,kBAAkB,EAC1B,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,KAAK;AAEtB,UAAU,aAAa,EACrB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK;AAEjB,UAAU,mBAAmB,EAC3B,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,KAAK;AAEtB,UAAU,cAAc,EACtB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK;AAEjB,UAAU,aAAa,EACrB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB,UAAU,aAAa,EACrB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB,UAAU,aAAa,EACrB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,CAAC;AAElB;AACE,YAAU,CAAC,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE;AAC7H;AAAA,IAAG;AAAA,IAAU;AAAA,IAAS;AACpB,wBAAkB;AAClB,wBAAkB;AAClB,wBAAkB;AAClB,yBAAmB;AACnB,oBAAc;AACd,0BAAoB;AACpB,qBAAe;AACf,oBAAc;AACd,oBAAc;AACd,oBAAc;AAChB;AACF;AACF;","names":[]}