npm package: @himal_bhattarai/nepali-datepicker
Description: Nepali Bikram Sambat (BS) date picker React component with BS↔AD conversion
Author: Himal Bhattarai
Latest version: 1.2.3

# @himal_bhattarai/nepali-datepicker

A modern, lightweight **Nepali (Bikram Sambat) Date Picker** for React with accurate BS↔AD conversion, bilingual support, and full theming control.

---

## Installation

```bash
npm install @himal_bhattarai/nepali-datepicker
```

---

## Quick Start

```jsx
import { useState } from "react";
import { NepaliDatePicker } from "@himal_bhattarai/nepali-datepicker";

function App() {
  const [date, setDate] = useState(null);

  return (
    <NepaliDatePicker
      value={date}
      onChange={(bs, ad) => setDate(bs)}
    />
  );
}
```

---

## Props

### `value`
- **Type:** `{ year, month, day } | null`
- **Default:** `null`
- The currently selected BS date. Pass `null` for no selection.

```jsx
const [date, setDate] = useState(null);

<NepaliDatePicker value={date} onChange={(bs) => setDate(bs)} />
```

---

### `onChange`
- **Type:** `(bsDate, adDate) => void`
- **Required:** Yes
- Called when the user picks a date. Receives two arguments:
  - `bsDate` — `{ year, month, day }` in Bikram Sambat
  - `adDate` — JavaScript `Date` object in AD

```jsx
<NepaliDatePicker
  value={date}
  onChange={(bs, ad) => {
    console.log(bs);  // { year: 2081, month: 11, day: 22 }
    console.log(ad);  // Wed Mar 05 2025 (JS Date)
    setDate(bs);
  }}
/>
```

---

### `language`
- **Type:** `"np" | "en"`
- **Default:** `"np"`
- Controls the display language of the entire calendar — month names, day headers, numerals, placeholder, and buttons.

```jsx
// Nepali — Devanagari script (default)
<NepaliDatePicker language="np" value={date} onChange={(bs) => setDate(bs)} />

// English — Romanized month names, Arabic numerals
<NepaliDatePicker language="en" value={date} onChange={(bs) => setDate(bs)} />
```

---

### `placeholder`
- **Type:** `string`
- **Default:** `"मिति छान्नुहोस्"` (np) or `"Select BS date"` (en)
- Text shown in the input when no date is selected.

```jsx
<NepaliDatePicker
  placeholder="Enter booking date"
  value={date}
  onChange={(bs) => setDate(bs)}
/>
```

---

### `minYear`
- **Type:** `number`
- **Default:** `2060`
- The earliest BS year available in the year dropdown.

---

### `maxYear`
- **Type:** `number`
- **Default:** `2090`
- The latest BS year available in the year dropdown.

```jsx
<NepaliDatePicker
  minYear={2075}
  maxYear={2085}
  value={date}
  onChange={(bs) => setDate(bs)}
/>
```

---

### `className`
- **Type:** `string`
- **Default:** `""`
- Adds a custom CSS class to the root element. Use this to override styles via CSS variables in your own stylesheet.

```css
/* your-styles.css */
.my-picker {
  --ndp-primary: #1a56db;
  --ndp-background: #fff;
  --ndp-border: #bfdbfe;
}
```

```jsx
import "./your-styles.css";

<NepaliDatePicker
  className="my-picker"
  value={date}
  onChange={(bs) => setDate(bs)}
/>
```

---

### `styles`
- **Type:** `object`
- **Default:** `{}`
- Override the color theme directly in JSX without a CSS file. Useful for dynamic theming.

```jsx
<NepaliDatePicker
  value={date}
  onChange={(bs) => setDate(bs)}
  styles={{
    primary:     "#1a56db",   // main accent color (header, selected day, etc.)
    primarySoft: "#e8f0fe",   // light tint of primary (hover backgrounds)
    background:  "#ffffff",   // calendar popup and input background
    text:        "#1e293b",   // main text color
    textMuted:   "#94a3b8",   // muted text (day headers, placeholder, AD date)
    border:      "#e2e8f0",   // all borders
    todayBg:     "#dbeafe",   // today's date highlight background
    controlsBg:  "#eff6ff",   // month/year selector bar background
    radius:      "12px",      // border radius of the popup
    shadow:      "0 8px 32px rgba(0,0,0,0.12)",  // popup drop shadow
  }}
/>
```

**All `styles` keys and their CSS variables:**

