# Nepali Date

A lightweight, open-source TypeScript library for Nepali date (BS ↔ AD) conversion and date-picking across all platforms (web, mobile, desktop, CLI).

![Bundle Size](https://img.shields.io/badge/core-<10kB-brightgreen)
![Bundle Size](https://img.shields.io/badge/picker-<30kB-brightgreen)
![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)
![React](https://img.shields.io/badge/React-16.8%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![npm](https://img.shields.io/npm/v/@manojshrestha/nepali-date)

## Features

### Core Date Converter

- Zero dependencies
- Accurate BS ↔ AD conversion with:
  - Leap year support (both calendars)
  - Custom epoch (1970 BS)
  - Validation (isValidBsDate(), isLeapYear())
  - Formatting (format(date, "YYYY-MM-DD"))
- Internationalization (auto-detect Nepali/English from navigator.language)

### Cross-Platform Date Picker

- Framework Support:
  - React (primary)
  - Vue/Svelte wrappers (coming soon)
  - React Native (coming soon)
- UI Features:
  - Tailwind-compatible, themable CSS
  - Toggle between BS/AD, min/max dates, disabled days (weekends/holidays)
  - Outputs both BS/AD dates simultaneously

## Installation

```bash
# Using npm
npm install @manojshrestha/nepali-date

# Using yarn
yarn add @manojshrestha/nepali-date

# Using pnpm
pnpm add @manojshrestha/nepali-date
```

## Usage

### Basic Date Conversion

```typescript
import { bsToAd, adToBs, formatBsDate, formatAdDate } from "@manojshrestha/nepali-date";

// BS to AD conversion
const bsDate = { year: 2080, month: 1, day: 1 };
const adDate = bsToAd(bsDate);
console.log(adDate); // { year: 2023, month: 4, day: 14 }

// AD to BS conversion
const adDate2 = { year: 2023, month: 4, day: 14 };
const bsDate2 = adToBs(adDate2);
console.log(bsDate2); // { year: 2080, month: 1, day: 1 }

// Formatting
console.log(formatBsDate(bsDate, "YYYY-MM-DD")); // '2080-01-01'
console.log(formatBsDate(bsDate, "MMMM DD, YYYY", "ne")); // 'बैशाख ०१, २०८०'
console.log(formatAdDate(adDate, "MMMM DD, YYYY")); // 'April 14, 2023'
```

### Date Validation

```typescript
import { isValidBsDate, isLeapYear, getDaysInBsMonth } from "@manojshrestha/nepali-date";

// Check if a BS date is valid
console.log(isValidBsDate({ year: 2080, month: 1, day: 1 })); // true
console.log(isValidBsDate({ year: 2080, month: 1, day: 32 })); // false

// Check if an AD year is a leap year
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(2023)); // false

// Get days in BS month
console.log(getDaysInBsMonth(2080, 1)); // 31
console.log(getDaysInBsMonth(2080, 3)); // 32
```

### React Date Picker

```tsx
import React, { useState } from "react";
import { NepaliDatePicker, DateConversion } from "@manojshrestha/nepali-date";

// Import the CSS (or use your own custom styles)
import "@manojshrestha/nepali-date/dist/DatePicker.css";

function App() {
  const [selectedDate, setSelectedDate] = useState<DateConversion | null>(null);

  const handleDateChange = (dates: DateConversion) => {
    setSelectedDate(dates);
    console.log("BS Date:", dates.bs);
    console.log("AD Date:", dates.ad);
  };

  return (
    <div className="App">
      <h1>Nepali Date Picker</h1>

      <NepaliDatePicker
        onChange={handleDateChange}
        defaultCalendar="BS"
        locale="en"
        theme="light"
        disabledDays={[0, 6]} // Disable weekends (Sunday, Saturday)
        minDate={{ year: 2075, month: 1, day: 1 }}
        maxDate={{ year: 2085, month: 12, day: 30 }}
      />

      {selectedDate && (
        <div>
          <h2>Selected Date:</h2>
          <p>
            BS: {selectedDate.bs.year}-{selectedDate.bs.month}-
            {selectedDate.bs.day}
          </p>
          <p>
            AD: {selectedDate.ad.year}-{selectedDate.ad.month}-
            {selectedDate.ad.day}
          </p>
        </div>## Framework Integration Examples

### Using with Next.js

```tsx
// components/DatePickerWrapper.tsx
'use client';

import { NepaliDatePicker, DateConversion } from "@manojshrestha/nepali-date";
import "@manojshrestha/nepali-date/dist/DatePicker.css";

export default function DatePickerWrapper({ onChange }) {
  return (
    <NepaliDatePicker 
      onChange={onChange}
      defaultCalendar="BS"
    />
  );
}
```

### Using with Laravel + Inertia.js

```tsx
// resources/js/Components/NepaliDateInput.tsx
import { NepaliDatePicker, DateConversion } from "@manojshrestha/nepali-date";
import "@manojshrestha/nepali-date/dist/DatePicker.css";

export default function NepaliDateInput({ name, value, onChange }) {
  const handleDateChange = (dates: DateConversion) => {
    // Format as YYYY-MM-DD for form submission
    const formattedDate = `${dates.bs.year}-${String(dates.bs.month).padStart(2, '0')}-${String(dates.bs.day).padStart(2, '0')}`;
    onChange(name, formattedDate);
  };

  return (
    <NepaliDatePicker
      onChange={handleDateChange}
      defaultCalendar="BS"
      locale="ne"
    />
  );
}
```

## API Reference

### Core Functions

| Function                               | Description                              |
| -------------------------------------- | ---------------------------------------- |
| `bsToAd(bsDate)`                       | Convert BS date to AD date               |
| `adToBs(adDate)`                       | Convert AD date to BS date               |
| `convertDate(date, calendar)`          | Convert between BS and AD (returns both) |
| `isValidBsDate(bsDate)`                | Check if a BS date is valid              |
| `isLeapYear(year)`                     | Check if an AD year is a leap year       |
| `getDaysInBsMonth(year, month)`        | Get days in a BS month                   |
| `formatBsDate(date, format?, locale?)` | Format a BS date                         |
| `formatAdDate(date, format?, locale?)` | Format an AD date                        |
| `detectLocale()`                       | Auto-detect locale from browser          |

### Date Picker Props

| Prop              | Type                              | Default     | Description                 |
| ----------------- | --------------------------------- | ----------- | --------------------------- |
| `value`           | `BsDate \| AdDate`                | -           | Initial date value          |
| `defaultCalendar` | `'BS' \| 'AD'`                    | `'BS'`      | Default calendar view       |
| `minDate`         | `BsDate \| AdDate`                | -           | Minimum selectable date     |
| `maxDate`         | `BsDate \| AdDate`                | -           | Maximum selectable date     |
| `disabledDays`    | `number[]`                        | `[]`        | Disabled days of week (0-6) |
| `holidays`        | `Array<BsDate \| AdDate>`         | `[]`        | Disabled holiday dates      |
| `locale`          | `'en' \| 'ne'`                    | Auto-detect | Display language            |
| `theme`           | `'light' \| 'dark' \| 'auto'`     | `'light'`   | Color theme                 |
| `onChange`        | `(dates: DateConversion) => void` | -           | Change event handler        |
| `className`       | `string`                          | `''`        | Additional CSS classes      |

## Tree-Shaking

This library supports tree-shaking, meaning you can import only what you need:

```typescript
// Just the conversion utilities
import { bsToAd, adToBs } from "@manojshrestha/nepali-date";

// Just the DatePicker component
import { NepaliDatePicker } from "@manojshrestha/nepali-date";
import "@manojshrestha/nepali-date/dist/DatePicker.css";
```

## Building from Source

```bash
# Clone the repository
git clone https://github.com/manojshrestha/nepali-date.git
cd nepali-date

# Install dependencies
npm install

# Build the library
npm run build

# Run tests
npm test
```

## Browser Support

- Chrome, Firefox, Safari, Edge: latest 2 versions
- IE: 11+

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Acknowledgements

Thanks to contributors and the community for their support in creating an accurate date conversion library for Nepali dates.
