feat: interactive date range

master
Guillermo Pages 5 months ago
parent 81fd7dec58
commit 22a02950c3

@ -0,0 +1,125 @@
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 styles from './Examples.module.scss';
export const InteractiveDateRange: React.FC = () => {
const [dayHeaderStyle, setDayHeaderStyle] = useState<HeaderStyle>('tiny');
const [size, setSize] = useState<DaySize>('l');
const [fontProportion, setFontProportion] = useState<number>(100);
const [included, setIncluded] = useState<boolean>(true);
const [selected, setSelected] = useState<boolean>(false);
const [monthCutoff, setMonthCutoff] = useState<MonthCutoffType>(undefined);
const [activeDates, setActiveDates] = useState<Date[]>([]);
const [lastClicked, setLastClicked] = useState<string>('');
const fromDate = new Date(2025, 0, 10); // January 10, 2025
const toDate = new Date(2025, 0, 25); // January 25, 2025
const handleDateClick = (date: Date) => {
const dateString = format(date, 'MMMM d, yyyy');
setLastClicked(dateString);
// Toggle the date in activeDates
setActiveDates(prev => {
const dateTime = startOfDay(date).getTime();
const existingIndex = prev.findIndex(d =>
startOfDay(d).getTime() === dateTime
);
if (existingIndex >= 0) {
// Remove if already active
return prev.filter((_, index) => index !== existingIndex);
} else {
// Add if not active
return [...prev, date];
}
});
// Show alert
alert(`Clicked: ${dateString}`);
};
return (
<section className={styles.section}>
<h2 className={styles.sectionTitle}>Interactive Date Range</h2>
<p className={styles.sectionDescription}>
Click on dates to toggle their active state. Active dates have inverted colors.
</p>
<Controls
headerStyle={dayHeaderStyle}
monthCutoff={monthCutoff}
size={size}
fontProportion={fontProportion}
onHeaderStyleChange={setDayHeaderStyle}
onMonthCutoffChange={setMonthCutoff}
onSizeChange={setSize}
onFontProportionChange={setFontProportion}
/>
<div className={styles.controlRow}>
<label className={styles.control}>
<input
type="checkbox"
checked={included}
onChange={(e) => setIncluded(e.target.checked)}
/>
<span>Include start/end dates</span>
</label>
<label className={styles.control}>
<input
type="checkbox"
checked={selected}
onChange={(e) => setSelected(e.target.checked)}
/>
<span>Show as selected range</span>
</label>
</div>
<div className={styles.info}>
<p>Last clicked: {lastClicked || 'None'}</p>
<p>Active dates: {activeDates.length > 0
? activeDates.map(d => format(d, 'MMM d')).join(', ')
: 'None'}</p>
</div>
<div className={styles.demoContainer}>
<DateRange
from={fromDate}
to={toDate}
included={included}
selected={selected}
headerStyle={dayHeaderStyle}
weekendDays={[6, 0]}
size={size}
fontProportion={fontProportion}
magnify={true}
onDateClick={handleDateClick}
activeDates={activeDates}
/>
</div>
<div className={styles.codeExample}>
<pre>{`<DateRange
from={new Date(2025, 0, 10)}
to={new Date(2025, 0, 25)}
included={${included}}
selected={${selected}}
headerStyle="${dayHeaderStyle}"
size="${size}"
fontProportion={${fontProportion}}
magnify={true}
onDateClick={(date) => {
alert(\`Clicked: \${format(date, 'MMMM d, yyyy')}\`);
// Toggle active state
setActiveDates(prev => {
const exists = prev.some(d => d.getTime() === date.getTime());
return exists
? prev.filter(d => d.getTime() !== date.getTime())
: [...prev, date];
});
}}
activeDates={activeDates}
/>`}</pre>
</div>
</section>
);
};
Loading…
Cancel
Save