@lesterarte/sefin-ui 0.0.10 → 0.0.12-dev.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.
@@ -3103,21 +3103,19 @@ class DatepickerComponent {
3103
3103
  cdr;
3104
3104
  ngZone;
3105
3105
  containerRef;
3106
- calendarRef;
3107
3106
  textfieldRef;
3107
+ calendarRef;
3108
3108
  value = null;
3109
3109
  placeholder = 'Selecciona una fecha';
3110
3110
  disabled = false;
3111
3111
  size = 'md';
3112
- class = '';
3113
3112
  format = 'DD/MM/YYYY';
3114
3113
  mode = 'single';
3115
3114
  minDate;
3116
3115
  maxDate;
3117
3116
  showTodayButton = true;
3118
3117
  showClearButton = true;
3119
- locale = 'es-ES';
3120
- firstDayOfWeek = 1; // 0 = Sunday, 1 = Monday
3118
+ firstDayOfWeek = 1;
3121
3119
  valueChange = new EventEmitter();
3122
3120
  dateSelected = new EventEmitter();
3123
3121
  isOpen = false;
@@ -3126,8 +3124,8 @@ class DatepickerComponent {
3126
3124
  rangeStart = null;
3127
3125
  rangeEnd = null;
3128
3126
  displayValue = '';
3129
- hoveredDate = null;
3130
- monthsES = [
3127
+ viewMode = 'month';
3128
+ months = [
3131
3129
  'Enero',
3132
3130
  'Febrero',
3133
3131
  'Marzo',
@@ -3141,42 +3139,49 @@ class DatepickerComponent {
3141
3139
  'Noviembre',
3142
3140
  'Diciembre',
3143
3141
  ];
3144
- daysES = ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'];
3145
- daysESFull = [
3146
- 'Domingo',
3147
- 'Lunes',
3148
- 'Martes',
3149
- 'Miércoles',
3150
- 'Jueves',
3151
- 'Viernes',
3152
- 'Sábado',
3153
- ];
3142
+ days = ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'];
3154
3143
  constructor(cdr, ngZone) {
3155
3144
  this.cdr = cdr;
3156
3145
  this.ngZone = ngZone;
3146
+ this.currentMonth.setDate(1);
3157
3147
  }
3158
3148
  ngOnInit() {
3159
3149
  this.initializeDates();
3160
- this.updateDisplayValue();
3150
+ }
3151
+ ngAfterViewInit() {
3152
+ // Asegurar que el textfield esté disponible antes de actualizar el display
3153
+ this.updateDisplay();
3154
+ this.cdr.detectChanges();
3161
3155
  }
3162
3156
  ngOnChanges(changes) {
3163
- if (changes['value']) {
3164
- this.initializeDates();
3165
- this.updateDisplayValue();
3166
- }
3167
- if (changes['mode']) {
3157
+ if (changes['value'] || changes['mode']) {
3168
3158
  this.initializeDates();
3169
- this.updateDisplayValue();
3159
+ // Usar setTimeout para asegurar que el textfield esté disponible
3160
+ setTimeout(() => {
3161
+ this.updateDisplay();
3162
+ }, 0);
3170
3163
  }
3171
3164
  }
3172
- ngOnDestroy() { }
3165
+ justOpened = false;
3166
+ isSelectingDate = false;
3173
3167
  onClickOutside(event) {
3174
- if (this.containerRef?.nativeElement && this.isOpen) {
3175
- const clickedInside = this.containerRef.nativeElement.contains(event.target);
3176
- if (!clickedInside) {
3168
+ // No procesar si el calendario está cerrado, se está seleccionando una fecha, o se acaba de abrir
3169
+ if (!this.isOpen || this.isSelectingDate || this.justOpened) {
3170
+ return;
3171
+ }
3172
+ const target = event.target;
3173
+ // Verificar si el click es dentro del calendario o del contenedor - si es así, no cerrar
3174
+ if (this.calendarRef?.nativeElement?.contains(target) ||
3175
+ this.containerRef?.nativeElement?.contains(target)) {
3176
+ return;
3177
+ }
3178
+ // Click está fuera - cerrar el calendario con un pequeño delay
3179
+ setTimeout(() => {
3180
+ // Verificar nuevamente antes de cerrar
3181
+ if (this.isOpen && !this.isSelectingDate && !this.justOpened) {
3177
3182
  this.closeCalendar();
3178
3183
  }
3179
- }
3184
+ }, 150);
3180
3185
  }
3181
3186
  onKeyDown(event) {
3182
3187
  if (event.key === 'Escape' && this.isOpen) {
@@ -3185,23 +3190,53 @@ class DatepickerComponent {
3185
3190
  }
3186
3191
  initializeDates() {
3187
3192
  if (this.mode === 'single') {
3188
- this.selectedDate = this.value instanceof Date ? new Date(this.value) : null;
3193
+ // Manejar diferentes tipos de valor
3194
+ if (this.value instanceof Date) {
3195
+ this.selectedDate = new Date(this.value);
3196
+ // Normalizar la fecha para evitar problemas de comparación
3197
+ this.selectedDate.setHours(0, 0, 0, 0);
3198
+ }
3199
+ else if (this.value && typeof this.value === 'object' && 'getTime' in this.value) {
3200
+ // Caso especial: objeto Date que no es instancia de Date
3201
+ this.selectedDate = new Date(this.value);
3202
+ this.selectedDate.setHours(0, 0, 0, 0);
3203
+ }
3204
+ else {
3205
+ this.selectedDate = null;
3206
+ }
3189
3207
  this.rangeStart = null;
3190
3208
  this.rangeEnd = null;
3191
3209
  if (this.selectedDate) {
3192
- this.currentMonth = new Date(this.selectedDate);
3210
+ this.currentMonth = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1);
3211
+ }
3212
+ else {
3213
+ this.currentMonth = new Date();
3214
+ this.currentMonth.setDate(1);
3193
3215
  }
3194
3216
  }
3195
3217
  else {
3196
3218
  const range = this.value;
3197
3219
  this.selectedDate = null;
3198
- this.rangeStart = range?.start ? new Date(range.start) : null;
3199
- this.rangeEnd = range?.end ? new Date(range.end) : null;
3220
+ if (range?.start) {
3221
+ this.rangeStart = new Date(range.start);
3222
+ this.rangeStart.setHours(0, 0, 0, 0);
3223
+ }
3224
+ else {
3225
+ this.rangeStart = null;
3226
+ }
3227
+ if (range?.end) {
3228
+ this.rangeEnd = new Date(range.end);
3229
+ this.rangeEnd.setHours(0, 0, 0, 0);
3230
+ }
3231
+ else {
3232
+ this.rangeEnd = null;
3233
+ }
3200
3234
  if (this.rangeStart) {
3201
- this.currentMonth = new Date(this.rangeStart);
3235
+ this.currentMonth = new Date(this.rangeStart.getFullYear(), this.rangeStart.getMonth(), 1);
3202
3236
  }
3203
- else if (this.rangeEnd) {
3204
- this.currentMonth = new Date(this.rangeEnd);
3237
+ else {
3238
+ this.currentMonth = new Date();
3239
+ this.currentMonth.setDate(1);
3205
3240
  }
3206
3241
  }
3207
3242
  }
@@ -3209,200 +3244,313 @@ class DatepickerComponent {
3209
3244
  if (this.disabled)
3210
3245
  return;
3211
3246
  this.isOpen = !this.isOpen;
3212
- if (this.isOpen && !this.currentMonth) {
3213
- this.currentMonth = new Date();
3214
- }
3247
+ this.cdr.detectChanges();
3215
3248
  }
3216
3249
  closeCalendar() {
3217
- this.isOpen = false;
3218
- this.hoveredDate = null;
3250
+ if (this.isOpen) {
3251
+ this.isOpen = false;
3252
+ this.viewMode = 'month';
3253
+ this.cdr.detectChanges();
3254
+ }
3219
3255
  }
3220
- onInputClick() {
3221
- if (!this.disabled) {
3222
- this.toggleCalendar();
3256
+ toggleViewMode(event) {
3257
+ if (event) {
3258
+ event.stopPropagation();
3223
3259
  }
3260
+ this.viewMode = this.viewMode === 'month' ? 'year' : 'month';
3261
+ this.cdr.detectChanges();
3224
3262
  }
3225
- onInputFocus() {
3263
+ getYears() {
3264
+ const currentYear = this.currentMonth.getFullYear();
3265
+ const years = [];
3266
+ const startYear = currentYear - 12;
3267
+ const endYear = currentYear + 12;
3268
+ for (let year = startYear; year <= endYear; year++) {
3269
+ years.push(year);
3270
+ }
3271
+ return years;
3272
+ }
3273
+ selectYear(year, event) {
3274
+ if (event) {
3275
+ event.stopPropagation();
3276
+ }
3277
+ this.currentMonth = new Date(year, this.currentMonth.getMonth(), 1);
3278
+ this.viewMode = 'month';
3279
+ this.cdr.detectChanges();
3280
+ }
3281
+ getMonths() {
3282
+ return this.months.map((name, index) => ({ index, name }));
3283
+ }
3284
+ selectMonth(monthIndex) {
3285
+ this.currentMonth = new Date(this.currentMonth.getFullYear(), monthIndex, 1);
3286
+ this.viewMode = 'month';
3287
+ this.cdr.detectChanges();
3288
+ }
3289
+ onTextFieldClick(event) {
3290
+ if (event) {
3291
+ event.stopPropagation();
3292
+ event.preventDefault();
3293
+ }
3226
3294
  if (!this.disabled) {
3295
+ // Establecer justOpened ANTES de abrir para prevenir que onClickOutside lo cierre
3296
+ this.justOpened = true;
3297
+ // Toggle calendar inmediatamente
3227
3298
  this.toggleCalendar();
3299
+ // Reset flag after a delay
3300
+ setTimeout(() => {
3301
+ this.justOpened = false;
3302
+ }, 300);
3228
3303
  }
3229
3304
  }
3230
- getDaysInMonth(date) {
3231
- return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
3305
+ onTextFieldFocus(event) {
3306
+ if (event) {
3307
+ event.stopPropagation();
3308
+ }
3309
+ if (!this.disabled && !this.isOpen) {
3310
+ // Establecer justOpened ANTES de abrir para prevenir que onClickOutside lo cierre
3311
+ this.justOpened = true;
3312
+ // Toggle calendar inmediatamente
3313
+ this.toggleCalendar();
3314
+ // Reset flag after a delay
3315
+ setTimeout(() => {
3316
+ this.justOpened = false;
3317
+ }, 300);
3318
+ }
3232
3319
  }
3233
- getFirstDayOfMonth(date) {
3234
- const firstDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay();
3235
- return this.firstDayOfWeek === 1 ? (firstDay === 0 ? 6 : firstDay - 1) : firstDay;
3320
+ onTrailingIconClick(event) {
3321
+ event.stopPropagation();
3322
+ event.preventDefault();
3323
+ if (this.displayValue && this.showClearButton && !this.disabled) {
3324
+ this.clearValue();
3325
+ }
3326
+ else if (!this.disabled) {
3327
+ // Establecer justOpened ANTES de abrir para prevenir que onClickOutside lo cierre
3328
+ this.justOpened = true;
3329
+ this.toggleCalendar();
3330
+ // Reset flag after a delay
3331
+ setTimeout(() => {
3332
+ this.justOpened = false;
3333
+ }, 300);
3334
+ }
3236
3335
  }
3237
3336
  getCalendarDays() {
3238
3337
  const days = [];
3239
- const daysInMonth = this.getDaysInMonth(this.currentMonth);
3240
- const firstDay = this.getFirstDayOfMonth(this.currentMonth);
3241
- // Add empty cells for days before the first day of the month
3242
- for (let i = 0; i < firstDay; i++) {
3338
+ const year = this.currentMonth.getFullYear();
3339
+ const month = this.currentMonth.getMonth();
3340
+ const firstDay = new Date(year, month, 1).getDay();
3341
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
3342
+ const offset = this.firstDayOfWeek === 1
3343
+ ? firstDay === 0
3344
+ ? 6
3345
+ : firstDay - 1
3346
+ : firstDay;
3347
+ for (let i = 0; i < offset; i++) {
3243
3348
  days.push(null);
3244
3349
  }
3245
- // Add days of the month
3246
3350
  for (let day = 1; day <= daysInMonth; day++) {
3247
- days.push(new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth(), day));
3351
+ days.push(new Date(year, month, day));
3248
3352
  }
3249
3353
  return days;
3250
3354
  }
3251
3355
  isToday(date) {
3252
3356
  const today = new Date();
3253
- return (date.getDate() === today.getDate() &&
3254
- date.getMonth() === today.getMonth() &&
3255
- date.getFullYear() === today.getFullYear());
3357
+ today.setHours(0, 0, 0, 0);
3358
+ const dateCompare = new Date(date);
3359
+ dateCompare.setHours(0, 0, 0, 0);
3360
+ return dateCompare.getTime() === today.getTime();
3256
3361
  }
3257
3362
  isSelected(date) {
3363
+ if (!date)
3364
+ return false;
3365
+ const dateCompare = new Date(date);
3366
+ dateCompare.setHours(0, 0, 0, 0);
3258
3367
  if (this.mode === 'single') {
3259
3368
  if (!this.selectedDate)
3260
3369
  return false;
3261
- return (date.getDate() === this.selectedDate.getDate() &&
3262
- date.getMonth() === this.selectedDate.getMonth() &&
3263
- date.getFullYear() === this.selectedDate.getFullYear());
3370
+ const selected = new Date(this.selectedDate);
3371
+ selected.setHours(0, 0, 0, 0);
3372
+ return dateCompare.getTime() === selected.getTime();
3264
3373
  }
3265
3374
  else {
3266
- if (!this.rangeStart && !this.rangeEnd)
3267
- return false;
3268
3375
  if (this.rangeStart && this.rangeEnd) {
3269
- return ((date >= this.rangeStart && date <= this.rangeEnd) ||
3270
- (date >= this.rangeEnd && date <= this.rangeStart));
3376
+ const start = new Date(this.rangeStart);
3377
+ start.setHours(0, 0, 0, 0);
3378
+ const end = new Date(this.rangeEnd);
3379
+ end.setHours(0, 0, 0, 0);
3380
+ return (dateCompare.getTime() === start.getTime() ||
3381
+ dateCompare.getTime() === end.getTime());
3271
3382
  }
3272
3383
  if (this.rangeStart) {
3273
- return (date.getDate() === this.rangeStart.getDate() &&
3274
- date.getMonth() === this.rangeStart.getMonth() &&
3275
- date.getFullYear() === this.rangeStart.getFullYear());
3384
+ const start = new Date(this.rangeStart);
3385
+ start.setHours(0, 0, 0, 0);
3386
+ return dateCompare.getTime() === start.getTime();
3276
3387
  }
3277
3388
  return false;
3278
3389
  }
3279
3390
  }
3280
3391
  isInRange(date) {
3281
- if (this.mode !== 'range')
3282
- return false;
3283
- if (!this.rangeStart || !this.rangeEnd) {
3284
- if (this.rangeStart && this.hoveredDate) {
3285
- const start = this.rangeStart < this.hoveredDate ? this.rangeStart : this.hoveredDate;
3286
- const end = this.rangeStart < this.hoveredDate ? this.hoveredDate : this.rangeStart;
3287
- return date >= start && date <= end;
3288
- }
3392
+ if (this.mode !== 'range' || !this.rangeStart || !this.rangeEnd)
3289
3393
  return false;
3290
- }
3291
- const start = this.rangeStart < this.rangeEnd ? this.rangeStart : this.rangeEnd;
3292
- const end = this.rangeStart < this.rangeEnd ? this.rangeEnd : this.rangeStart;
3293
- return date >= start && date <= end;
3394
+ const dateCompare = new Date(date);
3395
+ dateCompare.setHours(0, 0, 0, 0);
3396
+ const start = new Date(this.rangeStart);
3397
+ start.setHours(0, 0, 0, 0);
3398
+ const end = new Date(this.rangeEnd);
3399
+ end.setHours(0, 0, 0, 0);
3400
+ const startTime = start.getTime();
3401
+ const endTime = end.getTime();
3402
+ const dateTime = dateCompare.getTime();
3403
+ return ((dateTime >= startTime && dateTime <= endTime) ||
3404
+ (dateTime >= endTime && dateTime <= startTime));
3294
3405
  }
3295
3406
  isDisabled(date) {
3407
+ const dateCompare = new Date(date);
3408
+ dateCompare.setHours(0, 0, 0, 0);
3296
3409
  if (this.minDate) {
3297
3410
  const min = new Date(this.minDate);
3298
3411
  min.setHours(0, 0, 0, 0);
3299
- const dateCompare = new Date(date);
3300
- dateCompare.setHours(0, 0, 0, 0);
3301
3412
  if (dateCompare < min)
3302
3413
  return true;
3303
3414
  }
3304
3415
  if (this.maxDate) {
3305
3416
  const max = new Date(this.maxDate);
3306
- max.setHours(23, 59, 59, 999);
3307
- const dateCompare = new Date(date);
3308
- dateCompare.setHours(23, 59, 59, 999);
3417
+ max.setHours(0, 0, 0, 0);
3309
3418
  if (dateCompare > max)
3310
3419
  return true;
3311
3420
  }
3312
3421
  return false;
3313
3422
  }
3314
- onDayClick(date, event) {
3315
- if (!date)
3316
- return;
3317
- event.preventDefault();
3318
- event.stopPropagation();
3319
- if (!this.isDisabled(date)) {
3320
- this.selectDate(date);
3423
+ onDayMouseDown(day, event) {
3424
+ if (event) {
3425
+ // Stop propagation to prevent onClickOutside from firing
3426
+ event.stopPropagation();
3427
+ // Set flag IMMEDIATELY to prevent onClickOutside from closing calendar
3428
+ this.isSelectingDate = true;
3321
3429
  }
3322
3430
  }
3323
- selectDate(date) {
3324
- if (this.isDisabled(date))
3431
+ selectDate(date, event) {
3432
+ if (event) {
3433
+ event.stopPropagation();
3434
+ event.stopImmediatePropagation();
3435
+ event.preventDefault();
3436
+ }
3437
+ if (this.isDisabled(date)) {
3438
+ this.isSelectingDate = false;
3325
3439
  return;
3440
+ }
3441
+ // Flag should already be set from mousedown, but ensure it's set
3442
+ this.isSelectingDate = true;
3443
+ // Normalize date to avoid time comparison issues
3444
+ const normalizedDate = new Date(date);
3445
+ normalizedDate.setHours(0, 0, 0, 0);
3326
3446
  if (this.mode === 'single') {
3327
- this.selectedDate = new Date(date);
3328
- this.value = new Date(date);
3329
- // Calculate and set display value
3330
- const formattedDate = this.formatDate(this.selectedDate);
3331
- // Update displayValue
3332
- this.displayValue = formattedDate;
3333
- // Update textfield using writeValue (ControlValueAccessor method)
3447
+ // Check if clicking the same date - if so, just close calendar
3448
+ if (this.selectedDate) {
3449
+ const selected = new Date(this.selectedDate);
3450
+ selected.setHours(0, 0, 0, 0);
3451
+ if (normalizedDate.getTime() === selected.getTime()) {
3452
+ // Same date clicked, just close calendar
3453
+ this.isSelectingDate = false;
3454
+ this.closeCalendar();
3455
+ return;
3456
+ }
3457
+ }
3458
+ // Update state immediately - do this synchronously
3459
+ this.selectedDate = new Date(normalizedDate);
3460
+ this.value = new Date(normalizedDate);
3461
+ // Calculate display value immediately
3462
+ const newDisplayValue = this.formatDate(this.selectedDate);
3463
+ this.displayValue = newDisplayValue;
3464
+ // Update textfield - usar setTimeout para asegurar que el DOM esté listo
3334
3465
  if (this.textfieldRef) {
3335
- this.textfieldRef.writeValue(formattedDate);
3466
+ setTimeout(() => {
3467
+ if (this.textfieldRef) {
3468
+ this.textfieldRef.writeValue(newDisplayValue);
3469
+ }
3470
+ }, 0);
3336
3471
  }
3337
- // Force change detection
3472
+ // Force change detection immediately
3338
3473
  this.cdr.detectChanges();
3339
- // One more update after Angular processes the change
3340
- setTimeout(() => {
3341
- if (this.textfieldRef) {
3342
- this.textfieldRef.writeValue(formattedDate);
3343
- }
3344
- this.cdr.detectChanges();
3345
- }, 10);
3346
- // Emit events
3474
+ // Emit events synchronously to ensure they're processed
3347
3475
  this.valueChange.emit(this.value);
3348
3476
  this.dateSelected.emit(this.value);
3349
- // Close calendar after a delay to ensure value is updated and visible
3477
+ // Close calendar after a delay to ensure everything is updated
3478
+ // Keep flag set during this time to prevent onClickOutside from interfering
3350
3479
  setTimeout(() => {
3351
- this.closeCalendar();
3352
- }, 100);
3480
+ if (this.isOpen) {
3481
+ this.closeCalendar();
3482
+ }
3483
+ // Reset flag after closing
3484
+ this.isSelectingDate = false;
3485
+ }, 250);
3353
3486
  }
3354
3487
  else {
3355
3488
  if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) {
3356
- // Start new range
3357
- this.rangeStart = new Date(date);
3489
+ this.rangeStart = new Date(normalizedDate);
3358
3490
  this.rangeEnd = null;
3359
- this.hoveredDate = null;
3360
- const formattedDate = this.formatDate(this.rangeStart);
3361
- const displayText = `${formattedDate} - ...`;
3362
- this.displayValue = displayText;
3363
- this.updateTextField(displayText);
3491
+ this.value = { start: this.rangeStart, end: null };
3492
+ this.updateDisplay();
3493
+ this.cdr.detectChanges();
3494
+ this.ngZone.run(() => {
3495
+ this.valueChange.emit(this.value);
3496
+ });
3497
+ this.isSelectingDate = false;
3364
3498
  }
3365
3499
  else {
3366
- // Complete range
3367
- this.rangeEnd = new Date(date);
3368
- const range = {
3369
- start: this.rangeStart,
3370
- end: this.rangeEnd,
3371
- };
3372
- this.value = range;
3373
- const formattedValue = `${this.formatDate(range.start)} - ${this.formatDate(range.end)}`;
3374
- this.displayValue = formattedValue;
3375
- this.updateTextField(formattedValue);
3376
- this.valueChange.emit(this.value);
3377
- this.dateSelected.emit(this.value);
3378
- // Close calendar after a delay to ensure value is updated
3379
- setTimeout(() => {
3380
- this.closeCalendar();
3381
- }, 100);
3500
+ this.rangeEnd = new Date(normalizedDate);
3501
+ if (this.rangeStart.getTime() > this.rangeEnd.getTime()) {
3502
+ [this.rangeStart, this.rangeEnd] = [this.rangeEnd, this.rangeStart];
3503
+ }
3504
+ this.value = { start: this.rangeStart, end: this.rangeEnd };
3505
+ this.updateDisplay();
3506
+ this.cdr.detectChanges();
3507
+ this.ngZone.run(() => {
3508
+ this.valueChange.emit(this.value);
3509
+ this.dateSelected.emit(this.value);
3510
+ });
3511
+ this.ngZone.runOutsideAngular(() => {
3512
+ setTimeout(() => {
3513
+ this.ngZone.run(() => {
3514
+ if (this.isOpen) {
3515
+ this.closeCalendar();
3516
+ }
3517
+ this.isSelectingDate = false;
3518
+ });
3519
+ }, 150);
3520
+ });
3382
3521
  }
3383
3522
  }
3384
3523
  }
3385
- updateTextField(value) {
3386
- // This method is kept for compatibility but the main update is done in selectDate
3387
- // Update displayValue
3388
- this.displayValue = value;
3389
- // Update via writeValue
3390
- if (this.textfieldRef) {
3391
- this.textfieldRef.writeValue(value);
3524
+ trackByDate(index, day) {
3525
+ if (!day)
3526
+ return `empty-${index}`;
3527
+ return `${day.getFullYear()}-${day.getMonth()}-${day.getDate()}`;
3528
+ }
3529
+ previousMonth(event) {
3530
+ if (event) {
3531
+ event.stopPropagation();
3532
+ }
3533
+ if (this.viewMode === 'year') {
3534
+ const currentYear = this.currentMonth.getFullYear();
3535
+ this.currentMonth = new Date(currentYear - 25, this.currentMonth.getMonth(), 1);
3536
+ }
3537
+ else {
3538
+ this.currentMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() - 1, 1);
3392
3539
  }
3393
- // Force change detection
3394
3540
  this.cdr.detectChanges();
3395
3541
  }
3396
- onDateHover(date) {
3397
- if (this.mode === 'range' && this.rangeStart && !this.rangeEnd) {
3398
- this.hoveredDate = new Date(date);
3542
+ nextMonth(event) {
3543
+ if (event) {
3544
+ event.stopPropagation();
3399
3545
  }
3400
- }
3401
- previousMonth() {
3402
- this.currentMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() - 1, 1);
3403
- }
3404
- nextMonth() {
3405
- this.currentMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + 1, 1);
3546
+ if (this.viewMode === 'year') {
3547
+ const currentYear = this.currentMonth.getFullYear();
3548
+ this.currentMonth = new Date(currentYear + 25, this.currentMonth.getMonth(), 1);
3549
+ }
3550
+ else {
3551
+ this.currentMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + 1, 1);
3552
+ }
3553
+ this.cdr.detectChanges();
3406
3554
  }
3407
3555
  goToToday() {
3408
3556
  const today = new Date();
@@ -3420,14 +3568,12 @@ class DatepickerComponent {
3420
3568
  this.rangeEnd = null;
3421
3569
  this.value = null;
3422
3570
  }
3423
- this.updateDisplayValue();
3571
+ this.updateDisplay();
3424
3572
  this.valueChange.emit(null);
3425
3573
  this.dateSelected.emit(null);
3426
3574
  this.closeCalendar();
3427
3575
  }
3428
3576
  formatDate(date) {
3429
- if (!date)
3430
- return '';
3431
3577
  const day = String(date.getDate()).padStart(2, '0');
3432
3578
  const month = String(date.getMonth() + 1).padStart(2, '0');
3433
3579
  const year = date.getFullYear();
@@ -3444,42 +3590,46 @@ class DatepickerComponent {
3444
3590
  return `${day}/${month}/${year}`;
3445
3591
  }
3446
3592
  }
3447
- updateDisplayValue() {
3448
- const newValue = this.mode === 'single'
3449
- ? (this.selectedDate ? this.formatDate(this.selectedDate) : '')
3450
- : (() => {
3451
- const range = this.value;
3452
- if (range?.start && range?.end) {
3453
- return `${this.formatDate(range.start)} - ${this.formatDate(range.end)}`;
3454
- }
3455
- else if (range?.start) {
3456
- return `${this.formatDate(range.start)} - ...`;
3457
- }
3458
- else {
3459
- return '';
3460
- }
3461
- })();
3462
- // Update displayValue (for internal use)
3463
- this.displayValue = newValue;
3464
- // Update textfield using writeValue (ControlValueAccessor method)
3465
- // Use setTimeout to ensure ViewChild is available
3466
- setTimeout(() => {
3467
- if (this.textfieldRef) {
3468
- this.textfieldRef.writeValue(newValue);
3593
+ updateDisplay() {
3594
+ let newValue = '';
3595
+ if (this.mode === 'single') {
3596
+ newValue = this.selectedDate
3597
+ ? this.formatDate(this.selectedDate)
3598
+ : '';
3599
+ }
3600
+ else {
3601
+ const range = this.value;
3602
+ if (range?.start && range?.end) {
3603
+ newValue = `${this.formatDate(range.start)} - ${this.formatDate(range.end)}`;
3469
3604
  }
3470
- this.cdr.detectChanges();
3471
- }, 0);
3605
+ else if (range?.start) {
3606
+ newValue = `${this.formatDate(range.start)} - ...`;
3607
+ }
3608
+ else {
3609
+ newValue = '';
3610
+ }
3611
+ }
3612
+ this.displayValue = newValue;
3613
+ // Update textfield value using writeValue
3614
+ // Asegurar que el textfield esté disponible antes de actualizar
3615
+ if (this.textfieldRef) {
3616
+ // Usar setTimeout para asegurar que el DOM esté listo
3617
+ setTimeout(() => {
3618
+ if (this.textfieldRef) {
3619
+ this.textfieldRef.writeValue(this.displayValue);
3620
+ }
3621
+ }, 0);
3622
+ }
3472
3623
  }
3473
3624
  getMonthName() {
3474
- return this.monthsES[this.currentMonth.getMonth()];
3625
+ return this.months[this.currentMonth.getMonth()];
3475
3626
  }
3476
3627
  getYear() {
3477
3628
  return this.currentMonth.getFullYear();
3478
3629
  }
3479
3630
  getDayNames() {
3480
- const days = [...this.daysES];
3631
+ const days = [...this.days];
3481
3632
  if (this.firstDayOfWeek === 1) {
3482
- // Move Sunday to the end
3483
3633
  const sunday = days.shift();
3484
3634
  if (sunday)
3485
3635
  days.push(sunday);
@@ -3487,35 +3637,29 @@ class DatepickerComponent {
3487
3637
  return days;
3488
3638
  }
3489
3639
  get containerClasses() {
3490
- return [
3491
- 'sefin-datepicker',
3492
- this.isOpen ? 'sefin-datepicker--open' : '',
3493
- this.class,
3494
- ]
3495
- .filter(Boolean)
3496
- .join(' ');
3640
+ return `sefin-datepicker sefin-datepicker--${this.size} ${this.isOpen ? 'sefin-datepicker--open' : ''}`.trim();
3497
3641
  }
3498
- get todayDate() {
3499
- return new Date();
3642
+ getCurrentYear() {
3643
+ return new Date().getFullYear();
3500
3644
  }
3501
- isTodayDisabled() {
3502
- return this.isDisabled(this.todayDate);
3645
+ isCurrentYear(year) {
3646
+ return year === this.getCurrentYear();
3503
3647
  }
3504
3648
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DatepickerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
3505
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: DatepickerComponent, isStandalone: true, selector: "sefin-datepicker", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled", size: "size", class: "class", format: "format", mode: "mode", minDate: "minDate", maxDate: "maxDate", showTodayButton: "showTodayButton", showClearButton: "showClearButton", locale: "locale", firstDayOfWeek: "firstDayOfWeek" }, outputs: { valueChange: "valueChange", dateSelected: "dateSelected" }, host: { listeners: { "document:click": "onClickOutside($event)", "document:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }, { propertyName: "calendarRef", first: true, predicate: ["calendarRef"], descendants: true }, { propertyName: "textfieldRef", first: true, predicate: ["textfieldRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-datepicker__wrapper\">\n <sefin-textfield\n #textfieldRef\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [size]=\"size\"\n [readonly]=\"true\"\n [trailingIcon]=\"'calendar'\"\n (click)=\"onInputClick()\"\n (focus)=\"onInputFocus()\"\n class=\"sefin-datepicker__input\"\n ></sefin-textfield>\n <div class=\"sefin-datepicker__actions\">\n <button\n *ngIf=\"displayValue && showClearButton && !disabled\"\n type=\"button\"\n class=\"sefin-datepicker__clear\"\n (click)=\"clearValue()\"\n aria-label=\"Limpiar fecha\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"isOpen\"\n #calendarRef\n class=\"sefin-datepicker__calendar\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"sefin-datepicker__calendar-header\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav-button\"\n (click)=\"previousMonth()\"\n aria-label=\"Mes anterior\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 12L6 8L10 4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"sefin-datepicker__month-year\">\n <span class=\"sefin-datepicker__month\">{{ getMonthName() }}</span>\n <span class=\"sefin-datepicker__year\">{{ getYear() }}</span>\n </div>\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav-button\"\n (click)=\"nextMonth()\"\n aria-label=\"Mes siguiente\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"sefin-datepicker__calendar-body\">\n <div class=\"sefin-datepicker__weekdays\">\n <div\n *ngFor=\"let dayName of getDayNames()\"\n class=\"sefin-datepicker__weekday\"\n >\n {{ dayName }}\n </div>\n </div>\n <div class=\"sefin-datepicker__days\">\n <button\n *ngFor=\"let day of getCalendarDays(); let i = index\"\n type=\"button\"\n class=\"sefin-datepicker__day\"\n [class.sefin-datepicker__day--today]=\"day && isToday(day)\"\n [class.sefin-datepicker__day--selected]=\"day && isSelected(day)\"\n [class.sefin-datepicker__day--in-range]=\"day && isInRange(day)\"\n [class.sefin-datepicker__day--disabled]=\"day && isDisabled(day)\"\n [class.sefin-datepicker__day--empty]=\"!day\"\n [disabled]=\"!day || (day && isDisabled(day))\"\n (click)=\"day && !isDisabled(day) && selectDate(day); $event.stopPropagation(); $event.preventDefault()\"\n (mouseenter)=\"day && onDateHover(day)\"\n [attr.aria-label]=\"day ? formatDate(day) : ''\"\n >\n <span *ngIf=\"day\">{{ day.getDate() }}</span>\n </button>\n </div>\n </div>\n\n <div *ngIf=\"showTodayButton\" class=\"sefin-datepicker__calendar-footer\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__today-button\"\n (click)=\"goToToday()\"\n [disabled]=\"isTodayDisabled()\"\n >\n Hoy\n </button>\n </div>\n </div>\n</div>\n\n", styles: [".sefin-datepicker{position:relative;width:100%}.sefin-datepicker__wrapper{position:relative;display:flex;align-items:center;width:100%}.sefin-datepicker__input{width:100%;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield__input{cursor:pointer}.sefin-datepicker__actions{position:absolute;right:var(--sefin-spacing-sm);display:flex;align-items:center;gap:var(--sefin-spacing-xs);z-index:1;pointer-events:none}.sefin-datepicker__clear{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text-secondary);cursor:pointer;transition:all .2s ease-in-out;pointer-events:all}.sefin-datepicker__clear:hover{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-datepicker__clear:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__clear svg{width:16px;height:16px}.sefin-datepicker__calendar{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);padding:var(--sefin-spacing-md);min-width:300px;max-width:320px}.sefin-datepicker__calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sefin-spacing-md)}.sefin-datepicker__nav-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__nav-button:hover{background-color:var(--sefin-color-surface-hover)}.sefin-datepicker__nav-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__nav-button svg{width:16px;height:16px}.sefin-datepicker__month-year{display:flex;align-items:center;gap:var(--sefin-spacing-xs);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-semibold);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text)}.sefin-datepicker__month{text-transform:capitalize}.sefin-datepicker__year{color:var(--sefin-color-text-secondary)}.sefin-datepicker__calendar-body{margin-bottom:var(--sefin-spacing-sm)}.sefin-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs);margin-bottom:var(--sefin-spacing-xs)}.sefin-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-xs);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.sefin-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs)}.sefin-datepicker__day{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;position:relative}.sefin-datepicker__day:hover:not(.sefin-datepicker__day--disabled):not(.sefin-datepicker__day--empty){background-color:var(--sefin-color-surface-hover)}.sefin-datepicker__day--today{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary)}.sefin-datepicker__day--today:before{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:var(--sefin-color-primary);border-radius:50%}.sefin-datepicker__day--selected{background-color:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold)}.sefin-datepicker__day--selected:before{display:none}.sefin-datepicker__day--in-range{background-color:var(--sefin-color-primary-light);color:var(--sefin-color-primary)}.sefin-datepicker__day--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.sefin-datepicker__day--empty{cursor:default;pointer-events:none}.sefin-datepicker__day:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__calendar-footer{display:flex;align-items:center;justify-content:center;padding-top:var(--sefin-spacing-sm);border-top:1px solid var(--sefin-color-border)}.sefin-datepicker__today-button{padding:var(--sefin-spacing-xs) var(--sefin-spacing-md);background:transparent;border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-sm);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__today-button:hover:not(:disabled){background-color:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border-focus)}.sefin-datepicker__today-button:disabled{opacity:.5;cursor:not-allowed}.sefin-datepicker__today-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker--open .sefin-datepicker__input ::ng-deep .sefin-textfield__input{border-color:var(--sefin-color-border-focus)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TextFieldComponent, selector: "sefin-textfield", inputs: ["variant", "size", "type", "placeholder", "hint", "errorMessage", "required", "disabled", "readonly", "maxLength", "minLength", "pattern", "leadingIcon", "trailingIcon", "showCounter", "autocomplete", "name", "id", "class", "customValidator"], outputs: ["valueChange", "focused", "blurred", "trailingIconClick"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
3649
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: DatepickerComponent, isStandalone: true, selector: "sefin-datepicker", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled", size: "size", format: "format", mode: "mode", minDate: "minDate", maxDate: "maxDate", showTodayButton: "showTodayButton", showClearButton: "showClearButton", firstDayOfWeek: "firstDayOfWeek" }, outputs: { valueChange: "valueChange", dateSelected: "dateSelected" }, host: { listeners: { "document:click": "onClickOutside($event)", "document:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }, { propertyName: "textfieldRef", first: true, predicate: ["textfieldRef"], descendants: true }, { propertyName: "calendarRef", first: true, predicate: ["calendarRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-datepicker__wrapper\">\n <div\n (click)=\"onTextFieldClick($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\"\n class=\"sefin-datepicker__input-wrapper\"\n >\n <sefin-textfield\n #textfieldRef\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [size]=\"size\"\n [readonly]=\"true\"\n [trailingIcon]=\"\n displayValue && showClearButton && !disabled ? 'x' : 'calendar'\n \"\n (focused)=\"onTextFieldFocus($event)\"\n (trailingIconClick)=\"onTrailingIconClick($event)\"\n class=\"sefin-datepicker__input\"\n ></sefin-textfield>\n </div>\n </div>\n\n <div\n *ngIf=\"isOpen\"\n #calendarRef\n class=\"sefin-datepicker__calendar\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <div class=\"sefin-datepicker__header\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav\"\n (click)=\"previousMonth($event)\"\n >\n <sefin-icon name=\"chevron-left\" size=\"sm\"></sefin-icon>\n </button>\n <button\n type=\"button\"\n class=\"sefin-datepicker__month-year-btn\"\n (click)=\"toggleViewMode($event)\"\n >\n <span *ngIf=\"viewMode === 'month'\"\n >{{ getMonthName() }} {{ getYear() }}</span\n >\n <span *ngIf=\"viewMode === 'year'\">{{ getYear() }}</span>\n </button>\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav\"\n (click)=\"nextMonth($event)\"\n >\n <sefin-icon name=\"chevron-right\" size=\"sm\"></sefin-icon>\n </button>\n </div>\n\n <!-- Vista de Meses -->\n <div *ngIf=\"viewMode === 'month'\" class=\"sefin-datepicker__month-view\">\n <div class=\"sefin-datepicker__weekdays\">\n <div\n *ngFor=\"let day of getDayNames()\"\n class=\"sefin-datepicker__weekday\"\n >\n {{ day }}\n </div>\n </div>\n\n <div class=\"sefin-datepicker__days\">\n <button\n *ngFor=\"let day of getCalendarDays(); trackBy: trackByDate\"\n type=\"button\"\n class=\"sefin-datepicker__day\"\n [class.sefin-datepicker__day--today]=\"day && isToday(day)\"\n [class.sefin-datepicker__day--selected]=\"day && isSelected(day)\"\n [class.sefin-datepicker__day--in-range]=\"day && isInRange(day)\"\n [class.sefin-datepicker__day--disabled]=\"day && isDisabled(day)\"\n [class.sefin-datepicker__day--empty]=\"!day\"\n [disabled]=\"!day || (day && isDisabled(day))\"\n (mousedown)=\"day && !isDisabled(day) && onDayMouseDown(day, $event)\"\n (click)=\"day && !isDisabled(day) && selectDate(day, $event)\"\n >\n {{ day ? day.getDate() : \"\" }}\n </button>\n </div>\n </div>\n\n <!-- Vista de A\u00F1os -->\n <div *ngIf=\"viewMode === 'year'\" class=\"sefin-datepicker__year-view\">\n <div class=\"sefin-datepicker__years-grid\">\n <button\n *ngFor=\"let year of getYears()\"\n type=\"button\"\n class=\"sefin-datepicker__year\"\n [class.sefin-datepicker__year--current]=\"isCurrentYear(year)\"\n [class.sefin-datepicker__year--selected]=\"\n year === currentMonth.getFullYear()\n \"\n (click)=\"selectYear(year, $event)\"\n >\n {{ year }}\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"showTodayButton && viewMode === 'month'\"\n class=\"sefin-datepicker__footer\"\n >\n <button\n type=\"button\"\n class=\"sefin-datepicker__today\"\n (click)=\"goToToday()\"\n >\n Hoy\n </button>\n </div>\n </div>\n</div>\n", styles: [".sefin-datepicker{position:relative;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif)}.sefin-datepicker *{font-family:inherit}.sefin-datepicker__wrapper{position:relative;width:100%}.sefin-datepicker__input-wrapper{width:100%;cursor:pointer;position:relative}.sefin-datepicker__input{width:100%;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield{font-family:inherit;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield__input{cursor:pointer!important;font-family:inherit}.sefin-datepicker__input ::ng-deep .sefin-textfield__trailing-icon{cursor:pointer!important;pointer-events:auto}.sefin-datepicker__input ::ng-deep .sefin-textfield__wrapper{cursor:pointer}.sefin-datepicker__calendar{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;z-index:1000;background:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);padding:var(--sefin-spacing-md);min-width:300px;max-width:320px;animation:fadeIn .2s ease-in-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.sefin-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sefin-spacing-md);padding-bottom:var(--sefin-spacing-sm);border-bottom:1px solid var(--sefin-color-border)}.sefin-datepicker__nav{width:36px;height:36px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sefin-color-text);transition:all .2s ease-in-out}.sefin-datepicker__nav:hover:not(:disabled){background:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-datepicker__nav:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__nav:disabled{opacity:.4;cursor:not-allowed}.sefin-datepicker__month-year-btn{padding:var(--sefin-spacing-xs) var(--sefin-spacing-sm);background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-semibold);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);text-transform:capitalize;cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__month-year-btn:hover{background:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-datepicker__month-year-btn:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs);margin-bottom:var(--sefin-spacing-sm);padding-bottom:var(--sefin-spacing-xs)}.sefin-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:var(--sefin-font-size-xs);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.sefin-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs)}.sefin-datepicker__day{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;position:relative}.sefin-datepicker__day:hover:not(.sefin-datepicker__day--disabled):not(.sefin-datepicker__day--empty){background:var(--sefin-color-surface-hover);cursor:pointer}.sefin-datepicker__day--today{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary)}.sefin-datepicker__day--today:before{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:var(--sefin-color-primary);border-radius:50%}.sefin-datepicker__day--selected{background:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold);z-index:1;cursor:pointer}.sefin-datepicker__day--selected:before{display:none}.sefin-datepicker__day--selected:hover{background:var(--sefin-color-primary-dark);cursor:pointer}.sefin-datepicker__day--in-range{background:var(--sefin-color-primary-light);color:var(--sefin-color-primary);border-radius:0;cursor:pointer}.sefin-datepicker__day--in-range:first-child{border-top-left-radius:var(--sefin-radius-sm);border-bottom-left-radius:var(--sefin-radius-sm)}.sefin-datepicker__day--in-range:last-child{border-top-right-radius:var(--sefin-radius-sm);border-bottom-right-radius:var(--sefin-radius-sm)}.sefin-datepicker__day--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.sefin-datepicker__day--empty{cursor:default;pointer-events:none}.sefin-datepicker__day:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__footer{display:flex;align-items:center;justify-content:center;margin-top:var(--sefin-spacing-md);padding-top:var(--sefin-spacing-md);border-top:1px solid var(--sefin-color-border)}.sefin-datepicker__today{padding:var(--sefin-spacing-xs) var(--sefin-spacing-md);background:transparent;border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__today:hover:not(:disabled){background:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border-focus);color:var(--sefin-color-primary)}.sefin-datepicker__today:disabled{opacity:.5;cursor:not-allowed}.sefin-datepicker__today:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__year-view{padding:var(--sefin-spacing-sm) 0}.sefin-datepicker__years-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sefin-spacing-xs);max-height:300px;overflow-y:auto}.sefin-datepicker__year{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;text-align:center}.sefin-datepicker__year:hover{background:var(--sefin-color-surface-hover)}.sefin-datepicker__year--current{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary);cursor:pointer}.sefin-datepicker__year--selected{background:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold);cursor:pointer}.sefin-datepicker__year--selected:hover{cursor:pointer}.sefin-datepicker__year:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker--open .sefin-datepicker__input ::ng-deep .sefin-textfield .sefin-textfield__border{border-color:var(--sefin-color-border-focus)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconComponent, selector: "sefin-icon", inputs: ["name", "size", "color", "rotate", "flipH", "flipV", "class"] }, { kind: "component", type: TextFieldComponent, selector: "sefin-textfield", inputs: ["variant", "size", "type", "placeholder", "hint", "errorMessage", "required", "disabled", "readonly", "maxLength", "minLength", "pattern", "leadingIcon", "trailingIcon", "showCounter", "autocomplete", "name", "id", "class", "customValidator"], outputs: ["valueChange", "focused", "blurred", "trailingIconClick"] }] });
3506
3650
  }
3507
3651
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DatepickerComponent, decorators: [{
3508
3652
  type: Component,
3509
- args: [{ selector: 'sefin-datepicker', standalone: true, imports: [CommonModule, FormsModule, TextFieldComponent, IconComponent], changeDetection: ChangeDetectionStrategy.Default, template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-datepicker__wrapper\">\n <sefin-textfield\n #textfieldRef\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [size]=\"size\"\n [readonly]=\"true\"\n [trailingIcon]=\"'calendar'\"\n (click)=\"onInputClick()\"\n (focus)=\"onInputFocus()\"\n class=\"sefin-datepicker__input\"\n ></sefin-textfield>\n <div class=\"sefin-datepicker__actions\">\n <button\n *ngIf=\"displayValue && showClearButton && !disabled\"\n type=\"button\"\n class=\"sefin-datepicker__clear\"\n (click)=\"clearValue()\"\n aria-label=\"Limpiar fecha\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"isOpen\"\n #calendarRef\n class=\"sefin-datepicker__calendar\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"sefin-datepicker__calendar-header\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav-button\"\n (click)=\"previousMonth()\"\n aria-label=\"Mes anterior\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 12L6 8L10 4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"sefin-datepicker__month-year\">\n <span class=\"sefin-datepicker__month\">{{ getMonthName() }}</span>\n <span class=\"sefin-datepicker__year\">{{ getYear() }}</span>\n </div>\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav-button\"\n (click)=\"nextMonth()\"\n aria-label=\"Mes siguiente\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"sefin-datepicker__calendar-body\">\n <div class=\"sefin-datepicker__weekdays\">\n <div\n *ngFor=\"let dayName of getDayNames()\"\n class=\"sefin-datepicker__weekday\"\n >\n {{ dayName }}\n </div>\n </div>\n <div class=\"sefin-datepicker__days\">\n <button\n *ngFor=\"let day of getCalendarDays(); let i = index\"\n type=\"button\"\n class=\"sefin-datepicker__day\"\n [class.sefin-datepicker__day--today]=\"day && isToday(day)\"\n [class.sefin-datepicker__day--selected]=\"day && isSelected(day)\"\n [class.sefin-datepicker__day--in-range]=\"day && isInRange(day)\"\n [class.sefin-datepicker__day--disabled]=\"day && isDisabled(day)\"\n [class.sefin-datepicker__day--empty]=\"!day\"\n [disabled]=\"!day || (day && isDisabled(day))\"\n (click)=\"day && !isDisabled(day) && selectDate(day); $event.stopPropagation(); $event.preventDefault()\"\n (mouseenter)=\"day && onDateHover(day)\"\n [attr.aria-label]=\"day ? formatDate(day) : ''\"\n >\n <span *ngIf=\"day\">{{ day.getDate() }}</span>\n </button>\n </div>\n </div>\n\n <div *ngIf=\"showTodayButton\" class=\"sefin-datepicker__calendar-footer\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__today-button\"\n (click)=\"goToToday()\"\n [disabled]=\"isTodayDisabled()\"\n >\n Hoy\n </button>\n </div>\n </div>\n</div>\n\n", styles: [".sefin-datepicker{position:relative;width:100%}.sefin-datepicker__wrapper{position:relative;display:flex;align-items:center;width:100%}.sefin-datepicker__input{width:100%;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield__input{cursor:pointer}.sefin-datepicker__actions{position:absolute;right:var(--sefin-spacing-sm);display:flex;align-items:center;gap:var(--sefin-spacing-xs);z-index:1;pointer-events:none}.sefin-datepicker__clear{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text-secondary);cursor:pointer;transition:all .2s ease-in-out;pointer-events:all}.sefin-datepicker__clear:hover{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-datepicker__clear:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__clear svg{width:16px;height:16px}.sefin-datepicker__calendar{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);padding:var(--sefin-spacing-md);min-width:300px;max-width:320px}.sefin-datepicker__calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sefin-spacing-md)}.sefin-datepicker__nav-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__nav-button:hover{background-color:var(--sefin-color-surface-hover)}.sefin-datepicker__nav-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__nav-button svg{width:16px;height:16px}.sefin-datepicker__month-year{display:flex;align-items:center;gap:var(--sefin-spacing-xs);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-semibold);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text)}.sefin-datepicker__month{text-transform:capitalize}.sefin-datepicker__year{color:var(--sefin-color-text-secondary)}.sefin-datepicker__calendar-body{margin-bottom:var(--sefin-spacing-sm)}.sefin-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs);margin-bottom:var(--sefin-spacing-xs)}.sefin-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-xs);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.sefin-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs)}.sefin-datepicker__day{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;position:relative}.sefin-datepicker__day:hover:not(.sefin-datepicker__day--disabled):not(.sefin-datepicker__day--empty){background-color:var(--sefin-color-surface-hover)}.sefin-datepicker__day--today{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary)}.sefin-datepicker__day--today:before{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:var(--sefin-color-primary);border-radius:50%}.sefin-datepicker__day--selected{background-color:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold)}.sefin-datepicker__day--selected:before{display:none}.sefin-datepicker__day--in-range{background-color:var(--sefin-color-primary-light);color:var(--sefin-color-primary)}.sefin-datepicker__day--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.sefin-datepicker__day--empty{cursor:default;pointer-events:none}.sefin-datepicker__day:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__calendar-footer{display:flex;align-items:center;justify-content:center;padding-top:var(--sefin-spacing-sm);border-top:1px solid var(--sefin-color-border)}.sefin-datepicker__today-button{padding:var(--sefin-spacing-xs) var(--sefin-spacing-md);background:transparent;border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-sm);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__today-button:hover:not(:disabled){background-color:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border-focus)}.sefin-datepicker__today-button:disabled{opacity:.5;cursor:not-allowed}.sefin-datepicker__today-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker--open .sefin-datepicker__input ::ng-deep .sefin-textfield__input{border-color:var(--sefin-color-border-focus)}\n"] }]
3653
+ args: [{ selector: 'sefin-datepicker', standalone: true, imports: [CommonModule, IconComponent, TextFieldComponent], template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-datepicker__wrapper\">\n <div\n (click)=\"onTextFieldClick($event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\"\n class=\"sefin-datepicker__input-wrapper\"\n >\n <sefin-textfield\n #textfieldRef\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [size]=\"size\"\n [readonly]=\"true\"\n [trailingIcon]=\"\n displayValue && showClearButton && !disabled ? 'x' : 'calendar'\n \"\n (focused)=\"onTextFieldFocus($event)\"\n (trailingIconClick)=\"onTrailingIconClick($event)\"\n class=\"sefin-datepicker__input\"\n ></sefin-textfield>\n </div>\n </div>\n\n <div\n *ngIf=\"isOpen\"\n #calendarRef\n class=\"sefin-datepicker__calendar\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <div class=\"sefin-datepicker__header\">\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav\"\n (click)=\"previousMonth($event)\"\n >\n <sefin-icon name=\"chevron-left\" size=\"sm\"></sefin-icon>\n </button>\n <button\n type=\"button\"\n class=\"sefin-datepicker__month-year-btn\"\n (click)=\"toggleViewMode($event)\"\n >\n <span *ngIf=\"viewMode === 'month'\"\n >{{ getMonthName() }} {{ getYear() }}</span\n >\n <span *ngIf=\"viewMode === 'year'\">{{ getYear() }}</span>\n </button>\n <button\n type=\"button\"\n class=\"sefin-datepicker__nav\"\n (click)=\"nextMonth($event)\"\n >\n <sefin-icon name=\"chevron-right\" size=\"sm\"></sefin-icon>\n </button>\n </div>\n\n <!-- Vista de Meses -->\n <div *ngIf=\"viewMode === 'month'\" class=\"sefin-datepicker__month-view\">\n <div class=\"sefin-datepicker__weekdays\">\n <div\n *ngFor=\"let day of getDayNames()\"\n class=\"sefin-datepicker__weekday\"\n >\n {{ day }}\n </div>\n </div>\n\n <div class=\"sefin-datepicker__days\">\n <button\n *ngFor=\"let day of getCalendarDays(); trackBy: trackByDate\"\n type=\"button\"\n class=\"sefin-datepicker__day\"\n [class.sefin-datepicker__day--today]=\"day && isToday(day)\"\n [class.sefin-datepicker__day--selected]=\"day && isSelected(day)\"\n [class.sefin-datepicker__day--in-range]=\"day && isInRange(day)\"\n [class.sefin-datepicker__day--disabled]=\"day && isDisabled(day)\"\n [class.sefin-datepicker__day--empty]=\"!day\"\n [disabled]=\"!day || (day && isDisabled(day))\"\n (mousedown)=\"day && !isDisabled(day) && onDayMouseDown(day, $event)\"\n (click)=\"day && !isDisabled(day) && selectDate(day, $event)\"\n >\n {{ day ? day.getDate() : \"\" }}\n </button>\n </div>\n </div>\n\n <!-- Vista de A\u00F1os -->\n <div *ngIf=\"viewMode === 'year'\" class=\"sefin-datepicker__year-view\">\n <div class=\"sefin-datepicker__years-grid\">\n <button\n *ngFor=\"let year of getYears()\"\n type=\"button\"\n class=\"sefin-datepicker__year\"\n [class.sefin-datepicker__year--current]=\"isCurrentYear(year)\"\n [class.sefin-datepicker__year--selected]=\"\n year === currentMonth.getFullYear()\n \"\n (click)=\"selectYear(year, $event)\"\n >\n {{ year }}\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"showTodayButton && viewMode === 'month'\"\n class=\"sefin-datepicker__footer\"\n >\n <button\n type=\"button\"\n class=\"sefin-datepicker__today\"\n (click)=\"goToToday()\"\n >\n Hoy\n </button>\n </div>\n </div>\n</div>\n", styles: [".sefin-datepicker{position:relative;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif)}.sefin-datepicker *{font-family:inherit}.sefin-datepicker__wrapper{position:relative;width:100%}.sefin-datepicker__input-wrapper{width:100%;cursor:pointer;position:relative}.sefin-datepicker__input{width:100%;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield{font-family:inherit;cursor:pointer}.sefin-datepicker__input ::ng-deep .sefin-textfield__input{cursor:pointer!important;font-family:inherit}.sefin-datepicker__input ::ng-deep .sefin-textfield__trailing-icon{cursor:pointer!important;pointer-events:auto}.sefin-datepicker__input ::ng-deep .sefin-textfield__wrapper{cursor:pointer}.sefin-datepicker__calendar{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;z-index:1000;background:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);padding:var(--sefin-spacing-md);min-width:300px;max-width:320px;animation:fadeIn .2s ease-in-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.sefin-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sefin-spacing-md);padding-bottom:var(--sefin-spacing-sm);border-bottom:1px solid var(--sefin-color-border)}.sefin-datepicker__nav{width:36px;height:36px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sefin-color-text);transition:all .2s ease-in-out}.sefin-datepicker__nav:hover:not(:disabled){background:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-datepicker__nav:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__nav:disabled{opacity:.4;cursor:not-allowed}.sefin-datepicker__month-year-btn{padding:var(--sefin-spacing-xs) var(--sefin-spacing-sm);background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-semibold);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);text-transform:capitalize;cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__month-year-btn:hover{background:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-datepicker__month-year-btn:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs);margin-bottom:var(--sefin-spacing-sm);padding-bottom:var(--sefin-spacing-xs)}.sefin-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:var(--sefin-font-size-xs);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.sefin-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sefin-spacing-xs)}.sefin-datepicker__day{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;position:relative}.sefin-datepicker__day:hover:not(.sefin-datepicker__day--disabled):not(.sefin-datepicker__day--empty){background:var(--sefin-color-surface-hover);cursor:pointer}.sefin-datepicker__day--today{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary)}.sefin-datepicker__day--today:before{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:var(--sefin-color-primary);border-radius:50%}.sefin-datepicker__day--selected{background:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold);z-index:1;cursor:pointer}.sefin-datepicker__day--selected:before{display:none}.sefin-datepicker__day--selected:hover{background:var(--sefin-color-primary-dark);cursor:pointer}.sefin-datepicker__day--in-range{background:var(--sefin-color-primary-light);color:var(--sefin-color-primary);border-radius:0;cursor:pointer}.sefin-datepicker__day--in-range:first-child{border-top-left-radius:var(--sefin-radius-sm);border-bottom-left-radius:var(--sefin-radius-sm)}.sefin-datepicker__day--in-range:last-child{border-top-right-radius:var(--sefin-radius-sm);border-bottom-right-radius:var(--sefin-radius-sm)}.sefin-datepicker__day--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.sefin-datepicker__day--empty{cursor:default;pointer-events:none}.sefin-datepicker__day:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__footer{display:flex;align-items:center;justify-content:center;margin-top:var(--sefin-spacing-md);padding-top:var(--sefin-spacing-md);border-top:1px solid var(--sefin-color-border)}.sefin-datepicker__today{padding:var(--sefin-spacing-xs) var(--sefin-spacing-md);background:transparent;border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .2s ease-in-out}.sefin-datepicker__today:hover:not(:disabled){background:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border-focus);color:var(--sefin-color-primary)}.sefin-datepicker__today:disabled{opacity:.5;cursor:not-allowed}.sefin-datepicker__today:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker__year-view{padding:var(--sefin-spacing-sm) 0}.sefin-datepicker__years-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sefin-spacing-xs);max-height:300px;overflow-y:auto}.sefin-datepicker__year{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);background:transparent;border:none;border-radius:var(--sefin-radius-sm);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;transition:all .15s ease-in-out;text-align:center}.sefin-datepicker__year:hover{background:var(--sefin-color-surface-hover)}.sefin-datepicker__year--current{font-weight:var(--sefin-font-weight-semibold);color:var(--sefin-color-primary);cursor:pointer}.sefin-datepicker__year--selected{background:var(--sefin-color-primary);color:var(--sefin-color-surface);font-weight:var(--sefin-font-weight-semibold);cursor:pointer}.sefin-datepicker__year--selected:hover{cursor:pointer}.sefin-datepicker__year:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-datepicker--open .sefin-datepicker__input ::ng-deep .sefin-textfield .sefin-textfield__border{border-color:var(--sefin-color-border-focus)}\n"] }]
3510
3654
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { containerRef: [{
3511
3655
  type: ViewChild,
3512
3656
  args: ['containerRef', { static: false }]
3513
- }], calendarRef: [{
3514
- type: ViewChild,
3515
- args: ['calendarRef', { static: false }]
3516
3657
  }], textfieldRef: [{
3517
3658
  type: ViewChild,
3518
3659
  args: ['textfieldRef', { static: false }]
3660
+ }], calendarRef: [{
3661
+ type: ViewChild,
3662
+ args: ['calendarRef', { static: false }]
3519
3663
  }], value: [{
3520
3664
  type: Input
3521
3665
  }], placeholder: [{
@@ -3524,8 +3668,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
3524
3668
  type: Input
3525
3669
  }], size: [{
3526
3670
  type: Input
3527
- }], class: [{
3528
- type: Input
3529
3671
  }], format: [{
3530
3672
  type: Input
3531
3673
  }], mode: [{
@@ -3538,8 +3680,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
3538
3680
  type: Input
3539
3681
  }], showClearButton: [{
3540
3682
  type: Input
3541
- }], locale: [{
3542
- type: Input
3543
3683
  }], firstDayOfWeek: [{
3544
3684
  type: Input
3545
3685
  }], valueChange: [{