sidebar-calendar
Version:
A powerful calendar component for sidebars with day, week, and range selection modes
366 lines (283 loc) β’ 8.73 kB
Markdown
# π
SidebarCalendar
A powerful, lightweight calendar component designed specifically for sidebars with three distinct selection modes: day, week, and range selection.
[](https://badge.fury.io/js/sidebar-calendar)
[](https://opensource.org/licenses/MIT)
[](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!