Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
bf82d2c
Refactor FluentCalendar components to support generic TValue type for…
dvoituron Sep 15, 2025
54276fc
Refactoring CalendarTValue convert methods
dvoituron Sep 19, 2025
afb9ad9
Refacroring to extension methods
dvoituron Sep 19, 2025
7a3257a
Refactored `FluentCalendar.razor.cs` to use generic type `TValue` for…
dvoituron Sep 19, 2025
cd81cfc
Converted `PickerDay`, `PickerMonth`, and `PickerYear` to nullable ty…
dvoituron Sep 19, 2025
a122b4e
Refactor calendar components for nullable date handling
dvoituron Sep 19, 2025
14670be
Fix Unit Tests
dvoituron Sep 19, 2025
74a44e6
Refactoring
dvoituron Sep 22, 2025
482d831
Refactoring
dvoituron Sep 22, 2025
948165c
Remove "where TValue : struct, IComparable"
dvoituron Sep 22, 2025
d8a5045
Update example
dvoituron Sep 22, 2025
b0b7480
Refactoring
dvoituron Sep 22, 2025
e3da2c8
Refactoring
dvoituron Sep 22, 2025
3a555f7
Refactoring
dvoituron Sep 22, 2025
1ffebf6
Refactoring
dvoituron Sep 23, 2025
7145c26
Refactoring
dvoituron Sep 23, 2025
127ec79
Refactoring
dvoituron Sep 23, 2025
687f81b
Refactoring
dvoituron Sep 23, 2025
2b906d5
refactoring and add CalendarTypes example
dvoituron Sep 23, 2025
1b48006
Refactoring
dvoituron Sep 23, 2025
4db5db8
Refactoring
dvoituron Sep 23, 2025
c7bbdac
Refactoring
dvoituron Sep 23, 2025
6e8aca3
Fix Unit Tests
dvoituron Sep 23, 2025
0a91bd6
add comments
dvoituron Sep 23, 2025
73caccd
Rename IsNull to IsNullOrDefault and update usage
dvoituron Sep 27, 2025
7d7ceaf
Add Unit Tests
dvoituron Sep 27, 2025
622b2fa
Refactoring
dvoituron Sep 27, 2025
61929f9
Fix some Unit Tests
dvoituron Sep 27, 2025
f85a0f2
Fix Unit Tests
dvoituron Sep 27, 2025
78cf26d
Update Unit Tests
dvoituron Sep 27, 2025
559d4f0
Update parsing logic to handle invalid date inputs and adjust validat…
dvoituron Sep 28, 2025
698b7fd
Update Demo
dvoituron Sep 28, 2025
1abe8e8
Merge from dev-v5
dvoituron Sep 30, 2025
130490d
Update doc
dvoituron Sep 30, 2025
4fcfdca
Add TValue Unit Tests
dvoituron Sep 30, 2025
3d43b04
Add Unit Tests
dvoituron Sep 30, 2025
80e3529
Merge branch 'dev-v5' into users/dvoituron/dev-v5/poc-calendar-generic
vnbaaij Oct 1, 2025
6599d03
Merge branch 'dev-v5' into users/dvoituron/dev-v5/poc-calendar-generic
dvoituron Oct 1, 2025
8835627
Merge branch 'dev-v5' into users/dvoituron/dev-v5/poc-calendar-generic
dvoituron Oct 2, 2025
967280f
Update PR comments
dvoituron Oct 2, 2025
f25dc87
Fix PR comments
dvoituron Oct 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ dotnet_diagnostic.IDE0029.severity = warning
dotnet_diagnostic.IDE0030.severity = warning

# IDE0031: Use null propagation
dotnet_diagnostic.IDE0031.severity = warning
dotnet_diagnostic.IDE0031.severity = none

# IDE0035: Remove unreachable code
dotnet_diagnostic.IDE0035.severity = warning
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@using System.Globalization
@using System.Globalization

<FluentStack Wrap="true" HorizontalGap="64px">

