|
|
|
|
@ -1,8 +1,9 @@
|
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
import { DateRange } from '../components/calendar/DateRange';
|
|
|
|
|
import { Controls } from '../components/calendar/Controls';
|
|
|
|
|
import { HeaderStyle, DaySize, MonthCutoffType } from '../types/calendar';
|
|
|
|
|
import { format, startOfDay } from 'date-fns';
|
|
|
|
|
import { HeaderStyle, DaySize, MonthCutoffType, ColorScheme, ActiveColors } from '../types/calendar';
|
|
|
|
|
import { format, startOfDay, Locale } from 'date-fns';
|
|
|
|
|
import { enUS, es, fr, de, it, ja, ko, zhCN } from 'date-fns/locale';
|
|
|
|
|
import styles from './Examples.module.scss';
|
|
|
|
|
|
|
|
|
|
export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
@ -14,10 +15,193 @@ export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
const [monthCutoff, setMonthCutoff] = useState<MonthCutoffType>(undefined);
|
|
|
|
|
const [activeDates, setActiveDates] = useState<Date[]>([]);
|
|
|
|
|
const [lastClicked, setLastClicked] = useState<string>('');
|
|
|
|
|
const [selectedLocale, setSelectedLocale] = useState<string>('enUS');
|
|
|
|
|
const [useColorScheme, setUseColorScheme] = useState<boolean>(false);
|
|
|
|
|
const [colorTheme, setColorTheme] = useState<'ocean' | 'sunset' | 'forest'>('ocean');
|
|
|
|
|
|
|
|
|
|
const fromDate = new Date(2025, 0, 10); // January 10, 2025
|
|
|
|
|
const toDate = new Date(2025, 0, 25); // January 25, 2025
|
|
|
|
|
|
|
|
|
|
// Locale options
|
|
|
|
|
const locales: Record<string, { locale: Locale; name: string }> = {
|
|
|
|
|
enUS: { locale: enUS, name: 'English' },
|
|
|
|
|
es: { locale: es, name: 'Español' },
|
|
|
|
|
fr: { locale: fr, name: 'Français' },
|
|
|
|
|
de: { locale: de, name: 'Deutsch' },
|
|
|
|
|
it: { locale: it, name: 'Italiano' },
|
|
|
|
|
ja: { locale: ja, name: '日本語' },
|
|
|
|
|
ko: { locale: ko, name: '한국어' },
|
|
|
|
|
zhCN: { locale: zhCN, name: '中文' }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Color schemes with proper weekend support
|
|
|
|
|
const colorSchemes: Record<string, ColorScheme> = {
|
|
|
|
|
ocean: [
|
|
|
|
|
// Weekday states
|
|
|
|
|
{ type: 'weekday', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#006994', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffffff', color: '#006994' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#4a90a4', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#e8f4f8', color: '#006994' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#004d6f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#0084b4', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#004d6f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#0084b4', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#3ca0c8', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#b3d9ea', color: '#004d6f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#00a8e8', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#007ea7', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
// Weekend states - with subtle differentiation
|
|
|
|
|
{ type: 'weekend', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#5c8ca3', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#f0f6f9', color: '#3d5a6c' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#7aa3b8', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#dde9f0', color: '#4a6b7c' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#003f5c', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#006d94', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#003f5c', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#006d94', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#6eb5d0', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#cce5f0', color: '#003f5c' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#0096c7', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#0077b6', color: '#ffffff' }
|
|
|
|
|
}}
|
|
|
|
|
],
|
|
|
|
|
sunset: [
|
|
|
|
|
// Weekday states
|
|
|
|
|
{ type: 'weekday', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#ff6b35', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffffff', color: '#ff6b35' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#ff8c5a', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffe8df', color: '#c94820' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#d84315', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ff5722', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#d84315', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ff5722', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#ff8a65', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffccbc', color: '#bf360c' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#f4511e', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#e64a19', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
// Weekend states
|
|
|
|
|
{ type: 'weekend', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#ff9671', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#fff4f0', color: '#cc5030' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#ffab8f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffe0d6', color: '#b84020' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#bf360c', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ff6e40', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#bf360c', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ff6e40', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#ffab91', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffddd2', color: '#a73010' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#ff3d00', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ff6e40', color: '#ffffff' }
|
|
|
|
|
}}
|
|
|
|
|
],
|
|
|
|
|
forest: [
|
|
|
|
|
// Weekday states
|
|
|
|
|
{ type: 'weekday', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#2d6a4f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#ffffff', color: '#2d6a4f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#52b788', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#d8f3dc', color: '#1b5e3f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#1b5e3f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#40916c', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#1b5e3f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#40916c', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#74c69d', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#b7e4c7', color: '#1b5e3f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekday', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#388e3c', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#2e7d32', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
// Weekend states
|
|
|
|
|
{ type: 'weekend', state: 'default', colors: {
|
|
|
|
|
header: { backgroundColor: '#6a994e', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#f1f8f4', color: '#386641' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'selecting', colors: {
|
|
|
|
|
header: { backgroundColor: '#95d5b2', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#e5f5eb', color: '#2d6a4f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeStart', colors: {
|
|
|
|
|
header: { backgroundColor: '#155d3f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#52b788', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeEnd', colors: {
|
|
|
|
|
header: { backgroundColor: '#155d3f', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#52b788', color: '#ffffff' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'rangeMid', colors: {
|
|
|
|
|
header: { backgroundColor: '#95d5b2', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#d8f3dc', color: '#155d3f' }
|
|
|
|
|
}},
|
|
|
|
|
{ type: 'weekend', state: 'active', colors: {
|
|
|
|
|
header: { backgroundColor: '#2e7d32', color: '#ffffff' },
|
|
|
|
|
content: { backgroundColor: '#4caf50', color: '#ffffff' }
|
|
|
|
|
}}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Legacy active colors for comparison
|
|
|
|
|
const activeColors: ActiveColors = {
|
|
|
|
|
headerBg: '#ffd700',
|
|
|
|
|
headerColor: '#333333',
|
|
|
|
|
contentBg: '#ffeb3b',
|
|
|
|
|
contentColor: '#333333'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDateClick = (date: Date) => {
|
|
|
|
|
const dateString = format(date, 'MMMM d, yyyy');
|
|
|
|
|
setLastClicked(dateString);
|
|
|
|
|
@ -76,6 +260,45 @@ export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
<span>Show as selected range</span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles.controlRow} style={{ marginTop: '15px', padding: '15px', background: '#f5f5f5', borderRadius: '8px' }}>
|
|
|
|
|
<label className={styles.control} style={{ marginRight: '20px' }}>
|
|
|
|
|
<strong>🌍 Language:</strong>
|
|
|
|
|
<select
|
|
|
|
|
value={selectedLocale}
|
|
|
|
|
onChange={(e) => setSelectedLocale(e.target.value)}
|
|
|
|
|
style={{ marginLeft: '8px', padding: '4px 8px' }}
|
|
|
|
|
>
|
|
|
|
|
{Object.entries(locales).map(([key, { name }]) => (
|
|
|
|
|
<option key={key} value={key}>{name}</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
|
|
|
|
|
<label className={styles.control}>
|
|
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
|
|
|
|
checked={useColorScheme}
|
|
|
|
|
onChange={(e) => setUseColorScheme(e.target.checked)}
|
|
|
|
|
/>
|
|
|
|
|
<span><strong>🎨 Use Custom Colors</strong></span>
|
|
|
|
|
</label>
|
|
|
|
|
|
|
|
|
|
{useColorScheme && (
|
|
|
|
|
<label className={styles.control} style={{ marginLeft: '20px' }}>
|
|
|
|
|
Theme:
|
|
|
|
|
<select
|
|
|
|
|
value={colorTheme}
|
|
|
|
|
onChange={(e) => setColorTheme(e.target.value as any)}
|
|
|
|
|
style={{ marginLeft: '8px', padding: '4px 8px' }}
|
|
|
|
|
>
|
|
|
|
|
<option value="ocean">🌊 Ocean</option>
|
|
|
|
|
<option value="sunset">🌅 Sunset</option>
|
|
|
|
|
<option value="forest">🌲 Forest</option>
|
|
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.info}>
|
|
|
|
|
<p>Last clicked: {lastClicked || 'None'}</p>
|
|
|
|
|
<p>Active dates: {activeDates.length > 0
|
|
|
|
|
@ -95,6 +318,9 @@ export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
magnify={true}
|
|
|
|
|
onDateClick={handleDateClick}
|
|
|
|
|
activeDates={activeDates}
|
|
|
|
|
activeColors={!useColorScheme ? activeColors : undefined}
|
|
|
|
|
colorScheme={useColorScheme ? colorSchemes[colorTheme] : undefined}
|
|
|
|
|
locale={locales[selectedLocale].locale}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.codeExample}>
|
|
|
|
|
@ -107,8 +333,9 @@ export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
size="${size}"
|
|
|
|
|
fontProportion={${fontProportion}}
|
|
|
|
|
magnify={true}
|
|
|
|
|
locale={${selectedLocale !== 'enUS' ? selectedLocale : 'enUS'}}
|
|
|
|
|
${useColorScheme ? `colorScheme={${colorTheme}ColorScheme}` : 'activeColors={goldActiveColors}'}
|
|
|
|
|
onDateClick={(date) => {
|
|
|
|
|
alert(\`Clicked: \${format(date, 'MMMM d, yyyy')}\`);
|
|
|
|
|
// Toggle active state
|
|
|
|
|
setActiveDates(prev => {
|
|
|
|
|
const exists = prev.some(d => d.getTime() === date.getTime());
|
|
|
|
|
@ -120,6 +347,21 @@ export const InteractiveDateRange: React.FC = () => {
|
|
|
|
|
activeDates={activeDates}
|
|
|
|
|
/>`}</pre>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{useColorScheme && (
|
|
|
|
|
<div className={styles.info} style={{ marginTop: '20px', padding: '15px', background: '#f9f9f9', borderRadius: '8px' }}>
|
|
|
|
|
<h4 style={{ margin: '0 0 10px 0' }}>🎨 Color Scheme Features:</h4>
|
|
|
|
|
<ul style={{ margin: '10px 0', paddingLeft: '20px' }}>
|
|
|
|
|
<li><strong>Weekdays vs Weekends:</strong> Notice the subtle color differences</li>
|
|
|
|
|
<li><strong>Selecting State:</strong> Hover while range is selected to see the selecting colors</li>
|
|
|
|
|
<li><strong>Range States:</strong> Start/End dates have stronger colors than middle dates</li>
|
|
|
|
|
<li><strong>Active Dates:</strong> Click to toggle - active dates get special highlighting</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<p style={{ margin: '10px 0 0 0', fontSize: '0.9em', color: '#666' }}>
|
|
|
|
|
Try selecting Saturday and Sunday to see weekend-specific colors during selection!
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</section>
|
|
|
|
|
);
|
|
|
|
|
};
|