# 📅 SidebarCalendar

A powerful, lightweight calendar component designed specifically for sidebars with three distinct selection modes: day, week, and range selection.

[![npm version](https://badge.fury.io/js/sidebar-calendar.svg)](https://badge.fury.io/js/sidebar-calendar)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/sidebar-calendar)](https://bundlephobia.com/package/sidebar-calendar)

## ✨ Features

- 🎯 **Three Selection Modes**: Day, week, and range selection
- 🎨 **Beautiful Design**: Modern gradient themes for each mode
- 📱 **Responsive**: Works perfectly on all screen sizes
- ♿ **Accessible**: Full keyboard navigation and screen reader support
- 🌍 **Localization**: Multi-language support (Russian and English built-in)
- 🎭 **Theme Support**: Light/dark mode and high contrast support
- 🚫 **No Dependencies**: Pure vanilla JavaScript
- 📦 **Lightweight**: Less than 15KB gzipped
- 🔧 **Flexible API**: Rich event system and programmatic control

## 🚀 Installation

### NPM
```bash
npm install sidebar-calendar
```

### Yarn
```bash
yarn add sidebar-calendar
```

### CDN
```html
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/sidebar-calendar@1.0.0/dist/sidebar-calendar.css">

<!-- JavaScript -->
<script src="https://unpkg.com/sidebar-calendar@1.0.0/dist/sidebar-calendar.js"></script>
```

## 📖 Quick Start

### 1. Basic HTML Setup
```html
<div id="calendar"></div>
```

### 2. Initialize Calendar
```javascript
import SidebarCalendar from 'sidebar-calendar';
import 'sidebar-calendar/dist/sidebar-calendar.css';

// Create a day selection calendar
const dayCalendar = new SidebarCalendar('#calendar', {
  mode: 'day'
});

// Listen for date selection
dayCalendar.on('dateSelect', (data) => {
  console.log('Selected date:', data.date);
  console.log('Formatted:', data.formatted);
});
```

## 🎛️ Calendar Modes

### Day Mode
Select a single date with beautiful highlighting.

```javascript
const dayCalendar = new SidebarCalendar('#calendar', {
  mode: 'day'
});

dayCalendar.on('dateSelect', (data) => {
  console.log('Selected:', data.date); // Date object
  console.log('Formatted:', data.formatted); // "15 июня 2025"
});
```

### Week Mode
Select entire weeks with hover preview.

```javascript
const weekCalendar = new SidebarCalendar('#calendar', {
  mode: 'week'
});

weekCalendar.on('weekSelect', (data) => {
  console.log('Week start:', data.start); // Monday
  console.log('Week end:', data.end);     // Sunday
  console.log('Formatted:', data.formatted); // "10 июня 2025 - 16 июня 2025"
});
```

### Range Mode
Select custom date ranges with intuitive two-click selection.

```javascript
const rangeCalendar = new SidebarCalendar('#calendar', {
  mode: 'range'
});

rangeCalendar.on('rangeStart', (data) => {
  console.log('Range started:', data.date);
});

rangeCalendar.on('rangeSelect', (data) => {
  console.log('Range start:', data.start);
  console.log('Range end:', data.end);
  console.log('Formatted:', data.formatted); // "1 июня 2025 - 30 июня 2025"
});
```

## ⚙️ Configuration Options

```javascript
const calendar = new SidebarCalendar('#calendar', {
  mode: 'day',                    // 'day', 'week', 'range'
  locale: 'ru-RU',               // Locale for date formatting
  minDate: new Date('2025-01-01'), // Minimum selectable date
  maxDate: new Date('2025-12-31'), // Maximum selectable date
  disabledDates: [               // Array of disabled dates
    new Date('2025-06-15'),
    new Date('2025-07-04')
  ],
  
  // Legacy callback support (deprecated, use .on() instead)
  onDateSelect: (data) => console.log(data),
  onWeekSelect: (data) => console.log(data),
  onRangeSelect: (data) => console.log(data)
});
```

## 🎪 API Reference

### Methods

#### `on(event, callback)`
Subscribe to calendar events.

```javascript
calendar.on('dateSelect', (data) => {
  // Handle date selection
});
```

#### `off(event, callback)`
Unsubscribe from calendar events.

```javascript
const handler = (data) => console.log(data);
calendar.on('dateSelect', handler);
calendar.off('dateSelect', handler);
```

#### `getSelected()`
Get currently selected value.

```javascript
const selected = calendar.getSelected();
// Returns: Date object (day mode) or {start, end} object (week/range modes)
```

#### `setDate(date)`
Set selected date (day mode only).

```javascript
calendar.setDate(new Date('2025-06-15'));
calendar.setDate('2025-06-15'); // String also accepted
```

#### `setWeek(date)`
Set selected week (week mode only).

```javascript
calendar.setWeek(new Date('2025-06-15')); // Selects week containing this date
```

#### `setRange(start, end)`
Set selected range (range mode only).

```javascript
calendar.setRange('2025-06-01', '2025-06-30');
```

#### `clear()`
Clear all selections.

```javascript
calendar.clear();
```

#### `goToDate(date)`
Navigate to specific month/year.

```javascript
calendar.goToDate(new Date('2025-12-01')); // Go to December 2025
```

#### `navigate(direction)`
Navigate months programmatically.

```javascript
calendar.navigate(1);  // Next month
calendar.navigate(-1); // Previous month
```

#### `destroy()`
Clean up the calendar instance.

```javascript
calendar.destroy();
```

### Events

| Event | Mode | Data | Description |
|-------|------|------|-------------|
| `dateSelect` | day | `{type, date, formatted}` | Date selected |
| `weekSelect` | week | `{type, start, end, formatted}` | Week selected |
| `rangeStart` | range | `{type, date, formatted}` | Range start selected |
| `rangeSelect` | range | `{type, start, end, formatted}` | Range completed |
| `clear` | all | `{type}` | Selection cleared |
| `navigate` | all | `{direction, date}` | Month navigated |
| `destroy` | all | `{type}` | Calendar destroyed |

## 🎨 Styling & Themes

### SCSS Variables
Customize the calendar appearance using SCSS variables:

```scss
$calendar-width: 320px;
$calendar-bg: #ffffff;
$calendar-border-radius: 12px;
$color-day: #4ade80;
$color-week: #f59e0b;
$color-range: #8b5cf6;

@import 'sidebar-calendar/src/sidebar-calendar.scss';
```

### CSS Custom Properties
```css
.sidebar-calendar {
  --calendar-bg: #ffffff;
  --text-color: #111827;
  --color-day: #4ade80;
  --color-week: #f59e0b;
  --color-range: #8b5cf6;
}
```

### Dark Theme
The calendar automatically supports dark mode:

```css
@media (prefers-color-scheme: dark) {
  .sidebar-calendar {
    --calendar-bg: #1f2937;
    --text-color: #ffffff;
  }
}
```

## 🌍 Localization

### Built-in Locales
- `ru-RU` (Russian) - Default
- `en-US` (English)

```javascript
const calendar = new SidebarCalendar('#calendar', {
  locale: 'en-US' // Use English locale
});
```

### Custom Localization
Override month and weekday names by extending the class:

```javascript
class CustomCalendar extends SidebarCalendar {
  _getMonthNames() {
    return ['Jan', 'Feb', 'Mar', ...]; // Your custom month names
  }
  
  _getWeekdayNames() {
    return ['Mon', 'Tue', 'Wed', ...]; // Your custom weekday names
  }
}
```

## ♿ Accessibility

The calendar includes comprehensive accessibility features:

- Full keyboard navigation (Arrow keys, Escape)
- ARIA labels and roles
- Screen reader support
- High contrast mode support
- Focus management
- Reduced motion support

### Keyboard Shortcuts
- `Arrow Left/Right`: Navigate months
- `Escape`: Clear selection
- `Tab`: Navigate between elements
- `Enter/Space`: Select dates

## 📱 Responsive Design

The calendar automatically adapts to different screen sizes:

- **Desktop**: Full 320px width with all features
- **Tablet**: Responsive width with optimized spacing
- **Mobile**: Full width with touch-friendly interactions

## 🔧 Build System

### Development
```bash
# Install dependencies
npm install

# Start development
npm run watch

# Build for production
npm run build

# Run tests
npm run test

# Lint code
npm run lint
```

### File Structure
```
sidebar-calendar/
├── src/
│   ├── sidebar-calendar.js    # Main JavaScript file
│   └── sidebar-calendar.scss  # SCSS styles
├── dist/
│   ├── sidebar-calendar.js    # Built JavaScript
│   ├── sidebar-calendar.min.js
│   ├── sidebar-calendar.css   # Built CSS
│   └── sidebar-calendar.min.css
├── types/
│   └── index.d.ts            # TypeScript definitions
└── examples/                 # Usage examples
```

## 📋 Browser Support

- ✅ Chrome 70+
- ✅ Firefox 65+
- ✅ Safari 12+
- ✅ Edge 79+
- ❌ Internet Explorer (not supported)

## 🤝 Contributing

Contributions are welcome!