@sixbell-telco/sdk
Version:
A collection of reusable components designed for use in Sixbell Telco Angular projects
888 lines • 67.6 kB
JavaScript
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { signal, inject, viewChild, input, output, computed, effect, forwardRef, ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ButtonComponent } from '@sixbell-telco/sdk/components/button';
import { IconComponent } from '@sixbell-telco/sdk/components/icon';
import { heroClock } from '@sixbell-telco/sdk/components/icon/heroicons/outline';
import { matChevronLeft, matChevronRight } from '@sixbell-telco/sdk/components/icon/material/baseline';
import { OverlayComponent, OverlayTriggerComponent, OverlayContentComponent } from '@sixbell-telco/sdk/components/overlay';
import { DateUtils, TIME_SECONDS_FORMAT, TIME_MINUTES_FORMAT } from '@sixbell-telco/sdk/utils/date';
import { SyncUtils } from '@sixbell-telco/sdk/utils/sync';
import { TranslationService, TranslatePipe } from '@sixbell-telco/sdk/utils/translation';
import 'cally';
import dayjs from 'dayjs';
/**
* Supported locales (BCP 47) for the date picker.
* These map directly to the underlying calendar web component locale attribute.
*/
const SUPPORTED_LOCALES = [
'en-US', // English (United States)
'en-GB', // English (United Kingdom)
'es-ES', // Spanish (Spain)
'es-MX', // Spanish (Mexico)
'fr-FR', // French (France)
'de-DE', // German (Germany)
'it-IT', // Italian (Italy)
'pt-BR', // Portuguese (Brazil)
'pt-PT', // Portuguese (Portugal)
'ja-JP', // Japanese (Japan)
'ko-KR', // Korean (Korea)
'zh-CN', // Chinese (Simplified)
'zh-TW', // Chinese (Traditional)
'ru-RU', // Russian (Russia)
'ar-SA', // Arabic (Saudi Arabia)
'hi-IN', // Hindi (India)
'nl-NL', // Dutch (Netherlands)
'sv-SE', // Swedish (Sweden)
'da-DK', // Danish (Denmark)
'no-NO', // Norwegian (Norway)
'fi-FI', // Finnish (Finland)
'pl-PL', // Polish (Poland)
'tr-TR', // Turkish (Turkey)
'he-IL', // Hebrew (Israel)
'th-TH', // Thai (Thailand)
'vi-VN', // Vietnamese (Vietnam)
];
/** Allowed datepicker modes */
const DATEPICKER_MODES = ['single', 'range'];
/** Allowed time display formats for trigger text */
const TIME_DISPLAY_FORMATS = ['24h', '12h'];
/** Allowed Intl.DateTimeFormat dateStyle values we support */
const DATE_STYLES = ['short', 'medium', 'long', 'full'];
/** Allowed number of calendars in range mode */
const RANGE_CALENDARS = [1, 2];
/**
* Datepicker - Single date and date range picker with optional time selection
*
* @remarks
* This component wraps Cally.js calendar elements and provides a rich, accessible
* date and date-range picking experience for Angular apps. It supports:
* - Single or range modes
* - Quick action ranges
* - Optional time selection with minutes or seconds
* - 12h/24h time display for the trigger text
* - Locale-aware calendar (auto-mapped from the TranslationService or overridden)
* - Form integration (reactive forms) and standalone usage
*
* The component is exported as `stDatepicker` for template reference variables
* to access methods (e.g. displayValue()).
*
* @example Basic single date
* ```html
* <st-datepicker
* label="Pick a date"
* mode="single"
* format="DD/MM/YYYY"
* (dateUpdated)="onDate($event)"
* #picker="stDatepicker"
* >
* <st-button [outline]="true">{{ picker.displayValue() || 'Pick a date' }}</st-button>
* </st-datepicker>
* ```
*
* @example Date range with time (minutes)
* ```html
* <st-datepicker
* label="Pick range with time"
* mode="range"
* [showTimePicker]="true"
* [showSeconds]="false"
* (rangeUpdated)="onRange($event)"
* (startTimeChanged)="onStartTime($event)"
* (endTimeChanged)="onEndTime($event)"
* #picker="stDatepicker"
* >
* <st-button [outline]="true">{{ picker.displayValue() || 'Pick range' }}</st-button>
* </st-datepicker>
* ```
*
* @example Reactive form control (range)
* ```html
* <form [formGroup]="form">
* <st-datepicker
* [parentForm]="form"
* formControlName="range"
* mode="range"
* [rangeCalendars]="2"
* [showQuickActions]="true"
* name="range"
* >
* <st-input [value]="picker.displayValue()" [readonly]="true" name="range"></st-input>
* </st-datepicker>
* </form>
* ```
*/
class DatepickerComponent {
// ==================== STATE MANAGEMENT ====================
/** Internal state for single date (ISO format) */
_selectedDateValue = signal('');
/** Internal state for date range (ISO format) */
_selectedRangeValue = signal(null);
/** Disabled state */
_disabled = signal(false);
/** Flag to prevent concurrent range updates */
isUpdatingRange = false;
// ==================== DEPENDENCIES ====================
/** Translation service for reactive language changes */
translationService = inject(TranslationService);
// ==================== FORM INTEGRATION ====================
/** Form change callback */
onControlChange = () => { };
/** Form touch callback */
onControlTouch = () => { };
// ==================== COMPONENT REFERENCES ====================
/** Overlay reference for controlling calendar popup */
datePickerOverlay = viewChild('datePickerOverlay');
// ==================== INPUTS ====================
/** Label displayed above the fieldset legend */
label = input('');
/**
* Picker mode
* @defaultValue 'single'
* @remarks 'single' for single date, 'range' for start/end selection
*/
mode = input('single');
/**
* Display/parse format for dates
* @defaultValue 'DD/MM/YYYY'
* @remarks Used for trigger text and for parsing external values (when provided as display strings)
*/
format = input('DD/MM/YYYY');
/**
* Locale used by the calendar web component
* @defaultValue 'en-US'
* @remarks If omitted or set to 'en-US', the component will auto-map from the TranslationService using `languageMapping`.
*/
language = input('en-US');
/** Optional minimum selectable date (display or ISO). Internally coerced to ISO. */
minDate = input(null);
/** Optional maximum selectable date (display or ISO). Internally coerced to ISO. */
maxDate = input(null);
/** Single date value (external binding). Accepts display or ISO; stored internally as ISO. */
value = input('');
/** Date range value (external binding). Accepts display or ISO; stored internally as ISO. */
rangeValue = input(null);
/** Name attribute for associated input (useful when wrapping with st-input). */
name = input('');
/**
* Number of calendars to show in range mode
* @defaultValue 2
*/
rangeCalendars = input(2);
/**
* Whether to show quick action buttons for common ranges
* @defaultValue true
*/
showQuickActions = input(true);
/**
* Whether to show time pickers for start/end
* @defaultValue false
*/
showTimePicker = input(false);
/**
* Whether to include seconds in time inputs and display
* @defaultValue false
*/
showSeconds = input(false);
/**
* Time display format for trigger text
* @defaultValue '24h'
* @remarks Affects only the textual display in the trigger, not the underlying stored time format
*/
timeDisplayFormat = input('24h');
/**
* Mapping of translation language codes (e.g. 'en','es','pt') to calendar locales (e.g. 'en-US','es-MX','pt-BR')
* @defaultValue { en: 'en-US', es: 'es-MX', pt: 'pt-BR' }
*/
languageMapping = input({
en: 'en-US',
es: 'es-MX',
pt: 'pt-BR',
});
/**
* Use locale-based formatting for the trigger display instead of the custom pattern
* @defaultValue false
*/
useLocaleDisplay = input(false);
/**
* Locale date style when useLocaleDisplay=true
* @defaultValue 'short'
*/
dateStyle = input('short');
/** Optional external defaults for start/end time (HH:mm or HH:mm:ss). When empty string, inputs render blank. */
startTimeValue = input('');
endTimeValue = input('');
/**
* Current start time value (internal signal). Empty when unset.
* @internal
*/
startTime = signal('');
/**
* Current end time value (internal signal). Empty when unset.
* @internal
*/
endTime = signal('');
/** Parent reactive form group (optional) */
parentForm = input(null);
/** Name of the form control inside the parent form (optional) */
formControlName = input('');
// ==================== OUTPUTS ====================
/**
* Emits formatted single date when it changes
* @remarks Uses the `format` (or locale display if enabled). For range mode, use `rangeUpdated`.
*/
dateUpdated = output();
/**
* Emits an ISO `DateRange` when both start & end are selected
* @remarks Start/end are always emitted in ISO (YYYY-MM-DD). Time values are emitted separately.
*/
rangeUpdated = output();
/** Emits formatted date when value changes (single mode). Alias of `dateUpdated`. */
valueChanged = output();
/** Emits ISO date range (alias of `rangeUpdated`). */
rangeValueChanged = output();
/** Emits start time (HH:mm or HH:mm:ss) changes; empty string when cleared */
startTimeChanged = output();
/** Emits end time (HH:mm or HH:mm:ss) changes; empty string when cleared */
endTimeChanged = output();
// ==================== COMPUTED PROPERTIES ====================
/** Effective minimum date (input or default 10 years ago) */
effectiveMinDate = computed(() => {
const inputMin = this.minDate();
return inputMin ? DateUtils.toISODate(inputMin) : dayjs().subtract(10, 'year').format('YYYY-MM-DD');
});
/** Effective maximum date (input or default 10 years ahead) */
effectiveMaxDate = computed(() => {
const inputMax = this.maxDate();
return inputMax ? DateUtils.toISODate(inputMax) : dayjs().add(10, 'year').format('YYYY-MM-DD');
});
/** Locale for calendar components */
calendarLocale = computed(() => {
// Track translation changes so the locale updates reactively
this.translationService.changes();
// If a specific language is provided via input, use it
if (this.language() && this.language() !== 'en-US') {
return this.language();
}
// Otherwise, map the current translation language to a calendar locale
const currentLang = this.translationService.getCurrentLanguage();
const mapping = this.languageMapping();
return mapping[currentLang] || mapping['en'] || 'en-US';
});
/** Form control instance from parent form group */
formField = computed(() => {
const form = this.parentForm();
const controlName = this.formControlName();
if (!form || !controlName)
return null;
return form.get(controlName);
});
/** Formatted display value for single date */
selectedDate = computed(() => {
const isoValue = this._selectedDateValue();
if (!isoValue)
return '';
return this.useLocaleDisplay() ? this.formatDateLocale(isoValue) : DateUtils.toDisplayDate(isoValue, this.format());
});
/** Formatted display value for date range */
selectedRange = computed(() => {
const isoRange = this._selectedRangeValue();
if (!isoRange?.start || !isoRange?.end)
return null;
if (this.useLocaleDisplay()) {
return {
start: this.formatDateLocale(isoRange.start),
end: this.formatDateLocale(isoRange.end),
};
}
return { start: DateUtils.toDisplayDate(isoRange.start, this.format()), end: DateUtils.toDisplayDate(isoRange.end, this.format()) };
});
/** @internal Value for calendar-range component (ISO/ISO format) */
rangeCalendarValue = computed(() => {
return DateUtils.toRangeValue(this._selectedRangeValue());
});
// Unified display value (normalize seconds when enabled)
displayValue = computed(() => {
const includeTime = this.showTimePicker();
const withSeconds = this.showSeconds();
const timeFormat = this.timeDisplayFormat();
const use12Hour = timeFormat === '12h';
const normalize = (time) => {
if (!time)
return '';
// Normalize time format first
let normalizedTime;
if (withSeconds) {
normalizedTime = time.length === 8 ? time : `${time}:00`;
}
else {
normalizedTime = time.length >= 5 ? time.slice(0, 5) : time;
}
// Convert to 12-hour format if requested
if (use12Hour) {
normalizedTime = DateUtils.to12HourFormat(normalizedTime, withSeconds);
}
return normalizedTime;
};
if (this.mode() === 'range') {
const range = this.selectedRange();
if (!range)
return '';
if (!includeTime)
return `${range.start} - ${range.end}`;
const stDisp = normalize(this.startTime());
const etDisp = normalize(this.endTime());
const startLabel = stDisp ? `${range.start} ${stDisp}` : range.start;
const endLabel = etDisp ? `${range.end} ${etDisp}` : range.end;
return `${startLabel} - ${endLabel}`;
}
const d = this.selectedDate();
if (!includeTime)
return d;
const stDisp = normalize(this.startTime());
if (!d)
return '';
return stDisp ? `${d} ${stDisp}` : d;
});
/** Time values normalized for the inputs based on showSeconds */
startTimeDisplay = computed(() => {
const t = this.startTime();
const withSeconds = this.showSeconds();
if (!t)
return '';
if (withSeconds)
return t.length === 8 ? t : `${t.slice(0, 5)}:00`;
return t.length >= 5 ? t.slice(0, 5) : '';
});
endTimeDisplay = computed(() => {
const t = this.endTime();
const withSeconds = this.showSeconds();
if (!t)
return '';
if (withSeconds)
return t.length === 8 ? t : `${t.slice(0, 5)}:00`;
return t.length >= 5 ? t.slice(0, 5) : '';
});
/** Keep internal state in sync when rangeValue input changes */
syncInputEff = effect(() => {
if (this.mode() !== 'range')
return;
const inputRange = this.rangeValue();
if (inputRange?.start && inputRange?.end) {
const isoRange = {
start: DateUtils.toISODate(inputRange.start, this.format()),
end: DateUtils.toISODate(inputRange.end, this.format()),
};
this._selectedRangeValue.set(isoRange);
}
});
/** Sync external start/end time inputs into internal signals */
syncTimeInputsEff = effect(() => {
const st = this.startTimeValue();
this.startTime.set(st ?? '');
const et = this.endTimeValue();
this.endTime.set(et ?? '');
});
/** Exposed selected date value (ISO format) for template access */
selectedDateValue = computed(() => this._selectedDateValue());
// Localized From/To date labels (timezone-safe via dayjs)
formatMonthYear(date, locale) {
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }).format(date);
}
formatWeekday(date, locale) {
return new Intl.DateTimeFormat(locale, { weekday: 'long' }).format(date);
}
// Localized short/medium/long/full date for trigger display, timezone-safe for YYYY-MM-DD
formatDateLocale(iso) {
const d = dayjs(iso, 'YYYY-MM-DD', true);
if (!d.isValid())
return iso;
// Create a local Date to avoid TZ shifts when formatting
const safe = new Date(d.year(), d.month(), d.date());
return new Intl.DateTimeFormat(this.calendarLocale(), { dateStyle: this.dateStyle() }).format(safe);
}
fromDay = computed(() => {
const r = this._selectedRangeValue();
if (!r?.start)
return '';
const d = dayjs(r.start, 'YYYY-MM-DD', true);
return d.isValid() ? String(d.date()) : '';
});
fromMonthYear = computed(() => {
const r = this._selectedRangeValue();
if (!r?.start)
return '';
const d = dayjs(r.start, 'YYYY-MM-DD', true);
return d.isValid() ? this.formatMonthYear(d.toDate(), this.calendarLocale()) : '';
});
fromWeekday = computed(() => {
const r = this._selectedRangeValue();
if (!r?.start)
return '';
const d = dayjs(r.start, 'YYYY-MM-DD', true);
return d.isValid() ? this.formatWeekday(d.toDate(), this.calendarLocale()) : '';
});
toDay = computed(() => {
const r = this._selectedRangeValue();
if (!r?.end)
return '';
const d = dayjs(r.end, 'YYYY-MM-DD', true);
return d.isValid() ? String(d.date()) : '';
});
toMonthYear = computed(() => {
const r = this._selectedRangeValue();
if (!r?.end)
return '';
const d = dayjs(r.end, 'YYYY-MM-DD', true);
return d.isValid() ? this.formatMonthYear(d.toDate(), this.calendarLocale()) : '';
});
toWeekday = computed(() => {
const r = this._selectedRangeValue();
if (!r?.end)
return '';
const d = dayjs(r.end, 'YYYY-MM-DD', true);
return d.isValid() ? this.formatWeekday(d.toDate(), this.calendarLocale()) : '';
});
// ==================== COMPONENT LIFECYCLE ====================
constructor() {
// Initialize with default values if none provided
this.initializeValues();
}
// ==================== PRIVATE METHODS ====================
/**
* Initialize component values based on inputs
*/
initializeValues() {
if (this.mode() === 'range') {
// Only set a range if one is provided, otherwise leave empty
const inputRange = this.rangeValue();
if (inputRange?.start && inputRange?.end) {
const isoRange = {
start: DateUtils.toISODate(inputRange.start, this.format()),
end: DateUtils.toISODate(inputRange.end, this.format()),
};
this._selectedRangeValue.set(isoRange);
}
else {
this._selectedRangeValue.set(null);
}
}
else {
// Only set a date if one is provided, otherwise leave empty
const inputValue = this.value();
if (inputValue) {
const isoDate = DateUtils.toISODate(inputValue, this.format());
this._selectedDateValue.set(isoDate);
}
else {
this._selectedDateValue.set('');
}
}
}
/**
* Set single date value programmatically
*/
async setSingleDateValue(isoDate) {
this._selectedDateValue.set(isoDate);
const displayDate = this.selectedDate();
this.emitChanges(displayDate);
// Wait for next frame to ensure proper synchronization
await SyncUtils.nextFrame();
this.closeOverlay();
}
// ==================== PRIVATE HELPER METHODS ====================
/**
* Emit change events and notify form controls
*/
emitChanges(value) {
if (this.mode() === 'range') {
const rangeValue = value;
this.rangeUpdated.emit(rangeValue);
this.rangeValueChanged.emit(rangeValue);
}
else {
const dateValue = value;
this.dateUpdated.emit(dateValue);
this.valueChanged.emit(dateValue);
}
// For form controls, emit null for empty values to trigger validation properly
const formValue = value || null;
this.onControlChange(formValue);
this.onControlTouch();
}
/**
* Close overlay if available
*/
closeOverlay() {
this.datePickerOverlay()?.close();
}
// ==================== PUBLIC API ====================
/**
* Handle calendar change events from Cally components
* @internal
*/
onCalendarChange(calendarElement, event) {
if (this.mode() === 'range') {
// Fire and forget async operation
this.handleRangeCalendarChange(calendarElement, event).catch(console.error);
}
else {
this.handleSingleCalendarChange(calendarElement).catch(console.error);
}
}
/**
* Apply a predefined quick range preset
* @param preset One of: 'last7Days' | 'last30Days' | 'last6Months' | 'lastYear'
* @remarks This updates the date range (ISO). Time inputs are not modified.
*/
async selectQuickRange(preset) {
if (this.mode() !== 'range')
return;
try {
// Get pure date range (ISO) from utils
const quickRange = DateUtils.generateQuickRange(preset);
if (this.isUpdatingRange)
return;
this.isUpdatingRange = true;
await SyncUtils.nextTick();
// Always set range; time picker visibility only affects UI, not logic
await this.setRangeValue(quickRange);
await SyncUtils.nextFrame();
this.isUpdatingRange = false;
}
catch (error) {
console.error('Error applying quick range:', error);
this.isUpdatingRange = false;
}
}
/**
* Apply a time-based quick range (last N hours). Visible only when time picker is enabled.
* @param hours Number of hours to go back from now
* @remarks Updates the date range and emits start/end time strings (HH:mm:ss)
*/
async selectQuickLastHours(hours) {
if (this.mode() !== 'range')
return;
try {
const { range, startTime, endTime } = DateUtils.generateLastHoursRange(hours);
if (this.isUpdatingRange)
return;
this.isUpdatingRange = true;
await SyncUtils.nextTick();
await this.setRangeValue(range);
// Update times and notify
this.startTime.set(startTime);
this.endTime.set(endTime);
this.startTimeChanged.emit(startTime);
this.endTimeChanged.emit(endTime);
await SyncUtils.nextFrame();
this.isUpdatingRange = false;
}
catch (error) {
console.error('Error applying last-hours range:', error);
this.isUpdatingRange = false;
}
}
/**
* Clear the current range selection
* @remarks Also clears start/end time inputs and emits empty strings for time changes.
*/
async clearRange() {
if (this.mode() !== 'range')
return;
// Prevent rapid consecutive clicks
if (this.isUpdatingRange)
return;
this.isUpdatingRange = true;
// Use microtask to ensure proper state synchronization with Cally
await SyncUtils.nextTick();
await this.setRangeValue(null);
// Clear time inputs as well to reflect cleared selection
this.startTime.set('');
this.endTime.set('');
this.startTimeChanged.emit('');
this.endTimeChanged.emit('');
// Wait before allowing next update
await SyncUtils.nextFrame();
this.isUpdatingRange = false;
}
/**
* Clear the current single date selection
*/
clearDate() {
if (this.mode() !== 'single')
return;
this._selectedDateValue.set('');
this.emitChanges(null);
this.closeOverlay();
}
/**
* Set range value programmatically
*/
async setRangeValue(range) {
// Store the range in internal state first
this._selectedRangeValue.set(range);
// Update the calendar element value immediately to sync with Cally
await this.updateCalendarElementValue(range);
// Emit changes to form and outputs (always emit ISO to consumers)
if (range && DateUtils.isValidRange(range)) {
this.emitChanges(range);
}
else {
// Handle clear case - emit null for proper form validation
this.emitChanges(null);
}
// Close overlay after state is synchronized
await SyncUtils.nextFrame();
this.closeOverlay();
}
/**
* Update calendar element to ensure Cally.js synchronization
*/
async updateCalendarElementValue(range) {
// Wait for calendar element to be available
const calendarElement = await SyncUtils.waitForElement('calendar-range');
if (calendarElement) {
const typedElement = calendarElement;
const rangeValue = DateUtils.toRangeValue(range);
// Set the value property directly on the calendar element
typedElement.value = rangeValue;
// Also trigger a property update to ensure Cally.js internal state sync
if (range?.start && range?.end) {
typedElement.setAttribute('start', range.start);
typedElement.setAttribute('end', range.end);
}
else {
typedElement.removeAttribute('start');
typedElement.removeAttribute('end');
}
// Dispatch a change event to notify Cally.js of the programmatic update
typedElement.dispatchEvent(new Event('change', { bubbles: true }));
}
}
// ==================== CALENDAR EVENT HANDLERS ====================
/**
* Handle single date calendar change
*/
async handleSingleCalendarChange(calendarElement) {
const dateValue = this.extractDateValue(calendarElement);
if (dateValue && dayjs(dateValue).isValid()) {
await this.setSingleDateValue(dateValue);
}
}
/**
* Handle range calendar change
*/
async handleRangeCalendarChange(calendarElement, event) {
const rangeValue = this.extractRangeValue(calendarElement);
if (rangeValue && DateUtils.isValidRange(rangeValue)) {
// Update internal state immediately
this._selectedRangeValue.set(rangeValue);
// Determine if this event signals end of selection
const isRangeEnd = event?.type === 'rangeend';
const isSameDay = rangeValue.start === rangeValue.end;
await this.finalizeRangeSelection(rangeValue, isSameDay, isRangeEnd);
}
}
/**
* Finalize range selection: ensure same-day times if needed and emit when selection is complete
*/
async finalizeRangeSelection(rangeValue, isSameDay, isRangeEnd) {
// When time picker is enabled and the range selection is finalized (rangeend),
// ensure default times are set for both same-day and different-day ranges.
// IMPORTANT: Do not override non-empty times provided by the developer or already set by the user.
if (this.showTimePicker() && isRangeEnd) {
const withSeconds = this.showSeconds();
const fmt = withSeconds ? TIME_SECONDS_FORMAT : TIME_MINUTES_FORMAT;
const defaultStart = DateUtils.startOfDay(fmt);
const defaultEnd = DateUtils.endOfDay(fmt);
if (isSameDay) {
// Exception: when start and end are the same day, always span the full day
// even if times were previously set by developer/user.
this.startTime.set(defaultStart);
this.endTime.set(defaultEnd);
this.startTimeChanged.emit(defaultStart);
this.endTimeChanged.emit(defaultEnd);
}
else {
// Different-day range: set defaults only if empty, don't override developer values
if (!this.startTime()) {
this.startTime.set(defaultStart);
this.startTimeChanged.emit(defaultStart);
}
if (!this.endTime()) {
this.endTime.set(defaultEnd);
this.endTimeChanged.emit(defaultEnd);
}
}
}
// Emit and close when:
// - a full different-day range has been selected on change or rangeend
// - a same-day selection is finalized (rangeend)
if (!isSameDay || (isSameDay && isRangeEnd)) {
this.emitChanges(rangeValue);
await SyncUtils.nextFrame();
this.closeOverlay();
}
}
/**
* Extract date value from calendar element
*/
extractDateValue(element) {
const elementWithValue = element;
return elementWithValue.value || element.getAttribute('value') || elementWithValue._value || elementWithValue.__value || '';
}
/**
* Extract range value from calendar element
*/
extractRangeValue(element) {
const elementWithValue = element;
// Handle string format (ISO/ISO)
if (typeof elementWithValue.value === 'string') {
return DateUtils.parseRangeValue(elementWithValue.value);
}
// Handle object format
if (elementWithValue.value && typeof elementWithValue.value === 'object') {
return elementWithValue.value;
}
// Handle attributes
const start = element.getAttribute('start');
const end = element.getAttribute('end');
if (start && end) {
return { start, end };
}
return null;
}
// ==================== CONTROL VALUE ACCESSOR ====================
/**
* Write external model value into the component
*/
writeValue(obj) {
// Prevent writeValue during internal updates to avoid circular updates
if (this.isUpdatingRange)
return;
if (this.mode() === 'range') {
const rangeObj = obj;
if (rangeObj?.start && rangeObj?.end) {
// Convert display format to ISO if needed
const isoRange = {
start: DateUtils.toISODate(rangeObj.start, this.format()),
end: DateUtils.toISODate(rangeObj.end, this.format()),
};
this._selectedRangeValue.set(isoRange);
// Update calendar element to sync with Cally.js
this.updateCalendarElementValue(isoRange);
}
else {
this._selectedRangeValue.set(null);
// Update calendar element to sync with Cally.js
this.updateCalendarElementValue(null);
}
}
else {
const dateStr = obj;
if (dateStr) {
const isoDate = DateUtils.toISODate(dateStr, this.format());
this._selectedDateValue.set(isoDate);
}
else {
this._selectedDateValue.set('');
}
}
}
/**
* Register form change callback
*/
registerOnChange(fn) {
this.onControlChange = fn;
}
/**
* Register form touched callback
*/
registerOnTouched(fn) {
this.onControlTouch = fn;
}
/**
* Update disabled state from Angular forms
*/
setDisabledState(isDisabled) {
this._disabled.set(isDisabled);
}
// ==================== TEMPLATE ACCESS ====================
/** Icons for navigation buttons */
iconChevronLeft = matChevronLeft;
iconChevronRight = matChevronRight;
iconClock = heroClock;
// ==================== TIME PICKER HANDLERS ====================
clampTime(raw, withSeconds) {
// Accept HH:mm or HH:mm:ss; coerce to valid bounds
const parts = raw.split(':').map((p) => p.trim());
let h = Number(parts[0]);
let m = Number(parts[1] ?? '0');
let s = Number(parts[2] ?? '0');
if (!Number.isFinite(h))
h = 0;
if (!Number.isFinite(m))
m = 0;
if (!Number.isFinite(s))
s = 0;
h = Math.max(0, Math.min(23, h));
m = Math.max(0, Math.min(59, m));
s = Math.max(0, Math.min(59, s));
const hh = String(h).padStart(2, '0');
const mm = String(m).padStart(2, '0');
const ss = String(s).padStart(2, '0');
return (withSeconds ? `${hh}:${mm}:${ss}` : `${hh}:${mm}`);
}
onStartTimeChange(ev) {
const raw = ev.target?.value ?? '';
if (!raw) {
this.startTime.set('');
this.startTimeChanged.emit('');
return;
}
const val = this.clampTime(raw, this.showSeconds());
this.startTime.set(val);
this.startTimeChanged.emit(val);
}
onEndTimeChange(ev) {
const raw = ev.target?.value ?? '';
if (!raw) {
this.endTime.set('');
this.endTimeChanged.emit('');
return;
}
const val = this.clampTime(raw, this.showSeconds());
this.endTime.set(val);
this.endTimeChanged.emit(val);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.0", type: DatepickerComponent, isStandalone: true, selector: "st-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rangeValue: { classPropertyName: "rangeValue", publicName: "rangeValue", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, rangeCalendars: { classPropertyName: "rangeCalendars", publicName: "rangeCalendars", isSignal: true, isRequired: false, transformFunction: null }, showQuickActions: { classPropertyName: "showQuickActions", publicName: "showQuickActions", isSignal: true, isRequired: false, transformFunction: null }, showTimePicker: { classPropertyName: "showTimePicker", publicName: "showTimePicker", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, timeDisplayFormat: { classPropertyName: "timeDisplayFormat", publicName: "timeDisplayFormat", isSignal: true, isRequired: false, transformFunction: null }, languageMapping: { classPropertyName: "languageMapping", publicName: "languageMapping", isSignal: true, isRequired: false, transformFunction: null }, useLocaleDisplay: { classPropertyName: "useLocaleDisplay", publicName: "useLocaleDisplay", isSignal: true, isRequired: false, transformFunction: null }, dateStyle: { classPropertyName: "dateStyle", publicName: "dateStyle", isSignal: true, isRequired: false, transformFunction: null }, startTimeValue: { classPropertyName: "startTimeValue", publicName: "startTimeValue", isSignal: true, isRequired: false, transformFunction: null }, endTimeValue: { classPropertyName: "endTimeValue", publicName: "endTimeValue", isSignal: true, isRequired: false, transformFunction: null }, parentForm: { classPropertyName: "parentForm", publicName: "parentForm", isSignal: true, isRequired: false, transformFunction: null }, formControlName: { classPropertyName: "formControlName", publicName: "formControlName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateUpdated: "dateUpdated", rangeUpdated: "rangeUpdated", valueChanged: "valueChanged", rangeValueChanged: "rangeValueChanged", startTimeChanged: "startTimeChanged", endTimeChanged: "endTimeChanged" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatepickerComponent),
multi: true,
},
], viewQueries: [{ propertyName: "datePickerOverlay", first: true, predicate: ["datePickerOverlay"], descendants: true, isSignal: true }], exportAs: ["stDatepicker"], ngImport: i0, template: "<fieldset class=\"fieldset p-0\">\n\t@if (label()) {\n\t\t<legend class=\"fieldset-legend font-body pt-0 text-pretty\">{{ label() }}</legend>\n\t}\n\n\t<!-- Calendar overlay -->\n\t<st-overlay #datePickerOverlay=\"stOverlay\">\n\t\t<st-overlay-trigger>\n\t\t\t<!-- Projected trigger content (input, button, etc.) -->\n\t\t\t<ng-content></ng-content>\n\t\t</st-overlay-trigger>\n\t\t<st-overlay-content>\n\t\t\t<div class=\"bg-base-200 border-neutral rounded-box shadow-main border p-4\">\n\t\t\t\t@if (mode() === 'range') {\n\t\t\t\t\t<div class=\"flex gap-4\">\n\t\t\t\t\t\t@if (showQuickActions()) {\n\t\t\t\t\t\t\t<!-- Quick Options Sidebar -->\n\t\t\t\t\t\t\t<div class=\"flex w-56 shrink-0 flex-col gap-2\">\n\t\t\t\t\t\t\t\t<h4 class=\"mb-2 text-sm font-medium\">{{ 'sdk.datePicker.quickActions.title' | translate }}</h4>\n\t\t\t\t\t\t\t\t<div class=\"relative\">\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclass=\"flex flex-col overflow-y-auto overscroll-contain\"\n\t\t\t\t\t\t\t\t\t\t[class.pb-4]=\"showTimePicker()\"\n\t\t\t\t\t\t\t\t\t\t[class.max-h-auto]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t[class.max-h-52]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(1)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.lastHour' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(3)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last3Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(6)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last6Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(12)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last12Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(24)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last24Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last7Days')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last7Days' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last30Days')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last30Days' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last6Months')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last6Months' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('lastYear')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.lastYear' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t\t\t<div class=\"from-base-200 pointer-events-none absolute right-2 bottom-0 left-0 z-10 h-8 bg-gradient-to-t to-transparent\"></div>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"divider my-2\"></div>\n\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"clearRange()\">\n\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.clear' | translate }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div class=\"divider divider-horizontal m-0 w-0\"></div>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<div class=\"flex max-w-132 flex-1 flex-col gap-4\" [class.items-start]=\"!showTimePicker()\" [class.items-stretch]=\"showTimePicker()\">\n\t\t\t\t\t\t\t<!-- Calendar -->\n\t\t\t\t\t\t\t<div class=\"flex-1\">\n\t\t\t\t\t\t\t\t@if (rangeCalendars() === 2) {\n\t\t\t\t\t\t\t\t\t<!-- Two Calendar View -->\n\t\t\t\t\t\t\t\t\t<calendar-range\n\t\t\t\t\t\t\t\t\t\t#rangeCalendar\n\t\t\t\t\t\t\t\t\t\tmonths=\"2\"\n\t\t\t\t\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"rangeCalendarValue() || ''\"\n\t\t\t\t\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t\t\t\t\t(change)=\"onCalendarChange(rangeCalendar)\"\n\t\t\t\t\t\t\t\t\t\t(rangeend)=\"onCalendarChange(rangeCalendar, $event)\"\n\t\t\t\t\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronRight\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"next\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-wrap justify-center gap-6\">\n\t\t\t\t\t\t\t\t\t\t\t<calendar-month offset=\"0\" [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t\t\t<calendar-month offset=\"1\" [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</calendar-range>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<!-- Single Calendar View (one month) within range mode) -->\n\t\t\t\t\t\t\t\t\t<calendar-range\n\t\t\t\t\t\t\t\t\t\t#rangeCalendar\n\t\t\t\t\t\t\t\t\t\tmonths=\"1\"\n\t\t\t\t\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"rangeCalendarValue() || ''\"\n\t\t\t\t\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t\t\t\t\t(change)=\"onCalendarChange(rangeCalendar)\"\n\t\t\t\t\t\t\t\t\t\t(rangeend)=\"onCalendarChange(rangeCalendar, $event)\"\n\t\t\t\t\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronRight\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"next\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<calendar-month [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t</calendar-range>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t<div class=\"divider my-2\"></div>\n\t\t\t\t\t\t\t\t<!-- Bottom Time Picker Sidebar -->\n\t\t\t\t\t\t\t\t<div class=\"flex w-full justify-evenly gap-6\" [class.flex-col]=\"rangeCalendars() === 1\">\n\t\t\t\t\t\t\t\t\t<!-- From Time Picker -->\n\t\t\t\t\t\t\t\t\t<div class=\"flex w-63 flex-col\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"text-neutral-secondary font-body text-[14px] leading-normal font-medium tracking-tight text-pretty text-clip\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.labels.from' | translate }}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col\">\n\t\t\t\t\t\t\t\t\t\t\t<!-- Date Display -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-primary font-heading leading-tight font-light tracking-wide text-balance text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-5xl]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-6xl]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromDay() }}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col items-start\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"font-body leading-normal font-medium tracking-tight text-pretty text-clip whitespace-nowrap text-inherit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromMonthYear() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-neutral-secondary font-body leading-normal font-medium tracking-tight text-pretty text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromWeekday() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<!-- Time Picker -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<st-icon [icon]=\"iconClock\" class=\"text-primary text-2xl\"></st-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\t\t[attr.step]=\"showSeconds() ? 1 : null\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"time\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"input input-sm input-bordered input-secondary max-w-fit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[value]=\"startTimeDisplay()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t(input)=\"onStartTimeChange($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<!-- To Time Picker -->\n\t\t\t\t\t\t\t\t\t<div class=\"flex w-63 flex-col\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"text-neutral-secondary font-body text-[14px] leading-normal font-medium tracking-tight text-pretty text-clip\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.labels.to' | translate }}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col\">\n\t\t\t\t\t\t\t\t\t\t\t<!-- Date Display -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-primary font-heading leading-tight font-light tracking-wide text-balance text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-5xl]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-6xl]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toDay() }}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col items-start\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"font-body leading-normal font-medium tracking-tight text-pretty text-clip whitespace-nowrap text-inherit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toMonthYear() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-neutral-secondary font-body leading-normal font-medium tracking-tight text-pretty text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toWeekday() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<!-- Time Picker -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<st-icon [icon]=\"iconClock\" class=\"text-primary text-2xl\"></st-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\t\t[attr.step]=\"showSeconds() ? 1 : null\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"time\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"input input-sm input-bordered input-secondary max-w-fit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[value]=\"endTimeDisplay()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t(input)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<!-- Single Date Mode -->\n\t\t\t\t\t<calendar-date\n\t\t\t\t\t\t#singleCalendar\n\t\t\t\t\t\t[value]=\"selectedDateValue() || ''\"\n\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t(change)=\"onCalendarChange(singleCalendar)\"\n\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t<st-button variant=\"base\" [square]=\"true\" [icon]=\"iconChevronRight\" size=\"xs\" [ghost]=\"true\" aria-label=\"Next\" slot=\"next\"></st-button>\n\t\t\t\t\t\t<calendar-month [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t</calendar-date>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</st-overlay-content>\n\t</st-overlay>\n\n\t<!-- Hidden label for accessibility -->\n\t<label class=\"sr-only\" [for]=\"name()\">{{ label() }}</label>\n</fieldset>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: OverlayComponent, selector: "st-overlay", inputs: ["offsetX", "offsetY", "originX", "originY", "overlayX", "overlayY", "fallbacks", "syncWidth"], outputs: ["opened", "closed"], exportAs: ["stOverlay"] }, { kind: "component", type: OverlayTriggerComponent, selector: "st-overlay-trigger" }, { kind: "component", type: OverlayContentComponent, selector: "st-overlay-content" }, { kind: "component", type: ButtonComponent, selector: "st-button", inputs: ["variant", "ghost", "outline", "link", "soft", "dash", "wide", "circle", "square", "glass", "block", "loader", "size", "shadow", "focusable", "icon", "iconPosition", "type", "disabled"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: IconComponent, selector: "st-icon", inputs: ["color", "size", "icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DatepickerComponent, decorators: [{
type: Component,
args: [{ selector: 'st-datepicker', imports: [CommonModule, OverlayComponent, OverlayTriggerComponent, OverlayContentComponent, ButtonComponent, TranslatePipe, IconComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'stDatepicker', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatepickerComponent),
multi: true,
},
], template: "<fieldset class=\"fieldset p-0\">\n\t@if (label()) {\n\t\t<legend class=\"fieldset-legend font-body pt-0 text-pretty\">{{ label() }}</legend>\n\t}\n\n\t<!-- Calendar overlay -->\n\t<st-overlay #datePickerOverlay=\"stOverlay\">\n\t\t<st-overlay-trigger>\n\t\t\t<!-- Projected trigger content (input, button, etc.) -->\n\t\t\t<ng-content></ng-content>\n\t\t</st-overlay-trigger>\n\t\t<st-overlay-content>\n\t\t\t<div class=\"bg-base-200 border-neutral rounded-box shadow-main border p-4\">\n\t\t\t\t@if (mode() === 'range') {\n\t\t\t\t\t<div class=\"flex gap-4\">\n\t\t\t\t\t\t@if (showQuickActions()) {\n\t\t\t\t\t\t\t<!-- Quick Options Sidebar -->\n\t\t\t\t\t\t\t<div class=\"flex w-56 shrink-0 flex-col gap-2\">\n\t\t\t\t\t\t\t\t<h4 class=\"mb-2 text-sm font-medium\">{{ 'sdk.datePicker.quickActions.title' | translate }}</h4>\n\t\t\t\t\t\t\t\t<div class=\"relative\">\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclass=\"flex flex-col overflow-y-auto overscroll-contain\"\n\t\t\t\t\t\t\t\t\t\t[class.pb-4]=\"showTimePicker()\"\n\t\t\t\t\t\t\t\t\t\t[class.max-h-auto]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t[class.max-h-52]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(1)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.lastHour' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(3)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last3Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(6)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last6Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(12)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last12Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickLastHours(24)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last24Hours' | translate }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last7Days')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last7Days' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last30Days')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last30Days' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('last6Months')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.last6Months' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"selectQuickRange('lastYear')\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.lastYear' | translate }}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t\t\t<div class=\"from-base-200 pointer-events-none absolute right-2 bottom-0 left-0 z-10 h-8 bg-gradient-to-t to-transparent\"></div>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"divider my-2\"></div>\n\t\t\t\t\t\t\t\t<button class=\"btn btn-sm btn-ghost justify-start text-left\" (click)=\"clearRange()\">\n\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.quickActions.clear' | translate }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div class=\"divider divider-horizontal m-0 w-0\"></div>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<div class=\"flex max-w-132 flex-1 flex-col gap-4\" [class.items-start]=\"!showTimePicker()\" [class.items-stretch]=\"showTimePicker()\">\n\t\t\t\t\t\t\t<!-- Calendar -->\n\t\t\t\t\t\t\t<div class=\"flex-1\">\n\t\t\t\t\t\t\t\t@if (rangeCalendars() === 2) {\n\t\t\t\t\t\t\t\t\t<!-- Two Calendar View -->\n\t\t\t\t\t\t\t\t\t<calendar-range\n\t\t\t\t\t\t\t\t\t\t#rangeCalendar\n\t\t\t\t\t\t\t\t\t\tmonths=\"2\"\n\t\t\t\t\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"rangeCalendarValue() || ''\"\n\t\t\t\t\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t\t\t\t\t(change)=\"onCalendarChange(rangeCalendar)\"\n\t\t\t\t\t\t\t\t\t\t(rangeend)=\"onCalendarChange(rangeCalendar, $event)\"\n\t\t\t\t\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronRight\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"next\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-wrap justify-center gap-6\">\n\t\t\t\t\t\t\t\t\t\t\t<calendar-month offset=\"0\" [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t\t\t<calendar-month offset=\"1\" [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</calendar-range>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<!-- Single Calendar View (one month) within range mode) -->\n\t\t\t\t\t\t\t\t\t<calendar-range\n\t\t\t\t\t\t\t\t\t\t#rangeCalendar\n\t\t\t\t\t\t\t\t\t\tmonths=\"1\"\n\t\t\t\t\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"rangeCalendarValue() || ''\"\n\t\t\t\t\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t\t\t\t\t(change)=\"onCalendarChange(rangeCalendar)\"\n\t\t\t\t\t\t\t\t\t\t(rangeend)=\"onCalendarChange(rangeCalendar, $event)\"\n\t\t\t\t\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t[icon]=\"iconChevronRight\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\t\t\t\t\t\t\t\t\t\t\tslot=\"next\"\n\t\t\t\t\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t\t\t\t\t<calendar-month [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t\t\t\t\t</calendar-range>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t@if (showTimePicker()) {\n\t\t\t\t\t\t\t\t<div class=\"divider my-2\"></div>\n\t\t\t\t\t\t\t\t<!-- Bottom Time Picker Sidebar -->\n\t\t\t\t\t\t\t\t<div class=\"flex w-full justify-evenly gap-6\" [class.flex-col]=\"rangeCalendars() === 1\">\n\t\t\t\t\t\t\t\t\t<!-- From Time Picker -->\n\t\t\t\t\t\t\t\t\t<div class=\"flex w-63 flex-col\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"text-neutral-secondary font-body text-[14px] leading-normal font-medium tracking-tight text-pretty text-clip\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.labels.from' | translate }}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col\">\n\t\t\t\t\t\t\t\t\t\t\t<!-- Date Display -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-primary font-heading leading-tight font-light tracking-wide text-balance text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-5xl]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-6xl]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromDay() }}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col items-start\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"font-body leading-normal font-medium tracking-tight text-pretty text-clip whitespace-nowrap text-inherit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromMonthYear() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-neutral-secondary font-body leading-normal font-medium tracking-tight text-pretty text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ fromWeekday() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<!-- Time Picker -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<st-icon [icon]=\"iconClock\" class=\"text-primary text-2xl\"></st-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\t\t[attr.step]=\"showSeconds() ? 1 : null\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"time\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"input input-sm input-bordered input-secondary max-w-fit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[value]=\"startTimeDisplay()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t(input)=\"onStartTimeChange($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<!-- To Time Picker -->\n\t\t\t\t\t\t\t\t\t<div class=\"flex w-63 flex-col\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"text-neutral-secondary font-body text-[14px] leading-normal font-medium tracking-tight text-pretty text-clip\">\n\t\t\t\t\t\t\t\t\t\t\t{{ 'sdk.datePicker.labels.to' | translate }}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col\">\n\t\t\t\t\t\t\t\t\t\t\t<!-- Date Display -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-primary font-heading leading-tight font-light tracking-wide text-balance text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-5xl]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-6xl]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toDay() }}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex flex-col items-start\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"font-body leading-normal font-medium tracking-tight text-pretty text-clip whitespace-nowrap text-inherit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toMonthYear() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"text-neutral-secondary font-body leading-normal font-medium tracking-tight text-pretty text-clip\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-xs]=\"rangeCalendars() === 1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[class.text-sm]=\"rangeCalendars() === 2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ toWeekday() }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<!-- Time Picker -->\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<st-icon [icon]=\"iconClock\" class=\"text-primary text-2xl\"></st-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\t\t[attr.step]=\"showSeconds() ? 1 : null\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"time\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"input input-sm input-bordered input-secondary max-w-fit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t[value]=\"endTimeDisplay()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t(input)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<!-- Single Date Mode -->\n\t\t\t\t\t<calendar-date\n\t\t\t\t\t\t#singleCalendar\n\t\t\t\t\t\t[value]=\"selectedDateValue() || ''\"\n\t\t\t\t\t\t[locale]=\"calendarLocale()\"\n\t\t\t\t\t\t[min]=\"effectiveMinDate()\"\n\t\t\t\t\t\t[max]=\"effectiveMaxDate()\"\n\t\t\t\t\t\t(change)=\"onCalendarChange(singleCalendar)\"\n\t\t\t\t\t\tclass=\"w-full\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<st-button\n\t\t\t\t\t\t\tvariant=\"base\"\n\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t[icon]=\"iconChevronLeft\"\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t[ghost]=\"true\"\n\t\t\t\t\t\t\taria-label=\"Previous\"\n\t\t\t\t\t\t\tslot=\"previous\"\n\t\t\t\t\t\t></st-button>\n\t\t\t\t\t\t<st-button variant=\"base\" [square]=\"true\" [icon]=\"iconChevronRight\" size=\"xs\" [ghost]=\"true\" aria-label=\"Next\" slot=\"next\"></st-button>\n\t\t\t\t\t\t<calendar-month [min]=\"effectiveMinDate()\" [max]=\"effectiveMaxDate()\"></calendar-month>\n\t\t\t\t\t</calendar-date>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</st-overlay-content>\n\t</st-overlay>\n\n\t<!-- Hidden label for accessibility -->\n\t<label class=\"sr-only\" [for]=\"name()\">{{ label() }}</label>\n</fieldset>\n" }]
}], ctorParameters: () => [] });
/**
* Generated bundle index. Do not edit.
*/
export { DATEPICKER_MODES, DATE_STYLES, DatepickerComponent, RANGE_CALENDARS, SUPPORTED_LOCALES, TIME_DISPLAY_FORMATS };
//# sourceMappingURL=sixbell-telco-sdk-components-forms-date-picker.mjs.map