@itzsa/nepali-datepicker 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,2145 @@
1
+ import * as React6 from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+
7
+ // src/calendar-data.ts
8
+ var BS_MONTH_DAYS = {
9
+ 2e3: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
10
+ 2001: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
11
+ 2002: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
12
+ 2003: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
13
+ 2004: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
14
+ 2005: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
15
+ 2006: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
16
+ 2007: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
17
+ 2008: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
18
+ 2009: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
19
+ 2010: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
20
+ 2011: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
21
+ 2012: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
22
+ 2013: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
23
+ 2014: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
24
+ 2015: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
25
+ 2016: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
26
+ 2017: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
27
+ 2018: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
28
+ 2019: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
29
+ 2020: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
30
+ 2021: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
31
+ 2022: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
32
+ 2023: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
33
+ 2024: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
34
+ 2025: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
35
+ 2026: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
36
+ 2027: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
37
+ 2028: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
38
+ 2029: [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
39
+ 2030: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
40
+ 2031: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
41
+ 2032: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
42
+ 2033: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
43
+ 2034: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
44
+ 2035: [30, 32, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
45
+ 2036: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
46
+ 2037: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
47
+ 2038: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
48
+ 2039: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
49
+ 2040: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
50
+ 2041: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
51
+ 2042: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
52
+ 2043: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
53
+ 2044: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
54
+ 2045: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
55
+ 2046: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
56
+ 2047: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
57
+ 2048: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
58
+ 2049: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
59
+ 2050: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
60
+ 2051: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
61
+ 2052: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
62
+ 2053: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
63
+ 2054: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
64
+ 2055: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
65
+ 2056: [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
66
+ 2057: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
67
+ 2058: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
68
+ 2059: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
69
+ 2060: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
70
+ 2061: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
71
+ 2062: [30, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31],
72
+ 2063: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
73
+ 2064: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
74
+ 2065: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
75
+ 2066: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
76
+ 2067: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
77
+ 2068: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
78
+ 2069: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
79
+ 2070: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
80
+ 2071: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
81
+ 2072: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
82
+ 2073: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
83
+ 2074: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
84
+ 2075: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
85
+ 2076: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
86
+ 2077: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
87
+ 2078: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
88
+ 2079: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
89
+ 2080: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
90
+ 2081: [31, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30],
91
+ 2082: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
92
+ 2083: [31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
93
+ 2084: [31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
94
+ 2085: [31, 32, 31, 32, 30, 31, 30, 30, 29, 30, 30, 30],
95
+ 2086: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
96
+ 2087: [31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30],
97
+ 2088: [30, 31, 32, 32, 30, 31, 30, 30, 29, 30, 30, 30],
98
+ 2089: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
99
+ 2090: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
100
+ 2091: [31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30],
101
+ 2092: [30, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30],
102
+ 2093: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
103
+ 2094: [31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
104
+ 2095: [31, 31, 32, 31, 31, 31, 30, 29, 30, 30, 30, 30],
105
+ 2096: [30, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
106
+ 2097: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
107
+ 2098: [31, 31, 32, 31, 31, 31, 29, 30, 29, 30, 30, 31],
108
+ 2099: [31, 31, 32, 31, 31, 31, 30, 29, 29, 30, 30, 30],
109
+ 2100: [31, 32, 31, 32, 30, 31, 30, 29, 30, 29, 30, 30]
110
+ };
111
+ var BS_MIN_YEAR = 2e3;
112
+ var BS_MAX_YEAR = 2100;
113
+ var BS_EPOCH_AD = { year: 1943, month: 4, day: 14 };
114
+
115
+ // src/convert.ts
116
+ var MS_PER_DAY = 864e5;
117
+ function assertYear(year) {
118
+ if (!Number.isInteger(year) || year < BS_MIN_YEAR || year > BS_MAX_YEAR) {
119
+ throw new RangeError(
120
+ `BS year must be an integer between ${BS_MIN_YEAR} and ${BS_MAX_YEAR} (got ${year})`
121
+ );
122
+ }
123
+ }
124
+ function assertMonth(month) {
125
+ if (!Number.isInteger(month) || month < 1 || month > 12) {
126
+ throw new RangeError(`Month must be an integer 1\u201312 (got ${month})`);
127
+ }
128
+ }
129
+ function getDaysInBsMonth(year, month) {
130
+ assertYear(year);
131
+ assertMonth(month);
132
+ return BS_MONTH_DAYS[year][month - 1];
133
+ }
134
+ function getDaysInBsYear(year) {
135
+ assertYear(year);
136
+ return BS_MONTH_DAYS[year].reduce((sum, d) => sum + d, 0);
137
+ }
138
+ function isValidBsDate(year, month, day) {
139
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
140
+ return false;
141
+ }
142
+ if (year < BS_MIN_YEAR || year > BS_MAX_YEAR) return false;
143
+ if (month < 1 || month > 12) return false;
144
+ if (day < 1) return false;
145
+ const max = BS_MONTH_DAYS[year]?.[month - 1];
146
+ if (max == null) return false;
147
+ return day <= max;
148
+ }
149
+ function assertBsDate(year, month, day) {
150
+ if (!isValidBsDate(year, month, day)) {
151
+ throw new RangeError(`Invalid BS date ${year}-${month}-${day}`);
152
+ }
153
+ }
154
+ function daysFromBsEpoch(year, month, day) {
155
+ assertBsDate(year, month, day);
156
+ let days = 0;
157
+ for (let y = BS_MIN_YEAR; y < year; y++) {
158
+ days += getDaysInBsYear(y);
159
+ }
160
+ for (let m = 1; m < month; m++) {
161
+ days += getDaysInBsMonth(year, m);
162
+ }
163
+ return days + (day - 1);
164
+ }
165
+ function utcCivilParts(ms) {
166
+ const d = new Date(ms);
167
+ return {
168
+ year: d.getUTCFullYear(),
169
+ month: d.getUTCMonth() + 1,
170
+ day: d.getUTCDate()
171
+ };
172
+ }
173
+ function utcMsFromParts(parts) {
174
+ return Date.UTC(parts.year, parts.month - 1, parts.day);
175
+ }
176
+ function bsToAd(year, month, day) {
177
+ const offset = daysFromBsEpoch(year, month, day);
178
+ const epochMs = utcMsFromParts(BS_EPOCH_AD);
179
+ return utcCivilParts(epochMs + offset * MS_PER_DAY);
180
+ }
181
+ function adToBs(year, month, day) {
182
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
183
+ throw new RangeError("AD year/month/day must be integers");
184
+ }
185
+ if (month < 1 || month > 12 || day < 1 || day > 31) {
186
+ throw new RangeError(`Invalid AD date ${year}-${month}-${day}`);
187
+ }
188
+ const epochMs = utcMsFromParts(BS_EPOCH_AD);
189
+ const targetMs = Date.UTC(year, month - 1, day);
190
+ let remaining = Math.round((targetMs - epochMs) / MS_PER_DAY);
191
+ if (remaining < 0) {
192
+ throw new RangeError(
193
+ `AD date ${year}-${month}-${day} is before supported BS range`
194
+ );
195
+ }
196
+ let bsYear = BS_MIN_YEAR;
197
+ while (bsYear <= BS_MAX_YEAR) {
198
+ const yearDays = getDaysInBsYear(bsYear);
199
+ if (remaining < yearDays) break;
200
+ remaining -= yearDays;
201
+ bsYear += 1;
202
+ }
203
+ if (bsYear > BS_MAX_YEAR) {
204
+ throw new RangeError(
205
+ `AD date ${year}-${month}-${day} is after supported BS range`
206
+ );
207
+ }
208
+ let bsMonth = 1;
209
+ while (bsMonth <= 12) {
210
+ const monthDays = getDaysInBsMonth(bsYear, bsMonth);
211
+ if (remaining < monthDays) break;
212
+ remaining -= monthDays;
213
+ bsMonth += 1;
214
+ }
215
+ return { year: bsYear, month: bsMonth, day: remaining + 1 };
216
+ }
217
+ function todayBs() {
218
+ const now = /* @__PURE__ */ new Date();
219
+ return adToBs(now.getFullYear(), now.getMonth() + 1, now.getDate());
220
+ }
221
+ function todayBsDateTime() {
222
+ const now = /* @__PURE__ */ new Date();
223
+ const date = adToBs(now.getFullYear(), now.getMonth() + 1, now.getDate());
224
+ return {
225
+ ...date,
226
+ hour: now.getHours(),
227
+ minute: now.getMinutes(),
228
+ second: now.getSeconds()
229
+ };
230
+ }
231
+ function getBsWeekday(year, month, day) {
232
+ const ad = bsToAd(year, month, day);
233
+ return new Date(Date.UTC(ad.year, ad.month - 1, ad.day)).getUTCDay();
234
+ }
235
+ function compareDateParts(a, b) {
236
+ if (a.year !== b.year) return a.year < b.year ? -1 : 1;
237
+ if (a.month !== b.month) return a.month < b.month ? -1 : 1;
238
+ if (a.day !== b.day) return a.day < b.day ? -1 : 1;
239
+ return 0;
240
+ }
241
+ function clampBsDate(parts, min, max) {
242
+ let next = parts;
243
+ if (min && compareDateParts(next, min) < 0) next = min;
244
+ if (max && compareDateParts(next, max) > 0) next = max;
245
+ return next;
246
+ }
247
+ function addBsMonths(year, month, delta) {
248
+ const idx = year * 12 + (month - 1) + delta;
249
+ const y = Math.floor(idx / 12);
250
+ const m = idx % 12 + 1;
251
+ if (y < BS_MIN_YEAR || y > BS_MAX_YEAR) {
252
+ throw new RangeError("Month navigation out of supported BS range");
253
+ }
254
+ return { year: y, month: m };
255
+ }
256
+ function diffBsDays(a, b) {
257
+ const adA = bsToAd(a.year, a.month, a.day);
258
+ const adB = bsToAd(b.year, b.month, b.day);
259
+ return Math.round(
260
+ (utcMsFromParts(adB) - utcMsFromParts(adA)) / MS_PER_DAY
261
+ );
262
+ }
263
+ function addBsDays(parts, delta) {
264
+ const ad = bsToAd(parts.year, parts.month, parts.day);
265
+ const next = utcCivilParts(utcMsFromParts(ad) + delta * MS_PER_DAY);
266
+ return adToBs(next.year, next.month, next.day);
267
+ }
268
+
269
+ // src/datetime.ts
270
+ function pad2(n) {
271
+ return n < 10 ? `0${n}` : String(n);
272
+ }
273
+ function isValidTime(hour, minute, second = 0) {
274
+ return Number.isInteger(hour) && Number.isInteger(minute) && Number.isInteger(second) && hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59;
275
+ }
276
+ function parseDateTimeString(value) {
277
+ const trimmed = value.trim().replace(/\//g, "-");
278
+ const m = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?$/.exec(
279
+ trimmed
280
+ );
281
+ if (!m) return null;
282
+ const year = Number(m[1]);
283
+ const month = Number(m[2]);
284
+ const day = Number(m[3]);
285
+ const hour = m[4] != null ? Number(m[4]) : 0;
286
+ const minute = m[5] != null ? Number(m[5]) : 0;
287
+ const second = m[6] != null ? Number(m[6]) : 0;
288
+ if (!isValidBsDate(year, month, day)) return null;
289
+ if (!isValidTime(hour, minute, second)) return null;
290
+ return { year, month, day, hour, minute, second };
291
+ }
292
+ function toDateTimeString(parts, opts) {
293
+ const base = `${parts.year}-${pad2(parts.month)}-${pad2(parts.day)} ${pad2(parts.hour)}:${pad2(parts.minute)}`;
294
+ if (opts?.withSeconds) {
295
+ return `${base}:${pad2(parts.second ?? 0)}`;
296
+ }
297
+ return base;
298
+ }
299
+ function dateTimeToDateParts(dt) {
300
+ return { year: dt.year, month: dt.month, day: dt.day };
301
+ }
302
+ function compareDateTimeParts(a, b) {
303
+ if (a.year !== b.year) return a.year < b.year ? -1 : 1;
304
+ if (a.month !== b.month) return a.month < b.month ? -1 : 1;
305
+ if (a.day !== b.day) return a.day < b.day ? -1 : 1;
306
+ if (a.hour !== b.hour) return a.hour < b.hour ? -1 : 1;
307
+ if (a.minute !== b.minute) return a.minute < b.minute ? -1 : 1;
308
+ const as = a.second ?? 0;
309
+ const bs = b.second ?? 0;
310
+ if (as !== bs) return as < bs ? -1 : 1;
311
+ return 0;
312
+ }
313
+ function clampDateTime(parts, min, max) {
314
+ let next = parts;
315
+ if (min && compareDateTimeParts(next, min) < 0) next = { ...min };
316
+ if (max && compareDateTimeParts(next, max) > 0) next = { ...max };
317
+ return next;
318
+ }
319
+ function parseDateTimeBound(value, edge) {
320
+ if (!value) return null;
321
+ const full = parseDateTimeString(value);
322
+ if (full) {
323
+ const hasTime = /[T ]\d/.test(value.trim());
324
+ if (!hasTime) {
325
+ return edge === "min" ? { ...full, hour: 0, minute: 0, second: 0 } : { ...full, hour: 23, minute: 59, second: 59 };
326
+ }
327
+ return full;
328
+ }
329
+ return null;
330
+ }
331
+ function isCompleteBsDateTime(value, opts) {
332
+ const dt = parseDateTimeString(value);
333
+ if (!dt) return false;
334
+ const hasTime = /[T ]\d{1,2}:\d{1,2}/.test(value.trim());
335
+ if (!hasTime) return false;
336
+ if (opts?.requireSeconds) {
337
+ return /:\d{1,2}:\d{1,2}/.test(value.trim());
338
+ }
339
+ return true;
340
+ }
341
+ function snapMinute(minute, step) {
342
+ const s = Math.max(1, Math.min(30, Math.floor(step)));
343
+ return Math.floor(minute / s) * s;
344
+ }
345
+
346
+ // src/locale.ts
347
+ var NEPALI_MONTH_NAMES_EN = [
348
+ "Baisakh",
349
+ "Jestha",
350
+ "Ashar",
351
+ "Shrawan",
352
+ "Bhadra",
353
+ "Ashwin",
354
+ "Kartik",
355
+ "Mangsir",
356
+ "Poush",
357
+ "Magh",
358
+ "Falgun",
359
+ "Chaitra"
360
+ ];
361
+ var NEPALI_MONTH_NAMES_NE = [
362
+ "\u092C\u0948\u0936\u093E\u0916",
363
+ "\u091C\u0947\u0920",
364
+ "\u0905\u0938\u093E\u0930",
365
+ "\u0938\u093E\u0909\u0928",
366
+ "\u092D\u0926\u094C",
367
+ "\u0905\u0938\u094B\u091C",
368
+ "\u0915\u093E\u0930\u094D\u0924\u093F\u0915",
369
+ "\u092E\u0902\u0938\u093F\u0930",
370
+ "\u092A\u0941\u0937",
371
+ "\u092E\u093E\u0918",
372
+ "\u092B\u093E\u0932\u094D\u0917\u0941\u0928",
373
+ "\u091A\u0948\u0924"
374
+ ];
375
+ var WEEKDAY_NAMES_EN = [
376
+ "Sun",
377
+ "Mon",
378
+ "Tue",
379
+ "Wed",
380
+ "Thu",
381
+ "Fri",
382
+ "Sat"
383
+ ];
384
+ var WEEKDAY_NAMES_NE = [
385
+ "\u0906\u0907\u0924",
386
+ "\u0938\u094B\u092E",
387
+ "\u092E\u0902\u0917\u0932",
388
+ "\u092C\u0941\u0927",
389
+ "\u092C\u093F\u0939\u0940",
390
+ "\u0936\u0941\u0915\u094D\u0930",
391
+ "\u0936\u0928\u093F"
392
+ ];
393
+ var DIGITS_NE = ["\u0966", "\u0967", "\u0968", "\u0969", "\u096A", "\u096B", "\u096C", "\u096D", "\u096E", "\u096F"];
394
+ function getMonthName(month, locale = "en") {
395
+ const idx = month - 1;
396
+ if (idx < 0 || idx > 11) return String(month);
397
+ return locale === "ne" ? NEPALI_MONTH_NAMES_NE[idx] : NEPALI_MONTH_NAMES_EN[idx];
398
+ }
399
+ function getWeekdayNames(locale = "en") {
400
+ return locale === "ne" ? WEEKDAY_NAMES_NE : WEEKDAY_NAMES_EN;
401
+ }
402
+ function localizeDigits(value, locale) {
403
+ const s = String(value);
404
+ if (locale !== "ne") return s;
405
+ return s.replace(/\d/g, (d) => DIGITS_NE[Number(d)]);
406
+ }
407
+
408
+ // src/format.ts
409
+ function pad22(n) {
410
+ return n < 10 ? `0${n}` : String(n);
411
+ }
412
+ var BS_DATE_COMPLETE = /^\d{4}[-/]\d{2}[-/]\d{2}$/;
413
+ function parseDateString(value) {
414
+ const trimmed = value.trim().replace(/\//g, "-");
415
+ const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(trimmed);
416
+ if (!m) return null;
417
+ const year = Number(m[1]);
418
+ const month = Number(m[2]);
419
+ const day = Number(m[3]);
420
+ if (!isValidBsDate(year, month, day)) return null;
421
+ return { year, month, day };
422
+ }
423
+ function formatTypedBsDate(raw) {
424
+ const digits = raw.replace(/\D/g, "").slice(0, 8);
425
+ if (digits.length <= 4) return digits;
426
+ if (digits.length <= 6) return `${digits.slice(0, 4)}-${digits.slice(4)}`;
427
+ return `${digits.slice(0, 4)}-${digits.slice(4, 6)}-${digits.slice(6)}`;
428
+ }
429
+ function isCompleteBsDate(value) {
430
+ const normalized = value.trim().replace(/\//g, "-");
431
+ if (!BS_DATE_COMPLETE.test(normalized)) return false;
432
+ return parseDateString(normalized) != null;
433
+ }
434
+ function toDateString(parts) {
435
+ return `${parts.year}-${pad22(parts.month)}-${pad22(parts.day)}`;
436
+ }
437
+ function formatDateParts(parts, pattern = "YYYY-MM-DD", locale = "en") {
438
+ const y = String(parts.year);
439
+ const m = pad22(parts.month);
440
+ const d = pad22(parts.day);
441
+ let out;
442
+ switch (pattern) {
443
+ case "YYYY/MM/DD":
444
+ out = `${y}/${m}/${d}`;
445
+ break;
446
+ case "DD-MM-YYYY":
447
+ out = `${d}-${m}-${y}`;
448
+ break;
449
+ case "DD/MM/YYYY":
450
+ out = `${d}/${m}/${y}`;
451
+ break;
452
+ default:
453
+ out = `${y}-${m}-${d}`;
454
+ }
455
+ return localizeDigits(out, locale);
456
+ }
457
+ function formatBsLabel(parts, locale = "en") {
458
+ const day = localizeDigits(parts.day, locale);
459
+ const month = getMonthName(parts.month, locale);
460
+ const year = localizeDigits(parts.year, locale);
461
+ return `${day} ${month} ${year}`;
462
+ }
463
+ function formatBsDateTimeLabel(parts, locale = "en", opts) {
464
+ const date = formatBsLabel(parts, locale);
465
+ const h = localizeDigits(pad22(parts.hour), locale);
466
+ const m = localizeDigits(pad22(parts.minute), locale);
467
+ if (opts?.withSeconds) {
468
+ const s = localizeDigits(pad22(parts.second ?? 0), locale);
469
+ return `${date}, ${h}:${m}:${s}`;
470
+ }
471
+ return `${date}, ${h}:${m}`;
472
+ }
473
+
474
+ // src/validate.ts
475
+ function assertBsYear(year) {
476
+ if (typeof year !== "number" || !Number.isInteger(year)) {
477
+ throw new TypeError("bsYear must be an integer");
478
+ }
479
+ if (year < BS_MIN_YEAR || year > BS_MAX_YEAR) {
480
+ throw new RangeError(
481
+ `bsYear must be between ${BS_MIN_YEAR} and ${BS_MAX_YEAR} (got ${year})`
482
+ );
483
+ }
484
+ }
485
+ function assertBsMonth(month) {
486
+ if (typeof month !== "number" || !Number.isInteger(month)) {
487
+ throw new TypeError("bsMonth must be an integer");
488
+ }
489
+ if (month < 1 || month > 12) {
490
+ throw new RangeError(`bsMonth must be 1\u201312 (got ${month})`);
491
+ }
492
+ }
493
+ function assertBsDay(day) {
494
+ if (typeof day !== "number" || !Number.isInteger(day)) {
495
+ throw new TypeError("bsDay must be an integer");
496
+ }
497
+ if (day < 1 || day > 32) {
498
+ throw new RangeError(`bsDay must be 1\u201332 (got ${day})`);
499
+ }
500
+ }
501
+ function validateBsDate(year, month, day) {
502
+ if (year == null || month == null || day == null) {
503
+ return {
504
+ ok: false,
505
+ code: "required",
506
+ message: "year, month, and day are required"
507
+ };
508
+ }
509
+ if (typeof year !== "number" || typeof month !== "number" || typeof day !== "number" || !Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
510
+ return {
511
+ ok: false,
512
+ code: "type",
513
+ message: "year, month, and day must be integers"
514
+ };
515
+ }
516
+ if (year < BS_MIN_YEAR || year > BS_MAX_YEAR) {
517
+ return {
518
+ ok: false,
519
+ code: "year_range",
520
+ message: `year must be ${BS_MIN_YEAR}\u2013${BS_MAX_YEAR}`
521
+ };
522
+ }
523
+ if (month < 1 || month > 12) {
524
+ return {
525
+ ok: false,
526
+ code: "month_range",
527
+ message: "month must be 1\u201312"
528
+ };
529
+ }
530
+ if (day < 1 || day > 32) {
531
+ return {
532
+ ok: false,
533
+ code: "day_range",
534
+ message: "day must be 1\u201332"
535
+ };
536
+ }
537
+ if (!isValidBsDate(year, month, day)) {
538
+ return {
539
+ ok: false,
540
+ code: "invalid_date",
541
+ message: `invalid BS date ${year}-${month}-${day}`
542
+ };
543
+ }
544
+ return { ok: true };
545
+ }
546
+ function validateBsDateParts(parts) {
547
+ return validateBsDate(parts.year, parts.month, parts.day);
548
+ }
549
+ function assertValidBsDate(year, month, day) {
550
+ const result = validateBsDate(year, month, day);
551
+ if (!result.ok) {
552
+ if (result.code === "type" || result.code === "required") {
553
+ throw new TypeError(result.message);
554
+ }
555
+ throw new RangeError(result.message);
556
+ }
557
+ }
558
+ function cn(...inputs) {
559
+ return twMerge(clsx(inputs));
560
+ }
561
+ function mergeRefs(...refs) {
562
+ return (value) => {
563
+ for (const ref of refs) {
564
+ if (!ref) continue;
565
+ if (typeof ref === "function") {
566
+ ref(value);
567
+ } else {
568
+ ref.current = value;
569
+ }
570
+ }
571
+ };
572
+ }
573
+ function CalendarIcon({ className }) {
574
+ return /* @__PURE__ */ jsxs(
575
+ "svg",
576
+ {
577
+ className,
578
+ width: "16",
579
+ height: "16",
580
+ viewBox: "0 0 24 24",
581
+ fill: "none",
582
+ stroke: "currentColor",
583
+ strokeWidth: "2",
584
+ strokeLinecap: "round",
585
+ strokeLinejoin: "round",
586
+ "aria-hidden": true,
587
+ children: [
588
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
589
+ /* @__PURE__ */ jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
590
+ ]
591
+ }
592
+ );
593
+ }
594
+ function Chevron({
595
+ dir,
596
+ className
597
+ }) {
598
+ return /* @__PURE__ */ jsx(
599
+ "svg",
600
+ {
601
+ className,
602
+ width: "16",
603
+ height: "16",
604
+ viewBox: "0 0 24 24",
605
+ fill: "none",
606
+ stroke: "currentColor",
607
+ strokeWidth: "2",
608
+ strokeLinecap: "round",
609
+ strokeLinejoin: "round",
610
+ "aria-hidden": true,
611
+ children: dir === "left" ? /* @__PURE__ */ jsx("path", { d: "M15 18l-6-6 6-6" }) : dir === "right" ? /* @__PURE__ */ jsx("path", { d: "M9 18l6-6-6-6" }) : /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" })
612
+ }
613
+ );
614
+ }
615
+ function usePortalReady() {
616
+ const [ready, setReady] = React6.useState(false);
617
+ React6.useEffect(() => {
618
+ setReady(true);
619
+ }, []);
620
+ return ready;
621
+ }
622
+ function useFloatingPopover(open, anchorRef, opts) {
623
+ const minWidth = opts?.minWidth ?? 280;
624
+ const estimatedHeight = opts?.estimatedHeight ?? 340;
625
+ const [pos, setPos] = React6.useState({
626
+ top: 0,
627
+ left: 0,
628
+ width: minWidth
629
+ });
630
+ const updatePosition = React6.useCallback(() => {
631
+ const el = anchorRef.current;
632
+ if (!el) return;
633
+ const rect = el.getBoundingClientRect();
634
+ const width = Math.max(minWidth, rect.width);
635
+ let left = rect.left;
636
+ if (left + width > window.innerWidth - 8) {
637
+ left = Math.max(8, window.innerWidth - width - 8);
638
+ }
639
+ const below = rect.bottom + 6;
640
+ const top = below + estimatedHeight > window.innerHeight && rect.top > estimatedHeight ? rect.top - estimatedHeight - 6 : below;
641
+ setPos({ top, left, width });
642
+ }, [anchorRef, minWidth, estimatedHeight]);
643
+ React6.useEffect(() => {
644
+ if (!open) return;
645
+ updatePosition();
646
+ const onScroll = () => updatePosition();
647
+ const onResize = () => updatePosition();
648
+ window.addEventListener("scroll", onScroll, true);
649
+ window.addEventListener("resize", onResize);
650
+ return () => {
651
+ window.removeEventListener("scroll", onScroll, true);
652
+ window.removeEventListener("resize", onResize);
653
+ };
654
+ }, [open, updatePosition]);
655
+ return { pos, updatePosition };
656
+ }
657
+ function useDismissOnOutside(open, onClose, refs) {
658
+ const refsRef = React6.useRef(refs);
659
+ refsRef.current = refs;
660
+ React6.useEffect(() => {
661
+ if (!open) return;
662
+ const onKey = (e) => {
663
+ if (e.key === "Escape") onClose();
664
+ };
665
+ const onPointer = (e) => {
666
+ const t = e.target;
667
+ for (const ref of refsRef.current) {
668
+ if (ref.current?.contains(t)) return;
669
+ }
670
+ onClose();
671
+ };
672
+ document.addEventListener("keydown", onKey);
673
+ document.addEventListener("mousedown", onPointer);
674
+ return () => {
675
+ document.removeEventListener("keydown", onKey);
676
+ document.removeEventListener("mousedown", onPointer);
677
+ };
678
+ }, [open, onClose]);
679
+ }
680
+ function CalendarMonth({
681
+ year,
682
+ month,
683
+ locale,
684
+ isDisabledDay,
685
+ getModifiers,
686
+ onDayClick,
687
+ onDayHover,
688
+ showHeader = true,
689
+ onPrevMonth,
690
+ onNextMonth,
691
+ canPrevMonth = true,
692
+ canNextMonth = true,
693
+ onMonthTitleClick,
694
+ onYearTitleClick
695
+ }) {
696
+ const weekdays = getWeekdayNames(locale);
697
+ const daysInMonth = getDaysInBsMonth(year, month);
698
+ const startWeekday = getBsWeekday(year, month, 1);
699
+ return /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-month", children: [
700
+ showHeader ? /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-header", children: [
701
+ onPrevMonth ? /* @__PURE__ */ jsx(
702
+ "button",
703
+ {
704
+ type: "button",
705
+ className: "itzsa-ndp-nav-btn",
706
+ disabled: !canPrevMonth,
707
+ "aria-label": "Previous month",
708
+ onClick: onPrevMonth,
709
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "left" })
710
+ }
711
+ ) : /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-nav-spacer" }),
712
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-header-title", children: [
713
+ onMonthTitleClick ? /* @__PURE__ */ jsx(
714
+ "button",
715
+ {
716
+ type: "button",
717
+ className: "itzsa-ndp-title-btn",
718
+ onClick: onMonthTitleClick,
719
+ children: getMonthName(month, locale)
720
+ }
721
+ ) : /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-title-static", children: getMonthName(month, locale) }),
722
+ onYearTitleClick ? /* @__PURE__ */ jsx(
723
+ "button",
724
+ {
725
+ type: "button",
726
+ className: "itzsa-ndp-title-btn",
727
+ onClick: onYearTitleClick,
728
+ children: localizeDigits(year, locale)
729
+ }
730
+ ) : /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-title-static", children: localizeDigits(year, locale) })
731
+ ] }),
732
+ onNextMonth ? /* @__PURE__ */ jsx(
733
+ "button",
734
+ {
735
+ type: "button",
736
+ className: "itzsa-ndp-nav-btn",
737
+ disabled: !canNextMonth,
738
+ "aria-label": "Next month",
739
+ onClick: onNextMonth,
740
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "right" })
741
+ }
742
+ ) : /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-nav-spacer" })
743
+ ] }) : null,
744
+ /* @__PURE__ */ jsx("div", { className: "itzsa-ndp-weekdays", children: weekdays.map((w) => /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-weekday", children: w }, w)) }),
745
+ /* @__PURE__ */ jsxs(
746
+ "div",
747
+ {
748
+ className: "itzsa-ndp-days",
749
+ role: "grid",
750
+ onMouseLeave: () => onDayHover?.(null),
751
+ children: [
752
+ Array.from({ length: startWeekday }).map((_, i) => /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-day is-empty" }, `e-${i}`)),
753
+ Array.from({ length: daysInMonth }, (_, i) => {
754
+ const day = i + 1;
755
+ const parts = { year, month, day };
756
+ const disabledDay = isDisabledDay(parts);
757
+ const mod = getModifiers(parts);
758
+ return /* @__PURE__ */ jsx(
759
+ "button",
760
+ {
761
+ type: "button",
762
+ role: "gridcell",
763
+ disabled: disabledDay || mod.disabled,
764
+ "aria-selected": mod.selected || mod.rangeStart || mod.rangeEnd,
765
+ className: cn(
766
+ "itzsa-ndp-day",
767
+ mod.selected && "is-selected",
768
+ mod.today && "is-today",
769
+ (disabledDay || mod.disabled) && "is-disabled",
770
+ mod.rangeStart && "is-range-start",
771
+ mod.rangeEnd && "is-range-end",
772
+ mod.inRange && "is-in-range",
773
+ mod.rangePreview && "is-range-preview"
774
+ ),
775
+ onClick: () => onDayClick(parts),
776
+ onMouseEnter: () => onDayHover?.(parts),
777
+ children: localizeDigits(day, locale)
778
+ },
779
+ day
780
+ );
781
+ })
782
+ ]
783
+ }
784
+ )
785
+ ] });
786
+ }
787
+ function SingleCalendarPanel({
788
+ locale,
789
+ view,
790
+ onViewChange,
791
+ selected,
792
+ today,
793
+ minYear = BS_MIN_YEAR,
794
+ maxYear = BS_MAX_YEAR,
795
+ isDisabledDay,
796
+ onDayClick,
797
+ onToday,
798
+ onClear,
799
+ showClear = false
800
+ }) {
801
+ const [mode, setMode] = React6.useState("days");
802
+ const yearStart = Math.floor(view.year / 12) * 12;
803
+ const years = Array.from({ length: 12 }, (_, i) => yearStart + i).filter(
804
+ (y) => y >= minYear && y <= maxYear
805
+ );
806
+ const canPrevMonth = (() => {
807
+ try {
808
+ return addBsMonths(view.year, view.month, -1).year >= minYear;
809
+ } catch {
810
+ return false;
811
+ }
812
+ })();
813
+ const canNextMonth = (() => {
814
+ try {
815
+ return addBsMonths(view.year, view.month, 1).year <= maxYear;
816
+ } catch {
817
+ return false;
818
+ }
819
+ })();
820
+ return /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-panel", children: [
821
+ mode === "days" ? /* @__PURE__ */ jsx(
822
+ CalendarMonth,
823
+ {
824
+ year: view.year,
825
+ month: view.month,
826
+ locale,
827
+ isDisabledDay,
828
+ getModifiers: (parts) => ({
829
+ selected: selected != null && compareDateParts(selected, parts) === 0,
830
+ today: compareDateParts(today, parts) === 0
831
+ }),
832
+ onDayClick,
833
+ canPrevMonth,
834
+ canNextMonth,
835
+ onPrevMonth: () => {
836
+ try {
837
+ onViewChange(addBsMonths(view.year, view.month, -1));
838
+ } catch {
839
+ }
840
+ },
841
+ onNextMonth: () => {
842
+ try {
843
+ onViewChange(addBsMonths(view.year, view.month, 1));
844
+ } catch {
845
+ }
846
+ },
847
+ onMonthTitleClick: () => setMode("months"),
848
+ onYearTitleClick: () => setMode("years")
849
+ }
850
+ ) : null,
851
+ mode === "months" ? /* @__PURE__ */ jsxs(Fragment, { children: [
852
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-header", children: [
853
+ /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-nav-spacer" }),
854
+ /* @__PURE__ */ jsx("div", { className: "itzsa-ndp-header-title", children: /* @__PURE__ */ jsx(
855
+ "button",
856
+ {
857
+ type: "button",
858
+ className: "itzsa-ndp-title-btn",
859
+ onClick: () => setMode("years"),
860
+ children: localizeDigits(view.year, locale)
861
+ }
862
+ ) }),
863
+ /* @__PURE__ */ jsx("span", { className: "itzsa-ndp-nav-spacer" })
864
+ ] }),
865
+ /* @__PURE__ */ jsx("div", { className: "itzsa-ndp-grid-months", children: Array.from({ length: 12 }, (_, i) => {
866
+ const month = i + 1;
867
+ return /* @__PURE__ */ jsx(
868
+ "button",
869
+ {
870
+ type: "button",
871
+ className: cn(
872
+ "itzsa-ndp-chip",
873
+ view.month === month && "is-active"
874
+ ),
875
+ onClick: () => {
876
+ onViewChange({ year: view.year, month });
877
+ setMode("days");
878
+ },
879
+ children: getMonthName(month, locale)
880
+ },
881
+ month
882
+ );
883
+ }) })
884
+ ] }) : null,
885
+ mode === "years" ? /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-grid-years", children: [
886
+ /* @__PURE__ */ jsx(
887
+ "button",
888
+ {
889
+ type: "button",
890
+ className: "itzsa-ndp-nav-btn itzsa-ndp-year-shift",
891
+ disabled: yearStart - 12 < minYear,
892
+ "aria-label": "Previous years",
893
+ onClick: () => onViewChange({
894
+ ...view,
895
+ year: Math.max(minYear, yearStart - 12)
896
+ }),
897
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "left" })
898
+ }
899
+ ),
900
+ /* @__PURE__ */ jsx("div", { className: "itzsa-ndp-year-list", children: years.map((y) => /* @__PURE__ */ jsx(
901
+ "button",
902
+ {
903
+ type: "button",
904
+ className: cn("itzsa-ndp-chip", view.year === y && "is-active"),
905
+ onClick: () => {
906
+ onViewChange({ ...view, year: y });
907
+ setMode("months");
908
+ },
909
+ children: localizeDigits(y, locale)
910
+ },
911
+ y
912
+ )) }),
913
+ /* @__PURE__ */ jsx(
914
+ "button",
915
+ {
916
+ type: "button",
917
+ className: "itzsa-ndp-nav-btn itzsa-ndp-year-shift",
918
+ disabled: yearStart + 12 > maxYear,
919
+ "aria-label": "Next years",
920
+ onClick: () => onViewChange({
921
+ ...view,
922
+ year: Math.min(maxYear, yearStart + 12)
923
+ }),
924
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "right" })
925
+ }
926
+ )
927
+ ] }) : null,
928
+ (onToday || onClear) && /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-footer", children: [
929
+ onToday ? /* @__PURE__ */ jsx(
930
+ "button",
931
+ {
932
+ type: "button",
933
+ className: "itzsa-ndp-footer-btn",
934
+ disabled: isDisabledDay(today),
935
+ onClick: onToday,
936
+ children: locale === "ne" ? "\u0906\u091C" : "Today"
937
+ }
938
+ ) : /* @__PURE__ */ jsx("span", {}),
939
+ showClear && onClear ? /* @__PURE__ */ jsx(
940
+ "button",
941
+ {
942
+ type: "button",
943
+ className: "itzsa-ndp-footer-btn",
944
+ onClick: onClear,
945
+ children: locale === "ne" ? "\u0916\u093E\u0932\u0940" : "Clear"
946
+ }
947
+ ) : null
948
+ ] })
949
+ ] });
950
+ }
951
+ function createIsDisabledDay(opts) {
952
+ return (parts) => {
953
+ if (parts.year < opts.minYear || parts.year > opts.maxYear) return true;
954
+ if (opts.minParts && compareDateParts(parts, opts.minParts) < 0) return true;
955
+ if (opts.maxParts && compareDateParts(parts, opts.maxParts) > 0) return true;
956
+ return false;
957
+ };
958
+ }
959
+
960
+ // src/styling.ts
961
+ var VAR_MAP = {
962
+ accent: "--ndp-accent",
963
+ accentForeground: "--ndp-accent-fg",
964
+ background: "--ndp-bg",
965
+ foreground: "--ndp-fg",
966
+ muted: "--ndp-muted",
967
+ border: "--ndp-border",
968
+ surface: "--ndp-surface",
969
+ radius: "--ndp-radius",
970
+ font: "--ndp-font"
971
+ };
972
+ function mergePickerStyle(vars, style) {
973
+ if (!vars && !style) return style;
974
+ const next = { ...style };
975
+ if (vars) {
976
+ for (const key of Object.keys(vars)) {
977
+ const value = vars[key];
978
+ if (value == null || value === "") continue;
979
+ next[VAR_MAP[key]] = value;
980
+ }
981
+ }
982
+ return next;
983
+ }
984
+ function parseBound(value) {
985
+ if (!value) return null;
986
+ return parseDateString(value);
987
+ }
988
+ var NepaliDatePicker = React6.forwardRef(function NepaliDatePicker2({
989
+ value: valueProp,
990
+ defaultValue = "",
991
+ onChange,
992
+ onSelect,
993
+ locale = "ne",
994
+ valueLocale,
995
+ minDate,
996
+ maxDate,
997
+ minYear = BS_MIN_YEAR,
998
+ maxYear = BS_MAX_YEAR,
999
+ closeOnSelect = true,
1000
+ todayIfEmpty = true,
1001
+ placeholder,
1002
+ disabled = false,
1003
+ readOnly = false,
1004
+ id,
1005
+ name,
1006
+ required,
1007
+ className,
1008
+ inputClassName,
1009
+ popoverClassName,
1010
+ classNames,
1011
+ vars,
1012
+ style,
1013
+ popoverStyle,
1014
+ "aria-label": ariaLabel,
1015
+ "aria-labelledby": ariaLabelledBy
1016
+ }, forwardedRef) {
1017
+ const displayLocale = valueLocale ?? locale;
1018
+ const rootStyle = mergePickerStyle(vars, style);
1019
+ const panelStyle = mergePickerStyle(vars, popoverStyle);
1020
+ const isControlled = valueProp !== void 0;
1021
+ const [uncontrolled, setUncontrolled] = React6.useState(defaultValue);
1022
+ const value = isControlled ? valueProp ?? "" : uncontrolled;
1023
+ const minParts = React6.useMemo(() => parseBound(minDate), [minDate]);
1024
+ const maxParts = React6.useMemo(() => parseBound(maxDate), [maxDate]);
1025
+ const selected = React6.useMemo(() => parseDateString(value), [value]);
1026
+ const today = React6.useMemo(() => todayBs(), []);
1027
+ const initialView = React6.useMemo(() => {
1028
+ if (selected) return selected;
1029
+ if (todayIfEmpty) return clampBsDate(today, minParts, maxParts);
1030
+ return {
1031
+ year: Math.min(Math.max(2080, minYear), maxYear),
1032
+ month: 1,
1033
+ day: 1
1034
+ };
1035
+ }, [selected, todayIfEmpty, today, minParts, maxParts, minYear, maxYear]);
1036
+ const [open, setOpen] = React6.useState(false);
1037
+ const [view, setView] = React6.useState({
1038
+ year: initialView.year,
1039
+ month: initialView.month
1040
+ });
1041
+ const rootRef = React6.useRef(null);
1042
+ const inputRef = React6.useRef(null);
1043
+ const popoverRef = React6.useRef(null);
1044
+ const portalReady = usePortalReady();
1045
+ const { pos } = useFloatingPopover(open, rootRef, {
1046
+ minWidth: 288,
1047
+ estimatedHeight: 360
1048
+ });
1049
+ React6.useImperativeHandle(
1050
+ forwardedRef,
1051
+ () => inputRef.current
1052
+ );
1053
+ React6.useEffect(() => {
1054
+ if (!open) return;
1055
+ const next = selected ?? (todayIfEmpty ? today : initialView);
1056
+ setView({ year: next.year, month: next.month });
1057
+ }, [open]);
1058
+ const close = React6.useCallback(() => setOpen(false), []);
1059
+ useDismissOnOutside(open, close, [rootRef, popoverRef]);
1060
+ const setValue = React6.useCallback(
1061
+ (next) => {
1062
+ if (!isControlled) setUncontrolled(next);
1063
+ onChange?.(next);
1064
+ },
1065
+ [isControlled, onChange]
1066
+ );
1067
+ const isDisabledDay = React6.useMemo(
1068
+ () => createIsDisabledDay({ minYear, maxYear, minParts, maxParts }),
1069
+ [minYear, maxYear, minParts, maxParts]
1070
+ );
1071
+ const pickParts = (parts) => {
1072
+ if (isDisabledDay(parts)) return;
1073
+ const str = toDateString(parts);
1074
+ setValue(str);
1075
+ onSelect?.(str);
1076
+ if (closeOnSelect) setOpen(false);
1077
+ };
1078
+ const displayValue = selected ? formatBsLabel(selected, displayLocale) : "";
1079
+ const popover = open && portalReady ? createPortal(
1080
+ /* @__PURE__ */ jsx(
1081
+ "div",
1082
+ {
1083
+ ref: popoverRef,
1084
+ className: cn(
1085
+ "itzsa-ndp-popover",
1086
+ popoverClassName,
1087
+ classNames?.popover
1088
+ ),
1089
+ "data-locale": locale,
1090
+ style: {
1091
+ position: "fixed",
1092
+ top: pos.top,
1093
+ left: pos.left,
1094
+ width: pos.width,
1095
+ zIndex: 50,
1096
+ ...panelStyle
1097
+ },
1098
+ role: "dialog",
1099
+ "aria-modal": "false",
1100
+ "aria-label": "Nepali calendar",
1101
+ children: /* @__PURE__ */ jsx(
1102
+ SingleCalendarPanel,
1103
+ {
1104
+ locale,
1105
+ view,
1106
+ onViewChange: setView,
1107
+ selected,
1108
+ today,
1109
+ minYear,
1110
+ maxYear,
1111
+ isDisabledDay,
1112
+ onDayClick: pickParts,
1113
+ showClear: Boolean(value),
1114
+ onToday: () => {
1115
+ const clamped = clampBsDate(today, minParts, maxParts);
1116
+ setView({ year: clamped.year, month: clamped.month });
1117
+ pickParts(clamped);
1118
+ },
1119
+ onClear: () => {
1120
+ setValue("");
1121
+ onSelect?.("");
1122
+ }
1123
+ }
1124
+ )
1125
+ }
1126
+ ),
1127
+ document.body
1128
+ ) : null;
1129
+ return /* @__PURE__ */ jsxs(
1130
+ "div",
1131
+ {
1132
+ ref: rootRef,
1133
+ className: cn("itzsa-ndp", className, classNames?.root),
1134
+ style: rootStyle,
1135
+ "data-locale": locale,
1136
+ "data-disabled": disabled ? "" : void 0,
1137
+ "data-open": open ? "" : void 0,
1138
+ children: [
1139
+ /* @__PURE__ */ jsxs("div", { className: cn("itzsa-ndp-field", classNames?.field), children: [
1140
+ /* @__PURE__ */ jsx(
1141
+ "input",
1142
+ {
1143
+ ref: inputRef,
1144
+ id,
1145
+ name,
1146
+ required,
1147
+ disabled,
1148
+ readOnly: true,
1149
+ placeholder: placeholder ?? (displayLocale === "ne" ? "\u092E\u093F\u0924\u093F \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : "Select date"),
1150
+ value: displayValue,
1151
+ "aria-label": ariaLabel,
1152
+ "aria-labelledby": ariaLabelledBy,
1153
+ "aria-expanded": open,
1154
+ "aria-haspopup": "dialog",
1155
+ className: cn("itzsa-ndp-input", inputClassName, classNames?.input),
1156
+ onClick: () => {
1157
+ if (!disabled && !readOnly) setOpen(true);
1158
+ },
1159
+ onFocus: () => {
1160
+ if (!disabled && !readOnly) setOpen(true);
1161
+ },
1162
+ onKeyDown: (e) => {
1163
+ if (disabled || readOnly) return;
1164
+ if (e.key === "Enter" || e.key === " ") {
1165
+ e.preventDefault();
1166
+ setOpen((o) => !o);
1167
+ }
1168
+ }
1169
+ }
1170
+ ),
1171
+ /* @__PURE__ */ jsx(
1172
+ "button",
1173
+ {
1174
+ type: "button",
1175
+ className: cn("itzsa-ndp-trigger", classNames?.trigger),
1176
+ tabIndex: -1,
1177
+ disabled: disabled || readOnly,
1178
+ "aria-label": "Open calendar",
1179
+ onClick: () => {
1180
+ if (!disabled && !readOnly) setOpen((o) => !o);
1181
+ },
1182
+ children: /* @__PURE__ */ jsx(CalendarIcon, {})
1183
+ }
1184
+ )
1185
+ ] }),
1186
+ popover
1187
+ ]
1188
+ }
1189
+ );
1190
+ });
1191
+ function parseBound2(value) {
1192
+ if (!value) return null;
1193
+ return parseDateString(value);
1194
+ }
1195
+ var EditableNepaliDatePicker = React6.forwardRef(function EditableNepaliDatePicker2({
1196
+ value: valueProp,
1197
+ defaultValue = "",
1198
+ onChange,
1199
+ onSelect,
1200
+ locale = "en",
1201
+ minDate,
1202
+ maxDate,
1203
+ minYear = BS_MIN_YEAR,
1204
+ maxYear = BS_MAX_YEAR,
1205
+ closeOnSelect = true,
1206
+ placeholder = "YYYY-MM-DD",
1207
+ disabled = false,
1208
+ readOnly = false,
1209
+ id,
1210
+ name,
1211
+ required,
1212
+ className,
1213
+ inputClassName,
1214
+ popoverClassName,
1215
+ classNames,
1216
+ vars,
1217
+ style,
1218
+ popoverStyle,
1219
+ "aria-label": ariaLabel,
1220
+ "aria-labelledby": ariaLabelledBy
1221
+ }, forwardedRef) {
1222
+ const isControlled = valueProp !== void 0;
1223
+ const rootStyle = mergePickerStyle(vars, style);
1224
+ const panelStyle = mergePickerStyle(vars, popoverStyle);
1225
+ const [uncontrolled, setUncontrolled] = React6.useState(defaultValue);
1226
+ const value = isControlled ? valueProp ?? "" : uncontrolled;
1227
+ const [localValue, setLocalValue] = React6.useState(value);
1228
+ const cursorPosRef = React6.useRef(null);
1229
+ React6.useEffect(() => {
1230
+ setLocalValue(value);
1231
+ }, [value]);
1232
+ const minParts = React6.useMemo(() => parseBound2(minDate), [minDate]);
1233
+ const maxParts = React6.useMemo(() => parseBound2(maxDate), [maxDate]);
1234
+ const selected = React6.useMemo(
1235
+ () => parseDateString(localValue.replace(/\//g, "-")),
1236
+ [localValue]
1237
+ );
1238
+ const today = React6.useMemo(() => todayBs(), []);
1239
+ const [open, setOpen] = React6.useState(false);
1240
+ const [view, setView] = React6.useState(() => {
1241
+ const t = todayBs();
1242
+ return { year: t.year, month: t.month };
1243
+ });
1244
+ const rootRef = React6.useRef(null);
1245
+ const inputRef = React6.useRef(null);
1246
+ const popoverRef = React6.useRef(null);
1247
+ const portalReady = usePortalReady();
1248
+ const { pos } = useFloatingPopover(open, rootRef, {
1249
+ minWidth: 288,
1250
+ estimatedHeight: 360
1251
+ });
1252
+ React6.useLayoutEffect(() => {
1253
+ if (cursorPosRef.current !== null && inputRef.current) {
1254
+ inputRef.current.setSelectionRange(
1255
+ cursorPosRef.current,
1256
+ cursorPosRef.current
1257
+ );
1258
+ cursorPosRef.current = null;
1259
+ }
1260
+ });
1261
+ React6.useEffect(() => {
1262
+ if (!open) return;
1263
+ const next = selected ?? clampBsDate(today, minParts, maxParts);
1264
+ setView({ year: next.year, month: next.month });
1265
+ }, [open]);
1266
+ const close = React6.useCallback(() => setOpen(false), []);
1267
+ useDismissOnOutside(open, close, [rootRef, popoverRef]);
1268
+ const commit = React6.useCallback(
1269
+ (next) => {
1270
+ setLocalValue(next);
1271
+ if (!isControlled) setUncontrolled(next);
1272
+ onChange?.(next);
1273
+ },
1274
+ [isControlled, onChange]
1275
+ );
1276
+ const isDisabledDay = React6.useMemo(
1277
+ () => createIsDisabledDay({ minYear, maxYear, minParts, maxParts }),
1278
+ [minYear, maxYear, minParts, maxParts]
1279
+ );
1280
+ const handleType = (e) => {
1281
+ const input = e.target;
1282
+ const selStart = input.selectionStart ?? 0;
1283
+ const raw = input.value;
1284
+ const formatted = formatTypedBsDate(raw);
1285
+ const digitsBeforeCursor = raw.slice(0, selStart).replace(/\D/g, "").length;
1286
+ let newPos = digitsBeforeCursor;
1287
+ if (digitsBeforeCursor > 4) newPos += 1;
1288
+ if (digitsBeforeCursor > 6) newPos += 1;
1289
+ cursorPosRef.current = Math.min(newPos, formatted.length);
1290
+ commit(formatted);
1291
+ };
1292
+ const pickParts = (parts) => {
1293
+ if (isDisabledDay(parts)) return;
1294
+ const str = toDateString(parts);
1295
+ commit(str);
1296
+ onSelect?.(str);
1297
+ if (closeOnSelect) setOpen(false);
1298
+ };
1299
+ const popover = open && portalReady ? createPortal(
1300
+ /* @__PURE__ */ jsx(
1301
+ "div",
1302
+ {
1303
+ ref: popoverRef,
1304
+ className: cn(
1305
+ "itzsa-ndp-popover",
1306
+ popoverClassName,
1307
+ classNames?.popover
1308
+ ),
1309
+ "data-locale": locale,
1310
+ style: {
1311
+ position: "fixed",
1312
+ top: pos.top,
1313
+ left: pos.left,
1314
+ width: pos.width,
1315
+ zIndex: 50,
1316
+ ...panelStyle
1317
+ },
1318
+ role: "dialog",
1319
+ "aria-modal": "false",
1320
+ "aria-label": "Nepali calendar",
1321
+ children: /* @__PURE__ */ jsx(
1322
+ SingleCalendarPanel,
1323
+ {
1324
+ locale,
1325
+ view,
1326
+ onViewChange: setView,
1327
+ selected,
1328
+ today,
1329
+ minYear,
1330
+ maxYear,
1331
+ isDisabledDay,
1332
+ onDayClick: pickParts,
1333
+ showClear: Boolean(localValue),
1334
+ onToday: () => {
1335
+ const clamped = clampBsDate(today, minParts, maxParts);
1336
+ setView({ year: clamped.year, month: clamped.month });
1337
+ pickParts(clamped);
1338
+ },
1339
+ onClear: () => {
1340
+ commit("");
1341
+ onSelect?.("");
1342
+ }
1343
+ }
1344
+ )
1345
+ }
1346
+ ),
1347
+ document.body
1348
+ ) : null;
1349
+ return /* @__PURE__ */ jsxs(
1350
+ "div",
1351
+ {
1352
+ ref: rootRef,
1353
+ className: cn(
1354
+ "itzsa-ndp itzsa-ndp-editable",
1355
+ className,
1356
+ classNames?.root
1357
+ ),
1358
+ style: rootStyle,
1359
+ "data-locale": locale,
1360
+ "data-disabled": disabled ? "" : void 0,
1361
+ "data-open": open ? "" : void 0,
1362
+ children: [
1363
+ /* @__PURE__ */ jsxs("div", { className: cn("itzsa-ndp-field", classNames?.field), children: [
1364
+ /* @__PURE__ */ jsx(
1365
+ "input",
1366
+ {
1367
+ ref: mergeRefs(forwardedRef, inputRef),
1368
+ id,
1369
+ name,
1370
+ required,
1371
+ disabled,
1372
+ readOnly,
1373
+ inputMode: "numeric",
1374
+ autoComplete: "off",
1375
+ spellCheck: false,
1376
+ placeholder,
1377
+ value: localValue,
1378
+ "aria-label": ariaLabel,
1379
+ "aria-labelledby": ariaLabelledBy,
1380
+ "aria-expanded": open,
1381
+ "aria-haspopup": "dialog",
1382
+ className: cn(
1383
+ "itzsa-ndp-input itzsa-ndp-input-editable",
1384
+ inputClassName,
1385
+ classNames?.input
1386
+ ),
1387
+ onChange: readOnly ? void 0 : handleType,
1388
+ onKeyDown: (e) => {
1389
+ if (disabled || readOnly) return;
1390
+ if (e.key === "ArrowDown" && (e.altKey || e.metaKey)) {
1391
+ e.preventDefault();
1392
+ setOpen(true);
1393
+ }
1394
+ }
1395
+ }
1396
+ ),
1397
+ /* @__PURE__ */ jsx(
1398
+ "button",
1399
+ {
1400
+ type: "button",
1401
+ className: cn("itzsa-ndp-trigger", classNames?.trigger),
1402
+ tabIndex: -1,
1403
+ disabled: disabled || readOnly,
1404
+ "aria-label": "Open calendar",
1405
+ onClick: () => {
1406
+ if (!disabled && !readOnly) setOpen((o) => !o);
1407
+ },
1408
+ children: /* @__PURE__ */ jsx(CalendarIcon, {})
1409
+ }
1410
+ )
1411
+ ] }),
1412
+ popover
1413
+ ]
1414
+ }
1415
+ );
1416
+ });
1417
+ function parseBound3(value) {
1418
+ if (!value) return null;
1419
+ return parseDateString(value);
1420
+ }
1421
+ function orderedRange(a, b) {
1422
+ return compareDateParts(a, b) <= 0 ? { from: a, to: b } : { from: b, to: a };
1423
+ }
1424
+ function inInclusiveRange(day, from, to) {
1425
+ return compareDateParts(day, from) >= 0 && compareDateParts(day, to) <= 0;
1426
+ }
1427
+ function NepaliDateRangePicker({
1428
+ value: valueProp,
1429
+ defaultValue = {},
1430
+ onChange,
1431
+ locale = "ne",
1432
+ valueLocale,
1433
+ minDate,
1434
+ maxDate,
1435
+ minYear = BS_MIN_YEAR,
1436
+ maxYear = BS_MAX_YEAR,
1437
+ numberOfMonths = 2,
1438
+ closeOnSelect = true,
1439
+ placeholder,
1440
+ disabled = false,
1441
+ className,
1442
+ triggerClassName,
1443
+ popoverClassName,
1444
+ classNames,
1445
+ vars,
1446
+ style,
1447
+ popoverStyle,
1448
+ id,
1449
+ "aria-label": ariaLabel
1450
+ }) {
1451
+ const displayLocale = valueLocale ?? locale;
1452
+ const rootStyle = mergePickerStyle(vars, style);
1453
+ const panelStyle = mergePickerStyle(vars, popoverStyle);
1454
+ const isControlled = valueProp !== void 0;
1455
+ const [uncontrolled, setUncontrolled] = React6.useState(defaultValue);
1456
+ const value = isControlled ? valueProp ?? {} : uncontrolled;
1457
+ const minParts = React6.useMemo(() => parseBound3(minDate), [minDate]);
1458
+ const maxParts = React6.useMemo(() => parseBound3(maxDate), [maxDate]);
1459
+ const fromParts = React6.useMemo(
1460
+ () => value.from ? parseDateString(value.from) : null,
1461
+ [value.from]
1462
+ );
1463
+ const toParts = React6.useMemo(
1464
+ () => value.to ? parseDateString(value.to) : null,
1465
+ [value.to]
1466
+ );
1467
+ const today = React6.useMemo(() => todayBs(), []);
1468
+ const [open, setOpen] = React6.useState(false);
1469
+ const [hover, setHover] = React6.useState(null);
1470
+ const [anchor, setAnchor] = React6.useState(null);
1471
+ const [leftView, setLeftView] = React6.useState(() => {
1472
+ const t = todayBs();
1473
+ return { year: t.year, month: t.month };
1474
+ });
1475
+ const rightView = React6.useMemo(() => {
1476
+ try {
1477
+ return addBsMonths(leftView.year, leftView.month, 1);
1478
+ } catch {
1479
+ return leftView;
1480
+ }
1481
+ }, [leftView]);
1482
+ const rootRef = React6.useRef(null);
1483
+ const popoverRef = React6.useRef(null);
1484
+ const portalReady = usePortalReady();
1485
+ const dual = numberOfMonths === 2;
1486
+ const { pos } = useFloatingPopover(open, rootRef, {
1487
+ minWidth: dual ? 560 : 288,
1488
+ estimatedHeight: 380
1489
+ });
1490
+ React6.useEffect(() => {
1491
+ if (!open) return;
1492
+ const base = fromParts ?? clampBsDate(today, minParts, maxParts);
1493
+ setLeftView({ year: base.year, month: base.month });
1494
+ setAnchor(fromParts && !toParts ? fromParts : null);
1495
+ setHover(null);
1496
+ }, [open]);
1497
+ const close = React6.useCallback(() => setOpen(false), []);
1498
+ useDismissOnOutside(open, close, [rootRef, popoverRef]);
1499
+ const commit = React6.useCallback(
1500
+ (next) => {
1501
+ if (!isControlled) setUncontrolled(next);
1502
+ onChange?.(next);
1503
+ },
1504
+ [isControlled, onChange]
1505
+ );
1506
+ const isDisabledDay = React6.useMemo(
1507
+ () => createIsDisabledDay({ minYear, maxYear, minParts, maxParts }),
1508
+ [minYear, maxYear, minParts, maxParts]
1509
+ );
1510
+ const previewTo = anchor && hover ? orderedRange(anchor, hover) : null;
1511
+ const getModifiers = (parts) => {
1512
+ const start = fromParts;
1513
+ const end = toParts;
1514
+ const preview = !end && previewTo ? previewTo : null;
1515
+ const solidInRange = start && end ? inInclusiveRange(parts, start, end) && compareDateParts(parts, start) !== 0 && compareDateParts(parts, end) !== 0 : false;
1516
+ const previewInRange = preview != null && inInclusiveRange(parts, preview.from, preview.to) && compareDateParts(parts, preview.from) !== 0 && compareDateParts(parts, preview.to) !== 0;
1517
+ return {
1518
+ today: compareDateParts(today, parts) === 0,
1519
+ rangeStart: Boolean(
1520
+ start && compareDateParts(parts, start) === 0 || preview && compareDateParts(parts, preview.from) === 0
1521
+ ),
1522
+ rangeEnd: Boolean(
1523
+ end && compareDateParts(parts, end) === 0 || preview && compareDateParts(parts, preview.to) === 0 && compareDateParts(preview.from, preview.to) !== 0
1524
+ ),
1525
+ inRange: Boolean(solidInRange || previewInRange),
1526
+ rangePreview: Boolean(previewInRange),
1527
+ selected: Boolean(
1528
+ start && compareDateParts(parts, start) === 0 || end && compareDateParts(parts, end) === 0
1529
+ )
1530
+ };
1531
+ };
1532
+ const onDayClick = (parts) => {
1533
+ if (isDisabledDay(parts)) return;
1534
+ if (!anchor) {
1535
+ setAnchor(parts);
1536
+ commit({ from: toDateString(parts), to: void 0 });
1537
+ return;
1538
+ }
1539
+ const { from, to } = orderedRange(anchor, parts);
1540
+ commit({ from: toDateString(from), to: toDateString(to) });
1541
+ setAnchor(null);
1542
+ setHover(null);
1543
+ if (closeOnSelect) setOpen(false);
1544
+ };
1545
+ const shiftLeft = (delta) => {
1546
+ try {
1547
+ setLeftView(addBsMonths(leftView.year, leftView.month, delta));
1548
+ } catch {
1549
+ }
1550
+ };
1551
+ const canPrev = (() => {
1552
+ try {
1553
+ return addBsMonths(leftView.year, leftView.month, -1).year >= minYear;
1554
+ } catch {
1555
+ return false;
1556
+ }
1557
+ })();
1558
+ const canNext = (() => {
1559
+ try {
1560
+ const step = dual ? 1 : 1;
1561
+ const next = addBsMonths(
1562
+ dual ? rightView.year : leftView.year,
1563
+ dual ? rightView.month : leftView.month,
1564
+ step
1565
+ );
1566
+ return next.year <= maxYear;
1567
+ } catch {
1568
+ return false;
1569
+ }
1570
+ })();
1571
+ const nights = fromParts && toParts ? Math.max(0, diffBsDays(fromParts, toParts)) : null;
1572
+ const label = (() => {
1573
+ if (fromParts && toParts) {
1574
+ return `${formatBsLabel(fromParts, displayLocale)} \u2013 ${formatBsLabel(toParts, displayLocale)}`;
1575
+ }
1576
+ if (fromParts) {
1577
+ return `${formatBsLabel(fromParts, displayLocale)} \u2013 \u2026`;
1578
+ }
1579
+ return placeholder ?? (displayLocale === "ne" ? "\u092E\u093F\u0924\u093F \u0926\u093E\u092F\u0930\u093E \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : "Pick a date range");
1580
+ })();
1581
+ const popover = open && portalReady ? createPortal(
1582
+ /* @__PURE__ */ jsxs(
1583
+ "div",
1584
+ {
1585
+ ref: popoverRef,
1586
+ className: cn(
1587
+ "itzsa-ndp-popover itzsa-ndp-popover-range",
1588
+ dual && "is-dual",
1589
+ popoverClassName,
1590
+ classNames?.popover
1591
+ ),
1592
+ "data-locale": locale,
1593
+ style: {
1594
+ position: "fixed",
1595
+ top: pos.top,
1596
+ left: pos.left,
1597
+ width: Math.max(pos.width, dual ? 560 : 288),
1598
+ zIndex: 50,
1599
+ ...panelStyle
1600
+ },
1601
+ role: "dialog",
1602
+ "aria-modal": "false",
1603
+ "aria-label": "Nepali date range",
1604
+ children: [
1605
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-range-toolbar", children: [
1606
+ /* @__PURE__ */ jsx(
1607
+ "button",
1608
+ {
1609
+ type: "button",
1610
+ className: "itzsa-ndp-nav-btn",
1611
+ disabled: !canPrev,
1612
+ "aria-label": "Previous month",
1613
+ onClick: () => shiftLeft(-1),
1614
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "left" })
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ jsx("p", { className: "itzsa-ndp-range-hint", children: locale === "ne" ? anchor || fromParts && !toParts ? "\u0905\u0928\u094D\u0924\u093F\u092E \u092E\u093F\u0924\u093F \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : "\u0938\u0941\u0930\u0941 \u092E\u093F\u0924\u093F \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : anchor || fromParts && !toParts ? "Select end date" : "Select start date" }),
1618
+ /* @__PURE__ */ jsx(
1619
+ "button",
1620
+ {
1621
+ type: "button",
1622
+ className: "itzsa-ndp-nav-btn",
1623
+ disabled: !canNext,
1624
+ "aria-label": "Next month",
1625
+ onClick: () => shiftLeft(1),
1626
+ children: /* @__PURE__ */ jsx(Chevron, { dir: "right" })
1627
+ }
1628
+ )
1629
+ ] }),
1630
+ /* @__PURE__ */ jsxs("div", { className: cn("itzsa-ndp-range-months", dual && "is-dual", classNames?.rangeMonths), children: [
1631
+ /* @__PURE__ */ jsx(
1632
+ CalendarMonth,
1633
+ {
1634
+ year: leftView.year,
1635
+ month: leftView.month,
1636
+ locale,
1637
+ isDisabledDay,
1638
+ getModifiers,
1639
+ onDayClick,
1640
+ onDayHover: setHover,
1641
+ showHeader: true,
1642
+ onPrevMonth: void 0,
1643
+ onNextMonth: void 0
1644
+ }
1645
+ ),
1646
+ dual ? /* @__PURE__ */ jsx(
1647
+ CalendarMonth,
1648
+ {
1649
+ year: rightView.year,
1650
+ month: rightView.month,
1651
+ locale,
1652
+ isDisabledDay,
1653
+ getModifiers,
1654
+ onDayClick,
1655
+ onDayHover: setHover,
1656
+ showHeader: true
1657
+ }
1658
+ ) : null
1659
+ ] }),
1660
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-footer itzsa-ndp-range-footer", children: [
1661
+ /* @__PURE__ */ jsx("p", { className: "itzsa-ndp-range-meta", children: nights != null ? locale === "ne" ? `${nights} \u0926\u093F\u0928` : `${nights} day${nights === 1 ? "" : "s"}` : locale === "ne" ? "\u0926\u093E\u092F\u0930\u093E \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : "Select a range" }),
1662
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-range-actions", children: [
1663
+ /* @__PURE__ */ jsx(
1664
+ "button",
1665
+ {
1666
+ type: "button",
1667
+ className: "itzsa-ndp-footer-btn",
1668
+ onClick: () => {
1669
+ commit({});
1670
+ setAnchor(null);
1671
+ setHover(null);
1672
+ },
1673
+ children: locale === "ne" ? "\u0916\u093E\u0932\u0940" : "Clear"
1674
+ }
1675
+ ),
1676
+ /* @__PURE__ */ jsx(
1677
+ "button",
1678
+ {
1679
+ type: "button",
1680
+ className: "itzsa-ndp-footer-btn is-primary",
1681
+ disabled: !fromParts || !toParts,
1682
+ onClick: () => setOpen(false),
1683
+ children: locale === "ne" ? "\u0920\u093F\u0915 \u091B" : "Done"
1684
+ }
1685
+ )
1686
+ ] })
1687
+ ] })
1688
+ ]
1689
+ }
1690
+ ),
1691
+ document.body
1692
+ ) : null;
1693
+ return /* @__PURE__ */ jsxs(
1694
+ "div",
1695
+ {
1696
+ ref: rootRef,
1697
+ className: cn("itzsa-ndp itzsa-ndp-range", className, classNames?.root),
1698
+ style: rootStyle,
1699
+ "data-locale": locale,
1700
+ "data-disabled": disabled ? "" : void 0,
1701
+ "data-open": open ? "" : void 0,
1702
+ children: [
1703
+ /* @__PURE__ */ jsxs(
1704
+ "button",
1705
+ {
1706
+ type: "button",
1707
+ id,
1708
+ disabled,
1709
+ "aria-label": ariaLabel,
1710
+ "aria-expanded": open,
1711
+ "aria-haspopup": "dialog",
1712
+ className: cn(
1713
+ "itzsa-ndp-range-trigger",
1714
+ triggerClassName,
1715
+ classNames?.rangeTrigger
1716
+ ),
1717
+ onClick: () => {
1718
+ if (!disabled) setOpen((o) => !o);
1719
+ },
1720
+ children: [
1721
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "itzsa-ndp-range-trigger-icon" }),
1722
+ /* @__PURE__ */ jsx(
1723
+ "span",
1724
+ {
1725
+ className: cn(
1726
+ "itzsa-ndp-range-trigger-label",
1727
+ !(fromParts || toParts) && "is-placeholder",
1728
+ classNames?.rangeLabel
1729
+ ),
1730
+ children: label
1731
+ }
1732
+ ),
1733
+ /* @__PURE__ */ jsx(Chevron, { dir: "down", className: "itzsa-ndp-range-trigger-chevron" })
1734
+ ]
1735
+ }
1736
+ ),
1737
+ popover
1738
+ ]
1739
+ }
1740
+ );
1741
+ }
1742
+ function TimeColumn({
1743
+ label,
1744
+ values,
1745
+ selected,
1746
+ locale,
1747
+ disabledValues,
1748
+ onPick
1749
+ }) {
1750
+ const listRef = React6.useRef(null);
1751
+ React6.useEffect(() => {
1752
+ const root = listRef.current;
1753
+ if (!root) return;
1754
+ const el = root.querySelector("[data-selected]");
1755
+ el?.scrollIntoView({ block: "center" });
1756
+ }, [selected]);
1757
+ return /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-time-col", children: [
1758
+ /* @__PURE__ */ jsx("p", { className: "itzsa-ndp-time-col-label", children: label }),
1759
+ /* @__PURE__ */ jsx("div", { ref: listRef, className: "itzsa-ndp-time-list", role: "listbox", children: values.map((n) => {
1760
+ const disabled = disabledValues?.has(n) ?? false;
1761
+ const isSel = n === selected;
1762
+ return /* @__PURE__ */ jsx(
1763
+ "button",
1764
+ {
1765
+ type: "button",
1766
+ role: "option",
1767
+ "aria-selected": isSel,
1768
+ "data-selected": isSel ? "" : void 0,
1769
+ disabled,
1770
+ className: cn(
1771
+ "itzsa-ndp-time-item",
1772
+ isSel && "is-selected",
1773
+ disabled && "is-disabled"
1774
+ ),
1775
+ onClick: () => onPick(n),
1776
+ children: localizeDigits(pad23(n), locale)
1777
+ },
1778
+ n
1779
+ );
1780
+ }) })
1781
+ ] });
1782
+ }
1783
+ function pad23(n) {
1784
+ return n < 10 ? `0${n}` : String(n);
1785
+ }
1786
+ var NepaliDateTimePicker = React6.forwardRef(function NepaliDateTimePicker2({
1787
+ value: valueProp,
1788
+ defaultValue = "",
1789
+ onChange,
1790
+ onSelect,
1791
+ locale = "ne",
1792
+ valueLocale,
1793
+ minDateTime,
1794
+ minDate,
1795
+ maxDateTime,
1796
+ maxDate,
1797
+ minYear = BS_MIN_YEAR,
1798
+ maxYear = BS_MAX_YEAR,
1799
+ minuteStep = 5,
1800
+ withSeconds = false,
1801
+ closeOnSelect = true,
1802
+ todayIfEmpty = true,
1803
+ placeholder,
1804
+ disabled = false,
1805
+ readOnly = false,
1806
+ id,
1807
+ name,
1808
+ required,
1809
+ className,
1810
+ inputClassName,
1811
+ popoverClassName,
1812
+ classNames,
1813
+ vars,
1814
+ style,
1815
+ popoverStyle,
1816
+ "aria-label": ariaLabel,
1817
+ "aria-labelledby": ariaLabelledBy
1818
+ }, forwardedRef) {
1819
+ const displayLocale = valueLocale ?? locale;
1820
+ const rootStyle = mergePickerStyle(vars, style);
1821
+ const panelStyle = mergePickerStyle(vars, popoverStyle);
1822
+ const isControlled = valueProp !== void 0;
1823
+ const [uncontrolled, setUncontrolled] = React6.useState(defaultValue);
1824
+ const value = isControlled ? valueProp ?? "" : uncontrolled;
1825
+ const minBound = React6.useMemo(
1826
+ () => parseDateTimeBound(minDateTime ?? minDate, "min"),
1827
+ [minDateTime, minDate]
1828
+ );
1829
+ const maxBound = React6.useMemo(
1830
+ () => parseDateTimeBound(maxDateTime ?? maxDate, "max"),
1831
+ [maxDateTime, maxDate]
1832
+ );
1833
+ const selected = React6.useMemo(() => parseDateTimeString(value), [value]);
1834
+ const todayDate = React6.useMemo(() => todayBs(), []);
1835
+ const nowDt = React6.useMemo(() => todayBsDateTime(), []);
1836
+ const [open, setOpen] = React6.useState(false);
1837
+ const [draft, setDraft] = React6.useState(
1838
+ () => clampDateTime(
1839
+ selected ?? (todayIfEmpty ? nowDt : { ...nowDt, hour: 0, minute: 0, second: 0 }),
1840
+ minBound,
1841
+ maxBound
1842
+ )
1843
+ );
1844
+ const [view, setView] = React6.useState({
1845
+ year: draft.year,
1846
+ month: draft.month
1847
+ });
1848
+ const rootRef = React6.useRef(null);
1849
+ const inputRef = React6.useRef(null);
1850
+ const popoverRef = React6.useRef(null);
1851
+ const portalReady = usePortalReady();
1852
+ const { pos } = useFloatingPopover(open, rootRef, {
1853
+ minWidth: 320,
1854
+ estimatedHeight: 420
1855
+ });
1856
+ React6.useImperativeHandle(
1857
+ forwardedRef,
1858
+ () => inputRef.current
1859
+ );
1860
+ React6.useEffect(() => {
1861
+ if (!open) return;
1862
+ const base = selected ?? (todayIfEmpty ? nowDt : { year: 2080, month: 1, day: 1, hour: 0, minute: 0, second: 0 });
1863
+ const next = clampDateTime(
1864
+ {
1865
+ ...base,
1866
+ minute: snapMinute(base.minute, minuteStep),
1867
+ second: withSeconds ? base.second ?? 0 : 0
1868
+ },
1869
+ minBound,
1870
+ maxBound
1871
+ );
1872
+ setDraft(next);
1873
+ setView({ year: next.year, month: next.month });
1874
+ }, [open]);
1875
+ const close = React6.useCallback(() => setOpen(false), []);
1876
+ useDismissOnOutside(open, close, [rootRef, popoverRef]);
1877
+ const commit = React6.useCallback(
1878
+ (parts) => {
1879
+ const clamped = clampDateTime(parts, minBound, maxBound);
1880
+ const str = toDateTimeString(clamped, { withSeconds });
1881
+ if (!isControlled) setUncontrolled(str);
1882
+ onChange?.(str);
1883
+ onSelect?.(str);
1884
+ if (closeOnSelect) setOpen(false);
1885
+ },
1886
+ [minBound, maxBound, withSeconds, isControlled, onChange, onSelect, closeOnSelect]
1887
+ );
1888
+ const minParts = minBound ? dateTimeToDateParts(minBound) : null;
1889
+ const maxParts = maxBound ? dateTimeToDateParts(maxBound) : null;
1890
+ const isDisabledDay = React6.useMemo(
1891
+ () => createIsDisabledDay({ minYear, maxYear, minParts, maxParts }),
1892
+ [minYear, maxYear, minParts, maxParts]
1893
+ );
1894
+ const setDraftClamped = (next) => {
1895
+ setDraft(clampDateTime(next, minBound, maxBound));
1896
+ };
1897
+ const onDayClick = (parts) => {
1898
+ if (isDisabledDay(parts)) return;
1899
+ setDraftClamped({
1900
+ ...parts,
1901
+ hour: draft.hour,
1902
+ minute: draft.minute,
1903
+ second: draft.second ?? 0
1904
+ });
1905
+ };
1906
+ const hours = Array.from({ length: 24 }, (_, i) => i);
1907
+ const minutes = Array.from(
1908
+ { length: Math.floor(60 / Math.max(1, minuteStep)) },
1909
+ (_, i) => i * Math.max(1, minuteStep)
1910
+ );
1911
+ const seconds = Array.from({ length: 60 }, (_, i) => i);
1912
+ const disabledHours = React6.useMemo(() => {
1913
+ const set = /* @__PURE__ */ new Set();
1914
+ for (const h of hours) {
1915
+ const probe = {
1916
+ ...draft,
1917
+ hour: h,
1918
+ minute: 0,
1919
+ second: 0
1920
+ };
1921
+ const hi = {
1922
+ ...draft,
1923
+ hour: h,
1924
+ minute: 59,
1925
+ second: 59
1926
+ };
1927
+ if (minBound && compareDateTimeParts(hi, minBound) < 0) set.add(h);
1928
+ if (maxBound && compareDateTimeParts(probe, maxBound) > 0) set.add(h);
1929
+ }
1930
+ return set;
1931
+ }, [draft, minBound, maxBound, hours]);
1932
+ const disabledMinutes = React6.useMemo(() => {
1933
+ const set = /* @__PURE__ */ new Set();
1934
+ for (const m of minutes) {
1935
+ const probe = {
1936
+ ...draft,
1937
+ minute: m,
1938
+ second: 0
1939
+ };
1940
+ const hi = {
1941
+ ...draft,
1942
+ minute: m,
1943
+ second: 59
1944
+ };
1945
+ if (minBound && compareDateTimeParts(hi, minBound) < 0) set.add(m);
1946
+ if (maxBound && compareDateTimeParts(probe, maxBound) > 0) set.add(m);
1947
+ }
1948
+ return set;
1949
+ }, [draft, minBound, maxBound, minutes]);
1950
+ const displayValue = selected ? formatBsDateTimeLabel(selected, displayLocale, { withSeconds }) : "";
1951
+ const popover = open && portalReady ? createPortal(
1952
+ /* @__PURE__ */ jsxs(
1953
+ "div",
1954
+ {
1955
+ ref: popoverRef,
1956
+ className: cn(
1957
+ "itzsa-ndp-popover itzsa-ndp-popover-datetime",
1958
+ popoverClassName,
1959
+ classNames?.popover
1960
+ ),
1961
+ "data-locale": locale,
1962
+ style: {
1963
+ position: "fixed",
1964
+ top: pos.top,
1965
+ left: pos.left,
1966
+ width: Math.max(pos.width, 320),
1967
+ zIndex: 50,
1968
+ ...panelStyle
1969
+ },
1970
+ role: "dialog",
1971
+ "aria-modal": "false",
1972
+ "aria-label": "Nepali date and time",
1973
+ children: [
1974
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-datetime-layout", children: [
1975
+ /* @__PURE__ */ jsx(
1976
+ SingleCalendarPanel,
1977
+ {
1978
+ locale,
1979
+ view,
1980
+ onViewChange: setView,
1981
+ selected: dateTimeToDateParts(draft),
1982
+ today: todayDate,
1983
+ minYear,
1984
+ maxYear,
1985
+ isDisabledDay,
1986
+ onDayClick
1987
+ }
1988
+ ),
1989
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-time-panel", children: [
1990
+ /* @__PURE__ */ jsx("p", { className: "itzsa-ndp-time-heading", children: locale === "ne" ? "\u0938\u092E\u092F" : "Time" }),
1991
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-time-cols", children: [
1992
+ /* @__PURE__ */ jsx(
1993
+ TimeColumn,
1994
+ {
1995
+ label: locale === "ne" ? "\u0918\u0923\u094D\u091F\u093E" : "Hour",
1996
+ values: hours,
1997
+ selected: draft.hour,
1998
+ locale,
1999
+ disabledValues: disabledHours,
2000
+ onPick: (hour) => setDraftClamped({ ...draft, hour })
2001
+ }
2002
+ ),
2003
+ /* @__PURE__ */ jsx(
2004
+ TimeColumn,
2005
+ {
2006
+ label: locale === "ne" ? "\u092E\u093F\u0928\u0947\u091F" : "Min",
2007
+ values: minutes,
2008
+ selected: snapMinute(draft.minute, minuteStep),
2009
+ locale,
2010
+ disabledValues: disabledMinutes,
2011
+ onPick: (minute) => setDraftClamped({ ...draft, minute })
2012
+ }
2013
+ ),
2014
+ withSeconds ? /* @__PURE__ */ jsx(
2015
+ TimeColumn,
2016
+ {
2017
+ label: locale === "ne" ? "\u0938\u0947\u0915\u0947\u0928\u094D\u0921" : "Sec",
2018
+ values: seconds,
2019
+ selected: draft.second ?? 0,
2020
+ locale,
2021
+ onPick: (second) => setDraftClamped({ ...draft, second })
2022
+ }
2023
+ ) : null
2024
+ ] })
2025
+ ] })
2026
+ ] }),
2027
+ /* @__PURE__ */ jsxs("div", { className: cn("itzsa-ndp-footer", classNames?.footer), children: [
2028
+ /* @__PURE__ */ jsx(
2029
+ "button",
2030
+ {
2031
+ type: "button",
2032
+ className: "itzsa-ndp-footer-btn",
2033
+ onClick: () => {
2034
+ const now = todayBsDateTime();
2035
+ const t = clampDateTime(
2036
+ {
2037
+ ...now,
2038
+ minute: snapMinute(now.minute, minuteStep),
2039
+ second: withSeconds ? now.second : 0
2040
+ },
2041
+ minBound,
2042
+ maxBound
2043
+ );
2044
+ setDraft(t);
2045
+ setView({ year: t.year, month: t.month });
2046
+ },
2047
+ children: locale === "ne" ? "\u0905\u0939\u093F\u0932\u0947" : "Now"
2048
+ }
2049
+ ),
2050
+ /* @__PURE__ */ jsxs("div", { className: "itzsa-ndp-range-actions", children: [
2051
+ value ? /* @__PURE__ */ jsx(
2052
+ "button",
2053
+ {
2054
+ type: "button",
2055
+ className: "itzsa-ndp-footer-btn",
2056
+ onClick: () => {
2057
+ if (!isControlled) setUncontrolled("");
2058
+ onChange?.("");
2059
+ onSelect?.("");
2060
+ },
2061
+ children: locale === "ne" ? "\u0916\u093E\u0932\u0940" : "Clear"
2062
+ }
2063
+ ) : null,
2064
+ /* @__PURE__ */ jsx(
2065
+ "button",
2066
+ {
2067
+ type: "button",
2068
+ className: "itzsa-ndp-footer-btn is-primary",
2069
+ onClick: () => commit(draft),
2070
+ children: locale === "ne" ? "\u0920\u093F\u0915 \u091B" : "Confirm"
2071
+ }
2072
+ )
2073
+ ] })
2074
+ ] })
2075
+ ]
2076
+ }
2077
+ ),
2078
+ document.body
2079
+ ) : null;
2080
+ return /* @__PURE__ */ jsxs(
2081
+ "div",
2082
+ {
2083
+ ref: rootRef,
2084
+ className: cn("itzsa-ndp itzsa-ndp-datetime", className, classNames?.root),
2085
+ style: rootStyle,
2086
+ "data-locale": locale,
2087
+ "data-disabled": disabled ? "" : void 0,
2088
+ "data-open": open ? "" : void 0,
2089
+ children: [
2090
+ /* @__PURE__ */ jsxs("div", { className: cn("itzsa-ndp-field", classNames?.field), children: [
2091
+ /* @__PURE__ */ jsx(
2092
+ "input",
2093
+ {
2094
+ ref: inputRef,
2095
+ id,
2096
+ name,
2097
+ required,
2098
+ disabled,
2099
+ readOnly: true,
2100
+ placeholder: placeholder ?? (displayLocale === "ne" ? "\u092E\u093F\u0924\u093F \u0930 \u0938\u092E\u092F \u091B\u093E\u0928\u094D\u0928\u0941\u0939\u094B\u0938\u094D" : "Select date & time"),
2101
+ value: displayValue,
2102
+ "aria-label": ariaLabel,
2103
+ "aria-labelledby": ariaLabelledBy,
2104
+ "aria-expanded": open,
2105
+ "aria-haspopup": "dialog",
2106
+ className: cn("itzsa-ndp-input", inputClassName, classNames?.input),
2107
+ onClick: () => {
2108
+ if (!disabled && !readOnly) setOpen(true);
2109
+ },
2110
+ onFocus: () => {
2111
+ if (!disabled && !readOnly) setOpen(true);
2112
+ },
2113
+ onKeyDown: (e) => {
2114
+ if (disabled || readOnly) return;
2115
+ if (e.key === "Enter" || e.key === " ") {
2116
+ e.preventDefault();
2117
+ setOpen((o) => !o);
2118
+ }
2119
+ }
2120
+ }
2121
+ ),
2122
+ /* @__PURE__ */ jsx(
2123
+ "button",
2124
+ {
2125
+ type: "button",
2126
+ className: cn("itzsa-ndp-trigger", classNames?.trigger),
2127
+ tabIndex: -1,
2128
+ disabled: disabled || readOnly,
2129
+ "aria-label": "Open date and time picker",
2130
+ onClick: () => {
2131
+ if (!disabled && !readOnly) setOpen((o) => !o);
2132
+ },
2133
+ children: /* @__PURE__ */ jsx(CalendarIcon, {})
2134
+ }
2135
+ )
2136
+ ] }),
2137
+ popover
2138
+ ]
2139
+ }
2140
+ );
2141
+ });
2142
+
2143
+ export { BS_EPOCH_AD, BS_MAX_YEAR, BS_MIN_YEAR, BS_MONTH_DAYS, EditableNepaliDatePicker, NEPALI_MONTH_NAMES_EN, NEPALI_MONTH_NAMES_NE, NepaliDatePicker, NepaliDateRangePicker, NepaliDateTimePicker, WEEKDAY_NAMES_EN, WEEKDAY_NAMES_NE, adToBs, addBsDays, addBsMonths, assertBsDay, assertBsMonth, assertBsYear, assertValidBsDate, bsToAd, clampBsDate, clampDateTime, cn, compareDateParts, compareDateTimeParts, dateTimeToDateParts, diffBsDays, formatBsDateTimeLabel, formatBsLabel, formatDateParts, formatTypedBsDate, getBsWeekday, getDaysInBsMonth, getDaysInBsYear, getMonthName, getWeekdayNames, isCompleteBsDate, isCompleteBsDateTime, isValidBsDate, localizeDigits, mergeRefs, parseDateString, parseDateTimeBound, parseDateTimeString, snapMinute, toDateString, toDateTimeString, todayBs, todayBsDateTime, validateBsDate, validateBsDateParts };
2144
+ //# sourceMappingURL=index.mjs.map
2145
+ //# sourceMappingURL=index.mjs.map