Expand Down Expand Up @@ -27,3 +27,4 @@
.ToArray();
private CultureInfo SelectedCulture = new CultureInfo("fa");
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<FluentCalendar DisabledDateFunc="@DisabledDate" @bind-Value="@SelectedValue">
<FluentCalendar DisabledDateFunc="@DisabledDate" @bind-Value="@SelectedValue">
<DaysTemplate>
@if (!context.IsInactive &&
(context.Date.Day == 5 || context.Date.Day == 15))
Expand All @@ -14,16 +14,17 @@
</DaysTemplate>
</FluentCalendar>

<p>Selected date @(SelectedValue?.ToString("yyyy-MM-dd"))</p>
<p>Selected date @(SelectedValue.ToString("yyyy-MM-dd"))</p>

@code
{
private DateTime? SelectedValue = null;
private DateOnly SelectedValue = DateOnly.FromDateTime(DateTime.Today);

private bool DisabledDate(DateTime date)
private bool DisabledDate(DateOnly date)
{
return (date.Day == 3 ||
date.Day == 8 ||
date.Day == 20);
}
}

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<FluentStack Wrap="true" HorizontalGap="24px">
<FluentStack Wrap="true" HorizontalGap="24px">

<div>
<FluentCalendar DisabledDateFunc="@DisabledDay"
@bind-Value="@SelectedDay"
@bind-PickerMonth="@PickerDay"
Style="height: 250px; align-content: start;" />
<p>Selected @(SelectedDay?.ToString("yyyy-MM-dd"))</p>
<p>Selected @(SelectedDay.ToString("yyyy-MM-dd"))</p>
<p>Panel @(PickerDay.ToString("yyyy-MM-dd"))</p>
</div>

Expand All @@ -15,7 +15,7 @@
@bind-Value="@SelectedMonth"
@bind-PickerMonth="@PickerMonth"
Style="height: 250px; align-content: start;" />
<p>Selected @(SelectedMonth?.ToString("yyyy-MM-dd"))</p>
<p>Selected @(SelectedMonth.ToString("yyyy-MM-dd"))</p>
<p>Panel @(PickerMonth.ToString("yyyy-MM-dd"))</p>
</div>

Expand All @@ -25,19 +25,22 @@
@bind-Value="@SelectedYear"
@bind-PickerMonth="@PickerYear"
Style="height: 250px; align-content: start;" />
<p>Selected @(SelectedYear?.ToString("yyyy-MM-dd"))</p>
<p>Selected @(SelectedYear.ToString("yyyy-MM-dd"))</p>
<p>Panel @(PickerYear.ToString("yyyy-MM-dd"))</p>
</div>
</FluentStack>

