Enhanced Date Picker - Copy this Angular, Tailwind Component to your project
Refactoriza el siguiente codigo import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { CalendarView } from './calendar view'; import { Calendar } from './calendar'; @Component({ selector: 'app date picker', templateUrl: './date picker.component.html', styleUrls: ['./date picker.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DatePickerComponent), multi: true } ] }) export class DatePickerComponent implements OnInit, ControlValueAccessor { @Input() placeholder = 'Select date'; @Input() format = 'dd/MM/yyyy'; @Output() dateChange = new EventEmitter<Date>(); selectedDate: Date | null = null; isOpen = false; calendarView: CalendarView = CalendarView.Days; calendar: Calendar; private onChange: (value: Date | null) => void = () => {}; private onTouched: () => void = () => {}; constructor() { this.calendar = new Calendar(); } ngOnInit(): void { this.initializeCalendar(); } private initializeCalendar(): void { if (this.selectedDate) { this.calendar.setDate(this.selectedDate); } else { this.calendar.setDate(new Date()); } } toggleCalendar(): void { this.isOpen = !this.isOpen; if (this.isOpen) { this.onTouched(); } } selectDate(date: Date): void { this.selectedDate = date; this.calendar.setDate(date); this.isOpen = false; this.onChange(date); this.dateChange.emit(date); } changeView(view: CalendarView): void { this.calendarView = view; } changeMonth(delta: number): void { this.calendar.changeMonth(delta); } changeYear(delta: number): void { this.calendar.changeYear(delta); } isSelected(date: Date): boolean { return this.selectedDate?.getTime() === date.getTime(); } // ControlValueAccessor methods writeValue(value: Date): void { this.selectedDate = value; this.initializeCalendar(); } registerOnChange(fn: (value: Date | null) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { // Implement disabled state logic if needed } // Helper methods for template get formattedDate(): string { return this.selectedDate ? this.formatDate(this.selectedDate) : ''; } get currentMonthYear(): string { return this.calendar.getCurrentMonthYear(); } get weekDays(): string[] { return this.calendar.getWeekDays(); } get calendarDays(): (Date | null)[] { return this.calendar.getCalendarDays(); } get years(): number[] { return this.calendar.getYears(); } private formatDate(date: Date): string { // Implement date formatting logic based on the format input // For simplicity, we'll use a basic implementation here const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear(); return `${day}/${month}/${year}`; } } otro archivo es este export class Calendar { private currentDate: Date; constructor() { this.currentDate = new Date(); } setDate(date: Date): void { this.currentDate = new Date(date); } changeMonth(delta: number): void { this.currentDate.setMonth(this.currentDate.getMonth() + delta); } changeYear(delta: number): void { this.currentDate.setFullYear(this.currentDate.getFullYear() + delta); } getCurrentMonthYear(): string { return this.currentDate.toLocaleString('default', { month: 'long', year: 'numeric' }); } getWeekDays(): string[] { return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; } getCalendarDays(): (Date | null)[] { const year = this.currentDate.getFullYear(); const month = this.currentDate.getMonth(); const firstDay = new Date(year, month, 1); const lastDay = new Date(year, month + 1, 0); const daysInMonth = lastDay.getDate(); const startingDay = firstDay.getDay(); const calendarDays: (Date | null)[] = []; for (let i = 0; i < startingDay; i++) { calendarDays.push(null); } for (let i = 1; i <= daysInMonth; i++) { calendarDays.push(new Date(year, month, i)); } while (calendarDays.length % 7 !== 0) { calendarDays.push(null); } return calendarDays; } getYears(): number[] { const currentYear = this.currentDate.getFullYear(); return Array.from({ length: 21 }, (_, i) => currentYear 10 + i); } } y el html <div class="date picker"> <input type="text" [placeholder]="placeholder" [value]="formattedDate" (click)="toggleCalendar()" readonly /> <div *ngIf="isOpen" class="calendar"> <div class="calendar header"> <button (click)="changeMonth( 1)"><</button> <span (click)="changeView(CalendarView.Months)">{{ currentMonthYear }}</span> <button (click)="changeMonth(1)">></button> </div> <div [ngSwitch]="calendarView"> <div *ngSwitchCase="CalendarView.Days" class="calendar days"> <div class="weekdays"> <span *ngFor="let day of weekDays">{{ day }}</span> </div> <div class="days"> <button *ngFor="let day of calendarDays" [class.selected]="isSelected(day)" [disabled]="!day" (click)="day && selectDate(day)" > {{ day?.getDate() }} </button> </div> </div> <div *ngSwitchCase="CalendarView.Months" class="calendar months"> <button *ngFor="let month of ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']" (click)="calendar.setDate(new Date(calendar.currentDate.getFullYear(), $index, 1)); changeView(CalendarView.Days)" > {{ month }} </button> </div> <div *ngSwitchCase="CalendarView.Years" class="calendar years"> <button *ngFor="let year of years" (click)="calendar.setDate(new Date(year, calendar.currentDate.getMonth(), 1)); changeView(CalendarView.Months)" > {{ year }} </button> </div> </div> </div> </div>
