From 35d739a150f656d5b235d72ddebb98859aada27c Mon Sep 17 00:00:00 2001 From: mckaragoz <78308169+mckaragoz@users.noreply.github.com> Date: Sun, 29 Jan 2023 19:13:31 +0300 Subject: [PATCH 1/5] Initialize --- .../CodeBeam.MudExtensions.csproj | 4 +- .../MudInputCssHelperExtended.cs | 40 + .../InputExtended/MudInputExtended.razor | 150 +++ .../InputExtended/MudInputExtended.razor.cs | 238 ++++ .../ListExtended/MudListExtended.razor | 10 +- .../ListExtended/MudListExtended.razor.cs | 16 +- .../SelectExtended/IMudSelectExtended.cs | 14 + .../SelectExtended/MudSelectExtended.razor | 121 ++ .../SelectExtended/MudSelectExtended.razor.cs | 1038 +++++++++++++++++ .../MudSelectItemExtended.razor | 17 + .../MudSelectItemExtended.razor.cs | 168 +++ .../MudSelectItemGroupExtended.razor | 21 + .../MudSelectItemGroupExtended.razor.cs | 84 ++ .../Enums/ValuePresenter.cs | 16 + .../Styles/Components/_selectextended.scss | 93 ++ .../Styles/MudExtensions.css | 57 + .../Styles/MudExtensions.min.css | 2 +- .../Styles/MudExtensions.scss | 1 + .../wwwroot/MudExtensions.min.css | 2 +- .../Pages/Components/SelectExtendedPage.razor | 29 + .../Examples/SelectExtendedExample1.razor | 15 + .../Examples/SelectExtendedExample2.razor | 60 + .../Examples/SelectExtendedExample3.razor | 44 + .../Examples/SelectExtendedExample4.razor | 96 ++ .../Examples/SelectExtendedExample5.razor | 75 ++ ComponentViewer.Docs/Pages/Index.razor | 5 + 26 files changed, 2399 insertions(+), 17 deletions(-) create mode 100644 CodeBeam.MudExtensions/Components/InputExtended/MudInputCssHelperExtended.cs create mode 100644 CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor create mode 100644 CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor.cs create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/IMudSelectExtended.cs create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor.cs create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor.cs create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor create mode 100644 CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs create mode 100644 CodeBeam.MudExtensions/Enums/ValuePresenter.cs create mode 100644 CodeBeam.MudExtensions/Styles/Components/_selectextended.scss create mode 100644 ComponentViewer.Docs/Pages/Components/SelectExtendedPage.razor create mode 100644 ComponentViewer.Docs/Pages/Examples/SelectExtendedExample1.razor create mode 100644 ComponentViewer.Docs/Pages/Examples/SelectExtendedExample2.razor create mode 100644 ComponentViewer.Docs/Pages/Examples/SelectExtendedExample3.razor create mode 100644 ComponentViewer.Docs/Pages/Examples/SelectExtendedExample4.razor create mode 100644 ComponentViewer.Docs/Pages/Examples/SelectExtendedExample5.razor diff --git a/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj b/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj index 59b93cc2..29a3fa9d 100644 --- a/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj +++ b/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj @@ -36,9 +36,9 @@ - + diff --git a/CodeBeam.MudExtensions/Components/InputExtended/MudInputCssHelperExtended.cs b/CodeBeam.MudExtensions/Components/InputExtended/MudInputCssHelperExtended.cs new file mode 100644 index 00000000..759cc025 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/InputExtended/MudInputCssHelperExtended.cs @@ -0,0 +1,40 @@ +using System; +using MudBlazor; +using MudBlazor.Extensions; +using MudBlazor.Utilities; + +namespace MudExtensions +{ + internal static class MudInputCssHelperExtended + { + public static string GetClassname(MudBaseInput baseInput, Func shrinkWhen) => + new CssBuilder("mud-input") + .AddClass($"mud-input-{baseInput.Variant.ToDescriptionString()}") + .AddClass($"mud-input-adorned-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-input-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None) + .AddClass("mud-input-underline", when: () => baseInput.DisableUnderLine == false && baseInput.Variant != Variant.Outlined) + .AddClass("mud-shrink", when: shrinkWhen) + .AddClass("mud-disabled", baseInput.Disabled) + .AddClass("mud-input-error", baseInput.HasErrors) + //.AddClass("mud-ltr", baseInput.GetInputType() == InputType.Email || baseInput.GetInputType() == InputType.Telephone) + .AddClass(baseInput.Class) + .Build(); + + public static string GetInputClassname(MudBaseInput baseInput) => + new CssBuilder("mud-input-slot") + .AddClass("mud-input-root") + .AddClass($"mud-input-root-{baseInput.Variant.ToDescriptionString()}") + .AddClass($"mud-input-root-adorned-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-input-root-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None) + .AddClass(baseInput.Class) + .Build(); + + public static string GetAdornmentClassname(MudBaseInput baseInput) => + new CssBuilder("mud-input-adornment") + .AddClass($"mud-input-adornment-{baseInput.Adornment.ToDescriptionString()}", baseInput.Adornment != Adornment.None) + .AddClass($"mud-text", !string.IsNullOrEmpty(baseInput.AdornmentText)) + .AddClass($"mud-input-root-filled-shrink", baseInput.Variant == Variant.Filled) + .AddClass(baseInput.Class) + .Build(); + } +} diff --git a/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor b/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor new file mode 100644 index 00000000..97434392 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor @@ -0,0 +1,150 @@ +@namespace MudExtensions +@typeparam T +@inherits MudBaseInput +@using MudBlazor.Internal + +
+ @if (Adornment == Adornment.Start) + { + + } + + @if (Lines > 1) + { + + @*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@ + @*note: the value="@_internalText" is absolutely essential here. the inner html @Text is needed by tests checking it*@ + } + else + { + + @if (DataVisualiser != null) + { + @DataVisualiser + } + + + @*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@ + + @if (Disabled) + { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown. + In Disabled state the tabindex attribute must NOT be set at all or else it will get focus on click + *@ +
+ @ChildContent +
+ } + else + { + @*Note: this div must always be there to avoid crashes in WASM, but it is hidden most of the time except if ChildContent should be shown.*@ +
+ @ChildContent +
+ } + } + + @if (_showClearable && !Disabled) + { + + } + + @if (Adornment == Adornment.End) + { + + } + + @if (Variant == Variant.Outlined) + { +
+ } + + @if (!HideSpinButtons) + { +
+ + + + + + +
+ } +
\ No newline at end of file diff --git a/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor.cs b/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor.cs new file mode 100644 index 00000000..13cac8f3 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/InputExtended/MudInputExtended.razor.cs @@ -0,0 +1,238 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudBlazor; +using MudBlazor.Extensions; +using MudBlazor.Utilities; + +namespace MudExtensions +{ + public partial class MudInputExtended : MudBaseInput + { + protected string Classname => MudInputCssHelperExtended.GetClassname(this, + () => HasNativeHtmlPlaceholder() || !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || !string.IsNullOrWhiteSpace(Placeholder) || !string.IsNullOrEmpty(Converter.Set(Value))); + + protected string InputClassname => MudInputCssHelperExtended.GetInputClassname(this); + + protected string AdornmentClassname => MudInputCssHelperExtended.GetAdornmentClassname(this); + + protected string ClearButtonClassname => + new CssBuilder() + .AddClass("me-n1", Adornment == Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-end", Adornment == Adornment.End && HideSpinButtons == true) + .AddClass("me-6", Adornment != Adornment.End && HideSpinButtons == false) + .AddClass("mud-icon-button-edge-margin-end", Adornment != Adornment.End && HideSpinButtons == true) + .Build(); + + /// + /// Type of the input element. It should be a valid HTML5 input type. + /// + [Parameter] public InputType InputType { get; set; } = InputType.Text; + + internal InputType GetInputType() => InputType; + + protected string InputTypeString => InputType.ToDescriptionString(); + + protected Task OnInput(ChangeEventArgs args) + { + if (!Immediate) + return Task.CompletedTask; + _isFocused = true; + return SetTextAsync(args?.Value as string); + } + + protected async Task OnChange(ChangeEventArgs args) + { + _internalText = args?.Value as string; + await OnInternalInputChanged.InvokeAsync(args); + if (!Immediate) + { + await SetTextAsync(args?.Value as string); + } + } + + /// + /// Paste hook for descendants. + /// +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + + protected virtual async Task OnPaste(ClipboardEventArgs args) +#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously + { + // do nothing + return; + } + + /// + /// ChildContent of the MudInput will only be displayed if InputType.Hidden and if its not null. + /// + [Parameter] public RenderFragment ChildContent { get; set; } + + public ElementReference ElementReference { get; private set; } + private ElementReference _elementReference1; + + public override async ValueTask FocusAsync() + { + try + { + if (InputType == InputType.Hidden && ChildContent != null) + await _elementReference1.FocusAsync(); + else + await ElementReference.FocusAsync(); + } + catch (Exception e) + { + Console.WriteLine("MudInput.FocusAsync: " + e.Message); + } + } + + public override ValueTask BlurAsync() + { + return ElementReference.MudBlurAsync(); + } + + public override ValueTask SelectAsync() + { + return ElementReference.MudSelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return ElementReference.MudSelectRangeAsync(pos1, pos2); + } + + /// + /// Invokes the callback when the Up arrow button is clicked when the input is set to . + /// Note: use the optimized control if you need to deal with numbers. + /// + [Parameter] public EventCallback OnIncrement { get; set; } + + /// + /// Invokes the callback when the Down arrow button is clicked when the input is set to . + /// Note: use the optimized control if you need to deal with numbers. + /// + [Parameter] public EventCallback OnDecrement { get; set; } + + /// + /// Hides the spin buttons for + /// + [Parameter] public bool HideSpinButtons { get; set; } = true; + + [Parameter] public RenderFragment DataVisualiser { get; set; } + + /// + /// Show clear button. + /// + [Parameter] public bool Clearable + { + get => _showClearable; + set + { + if (_showClearable == value) + { + return; + } + _showClearable = value; + } + } + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] public EventCallback OnClearButtonClick { get; set; } + + /// + /// Mouse wheel event for input. + /// + [Parameter] public EventCallback OnMouseWheel { get; set; } + + /// + /// Custom clear icon. + /// + [Parameter] public string ClearIcon { get; set; } = Icons.Material.Filled.Clear; + + /// + /// Custom numeric up icon. + /// + [Parameter] public string NumericUpIcon { get; set; } = Icons.Material.Filled.KeyboardArrowUp; + + /// + /// Custom numeric down icon. + /// + [Parameter] public string NumericDownIcon { get; set; } = Icons.Material.Filled.KeyboardArrowDown; + + private Size GetButtonSize() => Margin == Margin.Dense ? Size.Small : Size.Medium; + + private bool _showClearable; + + private void UpdateClearable(object value) + { + var showClearable = Clearable && ((value is string stringValue && !string.IsNullOrWhiteSpace(stringValue)) || (value is not string && value is not null)); + if (_showClearable != showClearable) + _showClearable = showClearable; + } + + protected override async Task UpdateTextPropertyAsync(bool updateValue) + { + await base.UpdateTextPropertyAsync(updateValue); + if (Clearable) + UpdateClearable(Text); + } + + protected override async Task UpdateValuePropertyAsync(bool updateText) + { + await base.UpdateValuePropertyAsync(updateText); + if (Clearable) + UpdateClearable(Value); + } + + protected virtual async Task ClearButtonClickHandlerAsync(MouseEventArgs e) + { + await SetTextAsync(string.Empty, updateValue: true); + await ElementReference.FocusAsync(); + await OnClearButtonClick.InvokeAsync(e); + } + + private string _internalText; + + public override async Task SetParametersAsync(ParameterView parameters) + { + await base.SetParametersAsync(parameters); + //if (!_isFocused || _forceTextUpdate) + // _internalText = Text; + if (RuntimeLocation.IsServerSide && TextUpdateSuppression) + { + // Text update suppression, only in BSS (not in WASM). + // This is a fix for #1012 + if (!_isFocused || _forceTextUpdate) + _internalText = Text; + } + else + { + // in WASM (or in BSS with TextUpdateSuppression==false) we always update + _internalText = Text; + } + } + + /// + /// Sets the input text from outside programmatically + /// + /// + /// + public Task SetText(string text) + { + _internalText = text; + return SetTextAsync(text); + } + + + // Certain HTML5 inputs (dates and color) have a native placeholder + private bool HasNativeHtmlPlaceholder() + { + return GetInputType() is InputType.Color or InputType.Date or InputType.DateTimeLocal or InputType.Month + or InputType.Time or InputType.Week; + } + } + +} diff --git a/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor b/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor index e5e17fe3..41fcfa31 100644 --- a/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor +++ b/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor @@ -14,16 +14,16 @@ @if (ItemCollection != null) { -@* @if (MudSelect != null) + @if (MudSelectExtended != null) { - + } else { - - }*@ + + } @*Upper commented block will replace after Experimental Select*@ - + @**@ } else diff --git a/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor.cs b/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor.cs index 23c0cdd3..faa89d34 100644 --- a/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor.cs +++ b/CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor.cs @@ -40,7 +40,7 @@ public partial class MudListExtended : MudComponentBase, IDisposable .AddStyle(Style) .Build(); - [CascadingParameter] protected MudSelect MudSelect { get; set; } + [CascadingParameter] protected MudSelectExtended MudSelectExtended { get; set; } [CascadingParameter] protected MudAutocomplete MudAutocomplete { get; set; } [CascadingParameter] protected MudListExtended ParentList { get; set; } @@ -563,7 +563,7 @@ public override Task SetParametersAsync(ParameterView parameters) return Task.CompletedTask; } - if (MudSelect != null || MudAutocomplete != null) + if (MudSelectExtended != null || MudAutocomplete != null) { return Task.CompletedTask; } @@ -618,7 +618,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) }, }); - if (MudSelect == null && MudAutocomplete == null) + if (MudSelectExtended == null && MudAutocomplete == null) { if (MultiSelection == false && SelectedValue != null) { @@ -630,14 +630,14 @@ protected override async Task OnAfterRenderAsync(bool firstRender) } } - if (MudSelect != null || MudAutocomplete != null) + if (MudSelectExtended != null || MudAutocomplete != null) { if (MultiSelection) { UpdateSelectAllState(); - if (MudSelect != null) + if (MudSelectExtended != null) { - SelectedValues = MudSelect.SelectedValues; + SelectedValues = MudSelectExtended.SelectedValues; } else if (MudAutocomplete != null) { @@ -995,9 +995,9 @@ protected void SelectAllItems(bool? deselect = false) } SelectedValues = items.Where(x => x.IsSelected == true).Select(y => y.Value).ToHashSet(_comparer); - if (MudSelect != null) + if (MudSelectExtended != null) { - //MudSelect.BeginValidate(); + //MudSelectExtended.BeginValidate(); } } diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/IMudSelectExtended.cs b/CodeBeam.MudExtensions/Components/SelectExtended/IMudSelectExtended.cs new file mode 100644 index 00000000..9a6c8568 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/IMudSelectExtended.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Components; + +namespace MudExtensions +{ + internal interface IMudSelectExtended + { + void CheckGenericTypeMatch(object select_item); + bool MultiSelection { get; set; } + } + + internal interface IMudShadowSelectExtended + { + } +} diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor new file mode 100644 index 00000000..f3e890be --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor @@ -0,0 +1,121 @@ +@namespace MudExtensions +@typeparam T +@inherits MudBaseInput +@using MudExtensions.Enums + +@*To Be Discussed as Second ShadowItems: Needed to render directly into select to has initial values*@ +
+ + + @ChildContent + + +
+ + +
+ + + + + +
+ @if (Strict && !IsValueInList) + { + //Show nothing + @Placeholder + } + else if (ValuePresenter == ValuePresenter.Text) + { + @if (string.IsNullOrEmpty(Text)) + { + @Placeholder + } + + @GetSelectTextPresenter() + } + else if (ValuePresenter == ValuePresenter.Chip) + { + if (SelectedValues == null || !SelectedValues.Any()) + { + @Placeholder + } + else + { + @foreach (var val in SelectedValues) + { + + } + } + } + else if (ValuePresenter == ValuePresenter.ItemContent) + { + if (SelectedListItem == null) + { + @Placeholder + + } + else if (ItemTemplate != null) + { + if (SelectedListItem != null && SelectedListItem.Value != null) + { + @ItemTemplate(SelectedListItem) + } + else if (!string.IsNullOrEmpty(Placeholder)) + { + @Placeholder + } + } + else if (SelectedListItem.ChildContent != null) + { + @SelectedListItem.ChildContent + } + else + { + @if (string.IsNullOrEmpty(Text)) + { + @Placeholder + } + + @GetSelectTextPresenter() + } + } +
+
+
+ + + + + @ChildContent + + + +
+
+
+ + @*Shadow select items for IsValueInList and CanRenderValue*@ + + + @ChildContent + + + +
+ + \ No newline at end of file diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor.cs b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor.cs new file mode 100644 index 00000000..e01fed21 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectExtended.razor.cs @@ -0,0 +1,1038 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudBlazor; +using MudBlazor.Services; +using MudBlazor.Utilities; +using MudBlazor.Utilities.Exceptions; +using MudExtensions.Enums; +using static MudBlazor.CategoryTypes; + +namespace MudExtensions +{ + public partial class MudSelectExtended : MudBaseInput, IMudSelectExtended, IMudShadowSelectExtended + { + + #region Constructor, Injected Services, Parameters, Fields + + public MudSelectExtended() + { + Adornment = Adornment.End; + IconSize = Size.Medium; + } + + [Inject] private IKeyInterceptorFactory KeyInterceptorFactory { get; set; } + + private MudListExtended _list; + private bool _dense; + private string multiSelectionText; + private IKeyInterceptor _keyInterceptor; + /// + /// The collection of items within this select + /// + public IReadOnlyList> Items => _items; + + protected internal List> _items = new(); + protected Dictionary> _valueLookup = new(); + protected Dictionary> _shadowLookup = new(); + private MudInputExtended _elementReference; + internal bool _isOpen; + protected internal string _currentIcon { get; set; } + internal event Action> SelectionChangedFromOutside; + + protected string Classname => + new CssBuilder("mud-select-extended") + .AddClass(Class) + .Build(); + + protected string InputClassname => + new CssBuilder("mud-select-input-extended") + .AddClass(InputClass) + .Build(); + + private string _elementId = "select_" + Guid.NewGuid().ToString().Substring(0, 8); + + /// + /// User class names for the input, separated by space + /// + [Category(CategoryTypes.FormComponent.Appearance)] + [Parameter] public string InputClass { get; set; } + + /// + /// User style names for the input, separated by space + /// + [Category(CategoryTypes.FormComponent.Appearance)] + [Parameter] public string InputStyle { get; set; } + + /// + /// Fired when dropdown opens. + /// + [Category(CategoryTypes.FormComponent.Behavior)] + [Parameter] public EventCallback OnOpen { get; set; } + + /// + /// Fired when dropdown closes. + /// + [Category(CategoryTypes.FormComponent.Behavior)] + [Parameter] public EventCallback OnClose { get; set; } + + /// + /// Add the MudSelectItems here + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public RenderFragment ChildContent { get; set; } + + /// + /// Optional presentation template for items + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public RenderFragment> ItemTemplate { get; set; } + + /// + /// Optional presentation template for selected items + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public RenderFragment> ItemSelectedTemplate { get; set; } + + /// + /// Optional presentation template for disabled items + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public RenderFragment> ItemDisabledTemplate { get; set; } + + /// + /// Function to be invoked when checking whether an item should be disabled or not. Works both with renderfragment and ItemCollection approach. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public Func ItemDisabledFunc { get; set; } + + /// + /// Classname for item template or chips. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public string TemplateClass { get; set; } + + /// + /// If true the active (hilighted) item select on tab key. Designed for only single selection. Default is true. + /// + [Parameter] + [Category(CategoryTypes.List.Selecting)] + public bool SelectValueOnTab { get; set; } = true; + + /// + /// User class names for the popover, separated by space + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string PopoverClass { get; set; } + + /// + /// User class names for the popover, separated by space + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public bool DisablePopoverPadding { get; set; } + + /// + /// If true, selected items doesn't have a selected background color. + /// + [Parameter] + [Category(CategoryTypes.List.Appearance)] + public bool DisableSelectedItemStyle { get; set; } + + /// + /// If true, compact vertical padding will be applied to all Select items. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public bool Dense + { + get { return _dense; } + set { _dense = value; } + } + + /// + /// The Open Select Icon + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string OpenIcon { get; set; } = Icons.Filled.ArrowDropDown; + + /// + /// Dropdown color of select. Supports theme colors. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public Color Color { get; set; } = Color.Primary; + + /// + /// The Close Select Icon + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public string CloseIcon { get; set; } = Icons.Filled.ArrowDropUp; + + /// + /// The value presenter. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Appearance)] + public ValuePresenter ValuePresenter { get; set; } = ValuePresenter.Text; + + /// + /// If set to true and the MultiSelection option is set to true, a "select all" checkbox is added at the top of the list of items. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool SelectAll { get; set; } + + /// + /// Define the text of the Select All option. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string SelectAllText { get; set; } = "Select All"; + + /// + /// Function to define a customized multiselection text. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public Func, string> MultiSelectionTextFunc { get; set; } + + /// + /// If not null, select items will automatically created regard to the collection. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public ICollection ItemCollection { get; set; } = null; + + /// + /// Allows virtualization. Only work is ItemCollection parameter is not null. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public bool Virtualize { get; set; } + + /// + /// Parameter to define the delimited string separator. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Delimiter { get; set; } = ", "; + + /// + /// If true popover width will be the same as the select component. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool RelativeWidth { get; set; } = true; + + /// + /// Sets the maxheight the Select can have when open. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public int MaxHeight { get; set; } = 300; + + /// + /// Set the anchor origin point to determen where the popover will open from. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public Origin AnchorOrigin { get; set; } = Origin.TopCenter; + + /// + /// Sets the transform origin point for the popover. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public Origin TransformOrigin { get; set; } = Origin.TopCenter; + + /// + /// Sets the direction the Select menu should open. + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public Direction Direction { get; set; } = Direction.Bottom; + + /// + /// If true, the Select menu will open either before or after the input (left/right). + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetX { get; set; } + + /// + /// If true, the Select menu will open either before or after the input (top/bottom). + /// + /// [ExcludeFromCodeCoverage] + [Obsolete("Use AnchorOrigin or TransformOrigin instead.", true)] + [Parameter] public bool OffsetY { get; set; } + + /// + /// If true, the Select's input will not show any values that are not defined in the dropdown. + /// This can be useful if Value is bound to a variable which is initialized to a value which is not in the list + /// and you want the Select to show the label / placeholder instead. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Strict { get; set; } + + /// + /// Show clear button. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Clearable { get; set; } = false; + + /// + /// If true, prevent scrolling while dropdown is open. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool LockScroll { get; set; } = false; + + /// + /// Button click event for clear button. Called after text and value has been cleared. + /// + [Parameter] public EventCallback OnClearButtonClick { get; set; } + + /// + /// Custom checked icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string CheckedIcon { get; set; } = Icons.Filled.CheckBox; + + /// + /// Custom unchecked icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string UncheckedIcon { get; set; } = Icons.Filled.CheckBoxOutlineBlank; + + /// + /// Custom indeterminate icon. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListAppearance)] + public string IndeterminateIcon { get; set; } = Icons.Filled.IndeterminateCheckBox; + + private bool _multiSelection = false; + /// + /// If true, multiple values can be selected via checkboxes which are automatically shown in the dropdown + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public bool MultiSelection + { + get => _multiSelection; + set + { + if (value != _multiSelection) + { + _multiSelection = value; + UpdateTextPropertyAsync(false).AndForget(); + } + } + } + + /// + /// The MultiSelectionComponent's placement. Accepts Align.Start and Align.End + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public Align MultiSelectionAlign { get; set; } = Align.Start; + + /// + /// The component which shows as a MultiSelection check. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public MultiSelectionComponent MultiSelectionComponent { get; set; } = MultiSelectionComponent.CheckBox; + + private IEqualityComparer _comparer; + /// + /// The Comparer to use for comparing selected values internally. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public IEqualityComparer Comparer + { + get => _comparer; + set + { + if (_comparer == value) + return; + _comparer = value; + // Apply comparer and refresh selected values + _selectedValues = new HashSet(_selectedValues, _comparer); + SelectedValues = _selectedValues; + } + } + + private Func _toStringFunc = x => x?.ToString(); + /// + /// Defines how values are displayed in the drop-down list + /// + [Parameter] + [Category(CategoryTypes.FormComponent.ListBehavior)] + public Func ToStringFunc + { + get => _toStringFunc; + set + { + if (_toStringFunc == value) + return; + _toStringFunc = value; + Converter = new Converter + { + SetFunc = _toStringFunc ?? (x => x?.ToString()), + }; + } + } + + #endregion + + + #region Values, Texts & Items + + //This 'started' field is only for fixing multiselect keyboard navigation test. Has a very minor effect, so can be removable for a better gain. + private bool _selectedValuesSetterStarted = false; + private HashSet _selectedValues; + /// + /// Set of selected values. If MultiSelection is false it will only ever contain a single value. This property is two-way bindable. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Data)] + public IEnumerable SelectedValues + { + get + { + if (_selectedValues == null) + _selectedValues = new HashSet(_comparer); + return _selectedValues; + } + set + { + var set = value ?? new HashSet(_comparer); + if (value == null && _selectedValues == null) + { + return; + } + if (value != null && _selectedValues != null && _selectedValues.SetEquals(value)) + { + return; + } + if (SelectedValues.Count() == set.Count() && _selectedValues.All(x => set.Contains(x, _comparer))) + return; + + if (_selectedValuesSetterStarted == true) + { + return; + } + _selectedValuesSetterStarted = true; + _selectedValues = new HashSet(set, _comparer); + SelectionChangedFromOutside?.Invoke(new HashSet(_selectedValues, _comparer)); + if (MultiSelection == false) + { + SetValueAsync(_selectedValues.FirstOrDefault()).AndForget(); + } + else + { + SetValueAsync(_selectedValues.LastOrDefault(), false).AndForget(); + UpdateTextPropertyAsync(false).AndForget(); + } + + SelectedValuesChanged.InvokeAsync(new HashSet(SelectedValues, _comparer)).AndForget(); + _selectedValuesSetterStarted = false; + //Console.WriteLine("SelectedValues setter ended"); + } + } + + private MudListItemExtended _selectedListItem; + private HashSet> _selectedListItems; + + protected internal MudListItemExtended SelectedListItem + { + get => _selectedListItem; + + set + { + if (_selectedListItem == value) + { + return; + } + _selectedListItem = value; + } + } + + protected internal IEnumerable> SelectedListItems + { + get => _selectedListItems; + + set + { + if (value == null && _selectedListItems == null) + { + return; + } + + if (value != null && _selectedListItems != null && _selectedListItems.SetEquals(value)) + { + return; + } + _selectedListItems = value == null ? null : value.ToHashSet(); + } + } + + /// + /// Fires when SelectedValues changes. + /// + [Parameter] public EventCallback> SelectedValuesChanged { get; set; } + + /// + /// Should only be used for debugging and development purposes. + /// + [Parameter] public EventCallback>> SelectedListItemsChanged { get; set; } + + protected async Task SetCustomizedTextAsync(string text, bool updateValue = true, + List selectedConvertedValues = null, + Func, string> multiSelectionTextFunc = null) + { + // The Text property of the control is updated + Text = multiSelectionTextFunc?.Invoke(selectedConvertedValues); + + // The comparison is made on the multiSelectionText variable + if (multiSelectionText != text) + { + multiSelectionText = text; + if (!string.IsNullOrWhiteSpace(multiSelectionText)) + Touched = true; + if (updateValue) + await UpdateValuePropertyAsync(false); + await TextChanged.InvokeAsync(multiSelectionText); + } + } + + protected override Task UpdateValuePropertyAsync(bool updateText) + { + // For MultiSelection of non-string T's we don't update the Value!!! + //if (typeof(T) == typeof(string) || !MultiSelection) + base.UpdateValuePropertyAsync(updateText).AndForget(); + return Task.CompletedTask; + } + + protected override Task UpdateTextPropertyAsync(bool updateValue) + { + List textList = new List(); + if (Items != null && Items.Any()) + { + if (ItemCollection != null) + { + foreach (var val in SelectedValues) + { + var collectionValue = ItemCollection.FirstOrDefault(x => x != null && (Comparer != null ? Comparer.Equals(x, val) : x.Equals(val))); + if (collectionValue != null) + { + textList.Add(Converter.Set(collectionValue)); + } + } + } + else + { + foreach (var val in SelectedValues) + { + if (Strict == false && !Items.Select(x => x.Value).Contains(val)) + { + textList.Add(ToStringFunc != null ? ToStringFunc(val) : Converter.Set(val)); + continue; + } + var item = Items.FirstOrDefault(x => x != null && (x.Value == null ? val == null : Comparer != null ? Comparer.Equals(x.Value, val) : x.Value.Equals(val))); + if (item != null) + { + textList.Add(!string.IsNullOrEmpty(item.Text) ? item.Text : Converter.Set(item.Value)); + } + } + } + } + + // when multiselection is true, we return + // a comma separated list of selected values + if (MultiSelection == true) + { + if (MultiSelectionTextFunc != null) + { + return SetCustomizedTextAsync(string.Join(Delimiter, textList), + selectedConvertedValues: SelectedValues.ToList(), + multiSelectionTextFunc: MultiSelectionTextFunc, updateValue: updateValue); + } + else + { + return SetTextAsync(string.Join(Delimiter, textList), updateValue: updateValue); + } + } + else + { + var item = Items.FirstOrDefault(x => Value == null ? x.Value == null : Comparer != null ? Comparer.Equals(Value, x.Value) : Value.Equals(x.Value)); + if (item == null) + { + return SetTextAsync(Converter.Set(Value), false); + } + return SetTextAsync((!string.IsNullOrEmpty(item.Text) ? item.Text : Converter.Set(item.Value)), updateValue: updateValue); + } + } + + private string GetSelectTextPresenter() + { + return Text; + } + + #endregion + + + #region Lifecycle Methods + + protected override void OnInitialized() + { + base.OnInitialized(); + UpdateIcon(); + if (MultiSelection == false && Value != null) + { + _selectedValues = new HashSet(_comparer) { Value }; + } + else if (MultiSelection == true && SelectedValues != null) + { + // TODO: Check this line again + SetValueAsync(SelectedValues.FirstOrDefault()).AndForget(); + } + } + + protected override void OnParametersSet() + { + base.OnParametersSet(); + UpdateIcon(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + + if (firstRender) + { + _keyInterceptor = KeyInterceptorFactory.Create(); + await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() + { + //EnableLogging = true, + TargetClass = "mud-input-control", + Keys = { + new KeyOptions { Key=" ", PreventDown = "key+none" }, //prevent scrolling page, toggle open/close + new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead hilight previous item + new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead hilight next item + new KeyOptions { Key="Home", PreventDown = "key+none" }, + new KeyOptions { Key="End", PreventDown = "key+none" }, + new KeyOptions { Key="Escape" }, + new KeyOptions { Key="Enter", PreventDown = "key+none" }, + new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, + new KeyOptions { Key="a", PreventDown = "key+ctrl" }, // select all items instead of all page text + new KeyOptions { Key="A", PreventDown = "key+ctrl" }, // select all items instead of all page text + new KeyOptions { Key="/./", SubscribeDown = true, SubscribeUp = true }, // for our users + }, + }); + _keyInterceptor.KeyDown += HandleKeyDown; + _keyInterceptor.KeyUp += HandleKeyUp; + await UpdateTextPropertyAsync(false); + StateHasChanged(); + } + //Console.WriteLine("Select rendered"); + await base.OnAfterRenderAsync(firstRender); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing == true) + { + if (_keyInterceptor != null) + { + _keyInterceptor.KeyDown -= HandleKeyDown; + _keyInterceptor.KeyUp -= HandleKeyUp; + } + _keyInterceptor?.Dispose(); + } + } + + #endregion + + + #region Events (Key, Focus) + + protected internal async void HandleKeyDown(KeyboardEventArgs obj) + { + if (Disabled || ReadOnly) + return; + + if (_list != null && _isOpen == true) + { + await _list.HandleKeyDown(obj); + } + + switch (obj.Key) + { + case "Tab": + await CloseMenu(); + break; + case "ArrowUp": + if (obj.AltKey == true) + { + await CloseMenu(); + } + else if (_isOpen == false) + { + await OpenMenu(); + } + break; + case "ArrowDown": + if (obj.AltKey == true) + { + await OpenMenu(); + } + else if (_isOpen == false) + { + await OpenMenu(); + } + break; + case " ": + await ToggleMenu(); + break; + case "Escape": + await CloseMenu(); + break; + case "Enter": + case "NumpadEnter": + if (MultiSelection == false) + { + if (!_isOpen) + { + await OpenMenu(); + } + else + { + await CloseMenu(); + } + break; + } + else + { + if (_isOpen == false) + { + await OpenMenu(); + break; + } + else + { + await _elementReference.SetText(Text); + break; + } + } + } + await OnKeyDown.InvokeAsync(obj); + + } + + protected internal async void HandleKeyUp(KeyboardEventArgs obj) + { + await OnKeyUp.InvokeAsync(obj); + } + + internal void OnLostFocus(FocusEventArgs obj) + { + //if (_isOpen) + //{ + // // when the menu is open we immediately get back the focus if we lose it (i.e. because of checkboxes in multi-select) + // // otherwise we can't receive key strokes any longer + // _elementReference.FocusAsync().AndForget(TaskOption.Safe); + //} + //base.OnBlur.InvokeAsync(obj).AndForget(); + + OnBlurred(obj); + } + + public override ValueTask FocusAsync() + { + return _elementReference.FocusAsync(); + } + + public override ValueTask BlurAsync() + { + return _elementReference.BlurAsync(); + } + + public override ValueTask SelectAsync() + { + return _elementReference.SelectAsync(); + } + + public override ValueTask SelectRangeAsync(int pos1, int pos2) + { + return _elementReference.SelectRangeAsync(pos1, pos2); + } + + #endregion + + + #region PopoverState + + public async Task ToggleMenu() + { + if (Disabled || ReadOnly) + return; + if (_isOpen) + await CloseMenu(); + else + await OpenMenu(); + } + + public async Task OpenMenu() + { + if (Disabled || ReadOnly) + return; + _isOpen = true; + UpdateIcon(); + StateHasChanged(); + + //disable escape propagation: if selectmenu is open, only the select popover should close and underlying components should not handle escape key + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "Key+none" }); + + await OnOpen.InvokeAsync(); + } + + public async Task CloseMenu() + { + _isOpen = false; + UpdateIcon(); + StateHasChanged(); + //if (focusAgain == true) + //{ + // StateHasChanged(); + // await OnBlur.InvokeAsync(new FocusEventArgs()); + // _elementReference.FocusAsync().AndForget(TaskOption.Safe); + // StateHasChanged(); + //} + + //enable escape propagation: the select popover was closed, now underlying components are allowed to handle escape key + await _keyInterceptor.UpdateKey(new() { Key = "Escape", StopDown = "none" }); + + await OnClose.InvokeAsync(); + } + + #endregion + + + #region Item Registration & Selection + + public async Task SelectOption(int index) + { + if (index < 0 || index >= _items.Count) + { + if (!MultiSelection) + await CloseMenu(); + return; + } + await SelectOption(_items[index].Value); + } + + public async Task SelectOption(object obj) + { + var value = (T)obj; + if (MultiSelection) + { + await UpdateTextPropertyAsync(false); + //UpdateSelectAllChecked(); + BeginValidate(); + } + else + { + // single selection + // CloseMenu(true) doesn't close popover in BSS + await CloseMenu(); + + if (EqualityComparer.Default.Equals(Value, value)) + { + StateHasChanged(); + return; + } + + await SetValueAsync(value); + //await UpdateTextPropertyAsync(false); + _elementReference.SetText(Text).AndForget(); + //_selectedValues.Clear(); + //_selectedValues.Add(value); + } + + //await SelectedValuesChanged.InvokeAsync(SelectedValues); + //if (MultiSelection && typeof(T) == typeof(string)) + //await SetValueAsync((T)(object)Text, updateText: false); + await InvokeAsync(StateHasChanged); + } + + public async Task ForceUpdate() + { + //await base.ForceUpdate(); + if (MultiSelection == false) + { + SelectedValues = new HashSet(_comparer) { Value }; + } + else + { + await SelectedValuesChanged.InvokeAsync(new HashSet(SelectedValues, _comparer)); + } + } + + protected internal bool Add(MudSelectItemExtended item) + { + if (item == null) + return false; + bool? result = null; + if (!_items.Select(x => x.Value).Contains(item.Value)) + { + _items.Add(item); + + if (item.Value != null) + { + _valueLookup[item.Value] = item; + if (item.Value.Equals(Value) && !MultiSelection) + result = true; + } + } + //UpdateSelectAllChecked(); + if (result.HasValue == false) + { + result = item.Value?.Equals(Value); + } + return result == true; + } + + protected internal void Remove(MudSelectItemExtended item) + { + _items.Remove(item); + if (item.Value != null) + _valueLookup.Remove(item.Value); + } + + public void RegisterShadowItem(MudSelectItemExtended item) + { + if (item == null || item.Value == null) + return; + _shadowLookup[item.Value] = item; + } + + public void UnregisterShadowItem(MudSelectItemExtended item) + { + if (item == null || item.Value == null) + return; + _shadowLookup.Remove(item.Value); + } + + #endregion + + + #region Clear + + /// + /// Extra handler for clearing selection. + /// + protected async ValueTask SelectClearButtonClickHandlerAsync(MouseEventArgs e) + { + await SetValueAsync(default, false); + await SetTextAsync(default, false); + _selectedValues.Clear(); + SelectedListItem = null; + SelectedListItems = null; + BeginValidate(); + StateHasChanged(); + await SelectedValuesChanged.InvokeAsync(new HashSet(SelectedValues, _comparer)); + await OnClearButtonClick.InvokeAsync(e); + } + + [ExcludeFromCodeCoverage] + [Obsolete("Use Clear instead.", true)] + public Task ClearAsync() => Clear(); + + /// + /// Clear the selection + /// + public async Task Clear() + { + await SetValueAsync(default, false); + await SetTextAsync(default, false); + _selectedValues.Clear(); + BeginValidate(); + StateHasChanged(); + await SelectedValuesChanged.InvokeAsync(new HashSet(SelectedValues, _comparer)); + } + + protected override void ResetValue() + { + base.ResetValue(); + SelectedValues = null; + } + + #endregion + + protected bool IsValueInList + { + get + { + if (Value == null) + return false; + //return _shadowLookup.TryGetValue(Value, out var _); + foreach (var item in Items) + { + if (Comparer != null ? Comparer.Equals(item.Value, Value) : item.Value.Equals(Value)) //(Converter.Set(item.Value) == Converter.Set(Value)) + { + return true; + } + } + return false; + } + } + + protected void UpdateIcon() + { + _currentIcon = !string.IsNullOrWhiteSpace(AdornmentIcon) ? AdornmentIcon : _isOpen ? CloseIcon : OpenIcon; + } + + public void CheckGenericTypeMatch(object select_item) + { + var itemT = select_item.GetType().GenericTypeArguments[0]; + if (itemT != typeof(T)) + throw new GenericTypeMismatchException("MudSelectExtended", "MudSelectItemExtended", typeof(T), itemT); + } + + /// + /// Fixes issue #4328 + /// Returns true when MultiSelection is true and it has selected values(Since Value property is not used when MultiSelection=true + /// + /// + /// True when component has a value + protected override bool HasValue(T value) + { + if (MultiSelection) + return SelectedValues?.Count() > 0; + else + return base.HasValue(value); + } + } +} diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor new file mode 100644 index 00000000..01fbb9b7 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor @@ -0,0 +1,17 @@ +@namespace MudExtensions +@typeparam T +@inherits MudBaseSelectItem + +@if (HideContent == false) +{ + + @if (ChildContent != null && MudSelectExtended.ItemCollection == null) + { + @ChildContent + } + else + { + @DisplayString + } + +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor.cs b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor.cs new file mode 100644 index 00000000..19751319 --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Components; +using MudBlazor; +using MudBlazor.Utilities; + +namespace MudExtensions +{ + /// + /// Represents an option of a select or multi-select. To be used inside MudSelect. + /// + public partial class MudSelectItemExtended : MudBaseSelectItem, IDisposable + { + private String GetCssClasses() => new CssBuilder() + .AddClass(Class) + .Build(); + + private IMudSelectExtended _parent; + internal MudSelectExtended MudSelectExtended => (MudSelectExtended)IMudSelectExtended; + internal string ItemId { get; } = "_"+Guid.NewGuid().ToString().Substring(0,8); + + /// + /// The parent select component + /// + [CascadingParameter] + internal IMudSelectExtended IMudSelectExtended + { + get => _parent; + set + { + _parent = value; + if (_parent == null) + return; + _parent.CheckGenericTypeMatch(this); + if (MudSelectExtended == null) + return; + bool isSelected = MudSelectExtended.Add(this); + if (_parent.MultiSelection) + { + MudSelectExtended.SelectionChangedFromOutside += OnUpdateSelectionStateFromOutside; + InvokeAsync(() => OnUpdateSelectionStateFromOutside(MudSelectExtended.SelectedValues)); + } + else + { + IsSelected = isSelected; + } + } + } + + /// + /// Functional items does not hold values. If a value set on Functional item, it ignores by the MudSelect. They cannot be subject of keyboard navigation and selection. + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public bool IsFunctional { get; set; } + + /// + /// The text to display + /// + [Parameter] + [Category(CategoryTypes.List.Behavior)] + public string Text { get; set; } + + private IMudShadowSelectExtended _shadowParent; + [CascadingParameter] + internal IMudShadowSelectExtended IMudShadowSelectExtended + { + get => _shadowParent; + set + { + _shadowParent = value; + ((MudSelectExtended)_shadowParent)?.RegisterShadowItem(this); + } + } + + /// + /// Select items with HideContent==true are only there to register their RenderFragment with the select but + /// wont render and have no other purpose! + /// + [CascadingParameter(Name = "HideContent")] + internal bool HideContent { get; set; } + + private void OnUpdateSelectionStateFromOutside(IEnumerable selection) + { + if (selection == null) + return; + var old_is_selected = IsSelected; + IsSelected = selection.Contains(Value); + if (old_is_selected != IsSelected) + InvokeAsync(StateHasChanged); + } + + /// + /// A user-defined option that can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public T Value { get; set; } + + /// + /// Mirrors the MultiSelection status of the parent select + /// + protected bool MultiSelection + { + get + { + if (MudSelectExtended == null) + return false; + return MudSelectExtended.MultiSelection; + } + } + + private bool _isSelected; + internal bool IsSelected + { + get => _isSelected; + set + { + if (_isSelected == value) + return; + _isSelected = value; + } + } + + protected string DisplayString + { + get + { + var converter = MudSelectExtended?.Converter; + if (converter == null) + return $"{(string.IsNullOrEmpty(Text) ? Value : Text)}"; + return string.IsNullOrEmpty(Text) == false ? Text : converter.Set(Value); + } + } + + protected void HandleOnClick() + { + // Selection works on list. We arrange only popover state and some minor arrangements on click. + MudSelectExtended?.SelectOption(Value).AndForget(); + InvokeAsync(StateHasChanged); + if (MultiSelection == false) + { + MudSelectExtended.CloseMenu().AndForget(); + } + OnClick.InvokeAsync().AndForget(); + } + + protected bool GetDisabledStatus() + { + if (MudSelectExtended?.ItemDisabledFunc != null) + { + return MudSelectExtended.ItemDisabledFunc(Value); + } + return Disabled; + } + + public void Dispose() + { + try + { + MudSelectExtended?.Remove(this); + ((MudSelectExtended)_shadowParent)?.UnregisterShadowItem(this); + } + catch (Exception) { } + } + } +} diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor new file mode 100644 index 00000000..12c52f4f --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor @@ -0,0 +1,21 @@ +@namespace MudExtensions +@typeparam T +@inherits MudBaseSelectItem + +@if (HideContent == false) +{ + + if (Nested == true) + { + + + @ChildContent + + + } + else + { + @Text + @ChildContent + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs new file mode 100644 index 00000000..a28f0ccc --- /dev/null +++ b/CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using MudBlazor; +using MudBlazor.Utilities; + +namespace MudExtensions +{ + /// + /// Represents an option of a select or multi-select. To be used inside MudSelect. + /// + public partial class MudSelectItemGroupExtended : MudBaseSelectItem + { + + //private IMudSelect _parent; + internal string ItemId { get; } = "_" + Guid.NewGuid().ToString().Substring(0, 8); + + /// + /// A user-defined option that can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public T Value { get; set; } + + /// + /// A user-defined option that can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public string Text { get; set; } + + /// + /// A user-defined option that can be selected + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Nested { get; set; } + + /// + /// Sets the group's expanded state on popover opening. Works only if nested is true. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool InitiallyExpanded { get; set; } + + /// + /// Sticky header for item group. Works only with nested is false. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public bool Sticky { get; set; } + + [CascadingParameter] + internal MudListExtended MudListExtended { get; set; } + + /// + /// Select items with HideContent==true are only there to register their RenderFragment with the select but + /// wont render and have no other purpose! + /// + [CascadingParameter(Name = "HideContent")] + internal bool HideContent { get; set; } + + private void HandleExpandedChanged(bool isExpanded) + { + if (isExpanded) + { + MudListExtended?.UpdateSelectedStyles(); + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + if (firstRender) + { + //This line is for nested and initially expanded items. Still doesn't work for multiselection + MudListExtended?.UpdateSelectedStyles(false); + } + } + + } +} diff --git a/CodeBeam.MudExtensions/Enums/ValuePresenter.cs b/CodeBeam.MudExtensions/Enums/ValuePresenter.cs new file mode 100644 index 00000000..58cfe0f7 --- /dev/null +++ b/CodeBeam.MudExtensions/Enums/ValuePresenter.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace MudExtensions.Enums +{ + public enum ValuePresenter + { + [Description("none")] + None, + [Description("text")] + Text, + [Description("chip")] + Chip, + [Description("itemcontent")] + ItemContent, + } +} diff --git a/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss b/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss new file mode 100644 index 00000000..37d52e33 --- /dev/null +++ b/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss @@ -0,0 +1,93 @@ +.mud-select-extended { + display: flex; + flex-grow: 1; + flex-basis: 0; + min-width: 0; + position: relative; + //Required but broke outlined variant's label + overflow-x: auto; + + &.mud-autocomplete { + display: block; + + & .mud-select-input-extended { + cursor: text; + } + + & .mud-input-adornment-extended { + cursor: pointer; + } + } + + &.mud-autocomplete--with-progress { + & .mud-select-input-extended input { + padding-right: 3.5rem !important; + } + + & .mud-input-adorned-end input { + padding-right: 4.5rem !important; + } + + & .mud-select-input-extended .mud-icon-button { + display: none !important; + } + + & .progress-indicator-circular { + position: absolute; + width: 100%; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: flex-end; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-right: 1rem; + } + + & .progress-indicator-circular--with-adornment { + padding-right: 3rem; + } + + & .mud-progress-linear { + position: absolute; + bottom: -1px; + height: 2px; + } + } + + .mud-select-input-extended { + cursor: pointer; + + & .mud-input-slot { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + & .mud-input-adornment-end { + margin-left: 0; + } + + &:disabled { + cursor: default; + } + } + + .mud-disabled { + .mud-select-input { + cursor: default; + } + } +} + + +.mud-select-extended > .mud-form-helpertext { + margin-top: -21px; +} + +.mud-select-all-extended { + margin-top: 10px; + border-bottom: 1px solid lightgrey; + padding-bottom: 18px; +} diff --git a/CodeBeam.MudExtensions/Styles/MudExtensions.css b/CodeBeam.MudExtensions/Styles/MudExtensions.css index 044c06f9..637ca457 100644 --- a/CodeBeam.MudExtensions/Styles/MudExtensions.css +++ b/CodeBeam.MudExtensions/Styles/MudExtensions.css @@ -615,3 +615,60 @@ padding-left: 32px; padding-inline-start: 32px; padding-inline-end: unset; } + +.mud-select-extended { + display: flex; + flex-grow: 1; + flex-basis: 0; + min-width: 0; + position: relative; + overflow-x: auto; } + .mud-select-extended.mud-autocomplete { + display: block; } + .mud-select-extended.mud-autocomplete .mud-select-input-extended { + cursor: text; } + .mud-select-extended.mud-autocomplete .mud-input-adornment-extended { + cursor: pointer; } + .mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input { + padding-right: 3.5rem !important; } + .mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input { + padding-right: 4.5rem !important; } + .mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button { + display: none !important; } + .mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular { + position: absolute; + width: 100%; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: flex-end; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-right: 1rem; } + .mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment { + padding-right: 3rem; } + .mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear { + position: absolute; + bottom: -1px; + height: 2px; } + .mud-select-extended .mud-select-input-extended { + cursor: pointer; } + .mud-select-extended .mud-select-input-extended .mud-input-slot { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + .mud-select-extended .mud-select-input-extended .mud-input-adornment-end { + margin-left: 0; } + .mud-select-extended .mud-select-input-extended:disabled { + cursor: default; } + .mud-select-extended .mud-disabled .mud-select-input { + cursor: default; } + +.mud-select-extended > .mud-form-helpertext { + margin-top: -21px; } + +.mud-select-all-extended { + margin-top: 10px; + border-bottom: 1px solid lightgrey; + padding-bottom: 18px; } diff --git a/CodeBeam.MudExtensions/Styles/MudExtensions.min.css b/CodeBeam.MudExtensions/Styles/MudExtensions.min.css index a239c724..03dd61c8 100644 --- a/CodeBeam.MudExtensions/Styles/MudExtensions.min.css +++ b/CodeBeam.MudExtensions/Styles/MudExtensions.min.css @@ -1 +1 @@ -.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;} \ No newline at end of file +.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;overflow-x:auto;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file diff --git a/CodeBeam.MudExtensions/Styles/MudExtensions.scss b/CodeBeam.MudExtensions/Styles/MudExtensions.scss index d777835e..510028a0 100644 --- a/CodeBeam.MudExtensions/Styles/MudExtensions.scss +++ b/CodeBeam.MudExtensions/Styles/MudExtensions.scss @@ -7,3 +7,4 @@ @import 'components/_wheel'; @import 'components/_listextended'; +@import 'components/_selectextended'; diff --git a/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css b/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css index a239c724..03dd61c8 100644 --- a/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css +++ b/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css @@ -1 +1 @@ -.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;} \ No newline at end of file +.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;overflow-x:auto;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Components/SelectExtendedPage.razor b/ComponentViewer.Docs/Pages/Components/SelectExtendedPage.razor new file mode 100644 index 00000000..7c35cbb5 --- /dev/null +++ b/ComponentViewer.Docs/Pages/Components/SelectExtendedPage.razor @@ -0,0 +1,29 @@ +@page "/mudselectextended" +@using ComponentViewer.Docs.Pages.Examples + + +@* + + *@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample1.razor b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample1.razor new file mode 100644 index 00000000..3b85564c --- /dev/null +++ b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample1.razor @@ -0,0 +1,15 @@ + +
+ + + + + + + + +
+ +@code { + string[] _collection = new string[] { "Foo", "Bar", "Fizz", "Buzz" }; +} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample2.razor b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample2.razor new file mode 100644 index 00000000..1a032e1c --- /dev/null +++ b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample2.razor @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + @foreach (var state in states) + { + @state + } + + + + + + Primary + Secondary + Tertiary + Info + Success + Warning + Error + + + + +@code{ + Color _color = Color.Primary; + + private string[] states = + { + "Alabama", "Alaska", "American Samoa", "Arizona", + "Arkansas", "California", "Colorado", "Connecticut", + "Delaware", "District of Columbia", "Federated States of Micronesia", + "Florida", "Georgia", "Guam", "Hawaii", "Idaho", + "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", + "Louisiana", "Maine", "Marshall Islands", "Maryland", + "Massachusetts", "Michigan", "Minnesota", "Mississippi", + "Missouri", "Montana", "Nebraska", "Nevada", + "New Hampshire", "New Jersey", "New Mexico", "New York", + "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", + "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", + "Rhode Island", "South Carolina", "South Dakota", "Tennessee", + "Texas", "Utah", "Vermont", "Virgin Island", "Virginia", + "Washington", "West Virginia", "Wisconsin", "Wyoming", + }; +} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample3.razor b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample3.razor new file mode 100644 index 00000000..8c03b301 --- /dev/null +++ b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample3.razor @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Selected Value: @_selectedValue + Selected Values: @(_selectedValues == null ? null : string.Join(", ", _selectedValues)) + + + +@code { + bool _multiSelection = false; + bool _sticky = true; + bool _nested = false; + bool _initiallyExpanded = false; + string _selectedValue; + IEnumerable _selectedValues; +} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample4.razor b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample4.razor new file mode 100644 index 00000000..d4a398eb --- /dev/null +++ b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample4.razor @@ -0,0 +1,96 @@ + + + + + @foreach (var item in _players) + { + @(item.Item1 + " - Total Score: " + item.Item2) + } + + + + + + + + @context.Value.Item1 + + + + @(context.Value.Item3 == true ? "Retired" : "Active") + + Total Score: @context.Value.Item2 + + + + + + + + + + + @context.Value.Item1 + + + + @(context.Value.Item3 == true ? "Retired" : "Active") + + Total Score: @context.Value.Item2 + + + + + + + @context.Value.Item1 + + + + @*@(context.Value.Item3 == true ? "Retired" : "Active")*@ + + Total Score: @context.Value.Item2 + + + + + + + + + + @foreach (var item in _players) + { + @(item.Item1 + " - Total Score: " + item.Item2) + } + + + + + @context.Value.Item1 + Player is unavailable + + + + + + +@code { + Tuple[] _players = new Tuple[] + { + new Tuple("Kareem Abdul-Jabbar", "38.387", true), + new Tuple("LeBron James", "37.062", false), + new Tuple("Karl Malone", "36.928", true), + new Tuple("Kobe Bryant", "33.643", true), + new Tuple("Michael Jordan", "32.292", true), + }; + + private string StringFunc(Tuple tuple) + { + if (tuple == null) + { + return null; + } + return tuple.Item1 + " - Total Score: " + tuple.Item2; + } +} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample5.razor b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample5.razor new file mode 100644 index 00000000..4e3bf563 --- /dev/null +++ b/ComponentViewer.Docs/Pages/Examples/SelectExtendedExample5.razor @@ -0,0 +1,75 @@ + + + + + @foreach (var state in states) + { + + } + + + + + + Standard Text + Customized Text + Chip + + + + Value: + " + @value + " + + + SelectedValues: HashSet<string> + { + @(string.Join(", ", options.Select(x => $"\"{x}\""))) + } + + + + + +@code { + MudRadioGroup _radioGroup; + ValuePresenter _valuePresenter = ValuePresenter.Text; + string value { get; set; } = "Nothing selected"; + IEnumerable options { get; set; } = new HashSet() { "Alaska", "California" }; + + private string[] states = + { + "Alabama", "Alaska", "American Samoa", "Arizona", + "Arkansas", "California", "Colorado", "Connecticut", + "Delaware", "District of Columbia", "Federated States of Micronesia", + "Florida", "Georgia", "Guam", "Hawaii", "Idaho", + "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", + "Louisiana", "Maine", "Marshall Islands", "Maryland", + "Massachusetts", "Michigan", "Minnesota", "Mississippi", + "Missouri", "Montana", "Nebraska", "Nevada", + "New Hampshire", "New Jersey", "New Mexico", "New York", + "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", + "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", + "Rhode Island", "South Carolina", "South Dakota", "Tennessee", + "Texas", "Utah", "Vermont", "Virgin Island", "Virginia", + "Washington", "West Virginia", "Wisconsin", "Wyoming", + }; + + private string GetMultiSelectionText(List selectedValues) + { + return $"{selectedValues.Count} state{(selectedValues.Count > 1 ? "s have" : " has")} been selected"; + } + + private void GroupOptionChanged() + { + if (_radioGroup.SelectedOption == 2) + { + _valuePresenter = ValuePresenter.Chip; + } + else + { + _valuePresenter = ValuePresenter.Text; + } + } +} \ No newline at end of file diff --git a/ComponentViewer.Docs/Pages/Index.razor b/ComponentViewer.Docs/Pages/Index.razor index 98243b41..970cf054 100644 --- a/ComponentViewer.Docs/Pages/Index.razor +++ b/ComponentViewer.Docs/Pages/Index.razor @@ -49,6 +49,11 @@ + + + + From a76813794b2e5db96af97f2a59902915657187ce Mon Sep 17 00:00:00 2001 From: mckaragoz <78308169+mckaragoz@users.noreply.github.com> Date: Mon, 30 Jan 2023 22:35:52 +0300 Subject: [PATCH 2/5] Test Trying --- .../MultiSelectCustomizedTextTest.razor | 45 + .../SelectExtended/MultiSelectTest1.razor | 15 + .../SelectExtended/MultiSelectTest2.razor | 27 + .../SelectExtended/MultiSelectTest3.razor | 35 + .../SelectExtended/MultiSelectTest4.razor | 34 + .../SelectExtended/MultiSelectTest5.razor | 30 + .../MultiSelectTestRequiredValue.razor | 42 + .../SelectExtended/MultiSelectTextTest.razor | 19 + .../MultiSelectWithCustomComparerTest.razor | 52 + .../MultiSelectWithInitialValues.razor | 38 + .../ReloadSelectItemsTest.razor | 54 + .../SelectExtended/ReselectValueTest.razor | 26 + .../SelectExtended/SelectClearableTest.razor | 21 + .../SelectExtended/SelectEventCountTest.razor | 62 + .../SelectInitialValueTest.razor | 20 + .../SelectExtended/SelectOnCloseTest.razor | 21 + .../SelectExtended/SelectRequiredTest.razor | 16 + .../SelectExtended/SelectTest1.razor | 28 + .../SelectExtended/SelectTest2.razor | 15 + .../SelectExtended/SelectTextValueTest.razor | 10 + .../SelectUnrepresentableValueTest.razor | 14 + .../SelectUnrepresentableValueTest2.razor | 14 + .../SelectValidationDataAttrTest.razor | 36 + .../SelectExtended/SelectWithEnumTest.razor | 23 + .../CodeBeam.MudExtensions.UnitTest.csproj | 2 +- .../Components/SelectExtendedTests.cs | 1340 +++++++++++++++++ .../IRenderedComponentExtensions.cs | 46 + 27 files changed, 2084 insertions(+), 1 deletion(-) create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectCustomizedTextTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest1.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest2.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest3.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest4.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest5.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTestRequiredValue.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTextTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReloadSelectItemsTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectClearableTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectEventCountTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectOnCloseTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectRequiredTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest1.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest2.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTextValueTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest2.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectValidationDataAttrTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectWithEnumTest.razor create mode 100644 CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs create mode 100644 CodeBeam.MudExtensions.UnitTest/Extensions/IRenderedComponentExtensions.cs diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectCustomizedTextTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectCustomizedTextTest.razor new file mode 100644 index 00000000..15782507 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectCustomizedTextTest.razor @@ -0,0 +1,45 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + @foreach (TestItem item in AllItems) + { + + } + + +@code { + + private List AllItems = new(); + private HashSet SelectedItems = new(); + protected override async Task OnInitializedAsync() + { + AllItems.Add(new TestItem { A = "FirstA" }); + AllItems.Add(new TestItem { A = "SecondA" }); + AllItems.Add(new TestItem { A = "ThirdA" }); + + SelectedItems.Add(AllItems[0]); + SelectedItems.Add(AllItems[1]); + await base.OnInitializedAsync(); + } + + private string ToString(TestItem x) + => x is null ? string.Empty : $"{x.A}"; + + private string GetMultiSelectionText(List selectedValues) + { + return $"Selected values: {string.Join(", ", selectedValues.Select(x => x.A))}"; + } + + private class TestItem + { + public string A { get; set; } + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest1.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest1.razor new file mode 100644 index 00000000..02874bc6 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest1.razor @@ -0,0 +1,15 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + 1 + 2 + 3 + + + +@code { + public static string __description__ = "Click should not close the menu and selecting multiple values should update the bindable value with a comma separated list."; + + IEnumerable values = new HashSet(); +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest2.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest2.razor new file mode 100644 index 00000000..e912b9fe --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest2.razor @@ -0,0 +1,27 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + @foreach (var item in AllItems) + { + @item + } + + +@code { + public static string __description__ = "Test for the Select All option"; + private List AllItems = new(); + private IEnumerable SelectedItems = new HashSet(); + protected override void OnInitialized() + { + AllItems.Add("FirstA"); + AllItems.Add("SecondA"); + AllItems.Add("ThirdA"); + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest3.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest3.razor new file mode 100644 index 00000000..4332ec98 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest3.razor @@ -0,0 +1,35 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + MudSelect.Value: "@value" + Selected Values: "@string.Join(", ", options ?? new List())" + + + + @foreach (var feline in felines) + { + @feline + } + + + + +@code { + private string value { get; set; } = "Nothing selected"; + private IEnumerable options { get; set; } = new HashSet() { "Lion" }; + + private string[] felines = + { + "Jaguar", "Leopard", "Lion", "Lynx", "Panther", "Puma", "Tiger" + }; + + private string GetMultiSelectionText(List selectedValues) + { + return $"{selectedValues.Count} feline{(selectedValues.Count > 1 ? "s have" : " has")} been selected"; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest4.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest4.razor new file mode 100644 index 00000000..2ec1a3f7 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest4.razor @@ -0,0 +1,34 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + @foreach (var feline in felines) + { + @feline + } + + + + MudSelect.Value: "@value" + + + +@code { + private string value { get; set; } = "Nothing selected"; + private IEnumerable options { get; set; } + + private string[] felines = + { + "Jaguar", "Leopard", "Lion", "Lynx", "Panther", "Puma", "Tiger" + }; + + private string GetMultiSelectionText(List selectedValues) + { + return $"{selectedValues.Count} feline{(selectedValues.Count > 1 ? "s have" : " has")} been selected"; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest5.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest5.razor new file mode 100644 index 00000000..d013ebe0 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTest5.razor @@ -0,0 +1,30 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + +@if (_posts != null) +{ + + @foreach (var role in _posts) + { + @role + } + +} + + +@code +{ + private IEnumerable SelectedValues { get; set; } = new HashSet() + { + "Programista", "test" + }; + + private HashSet _posts; + + protected override void OnInitialized() + { + _posts = new HashSet + { + "Programista", "Programista 2", "test", "Technik", "Tester", "Tester tester" + }; + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTestRequiredValue.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTestRequiredValue.razor new file mode 100644 index 00000000..52d54e00 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTestRequiredValue.razor @@ -0,0 +1,42 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + 1 + 2 + 3 + + + + @foreach(var role in Roles) + { + + } + + +@code { + + public static string __description__ = "Multi-Select Required Should Recognize Values"; + + string value=null; + + public class TestClass + { + public string Name { get; set; } + public string NameTranslated { get; set; } + public override string ToString() => Name; + } + + + public List Roles {get; set; } = new(); + public IEnumerable SelectedRoles = new List(); + + Func converter = p => p?.NameTranslated; + + protected override void OnInitialized() + { + Roles.Add(new TestClass() { Name ="Admin", NameTranslated="Administrator"}); + Roles.Add(new TestClass() { Name ="Customer", NameTranslated="Kunde"}); + } + +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTextTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTextTest.razor new file mode 100644 index 00000000..2cb9859c --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectTextTest.razor @@ -0,0 +1,19 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + + + + +@code { + + +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor new file mode 100644 index 00000000..3f793936 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor @@ -0,0 +1,52 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + + + + + Set Selection + + + +@code { + static CoffeeComparer Comparer { get; } = new(); + + HashSet Selected { get; } = new(Comparer); + + void SelectedChanged(IEnumerable newSelected) + { + Selected.Clear(); + Selected.UnionWith(newSelected); + } + + void SetSelection() + { + Selected.Clear(); + Selected.Add(new("lat", "Selected Cafe Latte")); + Selected.Add(new("esp", "Selected Espresso")); + } + + class Coffee + { + public string Key { get; set; } + public string Name { get; set; } + public Coffee(string key, string name) { Key = key; Name = name; } + } + + class CoffeeComparer : IEqualityComparer + { + public bool Equals(Coffee a, Coffee b) => a.Key == b.Key; + public int GetHashCode(Coffee x) => HashCode.Combine(x.Key); + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor new file mode 100644 index 00000000..9726e8ab --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor @@ -0,0 +1,38 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + @foreach (TestItem item in AllItems) + { + + } + + +@code { + + private List AllItems = new(); + private HashSet SelectedItems = new(); + protected override async Task OnInitializedAsync() + { + AllItems.Add(new TestItem { A = "FirstA" }); + AllItems.Add(new TestItem { A = "SecondA" }); + AllItems.Add(new TestItem { A = "ThirdA" }); + + SelectedItems.Add(AllItems[0]); + SelectedItems.Add(AllItems[1]); + await base.OnInitializedAsync(); + } + + private string ToString(TestItem x) + => x is null ? string.Empty : $"{x.A}"; + + private class TestItem + { + public string A { get; set; } + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReloadSelectItemsTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReloadSelectItemsTest.razor new file mode 100644 index 00000000..e0aa9ea1 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReloadSelectItemsTest.razor @@ -0,0 +1,54 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + @foreach (var state in states) + { + @state + } + + + + MudSelect.Value: "@value" + + +
+Load new states + +@code { + public static string __description__ = "After clicking 'load new states' selecting items should result in the correct values being selected."; + private string value { get; set; } = "Nothing selected"; + + + List states2 = new List() + { + "Alabama", "Alaska", "American Samoa" + }; + + List states = new List() + { + "American Samoa", "Arizona", + "Arkansas", "California", "Colorado", "Connecticut", + "Delaware", "District of Columbia", "Federated States of Micronesia", + "Florida", "Georgia", "Guam", "Hawaii", "Idaho", + "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", + "Louisiana", "Maine", "Marshall Islands", "Maryland", + "Massachusetts", "Michigan", "Minnesota", "Mississippi", + "Missouri", "Montana", "Nebraska", "Nevada", + "New Hampshire", "New Jersey", "New Mexico", "New York", + "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", + "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", + "Rhode Island", "South Carolina", "South Dakota", "Tennessee", + "Texas", "Utah", "Vermont", "Virgin Island", "Virginia", + "Washington", "West Virginia", "Wisconsin", "Wyoming" + }; + + void ChangeStates() + { + value = "Nothing selected"; + states = states2; + } + +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor new file mode 100644 index 00000000..1e088662 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor @@ -0,0 +1,26 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + +
+ + + Apple + Orange + + + @fruit + @ChangeCount +
+ +@code{ + string fruit = "Apple"; + public int ChangeCount { get; private set; } + + void FruitChanged(IEnumerable fruits) + { + ChangeCount++; + } +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectClearableTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectClearableTest.razor new file mode 100644 index 00000000..9a4a17a8 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectClearableTest.razor @@ -0,0 +1,21 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + +@code { + public static string __description__ = "Initially hidden clear button should show when item is selected."; + + string value = null; + + public bool ClearButtonClicked { get; set; } + + private void ClearButtonClickHandler(MouseEventArgs e) + { + ClearButtonClicked = true; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectEventCountTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectEventCountTest.razor new file mode 100644 index 00000000..c1a31171 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectEventCountTest.razor @@ -0,0 +1,62 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents +@using global::MudExtensions; + +@* + + + + + +*@ + +@code { + [Parameter] + public bool MultiSelection { get; set; } + + public int ValueChangeCount { get; set; } + public int ValuesChangeCount { get; set; } + public int ItemChangeCount { get; set; } + public int ItemsChangeCount { get; set; } + MudSelectExtended _select; + MudSelectItemExtended FirstItem { get; set; } + MudSelectItemExtended SecondItem { get; set; } + MudSelectItemExtended ThirdItem { get; set; } + + //public void SetSelectedItem() + //{ + // #pragma warning disable BL0005 + // _select.SelectedItem = SecondItem; + //} + + //public void SetSelectedItems() + //{ + // _select.SelectedItems = new HashSet>() { SecondItem, ThirdItem }; + // //StateHasChanged(); + //} + + //public void SetReverseSelectedItems() + //{ + // _select.SelectedItems = new HashSet>() { ThirdItem, FirstItem }; + // //StateHasChanged(); + //} + + private void ValueChanged() + { + ValueChangeCount++; + } + + private void ValuesChanged() + { + ValuesChangeCount++; + } + + private void ItemChanged() + { + ItemChangeCount++; + } + + private void ItemsChanged() + { + ItemsChangeCount++; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor new file mode 100644 index 00000000..fe338c37 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor @@ -0,0 +1,20 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + +@code { + public static string __description__ = "Click should open the Menu and selecting a value should update the bindable value."; + + [Parameter] + public string SelectedValue { get; set; } + [Parameter] + public IEnumerable SelectedValues { get; set; } + [Parameter] + public bool MultiSelection { get; set; } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectOnCloseTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectOnCloseTest.razor new file mode 100644 index 00000000..a2498765 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectOnCloseTest.razor @@ -0,0 +1,21 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + +selected: @Selected + +selected When OnClose: @SelectedWhenOnClose +@code { + public string Selected { get; set; } = ""; + public string SelectedWhenOnClose { get; set; } = ""; + + public void onClose() + { + SelectedWhenOnClose = Selected; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectRequiredTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectRequiredTest.razor new file mode 100644 index 00000000..c81243fa --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectRequiredTest.razor @@ -0,0 +1,16 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + +@code +{ + public static string __description__ = "The Select should not show required-error initially. The first (empty) item should."; + + string value = null; +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest1.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest1.razor new file mode 100644 index 00000000..5da3a739 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest1.razor @@ -0,0 +1,28 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + + + +@code { + public static string __description__ = "Click should open the Menu and selecting a value should update the bindable value."; + + string value = null; + bool _focused = false; + + private void Focused() + { + _focused = true; + } + + private void Blurred() + { + _focused = false; + } +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest2.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest2.razor new file mode 100644 index 00000000..d23ed2ba --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTest2.razor @@ -0,0 +1,15 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + + +@code { + public static string __description__ = "Value 2 should be selected initially and hilighted."; + + string value="2"; +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTextValueTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTextValueTest.razor new file mode 100644 index 00000000..6f45c257 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectTextValueTest.razor @@ -0,0 +1,10 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + +@code { + public bool? _boolValue { get; set; } = true; +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest.razor new file mode 100644 index 00000000..c5f55675 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest.razor @@ -0,0 +1,14 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + One + Two + Three + + +@code { + public static string __description__ = "Initially, since the value is not in the list of options, it should be shown as text instead of render fragment."; + + int value=17; +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest2.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest2.razor new file mode 100644 index 00000000..aa8a5c6f --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectUnrepresentableValueTest2.razor @@ -0,0 +1,14 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + +@code { + public static string __description__ = "Don't show initial value which is not in list because of Strict=true."; + + int value=17; +} diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectValidationDataAttrTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectValidationDataAttrTest.razor new file mode 100644 index 00000000..41e1afbb --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectValidationDataAttrTest.razor @@ -0,0 +1,36 @@ +@using System.ComponentModel.DataAnnotations +@using Microsoft.AspNetCore.Components.Forms +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + + + + + + + @foreach (var v in metasyntacticVariable) + { + @v + } + + + + +@code { + #pragma warning disable CS1998 // async without await + public static string __description__ = "Test use of data attributes accessible using `For` bound expression."; + + class TestModel + { + [StringLength(3, ErrorMessage = "Should not be longer than 3")] + public string Value { get; set; } + } + + private TestModel Model { get; set; } = new TestModel(); + + // What does this awkward var name means ? => https://en.wikipedia.org/wiki/Metasyntactic_variable + private string[] metasyntacticVariable = + { + "Foo", "Bar", "Qux", "Quux" + }; +} \ No newline at end of file diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectWithEnumTest.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectWithEnumTest.razor new file mode 100644 index 00000000..a8dbdd81 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/TestComponents/SelectExtended/SelectWithEnumTest.razor @@ -0,0 +1,23 @@ +@namespace CodeBeam.MudExtensions.UnitTests.TestComponents + + +Value: @Selected +
+ + @foreach (MyEnum item in Enum.GetValues(typeof(MyEnum))) + { + @item + } + + +@code { + public static string __description__ = "Initial Text should be the enum's default value."; + + public MyEnum Selected { get; set; } + + public enum MyEnum + { + First, + Second, + } +} diff --git a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj b/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj index 44c25659..b95e267c 100644 --- a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj +++ b/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj @@ -9,7 +9,7 @@ - + diff --git a/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs b/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs new file mode 100644 index 00000000..3cd963a0 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs @@ -0,0 +1,1340 @@ +#pragma warning disable CS1998 // async without await +#pragma warning disable IDE1006 // leading underscore +#pragma warning disable BL0005 // Set parameter outside component + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Bunit; +using CodeBeam.MudExtensions.UnitTests; +using CodeBeam.MudExtensions.UnitTests.Components; +using CodeBeam.MudExtensions.UnitTests.TestComponents; +using FluentAssertions; +using Microsoft.AspNetCore.Components.Web; +using MudExtensions; +using NUnit.Framework; +using static CodeBeam.MudExtensions.UnitTests.TestComponents.SelectWithEnumTest; + +namespace MudBlazor.UnitTests.Components +{ + [TestFixture] + public class SelectExtendedTests : BunitTest + { + /// + /// Select id should propagate to label for attribute + /// + [Test] + public void SelectLabelFor() + { + var comp = Context.RenderComponent(); + var label = comp.FindAll(".mud-input-label"); + label[0].Attributes.GetNamedItem("for")?.Value.Should().Be("selectLabelTest"); + } + + // Note: MudSelect doesn't guaranteed the consequences of changing Value if MultiSelection is true for now. + // When this feature will add, just uncomment the testcase to test it. No need to write new test. + [Test] + [TestCase(false)] + //[TestCase(true)] + public void Select_InitialValueTest(bool multiSelection) + { + var comp = Context.RenderComponent(x => + { + x.Add(c => c.SelectedValue, "1"); + x.Add(c => c.MultiSelection, multiSelection); + }); + var select = comp.FindComponent>(); + + select.Instance.Value.Should().Be("1"); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "1" }); + select.Instance.Text.Should().Be("1"); + } + + // Note: MudSelect doesn't guaranteed the consequences of changing SelectedValues if MultiSelection is false for now. + // When this feature will add, just uncomment the testcase to test it. No need to write new test. + [Test] + //[TestCase(false)] + [TestCase(true)] + public void Select_InitialValuesTest(bool multiSelection) + { + var comp = Context.RenderComponent(x => + { + x.Add(c => c.SelectedValues, new HashSet() { "1" }); + x.Add(c => c.MultiSelection, multiSelection); + }); + var select = comp.FindComponent>(); + + select.Instance.Value.Should().Be("1"); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "1" }); + select.Instance.Text.Should().Be("1"); + } + + [Test] + public async Task Select_ValueBubblingTest() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + + select.Instance.Value.Should().BeNull(); + select.Instance.Text.Should().BeNull(); + + comp.SetParam("SelectedValue", "1"); + await comp.InvokeAsync(() => select.Instance.ForceUpdate()); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "1" }); + select.Instance.Text.Should().Be("1"); + + comp.SetParam("SelectedValue", "2"); + await comp.InvokeAsync(() => select.Instance.ForceUpdate()); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "2" }); + select.Instance.Text.Should().Be("2"); + } + + [Test] + public void Select_ValueBubblingTest_MultiSelection() + { + var comp = Context.RenderComponent(x => + { + x.Add(c => c.MultiSelection, true); + }); + var select = comp.FindComponent>(); + + select.Instance.Value.Should().BeNull(); + select.Instance.Text.Should().BeNullOrEmpty(); + + comp.SetParam("SelectedValues", new HashSet() { "1" }); + select.Instance.Value.Should().Be("1"); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "1" }); + select.Instance.Text.Should().Be("1"); + + comp.SetParam("SelectedValues", new HashSet() { "2", "1" }); + select.Instance.Value.Should().Be("1"); + select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "2", "1" }); + select.Instance.Text.Should().Be("2, 1"); + } + + [Test] + public async Task Select_ValueChangeEventCountTest() + { + var comp = Context.RenderComponent(x => + { + x.Add(c => c.MultiSelection, false); + }); + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + comp.Instance.ValueChangeCount.Should().Be(0); + comp.Instance.ValuesChangeCount.Should().Be(0); + + await comp.InvokeAsync(() => select.SetParam("Value", "1")); + await comp.InvokeAsync(() => select.Instance.ForceUpdate()); + comp.WaitForAssertion(() => comp.Instance.ValueChangeCount.Should().Be(1)); + comp.Instance.ValuesChangeCount.Should().Be(1); + select.Instance.Value.Should().Be("1"); + + // Changing value programmatically without ForceUpdate should change value, but should not fire change events + // Its by design, so this part can be change if design changes + await comp.InvokeAsync(() => select.SetParam("Value", "2")); + comp.WaitForAssertion(() => comp.Instance.ValueChangeCount.Should().Be(1)); + comp.Instance.ValuesChangeCount.Should().Be(1); + select.Instance.Value.Should().Be("2"); + } + + [Test] + public async Task Select_ValueChangeEventCountTest_MultiSelection() + { + var comp = Context.RenderComponent(x => + { + x.Add(c => c.MultiSelection, true); + }); + var select = comp.FindComponent>(); + + comp.Instance.ValueChangeCount.Should().Be(0); + comp.Instance.ValuesChangeCount.Should().Be(0); + comp.Instance.ItemChangeCount.Should().Be(0); + comp.Instance.ItemsChangeCount.Should().Be(0); + + await comp.InvokeAsync(() => select.SetParam("SelectedValues", new HashSet() { "1" })); + comp.WaitForAssertion(() => comp.Instance.ValueChangeCount.Should().Be(1)); + comp.Instance.ValuesChangeCount.Should().Be(1); + + // Setting same value should not fire events + await comp.InvokeAsync(() => select.SetParam("SelectedValues", new HashSet() { "1" })); + comp.WaitForAssertion(() => comp.Instance.ValueChangeCount.Should().Be(1)); + comp.Instance.ValuesChangeCount.Should().Be(1); + } + + /// + /// Click should open the Menu and selecting a value should update the bindable value. + /// + [Test] + public async Task SelectTest1() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check popover class + menu.ClassList.Should().Contain("select-popover-class"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + input.Click(); + menu.ClassList.Should().Contain("mud-popover-open"); + // now click an item and see the value change + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item").ToArray(); + items[1].Click(); + // menu should be closed now + comp.WaitForAssertion(() => menu.ClassList.Should().NotContain("mud-popover-open")); + select.Instance.Value.Should().Be("2"); + // now we cheat and click the list without opening the menu ;) + + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + items = comp.FindAll("div.mud-list-item").ToArray(); + + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + //Check user on blur implementation works + var @switch = comp.FindComponent>(); + @switch.Instance.Checked = true; + await comp.InvokeAsync(() => select.Instance.OnLostFocus(new FocusEventArgs())); + comp.WaitForAssertion(() => @switch.Instance.Checked.Should().Be(false)); + } + + /// + /// Click should not close the menu and selecting multiple values should update the bindable value with a comma separated list. + /// + [Test] + public async Task MultiSelectTest1() + { + //await ImproveChanceOfSuccess(async () => + //{ + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => + comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + await comp.InvokeAsync(() => input.Click()); + comp.WaitForAssertion(() => menu.ClassList.Should().Contain("mud-popover-open")); + // now click an item and see the value change + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item").ToArray(); + items[1].Click(); + // menu should still be open now!! + menu.ClassList.Should().Contain("mud-popover-open"); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2")); + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 1")); + items[2].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 1, 3")); + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 3")); + select.Instance.SelectedValues.Count().Should().Be(2); + select.Instance.SelectedValues.Should().Contain("2"); + select.Instance.SelectedValues.Should().Contain("3"); + //Console.WriteLine(comp.Markup); + const string @unchecked = + "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"; + const string @checked = + "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"; + // check that the correct items are checked + comp.WaitForAssertion(() => + comp.FindAll("div.mud-list-item path")[1].Attributes["d"].Value.Should().Be(@unchecked)); + comp.FindAll("div.mud-list-item path")[3].Attributes["d"].Value.Should().Be(@checked); + comp.FindAll("div.mud-list-item path")[5].Attributes["d"].Value.Should().Be(@checked); + // now check how setting the SelectedValues makes items checked or unchecked + // Note: If popover is open, selecting values programmatically doesn't work for now. + await comp.InvokeAsync(() => select.Instance.CloseMenu()); + await comp.InvokeAsync(() => + { + select.Instance.SelectedValues = new HashSet() { "1", "2" }; + }); + await comp.InvokeAsync(() => input.Click()); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item path")[1].Attributes["d"].Value.Should().Be(@checked)); + comp.FindAll("div.mud-list-item path")[3].Attributes["d"].Value.Should().Be(@checked); + select.Instance.SelectedValues.Should().NotContain("3"); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item path")[5].Attributes["d"].Value.Should().Be(@unchecked)); + //Console.WriteLine(comp.Markup); + //}); + } + + /// + /// Initial Text should be enums default value + /// Initial render fragment in input should be the pre-selected value's items's render fragment. + /// After clicking the second item, the render fragment should update + /// + [Test] + public async Task SelectWithEnumTest() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + select.Instance.Value.Should().Be(default(MyEnum)); + select.Instance.Text.Should().Be(default(MyEnum).ToString()); + + comp.Find("input").Attributes["value"]?.Value.Should().Be("First"); + comp.RenderCount.Should().Be(1); + + //Console.WriteLine(comp.Markup); + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + comp.WaitForAssertion(() => comp.Find("input").Attributes["value"]?.Value.Should().Be("Second")); + } + + /// + /// Initially we have a value of 17 which is not in the list. So we render it as text via MudInput + /// + [Test] + public void SelectUnrepresentableValueTest() + { + var comp = Context.RenderComponent(); + // select elements needed for the test + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + select.Instance.Value.Should().Be(17); + select.Instance.Text.Should().Be("17"); + comp.Find("input").Attributes["value"]?.Value.Should().Be("17"); + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].TextContent.Should().Be("Two"); + items[1].Click(); + //Console.WriteLine(comp.Markup); + //comp.WaitForAssertion(() => comp.Find("div.mud-input-slot").TextContent.Trim().Should().Be("Two")); + select.Instance.Value.Should().Be(2); + select.Instance.Text.Should().Be("2"); + } + + /// + /// Don't show initial value which is not in list because of Strict=true. + /// + [Test] + public void SelectUnrepresentableValueTest2() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + select.Instance.Value.Should().Be(17); + select.Instance.Text.Should().Be("17"); + //await Task.Delay(100); + // BUT: we have a select with Strict="true" so the Text will not be shown because it is not in the list of selectable values + comp.FindComponent>().Instance.Value.Should().Be(null); + comp.FindComponent>().Instance.InputType.Should().Be(InputType.Hidden); + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be(2)); + select.Instance.Text.Should().Be("2"); + //Console.WriteLine(comp.Markup); + comp.FindComponent>().Instance.Value.Should().Be("2"); + comp.FindComponent>().Instance.InputType.Should().Be(InputType.Hidden); // because list item has no render fragment, so we show it as text + } + + /// + /// The items have no render fragments, so instead of RF the select must display the converted string value + /// + [Test] + public void SelectWithoutItemPresentersTest() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + select.Instance.Value.Should().BeTrue(); + select.Instance.Text.Should().Be("Open"); + //comp.Find("div.mud-input-slot").Attributes["style"].Value.Should().Contain("display:none"); + //comp.RenderCount.Should().Be(1); + ////Console.WriteLine(comp.Markup); + + //Last item doesn't have text, so it should show value as text. + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[2].Click(); + //comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + //comp.WaitForAssertion(() => comp.Find("div.mud-input-slot").Attributes["style"].Value.Should().Contain("display:none")); + select.Instance.Value.Should().BeFalse(); + select.Instance.Text.Should().Be("False"); + + input.Click(); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[0].Click(); + select.Instance.Value.Should().BeNull(); + select.Instance.Text.Should().Be("Open and Closed"); + } + + [Test] + public void Select_Should_FireTextChangedWithNewValue() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + string text = null; + select.SetCallback(s => s.TextChanged, x => text = x); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + menu.ClassList.Should().Contain("mud-popover-open"); + // now click an item and see the value change + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + // menu should be closed now + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + select.Instance.Text.Should().Be("2"); + text.Should().Be("2"); + + //open the menu again + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + select.Instance.Text.Should().Be("1"); + text.Should().Be("1"); + } + + /// + /// SingleSelect: SelectedValuesChanged should be fired before TextChanged + /// We test this by checking the counter. The event which should be fired first must always + /// find an even counter value, the second must always find an odd value. + /// + [Test] + public void SingleSelect_Should_FireTextChangedBeforeSelectedValuesChanged() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + string text = null; + IEnumerable selectedValues = null; + var eventCounter = 0; + var textChangedCount = 0; + var selectedValuesChangedCount = 0; + select.SetCallback(s => s.TextChanged, x => + { + textChangedCount = eventCounter++; + text = x; + }); + select.SetCallback(s => s.SelectedValuesChanged, x => + { + selectedValuesChangedCount = eventCounter++; + selectedValues = x; + }); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + menu.ClassList.Should().Contain("mud-popover-open"); + // now click an item and see the value change + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item").ToArray(); + items[1].Click(); + // menu should be closed now + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + select.Instance.Text.Should().Be("2"); + text.Should().Be("2"); + selectedValuesChangedCount.Should().Be(1); + textChangedCount.Should().Be(0); + string.Join(",", selectedValues).Should().Be("2"); + + input.Click(); + comp.WaitForAssertion(()=>comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + select.Instance.Text.Should().Be("1"); + text.Should().Be("1"); + string.Join(",", selectedValues).Should().Be("1"); + comp.WaitForAssertion(() => selectedValuesChangedCount.Should().Be(3)); + comp.WaitForAssertion(() => textChangedCount.Should().Be(2)); + } + + /// + /// MultiSelect: SelectedValuesChanged should be fired before TextChanged + /// We test this by checking the counter. The event which should be fired first must always + /// find an even counter value, the second must always find an odd value. + /// + [Test] + public void MulitSelect_Should_FireTextChangedBeforeSelectedValuesChanged() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + string text = null; + IEnumerable selectedValues = null; + var eventCounter = 0; + var textChangedCount = 0; + var selectedValuesChangedCount = 0; + select.SetParam(s => s.MultiSelection, true); + select.SetCallback(s => s.TextChanged, x => + { + textChangedCount = eventCounter++; + text = x; + }); + select.SetCallback(s => s.SelectedValuesChanged, x => + { + selectedValuesChangedCount = eventCounter++; + selectedValues = x; + }); + + var selectElement = comp.Find("div.mud-input-control"); + selectElement.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + // click list item + items[1].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + select.Instance.Text.Should().Be("2"); + text.Should().Be("2"); + selectedValuesChangedCount.Should().Be(1); + textChangedCount.Should().Be(0); + string.Join(",", selectedValues).Should().Be("2"); + // click another list item + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + items = comp.FindAll("div.mud-list-item").ToArray(); + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().BeEquivalentTo(new HashSet() { "2", "1" })); + select.Instance.Text.Should().Be("2, 1"); + text.Should().Be("2, 1"); + string.Join(",", selectedValues).Should().Be("2,1"); + selectedValuesChangedCount.Should().Be(3); + textChangedCount.Should().Be(2); + } + + [Test] + public async Task Select_Should_Not_FireOnBlur() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + var eventCounter = 0; + select.SetCallback(s => s.OnBlur, x => eventCounter++); + await comp.InvokeAsync(async () => + { + await select.Instance.OpenMenu(); + await select.Instance.CloseMenu(); + }); + eventCounter.Should().Be(0); + } + + [Test] + public void Disabled_SelectItem_Should_Be_Respected() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + //Console.WriteLine(comp.Markup); + + var selectElement = comp.Find("div.mud-input-control"); + selectElement.Click(); + + // Disabled item found twice because we have 2 shadow lists. Need to be discussed later + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-disabled-extended").Count.Should().Be(2)); + comp.FindAll("div.mud-list-item-disabled-extended")[0].Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().BeNull()); + } + + [Test] + public async Task MultiSelect_ShouldCallValidationFunc() + { + //await ImproveChanceOfSuccess(async () => + //{ + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + IEnumerable validatedValue = null; + select.SetParam(x => x.Validation, new Func(value => + { + validatedValue = select.Instance.SelectedValues; + return true; + })); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + select.Instance.SelectedValues.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + comp.WaitForAssertion(() => menu.ClassList.Should().Contain("mud-popover-open")); + // now click an item and see the value change + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + await comp.InvokeAsync(() => items[1].Click()); + // menu should still be open now!! + comp.WaitForAssertion(() => menu.ClassList.Should().Contain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2")); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("2")); + validatedValue.Should().BeEquivalentTo(new HashSet() { "2" }); + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 1")); + validatedValue.Should().BeEquivalentTo(new HashSet() { "2", "1" }); + items[2].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 1, 3")); + validatedValue.Should().BeEquivalentTo(new HashSet() { "2", "1", "3" }); + items[0].Click(); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("2, 3")); + validatedValue.Should().BeEquivalentTo(new HashSet() { "2", "3" }); + //}); + } + + [Test] + public void MultiSelect_SelectAll() + { + var comp = Context.RenderComponent(); + // select element needed for the test + var select = comp.FindComponent>(); + IEnumerable validatedValue = null; + select.SetParam(x => x.Validation, (object)new Func(value => + { + validatedValue = select.Instance.SelectedValues; // NOTE: select does only update the value for T string + return true; + })); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // Open the menu + input.Click(); + menu.ClassList.Should().Contain("mud-popover-open"); + + comp.FindAll("div.mud-list-item-extended")[0].Click(); + // validate the result. all items should be selected + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("FirstA^SecondA^ThirdA")); + validatedValue.Should().BeEquivalentTo(new HashSet() { "FirstA", "SecondA", "ThirdA"}); + } + + [Test] + public void MultiSelect_SelectAll2() + { + var comp = Context.RenderComponent(); + // select element needed for the test + var select = comp.FindComponent>(); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // Open the menu + input.Click(); + menu.ClassList.Should().Contain("mud-popover-open"); + + // get the first (select all item) and check if it is indeterminate + var selectAllItem = comp.FindComponent>(); + selectAllItem.Instance.Icon.Should().Be(Icons.Filled.IndeterminateCheckBox); + + // Check that all normal select items are actually selected + //var items = comp.FindComponents>().Where(x=>x.Instance.HideContent==false).ToArray(); + + //items.Should().HaveCount(7); + //foreach (var item in items) + //{ + // item.Instance.IsSelected.Should().BeTrue(); + // item.FindComponent>().Instance.Icon.Should().Be(""); + //} + + //// Check shadow items + //var shadowItems = comp.FindComponents>().Where(x => x.Instance.HideContent == true).ToArray(); + //foreach (var item in shadowItems) + //{ + // // shadow items don't render, their state is irrelevant, all they do is provide render fragments to the select + // Assert.Throws(() => item.FindComponent>()); + //} + } + + [Test] + public void MultiSelect_SelectAll3() + { + var comp = Context.RenderComponent(); + // select element needed for the test + var select = comp.FindComponent>(); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // Open the menu + input.Click(); + menu.ClassList.Should().Contain("mud-popover-open"); + // Check that the icon corresponds to an unchecked checkbox + var mudListItem = comp.FindComponent>(); + mudListItem.Instance.Icon.Should().Be(""); + } + + [Test] + public void SingleSelect_Should_CallValidationFunc() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + string validatedValue = null; + select.SetParam(x => x.Validation, (object)new Func(value => + { + validatedValue = value; // NOTE: select does only update the value for T string + return true; + })); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + // check initial state + select.Instance.Value.Should().BeNullOrEmpty(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + // click and check if it has toggled the menu + input.Click(); + menu.ClassList.Should().Contain("mud-popover-open"); + // now click an item and see the value change + comp.WaitForAssertion(()=> comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + + comp.FindAll("div.mud-list-item")[1].Click(); + // menu should be closed now + comp.WaitForAssertion(() => menu.ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + select.Instance.Text.Should().Be("2"); + validatedValue.Should().Be("2"); + + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + comp.FindAll("div.mud-list-item")[0].Click(); + + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + select.Instance.Text.Should().Be("1"); + validatedValue.Should().Be("1"); + } + + /// + /// We filled the multiselect with initial selected values, that must + /// show in the value of the input as a comma separated list of strings + /// + /// + [Test] + public async Task MultiSelect_Initial_Values() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + + // select the input of the select + var input = comp.Find("input"); + //the value of the input + var value = input.Attributes.Where(a => a.LocalName == "value").First().Value; + value.Should().Be("FirstA, SecondA"); + } + + [Test] + public async Task MultiSelectTextTest() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + var selectItems = comp.FindAll("div.mud-list-item-extended"); + foreach (var item in selectItems) + { + item.Click(); + } + + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("Empty, One, 2, 3")); + } + + /// + /// We filled the multiselect with initial selected values. + /// Then the returned text in the selection is customized. + /// + /// + [Test] + public async Task MultiSelectCustomizedTextTest() + { + var comp = Context.RenderComponent(); + + // Select the input of the select + var input = comp.Find("input"); + + // The value of the input + var value = input.Attributes.Where(a => a.LocalName == "value").First().Value; + + // Value is equal to the customized values returned by the method + value.Should().Be("Selected values: FirstA, SecondA"); + } + + [Test] + public async Task SelectClearableTest() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + // No button when initialized + comp.FindAll("button").Should().BeEmpty(); + + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + // Button shows after selecting item + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + comp.Find("button").Should().NotBeNull(); + // Selection cleared and button removed after clicking clear button + comp.Find("button").Click(); + comp.WaitForAssertion(() => select.Instance.Value.Should().BeNullOrEmpty()); + comp.FindAll("button").Should().BeEmpty(); + // Clear button click handler should have been invoked + comp.Instance.ClearButtonClicked.Should().BeTrue(); + } + + /// + /// Reselect an already selected value should not call SelectedValuesChanged event. + /// + [Test] + public void SelectReselectTest() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + var menu = comp.Find("div.mud-popover"); + var input = comp.Find("div.mud-input-control"); + + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + select.Instance.Value.Should().Be("Apple"); + comp.Instance.ChangeCount.Should().Be(0); + + // now click an item and see the value change + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + + // menu should be closed now + comp.WaitForAssertion(() => menu.ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Orange")); + comp.Instance.ChangeCount.Should().Be(1); + + // now click an item and see the value change + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Orange")); + comp.Instance.ChangeCount.Should().Be(1); + + } + + #region DataAttribute validation + [Test] + public async Task TextField_Should_Validate_Data_Attribute_Fail() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var selectcomp = comp.FindComponent>(); + var select = selectcomp.Instance; + // Select invalid option + await comp.InvokeAsync(() => select.SelectOption("Quux")); + // check initial state + select.Value.Should().Be("Quux"); + select.Text.Should().Be("Quux"); + // check validity + await comp.InvokeAsync(() => select.Validate()); + select.ValidationErrors.Should().NotBeEmpty(); + select.ValidationErrors.Should().HaveCount(1); + select.ValidationErrors[0].Should().Be("Should not be longer than 3"); + } + + [Test] + public async Task TextField_Should_Validate_Data_Attribute_Success() + { + var comp = Context.RenderComponent(); + //Console.WriteLine(comp.Markup); + var selectcomp = comp.FindComponent>(); + var select = selectcomp.Instance; + // Select valid option + await comp.InvokeAsync(() => select.SelectOption("Qux")); + // check initial state + select.Value.Should().Be("Qux"); + select.Text.Should().Be("Qux"); + // check validity + await comp.InvokeAsync(() => select.Validate()); + select.ValidationErrors.Should().BeEmpty(); + } + #endregion + + /// + /// Tests the required property. + /// + [Test] + public async Task Select_Should_SetRequiredTrue() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>().Instance; + select.Required.Should().BeTrue(); + await comp.InvokeAsync(() => select.Validate()); + select.ValidationErrors.First().Should().Be("Required"); + } + + /// + /// Selected option should be hilighted when drop-down opens + /// + [Test] + public async Task Select_Should_HilightSelectedValue() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + var input = comp.Find("div.mud-input-control"); + + comp.Find("div.mud-popover").ClassList.Should().Contain("select-popover-class"); + select.Instance.Value.Should().BeNullOrEmpty(); + comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open"); + // open the select + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + // no option should be hilited + comp.WaitForAssertion(() => comp.FindAll("div.mud-selected-item").Count.Should().Be(0)); + // now click an item and see the value change + comp.FindAll("div.mud-list-item")[1].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("2")); + // open again and check hilited option + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + // Nr 2 should be hilited + comp.WaitForAssertion(() => comp.FindAll("div.mud-selected-item").Count.Should().Be(1)); + comp.FindAll("div.mud-list-item-extended")[1].ToMarkup().Should().Contain("mud-selected-item"); + await comp.InvokeAsync(() => select.Instance.CloseMenu()); + select.SetParam(nameof(MudSelectExtended.Value), null); + await comp.InvokeAsync(() => select.Instance.OpenMenu()); + // no option should be hilited + comp.WaitForAssertion(() => comp.FindAll("div.mud-selected-item").Count.Should().Be(0)); + } + + /// + /// Initially selected option should be hilighted when drop-down opens + /// + [Test] + public void Select_Should_HilightInitiallySelectedValue() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + var select = comp.FindComponent>(); + comp.Find("div.mud-popover").ClassList.Should().Contain("select-popover-class"); + select.Instance.Value.Should().Be("2"); + comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open"); + // open the select + comp.Find("div.mud-input-control").Click(); + //Console.WriteLine(comp.Markup); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + // Nr 2 should be hilited + comp.WaitForAssertion(() => comp.FindAll("div.mud-selected-item").Count.Should().Be(1)); + comp.FindAll("div.mud-list-item")[1].ToMarkup().Should().Contain("mud-selected-item"); + // now click an item and see the value change + comp.FindAll("div.mud-list-item")[0].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("1")); + // open again and check hilited option + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + // Nr 1 should be hilited + comp.WaitForAssertion(() => comp.FindAll("div.mud-selected-item").Count.Should().Be(1)); + comp.FindAll("div.mud-list-item")[0].ToMarkup().Should().Contain("mud-selected-item"); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + } + + [Test] + public async Task Select_Should_AllowReloadingItems() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + // normal, without reloading + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[0].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("American Samoa")); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[1].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Arizona")); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[2].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Arkansas")); + // reloading! + comp.Find(".reload").Click(); + // check again, different values expected now + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[0].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Alabama")); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[1].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("Alaska")); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.FindAll("div.mud-list-item")[2].Click(); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Instance.Value.Should().Be("American Samoa")); + } + + [Test] + public async Task SelectTest_ToggleOpenCloseMenuMethods() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + + var select = comp.FindComponent>(); + + await comp.InvokeAsync(() => select.Instance.ToggleMenu()); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + select.SetParam("Disabled", true); + await comp.InvokeAsync(() => select.Instance.ToggleMenu()); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + //Try to add null item and check the value should not changed. + await comp.InvokeAsync(() => select.Instance.Add(null)); + comp.WaitForAssertion(() => select.Instance._items.Count.Should().Be(4)); + + select.SetParam("Disabled", false); + await comp.InvokeAsync(() => select.Instance.ToggleMenu()); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + + select.SetParam("Disabled", true); + await comp.InvokeAsync(() => select.Instance.ToggleMenu()); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + + await comp.InvokeAsync(() => select.Instance.OpenMenu()); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + } + + [Test] + public async Task SelectTest_KeyboardNavigation_SingleSelect() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>().Instance; + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + //If we didn't select an item with mouse or arrow keys yet, value should remains null. + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Value.Should().Be(null)); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", AltKey = true, Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", AltKey = true, Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + //If dropdown is closed, arrow key should not set a value. + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + comp.WaitForAssertion(() => select.Value.Should().Be(null)); + // If no item is hiligted, enter should only close popover, not select any item and value + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Value.Should().Be(null)); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().BeNull()); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("2")); + //End key should not select the last disabled item + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("3")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + comp.WaitForAssertion(() => select.Value.Should().Be("3")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("3")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("1")); + //Arrow up should select still the first item + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("1")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("3")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "2", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("3")); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Value.Should().Be("2")); + comp.WaitForAssertion(() => select.SelectedValues.Should().HaveCount(1)); + + await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + //comp.Render(); // <-- this is necessary for reliable passing of the test + // TODO: Look at this line why working manually and not working on test run. + //comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + } + + [Test] + public async Task SelectTest_KeyboardNavigation_MultiSelect() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // select elements needed for the test + var select = comp.FindComponent>(); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "a", CtrlKey = true, Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("7 felines have been selected")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("0 feline has been selected")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("1 feline has been selected")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.Text.Should().Be("7 felines have been selected")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Tiger")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Jaguar")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Leopard")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); + + select.SetParam("Disabled", true); + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); + + select.SetParam("Disabled", false); + //Test the keyup event + await comp.InvokeAsync(() => select.Instance.HandleKeyUp(new KeyboardEventArgs() { Key = "Enter", Type = "keyup", })); + comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); + + await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Tab", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.OnKeyUp.InvokeAsync(new KeyboardEventArgs() { Key = "Tab" })); + comp.Render(); // <-- this is necessary for reliable passing of the test + comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); + } + + [Test] + public async Task SelectTest_ItemlessSelect() + { + var comp = Context.RenderComponent>(); + + // print the generated html + //Console.WriteLine(comp.Markup); + + await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + comp.WaitForAssertion(() => comp.Instance.SelectedValues.Should().HaveCount(0)); + comp.WaitForAssertion(() => comp.Instance.Value.Should().Be(null)); + } + + [Test] + public void Select_OnCloseValueTest() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>(); + + comp.Find("input").Click(); + comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open"); + + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + + comp.Instance.Selected.Should().Be("Cafe Latte"); + comp.Instance.SelectedWhenOnClose.Should().Be("Cafe Latte"); + + comp.Find("input").Click(); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[0].Click(); + comp.Instance.Selected.Should().Be("Cappuccino"); + comp.Instance.SelectedWhenOnClose.Should().Be("Cappuccino"); + } + + [Test] + public void MultiSelectWithCustomComparerTest() + { + var comp = Context.RenderComponent(); + // print the generated html + //Console.WriteLine(comp.Markup); + // Click select button + comp.Find("button").Click(); + // Check input text + comp.Find("input").GetAttribute("value").Should().Be("Selected Cafe Latte, Selected Espresso"); + // Click to render the menu + comp.Find("div.mud-input-control").Click(); + // Check check marks + const string @unchecked = + "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"; + const string @checked = + "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"; + var icons = comp.FindAll("div.mud-list-item path").ToArray(); + icons[1].Attributes["d"].Value.Should().Be(@unchecked); + icons[3].Attributes["d"].Value.Should().Be(@checked); + icons[5].Attributes["d"].Value.Should().Be(@checked); + icons[7].Attributes["d"].Value.Should().Be(@unchecked); + } + + [Test] + public void Select_Item_Collection_Should_Match_Number_Of_Select_Options() + { + var comp = Context.RenderComponent(); + var sut = comp.FindComponent>(); + + var input = comp.Find("div.mud-input-control"); + input.Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); + + sut.Instance.Items.Should().HaveCountGreaterOrEqualTo(4); + } + + /// + /// When MultiSelection and Required are True with no selected values, required validation should fail. + /// + [Test] + public async Task MultiSelectWithRequiredValue() + { + //1a. Check When SelectedItems is empty - Validation Should Fail + //Check on String type + var comp = Context.RenderComponent(); + var select = comp.FindComponent>().Instance; + select.Required.Should().BeTrue(); + await comp.InvokeAsync(() => select.Validate()); + select.ValidationErrors.First().Should().Be("Required"); + + //1b. Check on T type - MultiSelect of T(e.g. class object) + var selectWithT = comp.FindComponent>().Instance; + selectWithT.Required.Should().BeTrue(); + await comp.InvokeAsync(() => selectWithT.Validate()); + selectWithT.ValidationErrors.First().Should().Be("Required"); + + //2a. Now check when SelectedItems is greater than one - Validation Should Pass + var inputs = comp.FindAll("div.mud-input-control"); + Console.WriteLine(comp.Markup); + inputs[0].Click();//The 2nd one is the + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[1].Click(); + await comp.InvokeAsync(() => select.Validate()); + select.ValidationErrors.Count.Should().Be(0); + + //2b. + inputs[1].Click();//selectWithT + //wait for render and it will find 5 items from the component (5 also with shadow list) + comp.FindAll("div.mud-list-item").Count.Should().Be(10); + //comp.WaitForState(() => comp.FindAll("div.mud-list-item").Count == 5); + items = comp.FindAll("div.mud-list-item-extended").ToArray(); + items[3].Click(); + await comp.InvokeAsync(() => selectWithT.Validate()); + selectWithT.ValidationErrors.Count.Should().Be(0); + } + + /// + /// When MultiSelect attribute goes after SelectedValues, text should contain all selected values. + /// + [Test] + public async Task MultiSelectAttributesOrder() + { + var comp = Context.RenderComponent(); + var select = comp.FindComponent>().Instance; + select.SelectedValues.Count().Should().Be(2); + select.Text.Should().Be("Programista, test"); + await comp.InvokeAsync(() => + { + select.SelectedValues = new List { "test" }; + }); + select.SelectedValues.Count().Should().Be(1); + select.Text.Should().Be("test"); + } + } +} diff --git a/CodeBeam.MudExtensions.UnitTest/Extensions/IRenderedComponentExtensions.cs b/CodeBeam.MudExtensions.UnitTest/Extensions/IRenderedComponentExtensions.cs new file mode 100644 index 00000000..764b17f7 --- /dev/null +++ b/CodeBeam.MudExtensions.UnitTest/Extensions/IRenderedComponentExtensions.cs @@ -0,0 +1,46 @@ + +#pragma warning disable 8632 + +using System; +using System.Linq.Expressions; +using Bunit; +using Microsoft.AspNetCore.Components; + +namespace CodeBeam.MudExtensions.UnitTests +{ + public static class IRenderedComponentExtensions + { + public static void SetParam(this IRenderedComponentBase self, string name, object? value) where T : IComponent + { + self.SetParametersAndRender(ComponentParameter.CreateParameter(name, value)); + } + + public static void SetParam(this IRenderedComponentBase self, Expression> exp, object? value) where T : IComponent + { + var name = (exp.Body as MemberExpression ?? (MemberExpression)((UnaryExpression)exp.Body).Operand).Member.Name; + self.SetParametersAndRender(ComponentParameter.CreateParameter(name, value)); + } + + public static void SetCascadingValue(this IRenderedComponentBase self, Expression> exp, object value) where T : IComponent + { + var name = (exp.Body as MemberExpression ?? (MemberExpression)((UnaryExpression)exp.Body).Operand).Member.Name; + self.SetParametersAndRender(ComponentParameter.CreateCascadingValue(name, value)); + } + + public static void SetCascadingValue(this IRenderedComponentBase self, string name, object value) where T : IComponent + { + self.SetParametersAndRender(ComponentParameter.CreateCascadingValue(name, value)); + } + + public static void SetCallback(this IRenderedComponentBase self, string name, Action callback) where T : IComponent + { + self.SetParametersAndRender(ComponentParameter.CreateParameter(name, new EventCallback(null, callback))); + } + + public static void SetCallback(this IRenderedComponentBase self, Expression>> exp, Action callback) where T : IComponent + { + var name = (exp.Body as MemberExpression ?? (MemberExpression)((UnaryExpression)exp.Body).Operand).Member.Name; + self.SetParametersAndRender(ComponentParameter.CreateParameter(name, new EventCallback(null, callback))); + } + } +} From 130ad25e1e97aeb3ce250265b73f98576ff47071 Mon Sep 17 00:00:00 2001 From: mckaragoz <78308169+mckaragoz@users.noreply.github.com> Date: Tue, 31 Jan 2023 13:27:22 +0300 Subject: [PATCH 3/5] Some Fix --- .../Pages/Index.razor | 2 ++ .../Program.cs | 3 +++ .../Shared/MainLayout.razor | 4 ++++ .../wwwroot/index.html | 4 ++++ .../CodeBeam.MudExtensions.UnitTest.csproj | 2 +- .../Components/SelectExtendedTests.cs | 18 +++++++++--------- .../CodeBeam.MudExtensions.csproj | 4 ++-- .../Styles/Components/_selectextended.scss | 2 +- .../Styles/MudExtensions.css | 2 +- .../Styles/MudExtensions.min.css | 2 +- .../wwwroot/MudExtensions.min.css | 2 +- 11 files changed, 29 insertions(+), 16 deletions(-) diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor index 6085c4aa..860e1de0 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor @@ -7,3 +7,5 @@ Welcome to your new app. + + diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs b/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs index e87c66f7..d91196fb 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs @@ -1,11 +1,14 @@ using CodeBeam.MudExtensions.UnitTest.Viewer; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using MudBlazor.Services; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddMudServices(); +builder.Services.AddMudExtensions(); await builder.Build().RunAsync(); diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor b/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor index 839b8fe6..d5afdf4c 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor @@ -15,3 +15,7 @@ + + + + diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/wwwroot/index.html b/CodeBeam.MudExtensions.UnitTest.Viewer/wwwroot/index.html index b5faf62f..21728fae 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/wwwroot/index.html +++ b/CodeBeam.MudExtensions.UnitTest.Viewer/wwwroot/index.html @@ -10,6 +10,8 @@ + + @@ -27,6 +29,8 @@ 🗙 + + diff --git a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj b/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj index b95e267c..3fe30904 100644 --- a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj +++ b/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj @@ -9,7 +9,7 @@ - + diff --git a/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs b/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs index 3cd963a0..efde95e5 100644 --- a/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs +++ b/CodeBeam.MudExtensions.UnitTest/Components/SelectExtendedTests.cs @@ -219,7 +219,7 @@ public async Task MultiSelectTest1() //{ var comp = Context.RenderComponent(); // print the generated html - //Console.WriteLine(comp.Markup); + Console.WriteLine(comp.Markup); // select elements needed for the test var select = comp.FindComponent>(); var menu = comp.Find("div.mud-popover"); @@ -232,8 +232,8 @@ public async Task MultiSelectTest1() await comp.InvokeAsync(() => input.Click()); comp.WaitForAssertion(() => menu.ClassList.Should().Contain("mud-popover-open")); // now click an item and see the value change - comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item").Count.Should().BeGreaterThan(0)); - var items = comp.FindAll("div.mud-list-item").ToArray(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); items[1].Click(); // menu should still be open now!! menu.ClassList.Should().Contain("mud-popover-open"); @@ -254,9 +254,9 @@ public async Task MultiSelectTest1() "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"; // check that the correct items are checked comp.WaitForAssertion(() => - comp.FindAll("div.mud-list-item path")[1].Attributes["d"].Value.Should().Be(@unchecked)); - comp.FindAll("div.mud-list-item path")[3].Attributes["d"].Value.Should().Be(@checked); - comp.FindAll("div.mud-list-item path")[5].Attributes["d"].Value.Should().Be(@checked); + comp.FindAll("div.mud-list-item-extended path")[1].Attributes["d"].Value.Should().Be(@unchecked)); + comp.FindAll("div.mud-list-item-extended path")[3].Attributes["d"].Value.Should().Be(@checked); + comp.FindAll("div.mud-list-item-extended path")[5].Attributes["d"].Value.Should().Be(@checked); // now check how setting the SelectedValues makes items checked or unchecked // Note: If popover is open, selecting values programmatically doesn't work for now. await comp.InvokeAsync(() => select.Instance.CloseMenu()); @@ -265,10 +265,10 @@ await comp.InvokeAsync(() => select.Instance.SelectedValues = new HashSet() { "1", "2" }; }); await comp.InvokeAsync(() => input.Click()); - comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item path")[1].Attributes["d"].Value.Should().Be(@checked)); - comp.FindAll("div.mud-list-item path")[3].Attributes["d"].Value.Should().Be(@checked); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended path")[1].Attributes["d"].Value.Should().Be(@checked)); + comp.FindAll("div.mud-list-item-extended path")[3].Attributes["d"].Value.Should().Be(@checked); select.Instance.SelectedValues.Should().NotContain("3"); - comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item path")[5].Attributes["d"].Value.Should().Be(@unchecked)); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended path")[5].Attributes["d"].Value.Should().Be(@unchecked)); //Console.WriteLine(comp.Markup); //}); } diff --git a/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj b/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj index 29a3fa9d..59b93cc2 100644 --- a/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj +++ b/CodeBeam.MudExtensions/CodeBeam.MudExtensions.csproj @@ -36,9 +36,9 @@ - + diff --git a/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss b/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss index 37d52e33..21407599 100644 --- a/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss +++ b/CodeBeam.MudExtensions/Styles/Components/_selectextended.scss @@ -5,7 +5,7 @@ min-width: 0; position: relative; //Required but broke outlined variant's label - overflow-x: auto; + /*overflow-x: auto;*/ &.mud-autocomplete { display: block; diff --git a/CodeBeam.MudExtensions/Styles/MudExtensions.css b/CodeBeam.MudExtensions/Styles/MudExtensions.css index 637ca457..cf91768d 100644 --- a/CodeBeam.MudExtensions/Styles/MudExtensions.css +++ b/CodeBeam.MudExtensions/Styles/MudExtensions.css @@ -622,7 +622,7 @@ flex-basis: 0; min-width: 0; position: relative; - overflow-x: auto; } + /*overflow-x: auto;*/ } .mud-select-extended.mud-autocomplete { display: block; } .mud-select-extended.mud-autocomplete .mud-select-input-extended { diff --git a/CodeBeam.MudExtensions/Styles/MudExtensions.min.css b/CodeBeam.MudExtensions/Styles/MudExtensions.min.css index 03dd61c8..790c5fca 100644 --- a/CodeBeam.MudExtensions/Styles/MudExtensions.min.css +++ b/CodeBeam.MudExtensions/Styles/MudExtensions.min.css @@ -1 +1 @@ -.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;overflow-x:auto;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file +.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file diff --git a/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css b/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css index 03dd61c8..790c5fca 100644 --- a/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css +++ b/CodeBeam.MudExtensions/wwwroot/MudExtensions.min.css @@ -1 +1 @@ -.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;overflow-x:auto;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file +.mud-gallery-selected-toolbox{left:0;right:0;height:56px;width:100%;background-color:rgba(0,0,0,.6);}.mud-gallery-selected-toolbox.gallery-toolbox-top{top:0;}.mud-gallery-selected-toolbox.gallery-toolbox-bottom{bottom:0;}.mud-page{display:grid;box-sizing:border-box;width:100%;}.mud-page.mud-page-height-full{min-height:100vh;}.mud-page.mud-page-height-full-without-appbar{min-height:calc(100vh - var(--mud-appbar-height));}.mud-page.mud-page-column-2{grid-template-columns:repeat(2,50%);}.mud-page.mud-page-column-3{grid-template-columns:repeat(3,33.33333%);}.mud-page.mud-page-column-4{grid-template-columns:repeat(4,25%);}.mud-page.mud-page-column-5{grid-template-columns:repeat(5,20%);}.mud-page.mud-page-column-6{grid-template-columns:repeat(6,16.66667%);}.mud-page.mud-page-column-7{grid-template-columns:repeat(7,14.28571%);}.mud-page.mud-page-column-8{grid-template-columns:repeat(8,12.5%);}.mud-page.mud-page-column-9{grid-template-columns:repeat(9,11.11111%);}.mud-page.mud-page-column-10{grid-template-columns:repeat(10,10%);}.mud-page.mud-page-column-11{grid-template-columns:repeat(11,9.09091%);}.mud-page.mud-page-column-12{grid-template-columns:repeat(12,8.33333%);}.mud-page.mud-page-row-2{grid-template-rows:repeat(2,50%);}.mud-page.mud-page-row-3{grid-template-rows:repeat(3,33.33333%);}.mud-page.mud-page-row-4{grid-template-rows:repeat(4,25%);}.mud-page.mud-page-row-5{grid-template-rows:repeat(5,20%);}.mud-page.mud-page-row-6{grid-template-rows:repeat(6,16.66667%);}.mud-page.mud-page-row-7{grid-template-rows:repeat(7,14.28571%);}.mud-page.mud-page-row-8{grid-template-rows:repeat(8,12.5%);}.mud-page.mud-page-row-9{grid-template-rows:repeat(9,11.11111%);}.mud-page.mud-page-row-10{grid-template-rows:repeat(10,10%);}.mud-page.mud-page-row-11{grid-template-rows:repeat(11,9.09091%);}.mud-page.mud-page-row-12{grid-template-rows:repeat(12,8.33333%);}.mud-section{display:inline-grid;overflow:auto;}.mud-section.mud-section-col-start-1{grid-column-start:1;}.mud-section.mud-section-col-start-2{grid-column-start:2;}.mud-section.mud-section-col-start-3{grid-column-start:3;}.mud-section.mud-section-col-start-4{grid-column-start:4;}.mud-section.mud-section-col-start-5{grid-column-start:5;}.mud-section.mud-section-col-start-6{grid-column-start:6;}.mud-section.mud-section-col-start-7{grid-column-start:7;}.mud-section.mud-section-col-start-8{grid-column-start:8;}.mud-section.mud-section-col-start-9{grid-column-start:9;}.mud-section.mud-section-col-start-10{grid-column-start:10;}.mud-section.mud-section-col-start-11{grid-column-start:11;}.mud-section.mud-section-col-start-12{grid-column-start:12;}.mud-section.mud-section-col-end-1{grid-column-end:1;}.mud-section.mud-section-col-end-2{grid-column-end:2;}.mud-section.mud-section-col-end-3{grid-column-end:3;}.mud-section.mud-section-col-end-4{grid-column-end:4;}.mud-section.mud-section-col-end-5{grid-column-end:5;}.mud-section.mud-section-col-end-6{grid-column-end:6;}.mud-section.mud-section-col-end-7{grid-column-end:7;}.mud-section.mud-section-col-end-8{grid-column-end:8;}.mud-section.mud-section-col-end-9{grid-column-end:9;}.mud-section.mud-section-col-end-10{grid-column-end:10;}.mud-section.mud-section-col-end-11{grid-column-end:11;}.mud-section.mud-section-col-end-12{grid-column-end:12;}.mud-section.mud-section-row-start-1{grid-row-start:1;}.mud-section.mud-section-row-start-2{grid-row-start:2;}.mud-section.mud-section-row-start-3{grid-row-start:3;}.mud-section.mud-section-row-start-4{grid-row-start:4;}.mud-section.mud-section-row-start-5{grid-row-start:5;}.mud-section.mud-section-row-start-6{grid-row-start:6;}.mud-section.mud-section-row-start-7{grid-row-start:7;}.mud-section.mud-section-row-start-8{grid-row-start:8;}.mud-section.mud-section-row-start-9{grid-row-start:9;}.mud-section.mud-section-row-start-10{grid-row-start:10;}.mud-section.mud-section-row-start-11{grid-row-start:11;}.mud-section.mud-section-row-start-12{grid-row-start:12;}.mud-section.mud-section-row-end-1{grid-row-end:1;}.mud-section.mud-section-row-end-2{grid-row-end:2;}.mud-section.mud-section-row-end-3{grid-row-end:3;}.mud-section.mud-section-row-end-4{grid-row-end:4;}.mud-section.mud-section-row-end-5{grid-row-end:5;}.mud-section.mud-section-row-end-6{grid-row-end:6;}.mud-section.mud-section-row-end-7{grid-row-end:7;}.mud-section.mud-section-row-end-8{grid-row-end:8;}.mud-section.mud-section-row-end-9{grid-row-end:9;}.mud-section.mud-section-row-end-10{grid-row-end:10;}.mud-section.mud-section-row-end-11{grid-row-end:11;}.mud-section.mud-section-row-end-12{grid-row-end:12;}.mud-popup{z-index:2000;overflow:auto;background-color:var(--mud-palette-background);min-height:var(--mud-appbar-height);}.mud-popup.mud-popup-center{height:300px;left:50%;top:50%;transform:translate(-50%,-50%);width:320px;aspect-ratio:1/1;}.mud-splitter{display:grid;position:relative;width:100%;}.mud-splitter-content{overflow:auto;}.mud-splitter-thumb ::-webkit-slider-runnable-track{visibility:hidden !important;height:100% !important;}.mud-splitter-thumb ::-moz-range-track{visibility:hidden !important;height:100% !important;}.mud-splitter-track{position:absolute;top:50%;transform:translateY(-50%);height:100%;}.mud-splitter-track.mud-slider{visibility:hidden !important;}.mud-splitter-track.mud-slider .mud-slider-container{height:100% !important;}.mud-splitter-track.mud-slider .mud-slider-input{top:50%;}.mud-splitter-thumb ::-webkit-slider-thumb{visibility:visible !important;appearance:none !important;-webkit-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-splitter-thumb ::-moz-range-thumb{visibility:visible !important;appearance:none !important;-moz-appearance:none !important;top:50% !important;transform:translateY(-50%) !important;height:100% !important;width:8px !important;border:none !important;border-radius:0 !important;cursor:ew-resize !important;}.mud-stepper-header{min-height:62px;border-radius:var(--mud-default-borderradius);}.mud-stepper-header.mud-stepper-header-non-linear:hover{background-color:var(--mud-palette-action-default-hover);}.mud-stepper-header-dash{min-width:50px;border-bottom:1px solid;border-left:none;height:50%;border-color:var(--mud-palette-text-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical{min-width:unset;border-bottom:none;border-left:2px solid;border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-vertical.dash-tiny{height:20px;}.mud-stepper-header-dash.mud-stepper-header-dash-completed{border-bottom:2px solid;}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-primary{border-color:var(--mud-palette-primary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-secondary{border-color:var(--mud-palette-secondary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-tertiary{border-color:var(--mud-palette-tertiary);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-info{border-color:var(--mud-palette-info);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-success{border-color:var(--mud-palette-success);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-warning{border-color:var(--mud-palette-warning);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-error{border-color:var(--mud-palette-error);}.mud-stepper-header-dash.mud-stepper-header-dash-completed.mud-stepper-border-dark{border-color:var(--mud-palette-dark);}.mud-switch-m3{cursor:pointer;display:inline-flex;align-items:center;vertical-align:middle;-webkit-tap-highlight-color:transparent;}.mud-switch-m3.mud-disabled{color:var(--mud-palette-text-disabled) !important;cursor:default;}.mud-switch-m3.mud-readonly,.mud-switch-m3 .mud-readonly:hover{cursor:default;background-color:transparent !important;}.mud-switch-span-m3{width:52px;height:32px;display:inline-flex;z-index:0;position:relative;box-sizing:border-box;flex-shrink:0;vertical-align:middle;}.mud-switch-span-m3.mud-switch-child-content-m3{margin-inline-end:12px;}.mud-switch-span-m3 .mud-switch-track-m3{width:52px;height:32px;z-index:-1;transition:opacity 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;border-radius:30px;background-color:var(--mud-palette-background);border:2px solid;}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-default-m3{border-color:var(--mud-palette-text-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-primary-m3{border-color:var(--mud-palette-primary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-secondary-m3{border-color:var(--mud-palette-secondary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-tertiary-m3{border-color:var(--mud-palette-tertiary);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-info-m3{border-color:var(--mud-palette-info);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-success-m3{border-color:var(--mud-palette-success);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-warning-m3{border-color:var(--mud-palette-warning);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-error-m3{border-color:var(--mud-palette-error);}.mud-switch-span-m3 .mud-switch-track-m3.mud-switch-track-dark-m3{border-color:var(--mud-palette-dark);}.mud-switch-base-m3{padding-top:4px;padding-bottom:4px;padding-inline-start:8px;top:0;left:0;bottom:0;color:#fafafa;z-index:1;position:absolute;transition:left 150ms cubic-bezier(.4,0,.2,1) 0ms,transform 150ms cubic-bezier(.4,0,.2,1) 0ms,background-color 250ms cubic-bezier(.4,0,.2,1) 0ms,box-shadow 250ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-switch-base-m3.mud-switch-base-dense-m3{padding-inline-start:4px;}.mud-switch-base-m3.mud-checked{transform:translateX(20px);padding:4px;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3{opacity:1;}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-default{background-color:var(--mud-palette-text-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-primary{background-color:var(--mud-palette-primary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-secondary{background-color:var(--mud-palette-secondary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-tertiary{background-color:var(--mud-palette-tertiary);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-info{background-color:var(--mud-palette-info);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-success{background-color:var(--mud-palette-success);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-warning{background-color:var(--mud-palette-warning);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-error{background-color:var(--mud-palette-error);}.mud-switch-base-m3.mud-checked+.mud-switch-track-m3.mud-dark{background-color:var(--mud-palette-dark);}.mud-switch-base-m3.mud-checked .mud-switch-thumb-m3{width:24px;height:24px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;background-color:var(--mud-palette-background);}.mud-switch-base-m3:hover{background-color:var(--mud-palette-action-default-hover);}.mud-switch-base-m3.mud-switch-disabled{color:var(--mud-palette-grey-default) !important;}.mud-switch-base-m3.mud-switch-disabled+.mud-switch-track-m3{opacity:.12 !important;}.mud-switch-base-m3.mud-switch-disabled:hover,.mud-switch-base-m3.mud-switch-disabled:focus-visible{cursor:default;background-color:transparent !important;}.mud-switch-button-m3{display:flex;align-items:inherit;justify-content:inherit;}.mud-switch-button-m3 .mud-switch-input-m3{top:0;left:0;width:100%;cursor:inherit;height:100%;margin:0;opacity:0;padding:0;z-index:1;position:absolute;}.mud-switch-button-m3 .mud-switch-thumb-m3{width:16px;height:16px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:50%;}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-default-m3{background-color:var(--mud-palette-text-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-primary-m3{background-color:var(--mud-palette-primary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-secondary-m3{background-color:var(--mud-palette-secondary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-tertiary-m3{background-color:var(--mud-palette-tertiary);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-info-m3{background-color:var(--mud-palette-info);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-success-m3{background-color:var(--mud-palette-success);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-warning-m3{background-color:var(--mud-palette-warning);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-error-m3{background-color:var(--mud-palette-error);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-dark-m3{background-color:var(--mud-palette-dark);}.mud-switch-button-m3 .mud-switch-thumb-m3.mud-switch-thumb-off-icon-m3{width:24px;height:24px;}.mud-wheel{overflow:hidden;min-width:0;flex-grow:1;user-select:none;-webkit-user-select:none;}.mud-wheel-item{width:100%;display:flex;align-content:center;justify-content:center;color:var(--mud-palette-text-secondary);border-radius:var(--mud-default-borderradius);}.mud-wheel-item.mud-wheel-item:hover:not(.mud-disabled){background-color:var(--mud-palette-action-default-hover);}.mud-wheel-item.wheel-item-closest{color:var(--mud-palette-text);}.mud-wheel-item.wheel-item-empty{min-height:32px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty-dense{min-height:24px !important;}.mud-wheel-item.wheel-item-empty.wheel-item-empty:hover{background-color:unset;}.mud-wheel-item.mud-disabled{color:var(--mud-palette-text-disabled);}.middle-item{transform:scale(1.2);}.middle-item.mud-disabled{color:var(--mud-palette-text-disabled);}.mud-wheel-border{min-height:2px !important;}.mud-wheel-border.mud-wheel-border-default{background-color:var(--mud-palette-text-primary);}.mud-wheel-border.mud-wheel-border-primary{background-color:var(--mud-palette-primary);}.mud-wheel-border.wheel-border-gradient-primary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-primary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-secondary{background-color:var(--mud-palette-secondary);}.mud-wheel-border.wheel-border-gradient-secondary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-secondary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-tertiary{background-color:var(--mud-palette-tertiary);}.mud-wheel-border.wheel-border-gradient-tertiary{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-tertiary),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-info{background-color:var(--mud-palette-info);}.mud-wheel-border.wheel-border-gradient-info{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-info),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-success{background-color:var(--mud-palette-success);}.mud-wheel-border.wheel-border-gradient-success{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-success),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-warning{background-color:var(--mud-palette-warning);}.mud-wheel-border.wheel-border-gradient-warning{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-warning),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-error{background-color:var(--mud-palette-error);}.mud-wheel-border.wheel-border-gradient-error{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-error),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.mud-wheel-border-dark{background-color:var(--mud-palette-dark);}.mud-wheel-border.wheel-border-gradient-dark{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-dark),rgba(255,0,0,0));background-color:unset;}.mud-wheel-border.wheel-border-gradient-default{background-image:linear-gradient(to right,rgba(255,0,0,0),var(--mud-palette-text-primary),rgba(255,0,0,0));background-color:unset;}.mud-list-extended{margin:0;padding:0;position:relative;list-style:none;}.mud-list-extended.mud-list-padding-extended{padding-top:8px;padding-bottom:8px;}.mud-list-item-extended{width:100%;display:flex;position:relative;box-sizing:border-box;text-align:start;align-items:center;padding-top:8px;padding-bottom:8px;justify-content:flex-start;text-decoration:none;outline:none;}.mud-list-item-extended.mud-list-item-dense-extended{padding-top:4px;padding-bottom:4px;}.mud-list-item-extended.mud-list-item-disabled-extended{color:var(--mud-palette-action-disabled) !important;cursor:default !important;pointer-events:none !important;}.mud-list-item-extended.mud-list-item-disabled-extended .mud-list-item-icon-extended{color:var(--mud-palette-action-disabled) !important;}.mud-list-item-clickable-extended{color:inherit;border:0;cursor:pointer;margin:0;outline:0;user-select:none;border-radius:0;vertical-align:middle;background-color:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent;transition:background-color 150ms cubic-bezier(.4,0,.2,1) 0ms;}.mud-list-item-clickable-extended:hover{background-color:var(--mud-palette-action-default-hover);}.mud-list-item-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-item-text-extended{flex:1 1 auto;min-width:0;margin-top:4px;margin-bottom:4px;padding-inline-start:8px;padding-inline-end:8px;}.mud-list-item-text-inset-extended{padding-left:56px;padding-inline-start:56px;padding-inline-end:unset;}.mud-list-item-icon-extended{color:var(--mud-palette-action-default);display:inline-flex;flex-shrink:0;padding-inline-start:8px;padding-inline-end:8px;margin-inline-start:-4px;margin-inline-end:4px;}.mud-list-item-multiselect-extended{max-height:32px;}.mud-list-item-multiselect-extended.mud-list-item-multiselect-checkbox-extended{padding-inline-end:16px;}.mud-list-subheader-extended{color:var(--mud-palette-action-default);background-color:var(--mud-palette-background);font-size:.875rem;box-sizing:border-box;list-style:none;font-weight:500;padding-top:16px;padding-bottom:16px;}.mud-list-subheader-secondary-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-subheader-gutters-extended{padding-left:16px;padding-right:16px;}.mud-list-subheader-inset-extended{padding-left:72px;padding-inline-start:72px;padding-inline-end:unset;}.mud-list-subheader-sticky-extended{top:-8px;z-index:1;position:sticky;}.mud-list-subheader-sticky-extended.mud-list-subheader-sticky-dense-extended{top:0;}.mud-list-item-hilight-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-nested-background-extended{background-color:var(--mud-palette-background-grey);}.mud-list-item-avatar-extended{min-width:56px;flex-shrink:0;}.mud-nested-list-extended>.mud-list-item-extended{padding-left:32px;padding-inline-start:32px;padding-inline-end:unset;}.mud-select-extended{display:flex;flex-grow:1;flex-basis:0;min-width:0;position:relative;}.mud-select-extended.mud-autocomplete{display:block;}.mud-select-extended.mud-autocomplete .mud-select-input-extended{cursor:text;}.mud-select-extended.mud-autocomplete .mud-input-adornment-extended{cursor:pointer;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended input{padding-right:3.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-input-adorned-end input{padding-right:4.5rem !important;}.mud-select-extended.mud-autocomplete--with-progress .mud-select-input-extended .mud-icon-button{display:none !important;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular{position:absolute;width:100%;top:0;bottom:0;display:flex;align-items:center;justify-content:flex-end;padding-top:.25rem;padding-bottom:.25rem;padding-right:1rem;}.mud-select-extended.mud-autocomplete--with-progress .progress-indicator-circular--with-adornment{padding-right:3rem;}.mud-select-extended.mud-autocomplete--with-progress .mud-progress-linear{position:absolute;bottom:-1px;height:2px;}.mud-select-extended .mud-select-input-extended{cursor:pointer;}.mud-select-extended .mud-select-input-extended .mud-input-slot{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.mud-select-extended .mud-select-input-extended .mud-input-adornment-end{margin-left:0;}.mud-select-extended .mud-select-input-extended:disabled{cursor:default;}.mud-select-extended .mud-disabled .mud-select-input{cursor:default;}.mud-select-extended>.mud-form-helpertext{margin-top:-21px;}.mud-select-all-extended{margin-top:10px;border-bottom:1px solid #d3d3d3;padding-bottom:18px;} \ No newline at end of file From 23cce4df0071ea7904242a54413e8ba144b131bb Mon Sep 17 00:00:00 2001 From: mckaragoz <78308169+mckaragoz@users.noreply.github.com> Date: Tue, 31 Jan 2023 17:27:10 +0300 Subject: [PATCH 4/5] Fix Some Tests --- .../CodeBeam.MudExtensions.UnitTest.csproj | 29 ---------- .../App.razor | 0 ...Beam.MudExtensions.UnitTests.Viewer.csproj | 6 +- .../Pages/Index.razor | 2 - .../Program.cs | 2 +- .../Properties/launchSettings.json | 0 .../Shared/MainLayout.razor | 0 .../Shared/MainLayout.razor.css | 0 .../Shared/NavMenu.razor | 2 +- .../Shared/NavMenu.razor.css | 0 .../ListExperimentalCountTest.razor | 0 .../ListExperimentalEnhancedTest.razor | 0 ...xperimentalSelectionInitialValueTest.razor | 0 .../ListExperimentalSelectionTest.razor | 0 .../ListExperimentalVariantTest.razor | 0 .../MultiSelectCustomizedTextTest.razor | 0 .../SelectExtended/MultiSelectTest1.razor | 0 .../SelectExtended/MultiSelectTest2.razor | 0 .../SelectExtended/MultiSelectTest3.razor | 0 .../SelectExtended/MultiSelectTest4.razor | 0 .../SelectExtended/MultiSelectTest5.razor | 0 .../MultiSelectTestRequiredValue.razor | 6 +- .../SelectExtended/MultiSelectTextTest.razor | 0 .../MultiSelectWithCustomComparerTest.razor | 0 .../MultiSelectWithInitialValues.razor | 0 .../ReloadSelectItemsTest.razor | 0 .../SelectExtended/ReselectValueTest.razor | 0 .../SelectExtended/SelectClearableTest.razor | 0 .../SelectExtended/SelectEventCountTest.razor | 13 ++--- .../SelectInitialValueTest.razor | 0 .../SelectExtended/SelectOnCloseTest.razor | 0 .../SelectExtended/SelectRequiredTest.razor | 0 .../SelectExtended/SelectTest1.razor | 0 .../SelectExtended/SelectTest2.razor | 0 .../SelectExtended/SelectTextValueTest.razor | 0 .../SelectUnrepresentableValueTest.razor | 0 .../SelectUnrepresentableValueTest2.razor | 0 .../SelectValidationDataAttrTest.razor | 0 .../SelectExtended/SelectWithEnumTest.razor | 0 .../_Imports.razor | 4 +- .../wwwroot/css/app.css | 0 .../wwwroot/css/bootstrap/bootstrap.min.css | 0 .../css/bootstrap/bootstrap.min.css.map | 0 .../wwwroot/css/open-iconic/FONT-LICENSE | 0 .../wwwroot/css/open-iconic/ICON-LICENSE | 0 .../wwwroot/css/open-iconic/README.md | 0 .../font/css/open-iconic-bootstrap.min.css | 0 .../open-iconic/font/fonts/open-iconic.eot | Bin .../open-iconic/font/fonts/open-iconic.otf | Bin .../open-iconic/font/fonts/open-iconic.svg | 0 .../open-iconic/font/fonts/open-iconic.ttf | Bin .../open-iconic/font/fonts/open-iconic.woff | Bin .../wwwroot/favicon.png | Bin .../wwwroot/icon-192.png | Bin .../wwwroot/index.html | 4 +- .../CodeBeam.MudExtensions.UnitTests.csproj | 36 ++++++++++++ .../Components/BunitTest.cs | 18 ++++-- .../Components/ListExtendedTests.cs | 0 .../Components/RenderExampleTests.cs | 2 +- .../Components/RenderTests.cs | 2 +- .../Components/SelectExtendedTests.cs | 52 +++++++++--------- .../Components/StepperTests.cs | 0 .../IRenderedComponentExtensions.cs | 0 .../Mocks/MockBreakpointService.cs | 0 .../Mocks/MockBrowserWindowSizeProvider.cs | 0 .../Mocks/MockEventListener.cs | 0 .../Mocks/MockJsApiServices.cs | 0 .../Mocks/MockJsEvent.cs | 0 .../Mocks/MockKeyInterceptor.cs | 0 .../Mocks/MockLoggerProvider.cs | 0 .../Mocks/MockNavigationManager.cs | 0 .../Mocks/MockPopoverService.cs | 0 .../Mocks/MockResizeListenerService.cs | 0 .../Mocks/MockResizeObserver.cs | 0 .../Mocks/MockResizeService.cs | 0 .../Mocks/MockScrollServices.cs | 0 .../Mocks/MockScrollSpy.cs | 0 .../UnitTest1.cs | 2 +- .../Usings.cs | 0 .../CodeBeam.MudExtensions.csproj | 2 +- .../ListExtended/MudListItemExtended.razor.cs | 2 +- .../MudSelectItemExtended.razor.cs | 2 +- .../TScripts/MudExtensions.js | 16 +++--- CodeBeamMudExtensions.sln | 4 +- 84 files changed, 108 insertions(+), 98 deletions(-) delete mode 100644 CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/App.razor (100%) rename CodeBeam.MudExtensions.UnitTest.Viewer/CodeBeam.MudExtensions.UnitTest.Viewer.csproj => CodeBeam.MudExtensions.UnitTests.Viewer/CodeBeam.MudExtensions.UnitTests.Viewer.csproj (82%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Pages/Index.razor (74%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Program.cs (91%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Properties/launchSettings.json (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Shared/MainLayout.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Shared/MainLayout.razor.css (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Shared/NavMenu.razor (98%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/Shared/NavMenu.razor.css (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/ListExtended/ListExperimentalCountTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/ListExtended/ListExperimentalEnhancedTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/ListExtended/ListExperimentalSelectionInitialValueTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/ListExtended/ListExperimentalSelectionTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/ListExtended/ListExperimentalVariantTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectCustomizedTextTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTest1.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTest2.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTest3.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTest4.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTest5.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTestRequiredValue.razor (88%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectTextTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/ReloadSelectItemsTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/ReselectValueTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectClearableTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectEventCountTest.razor (76%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectInitialValueTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectOnCloseTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectRequiredTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectTest1.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectTest2.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectTextValueTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectUnrepresentableValueTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectUnrepresentableValueTest2.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectValidationDataAttrTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/TestComponents/SelectExtended/SelectWithEnumTest.razor (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/_Imports.razor (78%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/app.css (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/bootstrap/bootstrap.min.css (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/bootstrap/bootstrap.min.css.map (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/FONT-LICENSE (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/ICON-LICENSE (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/README.md (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/fonts/open-iconic.eot (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/fonts/open-iconic.otf (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/fonts/open-iconic.svg (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/css/open-iconic/font/fonts/open-iconic.woff (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/favicon.png (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/icon-192.png (100%) rename {CodeBeam.MudExtensions.UnitTest.Viewer => CodeBeam.MudExtensions.UnitTests.Viewer}/wwwroot/index.html (88%) create mode 100644 CodeBeam.MudExtensions.UnitTests/CodeBeam.MudExtensions.UnitTests.csproj rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/BunitTest.cs (63%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/ListExtendedTests.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/RenderExampleTests.cs (95%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/RenderTests.cs (96%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/SelectExtendedTests.cs (97%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Components/StepperTests.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Extensions/IRenderedComponentExtensions.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockBreakpointService.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockBrowserWindowSizeProvider.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockEventListener.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockJsApiServices.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockJsEvent.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockKeyInterceptor.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockLoggerProvider.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockNavigationManager.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockPopoverService.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockResizeListenerService.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockResizeObserver.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockResizeService.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockScrollServices.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Mocks/MockScrollSpy.cs (100%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/UnitTest1.cs (81%) rename {CodeBeam.MudExtensions.UnitTest => CodeBeam.MudExtensions.UnitTests}/Usings.cs (100%) diff --git a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj b/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj deleted file mode 100644 index 3fe30904..00000000 --- a/CodeBeam.MudExtensions.UnitTest/CodeBeam.MudExtensions.UnitTest.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net6.0 - enable - enable - - false - - - - - - - - - - - - - - - - - - - - - diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/App.razor b/CodeBeam.MudExtensions.UnitTests.Viewer/App.razor similarity index 100% rename from CodeBeam.MudExtensions.UnitTest.Viewer/App.razor rename to CodeBeam.MudExtensions.UnitTests.Viewer/App.razor diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/CodeBeam.MudExtensions.UnitTest.Viewer.csproj b/CodeBeam.MudExtensions.UnitTests.Viewer/CodeBeam.MudExtensions.UnitTests.Viewer.csproj similarity index 82% rename from CodeBeam.MudExtensions.UnitTest.Viewer/CodeBeam.MudExtensions.UnitTest.Viewer.csproj rename to CodeBeam.MudExtensions.UnitTests.Viewer/CodeBeam.MudExtensions.UnitTests.Viewer.csproj index 0d868fe1..83b56141 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/CodeBeam.MudExtensions.UnitTest.Viewer.csproj +++ b/CodeBeam.MudExtensions.UnitTests.Viewer/CodeBeam.MudExtensions.UnitTests.Viewer.csproj @@ -12,8 +12,8 @@ - - - + + + diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor b/CodeBeam.MudExtensions.UnitTests.Viewer/Pages/Index.razor similarity index 74% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor rename to CodeBeam.MudExtensions.UnitTests.Viewer/Pages/Index.razor index 860e1de0..a6f4207c 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Pages/Index.razor +++ b/CodeBeam.MudExtensions.UnitTests.Viewer/Pages/Index.razor @@ -6,6 +6,4 @@ Welcome to your new app. - - diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs b/CodeBeam.MudExtensions.UnitTests.Viewer/Program.cs similarity index 91% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs rename to CodeBeam.MudExtensions.UnitTests.Viewer/Program.cs index d91196fb..844aea13 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Program.cs +++ b/CodeBeam.MudExtensions.UnitTests.Viewer/Program.cs @@ -1,4 +1,4 @@ -using CodeBeam.MudExtensions.UnitTest.Viewer; +using CodeBeam.MudExtensions.UnitTests.Viewer; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Properties/launchSettings.json b/CodeBeam.MudExtensions.UnitTests.Viewer/Properties/launchSettings.json similarity index 100% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Properties/launchSettings.json rename to CodeBeam.MudExtensions.UnitTests.Viewer/Properties/launchSettings.json diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor b/CodeBeam.MudExtensions.UnitTests.Viewer/Shared/MainLayout.razor similarity index 100% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor rename to CodeBeam.MudExtensions.UnitTests.Viewer/Shared/MainLayout.razor diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor.css b/CodeBeam.MudExtensions.UnitTests.Viewer/Shared/MainLayout.razor.css similarity index 100% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Shared/MainLayout.razor.css rename to CodeBeam.MudExtensions.UnitTests.Viewer/Shared/MainLayout.razor.css diff --git a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/NavMenu.razor b/CodeBeam.MudExtensions.UnitTests.Viewer/Shared/NavMenu.razor similarity index 98% rename from CodeBeam.MudExtensions.UnitTest.Viewer/Shared/NavMenu.razor rename to CodeBeam.MudExtensions.UnitTests.Viewer/Shared/NavMenu.razor index 2f5bcad5..36093cf5 100644 --- a/CodeBeam.MudExtensions.UnitTest.Viewer/Shared/NavMenu.razor +++ b/CodeBeam.MudExtensions.UnitTests.Viewer/Shared/NavMenu.razor @@ -1,6 +1,6 @@