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:
@@ -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>
|
||||
|
Reference in New Issue
Block a user