@lilydesignsystem/angular-date-time-picker 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,558 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
3
+
4
+ /**
5
+ * Default button glyph: U+1F4C5 CALENDAR, followed by U+FE0E VARIATION
6
+ * SELECTOR-15 to request text (monochrome) presentation.
7
+ *
8
+ * Same construction as locale-picker's globe. The variation selector is a
9
+ * hint, not a guarantee — several platforms ignore it and render the emoji
10
+ * anyway — but where it is honoured the glyph inherits the page's text
11
+ * colour and stops looking like a sticker among the siblings' ◑, "A" and
12
+ * ➤. Written as an escape, never as a bare character: a variation
13
+ * selector has no visual form at all, so a bare one is invisible in an
14
+ * editor and trivially lost to a careless edit.
15
+ */
16
+ declare const CALENDAR = "\uD83D\uDCC5\uFE0E";
17
+ /** What the control collects. */
18
+ type DateTimeMode = "date" | "time" | "datetime";
19
+ /**
20
+ * A civil date: no time zone, no instant.
21
+ *
22
+ * The whole component works in these rather than in `Date`, because a
23
+ * `Date` is an instant and a calendar day is not. `new Date(2026, 2, 1)`
24
+ * is midnight *local*, and in a zone whose DST transition falls at
25
+ * midnight that instant can land on the previous day — so a picker built
26
+ * on local-midnight `Date` values shows the wrong day to some users a
27
+ * couple of times a year. Arithmetic here goes through UTC epoch days,
28
+ * which has no such edge.
29
+ */
30
+ type CivilDate = {
31
+ year: number;
32
+ month: number;
33
+ day: number;
34
+ };
35
+ /** A wall-clock time, 24-hour, no seconds. */
36
+ type CivilTime = {
37
+ hour: number;
38
+ minute: number;
39
+ };
40
+ /** One quick-pick button in the dialog. */
41
+ type DateTimeShortcut = {
42
+ /** Stable identifier, passed back on the `shortcut` output. */
43
+ id: string;
44
+ /** Visible button text. Consumer-supplied, so it localises. */
45
+ label: string;
46
+ /** Days from today. Mutually exclusive with `months` and `date`. */
47
+ days?: number;
48
+ /** Calendar months from today. */
49
+ months?: number;
50
+ /** An absolute ISO date, for shortcuts that are not relative. */
51
+ date?: string;
52
+ };
53
+ /**
54
+ * Every user-facing string the dialog needs.
55
+ *
56
+ * Grouped into one object rather than spread across a dozen flat inputs.
57
+ * The sibling helpers use flat inputs because they need two or three
58
+ * strings; this one needs ten, and ten flat inputs is a call site nobody
59
+ * can read. One object also maps cleanly onto a translation bundle, which
60
+ * is how these strings actually arrive.
61
+ *
62
+ * The four navigation labels and the two footer labels are required: they
63
+ * name buttons that always render, and a button whose accessible name we
64
+ * invented in English is precisely the defect this package exists to
65
+ * avoid. The rest gate optional UI.
66
+ */
67
+ type DateTimePickerLabels = {
68
+ /** Accessible name for the previous-year button. */
69
+ previousYear: string;
70
+ /** Accessible name for the previous-month button. */
71
+ previousMonth: string;
72
+ /** Accessible name for the previous-week button. */
73
+ previousWeek: string;
74
+ /** Accessible name for the previous-day button. */
75
+ previousDay: string;
76
+ /** Accessible name for the next-day button. */
77
+ nextDay: string;
78
+ /** Accessible name for the next-week button. */
79
+ nextWeek: string;
80
+ /** Accessible name for the next-month button. */
81
+ nextMonth: string;
82
+ /** Accessible name for the next-year button. */
83
+ nextYear: string;
84
+ /** Visible text of the commit button. */
85
+ confirm: string;
86
+ /** Visible text of the dismiss button. */
87
+ cancel: string;
88
+ /** Label for the hour select. Required when `mode` includes a time. */
89
+ hour?: string;
90
+ /** Label for the minute select. Required when `mode` includes a time. */
91
+ minute?: string;
92
+ /** Label for the AM/PM select, when `hour12` resolves true. */
93
+ meridiem?: string;
94
+ /** Column heading for week numbers. Required when `showWeekNumbers`. */
95
+ week?: string;
96
+ /** Visible text of the clear button. The button renders only when set. */
97
+ clear?: string;
98
+ /**
99
+ * Label for the time-zone select. The select renders only when set, for
100
+ * the same reason `clear` gates its button: a zone list is an opt-in
101
+ * part of the form, and we will not name it in English.
102
+ */
103
+ timeZone?: string;
104
+ /**
105
+ * Message announced when typed text will not parse or is out of range.
106
+ * When set, a `role="status"` live region renders after the field and
107
+ * is wired to it via `aria-errormessage` — without it, `aria-invalid`
108
+ * flips silently and a screen-reader user who has already left the
109
+ * field never hears that their date was refused.
110
+ */
111
+ invalid?: string;
112
+ /**
113
+ * Keyboard help for the dialog, e.g. "Use the arrow keys to choose a
114
+ * date". When set, it renders inside the dialog and becomes the
115
+ * dialog's `aria-describedby`, so a screen reader speaks it once on
116
+ * open — the APG date-picker dialog ships exactly this affordance.
117
+ */
118
+ instructions?: string;
119
+ };
120
+ /** Context passed to a projected icon `<ng-template>` (the button glyph). */
121
+ type ChildArgs = {
122
+ /** The committed value, in ISO form. */
123
+ value: string;
124
+ /** Is the dialog open? */
125
+ open: boolean;
126
+ /** The value as the user sees it in the field. */
127
+ display: string;
128
+ };
129
+ /** Payload of the `shortcut` output. */
130
+ type ShortcutEvent = {
131
+ /** The chosen shortcut's `id`. */
132
+ id: string;
133
+ /** The ISO date the shortcut resolved to. */
134
+ isoDate: string;
135
+ };
136
+ /** Zero-pad to `width`. */
137
+ declare function pad(n: number, width?: number): string;
138
+ /** Days in a month. `month` is 1-12. */
139
+ declare function daysInMonth(year: number, month: number): number;
140
+ /** `{2026, 3, 1}` → `"2026-03-01"`. */
141
+ declare function formatIsoDate(date: CivilDate): string;
142
+ /**
143
+ * `"2026-03-01"` → `{2026, 3, 1}`, or null.
144
+ *
145
+ * Rejects impossible components rather than rolling them over, so
146
+ * `"2026-02-31"` is null and not the 3rd of March. A field that silently
147
+ * reinterprets an impossible date is worse than one that refuses it.
148
+ */
149
+ declare function parseIsoDate(text: string): CivilDate | null;
150
+ /** Days since the Unix epoch. The unit all date arithmetic goes through. */
151
+ declare function toEpochDay(date: CivilDate): number;
152
+ /** Inverse of `toEpochDay`. */
153
+ declare function fromEpochDay(epochDay: number): CivilDate;
154
+ /** Shift an ISO date by whole days. */
155
+ declare function addDays(isoDate: string, days: number): string;
156
+ /**
157
+ * Shift an ISO date by whole months, clamping the day.
158
+ *
159
+ * 31 January + 1 month is 28 February (29 in a leap year), not 3 March.
160
+ * Rolling over is what `Date.prototype.setMonth` does and it is almost
161
+ * never what someone paging a calendar means.
162
+ */
163
+ declare function addMonths(isoDate: string, months: number): string;
164
+ /** Day of week: 0 = Sunday … 6 = Saturday. */
165
+ declare function weekdayOf(isoDate: string): number;
166
+ /**
167
+ * ISO-8601 week number.
168
+ *
169
+ * Weeks start Monday and week 1 is the one containing the first Thursday,
170
+ * which is why this pivots on Thursday rather than counting from 1
171
+ * January. Public-sector and clinical rotas quote ISO week numbers, so
172
+ * the column is worth getting exactly right.
173
+ */
174
+ declare function isoWeek(isoDate: string): number;
175
+ /** `"09:30"` → `{9, 30}`, or null. */
176
+ declare function parseIsoTime(text: string): CivilTime | null;
177
+ /** `{9, 30}` → `"09:30"`. */
178
+ declare function formatIsoTime(time: CivilTime): string;
179
+ /** Pull the date and time halves out of a mode-appropriate ISO value. */
180
+ declare function splitValue(value: string, mode: DateTimeMode): {
181
+ date: string;
182
+ time: string;
183
+ };
184
+ /** Recombine the halves. Returns "" when the value is incomplete. */
185
+ declare function joinValue(date: string, time: string, mode: DateTimeMode): string;
186
+ /** Is `isoDate` inside the inclusive [min, max] window? Empty bounds pass. */
187
+ declare function withinRange(isoDate: string, min?: string, max?: string): boolean;
188
+ /**
189
+ * First day of the week for a locale: 0 = Sunday … 6 = Saturday.
190
+ *
191
+ * `Intl.Locale.prototype.getWeekInfo` is the right answer, but it is
192
+ * recent enough that a fallback still earns its place — and it is
193
+ * missing from some SSR runtimes entirely. The fallback is a short
194
+ * region table plus a Monday default, Monday being both the ISO-8601
195
+ * rule and the majority convention worldwide.
196
+ */
197
+ declare function firstDayOfWeekFor(locale?: string): number;
198
+ /**
199
+ * The dates of one month's grid, always six rows of seven.
200
+ *
201
+ * Fixed height on purpose. A grid sized to its month runs four to six
202
+ * rows, so the footer — and the confirm button in it — moves vertically
203
+ * as you page months. That is a Fitts's-law tax on every subsequent click
204
+ * and it makes the dialog jump under the pointer. A constant six rows
205
+ * costs at most one extra trailing week.
206
+ */
207
+ declare function monthMatrix(year: number, month: number, firstDayOfWeek: number): string[][];
208
+ /** Long and short month names for a locale, index 0 = January. */
209
+ declare function monthNames(locale?: string): {
210
+ long: string[];
211
+ short: string[];
212
+ };
213
+ /**
214
+ * The order a locale writes a numeric date in — `["day","month","year"]`
215
+ * for en-GB, `["month","day","year"]` for en-US.
216
+ */
217
+ declare function numericFieldOrder(locale?: string): ("day" | "month" | "year")[];
218
+ /**
219
+ * Parse typed text into an ISO date.
220
+ *
221
+ * Accepts, in order: ISO `YYYY-MM-DD`; a numeric form whose field order
222
+ * follows the locale, so `03/04/2026` is 3 April in en-GB and 4 March in
223
+ * en-US — which is what each user means; and a form with a written month
224
+ * matched against the locale's own long and short month names, which is
225
+ * what lets DHCW's `27-Jun-2025` round-trip.
226
+ *
227
+ * Anything else is null. Guessing harder than this is how date fields
228
+ * silently record the wrong day.
229
+ */
230
+ declare function parseDateInput(text: string, locale?: string): string | null;
231
+ /** Accepts `9:30`, `09:30`, `0930`, `9.30`, and a trailing am/pm. */
232
+ declare function parseTimeInput(text: string): string | null;
233
+ /** Stable per-instance id prefix; SSR-safe (no Math.random / Date.now). */
234
+ declare function nextDateTimePickerId(): string;
235
+ /**
236
+ * Optional marker for the projected icon template. Gives consumers typed
237
+ * `let-` variables:
238
+ *
239
+ * ```html
240
+ * <lily-date-time-picker label="Choose a date" [labels]="labels">
241
+ * <ng-template lilyDateTimePickerIcon let-args>{{ args.open ? "×" : "📅" }}</ng-template>
242
+ * </lily-date-time-picker>
243
+ * ```
244
+ *
245
+ * The component queries any projected `<ng-template>`, so the marker is
246
+ * for type-checking and readability, not for matching.
247
+ */
248
+ declare class DateTimePickerIcon {
249
+ static ngTemplateContextGuard(_dir: DateTimePickerIcon, _ctx: unknown): _ctx is ChildArgs & {
250
+ $implicit: ChildArgs;
251
+ };
252
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateTimePickerIcon, never>;
253
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DateTimePickerIcon, "ng-template[lilyDateTimePickerIcon]", never, {}, {}, never, never, true, never>;
254
+ }
255
+ /**
256
+ * DateTimePicker — a headless date / time / datetime control.
257
+ *
258
+ * A typeable text field plus an icon button that opens a WAI-ARIA APG
259
+ * **Date Picker Dialog**: a month grid with a full keyboard contract.
260
+ * Locale-correct by construction — month names, weekday names, first day
261
+ * of week, numeric field order, 12- vs 24-hour clock and day-period names
262
+ * all come from `Intl`. See `spec/index.md` for the full contract.
263
+ *
264
+ * Unlike the three preference helpers this is a **form control**, not a
265
+ * page-header preference control, and it persists nothing.
266
+ */
267
+ declare class DateTimePicker {
268
+ /** Accessible name for the trigger button and the dialog. */
269
+ readonly label: _angular_core.InputSignal<string>;
270
+ /** Every other user-facing string. See `spec/index.md` §4.2. */
271
+ readonly labels: _angular_core.InputSignal<DateTimePickerLabels>;
272
+ /** What to collect: a date, a time, or both. */
273
+ readonly mode: _angular_core.InputSignal<DateTimeMode>;
274
+ /** ISO value: `YYYY-MM-DD`, `HH:MM`, or `YYYY-MM-DDTHH:MM`. Two-way bindable. */
275
+ readonly value: _angular_core.ModelSignal<string>;
276
+ /** BCP 47 tag driving month names, weekday names and first weekday. */
277
+ readonly locale: _angular_core.InputSignal<string>;
278
+ /** Earliest selectable date, ISO. */
279
+ readonly min: _angular_core.InputSignal<string>;
280
+ /** Latest selectable date, ISO. */
281
+ readonly max: _angular_core.InputSignal<string>;
282
+ /** Veto individual dates — true means "cannot be picked". */
283
+ readonly isDateDisabled: _angular_core.InputSignal<((isoDate: string) => boolean) | undefined>;
284
+ /** 0 = Sunday … 6 = Saturday. Defaults to the locale's convention. */
285
+ readonly firstDayOfWeek: _angular_core.InputSignal<number | undefined>;
286
+ /** Granularity of the minute select. */
287
+ readonly minuteStep: _angular_core.InputSignal<number>;
288
+ /** 12-hour clock. Defaults to the locale's convention. */
289
+ readonly hour12: _angular_core.InputSignal<boolean | undefined>;
290
+ /** Render an ISO-8601 week-number column. */
291
+ readonly showWeekNumbers: _angular_core.InputSignal<boolean>;
292
+ /** Quick-pick buttons. */
293
+ readonly shortcuts: _angular_core.InputSignal<DateTimeShortcut[]>;
294
+ /** Commit and close as soon as a day is chosen. Defaults to date-only. */
295
+ readonly confirmOnSelect: _angular_core.InputSignal<boolean | undefined>;
296
+ /** `name` of the hidden input that carries the value in a form post. */
297
+ readonly name: _angular_core.InputSignal<string>;
298
+ /**
299
+ * Selected IANA time zone (e.g. `Europe/London`), or `""` for none.
300
+ * Two-way bindable via `[(timeZone)]`, matching `value`. Rides its own
301
+ * hidden input `{name}-time-zone` and is reflected as `data-time-zone`
302
+ * on the root. It is metadata about WHERE the civil value applies, not
303
+ * part of the value — converting to an instant stays the consumer's
304
+ * job. Never guessed from the runtime: the picker no more picks a zone
305
+ * than `locale-picker` picks a locale.
306
+ */
307
+ readonly timeZone: _angular_core.ModelSignal<string>;
308
+ /**
309
+ * Zones offered by the select. Defaults to every zone the runtime
310
+ * knows via `Intl.supportedValuesOf("timeZone")` — never a bundled
311
+ * table, the rule month and weekday names already follow.
312
+ */
313
+ readonly timeZones: _angular_core.InputSignal<string[] | undefined>;
314
+ /** Display text per zone id; a zone without an entry shows its id. */
315
+ readonly timeZoneLabels: _angular_core.InputSignal<Record<string, string>>;
316
+ /** `id` of the text field, so a consumer `<label for>` can name it. */
317
+ readonly inputId: _angular_core.InputSignal<string>;
318
+ /** Forwarded to the text field as `aria-describedby`. */
319
+ readonly describedBy: _angular_core.InputSignal<string>;
320
+ /** Placeholder for the text field. */
321
+ readonly placeholder: _angular_core.InputSignal<string>;
322
+ /** Disable the whole control. */
323
+ readonly disabled: _angular_core.InputSignal<boolean>;
324
+ /**
325
+ * Show the value but refuse edits.
326
+ *
327
+ * Named `readOnly` (not `readonly`) so the Angular input has an
328
+ * unambiguous identifier distinct from the TypeScript `readonly`
329
+ * modifier — the one Angular-forced rename beyond `class` → `className`.
330
+ */
331
+ readonly readOnly: _angular_core.InputSignal<boolean>;
332
+ /** Mark the field required. */
333
+ readonly required: _angular_core.InputSignal<boolean>;
334
+ /** Override how a committed value is rendered into the text field. */
335
+ readonly formatValue: _angular_core.InputSignal<((value: string) => string) | undefined>;
336
+ /** Override how typed text is turned back into an ISO value. */
337
+ readonly parseInput: _angular_core.InputSignal<((text: string) => string | null) | undefined>;
338
+ /** Extra CSS class on the root `<div>`. */
339
+ readonly className: _angular_core.InputSignal<string>;
340
+ /** Fires after a new value is committed. */
341
+ readonly change: _angular_core.OutputEmitterRef<string>;
342
+ /** Fires when a shortcut is used, before the value settles. */
343
+ readonly shortcut: _angular_core.OutputEmitterRef<ShortcutEvent>;
344
+ /** Fires when typed text cannot be parsed. */
345
+ readonly invalidInput: _angular_core.OutputEmitterRef<string>;
346
+ /** Projected icon template; replaces the default glyph when supplied. */
347
+ protected readonly iconTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
348
+ private readonly rootRef;
349
+ private readonly buttonRef;
350
+ private readonly dialogRef;
351
+ /** Optional: the grid renders only when `mode` includes a date. */
352
+ private readonly gridRef;
353
+ protected readonly glyph = "\uD83D\uDCC5\uFE0E";
354
+ /**
355
+ * For rendering the view synchronously before a focus move.
356
+ *
357
+ * Svelte updates the DOM synchronously when state changes, so the
358
+ * canonical helper can focus a freshly-paged month from a microtask.
359
+ * Angular renders later — after the microtask queue drains, whether the
360
+ * app is zone-based or zoneless — so a queued focus into a month that
361
+ * has not rendered yet finds nothing (or, worse, finds and focuses a
362
+ * cell that the next render destroys, dropping focus to `<body>`).
363
+ * `cdr.detectChanges()` inside the event handler is the Angular
364
+ * equivalent of Svelte's synchronous flush.
365
+ */
366
+ private readonly cdr;
367
+ private readonly baseId;
368
+ protected readonly dialogId: string;
369
+ protected readonly periodId: string;
370
+ protected readonly hourId: string;
371
+ protected readonly minuteId: string;
372
+ protected readonly meridiemId: string;
373
+ protected readonly statusId: string;
374
+ protected readonly instructionsId: string;
375
+ protected readonly timeZoneId: string;
376
+ protected readonly open: _angular_core.WritableSignal<boolean>;
377
+ protected readonly invalid: _angular_core.WritableSignal<boolean>;
378
+ /**
379
+ * The element that opened the dialog, so close can return focus to it.
380
+ *
381
+ * The APG rule is "focus returns to the element that invoked the
382
+ * dialog" — which is the trigger button on a click, but the *text
383
+ * field* when the user pressed Alt+ArrowDown. Always refocusing the
384
+ * button strands a keyboard user one Tab stop past where they were.
385
+ */
386
+ private openerEl;
387
+ /**
388
+ * Text the user has typed but not yet resolved.
389
+ *
390
+ * `null` means "no pending edit, show the formatted value". An empty
391
+ * string is a real state (the user cleared the field) and must not
392
+ * collapse into `null`.
393
+ */
394
+ protected readonly typed: _angular_core.WritableSignal<string | null>;
395
+ /**
396
+ * The pending selection, live only while the dialog is open.
397
+ *
398
+ * Kept separate from `value` so Cancel and Escape can genuinely revert.
399
+ * A picker that writes through on every arrow key has no cancel — only
400
+ * an undo the user has to perform by hand, from memory.
401
+ */
402
+ protected readonly pendingDate: _angular_core.WritableSignal<string>;
403
+ protected readonly pendingTime: _angular_core.WritableSignal<string>;
404
+ /** The month on screen. */
405
+ protected readonly viewYear: _angular_core.WritableSignal<number>;
406
+ protected readonly viewMonth: _angular_core.WritableSignal<number>;
407
+ /** The day the grid's roving tabindex sits on. */
408
+ protected readonly cursor: _angular_core.WritableSignal<string>;
409
+ /**
410
+ * Today, sampled once at open and refreshed on the initial effect below.
411
+ * Not re-read per cell: the grid asks "is this today?" 42 times a
412
+ * render, and a clock read per cell buys nothing over a clock read per
413
+ * open.
414
+ */
415
+ protected readonly today: _angular_core.WritableSignal<string>;
416
+ protected readonly fieldId: _angular_core.Signal<string>;
417
+ protected readonly committed: _angular_core.Signal<{
418
+ date: string;
419
+ time: string;
420
+ }>;
421
+ protected readonly weekStart: _angular_core.Signal<number>;
422
+ protected readonly commitOnDay: _angular_core.Signal<boolean>;
423
+ protected readonly usesDate: _angular_core.Signal<boolean>;
424
+ protected readonly usesTime: _angular_core.Signal<boolean>;
425
+ protected readonly clock12: _angular_core.Signal<boolean>;
426
+ /**
427
+ * `aria-describedby` for the field: the consumer's hint, plus — while
428
+ * invalid, with `labels().invalid` supplied — the status region, for
429
+ * the assistive technologies that read `aria-describedby` but not the
430
+ * newer `aria-errormessage`.
431
+ */
432
+ protected readonly fieldDescribedBy: _angular_core.Signal<string | null>;
433
+ /** The text shown in the field. A pending edit wins until resolved. */
434
+ protected readonly display: _angular_core.Signal<string>;
435
+ /** The "March 2026" heading. */
436
+ /**
437
+ * `Intl.supportedValuesOf` is guarded rather than called bare: an empty
438
+ * select beats a throw at mount on an older embedded runtime that
439
+ * lacks the method entirely.
440
+ */
441
+ protected readonly zoneOptions: _angular_core.Signal<string[]>;
442
+ protected readonly periodText: _angular_core.Signal<string>;
443
+ /** Column headings, in this locale, starting on `weekStart`. */
444
+ protected readonly weekdays: _angular_core.Signal<{
445
+ short: string;
446
+ long: string;
447
+ }[]>;
448
+ protected readonly weeks: _angular_core.Signal<string[][]>;
449
+ protected readonly pendingHour: _angular_core.Signal<number>;
450
+ protected readonly pendingMinute: _angular_core.Signal<number>;
451
+ /**
452
+ * The hours offered.
453
+ *
454
+ * On a 12-hour clock this lists only the half of the day the meridiem
455
+ * select is currently on, so the two controls together name exactly one
456
+ * hour. Listing 1-12 once and letting the meridiem reinterpret it is
457
+ * the same thing, but it makes "12 AM" ambiguous at precisely the point
458
+ * where users already get it wrong.
459
+ */
460
+ protected readonly hourOptions: _angular_core.Signal<{
461
+ value: number;
462
+ label: string;
463
+ }[]>;
464
+ protected readonly minuteOptions: _angular_core.Signal<number[]>;
465
+ protected readonly childContext: _angular_core.Signal<{
466
+ /** The committed value, in ISO form. */
467
+ value: string;
468
+ /** Is the dialog open? */
469
+ open: boolean;
470
+ /** The value as the user sees it in the field. */
471
+ display: string;
472
+ $implicit: ChildArgs;
473
+ }>;
474
+ private initialised;
475
+ constructor();
476
+ protected pad2(n: number): string;
477
+ protected isoWeekOf(isoDate: string): number;
478
+ /** Per-cell derived values for the grid template's `@let`. */
479
+ protected parseCell(isoDate: string): {
480
+ day: string;
481
+ outside: boolean;
482
+ };
483
+ /** Accessible name for one day cell, e.g. "Sunday 1 March 2026". */
484
+ protected dayLabel(isoDate: string): string;
485
+ /** The locale's own AM / PM strings, so neither is hardcoded. */
486
+ protected dayPeriodName(pm: boolean): string;
487
+ private formatTimeForDisplay;
488
+ /** Render an ISO value the way this locale writes it. */
489
+ private defaultFormat;
490
+ protected dayDisabled(isoDate: string): boolean;
491
+ /** The nearest selectable day to `isoDate`, searching outwards. */
492
+ private nearestSelectable;
493
+ protected openDialog(): void;
494
+ /** Where an unset time starts: now, snapped down to the step. */
495
+ private defaultTime;
496
+ /** Focus the grid cursor, or the first control when there is no grid. */
497
+ private focusInitial;
498
+ protected closeDialog(refocus?: boolean): void;
499
+ /** Commit the pending selection to `value` and notify. */
500
+ protected commit(): void;
501
+ protected clear(): void;
502
+ /**
503
+ * Move the cursor, paging the view when the target is off-screen.
504
+ *
505
+ * Disabled days are still reachable — the cursor lands on them and the
506
+ * button is `aria-disabled` (so it takes real focus and announces), so
507
+ * arrowing across a blocked range works. What is refused is leaving
508
+ * the min/max window entirely, because there is nothing out there to
509
+ * navigate to.
510
+ */
511
+ private moveCursor;
512
+ private focusCursor;
513
+ protected selectDay(isoDate: string): void;
514
+ protected shiftMonth(delta: number): void;
515
+ protected shiftYear(delta: number): void;
516
+ /**
517
+ * Week/day steps are the fine end of the header: unlike month/year,
518
+ * which move the GRID and merely carry the cursor, these move the
519
+ * pending day itself by ±7 / ±1 civil days and page the grid only
520
+ * when the new day leaves the shown month. A step off the min/max
521
+ * window is refused outright; a step onto a vetoed day moves the
522
+ * cursor — vetoed days are reachable, as with the arrow keys — but
523
+ * leaves the pending selection where it was. No commit even under
524
+ * `confirmOnSelect`.
525
+ */
526
+ protected shiftDays(delta: number): void;
527
+ protected onTimeZoneSelect(event: Event): void;
528
+ /**
529
+ * A plain index expression (`timeZoneLabels()[zone] ?? zone`) trips
530
+ * NG8102: without `noUncheckedIndexedAccess`, TypeScript types a
531
+ * `Record<string, string>` index as always `string`, so the compiler
532
+ * sees the `??` as dead code even though a real, unlisted zone id is
533
+ * exactly the case it exists for. The cast documents that the index
534
+ * genuinely can miss.
535
+ */
536
+ protected zoneLabel(zone: string): string;
537
+ protected onGridKeydown(event: KeyboardEvent): void;
538
+ /** Everything tabbable inside the dialog, in DOM order. */
539
+ private focusables;
540
+ protected onDialogKeydown(event: KeyboardEvent): void;
541
+ /** Default text parsing, per mode. */
542
+ private parseTypedForMode;
543
+ /** Resolve typed text on blur or Enter. */
544
+ protected resolveTyped(): void;
545
+ protected onFieldKeydown(event: KeyboardEvent): void;
546
+ protected setHour(hour: number): void;
547
+ protected setMinute(minute: number): void;
548
+ /** Cross between AM and PM without changing the minute of the hour. */
549
+ protected setMeridiem(pm: boolean): void;
550
+ protected applyShortcut(shortcut: DateTimeShortcut): void;
551
+ protected onDocumentClick(event: Event): void;
552
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateTimePicker, never>;
553
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateTimePicker, "lily-date-time-picker", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "labels": { "alias": "labels"; "required": true; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "isDateDisabled": { "alias": "isDateDisabled"; "required": false; "isSignal": true; }; "firstDayOfWeek": { "alias": "firstDayOfWeek"; "required": false; "isSignal": true; }; "minuteStep": { "alias": "minuteStep"; "required": false; "isSignal": true; }; "hour12": { "alias": "hour12"; "required": false; "isSignal": true; }; "showWeekNumbers": { "alias": "showWeekNumbers"; "required": false; "isSignal": true; }; "shortcuts": { "alias": "shortcuts"; "required": false; "isSignal": true; }; "confirmOnSelect": { "alias": "confirmOnSelect"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "timeZone": { "alias": "timeZone"; "required": false; "isSignal": true; }; "timeZones": { "alias": "timeZones"; "required": false; "isSignal": true; }; "timeZoneLabels": { "alias": "timeZoneLabels"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "describedBy": { "alias": "describedBy"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readOnly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "formatValue": { "alias": "formatValue"; "required": false; "isSignal": true; }; "parseInput": { "alias": "parseInput"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "timeZone": "timeZoneChange"; "change": "change"; "shortcut": "shortcut"; "invalidInput": "invalidInput"; }, ["iconTemplate"], never, true, never>;
554
+ }
555
+
556
+ export { CALENDAR, DateTimePicker, DateTimePickerIcon, addDays, addMonths, daysInMonth, firstDayOfWeekFor, formatIsoDate, formatIsoTime, fromEpochDay, isoWeek, joinValue, monthMatrix, monthNames, nextDateTimePickerId, numericFieldOrder, pad, parseDateInput, parseIsoDate, parseIsoTime, parseTimeInput, splitValue, toEpochDay, weekdayOf, withinRange };
557
+ export type { ChildArgs, CivilDate, CivilTime, DateTimeMode, DateTimePickerLabels, DateTimeShortcut, ShortcutEvent };
558
+ //# sourceMappingURL=lilydesignsystem-angular-date-time-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lilydesignsystem-angular-date-time-picker.d.ts","sources":["../../date-time-picker.component.ts"],"mappings":"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","names":[]}