You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
4.5 KiB
Markdown

# React Calendar Component
A modern, flexible calendar component built with React, TypeScript, and SCSS modules.
## Demo
Check out the live demo at [calendar.code.meow.ch](https://calendar.code.meow.ch)
## Features
- 📅 Multiple calendar views:
- Full year view with configurable month grid
- Single month view with customizable layout
- Week view with interactive options
- Date range picker with hover preview
- 🎨 Visual customization:
- Four header styles: expanded, compacted, tiny, and numeric
- Configurable day sizes (XS to XL)
- Adjustable font proportions
- Optional magnify effect for selected dates
- Weekend highlighting
- 🔧 Functional options:
- Month cutoff handling (dimmed, truncated, or show all)
- Interactive date range selection
- Hover states and preview
- Responsive design for all screen sizes
- 🛠 Technical features:
- Built with React + TypeScript
- SCSS modules for styling
- date-fns for date manipulation
- Zero external dependencies beyond core requirements
## Installation
```bash
npm install
```
## Development
```bash
npm run dev
```
## Usage Examples
### Date Range Picker
```tsx
import React, { useState } from 'react';
import { Year } from './components/calendar/Year';
import { DateRange } from './types/calendar';
function DateRangePicker() {
const [dateRange, setDateRange] = useState<DateRange>({
startDate: null,
endDate: null,
selecting: false,
hoverDate: null,
anchorDate: null
});
const handleDateSelect = (date: Date) => {
setDateRange(prev => {
if (!prev.selecting) {
return {
startDate: date,
endDate: date,
selecting: true,
hoverDate: date,
anchorDate: date
};
}
// Complete the selection
return {
startDate: prev.anchorDate,
endDate: date,
selecting: false,
hoverDate: null,
anchorDate: null
};
});
};
return (
<Year
year={2024}
dayHeaderStyle="tiny"
monthCutoff="truncate"
weekendDays={[6, 0]}
dateRange={dateRange}
onDateSelect={handleDateSelect}
onDateHover={(date) => setDateRange(prev => ({ ...prev, hoverDate: date }))}
size="l"
fontProportion={100}
magnify={true}
/>
);
}
```
### Single Month View
```tsx
import React from 'react';
import { Month } from './components/calendar/Month';
function SingleMonth() {
return (
<Month
date={new Date()}
dayHeaderStyle="expanded"
direction="column"
monthCutoff="dimmed"
weekendDays={[6, 0]}
size="xl"
fontProportion={100}
/>
);
}
```
### Week View
```tsx
import React from 'react';
import { Week } from './components/calendar/Week';
function WeekView() {
return (
<Week
startDate={new Date()}
headerStyle="compacted"
referenceMonth={new Date().getMonth()}
weekendDays={[6, 0]}
size="l"
fontProportion={100}
/>
);
}
```
### Compact Year View
```tsx
import React from 'react';
import { Year } from './components/calendar/Year';
function CompactYear() {
return (
<Year
year={2024}
dayHeaderStyle="tiny"
monthCutoff="truncate"
weekendDays={[6, 0]}
size="xs"
fontProportion={80}
magnify={true}
/>
);
}
```
## Component Props
### Year Component
```typescript
interface YearProps {
year: number;
dayHeaderStyle: 'expanded' | 'compacted' | 'tiny' | 'none';
monthDayOfWeekHeaderStyle?: HeaderStyle;
monthCutoff?: 'dimmed' | 'truncate' | undefined;
weekendDays?: number[];
dateRange?: DateRange;
onDateSelect?: (date: Date) => void;
onDateHover?: (date: Date) => void;
size?: 'xl' | 'l' | 'm' | 's' | 'xs';
fontProportion?: number;
magnify?: boolean;
}
```
### Month Component
```typescript
interface MonthProps {
date: Date;
dayHeaderStyle: HeaderStyle;
direction: 'row' | 'column';
monthCutoff?: MonthCutoffType;
weekendDays?: number[];
dateRange?: DateRange;
onDateSelect?: (date: Date) => void;
onDateHover?: (date: Date) => void;
size?: DaySize;
fontProportion?: number;
magnify?: boolean;
}
```
## Styling
The component uses SCSS modules for styling. Key style files:
- `src/components/calendar/shared/_colors.scss`: Color variables
- `src/components/calendar/shared/_variables.scss`: Layout variables
- Individual component SCSS modules for specific styling
## Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
## License
MIT