Description:
When using [min]
on <ion-datetime>
, dates before the minimum are visually removed from the calendar UI, making it clear to the user that those dates are not available. However, when using [isDateEnabled]
to disable dates (including past dates), the calendar still displays those dates—they are just unselectable. This leads to inconsistent user experience: dates that should be unavailable are still visible, but cannot be selected.
Steps to reproduce:
- Use
<ion-datetime [min]="today">
and observe that past dates are not shown in the calendar. - Remove
[min]
and use only[isDateEnabled]="isDateEnabled"
to block past dates.
Note: If you use[min]
together with[isDateEnabled]
, there will be a conflict and the calendar may behave unexpectedly. - Notice that past dates are still visible, but cannot be selected.
Expected behavior:
Dates disabled by [isDateEnabled]
should be visually removed from the calendar UI, just like dates blocked by [min]
.
Actual behavior:
Dates disabled by [isDateEnabled]
are still visible in the calendar, but are unselectable.
Why this matters:
- The user experience is inconsistent and confusing.
- Using only
[isDateEnabled]
is necessary for complex logic (e.g., blocking ranges), but the UI is less clear than with[min]
.
Environment:
- Ionic version: 8.x
- Angular 19.x
- Platform: Android/iOS/Web
Sample code:
<ion-datetime
id="datetimeStart"
formControlName="start_date"
display-format="DD/MM/YYYY"
required
locale="pt-BR"
presentation="date"
class="custom-datetime"
[isDateEnabled]="isDateEnabled.bind(this)"
></ion-datetime>
isDateEnabled(dateIsoString: string): boolean {
const weeks = this.treinoForm.get('duration_weeks')?.value;
if (!weeks) return true;
const startDate = new Date(dateIsoString);
const today = new Date(this.today);
// Não permitir datas anteriores a hoje (Hack to replace [min])
if (startDate < today) return false;
const endDate = new Date(startDate);
endDate.setDate(endDate.getDate() + weeks * 7 - 1);
for (const period of this.blockedTrainingPeriods) {
const blockedStart = new Date(period.startDate);
const blockedEnd = new Date(period.endDate);
if (startDate <= blockedEnd && endDate >= blockedStart) {
return false;
}
}
return true;
}