diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 581c0e9977..72dfda5a87 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,7 +6,7 @@ You can contribute to bit platform with issues and PRs. Simply filing issues for
We always welcome bug reports, API proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible.
-The bit platform codebase is consisted of multiple projects/products in a monorepo structure. Depending on the feedback you might want to file the issue with enough information to distinguish it among these projects/products.
+The bit platform codebase consists of multiple projects/products in a monorepo structure. Depending on the feedback you might want to file the issue with enough information to distinguish it among these projects/products.
### Finding Existing Issues
@@ -32,7 +32,7 @@ When ready to submit a bug report, please use the [Bug Report issue template](ht
#### Are Minimal Reproductions Required?
-In certain cases, creating a minimal reproduction might not be practical (e.g. due to nondeterministic factors, external dependencies). In such cases you would be asked to provide as much information as possible. If maintainers are unable to root cause the problem, they might still close the issue as not actionable. While not required, minimal reproductions are strongly encouraged and will significantly improve the chances of your issue being prioritized and fixed by the maintainers.
+In certain cases, creating a minimal reproduction might not be practical (e.g. due to nondeterministic factors, external dependencies). In such cases you would be asked to provide as much information as possible. If maintainers are unable to root cause of the problem, they might still close the issue as not actionable. While not required, minimal reproductions are strongly encouraged and will significantly improve the chances of your issue being prioritized and fixed by the maintainers.
#### How to Create a Minimal Reproduction
diff --git a/README.md b/README.md
index e570660c4b..4a62c1d764 100644
--- a/README.md
+++ b/README.md
@@ -6,14 +6,14 @@
![Code size](https://img.shields.io/github/languages/code-size/bitfoundation/bitplatform.svg?logo=github)
![CI Status](https://github.com/bitfoundation/bitplatform/actions/workflows/bit.ci.yml/badge.svg)
![NuGet version](https://img.shields.io/nuget/v/bit.blazorui.svg?logo=nuget)
-[![Nuget downloads](https://img.shields.io/badge/packages_download-3.6M-blue.svg?logo=nuget)](https://www.nuget.org/profiles/bit-foundation)
+[![Nuget downloads](https://img.shields.io/badge/packages_download-3.7M-blue.svg?logo=nuget)](https://www.nuget.org/profiles/bit-foundation)
![image](https://user-images.githubusercontent.com/6169846/271820882-0d816266-ebd1-4c2b-a3b7-296b35248536.png)
-Join us and start contributing to bit platform in [hacktoberfest](https://hacktoberfest.com/). you can find the up-for-grabs issues [here](https://github.com/bitfoundation/bitplatform/labels/up%20for%20grabs).
+Join us and start contributing to bit platform in [hacktoberfest](https://hacktoberfest.com/). you can find the the `good first issues` [here](https://github.com/bitfoundation/bitplatform/labels/good%20first%20issue).
diff --git a/docs/how-to-build.md b/docs/how-to-build.md
index e156d481b7..f6af667588 100644
--- a/docs/how-to-build.md
+++ b/docs/how-to-build.md
@@ -8,7 +8,7 @@
## Projects
-bit platform consists of multiple different projects/prodcuts with the following being the most important ones:
+bit platform consists of multiple different projects/products with the following being the most important ones:
- [bit platform website](../src/Websites/Platform/)
- [bit BlazorUI (Blazor components)](../src/BlazorUI/)
@@ -34,7 +34,7 @@ Building each bit platform project requires specific steps that are explained pe
### bit platform Website
-This website only requires the basic requirements and can be simply built by runnning the following command in the `Bit.Websites.Platform.Web` project folder:
+This website only requires the basic requirements and can be simply built by running the following command in the `Bit.Websites.Platform.Web` project folder:
```bash
dotnet build
@@ -92,7 +92,7 @@ dotnet build
### bit Project Templates
Like the bit BlazorUI Demo project, the project templates (located in the `src/Templates` folder) have two different projects (Web & App) with different requirements to build.
-For exmaple for the `AdminPanel` porject template in the `AdminPanel/Bit.AdminPanel` folder:
+For example for the `AdminPanel` project template in the `AdminPanel/Bit.AdminPanel` folder:
The `Web` project just like the bit platform website only needs the basic requirements and can be simply built by running the following command in the `AdminPanel.Client.Web` project folder (`src/Client/Web`):
@@ -117,4 +117,4 @@ To build the App project run the following command in the `AdminPanel.Client.App
```bash
dotnet build
-```
\ No newline at end of file
+```
diff --git a/src/Bit.Build.props b/src/Bit.Build.props
index 53d56301ac..e5bca0698e 100644
--- a/src/Bit.Build.props
+++ b/src/Bit.Build.props
@@ -25,7 +25,7 @@
https://github.com/bitfoundation/bitplatformhttps://avatars.githubusercontent.com/u/22663390
- 7.0.0
+ 7.1.0https://github.com/bitfoundation/bitplatform/releases/tag/v-$(ReleaseVersion)$(ReleaseVersion)
diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
index e28c82aab0..7a9c3a860f 100644
--- a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
@@ -25,4 +25,15 @@
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
index 7a43e13ccc..43230e1f1d 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
@@ -58,4 +58,15 @@
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj
index ea9a6fab50..aa08e8cc70 100644
--- a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj
@@ -25,4 +25,15 @@
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj
index d6e1dcc28f..97ee9a8ef5 100644
--- a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj
@@ -11,4 +11,15 @@
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/README.md b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/README.md
new file mode 100644
index 0000000000..f79a02c3fc
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/README.md
@@ -0,0 +1 @@
+### bit Source Generators
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj b/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
index cdfad7a7eb..b5a924cce7 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs
index 3b6d37528e..209feda1f1 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs
@@ -204,4 +204,82 @@ public void BitButtonButtonStateNotOverriddenInEditContextTest()
Assert.AreEqual("button", bitButton.GetAttribute("type"));
}
+
+ [DataTestMethod,
+ DataRow(BitButtonColor.Info),
+ DataRow(BitButtonColor.Success),
+ DataRow(BitButtonColor.Warning),
+ DataRow(BitButtonColor.SevereWarning),
+ DataRow(BitButtonColor.Error),
+ DataRow(null),
+ ]
+ [TestMethod]
+ public void BitButtonColorOfButtonTest(BitButtonColor? color)
+ {
+ var com = RenderComponent(parameters =>
+ {
+ if (color.HasValue)
+ {
+ parameters.Add(p => p.Color, color.Value);
+ }
+ });
+
+ var bitButton = com.Find(".bit-btn");
+
+ var colorClassName = color switch
+ {
+ BitButtonColor.Info => "bit-btn-inf",
+ BitButtonColor.Success => "bit-btn-suc",
+ BitButtonColor.Warning => "bit-btn-wrn",
+ BitButtonColor.SevereWarning => "bit-btn-swr",
+ BitButtonColor.Error => "bit-btn-err",
+ _ => String.Empty
+ };
+
+ if (color.HasValue)
+ {
+ Assert.IsTrue(bitButton.ClassList.Contains(colorClassName));
+ }
+ else
+ {
+ Assert.AreEqual(2, bitButton.ClassList.Length);
+ }
+ }
+
+ [DataTestMethod,
+ DataRow(BitButtonSize.Small),
+ DataRow(BitButtonSize.Medium),
+ DataRow(BitButtonSize.Large),
+ DataRow(null)
+ ]
+ [TestMethod]
+ public void BitButtonSizeOfButtonTest(BitButtonSize? size)
+ {
+ var com = RenderComponent(parameters =>
+ {
+ if (size.HasValue)
+ {
+ parameters.Add(p => p.Size, size.Value);
+ }
+ });
+
+ var bitButton = com.Find(".bit-btn");
+
+ var sizeClassName = size switch
+ {
+ BitButtonSize.Small => "bit-btn-sm",
+ BitButtonSize.Medium => "bit-btn-md",
+ BitButtonSize.Large => "bit-btn-lg",
+ _ => String.Empty
+ };
+
+ if (size.HasValue)
+ {
+ Assert.IsTrue(bitButton.ClassList.Contains(sizeClassName));
+ }
+ else
+ {
+ Assert.AreEqual(2, bitButton.ClassList.Length);
+ }
+ }
}
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs
similarity index 80%
rename from src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTestModel.cs
rename to src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs
index b8fdce48d2..1e7b117f4c 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTestModel.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs
@@ -1,7 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
-namespace Bit.BlazorUI.Tests.Pickers;
+namespace Bit.BlazorUI.Tests.DatePicker;
public class BitDatePickerTestModel
{
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs
similarity index 79%
rename from src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTests.cs
rename to src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs
index d136648a1f..f12bb545ab 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs
@@ -3,7 +3,7 @@
using Bunit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace Bit.BlazorUI.Tests.Pickers;
+namespace Bit.BlazorUI.Tests.DatePicker;
[TestClass]
public class BitDatePickerTests : BunitTestContext
@@ -48,7 +48,7 @@ public void BitDatePickerShouldGiveValueToGoToToday(string goToToday)
{
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.GoToToday, goToToday);
+ parameters.Add(p => p.GoToTodayTitle, goToToday);
parameters.Add(p => p.IsOpen, true);
});
@@ -83,16 +83,17 @@ public void BitDatePickerShouldHandleOnClickEvent(bool isEnabled, int count)
]
public void BitDatePickerCalendarItemsShouldRespectIsEnabled(bool isEnabled, int count)
{
- int selectedDateValue = 0;
+ var selectedDateValue = 0;
+ var isOpen = true;
Context.JSInterop.Mode = JSRuntimeMode.Loose;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.IsOpen, true);
+ parameters.Bind(p => p.IsOpen, isOpen, v => isOpen = v);
parameters.Add(p => p.IsEnabled, isEnabled);
parameters.Add(p => p.OnSelectDate, () => selectedDateValue++);
});
- var dateItems = component.FindAll(".bit-dtp-dbtn");
+ var dateItems = component.FindAll(".bit-dtp-dbt");
Random random = new();
int randomNumber = random.Next(0, dateItems.Count - 1);
@@ -104,15 +105,16 @@ public void BitDatePickerCalendarItemsShouldRespectIsEnabled(bool isEnabled, int
public void BitDatePickerCalendarSelectTodayDate()
{
Context.JSInterop.Mode = JSRuntimeMode.Loose;
+ var isOpen = true;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.IsOpen, true);
+ parameters.Bind(p => p.IsOpen, isOpen, v => isOpen = v);
parameters.Add(p => p.IsEnabled, true);
});
Assert.IsNull(component.Instance.Value);
- var today = component.Find(".bit-dtp-dc-tdy button.bit-dtp-dbtn");
+ var today = component.Find(".bit-dtp-dtd");
today.Click();
Assert.IsNotNull(component.Instance.Value);
@@ -120,27 +122,6 @@ public void BitDatePickerCalendarSelectTodayDate()
Assert.AreEqual(component.Instance.Value.Value.Offset, DateTimeOffset.Now.Offset);
}
- [DataTestMethod]
- public void BitDatePickerCalendarWithCustomCultureInfo()
- {
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
- var component = RenderComponent(parameters =>
- {
- parameters.Add(p => p.IsOpen, true);
- parameters.Add(p => p.Culture, CultureInfoHelper.GetFaIrCultureByFingilishNames());
- });
-
- var monthButtons = component.FindAll(".bit-dtp-mwp .bit-dtp-gctn .bit-dtp-btn-row button");
- Assert.IsTrue(monthButtons.Count > 0);
- Assert.AreEqual(12, monthButtons.Count);
-
- var index = 0;
- foreach (var button in monthButtons)
- {
- Assert.AreEqual(button.FirstElementChild.TextContent, component.Instance.Culture.DateTimeFormat.AbbreviatedMonthNames[index++]);
- }
- }
-
[DataTestMethod]
public void BitDatePickerValidationFormTest()
{
@@ -162,7 +143,7 @@ public void BitDatePickerValidationFormTest()
datePicker.Click();
//select today
- var today = component.Find(".bit-dtp-dc-tdy button.bit-dtp-dbtn");
+ var today = component.Find(".bit-dtp-dtd");
today.Click();
form.Submit();
@@ -196,7 +177,7 @@ public void BitDatePickerValidationInvalidHtmlAttributeTest()
datePicker.Click();
//select today
- var today = component.Find(".bit-dtp-dc-tdy button.bit-dtp-dbtn");
+ var today = component.Find(".bit-dtp-dtd");
today.Click();
form.Submit();
@@ -228,7 +209,7 @@ public void BitDatePickerValidationInvalidCssClassTest()
datePicker.Click();
//select today
- var today = component.Find(".bit-dtp-dc-tdy button.bit-dtp-dbtn");
+ var today = component.Find(".bit-dtp-dtd");
today.Click();
Assert.IsFalse(bitDatePicker.ClassList.Contains("bit-inv"));
@@ -240,10 +221,10 @@ public void BitDatePickerAriaLabelTest(string pickerAriaLabel)
Context.JSInterop.Mode = JSRuntimeMode.Loose;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.PickerAriaLabel, pickerAriaLabel);
+ parameters.Add(p => p.CalloutAriaLabel, pickerAriaLabel);
});
- var bitDatePickerCallout = component.Find(".bit-dtp-mcal");
+ var bitDatePickerCallout = component.Find(".bit-dtp-cac");
var calloutAriaLabel = bitDatePickerCallout.GetAttribute("aria-label");
Assert.AreEqual(pickerAriaLabel, calloutAriaLabel);
@@ -273,29 +254,29 @@ public void BitDatePickerShowGoToTodayTest(bool showGoToToday)
}
}
- [DataTestMethod,
- DataRow(false),
- DataRow(true)
- ]
- public void BitDatePickerShowCloseButtonTest(bool showCloseButton)
- {
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
- var component = RenderComponent(parameters =>
- {
- parameters.Add(p => p.ShowCloseButton, showCloseButton);
- });
-
- var closeBtnElms = component.FindAll(".bit-dtp-cbtn");
-
- if (showCloseButton)
- {
- Assert.AreEqual(1, closeBtnElms.Count);
- }
- else
- {
- Assert.AreEqual(0, closeBtnElms.Count);
- }
- }
+ //[DataTestMethod,
+ // DataRow(false),
+ // DataRow(true)
+ //]
+ //public void BitDatePickerShowCloseButtonTest(bool showCloseButton)
+ //{
+ // Context.JSInterop.Mode = JSRuntimeMode.Loose;
+ // var component = RenderComponent(parameters =>
+ // {
+ // parameters.Add(p => p.ShowCloseButton, showCloseButton);
+ // });
+
+ // var closeBtnElms = component.FindAll(".bit-dtp-cbtn");
+
+ // if (showCloseButton)
+ // {
+ // Assert.AreEqual(1, closeBtnElms.Count);
+ // }
+ // else
+ // {
+ // Assert.AreEqual(0, closeBtnElms.Count);
+ // }
+ //}
[DataTestMethod,
DataRow(false),
@@ -309,7 +290,7 @@ public void BitDatePickerHighlightCurrentMonthTest(bool highlightCurrentMonth)
parameters.Add(p => p.HighlightCurrentMonth, highlightCurrentMonth);
});
- var currentMonthCells = component.FindAll(".bit-dtp-crtm");
+ var currentMonthCells = component.FindAll(".bit-dtp-pcm");
if (highlightCurrentMonth)
{
@@ -334,7 +315,7 @@ public void BitDatePickerHighlightSelectedMonthTest(bool highlightSelectedMonth)
});
- var selectedMonthCells = component.FindAll(".bit-dtp-selm");
+ var selectedMonthCells = component.FindAll(".bit-dtp-psm");
if (highlightSelectedMonth)
{
@@ -360,7 +341,7 @@ public void BitDatePickerCalloutHtmlAttributesTest()
parameters.Add(p => p.CalloutHtmlAttributes, calloutHtmlAttributes);
});
- var bitDatePickerCallout = component.Find(".bit-dtp-mcal");
+ var bitDatePickerCallout = component.Find(".bit-dtp-cac");
var calloutStyle = bitDatePickerCallout.GetAttribute("style");
Assert.AreEqual("color: blue", calloutStyle);
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerValidationTest.razor
similarity index 94%
rename from src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerValidationTest.razor
rename to src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerValidationTest.razor
index d824fe50b2..106e79041e 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Pickers/BitDatePickerValidationTest.razor
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerValidationTest.razor
@@ -7,8 +7,8 @@
Culture="Culture"
@bind-Value="@TestModel.Value"
Placeholder="@Placeholder"
- GoToToday="@GoToToday"
- IsOpen="IsOpen"
+ GoToTodayTitle="@GoToToday"
+ @bind-IsOpen="IsOpen"
OnClick="HandleOnClick"
OnSelectDate="HandleSelectDate">
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs
index 1104fec908..df3cc5dd45 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs
@@ -39,7 +39,7 @@ public void BitDateRangePickerShouldRenderLabelFragment(string labelTemplate)
parameters.Add(p => p.LabelTemplate, labelTemplate);
});
- var bitDateRangePickerLabelChild = component.Find(".bit-dtrp > label.bit-dtrp-lbl").ChildNodes;
+ var bitDateRangePickerLabelChild = component.Find(".bit-dtrp > label").ChildNodes;
bitDateRangePickerLabelChild.MarkupMatches(labelTemplate);
}
@@ -48,7 +48,7 @@ public void BitDateRangePickerShouldGiveValueToGoToToday(string goToToday)
{
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.GoToToday, goToToday);
+ parameters.Add(p => p.GoToTodayTitle, goToToday);
parameters.Add(p => p.IsOpen, true);
});
@@ -78,42 +78,44 @@ public void BitDateRangePickerShouldHandleOnClickEvent(bool isEnabled, int count
}
[DataTestMethod,
- DataRow(true, 1),
- DataRow(false, 0)
+ DataRow(true),
+ DataRow(false)
]
- public void BitDateRangePickerCalendarItemsShouldRespectIsEnabled(bool isEnabled, int count)
+ public void BitDateRangePickerCalendarItemsShouldRespectIsEnabled(bool isEnabled)
{
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
+ var isOpen = true;
var selectedDateValue = 0;
+ Context.JSInterop.Mode = JSRuntimeMode.Loose;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.IsOpen, true);
+ parameters.Bind(p => p.IsOpen, isOpen, v => isOpen = v);
parameters.Add(p => p.IsEnabled, isEnabled);
parameters.Add(p => p.OnSelectDate, () => selectedDateValue++);
});
- var dateItems = component.FindAll(".bit-dtrp-dbtn");
+ var dateItems = component.FindAll(".bit-dtrp-dbt");
Random random = new();
int randomNumber = random.Next(0, dateItems.Count - 1);
dateItems[randomNumber].Click();
- Assert.AreEqual(count, selectedDateValue);
+ Assert.AreEqual(isEnabled ? 1 : 0, selectedDateValue);
}
[DataTestMethod]
public void BitDateRangePickerCalendarSelectTodayDate()
{
+ var isOpen = true;
Context.JSInterop.Mode = JSRuntimeMode.Loose;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.IsOpen, true);
+ parameters.Bind(p => p.IsOpen, isOpen, v => isOpen = v);
parameters.Add(p => p.IsEnabled, true);
});
Assert.IsNull(component.Instance.Value.StartDate);
Assert.IsNull(component.Instance.Value.EndDate);
- var today = component.Find(".bit-dtrp-dc-tdy button.bit-dtrp-dbtn");
+ var today = component.Find(".bit-dtrp-dtd");
today.Click();
Assert.IsNotNull(component.Instance.Value.StartDate);
@@ -131,27 +133,6 @@ public void BitDateRangePickerCalendarSelectTodayDate()
Assert.AreEqual(component.Instance.Value.EndDate.Value.Offset, DateTimeOffset.Now.Offset);
}
- [DataTestMethod]
- public void BitDateRangePickerCalendarWithCustomCultureInfo()
- {
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
- var component = RenderComponent(parameters =>
- {
- parameters.Add(p => p.IsOpen, true);
- parameters.Add(p => p.Culture, CultureInfoHelper.GetFaIrCultureByFingilishNames());
- });
-
- var monthButtons = component.FindAll("button.bit-dtrp-rbtn");
- Assert.IsTrue(monthButtons.Count > 0);
- Assert.AreEqual(12, monthButtons.Count);
-
- var index = 0;
- foreach (var button in monthButtons)
- {
- Assert.AreEqual(button.FirstElementChild.TextContent, component.Instance.Culture.DateTimeFormat.AbbreviatedMonthNames[index++]);
- }
- }
-
[DataTestMethod,
DataRow("DateRangePicker")
]
@@ -160,10 +141,10 @@ public void BitDateRangePickerAriaLabelTest(string pickerAriaLabel)
Context.JSInterop.Mode = JSRuntimeMode.Loose;
var component = RenderComponent(parameters =>
{
- parameters.Add(p => p.PickerAriaLabel, pickerAriaLabel);
+ parameters.Add(p => p.CalloutAriaLabel, pickerAriaLabel);
});
- var bitDateRangePickerCallout = component.Find(".bit-dtrp-mcal");
+ var bitDateRangePickerCallout = component.Find(".bit-dtrp-cac");
var calloutAriaLabel = bitDateRangePickerCallout.GetAttribute("aria-label");
Assert.AreEqual(pickerAriaLabel, calloutAriaLabel);
@@ -193,29 +174,29 @@ public void BitDateRangePickerShowGoToTodayTest(bool showGoToToday)
}
}
- [DataTestMethod,
- DataRow(false),
- DataRow(true)
- ]
- public void BitDateRangePickerShowCloseButtonTest(bool showCloseButton)
- {
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
- var component = RenderComponent(parameters =>
- {
- parameters.Add(p => p.ShowCloseButton, showCloseButton);
- });
-
- var closeBtnElms = component.FindAll(".bit-dtrp-cbtn");
-
- if (showCloseButton)
- {
- Assert.AreEqual(1, closeBtnElms.Count);
- }
- else
- {
- Assert.AreEqual(0, closeBtnElms.Count);
- }
- }
+ //[DataTestMethod,
+ // DataRow(false),
+ // DataRow(true)
+ //]
+ //public void BitDateRangePickerShowCloseButtonTest(bool showCloseButton)
+ //{
+ // Context.JSInterop.Mode = JSRuntimeMode.Loose;
+ // var component = RenderComponent(parameters =>
+ // {
+ // parameters.Add(p => p.ShowCloseButton, showCloseButton);
+ // });
+
+ // var closeBtnElms = component.FindAll(".bit-dtrp-cbtn");
+
+ // if (showCloseButton)
+ // {
+ // Assert.AreEqual(1, closeBtnElms.Count);
+ // }
+ // else
+ // {
+ // Assert.AreEqual(0, closeBtnElms.Count);
+ // }
+ //}
[DataTestMethod,
DataRow(false),
@@ -229,7 +210,7 @@ public void BitDateRangePickerHighlightCurrentMonthTest(bool highlightCurrentMon
parameters.Add(p => p.HighlightCurrentMonth, highlightCurrentMonth);
});
- var currentMonthCells = component.FindAll(".bit-dtrp-crtm");
+ var currentMonthCells = component.FindAll(".bit-dtrp-pcm");
if (highlightCurrentMonth)
{
@@ -254,7 +235,7 @@ public void BitDateRangePickerHighlightSelectedMonthTest(bool highlightSelectedM
});
- var selectedMonthCells = component.FindAll(".bit-dtrp-selm");
+ var selectedMonthCells = component.FindAll(".bit-dtrp-psm");
if (highlightSelectedMonth)
{
@@ -280,7 +261,7 @@ public void BitDateRangePickerCalloutHtmlAttributesTest()
parameters.Add(p => p.CalloutHtmlAttributes, calloutHtmlAttributes);
});
- var bitDateRangePickerCallout = component.Find(".bit-dtrp-mcal");
+ var bitDateRangePickerCallout = component.Find(".bit-dtrp-cac");
var calloutStyle = bitDateRangePickerCallout.GetAttribute("style");
Assert.AreEqual("color: blue", calloutStyle);
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs
index 980c36cd32..139184d6f8 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs
@@ -44,26 +44,28 @@ public void BitDropdownTest(bool isEnabled)
]
public void ResponsiveDropdownShouldTakeCorrectClassNameAndRenderElements(bool isResponsiveModeEnabled)
{
- Context.JSInterop.Mode = JSRuntimeMode.Loose;
+ //// since it's now handled in the JS this test needs to be changed!
- var component = RenderComponent, string>>(parameters =>
- {
- parameters.Add(p => p.IsResponsive, isResponsiveModeEnabled);
- });
+ //Context.JSInterop.Mode = JSRuntimeMode.Loose;
- var bitDropdown = component.Find(".bit-drp");
+ //var component = RenderComponent, string>>(parameters =>
+ //{
+ // parameters.Add(p => p.IsResponsive, isResponsiveModeEnabled);
+ //});
- if (isResponsiveModeEnabled)
- {
- Assert.IsTrue(bitDropdown.ClassList.Contains("bit-drp-rsp"));
+ //var callout = component.Find(".bit-drp-cal");
- var lblContainer = component.Find(".bit-drp-rlc");
- Assert.IsNotNull(lblContainer);
- }
- else
- {
- Assert.ThrowsException(() => component.Find(".bit-drp-rlc"));
- }
+ //if (isResponsiveModeEnabled)
+ //{
+ // Assert.IsTrue(callout.ClassList.Contains("bit-drp-rsp"));
+
+ // var lblContainer = component.Find(".bit-drp-rlc");
+ // Assert.IsNotNull(lblContainer);
+ //}
+ //else
+ //{
+ // Assert.ThrowsException(() => component.Find(".bit-drp-rlc"));
+ //}
}
[DataTestMethod,
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs
index 5b4094896c..08599d0107 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs
@@ -21,7 +21,7 @@ public void BitModalIsAlertTest(bool? isAlert)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-mdl > div");
+ var element = com.Find(".bit-mdl");
Assert.AreEqual(element.Attributes["role"].Value, isAlert.HasValue && isAlert.Value ? "alertdialog" : "dialog");
}
@@ -60,7 +60,7 @@ public void BitModalIsModelessTest(bool isModeless)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-mdl > div");
+ var element = com.Find(".bit-mdl");
Assert.AreEqual(element.Attributes["aria-modal"].Value, (isModeless is false).ToString());
var elementOverlay = com.FindAll(".bit-mdl-ovl");
@@ -95,7 +95,7 @@ public void BitModalSubtitleAriaIdTest(string subtitleAriaId)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-mdl > div");
+ var element = com.Find(".bit-mdl");
if (subtitleAriaId == null)
{
@@ -124,7 +124,7 @@ public void BitModalTitleAriaIdTest(string titleAriaId)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-mdl > div");
+ var element = com.Find(".bit-mdl");
if (titleAriaId == null)
{
@@ -149,9 +149,9 @@ public void BitModalContentTest()
parameters.AddChildContent("
Test Content
");
});
- var elementContent = com.Find(".bit-mdl-scr-cnt");
+ var elementContent = com.Find(".bit-mdl-scn");
- elementContent.MarkupMatches("
Test Content
");
+ elementContent.MarkupMatches("
Test Content
");
}
[TestMethod]
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs
index 3abc865983..390674d771 100644
--- a/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs
@@ -43,7 +43,7 @@ public void BitPanelIsModelessTest(bool isModeless)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-pnl > div");
+ var element = com.Find(".bit-pnl");
Assert.AreEqual(element.Attributes["aria-modal"].Value, (isModeless is false).ToString());
var elementOverlay = com.FindAll(".bit-pnl-ovl");
@@ -78,7 +78,7 @@ public void BitPanelSubtitleAriaIdTest(string subtitleAriaId)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-pnl > div");
+ var element = com.Find(".bit-pnl");
if (subtitleAriaId == null)
{
@@ -107,7 +107,7 @@ public void BitPanelTitleAriaIdTest(string titleAriaId)
parameters.Add(p => p.IsOpen, true);
});
- var element = com.Find(".bit-pnl > div");
+ var element = com.Find(".bit-pnl");
if (titleAriaId == null)
{
diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs
new file mode 100644
index 0000000000..fbce056d5e
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Threading.Tasks;
+using Bunit;
+using Bunit.Extensions;
+using Microsoft.AspNetCore.Components;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Bit.BlazorUI.Tests.SnackBar;
+
+[TestClass]
+public class BitSnackBarTests : BunitTestContext
+{
+ [DataTestMethod,
+ DataRow(BitSnackBarPosition.TopLeft),
+ DataRow(BitSnackBarPosition.TopCenter),
+ DataRow(BitSnackBarPosition.TopRight),
+ DataRow(BitSnackBarPosition.BottomLeft),
+ DataRow(BitSnackBarPosition.BottomCenter),
+ DataRow(BitSnackBarPosition.BottomRight),
+ DataRow(null)
+ ]
+ [TestMethod]
+ public void BitSnackBarPositionTest(BitSnackBarPosition? position)
+ {
+ var com = RenderComponent(parameters =>
+ {
+ if (position.HasValue) parameters.Add(p => p.Position, position.Value);
+ });
+
+ var element = com.Find(".bit-snb");
+
+ var positionClass = position switch
+ {
+ BitSnackBarPosition.TopLeft => "bit-snb-tlf",
+ BitSnackBarPosition.TopCenter => "bit-snb-tcn",
+ BitSnackBarPosition.TopRight => "bit-snb-trt",
+
+ BitSnackBarPosition.BottomLeft => "bit-snb-blf",
+ BitSnackBarPosition.BottomCenter => "bit-snb-bcn",
+ BitSnackBarPosition.BottomRight => "bit-snb-brt",
+
+ _ => "bit-snb-brt",
+ };
+
+ Assert.IsTrue(element.ClassList.Contains(positionClass));
+ }
+
+ [DataTestMethod,
+ DataRow("title", "body"),
+ DataRow("title", "")
+ ]
+ [TestMethod]
+ public async Task BitSnackBarShowTest(string title, string body)
+ {
+ var com = RenderComponent();
+
+ await com.Instance.Show(title, body);
+
+ var item = com.Find(".bit-snb-itm");
+ Assert.IsNotNull(item);
+
+ var titleElement = com.Find(".bit-snb-ttl");
+ Assert.AreEqual(title, titleElement.InnerHtml);
+
+ if (body.IsNullOrEmpty() is false)
+ {
+ var bodyElement = com.Find(".bit-snb-bdy");
+ Assert.AreEqual(body, bodyElement.InnerHtml);
+ }
+ }
+
+ [DataTestMethod,
+ DataRow(true),
+ DataRow(false)
+ ]
+ [TestMethod]
+ public async Task BitSnackBarAutoDismissTest(bool autoDismiss)
+ {
+ var com = RenderComponent(
+ parameters =>
+ {
+ parameters.Add(p => p.AutoDismiss, autoDismiss);
+ }
+ );
+
+ await com.Instance.Show("title");
+
+ //Added a sec delay to be sure we are asserting after AutoDismissTime passed
+ await Task.Delay(com.Instance.AutoDismissTime + TimeSpan.FromSeconds(1));
+
+ var items = com.FindAll(".bit-snb-itm");
+
+ Assert.AreEqual(autoDismiss ? 0 : 1, items.Count);
+ }
+
+ [DataTestMethod,
+ DataRow("title", BitSnackBarType.Info),
+ DataRow("title", BitSnackBarType.Warning),
+ DataRow("title", BitSnackBarType.Success),
+ DataRow("title", BitSnackBarType.Error),
+ DataRow("title", BitSnackBarType.SevereWarning),
+ DataRow("title", null)
+ ]
+ [TestMethod]
+ public async Task BitSnackBarTypeTest(string title, BitSnackBarType? type)
+ {
+ var com = RenderComponent();
+
+ if (type.HasValue)
+ {
+ await com.Instance.Show(title, type: type.Value);
+ }
+ else
+ {
+ await com.Instance.Show(title);
+ }
+
+ var element = com.Find(".bit-snb-itm");
+
+ var typeClass = type switch
+ {
+ BitSnackBarType.Info => $"bit-snb-info",
+ BitSnackBarType.Warning => $"bit-snb-warning",
+ BitSnackBarType.Success => $"bit-snb-success",
+ BitSnackBarType.Error => $"bit-snb-error",
+ BitSnackBarType.SevereWarning => $"bit-snb-severe-warning",
+ _ => String.Empty
+ };
+
+ if (typeClass.IsNullOrEmpty())
+ {
+ Assert.AreEqual(1, element.ClassList.Length);
+ }
+ else
+ {
+ Assert.IsTrue(element.ClassList.Contains(typeClass));
+ }
+ }
+
+ [DataTestMethod,
+ DataRow("title")
+ ]
+ [TestMethod]
+ public async Task BitSnackBarCloseButtonTest(string title)
+ {
+ var com = RenderComponent();
+
+ await com.Instance.Show(title);
+
+ var closeButton = com.Find(".bit-snb-cbt");
+
+ var itemsBeforeClose = com.FindAll(".bit-snb-itm");
+ Assert.AreEqual(1, itemsBeforeClose.Count);
+
+ closeButton.Click();
+
+ var itemsAfterClose = com.FindAll(".bit-snb-itm");
+ Assert.AreEqual(0, itemsAfterClose.Count);
+ }
+
+ [DataTestMethod,
+ DataRow("title", "Go"),
+ DataRow("title", "Cancel")
+ ]
+ [TestMethod]
+ public async Task BitSnackBarDismissIconNameTest(string title, string iconName)
+ {
+ var com = RenderComponent(
+ parameters =>
+ {
+ parameters.Add(x => x.DismissIconName, iconName);
+ }
+ );
+
+ await com.Instance.Show(title);
+
+ var closeButtonIcon = com.Find(".bit-snb-cbt > .bit-icon");
+
+ Assert.IsTrue(closeButtonIcon.ClassList.Contains($"bit-icon--{iconName}"));
+ }
+
+ [DataTestMethod,
+ DataRow("title")
+ ]
+ [TestMethod]
+ public async Task BitSnackBarTitleTemplateTest(string title)
+ {
+ RenderFragment titleTemplate = (string text) => (builder) =>
+ {
+ builder.AddMarkupContent(0, $"{text}");
+ };
+ var com = RenderComponent(parameters => parameters
+ .Add(p => p.TitleTemplate, titleTemplate)
+ );
+
+ await com.Instance.Show(title);
+
+ var titleTemplateElement = com.Find(".bit-snb-hdr");
+
+ var expectedHtml = $@"
+ {title}";
+
+ titleTemplateElement.InnerHtml.MarkupMatches(expectedHtml);
+ }
+
+ [DataTestMethod,
+ DataRow("title", "body")
+ ]
+ [TestMethod]
+ public async Task BitSnackBarBodyTemplateTest(string title, string body)
+ {
+ RenderFragment bodyTemplate = (string text) => (builder) =>
+ {
+ builder.AddMarkupContent(0, $"
{text}
");
+ };
+ var com = RenderComponent(parameters => parameters
+ .Add(p => p.BodyTemplate, bodyTemplate)
+ );
+
+ await com.Instance.Show(title, body);
+
+ var itemTemplateElement = com.Find(".bit-snb-itm");
+
+ var expectedHtml = $@"
+
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs
index 47a4e5d10f..9d0d801093 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs
@@ -9,94 +9,70 @@ public partial class BitCalendar
private const int DEFAULT_DAY_COUNT_PER_WEEK = 7;
private const int DEFAULT_WEEK_COUNT = 6;
- private CultureInfo culture = CultureInfo.CurrentUICulture;
+
+ private CultureInfo culture = CultureInfo.CurrentUICulture;
private bool isMonthPickerVisible = true;
- private string focusClass = string.Empty;
- private string _focusClass
- {
- get => focusClass;
- set
- {
- focusClass = value;
- ClassBuilder.Reset();
- }
- }
- private bool _showYearView;
- private bool _showMonthPicker;
- private int[,] _currentMonthCalendar = new int[DEFAULT_WEEK_COUNT, DEFAULT_DAY_COUNT_PER_WEEK];
- private int _currentDay;
- private int _currentMonth;
- private int _currentYear;
- private int _displayYear;
- private int _monthLength;
- private int? _selectedDateWeek;
- private int? _selectedDateDayOfWeek;
- private int _yearRangeFrom;
- private int _yearRangeTo;
- private string _monthTitle = string.Empty;
- private string? _monthTitleId;
- private string? _activeDescendantId;
- private ElementReference _inputTimeHourRef = default!;
- private ElementReference _inputTimeMinuteRef = default!;
private int timeHour;
- private int timeMinute;
-
private int _timeHour
{
- get
- {
- return timeHour;
- }
+ get => timeHour;
set
{
- if (value > 23)
- {
- timeHour = 23;
- }
- else if (value < 0)
- {
- timeHour = 0;
- }
- else
- {
- timeHour = value;
- }
+ timeHour = value > 23 ? 23
+ : value < 0 ? 0
+ : value;
UpdateTime();
}
}
+ private int timeMinute;
private int _timeMinute
{
- get
- {
- return timeMinute;
- }
+ get => timeMinute;
set
{
- if (value > 59)
- {
- timeMinute = 59;
- }
- else if (value < 0)
- {
- timeMinute = 0;
- }
- else
- {
- timeMinute = value;
- }
+ timeMinute = value > 59 ? 59
+ : value < 0 ? 0
+ : value;
UpdateTime();
}
}
+
+
+ private int _currentDay;
+ private int _currentYear;
+ private int _displayYear;
+ private int _yearPickerEndYear;
+ private int _currentMonth;
+ private int _yearPickerStartYear;
+ private bool _showYearPicker;
+ private bool _showMonthPicker;
+ private int? _selectedDateWeek;
+ private int? _selectedDateDayOfWeek;
+ private string? _activeDescendantId;
+ private string _monthTitle = string.Empty;
+ private ElementReference _inputTimeHourRef = default!;
+ private ElementReference _inputTimeMinuteRef = default!;
+ private int[,] _daysOfCurrentMonth = new int[DEFAULT_WEEK_COUNT, DEFAULT_DAY_COUNT_PER_WEEK];
+
+
+
[Inject] private IJSRuntime _js { get; set; } = default!;
+
+
+ ///
+ /// Custom CSS classes for different parts of the BitCalendar component.
+ ///
+ [Parameter] public BitCalendarClassStyles? Classes { get; set; }
+
///
- /// CultureInfo for the Calendar
+ /// CultureInfo for the Calendar.
///
[Parameter]
public CultureInfo Culture
@@ -112,7 +88,7 @@ public CultureInfo Culture
}
///
- /// The format of the date in the Calendar
+ /// The format of the date in the Calendar.
///
[Parameter] public string? DateFormat { get; set; }
@@ -122,29 +98,49 @@ public CultureInfo Culture
[Parameter] public RenderFragment? DayCellTemplate { get; set; }
///
- /// GoToToday text for the Calendar
+ /// The title of the Go to next month button (tooltip).
///
- [Parameter] public string GoToToday { get; set; } = "Go to today";
+ [Parameter] public string GoToNextMonthTitle { get; set; } = "Go to next month";
+
+ ///
+ /// The title of the Go to next year range button (tooltip).
+ ///
+ [Parameter] public string GoToNextYearRangeTitle { get; set; } = "Next year range {0} - {1}";
///
- /// The title of the Go to previous month button
+ /// The title of the Go to next year button (tooltip).
+ ///
+ [Parameter] public string GoToNextYearTitle { get; set; } = "Go to next year {0}";
+
+ ///
+ /// The title of the Go to previous month button (tooltip).
///
[Parameter] public string GoToPrevMonthTitle { get; set; } = "Go to previous month";
///
- /// The title of the Go to next month button
+ /// The title of the Go to previous year range button (tooltip).
///
- [Parameter] public string GoToNextMonthTitle { get; set; } = "Go to next month";
+ [Parameter] public string GoToPrevYearRangeTitle { get; set; } = "Previous year range {0} - {1}";
+
+ ///
+ /// The title of the Go to previous year button (tooltip).
+ ///
+ [Parameter] public string GoToPrevYearTitle { get; set; } = "Go to previous year {0}";
+
+ ///
+ /// The title of the GoToToday button (tooltip).
+ ///
+ [Parameter] public string GoToTodayTitle { get; set; } = "Go to today";
///
/// Whether the month picker should highlight the current month.
///
- [Parameter] public bool HighlightCurrentMonth { get; set; } = false;
+ [Parameter] public bool HighlightCurrentMonth { get; set; }
///
/// Whether the month picker should highlight the selected month.
///
- [Parameter] public bool HighlightSelectedMonth { get; set; } = false;
+ [Parameter] public bool HighlightSelectedMonth { get; set; }
///
/// The custom validation error message for the invalid value.
@@ -152,7 +148,7 @@ public CultureInfo Culture
[Parameter] public string? InvalidErrorMessage { get; set; }
///
- /// Whether the month picker is shown beside the day picker or hidden.
+ /// Whether the month picker is shown or hidden.
///
[Parameter]
public bool IsMonthPickerVisible
@@ -160,8 +156,6 @@ public bool IsMonthPickerVisible
get => isMonthPickerVisible;
set
{
- if (isMonthPickerVisible == value) return;
-
isMonthPickerVisible = value;
if (value is false)
@@ -170,13 +164,14 @@ public bool IsMonthPickerVisible
}
}
}
+
///
- /// MaxDate for the Calendar
+ /// The maximum allowable date of the calendar.
///
[Parameter] public DateTimeOffset? MaxDate { get; set; }
///
- /// MinDate for the Calendar
+ /// The minimum allowable date of the calendar.
///
[Parameter] public DateTimeOffset? MinDate { get; set; }
@@ -186,29 +181,49 @@ public bool IsMonthPickerVisible
[Parameter] public RenderFragment? MonthCellTemplate { get; set; }
///
- /// Used to set month picker position.
+ /// The title of the month picker's toggle (tooltip).
+ ///
+ [Parameter] public string MonthPickerToggleTitle { get; set; } = "{0}, change month";
+
+ ///
+ /// Used to set the month picker position.
///
[Parameter] public BitCalendarMonthPickerPosition MonthPickerPosition { get; set; } = BitCalendarMonthPickerPosition.Besides;
///
- /// Callback for when the date changes.
+ /// Callback for when the user selects a date.
///
[Parameter] public EventCallback OnSelectDate { get; set; }
///
- /// Whether the "Go to today" link should be shown or not.
+ /// The text of selected date aria-atomic of the calendar.
+ ///
+ [Parameter] public string SelectedDateAriaAtomic { get; set; } = "Selected date {0}";
+
+ ///
+ /// Whether the GoToToday button should be shown or not.
///
[Parameter] public bool ShowGoToToday { get; set; } = true;
///
- /// Whether the calendar should show the week number (weeks 1 to 53) before each week row.
+ /// Whether the time picker should be shown or not.
+ ///
+ [Parameter] public bool ShowTimePicker { get; set; }
+
+ ///
+ /// Whether the week number (weeks 1 to 53) should be shown before each week row.
///
[Parameter] public bool ShowWeekNumbers { get; set; }
///
- /// The tabIndex of the TextField.
+ /// Custom CSS styles for different parts of the BitCalendar component.
///
- [Parameter] public int TabIndex { get; set; }
+ [Parameter] public BitCalendarClassStyles? Styles { get; set; }
+
+ ///
+ /// The title of the week number (tooltip).
+ ///
+ [Parameter] public string WeekNumberTitle { get; set; } = "Week number {0}";
///
/// Used to customize how content inside the year cell is rendered.
@@ -216,48 +231,57 @@ public bool IsMonthPickerVisible
[Parameter] public RenderFragment? YearCellTemplate { get; set; }
///
- /// Show time picker for select times.
+ /// The title of the year picker's toggle (tooltip).
///
- [Parameter] public bool ShowTimePicker { get; set; }
+ [Parameter] public string YearPickerToggleTitle { get; set; } = "{0}, change year";
+
+ ///
+ /// The title of the year range picker's toggle (tooltip).
+ ///
+ [Parameter] public string YearRangePickerToggleTitle { get; set; } = "{0} - {1}, change month";
protected override string RootElementClass { get; } = "bit-cal";
- protected override Task OnInitializedAsync()
+ protected override void RegisterCssClasses()
{
- _monthTitleId = $"BitCalendar-{UniqueId}-month-title";
- _activeDescendantId = $"BitCalendar-{UniqueId}-active-descendant";
+ ClassBuilder.Register(() => Classes?.Root);
- return base.OnInitializedAsync();
+ ClassBuilder.Register(() => Culture.TextInfo.IsRightToLeft ? $"{RootElementClass}-rtl" : string.Empty);
}
- protected override void RegisterCssClasses()
+ protected override void RegisterCssStyles()
{
- ClassBuilder.Register(() => Culture.TextInfo.IsRightToLeft ? $"{RootElementClass}-rtl" : string.Empty);
+ StyleBuilder.Register(() => Styles?.Root);
+ }
- ClassBuilder.Register(() => _focusClass);
+ protected override void OnInitialized()
+ {
+ _activeDescendantId = $"BitCalendar-{UniqueId}-active-descendant";
+
+ base.OnInitialized();
}
- protected override Task OnParametersSetAsync()
+ protected override void OnParametersSet()
{
- var dateTime = CurrentValue.GetValueOrDefault(DateTimeOffset.Now).DateTime;
+ var dateTime = CurrentValue.GetValueOrDefault(DateTimeOffset.Now);
- if (MinDate.HasValue && MinDate > new DateTimeOffset(dateTime))
+ if (MinDate.HasValue && MinDate > dateTime)
{
- dateTime = MinDate.GetValueOrDefault(DateTimeOffset.Now).DateTime;
+ dateTime = MinDate.GetValueOrDefault(DateTimeOffset.Now);
}
- if (MaxDate.HasValue && MaxDate < new DateTimeOffset(dateTime))
+ if (MaxDate.HasValue && MaxDate < dateTime)
{
- dateTime = MaxDate.GetValueOrDefault(DateTimeOffset.Now).DateTime;
+ dateTime = MaxDate.GetValueOrDefault(DateTimeOffset.Now);
}
timeHour = CurrentValue.HasValue ? CurrentValue.Value.Hour : 0;
timeMinute = CurrentValue.HasValue ? CurrentValue.Value.Minute : 0;
- CreateMonthCalendar(dateTime);
+ GenerateCalendarData(dateTime.DateTime);
- return base.OnParametersSetAsync();
+ base.OnParametersSet();
}
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out DateTimeOffset? result, [NotNullWhen(false)] out string? validationErrorMessage)
@@ -284,84 +308,37 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa
protected override string? FormatValueAsString(DateTimeOffset? value) =>
value.HasValue ? value.Value.ToString(DateFormat ?? Culture.DateTimeFormat.ShortDatePattern, Culture) : null;
- private async Task HandleOnChange(ChangeEventArgs e)
- {
- if (IsEnabled is false) return;
- if (ValueHasBeenSet && ValueChanged.HasDelegate is false) return;
-
- var oldValue = CurrentValue.GetValueOrDefault(DateTimeOffset.Now);
- CurrentValueAsString = e.Value?.ToString();
- var curValue = CurrentValue.GetValueOrDefault(DateTimeOffset.Now);
- if (oldValue != curValue)
- {
- CheckCurrentCalendarMatchesCurrentValue();
- if (curValue.Year != oldValue.Year)
- {
- _displayYear = curValue.Year;
- ChangeYearRanges(_currentYear - 1);
- }
- }
- await OnSelectDate.InvokeAsync(CurrentValue);
- }
- private async Task SelectDate(int dayIndex, int weekIndex)
+ private void SelectDate(int dayIndex, int weekIndex)
{
if (IsEnabled is false) return;
if (ValueHasBeenSet && ValueChanged.HasDelegate is false) return;
if (IsWeekDayOutOfMinAndMaxDate(dayIndex, weekIndex)) return;
- _currentDay = _currentMonthCalendar[weekIndex, dayIndex];
- int selectedMonth = GetCorrectTargetMonth(weekIndex, dayIndex);
- if (selectedMonth < _currentMonth && _currentMonth == 12 && IsInCurrentMonth(weekIndex, dayIndex) is false)
+ _currentDay = _daysOfCurrentMonth[weekIndex, dayIndex];
+ var selectedMonth = FindMonth(weekIndex, dayIndex);
+ var isNotInCurrentMonth = IsInCurrentMonth(weekIndex, dayIndex) is false;
+
+ if (selectedMonth < _currentMonth && _currentMonth == 12 && isNotInCurrentMonth)
{
_currentYear++;
}
- if (selectedMonth > _currentMonth && _currentMonth == 1 && IsInCurrentMonth(weekIndex, dayIndex) is false)
+ if (selectedMonth > _currentMonth && _currentMonth == 1 && isNotInCurrentMonth)
{
_currentYear--;
}
_displayYear = _currentYear;
_currentMonth = selectedMonth;
- CurrentValue = new DateTimeOffset(Culture.Calendar.ToDateTime(_currentYear, _currentMonth, _currentDay, _timeHour, _timeMinute, 0, 0), DateTimeOffset.Now.Offset);
- CreateMonthCalendar(_currentYear, _currentMonth);
- await OnSelectDate.InvokeAsync(CurrentValue);
- }
- private void HandleOnMonthChange(ChangeDirection direction)
- {
- if (IsEnabled is false) return;
- if (CanMonthChange(direction) is false) return;
+ var currentDateTime = Culture.Calendar.ToDateTime(_currentYear, _currentMonth, _currentDay, _timeHour, _timeMinute, 0, 0);
+ CurrentValue = new DateTimeOffset(currentDateTime, DateTimeOffset.Now.Offset);
- if (direction == ChangeDirection.Next)
- {
- if (_currentMonth + 1 == 13)
- {
- _currentYear++;
- _currentMonth = 1;
- }
- else
- {
- _currentMonth++;
- }
- }
- else
- {
- if (_currentMonth - 1 == 0)
- {
- _currentYear--;
- _currentMonth = 12;
- }
- else
- {
- _currentMonth--;
- }
- }
+ GenerateMonthData(_currentYear, _currentMonth);
- _displayYear = _currentYear;
- CreateMonthCalendar(_currentYear, _currentMonth);
+ _ = OnSelectDate.InvokeAsync(CurrentValue);
}
private void SelectMonth(int month)
@@ -371,10 +348,13 @@ private void SelectMonth(int month)
_currentMonth = month;
_currentYear = _displayYear;
- CreateMonthCalendar(_currentYear, _currentMonth);
- if (MonthPickerPosition == BitCalendarMonthPickerPosition.Besides) return;
- ToggleMonthPickerAsOverlay();
+ GenerateMonthData(_currentYear, _currentMonth);
+
+ if (MonthPickerPosition == BitCalendarMonthPickerPosition.Overlay)
+ {
+ ToggleMonthPickerOverlay();
+ }
}
private void SelectYear(int year)
@@ -383,8 +363,11 @@ private void SelectYear(int year)
if (IsYearOutOfMinAndMaxDate(year)) return;
_currentYear = _displayYear = year;
+
ChangeYearRanges(_currentYear - 1);
- CreateMonthCalendar(_currentYear, _currentMonth);
+
+ GenerateMonthData(_currentYear, _currentMonth);
+
ToggleBetweenMonthAndYearPicker();
}
@@ -392,32 +375,60 @@ private void ToggleBetweenMonthAndYearPicker()
{
if (IsEnabled is false) return;
- _showYearView = !_showYearView;
+ _showYearPicker = !_showYearPicker;
}
- private void HandleYearChange(ChangeDirection direction)
+ private void HandleMonthChange(bool isNext)
{
if (IsEnabled is false) return;
- if (CanYearChange(direction) is false) return;
+ if (CanChangeMonth(isNext) is false) return;
- if (direction == ChangeDirection.Next)
+ if (isNext)
{
- _displayYear++;
+ if (_currentMonth < 12)
+ {
+ _currentMonth++;
+ }
+ else
+ {
+ _currentYear++;
+ _currentMonth = 1;
+ }
}
else
{
- _displayYear--;
+ if (_currentMonth > 1)
+ {
+ _currentMonth--;
+ }
+ else
+ {
+ _currentYear--;
+ _currentMonth = 12;
+ }
}
- CreateMonthCalendar(_currentYear, _currentMonth);
+ _displayYear = _currentYear;
+
+ GenerateMonthData(_currentYear, _currentMonth);
}
- private void HandleOnYearRangeChange(ChangeDirection direction)
+ private void HandleYearChange(bool isNext)
{
if (IsEnabled is false) return;
- if (CanYearRangeChange(direction) is false) return;
+ if (CanChangeYear(isNext) is false) return;
- var fromYear = direction == ChangeDirection.Next ? _yearRangeFrom + 12 : _yearRangeFrom - 12;
+ _displayYear += isNext ? +1 : -1;
+
+ GenerateMonthData(_currentYear, _currentMonth);
+ }
+
+ private void HandleYearRangeChange(bool isNext)
+ {
+ if (IsEnabled is false) return;
+ if (CanChangeYearRange(isNext) is false) return;
+
+ var fromYear = _yearPickerStartYear + (isNext ? +12 : -12);
ChangeYearRanges(fromYear);
}
@@ -426,83 +437,94 @@ private void HandleGoToToday()
{
if (IsEnabled is false) return;
- CreateMonthCalendar(DateTime.Now);
+ GenerateCalendarData(DateTime.Now);
}
- private void CreateMonthCalendar(DateTime dateTime)
+ private void GenerateCalendarData(DateTime dateTime)
{
_currentMonth = Culture.Calendar.GetMonth(dateTime);
_currentYear = Culture.Calendar.GetYear(dateTime);
+
_displayYear = _currentYear;
- _yearRangeFrom = _currentYear - 1;
- _yearRangeTo = _currentYear + 10;
- CreateMonthCalendar(_currentYear, _currentMonth);
+ _yearPickerStartYear = _currentYear - 1;
+ _yearPickerEndYear = _currentYear + 10;
+
+ GenerateMonthData(_currentYear, _currentMonth);
}
- private void CreateMonthCalendar(int year, int month)
+ private void GenerateMonthData(int year, int month)
{
+ _selectedDateWeek = null;
+ _selectedDateDayOfWeek = null;
_monthTitle = $"{Culture.DateTimeFormat.GetMonthName(month)} {year}";
- _monthLength = Culture.Calendar.GetDaysInMonth(year, month);
- var firstDay = Culture.Calendar.ToDateTime(year, month, 1, 0, 0, 0, 0);
- var currentDay = 1;
- ResetCalendar();
- var isCalendarEnded = false;
for (int weekIndex = 0; weekIndex < DEFAULT_WEEK_COUNT; weekIndex++)
{
for (int dayIndex = 0; dayIndex < DEFAULT_DAY_COUNT_PER_WEEK; dayIndex++)
{
- if (weekIndex == 0
- && currentDay == 1
- && (int)firstDay.DayOfWeek > dayIndex + GetValueForComparison((int)firstDay.DayOfWeek))
+ _daysOfCurrentMonth[weekIndex, dayIndex] = 0;
+ }
+ }
+
+ var monthDays = Culture.Calendar.GetDaysInMonth(year, month);
+ var firstDayOfMonth = Culture.Calendar.ToDateTime(year, month, 1, 0, 0, 0, 0);
+ var startWeekDay = (int)Culture.DateTimeFormat.FirstDayOfWeek;
+ var weekDayOfFirstDay = (int)firstDayOfMonth.DayOfWeek;
+ var correctedWeekDayOfFirstDay = weekDayOfFirstDay > startWeekDay ? startWeekDay : startWeekDay - 7;
+
+ var currentDay = 1;
+ var isCurrentMonthEnded = false;
+ for (int weekIndex = 0; weekIndex < DEFAULT_WEEK_COUNT; weekIndex++)
+ {
+ for (int dayIndex = 0; dayIndex < DEFAULT_DAY_COUNT_PER_WEEK; dayIndex++)
+ {
+ if (weekIndex == 0 && currentDay == 1 && weekDayOfFirstDay > dayIndex + correctedWeekDayOfFirstDay)
{
- int previousMonth;
- int previousMonthDaysCount;
- if (month - 1 == 0)
+ int prevMonth;
+ int prevMonthDays;
+ if (month > 1)
{
- previousMonth = 12;
- previousMonthDaysCount = Culture.Calendar.GetDaysInMonth(year - 1, previousMonth);
+ prevMonth = month - 1;
+ prevMonthDays = Culture.Calendar.GetDaysInMonth(year, prevMonth);
}
else
{
- previousMonth = month - 1;
- previousMonthDaysCount = Culture.Calendar.GetDaysInMonth(year, previousMonth);
+ prevMonth = 12;
+ prevMonthDays = Culture.Calendar.GetDaysInMonth(year - 1, prevMonth);
}
- var firstDayOfWeek = (int)(Culture.DateTimeFormat.FirstDayOfWeek);
-
- if ((int)firstDay.DayOfWeek > firstDayOfWeek)
+ if (weekDayOfFirstDay > startWeekDay)
{
- _currentMonthCalendar[weekIndex, dayIndex] = previousMonthDaysCount + dayIndex - (int)firstDay.DayOfWeek + 1 + firstDayOfWeek;
+ _daysOfCurrentMonth[weekIndex, dayIndex] = prevMonthDays + dayIndex - (weekDayOfFirstDay - startWeekDay - 1);
}
else
{
- _currentMonthCalendar[weekIndex, dayIndex] = previousMonthDaysCount + dayIndex - (7 + (int)firstDay.DayOfWeek - 1 - firstDayOfWeek);
+ _daysOfCurrentMonth[weekIndex, dayIndex] = prevMonthDays + dayIndex - (7 + weekDayOfFirstDay - startWeekDay - 1);
}
}
- else if (currentDay <= _monthLength)
+ else if (currentDay <= monthDays)
{
- _currentMonthCalendar[weekIndex, dayIndex] = currentDay;
+ _daysOfCurrentMonth[weekIndex, dayIndex] = currentDay;
currentDay++;
}
- if (currentDay > _monthLength)
+ if (currentDay > monthDays)
{
currentDay = 1;
- isCalendarEnded = true;
+ isCurrentMonthEnded = true;
}
}
- if (isCalendarEnded)
+ if (isCurrentMonthEnded)
{
break;
}
}
- SetSelectedDateInMonthCalendar();
+ SetSelectedDateWeek();
}
- private void SetSelectedDateInMonthCalendar()
+ private void SetSelectedDateWeek()
{
if (Culture is null) return;
if (CurrentValue.HasValue is false || (_selectedDateWeek.HasValue && _selectedDateDayOfWeek.HasValue)) return;
@@ -512,136 +534,90 @@ private void SetSelectedDateInMonthCalendar()
if (year == _currentYear && month == _currentMonth)
{
- var day = Culture.Calendar.GetDayOfMonth(CurrentValue.Value.DateTime);
- var firstDayOfWeek = (int)Culture.DateTimeFormat.FirstDayOfWeek;
- var firstDayOfWeekInMonth = (int)Culture.Calendar.ToDateTime(year, month, 1, 0, 0, 0, 0).DayOfWeek;
- var firstDayOfWeekInMonthIndex = (firstDayOfWeekInMonth - firstDayOfWeek + DEFAULT_DAY_COUNT_PER_WEEK) % DEFAULT_DAY_COUNT_PER_WEEK;
- _selectedDateDayOfWeek = ((int)CurrentValue.Value.DayOfWeek - firstDayOfWeek + DEFAULT_DAY_COUNT_PER_WEEK) % DEFAULT_DAY_COUNT_PER_WEEK;
- var days = firstDayOfWeekInMonthIndex + day;
+ var dayOfMonth = Culture.Calendar.GetDayOfMonth(CurrentValue.Value.DateTime);
+ var startWeekDay = (int)Culture.DateTimeFormat.FirstDayOfWeek;
+ var weekDayOfFirstDay = (int)Culture.Calendar.ToDateTime(year, month, 1, 0, 0, 0, 0).DayOfWeek;
+ var indexOfWeekDayOfFirstDay = (weekDayOfFirstDay - startWeekDay + DEFAULT_DAY_COUNT_PER_WEEK) % DEFAULT_DAY_COUNT_PER_WEEK;
+
+ _selectedDateDayOfWeek = ((int)CurrentValue.Value.DayOfWeek - startWeekDay + DEFAULT_DAY_COUNT_PER_WEEK) % DEFAULT_DAY_COUNT_PER_WEEK;
+
+ var days = indexOfWeekDayOfFirstDay + dayOfMonth;
+
_selectedDateWeek = days % DEFAULT_DAY_COUNT_PER_WEEK == 0 ? (days / DEFAULT_DAY_COUNT_PER_WEEK) - 1 : days / DEFAULT_DAY_COUNT_PER_WEEK;
- if (firstDayOfWeekInMonthIndex is 0)
- {
- _selectedDateWeek++;
- }
- }
- }
- private void ResetCalendar()
- {
- for (int weekIndex = 0; weekIndex < DEFAULT_WEEK_COUNT; weekIndex++)
- {
- for (int dayIndex = 0; dayIndex < DEFAULT_DAY_COUNT_PER_WEEK; dayIndex++)
+ if (indexOfWeekDayOfFirstDay is 0)
{
- _currentMonthCalendar[weekIndex, dayIndex] = 0;
+ _selectedDateWeek++;
}
}
-
- _selectedDateWeek = null;
- _selectedDateDayOfWeek = null;
}
private void ChangeYearRanges(int fromYear)
{
- _yearRangeFrom = fromYear;
- _yearRangeTo = fromYear + 11;
+ _yearPickerStartYear = fromYear;
+ _yearPickerEndYear = fromYear + 11;
}
- private string GetDateElClass(int day, int week)
+ private bool IsInCurrentMonth(int week, int day)
{
- StringBuilder className = new StringBuilder();
- var todayYear = Culture.Calendar.GetYear(DateTime.Now);
- var todayMonth = Culture.Calendar.GetMonth(DateTime.Now);
- var todayDay = Culture.Calendar.GetDayOfMonth(DateTime.Now);
- var currentDay = _currentMonthCalendar[week, day];
-
- if (IsInCurrentMonth(week, day) is false)
- {
- className.Append(' ').Append(RootElementClass).Append("-dc-ots-m");
- }
- else if (todayYear == _currentYear && todayMonth == _currentMonth && todayDay == currentDay)
- {
- className.Append(' ').Append(RootElementClass).Append("-dc-tdy");
- }
-
- if (week == _selectedDateWeek && day == _selectedDateDayOfWeek)
- {
- className.Append(' ').Append(RootElementClass).Append("-dc-sel");
- }
-
- return className.ToString();
+ return (
+ ((week == 0 || week == 1) && _daysOfCurrentMonth[week, day] > 20) ||
+ ((week == 4 || week == 5) && _daysOfCurrentMonth[week, day] < 7)
+ ) is false;
}
- private bool IsInCurrentMonth(int week, int day) =>
- (((week == 0 || week == 1) && _currentMonthCalendar[week, day] > 20) ||
- ((week == 4 || week == 5) && _currentMonthCalendar[week, day] < 7)) is false;
-
- private int GetCorrectTargetMonth(int week, int day)
+ private int FindMonth(int week, int day)
{
int month = _currentMonth;
+
if (IsInCurrentMonth(week, day) is false)
{
if (week >= 4)
{
- month = _currentMonth + 1 == 13 ? 1 : _currentMonth + 1;
+ month = _currentMonth < 12 ? _currentMonth + 1 : 1;
}
else
{
- month = _currentMonth - 1 == 0 ? 12 : _currentMonth - 1;
+ month = _currentMonth > 1 ? _currentMonth - 1 : 12;
}
}
return month;
}
- private string GetDateAriaLabel(int week, int day)
+ private bool IsGoToTodayButtonDisabled(int todayYear, int todayMonth)
{
- int month = GetCorrectTargetMonth(week, day);
- int year = _currentYear;
- if (IsInCurrentMonth(week, day) is false)
- {
- if (_currentMonth == 12 && month == 1)
- {
- year++;
- }
- else if (_currentMonth == 1 && month == 12)
- {
- year--;
- }
- }
-
- return $"{_currentMonthCalendar[week, day]}, {Culture.DateTimeFormat.GetMonthName(month)}, {year}";
- }
-
- private bool IsMonthSelected(int month) => month == _currentMonth;
-
- private bool IsYearSelected(int year) => year == _currentYear;
-
- private bool IsGoTodayDisabled()
- {
- var todayMonth = Culture.Calendar.GetMonth(DateTime.Now);
- var todayYear = Culture.Calendar.GetYear(DateTime.Now);
-
if (MonthPickerPosition == BitCalendarMonthPickerPosition.Overlay)
{
- return (_yearRangeFrom == todayYear - 1 && _yearRangeTo == todayYear + 10 && todayMonth == _currentMonth && todayYear == _currentYear);
+ return _yearPickerStartYear == todayYear - 1
+ && _yearPickerEndYear == todayYear + 10
+ && todayMonth == _currentMonth
+ && todayYear == _currentYear;
}
else
{
- return (todayMonth == _currentMonth && todayYear == _currentYear);
+ return todayMonth == _currentMonth
+ && todayYear == _currentYear;
}
}
private DayOfWeek GetDayOfWeek(int index)
{
- int dayOfWeek = (int)(Culture.DateTimeFormat.FirstDayOfWeek) + index;
- if (dayOfWeek > 6) dayOfWeek -= 7;
+ int dayOfWeek = (int)Culture.DateTimeFormat.FirstDayOfWeek + index;
+
+ if (dayOfWeek > 6)
+ {
+ dayOfWeek -= 7;
+ }
+
return (DayOfWeek)dayOfWeek;
}
private int GetWeekNumber(int weekIndex)
{
- int month = GetCorrectTargetMonth(weekIndex, 0);
- int year = _currentYear;
+ var year = _currentYear;
+ var month = FindMonth(weekIndex, 0);
+
if (IsInCurrentMonth(weekIndex, 0) is false)
{
if (_currentMonth == 12 && month == 1)
@@ -654,23 +630,20 @@ private int GetWeekNumber(int weekIndex)
}
}
- int day = _currentMonthCalendar[weekIndex, 0];
+ int day = _daysOfCurrentMonth[weekIndex, 0];
var date = Culture.Calendar.ToDateTime(year, month, day, 0, 0, 0, 0);
+
return Culture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFullWeek, Culture.DateTimeFormat.FirstDayOfWeek);
}
- private void ToggleMonthPickerAsOverlay() => _showMonthPicker = !_showMonthPicker;
-
- private int GetValueForComparison(int firstDay)
+ private void ToggleMonthPickerOverlay()
{
- var firstDayOfWeek = (int)(Culture.DateTimeFormat.FirstDayOfWeek);
-
- return firstDay > firstDayOfWeek ? firstDayOfWeek : firstDayOfWeek - 7;
+ _showMonthPicker = !_showMonthPicker;
}
- private bool CanMonthChange(ChangeDirection direction)
+ private bool CanChangeMonth(bool isNext)
{
- if (direction == ChangeDirection.Next && MaxDate.HasValue)
+ if (isNext && MaxDate.HasValue)
{
var maxDateYear = Culture.Calendar.GetYear(MaxDate.Value.DateTime);
var maxDateMonth = Culture.Calendar.GetMonth(MaxDate.Value.DateTime);
@@ -679,7 +652,7 @@ private bool CanMonthChange(ChangeDirection direction)
}
- if (direction == ChangeDirection.Previous && MinDate.HasValue)
+ if (isNext is false && MinDate.HasValue)
{
var minDateYear = Culture.Calendar.GetYear(MinDate.Value.DateTime);
var minDateMonth = Culture.Calendar.GetMonth(MinDate.Value.DateTime);
@@ -690,18 +663,26 @@ private bool CanMonthChange(ChangeDirection direction)
return true;
}
- private bool CanYearChange(ChangeDirection direction) =>
- ((direction == ChangeDirection.Next && MaxDate.HasValue && Culture.Calendar.GetYear(MaxDate.Value.DateTime) == _displayYear) ||
- (direction == ChangeDirection.Previous && MinDate.HasValue && Culture.Calendar.GetYear(MinDate.Value.DateTime) == _displayYear)) is false;
+ private bool CanChangeYear(bool isNext)
+ {
+ return (
+ (isNext && MaxDate.HasValue && Culture.Calendar.GetYear(MaxDate.Value.DateTime) == _displayYear) ||
+ (isNext is false && MinDate.HasValue && Culture.Calendar.GetYear(MinDate.Value.DateTime) == _displayYear)
+ ) is false;
+ }
- private bool CanYearRangeChange(ChangeDirection direction) =>
- ((direction == ChangeDirection.Next && MaxDate.HasValue && Culture.Calendar.GetYear(MaxDate.Value.DateTime) < _yearRangeFrom + 12) ||
- (direction == ChangeDirection.Previous && MinDate.HasValue && Culture.Calendar.GetYear(MinDate.Value.DateTime) >= _yearRangeFrom)) is false;
+ private bool CanChangeYearRange(bool isNext)
+ {
+ return (
+ (isNext && MaxDate.HasValue && Culture.Calendar.GetYear(MaxDate.Value.DateTime) < _yearPickerStartYear + 12) ||
+ (isNext is false && MinDate.HasValue && Culture.Calendar.GetYear(MinDate.Value.DateTime) >= _yearPickerStartYear)
+ ) is false;
+ }
private bool IsWeekDayOutOfMinAndMaxDate(int dayIndex, int weekIndex)
{
- var day = _currentMonthCalendar[weekIndex, dayIndex];
- var month = GetCorrectTargetMonth(weekIndex, dayIndex);
+ var day = _daysOfCurrentMonth[weekIndex, dayIndex];
+ var month = FindMonth(weekIndex, dayIndex);
if (MaxDate.HasValue)
{
@@ -749,9 +730,11 @@ private bool IsMonthOutOfMinAndMaxDate(int month)
return false;
}
- private bool IsYearOutOfMinAndMaxDate(int year) =>
- (MaxDate.HasValue && year > Culture.Calendar.GetYear(MaxDate.Value.DateTime)) ||
- (MinDate.HasValue && year < Culture.Calendar.GetYear(MinDate.Value.DateTime));
+ private bool IsYearOutOfMinAndMaxDate(int year)
+ {
+ return (MaxDate.HasValue && year > Culture.Calendar.GetYear(MaxDate.Value.DateTime))
+ || (MinDate.HasValue && year < Culture.Calendar.GetYear(MinDate.Value.DateTime));
+ }
private void CheckCurrentCalendarMatchesCurrentValue()
{
@@ -764,38 +747,74 @@ private void CheckCurrentCalendarMatchesCurrentValue()
{
_currentYear = currentValueYear;
_currentMonth = currentValueMonth;
- CreateMonthCalendar(_currentYear, _currentMonth);
+ GenerateMonthData(_currentYear, _currentMonth);
}
}
- private string GetMonthCellClassName(int monthIndex)
+ private (string style, string klass) GetDayButtonCss(int day, int week, int todayYear, int todayMonth, int todayDay)
{
- var className = new StringBuilder();
- if (HighlightCurrentMonth)
+ StringBuilder klass = new StringBuilder();
+ StringBuilder style = new StringBuilder();
+
+ if (week == _selectedDateWeek && day == _selectedDateDayOfWeek)
{
- var todayMonth = Culture.Calendar.GetMonth(DateTime.Now);
- if (todayMonth == monthIndex)
+ klass.Append(" bit-cal-dbs");
+
+ if (Classes?.SelectedDayButton is not null)
{
- className.Append(RootElementClass).Append("-crtm");
+ klass.Append(' ').Append(Classes?.SelectedDayButton);
+ }
+
+ if (Styles?.SelectedDayButton is not null)
+ {
+ style.Append(Styles?.SelectedDayButton);
}
}
- if (HighlightSelectedMonth && _currentMonth == monthIndex)
+ if (IsInCurrentMonth(week, day) is false)
{
- if (className.Length > 0)
+ klass.Append(" bit-cal-dbo");
+ }
+
+ var currentDay = _daysOfCurrentMonth[week, day];
+ if (IsInCurrentMonth(week, day) && todayYear == _currentYear && todayMonth == _currentMonth && todayDay == currentDay)
+ {
+ klass.Append(" bit-cal-dtd");
+
+ if (Classes?.TodayDayButton is not null)
{
- className.Append(' ');
+ klass.Append(' ').Append(Classes?.TodayDayButton);
+ }
+
+ if (Styles?.TodayDayButton is not null)
+ {
+ style.Append(' ').Append(Styles?.TodayDayButton);
}
- className.Append(RootElementClass).Append("-selm");
+ }
+
+ return (style.ToString(), klass.ToString());
+ }
+
+ private string GetMonthCellCssClass(int monthIndex, int todayYear, int todayMonth)
+ {
+ var className = new StringBuilder();
+ if (HighlightCurrentMonth && todayMonth == monthIndex && todayYear == _displayYear)
+ {
+ className.Append(" bit-cal-pcm");
+ }
+
+ if (HighlightSelectedMonth && _currentMonth == monthIndex)
+ {
+ className.Append(" bit-cal-psm");
}
return className.ToString();
}
- private DateTimeOffset GetDayCellDate(int dayIndex, int weekIndex)
+ private DateTimeOffset GetDateTimeOfDayCell(int dayIndex, int weekIndex)
{
- int selectedMonth = GetCorrectTargetMonth(weekIndex, dayIndex);
- var currentDay = _currentMonthCalendar[weekIndex, dayIndex];
+ int selectedMonth = FindMonth(weekIndex, dayIndex);
+ var currentDay = _daysOfCurrentMonth[weekIndex, dayIndex];
var currentYear = _currentYear;
if (selectedMonth < _currentMonth && _currentMonth == 12 && IsInCurrentMonth(weekIndex, dayIndex) is false)
{
@@ -810,8 +829,10 @@ private DateTimeOffset GetDayCellDate(int dayIndex, int weekIndex)
return new DateTimeOffset(Culture.Calendar.ToDateTime(currentYear, selectedMonth, currentDay, 0, 0, 0, 0), DateTimeOffset.Now.Offset);
}
- private DateTimeOffset GetMonthCellDate(int monthIndex)
- => new(Culture.Calendar.ToDateTime(_currentYear, monthIndex, 1, 0, 0, 0, 0), DateTimeOffset.Now.Offset);
+ private DateTimeOffset GetDateTimeOfMonthCell(int monthIndex)
+ {
+ return new(Culture.Calendar.ToDateTime(_currentYear, monthIndex, 1, 0, 0, 0, 0), DateTimeOffset.Now.Offset);
+ }
private void UpdateTime()
{
@@ -820,6 +841,7 @@ private void UpdateTime()
var currentValueYear = Culture.Calendar.GetYear(CurrentValue.Value.LocalDateTime);
var currentValueMonth = Culture.Calendar.GetMonth(CurrentValue.Value.LocalDateTime);
var currentValueDay = Culture.Calendar.GetDayOfMonth(CurrentValue.Value.LocalDateTime);
+
CurrentValue = new DateTimeOffset(Culture.Calendar.ToDateTime(currentValueYear, currentValueMonth, currentValueDay, _timeHour, _timeMinute, 0, 0), DateTimeOffset.Now.Offset);
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.scss b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.scss
index 80e8bddde1..e0ad94c74c 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.scss
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.scss
@@ -6,35 +6,35 @@
box-shadow: none;
font-weight: 400;
position: relative;
+ max-width: fit-content;
box-sizing: border-box;
font-size: spacing(2.25);
font-family: $typography-font-family;
&.bit-dis {
- .bit-cal-ctn {
+ .bit-cal-cnt {
user-select: none;
pointer-events: none;
-webkit-user-select: none;
}
- .bit-cal-pkr-tit,
- .bit-cal-nav-btn,
- .bit-cal-wd-lbl,
- .bit-cal-dbtn,
- .bit-cal-rbtn,
- .bit-cal-dc {
+ .bit-cal-pkt,
+ .bit-cal-nbt,
+ .bit-cal-wlb,
+ .bit-cal-dbt,
+ .bit-cal-pkb,
+ .bit-cal-ptb {
color: $color-foreground-disabled;
}
- .bit-cal-dc-tdy {
- .bit-cal-dbtn {
- background-color: $color-background-disabled;
- }
+ .bit-cal-dbt.bit-cal-dtd {
+ background-color: $color-background-disabled;
}
}
}
-.bit-cal-ctn {
+.bit-cal-cnt {
+ display: flex;
font-weight: 400;
top: spacing(4.25);
outline: transparent;
@@ -44,25 +44,7 @@
font-family: $typography-font-family;
}
-
-.bit-cal-mcal {
- outline: none;
- position: relative;
- overflow: hidden auto;
- border-radius: $shape-border-radius;
- background-color: $color-background-primary;
-}
-
-.bit-cal-grp {
- margin: 0;
- padding: 0;
- display: flex;
- outline: none;
- box-shadow: none;
- box-sizing: border-box;
-}
-
-.bit-cal-sd {
+.bit-cal-sdt {
height: 0;
border: 0;
margin: 0;
@@ -80,29 +62,29 @@
box-sizing: content-box;
min-width: spacing(24.5);
flex-flow: column nowrap;
+}
- table {
- border-spacing: 0;
- position: relative;
- text-align: center;
- font-size: inherit;
- table-layout: fixed;
- margin-top: spacing(0.5);
- border-collapse: collapse;
- }
+.bit-cal-dgd {
+ border-spacing: 0;
+ position: relative;
+ text-align: center;
+ font-size: inherit;
+ table-layout: fixed;
+ margin-top: spacing(0.5);
+ border-collapse: collapse;
+}
- tr {
- width: 100%;
- display: flex;
- flex-flow: row nowrap;
- }
+.bit-cal-dgh,
+.bit-cal-dgr {
+ width: 100%;
+ display: flex;
+ flex-flow: row nowrap;
}
-.bit-cal-wd-lbl {
+.bit-cal-wlb {
margin: 0;
padding: 0;
border: none;
- cursor: pointer;
font-weight: 400;
position: relative;
text-align: center;
@@ -117,80 +99,44 @@
animation-timing-function: cubic-bezier(0.1, 0.25, 0.75, 0.9);
}
-.bit-cal-dc {
- margin: 0;
- padding: 0;
- border: none;
- cursor: pointer;
- font-weight: 400;
- position: relative;
- text-align: center;
- font-size: spacing(1.5);
- line-height: spacing(3.5);
- color: $color-foreground-primary;
- border-radius: $shape-border-radius;
-
- @media (hover: hover) {
- &:hover {
- background-color: $color-action-hover-background-primary;
- }
- }
-}
-
-.bit-cal-dbtn {
+.bit-cal-dbt {
padding: 0;
border: none;
display: flex;
- color: inherit;
cursor: pointer;
overflow: visible;
position: relative;
+ width: spacing(3.5);
+ align-items: center;
+ height: spacing(3.5);
outline: transparent;
font-weight: inherit;
box-sizing: border-box;
font-size: spacing(1.5);
line-height: spacing(3);
+ justify-content: center;
background-color: transparent;
+ color: $color-foreground-primary;
border-radius: $shape-border-radius;
- &:disabled {
- pointer-events: none;
- color: $color-foreground-disabled;
- background-color: transparent;
+ @media (hover: hover) {
+ &:hover {
+ background-color: $color-action-hover-background-primary;
+ }
}
- span {
- align-items: center;
- width: spacing(3.5);
- height: spacing(3.5);
- display: inline-flex;
- justify-content: center;
+ &:active {
+ background-color: $color-action-active-background-primary;
}
-}
-.bit-cal-dc-ots-m {
- .bit-cal-dbtn {
- font-weight: 400;
- color: $color-foreground-secondary;
- }
-}
-
-.bit-cal-dc-tdy {
- .bit-cal-dbtn {
- font-weight: 600;
- border-radius: 50%;
- color: $color-primary-text;
- background-color: $color-primary-main;
-
- @media(hover: hover) {
- &:hover {
- background-color: $color-action-hover-primary;
- }
- }
+ &:disabled {
+ pointer-events: none;
+ background-color: transparent;
+ color: $color-foreground-disabled;
}
}
-.bit-cal-dc-sel {
+.bit-cal-dbs {
background-color: $color-background-secondary;
&::after {
@@ -201,7 +147,29 @@
}
}
-.bit-cal-wnumc {
+.bit-cal-dbo {
+ font-weight: 400;
+ color: $color-foreground-secondary;
+}
+
+.bit-cal-dtd {
+ font-weight: 600;
+ border-radius: 50%;
+ color: $color-primary-text;
+ background-color: $color-primary-main;
+
+ @media(hover: hover) {
+ &:hover {
+ background-color: $color-action-hover-primary;
+ }
+ }
+
+ &:active {
+ background-color: $color-action-active-primary;
+ }
+}
+
+.bit-cal-wnm {
margin: 0;
display: flex;
font-weight: 400;
@@ -217,25 +185,16 @@
border-right: $shape-border-width $shape-border-style $color-border-secondary;
}
-.bit-cal-pkr-hdr {
+.bit-cal-pkh {
width: 100%;
position: relative;
height: spacing(3.5);
display: inline-flex;
line-height: spacing(5.5);
-
- button.bit-cal-pkr-tit {
- cursor: pointer;
-
- @media (hover: hover) {
- &:hover {
- background-color: $color-action-hover-background-primary;
- }
- }
- }
}
-.bit-cal-pkr-tit {
+.bit-cal-pkt,
+.bit-cal-ptb {
margin: 0;
border: none;
flex-grow: 1;
@@ -261,53 +220,24 @@
animation-timing-function: cubic-bezier(0.1, 0.25, 0.75, 0.9);
}
-.bit-cal-nav-btn-ctn {
- display: flex;
- align-items: center;
- align-self: flex-end;
-}
-
-.bit-cal-nav-btn {
- padding: 0;
- border: none;
- display: block;
+.bit-cal-ptb {
cursor: pointer;
- overflow: visible;
- position: relative;
- text-align: center;
- width: spacing(3.5);
- height: spacing(3.5);
- outline: transparent;
- min-width: spacing(3.5);
- font-size: spacing(1.5);
- min-height: spacing(3.5);
- line-height: spacing(3.5);
- background-color: transparent;
- color: $color-foreground-primary;
- border-radius: $shape-border-radius;
@media (hover: hover) {
&:hover {
background-color: $color-action-hover-background-primary;
}
}
+}
- i {
- speak: none;
- display: inline-block;
- }
-
- &:disabled {
- pointer-events: none;
- background-color: transparent;
-
- i {
- color: $color-foreground-disabled;
- }
- }
+.bit-cal-nbc {
+ display: flex;
+ align-items: center;
+ align-self: flex-end;
}
-.bit-cal-hdr-ibtn {
+.bit-cal-nbt,
+.bit-cal-gtb {
padding: 0;
border: none;
display: block;
@@ -332,14 +262,17 @@
}
}
- span {
- i {
- font-size: spacing(1.5);
+ &:disabled {
+ pointer-events: none;
+ background-color: transparent;
+
+ .bit-cal-gti {
+ color: $color-foreground-disabled;
}
}
}
-.bit-cal-div {
+.bit-cal-dvd {
top: 0;
border-right: $shape-border-width $shape-border-style $color-border-secondary;
}
@@ -355,22 +288,17 @@
flex-flow: column nowrap;
}
-.bit-cal-gctn {
- margin-top: spacing(0.5);
- margin-bottom: spacing(1.5);
-}
-
-.bit-cal-btn-row {
+.bit-cal-pkr {
display: flex;
+ gap: spacing(0.5);
margin-bottom: spacing(2);
- justify-content: space-evenly;
&:last-child {
margin: 0;
}
}
-.bit-cal-rbtn {
+.bit-cal-pkb {
border: none;
cursor: pointer;
overflow: hidden;
@@ -395,43 +323,42 @@
&:disabled {
pointer-events: none;
- color: $color-foreground-disabled;
background-color: transparent;
+ color: $color-foreground-disabled;
}
}
-.bit-cal-crtm {
- color: $color-primary-text;
- background-color: $color-primary-main;
+.bit-cal-psm {
+ font-weight: 600;
+ background-color: $color-background-secondary;
@media (hover: hover) {
&:hover {
- color: $color-action-hover-secondary;
- background-color: $color-action-hover-primary;
+ background-color: $color-action-hover-background-primary;
}
}
}
-.bit-cal-selm {
- font-weight: 600;
+.bit-cal-pcm {
color: $color-primary-text;
background-color: $color-primary-main;
@media (hover: hover) {
&:hover {
+ color: $color-action-hover-secondary;
background-color: $color-action-hover-primary;
}
}
}
-.bit-cal-time-grp {
+.bit-cal-tgp {
display: flex;
align-items: center;
justify-content: center;
padding-bottom: spacing(0.5);
}
-.bit-cal-time-wrp {
+.bit-cal-twp {
display: flex;
align-items: center;
justify-content: center;
@@ -445,11 +372,11 @@
}
}
-.bit-cal-tdiv {
+.bit-cal-tdv {
display: block;
}
-.bit-cal-tinp {
+.bit-cal-tin {
border: none;
display: flex;
cursor: pointer;
@@ -459,10 +386,10 @@
height: spacing(3.75);
box-sizing: border-box;
justify-content: center;
- -moz-appearance: textfield; // Firefox
+ -moz-appearance: textfield;
background-color: $color-background-primary;
- &::-webkit-inner-spin-button, // Chrome, Safari, Edge, Opera
+ &::-webkit-inner-spin-button,
&::-webkit-outer-spin-button {
-webkit-appearance: none
}
@@ -473,97 +400,23 @@
}
}
-.bit-cal-gtd-btn {
- border: none;
- overflow: visible;
- position: relative;
- bottom: spacing(-2);
- outline: transparent;
- align-self: flex-end;
- height: spacing(3.75);
- padding: 0 spacing(0.5);
- font-size: spacing(1.5);
- box-sizing: content-box;
- line-height: spacing(3.75);
- background-color: transparent;
- color: $color-foreground-primary;
- margin: spacing(0.375) spacing(0.5) 0 0;
-
- @media (hover: hover) {
- &:hover {
- cursor: pointer;
- background-color: transparent;
- color: $color-action-hover-primary;
- }
- }
-
- &:disabled {
- pointer-events: none;
- color: $color-foreground-disabled;
- }
-}
-
-.bit-cal-ovl {
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- display: none;
- position: fixed;
- z-index: $zindex-overlay;
- background-color: transparent;
-}
-
-.bit-cal-und {
- .bit-cal-wrp {
- width: 100%;
- display: flex;
- border-bottom: $shape-border-width $shape-border-style $color-border-primary;
- }
-
- .bit-cal-fld-grp {
- border: none;
- flex: 1 1 0px;
- text-align: left;
- }
-
- &.bit-dis {
- .bit-cal-wrp {
- border-bottom-color: $color-border-disabled;
- }
- }
-
- &.bit-cal-foc {
- .bit-cal-fld-grp::after {
- border: none;
- border-radius: 0;
- border-bottom: spacing(0.25) $shape-border-style $color-border-primary;
- }
- }
-}
-
-.bit-cal-no-brd {
- .bit-cal-fld-grp {
- border: none;
- }
-}
-
.bit-cal-rtl {
- .bit-cal-grp {
+ .bit-cal-cnt {
direction: rtl;
}
- .bit-cal-wnumc {
+ .bit-cal-wnm {
border-right: none;
border-left: $shape-border-width $shape-border-style $color-border-secondary;
}
- .bit-cal-pkr-tit {
+ .bit-cal-pkt,
+ .bit-cal-ptb {
text-align: right;
padding: 0 spacing(1.25) 0 spacing(0.5);
}
- .bit-cal-time-wrp {
+ .bit-cal-twp {
flex-direction: row-reverse;
}
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarClassStyles.cs
new file mode 100644
index 0000000000..043e9f4a1a
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarClassStyles.cs
@@ -0,0 +1,224 @@
+namespace Bit.BlazorUI;
+
+public class BitCalendarClassStyles
+{
+ ///
+ /// Custom CSS classes/styles for the root element of the BitCalendar.
+ ///
+ public string? Root { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the main container of the BitCalendar.
+ ///
+ public string? Container { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the day-picker's wrapper of the BitCalendar.
+ ///
+ public string? DayPickerWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the day-picker's header of the BitCalendar.
+ ///
+ public string? DayPickerHeader { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the day-picker's month of the BitCalendar.
+ ///
+ public string? DayPickerMonth { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the wrapper of the day-picker's nav buttons of the BitCalendar.
+ ///
+ public string? DayPickerNavWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous month button of the BitCalendar.
+ ///
+ public string? PrevMonthNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous month icon of the BitCalendar.
+ ///
+ public string? PrevMonthNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to today button of the BitCalendar.
+ ///
+ public string? GoToTodayButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to today icon of the BitCalendar.
+ ///
+ public string? GoToTodayIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next month button of the BitCalendar.
+ ///
+ public string? NextMonthNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next month icon of the BitCalendar.
+ ///
+ public string? NextMonthNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the header row of the days of the BitCalendar.
+ ///
+ public string? DaysHeaderRow { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the header of the week numbers of the BitCalendar.
+ ///
+ public string? WeekNumbersHeader { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each row of the days of the BitCalendar.
+ ///
+ public string? DaysRow { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the week number of the BitCalendar.
+ ///
+ public string? WeekNumber { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each day button of the BitCalendar.
+ ///
+ public string? DayButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for today day button of the BitCalendar.
+ ///
+ public string? TodayDayButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for selected day button of the BitCalendar.
+ ///
+ public string? SelectedDayButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the time-picker's main container of the BitCalendar.
+ ///
+ public string? TimePickerContainer { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the time-picker's wrapper of the BitCalendar.
+ ///
+ public string? TimePickerWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the time-picker's hour input of the BitCalendar.
+ ///
+ public string? TimePickerHourInput { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the time-picker's divider of the BitCalendar.
+ ///
+ public string? TimePickerDivider { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the time-picker's minute input of the BitCalendar.
+ ///
+ public string? TimePickerMinuteInput { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the main divider of the BitCalendar.
+ ///
+ public string? Divider { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the year-month-picker's wrapper of the BitCalendar.
+ ///
+ public string? YearMonthPickerWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the month-picker's header of the BitCalendar.
+ ///
+ public string? MonthPickerHeader { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the year-picker's toggle button of the BitCalendar.
+ ///
+ public string? YearPickerToggleButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the wrapper of the month-picker's nav buttons of the BitCalendar.
+ ///
+ public string? MonthPickerNavWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous year button of the BitCalendar.
+ ///
+ public string? PrevYearNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous year icon of the BitCalendar.
+ ///
+ public string? PrevYearNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next year button of the BitCalendar.
+ ///
+ public string? NextYearNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next year icon of the BitCalendar.
+ ///
+ public string? NextYearNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each row of the months of the BitCalendar.
+ ///
+ public string? MonthsRow { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each month button of the BitCalendar.
+ ///
+ public string? MonthButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the year-picker's header of the BitCalendar.
+ ///
+ public string? YearPickerHeader { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the month-picker's toggle button of the BitCalendar.
+ ///
+ public string? MonthPickerToggleButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the wrapper of the year-picker nav buttons of the BitCalendar.
+ ///
+ public string? YearPickerNavWrapper { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous year-range button of the BitCalendar.
+ ///
+ public string? PrevYearRangeNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to previous year-range icon of the BitCalendar.
+ ///
+ public string? PrevYearRangeNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next year-range button of the BitCalendar.
+ ///
+ public string? NextYearRangeNavButton { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for the Go to next year-range icon of the BitCalendar.
+ ///
+ public string? NextYearRangeNavIcon { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each row of the years of the BitCalendar.
+ ///
+ public string? YearsRow { get; set; }
+
+ ///
+ /// Custom CSS classes/styles for each year button of the BitCalendar.
+ ///
+ public string? YearButton { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarMonthPickerPosition.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarMonthPickerPosition.cs
index 5ef82f1b87..158167ffca 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarMonthPickerPosition.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendarMonthPickerPosition.cs
@@ -3,7 +3,7 @@
public enum BitCalendarMonthPickerPosition
{
///
- /// Show the month picker at the beside.
+ /// Show the month picker besides the calendar.
///
Besides,
///
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
index 079a56ee37..a4c80ec122 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
@@ -30,11 +30,16 @@
- @foreach (var item in _items)
+ @for (var i = 0; i < _items.Count; i++)
{
+ var index = i;
+ var item = _items[i];
+ SetIndex(item, index);
+
var inputId = GetInputId(item);
- var isChecked = GetIsCheckedItem(item);
var template = GetTemplate(item);
+ var prefix = GetPrefix(item);
+ var isChecked = GetIsCheckedItem(item);
@@ -48,6 +53,15 @@
}
else
{
+ @if (prefix is not null)
+ {
+ @prefix
+ }
+ else if (ItemPrefixTemplate is not null)
+ {
+ @ItemPrefixTemplate(item)
+ }
+
@if (ItemLabelTemplate is not null)
{
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
index 7e7f4e4c4a..cc22ca7453 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
@@ -41,6 +41,11 @@ public partial class BitChoiceGroup where TItem : class
///
[Parameter] public RenderFragment? ItemLabelTemplate { get; set; }
+ ///
+ /// Used to add a prefix to each item.
+ ///
+ [Parameter] public RenderFragment? ItemPrefixTemplate { get; set; }
+
///
/// Used to customize the label for the Item content.
///
@@ -181,6 +186,94 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa
=> throw new NotSupportedException($"This component does not parse string inputs. Bind to the '{nameof(CurrentValue)}' property, not '{nameof(CurrentValueAsString)}'.");
+
+ private string? GetInputId(TItem item) => GetId(item) ?? $"ChoiceGroup-{UniqueId}-Input-{GetValue(item)}";
+
+ private bool GetIsCheckedItem(TItem item)
+ {
+ if (CurrentValue is null) return false;
+
+ return EqualityComparer.Default.Equals(GetValue(item), CurrentValue);
+ }
+
+ private bool ItemValueEqualityComparer(TItem item, TValue? value)
+ {
+ var itemValue = GetValue(item);
+
+ if (itemValue is null) return false;
+
+ return EqualityComparer.Default.Equals(itemValue, value);
+ }
+
+ private async Task HandleClick(TItem item)
+ {
+ if (IsEnabled is false || GetIsEnabled(item) is false) return;
+
+ await OnClick.InvokeAsync(item);
+ }
+
+ private async Task HandleChange(TItem item)
+ {
+ if (IsEnabled is false || GetIsEnabled(item) is false) return;
+
+ var oldValue = CurrentValue;
+ CurrentValue = GetValue(item);
+
+ await OnChange.InvokeAsync(new(oldValue, CurrentValue));
+ }
+
+ private string GetAriaLabelledBy() => AriaLabelledBy ?? _labelId;
+
+ private string? GetLayoutFlowClass() => LayoutFlow switch
+ {
+ BitLayoutFlow.Horizontal => "horizontal",
+ BitLayoutFlow.Vertical => "vertical",
+ _ => null
+ };
+
+ private string GetItemContainerCssClasses(TItem item)
+ {
+ StringBuilder cssClass = new(RootElementClass);
+ cssClass.Append("-icn");
+
+ if (ItemTemplate is not null) return cssClass.ToString();
+
+ if (GetIsCheckedItem(item))
+ {
+ cssClass.Append(' ')
+ .Append(RootElementClass)
+ .Append("-ich");
+ }
+
+ if (ItemLabelTemplate is not null) return cssClass.ToString();
+
+ if (IsEnabled is false || GetIsEnabled(item) is false)
+ {
+ cssClass.Append(' ')
+ .Append(RootElementClass)
+ .Append("-ids");
+ }
+
+ if (GetImageSrc(item).HasValue() || GetIconName(item).HasValue())
+ {
+ cssClass.Append(' ')
+ .Append(RootElementClass)
+ .Append("-ihi");
+ }
+
+ return cssClass.ToString();
+ }
+
+ private string GetItemLabelWrapperCssClasses(TItem item)
+ {
+ var hasImageOrIcon = GetImageSrc(item).HasValue() || GetIconName(item).HasValue();
+ return hasImageOrIcon && ItemLabelTemplate is null
+ ? "bit-chg-ilwi"
+ : "bit-chg-ilw";
+ }
+
+
+
private string? GetAriaLabel(TItem item)
{
if (item is BitChoiceGroupItem choiceGroupItem)
@@ -357,6 +450,28 @@ private BitSize GetImageSize(TItem item)
return item.GetValueFromProperty(NameSelectors.ImageSize.Name) ?? new BitSize(0, 0);
}
+ private string? GetPrefix(TItem item)
+ {
+ if (item is BitChoiceGroupItem choiceGroupItem)
+ {
+ return choiceGroupItem.Prefix;
+ }
+
+ if (item is BitChoiceGroupOption choiceGroupOption)
+ {
+ return choiceGroupOption.Prefix;
+ }
+
+ if (NameSelectors is null) return null;
+
+ if (NameSelectors.Prefix.Selector is not null)
+ {
+ return NameSelectors.Prefix.Selector!(item);
+ }
+
+ return item.GetValueFromProperty(NameSelectors.Prefix.Name);
+ }
+
private string? GetSelectedImageSrc(TItem item)
{
if (item is BitChoiceGroupItem choiceGroupItem)
@@ -467,88 +582,21 @@ private BitSize GetImageSize(TItem item)
return item.GetValueFromProperty(NameSelectors.Value.Name);
}
- private string? GetInputId(TItem item) => GetId(item) ?? $"ChoiceGroup-{UniqueId}-Input-{GetValue(item)}";
-
- private bool GetIsCheckedItem(TItem item)
- {
- if (CurrentValue is null) return false;
-
- return EqualityComparer.Default.Equals(GetValue(item), CurrentValue);
- }
-
- private bool ItemValueEqualityComparer(TItem item, TValue? value)
- {
- var itemValue = GetValue(item);
-
- if (itemValue is null) return false;
-
- return EqualityComparer.Default.Equals(itemValue, value);
- }
-
- private async Task HandleClick(TItem item)
- {
- if (IsEnabled is false || GetIsEnabled(item) is false) return;
-
- await OnClick.InvokeAsync(item);
- }
-
- private async Task HandleChange(TItem item)
- {
- if (IsEnabled is false || GetIsEnabled(item) is false) return;
-
- var oldValue = CurrentValue;
- CurrentValue = GetValue(item);
-
- await OnChange.InvokeAsync(new(oldValue, CurrentValue));
- }
-
- private string GetAriaLabelledBy() => AriaLabelledBy ?? _labelId;
- private string? GetLayoutFlowClass() => LayoutFlow switch
+ private void SetIndex(TItem item, int value)
{
- BitLayoutFlow.Horizontal => "horizontal",
- BitLayoutFlow.Vertical => "vertical",
- _ => null
- };
-
- private string GetItemContainerCssClasses(TItem item)
- {
- StringBuilder cssClass = new(RootElementClass);
- cssClass.Append("-icn");
-
- if (ItemTemplate is not null) return cssClass.ToString();
-
- if (GetIsCheckedItem(item))
- {
- cssClass.Append(' ')
- .Append(RootElementClass)
- .Append("-ich");
- }
-
- if (ItemLabelTemplate is not null) return cssClass.ToString();
-
- if (IsEnabled is false || GetIsEnabled(item) is false)
+ if (item is BitChoiceGroupItem choiceGroupItem)
{
- cssClass.Append(' ')
- .Append(RootElementClass)
- .Append("-ids");
+ choiceGroupItem.Index = value;
}
- if (GetImageSrc(item).HasValue() || GetIconName(item).HasValue())
+ if (item is BitChoiceGroupOption choiceGroupOption)
{
- cssClass.Append(' ')
- .Append(RootElementClass)
- .Append("-ihi");
+ choiceGroupOption.Index = value;
}
- return cssClass.ToString();
- }
+ if (NameSelectors is null) return;
- private string GetItemLabelWrapperCssClasses(TItem item)
- {
- var hasImageOrIcon = GetImageSrc(item).HasValue() || GetIconName(item).HasValue();
- return (hasImageOrIcon) && ItemLabelTemplate is null
- ? "bit-chg-ilwi"
- : "bit-chg-ilw";
+ item.SetValueToProperty(NameSelectors.Index, value);
}
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
index f543e633dc..f0a3732528 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
@@ -88,6 +88,9 @@
}
.bit-chg-ilw {
+ padding-left: 0;
+ padding-right: spacing(3.25);
+
&::before {
right: 0;
}
@@ -99,11 +102,6 @@
}
}
}
-
- .bit-chg-itx {
- padding-left: 0;
- padding-right: spacing(3.25);
- }
}
.bit-chg-ich {
@@ -169,6 +167,7 @@
vertical-align: top;
display: inline-block;
min-height: spacing(2.5);
+ padding-left: spacing(3.25);
&:before {
top: 0;
@@ -279,7 +278,6 @@
.bit-chg-itx {
display: inline-block;
- padding-left: spacing(3.25);
}
.bit-chg-itw {
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
index 80d1238a88..a695ec15ef 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
@@ -72,6 +72,11 @@ public class BitChoiceGroupClassStyles
///
public string? ItemIcon { get; set; }
+ ///
+ /// Custom CSS classes/styles for the prefix of each item of the BitChoiceGroup.
+ ///
+ public string? ItemPrefix { get; set; }
+
///
/// Custom CSS classes/styles for the text wrapper of each item of the BitChoiceGroup.
///
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
index 5b4ab1b54c..25613d41c3 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
@@ -42,6 +42,11 @@ public class BitChoiceGroupItem
///
public BitSize? ImageSize { get; set; }
+ ///
+ /// The text to show as a prefix for the BitChoiceGroup item.
+ ///
+ public string? Prefix { get; set; }
+
///
/// Provides a new image for the selected state of the image of the BitChoiceGroup item.
///
@@ -66,4 +71,11 @@ public class BitChoiceGroupItem
/// The value returned when BitChoiceGroup item is checked.
///
public TValue? Value { get; set; }
+
+
+
+ ///
+ /// Index of the BitChoiceGroup item. This property's value is set by the component at render.
+ ///
+ public int Index { get; internal set; }
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
index 35b3030f92..50ef78f226 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
@@ -42,6 +42,11 @@ public class BitChoiceGroupNameSelectors
///
public BitNameSelectorPair ImageSize { get; set; } = new(nameof(BitChoiceGroupItem.ImageSize));
+ ///
+ /// The Prefix field name and selector of the custom input class.
+ ///
+ public BitNameSelectorPair Prefix { get; set; } = new(nameof(BitChoiceGroupItem.Prefix));
+
///
/// The SelectedImageSrc field name and selector of the custom input class.
///
@@ -66,4 +71,11 @@ public class BitChoiceGroupNameSelectors
/// The Value field name and selector of the custom input class.
///
public BitNameSelectorPair Value { get; set; } = new(nameof(BitChoiceGroupItem.Value));
+
+
+
+ ///
+ /// The Index field name of the custom input class. This property's value is set by the component at render.
+ ///
+ public string Index { get; set; } = nameof(BitChoiceGroupItem.Index);
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
similarity index 89%
rename from src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.razor.cs
rename to src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
index 7c1e7a5cec..5e6305fc67 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
@@ -46,6 +46,11 @@ public partial class BitChoiceGroupOption : ComponentBase, IDisposable
///
[Parameter] public BitSize? ImageSize { get; set; }
+ ///
+ /// The text to show as a prefix for the BitChoiceGroup option.
+ ///
+ [Parameter] public string? Prefix { get; set; }
+
///
/// Provides a new image for the selected state of the image of the BitChoiceGroup option.
///
@@ -73,6 +78,13 @@ public partial class BitChoiceGroupOption : ComponentBase, IDisposable
+ ///
+ /// Index of the BitChoiceGroup option. This property's value is set by the component at render.
+ ///
+ public int Index { get; internal set; }
+
+
+
protected override async Task OnInitializedAsync()
{
Parent.RegisterOption(this);
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/DatePicker/BitDatePicker.razor b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/DatePicker/BitDatePicker.razor
index 352d001433..981edb2314 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/DatePicker/BitDatePicker.razor
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/DatePicker/BitDatePicker.razor
@@ -8,18 +8,19 @@
@if (LabelTemplate is not null)
{
-
+
@LabelTemplate
}
else if (Label.HasValue())
{
-
+
@Label
}
-
-
+
+
+
-
+ aria-labelledby="@((LabelTemplate is not null || Label.HasValue()) ? _labelId : null)"
+ style="@Styles?.Input"
+ class="bit-dtp-inp@(AllowTextInput ? " bit-dtp-ein" : null) @Classes?.Input" />
@if (IconTemplate is not null)
{
@IconTemplate
}
else
{
-
+
}
- @for (var week = 0; week < 6; week++)
+ @for (var index = 0; index < 7; index++)
+ {
+ var dayOfWeekName = Culture.DateTimeFormat.GetShortestDayName(GetDayOfWeek(index));
+
+ @dayOfWeekName[0]
+
+ }
+
+
+ @for (var week = 0; week < 6; week++)
+ {
+ //to ignore the last empty week out of month || to ignore the first whole week out of month
+ if (_daysOfCurrentMonth[week, 0] == 0 || (week == 0 && _daysOfCurrentMonth[week, 6] > 20)) continue;
+
+
+ @if (ShowWeekNumbers)
{
- //to ignore the last empty week out of month || to ignore the first whole week out of month
- if (_currentMonthCalendar[week, 0] == 0 || (week == 0 && _currentMonthCalendar[week, 6] > 20))
- {
- continue;
- }
+ var weekNumber = GetWeekNumber(week);
+ var title = string.Format(WeekNumberTitle, weekNumber);
+
+ @weekNumber
+
+ }
-
- @if (ShowWeekNumbers)
+ @for (var day = 0; day < 7; day++)
+ {
+ var w = week;
+ var d = day;
+ var disabled = IsWeekDayOutOfMinAndMaxDate(d, w);
+ var (style, klass) = GetDayButtonCss(d, w, todayYear, todayMonth, todayDay);
+ SelectDate(d, w)"
+ type="button"
+ role="gridcell"
+ style="@style @Styles?.DayButton"
+ class="bit-dtp-dbt@(klass) @Classes?.DayButton"
+ aria-readonly="true"
+ disabled="@disabled"
+ aria-disabled="@disabled"
+ tabindex="@(week == _selectedDateWeek && day == _selectedDateDayOfWeek ? 0 : -1)"
+ aria-selected="@(week == _selectedDateWeek && day == _selectedDateDayOfWeek ? "true" : "false")">
+ @if (DayCellTemplate is not null)
{
-
- @GetWeekNumber(week)
-
+ @DayCellTemplate(GetDateTimeOfDayCell(d, w))
}
-
- @for (var day = 0; day < 7; day++)
+ else
{
- var localWeek = week;
- var localDay = day;
-
- @for (var week = 0; week < 6; week++)
+ @for (var index = 0; index < 7; index++)
+ {
+ var dayOfWeekName = Culture.DateTimeFormat.GetShortestDayName(GetDayOfWeek(index));
+
+ @dayOfWeekName[0]
+
+ }
+
+ @for (var week = 0; week < 6; week++)
+ {
+ //to ignore the last empty week out of month || to ignore the first whole week out of month
+ if (_daysOfCurrentMonth[week, 0] == 0 || (week == 0 && _daysOfCurrentMonth[week, 6] > 20)) continue;
+
+
+ @if (ShowWeekNumbers)
{
- //to ignore the last empty week out of month || to ignore the first whole week out of month
- if (_currentMonthCalendar[week, 0] == 0 || (week == 0 && _currentMonthCalendar[week, 6] > 20))
- {
- continue;
- }
+ var weekNumber = GetWeekNumber(week);
+ var title = string.Format(WeekNumberTitle, weekNumber);
+
+ @weekNumber
+
+ }
-
- @if (ShowWeekNumbers)
+ @for (var day = 0; day < 7; day++)
+ {
+ var w = week;
+ var d = day;
+ var disabled = IsWeekDayOutOfMinAndMaxDate(d, w);
+ var klass = GetDayButtonCss(d, w, todayYear, todayMonth, todayDay);
+ var isSelected = (w == _selectedStartDateWeek && d == _selectedStartDateDayOfWeek) || (w == _selectedEndDateWeek && d == _selectedEndDateDayOfWeek);
+ SelectDate(d, w)"
+ type="button"
+ role="gridcell"
+ aria-readonly="true"
+ class="bit-dtrp-dbt@(klass)"
+ disabled="@disabled"
+ aria-disabled="@disabled"
+ tabindex="@(isSelected ? 0 : -1)"
+ aria-selected="@(isSelected ? "true" : "false")">
+ @if (DayCellTemplate is not null)
{
-
- @GetWeekNumber(week)
-
+ @DayCellTemplate(GetDateTimeOfDayCell(d, w))
}
-
- @for (var day = 0; day < 7; day++)
+ else
{
- var localWeek = week;
- var localDay = day;
-
@@ -186,7 +186,7 @@
{
@if (iconName.HasValue())
{
-
+
}
@text
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Nav/_BitNavChild.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Nav/_BitNavChild.razor.cs
index 20b3036eae..7893fe816d 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Nav/_BitNavChild.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Nav/_BitNavChild.razor.cs
@@ -67,15 +67,15 @@ private string GetItemContainerClasses()
if (Nav.SelectedItem == Item)
{
classes.Add("bit-nav-sel");
- if (Nav.ClassStyles?.SelectedItemContainer?.Class is not null)
+ if (Nav.Classes?.SelectedItemContainer is not null)
{
- classes.Add(Nav.ClassStyles?.SelectedItemContainer?.Class!);
+ classes.Add(Nav.Classes?.SelectedItemContainer!);
}
}
- if (Nav.ClassStyles?.ItemContainer?.Class is not null)
+ if (Nav.Classes?.ItemContainer is not null)
{
- classes.Add(Nav.ClassStyles?.ItemContainer?.Class!);
+ classes.Add(Nav.Classes?.ItemContainer!);
}
return string.Join(" ", classes);
@@ -83,14 +83,14 @@ private string GetItemContainerClasses()
private string GetItemContainerStyles()
{
var classes = new List();
- if (Nav.ClassStyles?.ItemContainer?.Style is not null)
+ if (Nav.Styles?.ItemContainer is not null)
{
- classes.Add(Nav.ClassStyles?.ItemContainer?.Style!);
+ classes.Add(Nav.Styles.ItemContainer);
}
- if (Nav.SelectedItem == Item && Nav.ClassStyles?.SelectedItemContainer?.Style is not null)
+ if (Nav.SelectedItem == Item && Nav.Styles?.SelectedItemContainer is not null)
{
- classes.Add(Nav.ClassStyles?.SelectedItemContainer?.Style!);
+ classes.Add(Nav.Styles?.SelectedItemContainer!);
}
return string.Join(" ", classes);
@@ -99,14 +99,14 @@ private string GetItemContainerStyles()
private string GetItemClasses()
{
var classes = new List();
- if (Nav.ClassStyles?.Item?.Class is not null)
+ if (Nav.Classes?.Item is not null)
{
- classes.Add(Nav.ClassStyles?.Item?.Class!);
+ classes.Add(Nav.Classes?.Item!);
}
- if (Nav.SelectedItem == Item && Nav.ClassStyles?.SelectedItem?.Class is not null)
+ if (Nav.SelectedItem == Item && Nav.Classes?.SelectedItem is not null)
{
- classes.Add(Nav.ClassStyles?.SelectedItem?.Class!);
+ classes.Add(Nav.Classes?.SelectedItem!);
}
return string.Join(" ", classes);
@@ -114,14 +114,14 @@ private string GetItemClasses()
private string GetItemStyles()
{
var classes = new List();
- if (Nav.ClassStyles?.Item?.Style is not null)
+ if (Nav.Styles?.Item is not null)
{
- classes.Add(Nav.ClassStyles?.Item?.Style!);
+ classes.Add(Nav.Styles?.Item!);
}
- if (Nav.SelectedItem == Item && Nav.ClassStyles?.SelectedItem?.Style is not null)
+ if (Nav.SelectedItem == Item && Nav.Styles?.SelectedItem is not null)
{
- classes.Add(Nav.ClassStyles?.SelectedItem?.Style!);
+ classes.Add(Nav.Styles?.SelectedItem!);
}
return string.Join(" ", classes);
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Panel/BitPanel.razor b/src/BlazorUI/Bit.BlazorUI/Components/Panel/BitPanel.razor
index 6fcfcf07fb..5d4a7e38da 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Panel/BitPanel.razor
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Panel/BitPanel.razor
@@ -6,54 +6,51 @@
You can set a short description inside the Accordion header.
@@ -50,7 +50,7 @@
-
+
Only one Accordion can be open.
@@ -76,7 +76,7 @@
-
+
You can bind values with Accordion.
@@ -94,7 +94,7 @@
-
+
This Accordion header is Customized.
diff --git a/src/BlazorUI/Demo/Client/Core/Pages/Components/Breadcrumb/BitBreadcrumbDemo.razor b/src/BlazorUI/Demo/Client/Core/Pages/Components/Breadcrumb/BitBreadcrumbDemo.razor
index 3225a94bf5..b35b4204cf 100644
--- a/src/BlazorUI/Demo/Client/Core/Pages/Components/Breadcrumb/BitBreadcrumbDemo.razor
+++ b/src/BlazorUI/Demo/Client/Core/Pages/Components/Breadcrumb/BitBreadcrumbDemo.razor
@@ -10,7 +10,7 @@
ComponentParameters="componentParameters"
ComponentSubClasses="componentSubClasses"
Notes="The BitBreadcrumb is a Multi-API component which can accept the list of Items in 3 different ways: BitBreadcrumbItem class, a custom Generic class, and BitBreadcrumbOption component.">
-
+