@code
{
private DateTime? SelectedDay = null;
private DateTime PickerDay = DateTime.Today;
private DateTime? SelectedMonth = null;
private DateTime PickerMonth = DateTime.Today;
private DateTime? SelectedYear = null;
private DateTime PickerYear = DateTime.Today;
private static readonly DateTime Today = DateTime.Today;
private static readonly DateTime StartOfMonth = new DateTime(Today.Year, Today.Month, 1);

private DateTime SelectedDay = Today;
private DateTime PickerDay = StartOfMonth;
private DateTime SelectedMonth = Today;
private DateTime PickerMonth = StartOfMonth;
private DateTime SelectedYear = Today;
private DateTime PickerYear = StartOfMonth;

private bool DisabledDay(DateTime date) => date.Day == 3 || date.Day == 8 || date.Day == 20;
private bool DisableMonth(DateTime date) => date.Month == 3 || date.Month == 8;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
@* SelectMode: Single *@
<div>
<FluentCalendar Label="Single"
DisabledDateFunc="@DisabledDay"
DisabledDateFunc="@DisabledNullableDay"
DisplayToday="false"
@bind-Value="@SelectedDay"
SelectMode="CalendarSelectMode.Single" />
Expand Down Expand Up @@ -69,6 +69,7 @@

// Disable all days with the day number 3, 8, and 20.
private bool DisabledDay(DateTime date) => date.Day == 3 || date.Day == 8 || date.Day == 20;
private bool DisabledNullableDay(DateTime? date) => date.HasValue && DisabledDay(date.Value);

// Always select the full week, containing the "clicked" day.
private IEnumerable<DateTime> SelectOneWeek(DateTime date)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<FluentStack Wrap="true" HorizontalGap="24px">
<FluentDatePicker Label="DateTime?" @bind-Value="@NullableDateTime" Width="140px" />
<FluentDatePicker Label="DateTime" @bind-Value="@DateTime" Width="140px" />
<FluentDatePicker Label="DateOnly?" @bind-Value="@NullableDateOnly" Width="140px" />
<FluentDatePicker Label="DateOnly" @bind-Value="@DateOnly" Width="140px" />
</FluentStack>

@code
{
private DateTime? NullableDateTime;
private DateTime DateTime = DateTime.Today;
private DateOnly? NullableDateOnly;
private DateOnly DateOnly = DateOnly.FromDateTime(DateTime.Today);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ Example: `Culture="@(new CultureInfo("fr"))"` will display the calendar in Frenc

{{ CalendarCulture }}

## Value type

The **FluentCalendar** and **FluentDatePicker** components are a generic components, so you can use it with date types such as `DateTime?`, `DateTime`, `DateOnly?` or `DateOnly`.
Blazor will automatically infer the type based on the value you provide to the `Value` or `SelectedDates` parameters.
You can also explicitly set the type using the generic type parameter: `TValue` (i.e. `TValue="DateOnly?"`).

{{ CalendarTypes }}

## API FluentCalendar

{{ API Type=FluentCalendar }}
{{ API Type=FluentCalendar<DateTime> }}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@using System.Globalization
@using System.Globalization

<FluentStack Wrap="true" HorizontalGap="64px">

Expand Down Expand Up @@ -26,3 +26,4 @@
.ToArray();
private CultureInfo SelectedCulture = new CultureInfo("fa");
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div>
<div>
<b>Selected Date:</b> @(SelectedValue?.ToString("yyyy-MM-dd"))
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

<FluentDatePicker @bind-Value="@SelectedValue"
DoubleClickToDate="@DateTime.Today" />
@code
{
DateTime? SelectedValue = DateTime.Today.AddDays(-2);
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div>
<div>
<b>Selected Date:</b> @(SelectedValue?.ToString("yyyy-MM-dd"))
</div>

Expand Down Expand Up @@ -27,3 +27,4 @@
{
DateTime? SelectedValue = DateTime.Today.AddDays(-2);
}

Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ In this case, the mobile picker will be used. This could be useful to use the na

{{ DatePickerRendering }}

## Value type

The **FluentCalendar** and **FluentDatePicker** components are a generic components, so you can use it with date types such as `DateTime?`, `DateTime`, `DateOnly?` or `DateOnly`.
Blazor will automatically infer the type based on the value you provide to the `Value` or `SelectedDates` parameters.
You can also explicitly set the type using the generic type parameter: `TValue` (i.e. `TValue="DateOnly?"`).

{{ CalendarTypes }}

## API FluentDatePicker

{{ API Type=FluentDatePicker }}
{{ API Type=FluentDatePicker<DateTime> }}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ The `FluentDatePicker` is an input field that shows a calendar dropdown to selec

The `FluentTimePicker` allows for picking a specific time of day by selecting hour, minutes and AM/PM

> [!Note]
> The FluentCalendar and FluentDatePicker components are not yet fully compatible with the EditForm and FluentEditForm elements.
> Some functionalities, such as error messages, the requirement message or the validation messages are missing.
> [!Note] The FluentCalendar and FluentDatePicker components are not yet fully compatible with the EditForm and FluentEditForm elements.
> Some functionalities, such as error messages, the required message or the validation messages are missing.

## Calendar

Navigate to this [page](/DateTime/Calendar) for more details.

{{ CalendarDefault }}

## Minimum and Maximum dates

The minimum selectable date is the 1st of February 0001 and the maximum selectable date is the 31st of December 9999.
4 changes: 2 additions & 2 deletions examples/Tools/FluentUI.Demo.DocViewer/Models/Section.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ private static (string Name, Dictionary<string, string> Arguments) ParseComponen
/// <summary />
private static string ReplaceMarkupKeyWord(string content)
{
const string NOTE_ICON = "<svg viewBox=\"0 0 16 16\"><path d=\"M8 2a6 6 0 1 1 0 12A6 6 0 0 1 8 2Zm0 1a5 5 0 1 0 0 10A5 5 0 0 0 8 3Zm0 7a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5Zm0-5.5a.5.5 0 0 1 .5.41V8.5a.5.5 0 0 1-1 .09V5c0-.28.22-.5.5-.5Z\" /></svg>";
const string NOTE_ICON = "<svg viewBox=\"0 0 16 16\" style=\"fill: currentColor;\"><path d=\"M8 2a6 6 0 1 1 0 12A6 6 0 0 1 8 2Zm0 1a5 5 0 1 0 0 10A5 5 0 0 0 8 3Zm0 7a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5Zm0-5.5a.5.5 0 0 1 .5.41V8.5a.5.5 0 0 1-1 .09V5c0-.28.22-.5.5-.5Z\" /></svg>";
const string WARN_ICON = NOTE_ICON;
const string TIP_ICON = "<svg viewBox=\"0 0 16 16\"><path d=\"M4.5 6.5A3.5 3.5 0 1 1 10.45 9c-.19.19-.36.43-.44.73L9.66 11H6.34l-.35-1.27c-.08-.3-.25-.54-.44-.73A3.49 3.49 0 0 1 4.5 6.5ZM6.6 12h2.8l-.18.63a.5.5 0 0 1-.48.37H7.26a.5.5 0 0 1-.48-.37L6.61 12ZM8 2a4.5 4.5 0 0 0-3.16 7.7c.1.1.16.2.19.3l.79 2.9c.17.65.77 1.1 1.44 1.1h1.48a1.5 1.5 0 0 0 1.44-1.1l.8-2.9c.02-.1.08-.2.18-.3A4.49 4.49 0 0 0 8 2Z\" /></svg>";
const string TIP_ICON = "<svg viewBox=\"0 0 16 16\" style=\"fill: currentColor;\"><path d=\"M4.5 6.5A3.5 3.5 0 1 1 10.45 9c-.19.19-.36.43-.44.73L9.66 11H6.34l-.35-1.27c-.08-.3-.25-.54-.44-.73A3.49 3.49 0 0 1 4.5 6.5ZM6.6 12h2.8l-.18.63a.5.5 0 0 1-.48.37H7.26a.5.5 0 0 1-.48-.37L6.61 12ZM8 2a4.5 4.5 0 0 0-3.16 7.7c.1.1.16.2.19.3l.79 2.9c.17.65.77 1.1 1.44 1.1h1.48a1.5 1.5 0 0 0 1.44-1.1l.8-2.9c.02-.1.08-.2.18-.3A4.49 4.49 0 0 0 8 2Z\" /></svg>";

content = Regex.Replace(content, @"\[!NOTE\]", $"<span keyword=\"note\">{NOTE_ICON}Note</span>", RegexOptions.IgnoreCase);
content = Regex.Replace(content, @"\[!NOTE_ICON\]", $"<span keyword=\"note\">{NOTE_ICON}</span>", RegexOptions.IgnoreCase);
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Components/DateTime/CalendarExtended.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Globalization;
using Microsoft.FluentUI.AspNetCore.Components.Extensions;

namespace Microsoft.FluentUI.AspNetCore.Components;
namespace Microsoft.FluentUI.AspNetCore.Components.Calendar;

/// <summary>
/// Gets few calendar details in the right culture.
Expand Down
Loading
Loading