Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FluentCalendar implementation #192

Merged
merged 3 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 49 additions & 0 deletions examples/FluentUI.Demo.Shared/Pages/CalendarPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@page "/CalendarPage"
<h1>Calendar</h1>

<h2>Default</h2>
<p>
<FluentCalendar />
</p>

<h2>Show 6 weeks minimal</h2>
<p>
<FluentCalendar MinWeeks="4" />
</p>

<h2>Disabled dates</h2>
<p>
<FluentCalendar DisabledDates=@disabledDates />
</p>

<h2>Selected dates</h2>
<p>
<FluentCalendar SelectedDates=@selectedDates />
</p>

<h2>Day Format = 2 digit</h2>
<p>
<FluentCalendar DayFormat=DayFormat.TwoDigit />
</p>

@code {
static int currentYear = DateTime.Now.Year;
static int currentMonth = DateTime.Now.Month;

static int daysInMonth = DateTime.DaysInMonth(currentYear, currentMonth) + 1;
static Random random = new();

List<DateOnly> disabledDates = new();
List<DateOnly> selectedDates = new();

protected override void OnInitialized()
{
base.OnInitialized();

for (int i = 0; i < 3; i++)
{
disabledDates.Add(new DateOnly(currentYear, currentMonth, random.Next(1, daysInMonth)));
selectedDates.Add(new DateOnly(currentYear, currentMonth, random.Next(1, daysInMonth)));
};
}
}
2 changes: 1 addition & 1 deletion examples/FluentUI.Demo.Shared/Shared/MainLayout.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public async Task SwitchDirection()

public void SwitchTheme()
{
baseLayerLuminance = baseLayerLuminance == 0.2f ? 1 : 0.2f;
baseLayerLuminance = baseLayerLuminance == 0.15f ? 0.98f : 0.15f;
}

protected override void OnParametersSet()
Expand Down
3 changes: 3 additions & 0 deletions examples/FluentUI.Demo.Shared/Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<li>
<FluentAnchor Href="ButtonPage" Appearance=@SetAppearance("ButtonPage")>Button</FluentAnchor>
</li>
<li>
<FluentAnchor Href="CalendarPage" Appearance=@SetAppearance("CalendarPage")>Calendar</FluentAnchor>
</li>
<li>
<FluentAnchor Href="CardPage" Appearance=@SetAppearance("CardPage")>Card</FluentAnchor>
</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@inherits FluentComponentBase
<fluent-calendar
readonly=@Readonly
month=@Month
year=@Year
locale=@Locale
day-format=@DayFormat.ToAttributeValue()
weekday-format=@WeekdayFormat.ToAttributeValue()
month-format=@MonthFormat.ToAttributeValue()
year-format=@YearFormat.ToAttributeValue()
min-weeks=@MinWeeks
disabled-dates=@disabledDates
selected-dates=@selectedDates
@ref=Element
@attributes="AdditionalAttributes">
@ChildContent
</fluent-calendar>
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Microsoft.AspNetCore.Components;

