feat: interactive date range
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…
Reference in New Issue