100 lines
3.2 KiB
Plaintext
100 lines
3.2 KiB
Plaintext
<div class="custom-date-trigger-box @(isCalendarOpen ? "focused" : "")" @onclick="ToggleCalendar">
|
|
<span>@Value.ToString("yyyy / MM / dd")</span>
|
|
<i class="bi bi-calendar3 calendar-icon"></i>
|
|
</div>
|
|
|
|
@if (isCalendarOpen)
|
|
{
|
|
<div class="brand-calendar-popup">
|
|
<div class="calendar-nav-header">
|
|
<button type="button" class="btn-cal-nav" @onclick="NavigateMonthPrevious"><</button>
|
|
<span class="calendar-current-month">@currentMonthDisplay.ToString("MMMM yyyy")</span>
|
|
<button type="button" class="btn-cal-nav" @onclick="NavigateMonthNext">></button>
|
|
</div>
|
|
|
|
<div class="calendar-days-grid-header">
|
|
<div>Su</div><div>Mo</div><div>Tu</div><div>We</div><div>Th</div><div>Fr</div><div>Sa</div>
|
|
</div>
|
|
|
|
<div class="calendar-days-matrix">
|
|
@foreach (var day in paddingDays)
|
|
{
|
|
<div class="calendar-day-blank"></div>
|
|
}
|
|
@foreach (var day in currentMonthDays)
|
|
{
|
|
var loopDay = day;
|
|
<button type="button"
|
|
class="calendar-day-btn @(IsToday(loopDay) ? "is-today" : "") @(IsSelected(loopDay) ? "is-selected" : "")"
|
|
@onclick="() => SelectDate(loopDay)">
|
|
@loopDay.Day
|
|
</button>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@code {
|
|
[Parameter]
|
|
public DateTime Value { get; set; } = DateTime.Today;
|
|
|
|
[Parameter]
|
|
public EventCallback<DateTime> ValueChanged { get; set; }
|
|
|
|
private bool isCalendarOpen = false;
|
|
private DateTime currentMonthDisplay;
|
|
private List<DateTime> paddingDays = new();
|
|
private List<DateTime> currentMonthDays = new();
|
|
|
|
protected override void OnParametersSet()
|
|
{
|
|
if (currentMonthDisplay == DateTime.MinValue)
|
|
{
|
|
currentMonthDisplay = new DateTime(Value.Year, Value.Month, 1);
|
|
GenerateCalendarMatrix();
|
|
}
|
|
}
|
|
|
|
private void ToggleCalendar() => isCalendarOpen = !isCalendarOpen;
|
|
|
|
private async Task SelectDate(DateTime date)
|
|
{
|
|
Value = date;
|
|
isCalendarOpen = false;
|
|
await ValueChanged.InvokeAsync(Value);
|
|
}
|
|
|
|
private void NavigateMonthPrevious()
|
|
{
|
|
currentMonthDisplay = currentMonthDisplay.AddMonths(-1);
|
|
GenerateCalendarMatrix();
|
|
}
|
|
|
|
private void NavigateMonthNext()
|
|
{
|
|
currentMonthDisplay = currentMonthDisplay.AddMonths(1);
|
|
GenerateCalendarMatrix();
|
|
}
|
|
|
|
private void GenerateCalendarMatrix()
|
|
{
|
|
currentMonthDays.Clear();
|
|
paddingDays.Clear();
|
|
|
|
int daysInMonth = DateTime.DaysInMonth(currentMonthDisplay.Year, currentMonthDisplay.Month);
|
|
DayOfWeek firstDayOfWeek = currentMonthDisplay.DayOfWeek;
|
|
|
|
for (int i = 0; i < (int)firstDayOfWeek; i++)
|
|
{
|
|
paddingDays.Add(DateTime.MinValue);
|
|
}
|
|
|
|
for (int day = 1; day <= daysInMonth; day++)
|
|
{
|
|
currentMonthDays.Add(new DateTime(currentMonthDisplay.Year, currentMonthDisplay.Month, day));
|
|
}
|
|
}
|
|
|
|
private bool IsToday(DateTime date) => date.Date == DateTime.Today;
|
|
private bool IsSelected(DateTime date) => date.Date == Value.Date;
|
|
} |