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.
|
|
5 months ago | |
|---|---|---|
| nginx | 10 months ago | |
| src | 5 months ago | |
| .DS_Store | 10 months ago | |
| .deploy.yml | 10 months ago | |
| .drone.yml | 10 months ago | |
| .gitignore | 10 months ago | |
| Dockerfile | 10 months ago | |
| README.md | 10 months ago | |
| docker-compose.yml | 5 months ago | |
| index.html | 10 months ago | |
| package-lock.json | 5 months ago | |
| package.json | 5 months ago | |
| tsconfig.json | 10 months ago | |
| vite.config.ts | 10 months ago | |
README.md
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
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
npm install
Development
npm run dev
Usage Examples
Date Range Picker
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
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
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
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
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
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 variablessrc/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