tecnualng 21.1.2 → 21.1.5

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.
@@ -382,6 +382,8 @@ class TecnualDatepickerComponent {
382
382
  maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
383
383
  disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
384
384
  id = input(`tng-datepicker-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
385
+ locale = input((typeof navigator !== 'undefined' ? navigator.language : 'en-US'), ...(ngDevMode ? [{ debugName: "locale" }] : []));
386
+ firstDayOfWeek = input(null, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : [])); // 0 = Sunday, 1 = Monday, etc.
385
387
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
386
388
  currentViewDate = signal(new Date(), ...(ngDevMode ? [{ debugName: "currentViewDate" }] : [])); // The month we are looking at
387
389
  viewMode = signal('day', ...(ngDevMode ? [{ debugName: "viewMode" }] : []));
@@ -393,29 +395,79 @@ class TecnualDatepickerComponent {
393
395
  constructor(elementRef) {
394
396
  this.elementRef = elementRef;
395
397
  }
398
+ getEffectiveFirstDayOfWeek() {
399
+ const definedDay = this.firstDayOfWeek();
400
+ if (definedDay !== null)
401
+ return definedDay;
402
+ // Try to determine from locale
403
+ try {
404
+ // @ts-ignore: weekInfo is a newer API, might need a shim or ignore
405
+ const weekInfo = new Intl.Locale(this.locale()).weekInfo;
406
+ if (weekInfo && typeof weekInfo.firstDay === 'number') {
407
+ return weekInfo.firstDay;
408
+ }
409
+ }
410
+ catch (e) {
411
+ // Fallback
412
+ }
413
+ // Default fallback: US=0 (Sun), others usually 1 (Mon). Simplified logic:
414
+ const l = this.locale().toLowerCase();
415
+ if (l.includes('us') || l.includes('en-ca') || l.includes('zh'))
416
+ return 0;
417
+ return 1;
418
+ }
396
419
  // Calendar Logic
397
- daysOfWeek = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
398
- monthNames = [
399
- 'January', 'February', 'March', 'April', 'May', 'June',
400
- 'July', 'August', 'September', 'October', 'November', 'December'
401
- ];
420
+ daysOfWeek = computed(() => {
421
+ const firstDay = this.getEffectiveFirstDayOfWeek();
422
+ const days = [];
423
+ // Create a date that is definitely a valid day index to start iterating.
424
+ // 2024-01-07 is a Sunday.
425
+ // We want to generate names: Sun, Mon, etc.
426
+ // Let's iterate 7 days starting from a known Sunday + offset
427
+ const baseDate = new Date(2024, 0, 7); // Jan 7, 2024 is Sunday
428
+ const formatter = new Intl.DateTimeFormat(this.locale(), { weekday: 'short' });
429
+ for (let i = 0; i < 7; i++) {
430
+ const d = new Date(baseDate);
431
+ d.setDate(baseDate.getDate() + (firstDay + i));
432
+ // Remove dot usually found in some locales (e.g. es-ES "lun.") if desired or keep it.
433
+ // Let's keep it clean
434
+ days.push(formatter.format(d).replace('.', ''));
435
+ }
436
+ return days;
437
+ }, ...(ngDevMode ? [{ debugName: "daysOfWeek" }] : []));
438
+ monthNames = computed(() => {
439
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long' });
440
+ const months = [];
441
+ for (let i = 0; i < 12; i++) {
442
+ const d = new Date(2024, i, 1);
443
+ months.push(formatter.format(d));
444
+ }
445
+ return months;
446
+ }, ...(ngDevMode ? [{ debugName: "monthNames" }] : []));
402
447
  calendarDays = computed(() => {
403
448
  const year = this.currentViewDate().getFullYear();
404
449
  const month = this.currentViewDate().getMonth();
450
+ const firstDayIndex = this.getEffectiveFirstDayOfWeek();
405
451
  const firstDayOfMonth = new Date(year, month, 1);
406
452
  const lastDayOfMonth = new Date(year, month + 1, 0);
407
453
  const days = [];
408
454
  // Padding days from previous month
409
- const startDay = firstDayOfMonth.getDay();
410
- for (let i = startDay - 1; i >= 0; i--) {
455
+ // Calculate how many days to fallback:
456
+ // current day of week (0-6) - firstDayIndex
457
+ // if result < 0, add 7
458
+ let startDayOfWeek = firstDayOfMonth.getDay();
459
+ let daysToBacktrack = startDayOfWeek - firstDayIndex;
460
+ if (daysToBacktrack < 0)
461
+ daysToBacktrack += 7;
462
+ for (let i = daysToBacktrack - 1; i >= 0; i--) {
411
463
  days.push(new Date(year, month, -i));
412
464
  }
413
465
  // Days of current month
414
466
  for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
415
467
  days.push(new Date(year, month, i));
416
468
  }
417
- // Padding days for next month (to fill 6 rows usually, or just enough to finish week)
418
- const remaining = 42 - days.length; // 6 rows * 7 days
469
+ // Padding days for next month to fill complete rows (usually 6 rows total 42 days)
470
+ const remaining = 42 - days.length;
419
471
  for (let i = 1; i <= remaining; i++) {
420
472
  days.push(new Date(year, month + 1, i));
421
473
  }
@@ -432,15 +484,16 @@ class TecnualDatepickerComponent {
432
484
  return years;
433
485
  }, ...(ngDevMode ? [{ debugName: "yearsList" }] : []));
434
486
  get formattedValue() {
487
+ const locale = this.locale();
435
488
  if (this.mode() === 'single') {
436
- return this.singleValue ? this.singleValue.toLocaleDateString() : '';
489
+ return this.singleValue ? this.singleValue.toLocaleDateString(locale) : '';
437
490
  }
438
491
  else {
439
492
  if (this.rangeValue.start && this.rangeValue.end) {
440
- return `${this.rangeValue.start.toLocaleDateString()} - ${this.rangeValue.end.toLocaleDateString()}`;
493
+ return `${this.rangeValue.start.toLocaleDateString(locale)} - ${this.rangeValue.end.toLocaleDateString(locale)}`;
441
494
  }
442
495
  else if (this.rangeValue.start) {
443
- return `${this.rangeValue.start.toLocaleDateString()} - ...`;
496
+ return `${this.rangeValue.start.toLocaleDateString(locale)} - ...`;
444
497
  }
445
498
  return '';
446
499
  }
@@ -448,7 +501,7 @@ class TecnualDatepickerComponent {
448
501
  get headerLabel() {
449
502
  const d = this.currentViewDate();
450
503
  if (this.viewMode() === 'day') {
451
- return d.toLocaleString('default', { month: 'long', year: 'numeric' });
504
+ return d.toLocaleString(this.locale(), { month: 'long', year: 'numeric' });
452
505
  }
453
506
  else if (this.viewMode() === 'month') {
454
507
  return d.getFullYear().toString();
@@ -459,9 +512,17 @@ class TecnualDatepickerComponent {
459
512
  return `${years[0]} - ${years[years.length - 1]}`;
460
513
  }
461
514
  }
462
- toggleCalendar() {
515
+ toggleCalendar(event) {
463
516
  if (this.disabled())
464
517
  return;
518
+ // If clicking the input itself, ensure we don't close if already open
519
+ if (event && event.target.tagName === 'INPUT') {
520
+ if (!this.isOpen()) {
521
+ this.isOpen.set(true);
522
+ this.viewMode.set('day');
523
+ }
524
+ return;
525
+ }
465
526
  if (!this.isOpen()) {
466
527
  // Reset to day view when opening
467
528
  this.viewMode.set('day');
@@ -516,19 +577,22 @@ class TecnualDatepickerComponent {
516
577
  this.currentViewDate.set(new Date(year, d.getMonth(), 1));
517
578
  this.viewMode.set('month');
518
579
  }
519
- selectDate(date) {
580
+ selectDate(date, closeCalendar = true) {
520
581
  if (this.isDisabled(date))
521
582
  return;
522
583
  if (this.mode() === 'single') {
523
584
  this.singleValue = date;
585
+ this.currentViewDate.set(new Date(date)); // Sync view
524
586
  this.onChange(date);
525
- this.isOpen.set(false);
587
+ if (closeCalendar)
588
+ this.isOpen.set(false);
526
589
  }
527
590
  else {
528
591
  // Range logic
529
592
  if (!this.rangeValue.start || (this.rangeValue.start && this.rangeValue.end)) {
530
593
  // Start new range
531
594
  this.rangeValue = { start: date, end: null };
595
+ this.currentViewDate.set(new Date(date)); // Sync view
532
596
  }
533
597
  else {
534
598
  // Complete range
@@ -539,10 +603,66 @@ class TecnualDatepickerComponent {
539
603
  this.rangeValue = { ...this.rangeValue, end: date };
540
604
  }
541
605
  this.onChange(this.rangeValue);
542
- this.isOpen.set(false);
606
+ if (closeCalendar)
607
+ this.isOpen.set(false);
543
608
  }
544
609
  }
545
610
  }
611
+ parseDate(value) {
612
+ if (!value)
613
+ return null;
614
+ const locale = this.locale();
615
+ // Use Intl to determine the order of parts
616
+ const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(2000, 10, 25)); // Nov 25, 2000
617
+ // Parts will contain type: 'day', 'month', 'year', 'literal'
618
+ const formatOrder = [];
619
+ parts.forEach(p => {
620
+ if (p.type === 'day' || p.type === 'month' || p.type === 'year') {
621
+ formatOrder.push(p.type);
622
+ }
623
+ });
624
+ // Split input by non-digit characters
625
+ const dateParts = value.split(/\D+/).filter(part => part.trim() !== '').map(p => parseInt(p, 10));
626
+ if (dateParts.length !== 3) {
627
+ // Fallback to standard parse if structure doesn't match
628
+ const d = new Date(value);
629
+ return isNaN(d.getTime()) ? null : d;
630
+ }
631
+ let day;
632
+ let month;
633
+ let year;
634
+ // Map input parts to Day/Month/Year based on locale order
635
+ for (let i = 0; i < 3; i++) {
636
+ const type = formatOrder[i];
637
+ const val = dateParts[i];
638
+ if (type === 'day')
639
+ day = val;
640
+ if (type === 'month')
641
+ month = val - 1; // JS months are 0-indexed
642
+ if (type === 'year')
643
+ year = val;
644
+ }
645
+ if (day === undefined || month === undefined || year === undefined)
646
+ return null;
647
+ // Validate year length (handle 2-digit years if needed, but let's stick to 4 for now or simple logic)
648
+ if (year < 100)
649
+ year += 2000; // Very basic 2-digit handling
650
+ const d = new Date(year, month, day);
651
+ if (d.getFullYear() === year && d.getMonth() === month && d.getDate() === day) {
652
+ return d;
653
+ }
654
+ return null;
655
+ }
656
+ onManualInput(event) {
657
+ const value = event.target.value;
658
+ if (!value)
659
+ return;
660
+ // Try localized parse first
661
+ let date = this.parseDate(value);
662
+ if (date) {
663
+ this.selectDate(date, false);
664
+ }
665
+ }
546
666
  // Helper checks
547
667
  isSelected(date) {
548
668
  if (this.mode() === 'single') {
@@ -616,13 +736,13 @@ class TecnualDatepickerComponent {
616
736
  }
617
737
  }
618
738
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualDatepickerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
619
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TecnualDatepickerComponent, isStandalone: true, selector: "tng-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", 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 }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
739
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TecnualDatepickerComponent, isStandalone: true, selector: "tng-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", 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 }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
620
740
  {
621
741
  provide: NG_VALUE_ACCESSOR,
622
742
  useExisting: forwardRef(() => TecnualDatepickerComponent),
623
743
  multi: true
624
744
  }
625
- ], ngImport: i0, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <i class=\"fa-solid fa-calendar tng-icon\"></i>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prev($event)\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n <button type=\"button\" class=\"header-label-btn\" (click)=\"onHeaderClick()\">\n {{ headerLabel }}\n </button>\n <button type=\"button\" class=\"nav-btn\" (click)=\"next($event)\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n @switch (viewMode()) {\n @case ('day') {\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n }\n @case ('month') {\n <div class=\"tng-month-grid\">\n @for (month of monthNames; track $index) {\n <div \n class=\"month-cell\"\n [class.current]=\"currentViewDate().getMonth() === $index\"\n (click)=\"selectMonth($index)\"\n >\n {{ month.substring(0, 3) }}\n </div>\n }\n </div>\n }\n @case ('year') {\n <div class=\"tng-year-grid\">\n @for (year of yearsList(); track year) {\n <div \n class=\"year-cell\"\n [class.current]=\"currentViewDate().getFullYear() === year\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </div>\n }\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-input-trigger{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px;transition:max-width .1s cubic-bezier(.4,0,.2,1)}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center;z-index:1;padding-bottom:5px}.tng-icon{color:var(--tng-text-secondary, #666);font-size:16px;margin-left:8px;z-index:1;padding-bottom:5px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:320px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee);color:var(--tng-text, #333)}@media(max-width:768px){.tng-calendar-popup{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:90vw;max-width:350px;margin-top:0;box-shadow:0 10px 40px #0000004d,0 0 0 100vmax #0006;z-index:10000;animation:fadeInMobile .3s cubic-bezier(.16,1,.3,1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInMobile{0%{opacity:0;transform:translate(-50%,-40%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .header-label-btn{background:none;border:none;font-weight:600;font-size:16px;color:var(--tng-text, #333);text-transform:capitalize;cursor:pointer;padding:4px 8px;border-radius:var(--tng-border-radius, 4px);transition:background-color .2s ease}.tng-calendar-header .header-label-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:8px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666);transition:background-color .2s ease}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn i{font-size:14px}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:var(--tng-text-secondary, #ccc);opacity:.5}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 85%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}.tng-month-grid,.tng-year-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:8px 0}.month-cell,.year-cell{height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:var(--tng-border-radius, 4px);transition:all .2s ease;color:var(--tng-text, #333)}.month-cell:hover,.year-cell:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.month-cell.current,.year-cell.current{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
745
+ ], ngImport: i0, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar($event)\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <input\n type=\"text\"\n class=\"tng-input-display\"\n [value]=\"formattedValue || (isOpen() ? '' : '')\"\n [placeholder]=\"isOpen() ? placeholder() : ''\"\n [disabled]=\"disabled()\"\n (input)=\"onManualInput($event)\"\n (click)=\"toggleCalendar($event)\"\n />\n <i class=\"fa-solid fa-calendar tng-icon\"></i>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prev($event)\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n <button type=\"button\" class=\"header-label-btn\" (click)=\"onHeaderClick()\">\n {{ headerLabel }}\n </button>\n <button type=\"button\" class=\"nav-btn\" (click)=\"next($event)\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n @switch (viewMode()) {\n @case ('day') {\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek(); track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n }\n @case ('month') {\n <div class=\"tng-month-grid\">\n @for (month of monthNames(); track $index) {\n <div \n class=\"month-cell\"\n [class.current]=\"currentViewDate().getMonth() === $index\"\n (click)=\"selectMonth($index)\"\n >\n {{ month.substring(0, 3) }}\n </div>\n }\n </div>\n }\n @case ('year') {\n <div class=\"tng-year-grid\">\n @for (year of yearsList(); track year) {\n <div \n class=\"year-cell\"\n [class.current]=\"currentViewDate().getFullYear() === year\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </div>\n }\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-input-trigger{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px;transition:max-width .1s cubic-bezier(.4,0,.2,1)}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);height:100%;border:none;background:transparent;outline:none;padding:0 0 5px;margin:0;width:100%;font-family:inherit;pointer-events:auto;z-index:1}.tng-icon{color:var(--tng-text-secondary, #666);font-size:16px;margin-left:8px;z-index:1;padding-bottom:5px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:320px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee);color:var(--tng-text, #333)}@media(max-width:768px){.tng-calendar-popup{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:90vw;max-width:350px;margin-top:0;box-shadow:0 10px 40px #0000004d,0 0 0 100vmax #0006;z-index:10000;animation:fadeInMobile .3s cubic-bezier(.16,1,.3,1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInMobile{0%{opacity:0;transform:translate(-50%,-40%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .header-label-btn{background:none;border:none;font-weight:600;font-size:16px;color:var(--tng-text, #333);text-transform:capitalize;cursor:pointer;padding:4px 8px;border-radius:var(--tng-border-radius, 4px);transition:background-color .2s ease}.tng-calendar-header .header-label-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:8px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666);transition:background-color .2s ease}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn i{font-size:14px}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:var(--tng-text-secondary, #ccc);opacity:.5}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}.tng-month-grid,.tng-year-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:8px 0}.month-cell,.year-cell{height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:var(--tng-border-radius, 4px);transition:all .2s ease;color:var(--tng-text, #333)}.month-cell:hover,.year-cell:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.month-cell.current,.year-cell.current{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
626
746
  }
627
747
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualDatepickerComponent, decorators: [{
628
748
  type: Component,
@@ -632,8 +752,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
632
752
  useExisting: forwardRef(() => TecnualDatepickerComponent),
633
753
  multi: true
634
754
  }
635
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <i class=\"fa-solid fa-calendar tng-icon\"></i>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prev($event)\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n <button type=\"button\" class=\"header-label-btn\" (click)=\"onHeaderClick()\">\n {{ headerLabel }}\n </button>\n <button type=\"button\" class=\"nav-btn\" (click)=\"next($event)\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n @switch (viewMode()) {\n @case ('day') {\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n }\n @case ('month') {\n <div class=\"tng-month-grid\">\n @for (month of monthNames; track $index) {\n <div \n class=\"month-cell\"\n [class.current]=\"currentViewDate().getMonth() === $index\"\n (click)=\"selectMonth($index)\"\n >\n {{ month.substring(0, 3) }}\n </div>\n }\n </div>\n }\n @case ('year') {\n <div class=\"tng-year-grid\">\n @for (year of yearsList(); track year) {\n <div \n class=\"year-cell\"\n [class.current]=\"currentViewDate().getFullYear() === year\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </div>\n }\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-input-trigger{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px;transition:max-width .1s cubic-bezier(.4,0,.2,1)}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center;z-index:1;padding-bottom:5px}.tng-icon{color:var(--tng-text-secondary, #666);font-size:16px;margin-left:8px;z-index:1;padding-bottom:5px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:320px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee);color:var(--tng-text, #333)}@media(max-width:768px){.tng-calendar-popup{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:90vw;max-width:350px;margin-top:0;box-shadow:0 10px 40px #0000004d,0 0 0 100vmax #0006;z-index:10000;animation:fadeInMobile .3s cubic-bezier(.16,1,.3,1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInMobile{0%{opacity:0;transform:translate(-50%,-40%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .header-label-btn{background:none;border:none;font-weight:600;font-size:16px;color:var(--tng-text, #333);text-transform:capitalize;cursor:pointer;padding:4px 8px;border-radius:var(--tng-border-radius, 4px);transition:background-color .2s ease}.tng-calendar-header .header-label-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:8px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666);transition:background-color .2s ease}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn i{font-size:14px}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:var(--tng-text-secondary, #ccc);opacity:.5}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 85%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}.tng-month-grid,.tng-year-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:8px 0}.month-cell,.year-cell{height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:var(--tng-border-radius, 4px);transition:all .2s ease;color:var(--tng-text, #333)}.month-cell:hover,.year-cell:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.month-cell.current,.year-cell.current{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}\n"] }]
636
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], onClickOutside: [{
755
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar($event)\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <input\n type=\"text\"\n class=\"tng-input-display\"\n [value]=\"formattedValue || (isOpen() ? '' : '')\"\n [placeholder]=\"isOpen() ? placeholder() : ''\"\n [disabled]=\"disabled()\"\n (input)=\"onManualInput($event)\"\n (click)=\"toggleCalendar($event)\"\n />\n <i class=\"fa-solid fa-calendar tng-icon\"></i>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prev($event)\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n <button type=\"button\" class=\"header-label-btn\" (click)=\"onHeaderClick()\">\n {{ headerLabel }}\n </button>\n <button type=\"button\" class=\"nav-btn\" (click)=\"next($event)\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n @switch (viewMode()) {\n @case ('day') {\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek(); track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n }\n @case ('month') {\n <div class=\"tng-month-grid\">\n @for (month of monthNames(); track $index) {\n <div \n class=\"month-cell\"\n [class.current]=\"currentViewDate().getMonth() === $index\"\n (click)=\"selectMonth($index)\"\n >\n {{ month.substring(0, 3) }}\n </div>\n }\n </div>\n }\n @case ('year') {\n <div class=\"tng-year-grid\">\n @for (year of yearsList(); track year) {\n <div \n class=\"year-cell\"\n [class.current]=\"currentViewDate().getFullYear() === year\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </div>\n }\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-input-trigger{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px;transition:max-width .1s cubic-bezier(.4,0,.2,1)}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);height:100%;border:none;background:transparent;outline:none;padding:0 0 5px;margin:0;width:100%;font-family:inherit;pointer-events:auto;z-index:1}.tng-icon{color:var(--tng-text-secondary, #666);font-size:16px;margin-left:8px;z-index:1;padding-bottom:5px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:320px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee);color:var(--tng-text, #333)}@media(max-width:768px){.tng-calendar-popup{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:90vw;max-width:350px;margin-top:0;box-shadow:0 10px 40px #0000004d,0 0 0 100vmax #0006;z-index:10000;animation:fadeInMobile .3s cubic-bezier(.16,1,.3,1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInMobile{0%{opacity:0;transform:translate(-50%,-40%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .header-label-btn{background:none;border:none;font-weight:600;font-size:16px;color:var(--tng-text, #333);text-transform:capitalize;cursor:pointer;padding:4px 8px;border-radius:var(--tng-border-radius, 4px);transition:background-color .2s ease}.tng-calendar-header .header-label-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:8px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666);transition:background-color .2s ease}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.tng-calendar-header .nav-btn i{font-size:14px}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:var(--tng-text-secondary, #ccc);opacity:.5}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),var(--tng-surface));z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}.tng-month-grid,.tng-year-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:8px 0}.month-cell,.year-cell{height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:var(--tng-border-radius, 4px);transition:all .2s ease;color:var(--tng-text, #333)}.month-cell:hover,.year-cell:hover{background-color:var(--tng-background, #f5f5f5);color:var(--tng-primary, #6200ee)}.month-cell.current,.year-cell.current{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}\n"] }]
756
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], onClickOutside: [{
637
757
  type: HostListener,
638
758
  args: ['document:click', ['$event']]
639
759
  }] } });