/** * Copyright Aquera Inc 2026 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import { CSSResultArray, TemplateResult, PropertyValues } from 'lit'; import NileElement from '../internal/nile-element'; import type { NileFloatingPanel } from '../nile-floating-panel'; import '../nile-floating-panel'; import '../nile-calendar'; import '../nile-input'; type TimeUnits = 'minutes' | 'hours' | 'days' | 'weeks' | 'months'; /** * @tag nile-date-time-picker * @event nile-change - Absolute `{ value, localTimezoneValue, unixEpoch, timezone }` (`unixEpoch` = ms since 1970, null when empty); relative `{ startDate, endDate, timezone }`. * @event nile-clear */ export declare class NileDateTimePicker extends NileElement { static get styles(): CSSResultArray; showMonthDropdown: boolean; showYearDropdown: boolean; type: 'absolute' | 'relative'; /** Show the Absolute / Relative type switcher. Hidden by default; set to reveal it. */ showTypes: boolean; hideDurationFields: string[]; hideTimeFields: string[]; /** Selected date/time for the inner `nile-calendar`: an instant, an offset-less wall clock read in `timezone`, the bracketed form, or date-only — all different. `unixEpoch` is the authoritative instant. */ value: string | null; timezone: string; selectedUnit?: TimeUnits; selectedValue?: number; startYear?: number; endYear?: number; allowedDates: string; dateFormat: string; placeholder: string; label: string; accessibleLabel: string; private get structuredInput(); doubleClickUnselect: boolean; disabled: boolean; open: boolean; panel: NileFloatingPanel; private calendarRef; private _openSyncFromPanel; private _skipNextSeed; /** true once the user has typed/pasted/deleted in the mask since the last seed, so only user edits are clamped to allowedDates */ private _maskEdited; /** the zone the consumer configured (first render, or any later external change), restored on Clear instead of forcing UTC */ private _defaultTimezone; /** the last zone this component assigned itself, so `updated` can tell it apart from a consumer change */ private _internalTimezone; private setTimezoneInternally; private static readonly TIME_SPEC; private get resolvedTimeFields(); private get shownTimeFields(); private timeSep; private get showTimezone(); private get defaultPlaceholder(); private get triggerInput(); get calendarElement(): any; connectedCallback(): void; disconnectedCallback(): void; private syncOpenFromPanel; /** keep `open` in sync with the panel's own show/hide (click, outside-click, Escape) */ /** `performance.now()` of an Escape pressed while focus was inside the panel; 0 when there is none to honour */ private _escapeFromPanelAt; /** * The panel hides on a document-level Escape and drops focus to
when the focused control disappears with it. * Runs in the capture phase, before the panel's own handler, to note whether focus was inside the panel; onPanelHide * then hands focus back to the trigger. Escape with focus anywhere else leaves focus where it is. */ private onEscapeKeydown; /** the element that really holds focus, however deep in shadow roots */ private deepActiveElement; /** tab stops inside the panel in DOM order, looking through shadow roots (the panel is portaled to ) */ private panelTabbables; /** the panel's way in: the day that owns the grid's tab stop, else the first control */ private focusIntoPanel; /** * The panel is portaled to the end of , so the browser's own Tab order skips it (Chrome, Edge, Firefox) or * lands in it from the wrong side. While it is open Tab from the field enters it at its first control, Shift+Tab from its first control * returns to the field, and Tab from its last control hands focus back to the field so the browser's default move * continues to the next page element (the panel then closes: it has been left). No trap: Shift+Tab from the field and * every Tab outside the panel behave as usual. */ private onPanelTab; /** ArrowDown / Alt+ArrowDown on the field opens the panel and moves focus into it. Enter, Space and typing are untouched. */ private onTriggerKeydown; private focusIsInPanel; /** * nile-floating-panel creates the `role="dialog"` container itself, portals it out of this shadow root and gives it no * name. Name it here after the field it belongs to, so the shared panel (and nile-context-menu) stays untouched. */ private applyDialogName; private onPanelShow; /** set by Apply: the next open lands on the committed date, not on whatever year/month was browsed before it */ private _showCommittedOnOpen; /** * The month/year dropdowns only navigate, so after Apply the view can be left on a browsed month. Reopening then shows the * committed date's month/year. Dismissing without Apply (Escape, outside click) never takes this path: the view and any * pending selection stay as the user left them. With no selection the view is left alone. */ private showSelectedMonth; private onPanelHide; willUpdate(changedProperties: PropertyValues): void; firstUpdated(changedProperties: PropertyValues): void; updated(changedProperties: Map