namespace Microsoft.Fast.Components.FluentUI;
public partial class FluentCalendar : FluentComponentBase
{
private string? disabledDates = null;
private string? selectedDates = null;

/// <summary>
/// Gets or sets if the calendar is readonly
/// </summary>
[Parameter]
public bool? Readonly { get; set; }


/// <summary>
/// Gets or sets the month of the calendar to display
/// </summary>
[Parameter]
public int Month { get; set; } = DateTime.Now.Month;

/// <summary>
/// Gets or sets the year of the calendar to display
/// </summary>
[Parameter]
public int Year { get; set; } = DateTime.Now.Year;

/// <summary>
/// Locale information which can include market (language and country), calendar type and numbering type.
/// </summary>
[Parameter]
public string? Locale { get; set; }

/// <summary>
/// Gets or sets formatting for the numbered days.
/// </summary>
[Parameter]
public DayFormat? DayFormat { get; set; } = FluentUI.DayFormat.Numeric;

/// <summary>
/// Gets or sets formatting for the weekday titles.
/// </summary>
[Parameter]
public WeekdayFormat? WeekdayFormat { get; set; } = FluentUI.WeekdayFormat.Short;

/// <summary>
/// Gets or sets formatting for the month name in the title.
/// </summary>
[Parameter]
public MonthFormat? MonthFormat { get; set; } = FluentUI.MonthFormat.Long;

/// <summary>
/// Gets or sets formatting for the year in the title.
/// </summary>
[Parameter]
public YearFormat? YearFormat { get; set; } = FluentUI.YearFormat.Numeric;

/// <summary>
/// Gets or sets the minimum number of weeks to show. This allows for normalizing of calendars so that they take up the same vertical space.
/// </summary>
[Parameter]
public int MinWeeks { get; set; } = 4;


/// <summary>
/// Gets or sets dates to be shown as disabled.
/// </summary>
[Parameter]
public IEnumerable<DateOnly>? DisabledDates
{
get
{
return disabledDates!.Split(",").Select(x =>
{
_ = DateOnly.TryParse(x, out DateOnly d);
return d;
});
}
set
{
disabledDates = string.Join(",", value!.Select(x => x.ToString("M-d-yyyy")));
}
}

/// <summary>
/// Gets or sets dates to be shown as selected
/// </summary>
[Parameter]
public IEnumerable<DateOnly>? SelectedDates
{
get
{
return selectedDates!.Split(",").Select(x =>
{
_ = DateOnly.TryParse(x, out DateOnly d);
return d;
});
}
set
{
selectedDates = string.Join(",", value!.Select(x => x.ToString("M-d-yyyy")));
}
}
}
92 changes: 92 additions & 0 deletions src/Microsoft.Fast.Components.FluentUI/Enums/CalendarFormats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
ο»Ώnamespace Microsoft.Fast.Components.FluentUI;

/// <summary>
/// Enum representing the different day formats
/// </summary>
public enum DayFormat
{
TwoDigit,
Numeric
}

/// <summary>
/// Enum representing the different weekday formats
/// </summary>
public enum WeekdayFormat
{
Long,
Narrow,
Short
}

/// <summary>
/// Enum representing the different month formats
/// </summary>
public enum MonthFormat
{
TwoDigit,
Long,
Narrow,
Numeric,
Short
}

/// <summary>
/// Enum representing the different year formats
/// </summary>
public enum YearFormat
{
TwoDigit,
Numeric
}

internal static class CalendarFormatExtensions
{
// DayFormat extension
private static readonly Dictionary<DayFormat, string> _dayFormatValues =
Enum.GetValues<DayFormat>().ToDictionary(id => id, id => Enum.GetName(id)!.ToLowerInvariant());

public static string? ToAttributeValue(this DayFormat? value)
{
if (value is null) return null;
return value switch
{
DayFormat.TwoDigit => "2-digit",
_ => _dayFormatValues[value.Value],
};
}

// WeekdayFormat extension
private static readonly Dictionary<WeekdayFormat, string> _weekdayFormatValues =
Enum.GetValues<WeekdayFormat>().ToDictionary(id => id, id => Enum.GetName(id)!.ToLowerInvariant());

public static string? ToAttributeValue(this WeekdayFormat? value) => value == null ? null : _weekdayFormatValues[value.Value];

// MonthFormat extension
private static readonly Dictionary<MonthFormat, string> _monthFormatValues =
Enum.GetValues<MonthFormat>().ToDictionary(id => id, id => Enum.GetName(id)!.ToLowerInvariant());

public static string? ToAttributeValue(this MonthFormat? value)
{
if (value is null) return null;
return value switch
{
MonthFormat.TwoDigit => "2-digit",
_ => _monthFormatValues[value.Value],
};
}

// YearFormat extension
private static readonly Dictionary<YearFormat, string> _yearFormatValues =
Enum.GetValues<YearFormat>().ToDictionary(id => id, id => Enum.GetName(id)!.ToLowerInvariant());

public static string? ToAttributeValue(this YearFormat? value)
{
if (value is null) return null;
return value switch
{
YearFormat.TwoDigit => "2-digit",
_ => _yearFormatValues[value.Value],
};
}
}