| Key | CSS Variable | Default | Controls |
|---|---|---|---|
| `primary` | `--ndp-primary` | `#C0392B` | Header bg, selected day, accents |
| `primarySoft` | `--ndp-primary-soft` | `#fff0ee` | Hover background on days |
| `background` | `--ndp-background` | `#ffffff` | Input + popup background |
| `text` | `--ndp-text` | `#1A1208` | Main text |
| `textMuted` | `--ndp-text-muted` | `#8C7B6B` | Day headers, muted labels |
| `border` | `--ndp-border` | `#E8DED0` | All borders |
| `todayBg` | `--ndp-today-bg` | `#fde8e6` | Today's date cell background |
| `controlsBg` | `--ndp-controls-bg` | `#fffaee` | Month/year bar background |
| `radius` | `--ndp-radius` | `16px` | Popup corner radius |
| `shadow` | `--ndp-shadow` | `0 24px 64px …` | Popup drop shadow |

> **Note:** You don't need to pass all keys — only pass what you want to change. Unset keys keep their defaults.

---

## Utility Functions

Standalone BS↔AD helpers exported from the package.

```jsx
import { bsToAd, adToBs, getTodayBS } from "@himal_bhattarai/nepali-datepicker";
```

### `bsToAd(year, month, day)` → `Date`
Converts a BS date to a JavaScript `Date` object.
```js
bsToAd(2081, 11, 22)  // → Wed Mar 05 2025
```

### `adToBs(jsDate)` → `{ year, month, day }`
Converts a JavaScript `Date` to a BS date object.
```js
adToBs(new Date("2025-03-05"))  // → { year: 2081, month: 11, day: 22 }
```

### `getTodayBS()` → `{ year, month, day }`
Returns today's date in BS, always computed live from the browser clock.
```js
getTodayBS()  // → { year: 2082, month: 11, day: 22 }
```

---

## Examples

### Default (no config)
```jsx
<NepaliDatePicker value={date} onChange={(bs) => setDate(bs)} />
```

### English language + custom year range
```jsx
<NepaliDatePicker
  language="en"
  minYear={2075}
  maxYear={2085}
  placeholder="Select date"
  value={date}
  onChange={(bs, ad) => setDate(bs)}
/>
```

### Dark theme via `styles` prop
```jsx
<NepaliDatePicker
  value={date}
  onChange={(bs) => setDate(bs)}
  styles={{
    primary:    "#e05c4d",
    background: "#1e2235",
    text:       "#e2e8f0",
    textMuted:  "#94a3b8",
    border:     "#2d3554",
    todayBg:    "#1e3a5f",
    controlsBg: "#252a42",
  }}
/>
```

### Green theme via `className`
```css
/* app.css */
.green-picker {
  --ndp-primary: #16a34a;
  --ndp-primary-soft: #dcfce7;
  --ndp-today-bg: #bbf7d0;
  --ndp-border: #86efac;
  --ndp-controls-bg: #f0fdf4;
}
```
```jsx
<NepaliDatePicker
  className="green-picker"
  value={date}
  onChange={(bs) => setDate(bs)}
/>
```

### Sending BS date to a backend API
```jsx
<NepaliDatePicker
  value={date}
  onChange={(bs) => {
    setDate(bs);

    // Send BS date as separate fields
    fetch("/api/booking", {
      method: "POST",
      body: JSON.stringify({
        year:  bs.year,   // 2081
        month: bs.month,  // 11
        day:   bs.day,    // 22
      }),
    });
  }}
/>
```

Or as a formatted BS date string:
```jsx
onChange={(bs) => {
  setDate(bs);

  const bsFormatted = `${bs.year}-${String(bs.month).padStart(2,"0")}-${String(bs.day).padStart(2,"0")}`;
  // → "2081-11-22"

  fetch("/api/booking", {
    method: "POST",
    body: JSON.stringify({ date: bsFormatted }),
  });
}}
```

---

## How the Calendar Works

- **BS to AD** — computed at runtime using a single verified epoch: `BS 2000/1/1 = AD 1943/04/14`
- **Today's date** — always from `new Date()`, never hardcoded
- **Month lengths** — stored as a static lookup table (BS month lengths are astronomical, not mathematical)
- **Saturday** is highlighted as Nepal's weekly holiday (not Sunday)
- **Calendar grid** — always 6 rows × 7 columns (no layout shift between months)
- **Overflow days** — previous/next month's dates shown as dimmed, non-clickable

---

## BS Month Names

| # | Nepali | English |
|---|--------|---------|
| 1 | बैशाख | Baisakh |
| 2 | जेठ | Jestha |
| 3 | असार | Ashadh |
| 4 | श्रावण | Shrawan |
| 5 | भाद्र | Bhadra |
| 6 | असोज | Ashwin |
| 7 | कार्तिक | Kartik |
| 8 | मङ्सिर | Mangsir |
| 9 | पुष | Poush |
| 10 | माघ | Magh |
| 11 | फागुन | Falgun |
| 12 | चैत्र | Chaitra |

---

## Requirements

- React `>= 17`
- Modern browser (Chrome, Firefox, Safari, Edge)

---

## License

MIT © [Himal Bhattarai](https://github.com/himal-bhattarai)