@nepdatejs/datepicker 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,420 @@
1
+ import { AdDate, BsDate, CalendarDate, CalendarSystem, DateFormatPattern, LocaleCode, TimeOfDay, Weekday } from "@nepdatejs/core";
2
+ import { CalendarState, CalendarStore, EventMarker, HolidayInput, HolidayLookup } from "@nepdatejs/calendar";
3
+ //#region src/presets.d.ts
4
+ /** Built-in shortcuts for a single date. */
5
+ type SinglePresetId = "today" | "yesterday" | "tomorrow";
6
+ /** Built-in shortcuts for a range. Weeks, months and years count in the calendar on screen. */
7
+ type RangePresetId = "today" | "yesterday" | "thisWeek" | "lastWeek" | "last7Days" | "last30Days" | "thisMonth" | "lastMonth" | "thisYear" | "thisFiscalYear" | "lastFiscalYear";
8
+ /** What a preset gets to work out its date: today (in the configured zone), the calendar on screen, the week start. */
9
+ interface PresetContext {
10
+ readonly today: AdDate;
11
+ readonly calendar: CalendarSystem;
12
+ readonly weekStartsOn: Weekday;
13
+ }
14
+ interface PresetRange {
15
+ readonly start: CalendarDate;
16
+ readonly end: CalendarDate;
17
+ }
18
+ /** An app-defined shortcut, e.g. { id: 'admission', label: 'Admission day', resolve: () => bsDate(2083, 1, 15) }. */
19
+ interface CustomPreset<R> {
20
+ readonly id: string;
21
+ readonly label: string;
22
+ readonly resolve: (context: PresetContext) => R;
23
+ }
24
+ type SinglePreset = SinglePresetId | CustomPreset<CalendarDate>;
25
+ type RangePreset = RangePresetId | CustomPreset<PresetRange>;
26
+ /** One shortcut as the panel shows it. */
27
+ interface PresetState {
28
+ readonly id: string;
29
+ readonly label: string;
30
+ /** The current value is exactly this preset's date or range. */
31
+ readonly isActive: boolean;
32
+ /** Outside min/max, too short/long, or outside the BS table. */
33
+ readonly isDisabled: boolean;
34
+ }
35
+ /** The date a built-in single preset stands for. */
36
+ export declare function resolveSinglePreset(id: SinglePresetId, context: PresetContext): CalendarDate;
37
+ /** The range a built-in range preset stands for, in the calendar on screen. */
38
+ export declare function resolveRangePreset(id: RangePresetId, context: PresetContext): PresetRange;
39
+ //#endregion
40
+ //#region src/types.d.ts
41
+ /** The same day in both calendars, sent with every change. */
42
+ interface DateDetail {
43
+ readonly ad: AdDate;
44
+ readonly bs: BsDate;
45
+ }
46
+ type DateErrorCode = "format" | "range" | "disabled" | "tooShort" | "tooLong" | "tooMany";
47
+ interface DateError {
48
+ readonly code: DateErrorCode;
49
+ /** Already translated for the picker's locale. */
50
+ readonly message: string;
51
+ }
52
+ /** Options both pickers share. Dates in options are AD "YYYY-MM-DD" strings (docs/plan D-003). */
53
+ interface PickerBaseOptions {
54
+ /** Show and type dates in this calendar only, and hide the BS/AD switch. */
55
+ readonly calendar?: CalendarSystem | undefined;
56
+ /** The calendar shown first when switching is allowed. Default 'BS'. */
57
+ readonly defaultCalendar?: CalendarSystem | undefined;
58
+ /** Called when the user switches BS/AD (adapters may remember it). */
59
+ readonly onCalendarChange?: ((calendar: CalendarSystem) => void) | undefined;
60
+ /** Earliest and latest allowed days, as AD "YYYY-MM-DD". */
61
+ readonly min?: string | undefined;
62
+ readonly max?: string | undefined;
63
+ readonly isDateDisabled?: ((date: CalendarDate) => boolean) | undefined;
64
+ readonly locale?: LocaleCode | undefined;
65
+ /** How the input shows a date. Default 'iso' (YYYY-MM-DD), which can be typed back. */
66
+ readonly displayFormat?: DateFormatPattern | undefined;
67
+ /** Close the panel after a pick. Default true. */
68
+ readonly closeOnSelect?: boolean | undefined;
69
+ /** Show the calendar in the page, always open, instead of in a popover. Default false. */
70
+ readonly inline?: boolean | undefined;
71
+ /** Add the dashes of YYYY-MM-DD while the user types digits. Default true. */
72
+ readonly mask?: boolean | undefined;
73
+ readonly holidays?: readonly HolidayInput[] | HolidayLookup | undefined;
74
+ readonly events?: ((date: CalendarDate) => readonly EventMarker[]) | undefined;
75
+ readonly showOtherCalendar?: boolean | undefined;
76
+ readonly weekStartsOn?: Weekday | undefined;
77
+ readonly weekendDays?: readonly Weekday[] | undefined;
78
+ /** Override "today" (tests, server rendering). */
79
+ readonly today?: CalendarDate | undefined;
80
+ }
81
+ interface DatePickerOptions extends PickerBaseOptions {
82
+ /** AD "YYYY-MM-DD" or "". Passing it again through setOptions replaces the value. */
83
+ readonly value?: string | undefined;
84
+ /** The starting value when the picker keeps its own state. */
85
+ readonly defaultValue?: string | undefined;
86
+ readonly onChange?: ((value: string, detail: DateDetail | null) => void) | undefined;
87
+ /** Shortcuts shown in the panel: 'today', 'yesterday', 'tomorrow' or your own. */
88
+ readonly presets?: readonly SinglePreset[] | undefined;
89
+ }
90
+ interface DatePickerState {
91
+ /** AD "YYYY-MM-DD", or "" when empty or invalid. Never a BS date. */
92
+ readonly value: string;
93
+ readonly date: DateDetail | null;
94
+ /** What the input shows. */
95
+ readonly text: string;
96
+ /** The calendar the input and panel use. */
97
+ readonly calendar: CalendarSystem;
98
+ readonly canSwitchCalendar: boolean;
99
+ /** The panel is showing. Always true for an inline picker. */
100
+ readonly open: boolean;
101
+ /** The calendar sits in the page and never closes (option `inline`). */
102
+ readonly inline: boolean;
103
+ readonly error: DateError | null;
104
+ /** The same day in the other calendar, e.g. "10 October 2026 AD". */
105
+ readonly equivalentText: string | null;
106
+ /** "YYYY-MM-DD (BS)" */
107
+ readonly placeholder: string;
108
+ readonly presets: readonly PresetState[];
109
+ readonly calendarState: CalendarState;
110
+ }
111
+ interface DatePickerActions {
112
+ /** The user typed. Updates the value when the text is a valid, allowed date. */
113
+ type(text: string): void;
114
+ /** Tidy the text ("2083/6/4" → "2083-06-04") unless it has an error. */
115
+ blur(): void;
116
+ clear(): void;
117
+ /** Set the value from outside; does not call onChange. */
118
+ setValue(value: string): void;
119
+ open(): void;
120
+ close(): void;
121
+ toggle(): void;
122
+ /** Show BS or AD. The value does not change. Ignored when the calendar is fixed. */
123
+ switchCalendar(calendar: CalendarSystem): void;
124
+ /** Pick a day (e.g. from the panel). Returns false when the day is disabled. */
125
+ select(date: CalendarDate): boolean;
126
+ /** Returns false when today is not allowed. */
127
+ selectToday(): boolean;
128
+ /** Back to defaultValue (form reset). */
129
+ reset(): void;
130
+ /** Apply a shortcut by id. Returns false when it is disabled or unknown. */
131
+ applyPreset(id: string): boolean;
132
+ }
133
+ interface DatePickerStore {
134
+ getState(): DatePickerState;
135
+ subscribe(listener: () => void): () => void;
136
+ setOptions(changes: Partial<DatePickerOptions>): void;
137
+ readonly actions: DatePickerActions;
138
+ /** The panel's calendar store, for adapters (keyboard moves, views, hover). */
139
+ readonly calendar: CalendarStore;
140
+ destroy(): void;
141
+ }
142
+ interface RangeValue {
143
+ readonly start: string;
144
+ readonly end: string;
145
+ }
146
+ interface RangeDetail {
147
+ readonly start: DateDetail | null;
148
+ readonly end: DateDetail | null;
149
+ }
150
+ interface DateRangePickerOptions extends PickerBaseOptions {
151
+ readonly value?: RangeValue | undefined;
152
+ readonly defaultValue?: RangeValue | undefined;
153
+ readonly onChange?: ((value: RangeValue, detail: RangeDetail) => void) | undefined;
154
+ /** Shortest and longest allowed range, in days, counting both ends. */
155
+ readonly minDays?: number | undefined;
156
+ readonly maxDays?: number | undefined;
157
+ /** Shortcuts: 'last7Days', 'thisMonth', 'thisFiscalYear', … or your own. */
158
+ readonly presets?: readonly RangePreset[] | undefined;
159
+ }
160
+ type RangeField = "start" | "end";
161
+ interface DateRangePickerState {
162
+ readonly value: RangeValue;
163
+ readonly date: RangeDetail;
164
+ readonly startText: string;
165
+ readonly endText: string;
166
+ readonly calendar: CalendarSystem;
167
+ readonly canSwitchCalendar: boolean;
168
+ /** The panel is showing. Always true for an inline picker. */
169
+ readonly open: boolean;
170
+ /** The calendar sits in the page and never closes (option `inline`). */
171
+ readonly inline: boolean;
172
+ /** The first problem, and which field it belongs to ('range' for length problems). */
173
+ readonly error: (DateError & {
174
+ readonly field: RangeField | "range";
175
+ }) | null;
176
+ readonly equivalentText: {
177
+ readonly start: string | null;
178
+ readonly end: string | null;
179
+ };
180
+ readonly placeholder: string;
181
+ readonly presets: readonly PresetState[];
182
+ readonly calendarState: CalendarState;
183
+ }
184
+ interface DateRangePickerActions {
185
+ type(field: RangeField, text: string): void;
186
+ blur(field: RangeField): void;
187
+ clear(): void;
188
+ setValue(value: RangeValue): void;
189
+ open(): void;
190
+ close(): void;
191
+ toggle(): void;
192
+ switchCalendar(calendar: CalendarSystem): void;
193
+ /** A click in the panel: first sets the start, second the end. */
194
+ select(date: CalendarDate): boolean;
195
+ reset(): void;
196
+ /** Apply a shortcut by id. Returns false when it is disabled or unknown. */
197
+ applyPreset(id: string): boolean;
198
+ }
199
+ interface DateRangePickerStore {
200
+ getState(): DateRangePickerState;
201
+ subscribe(listener: () => void): () => void;
202
+ setOptions(changes: Partial<DateRangePickerOptions>): void;
203
+ readonly actions: DateRangePickerActions;
204
+ readonly calendar: CalendarStore;
205
+ destroy(): void;
206
+ }
207
+ interface MultiDatePickerOptions extends PickerBaseOptions {
208
+ /** AD "YYYY-MM-DD" days. Passing it again through setOptions replaces the value. */
209
+ readonly value?: readonly string[] | undefined;
210
+ readonly defaultValue?: readonly string[] | undefined;
211
+ readonly onChange?: ((value: readonly string[], dates: readonly DateDetail[]) => void) | undefined;
212
+ /** The most days that may be chosen. */
213
+ readonly maxDates?: number | undefined;
214
+ }
215
+ interface MultiDatePickerState {
216
+ /** AD "YYYY-MM-DD" days, sorted, no repeats. Never BS dates. */
217
+ readonly value: readonly string[];
218
+ readonly dates: readonly DateDetail[];
219
+ /** What the input shows: the days as YYYY-MM-DD, separated by ", ". */
220
+ readonly text: string;
221
+ readonly calendar: CalendarSystem;
222
+ readonly canSwitchCalendar: boolean;
223
+ /** The panel is showing. Always true for an inline picker. */
224
+ readonly open: boolean;
225
+ readonly inline: boolean;
226
+ readonly error: DateError | null;
227
+ readonly placeholder: string;
228
+ readonly calendarState: CalendarState;
229
+ }
230
+ interface MultiDatePickerActions {
231
+ /** The user typed days separated by commas or spaces. */
232
+ type(text: string): void;
233
+ /** Tidy the text unless it has an error. */
234
+ blur(): void;
235
+ clear(): void;
236
+ /** Set the value from outside; does not call onChange. */
237
+ setValue(value: readonly string[]): void;
238
+ open(): void;
239
+ close(): void;
240
+ toggle(): void;
241
+ switchCalendar(calendar: CalendarSystem): void;
242
+ /** Add the day, or remove it when chosen. Returns false when disabled or over maxDates. */
243
+ select(date: CalendarDate): boolean;
244
+ /** Remove one day, by its AD "YYYY-MM-DD" value. */
245
+ remove(value: string): void;
246
+ /** Back to defaultValue (form reset). */
247
+ reset(): void;
248
+ }
249
+ interface MultiDatePickerStore {
250
+ getState(): MultiDatePickerState;
251
+ subscribe(listener: () => void): () => void;
252
+ setOptions(changes: Partial<MultiDatePickerOptions>): void;
253
+ readonly actions: MultiDatePickerActions;
254
+ readonly calendar: CalendarStore;
255
+ destroy(): void;
256
+ }
257
+ //#endregion
258
+ //#region src/picker.d.ts
259
+ /**
260
+ * A BS/AD date picker without UI: typed text ⇄ value, validation, the BS/AD
261
+ * switch and open/close, plus the panel's calendar store. The value is always
262
+ * an AD "YYYY-MM-DD" string (docs/plan D-003); all date work goes through core.
263
+ *
264
+ * Like the calendar, the picker keeps its own value; passing `value` through
265
+ * setOptions replaces it (controlled use). Passing back the value the user just
266
+ * typed leaves their text alone, so the cursor does not jump.
267
+ */
268
+ export declare function createDatePicker(initial?: DatePickerOptions): DatePickerStore;
269
+ //#endregion
270
+ //#region src/range.d.ts
271
+ /**
272
+ * A BS/AD date range picker without UI: two typed fields (start, end), a panel
273
+ * calendar in range mode, minDays/maxDays checks and the BS/AD switch. Values
274
+ * are AD "YYYY-MM-DD" strings; an unfinished or invalid end is "".
275
+ */
276
+ export declare function createDateRangePicker(initial?: DateRangePickerOptions): DateRangePickerStore;
277
+ //#endregion
278
+ //#region src/mask.d.ts
279
+ /**
280
+ * Add the dashes of YYYY-MM-DD while the user types digits: "2083" becomes
281
+ * "2083-", "208306" becomes "2083-06-" and a pasted "20830624" becomes
282
+ * "2083-06-24". ASCII and Devanagari digits keep their script, and a
283
+ * separator typed straight after a dash is dropped, so typing the dashes
284
+ * yourself works too. Only text that grew at the end (typing, or a paste into
285
+ * an empty field) is touched: deleting, editing in the middle and other
286
+ * separators ("2083/6/4") are left as the user wrote them. Pure.
287
+ */
288
+ export declare function maskDateText(next: string, previous?: string): string;
289
+ //#endregion
290
+ //#region src/multi.d.ts
291
+ /**
292
+ * A picker for several separate days (PICK-001). The value is a sorted list of
293
+ * AD "YYYY-MM-DD" strings; the input lists the days in the calendar on screen,
294
+ * separated by ", ", and clicking a day in the panel adds or removes it. The
295
+ * list is always written as YYYY-MM-DD so it can be typed back.
296
+ */
297
+ export declare function createMultiDatePicker(initial?: MultiDatePickerOptions): MultiDatePickerStore;
298
+ //#endregion
299
+ //#region src/datetime.d.ts
300
+ interface DateTimeDetail {
301
+ readonly ad: AdDate;
302
+ readonly bs: BsDate;
303
+ readonly time: TimeOfDay;
304
+ /** The same instant as the value. */
305
+ readonly iso: string;
306
+ }
307
+ interface DateTimePickerOptions extends PickerBaseOptions {
308
+ /** An ISO timestamp with offset ("2026-10-18T14:30:00+05:45"), a local "YYYY-MM-DDTHH:MM", or "". */
309
+ readonly value?: string | undefined;
310
+ readonly defaultValue?: string | undefined;
311
+ readonly onChange?: ((value: string, detail: DateTimeDetail | null) => void) | undefined;
312
+ /** The zone the date and time are read in, and whose offset the value carries. Default: core config (Nepal). */
313
+ readonly timeZone?: string | undefined;
314
+ /** Show 12-hour times (2:30 PM). Default false (14:30). */
315
+ readonly hour12?: boolean | undefined;
316
+ /** Minutes offered in the column: 1–30. Default 5. Any minute can still be typed. */
317
+ readonly minuteStep?: number | undefined;
318
+ /** The time used when a date is picked before any time. Default "00:00". */
319
+ readonly defaultTime?: string | undefined;
320
+ readonly presets?: readonly SinglePreset[] | undefined;
321
+ }
322
+ /** One hour or minute in the time columns (Figma "Time Item"). */
323
+ interface TimeCell {
324
+ readonly value: number;
325
+ readonly label: string;
326
+ readonly isSelected: boolean;
327
+ }
328
+ interface DateTimePickerState {
329
+ /** ISO timestamp with the zone's offset, or "" until both date and time are valid. */
330
+ readonly value: string;
331
+ readonly detail: DateTimeDetail | null;
332
+ readonly dateText: string;
333
+ readonly timeText: string;
334
+ readonly time: TimeOfDay | null;
335
+ readonly calendar: CalendarSystem;
336
+ readonly canSwitchCalendar: boolean;
337
+ /** The panel is showing. Always true for an inline picker. */
338
+ readonly open: boolean;
339
+ /** The calendar sits in the page and never closes (option `inline`). */
340
+ readonly inline: boolean;
341
+ readonly error: (DateError & {
342
+ readonly field: "date" | "time";
343
+ }) | null;
344
+ readonly equivalentText: string | null;
345
+ readonly placeholder: string;
346
+ readonly timePlaceholder: string;
347
+ readonly hours: readonly TimeCell[];
348
+ readonly minutes: readonly TimeCell[];
349
+ readonly presets: readonly PresetState[];
350
+ readonly calendarState: CalendarState;
351
+ }
352
+ interface DateTimePickerActions {
353
+ typeDate(text: string): void;
354
+ typeTime(text: string): void;
355
+ blurDate(): void;
356
+ blurTime(): void;
357
+ /** Pick a day; the time stays (or becomes defaultTime). Returns false when disabled. */
358
+ selectDate(date: CalendarDate): boolean;
359
+ selectHour(hour: number): void;
360
+ selectMinute(minute: number): void;
361
+ /** Today and the current time in the zone. Returns false when today is not allowed. */
362
+ selectNow(): boolean;
363
+ applyPreset(id: string): boolean;
364
+ open(): void;
365
+ close(): void;
366
+ toggle(): void;
367
+ clear(): void;
368
+ setValue(value: string): void;
369
+ switchCalendar(calendar: CalendarSystem): void;
370
+ reset(): void;
371
+ }
372
+ interface DateTimePickerStore {
373
+ getState(): DateTimePickerState;
374
+ subscribe(listener: () => void): () => void;
375
+ setOptions(changes: Partial<DateTimePickerOptions>): void;
376
+ readonly actions: DateTimePickerActions;
377
+ readonly calendar: CalendarStore;
378
+ destroy(): void;
379
+ }
380
+ /**
381
+ * A BS/AD date and time picker without UI. The date half is a regular date
382
+ * picker; the value is the instant as an ISO timestamp carrying the zone's
383
+ * offset, so servers store one unambiguous moment.
384
+ */
385
+ export declare function createDateTimePicker(initial?: DateTimePickerOptions): DateTimePickerStore;
386
+ //#endregion
387
+ //#region src/input.d.ts
388
+ /** What a picker allows, in any calendar. */
389
+ interface InputLimits {
390
+ readonly min: CalendarDate;
391
+ readonly max: CalendarDate;
392
+ /** Whether the app set min/max (else they are the edges of the BS table). Picks the message. */
393
+ readonly hasMin?: boolean;
394
+ readonly hasMax?: boolean;
395
+ readonly isDateDisabled?: ((date: CalendarDate) => boolean) | undefined;
396
+ }
397
+ type ParseResult = {
398
+ readonly kind: "empty";
399
+ } | {
400
+ readonly kind: "date";
401
+ readonly date: AdDate;
402
+ } | {
403
+ readonly kind: "error";
404
+ readonly error: DateError;
405
+ };
406
+ /**
407
+ * Read what the user typed: year first, ASCII or Devanagari digits, in the
408
+ * calendar on screen. All date work is done by core (docs/plan D-005).
409
+ */
410
+ export declare function parseInput(text: string, calendar: CalendarSystem, limits: InputLimits, locale: LocaleCode, format?: DateFormatPattern): ParseResult;
411
+ /** Null when the day is allowed; otherwise a translated error. */
412
+ export declare function checkDate(date: CalendarDate, calendar: CalendarSystem, limits: InputLimits, locale: LocaleCode, format?: DateFormatPattern): DateError | null;
413
+ /** How the input shows a date: in the calendar on screen, with the locale's digits. */
414
+ export declare function formatInput(date: CalendarDate | null, calendar: CalendarSystem, format: DateFormatPattern, locale: LocaleCode): string;
415
+ /** "10 October 2026 AD": the same day in the other calendar. */
416
+ export declare function equivalentText(date: CalendarDate | null, calendar: CalendarSystem, locale: LocaleCode): string | null;
417
+ export declare function placeholderText(calendar: CalendarSystem, locale: LocaleCode): string;
418
+ //#endregion
419
+ export type { CustomPreset, DateDetail, DateError, DateErrorCode, DatePickerActions, DatePickerOptions, DatePickerState, DatePickerStore, DateRangePickerActions, DateRangePickerOptions, DateRangePickerState, DateRangePickerStore, DateTimeDetail, DateTimePickerActions, DateTimePickerOptions, DateTimePickerState, DateTimePickerStore, InputLimits, MultiDatePickerActions, MultiDatePickerOptions, MultiDatePickerState, MultiDatePickerStore, ParseResult, PickerBaseOptions, PresetContext, PresetRange, PresetState, RangeDetail, RangeField, RangePreset, RangePresetId, RangeValue, SinglePreset, SinglePresetId, TimeCell };
420
+ //# sourceMappingURL=index.d.ts.map