Enhance ContributionCalendar and development.astro for dark mode support and improved commit display

- Refactor ContributionCalendar to support light and dark color schemes based on user preference.
- Implement dark mode detection using a MutationObserver to dynamically adjust styles.
- Update development.astro to include a new CollapsibleIntro component for better user experience.
- Improve commit display logic to format messages with bullet points and enhance layout for clarity.
This commit is contained in:
2025-06-06 23:36:00 +02:00
parent bbbcb96905
commit aa37cb23cf
3 changed files with 125 additions and 40 deletions

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
// Helper to get all days in the last 52 weeks, starting on Monday
function getCalendarDays() {
@@ -38,23 +38,45 @@ function getMonthLabels(days) {
// Day labels for rows (Monday to Sunday)
const DAY_LABELS = ['Mon', '', 'Wed', '', 'Fri', '', 'Sun'];
// Color scale (GitHub-like)
const COLORS = [
// Color scales
const COLORS_LIGHT = [
'#ebedf0', // 0
'#c6e48b', // 1
'#7bc96f', // 2
'#239a3b', // 3
'#196127', // 4+
];
function getColor(count) {
if (!count) return COLORS[0];
if (count >= 4) return COLORS[4];
return COLORS[count];
const COLORS_DARK = [
'#23272e', // 0
'#3c4d36', // 1
'#4e7c4e', // 2
'#399150', // 3
'#6ee7b7', // 4+
];
function getColor(count, isDark) {
const palette = isDark ? COLORS_DARK : COLORS_LIGHT;
if (!count) return palette[0];
if (count >= 4) return palette[4];
return palette[count];
}
export default function ContributionCalendar({ data }) {
const days = getCalendarDays();
const monthLabels = getMonthLabels(days);
const [isDark, setIsDark] = useState(false);
useEffect(() => {
// Detect dark mode by checking for 'dark' class on <html>
const checkDark = () => {
setIsDark(document.documentElement.classList.contains('dark'));
};
checkDark();
const observer = new MutationObserver(checkDark);
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
return () => observer.disconnect();
}, []);
// Get max count for scaling (optional, for more dynamic color)
// const max = Math.max(...Object.values(data));
@@ -66,11 +88,11 @@ export default function ContributionCalendar({ data }) {
margin: '0 auto',
padding: 0,
borderRadius: '1rem',
background: 'rgba(255,255,255,0.7)',
boxShadow: '0 4px 24px 0 rgba(0,0,0,0.08)',
background: isDark ? 'rgba(30,41,59,0.85)' : 'rgba(255,255,255,0.7)',
boxShadow: isDark ? '0 4px 24px 0 rgba(0,0,0,0.32)' : '0 4px 24px 0 rgba(0,0,0,0.08)',
backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)',
border: '1px solid rgba(255,255,255,0.3)',
border: isDark ? '1px solid rgba(51,65,85,0.5)' : '1px solid rgba(255,255,255,0.3)',
overflowX: 'auto',
display: 'flex',
flexDirection: 'column',
@@ -92,7 +114,7 @@ export default function ContributionCalendar({ data }) {
flex: '0 0 14px',
textAlign: 'center',
fontSize: 12,
color: '#888',
color: isDark ? '#b6c2d1' : '#888',
fontWeight: 500,
minWidth: 14,
}}
@@ -111,7 +133,7 @@ export default function ContributionCalendar({ data }) {
style={{
height: 14,
fontSize: 12,
color: '#888',
color: isDark ? '#b6c2d1' : '#888',
textAlign: 'right',
lineHeight: '14px',
marginBottom: 1,
@@ -141,7 +163,7 @@ export default function ContributionCalendar({ data }) {
width: 12,
height: 12,
margin: 1,
background: getColor(count),
background: getColor(count, isDark),
borderRadius: 2,
}}
/>
@@ -151,9 +173,9 @@ export default function ContributionCalendar({ data }) {
))}
</div>
</div>
<div style={{ fontSize: 12, color: '#888', marginTop: 4, textAlign: 'center' }}>
<div style={{ fontSize: 12, color: isDark ? '#b6c2d1' : '#888', marginTop: 4, textAlign: 'center' }}>
<span>Less</span>
{COLORS.map((color, i) => (
{(isDark ? COLORS_DARK : COLORS_LIGHT).map((color, i) => (
<span key={i} style={{ display: 'inline-block', width: 12, height: 12, background: color, margin: '0 2px', borderRadius: 2 }} />
))}
<span>More</span>