diff --git a/examples/Demo/Shared/Pages/Lab/IssueTester.razor b/examples/Demo/Shared/Pages/Lab/IssueTester.razor
index 5f282702bb..d230efc4f4 100644
--- a/examples/Demo/Shared/Pages/Lab/IssueTester.razor
+++ b/examples/Demo/Shared/Pages/Lab/IssueTester.razor
@@ -1 +1,2 @@
-
\ No newline at end of file
+@using FluentUI.Demo.Shared.Pages.List.Select.Examples
+
diff --git a/examples/Demo/Shared/Pages/List/Listbox/ListboxPage.razor b/examples/Demo/Shared/Pages/List/Listbox/ListboxPage.razor
index 3198bdb614..68a408ea84 100644
--- a/examples/Demo/Shared/Pages/List/Listbox/ListboxPage.razor
+++ b/examples/Demo/Shared/Pages/List/Listbox/ListboxPage.razor
@@ -31,8 +31,6 @@
-
-
+
@Body
diff --git a/src/Core/Components/List/ListComponentBase.razor b/src/Core/Components/List/ListComponentBase.razor
index 19fb3b7ef4..a736ee2571 100644
--- a/src/Core/Components/List/ListComponentBase.razor
+++ b/src/Core/Components/List/ListComponentBase.razor
@@ -30,7 +30,8 @@
Value="@GetOptionValue(item)"
Selected="@GetOptionSelected(item)"
Disabled="@(GetOptionDisabled(item) ?? false)"
- OnSelect="@OnSelectCallback(item)">
+ OnSelect="@OnSelectCallback(item)"
+ aria-selected="@(GetOptionSelected(item) ? "true" : "false")">
@if (OptionTemplate is not null)
{
@OptionTemplate(item)
diff --git a/src/Core/Components/List/ListComponentBase.razor.cs b/src/Core/Components/List/ListComponentBase.razor.cs
index 51caceb484..9fa23b31eb 100644
--- a/src/Core/Components/List/ListComponentBase.razor.cs
+++ b/src/Core/Components/List/ListComponentBase.razor.cs
@@ -2,13 +2,13 @@
// MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------
+using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.FluentUI.AspNetCore.Components.Extensions;
using Microsoft.FluentUI.AspNetCore.Components.Utilities;
using Microsoft.JSInterop;
-using System.Diagnostics.CodeAnalysis;
namespace Microsoft.FluentUI.AspNetCore.Components;
@@ -209,57 +209,78 @@ public override async Task SetParametersAsync(ParameterView parameters)
isSetValue = true;
newValue = (string?)parameter.Value;
break;
+ case nameof(Items):
+ if (Items is not null)
+ {
+ newSelectedOption = Items.FirstOrDefault(i => OptionSelected?.Invoke(i) == true);
+ newValue = GetOptionValue(newSelectedOption);
+ }
+ break;
default:
break;
}
}
- if (isSetSelectedOption && !Equals(_currentSelectedOption, newSelectedOption))
+ if (newSelectedOption is not null || newValue is not null || Value is not null)
{
- if (Items != null)
+ if (isSetSelectedOption && !Equals(_currentSelectedOption, newSelectedOption))
{
- if (Items.Contains(newSelectedOption))
+ if (Items != null)
{
- _currentSelectedOption = newSelectedOption;
- // Make value follow new selected option
- Value = GetOptionValue(_currentSelectedOption);
+ if (Items.Contains(newSelectedOption))
+ {
+ _currentSelectedOption = newSelectedOption;
+ // Make value follow new selected option
+ Value = GetOptionValue(_currentSelectedOption);
+ await ValueChanged.InvokeAsync(Value);
+ }
+ else
+ {
+ // If the selected option is not in the list of items, reset the selected option
+ _currentSelectedOption = SelectedOption = default;
+ // and also reset the value
+ Value = null;
+ await SelectedOptionChanged.InvokeAsync(SelectedOption);
+ }
}
else
{
- // If the selected option is not in the list of items, reset the selected option
- _currentSelectedOption = SelectedOption = default;
- // and also reset the value
- Value = null;
- await SelectedOptionChanged.InvokeAsync(SelectedOption);
+ // If Items is null, we don't know if the selected option is in the list of items, so we just set it
+ _currentSelectedOption = newSelectedOption;
}
}
- else
- {
- // If Items is null, we don't know if the selected option is in the list of items, so we just set it
- _currentSelectedOption = newSelectedOption;
- }
- }
- else if (isSetValue && Items != null && GetOptionValue(_currentSelectedOption) != newValue)
- {
- newSelectedOption = Items.FirstOrDefault(item => GetOptionValue(item) == newValue);
- if (newSelectedOption != null)
- {
- _currentSelectedOption = SelectedOption = newSelectedOption;
- }
- else
+ if (isSetValue && newValue is null)
{
- // If the selected option is not in the list of items, reset the selected option
- _currentSelectedOption = SelectedOption = default;
- if (this is not FluentCombobox
)
+ // Check if one of the Items is selected
+ if (Items is not null)
{
- Value = null;
- await ValueChanged.InvokeAsync(Value);
+ newSelectedOption = Items.FirstOrDefault(item => OptionSelected?.Invoke(item) == true);
+ if (newSelectedOption is not null)
+ {
+ _currentSelectedOption = SelectedOption = newSelectedOption;
+ newValue = GetOptionValue(_currentSelectedOption);
+ }
}
- }
- await SelectedOptionChanged.InvokeAsync(SelectedOption);
+ if (newValue is null)
+ {
+ // If the selected option is not in the list of items, reset the selected option
+ _currentSelectedOption = SelectedOption = default;
+ if (this is not FluentCombobox)
+ {
+ Value = null;
+ await ValueChanged.InvokeAsync(Value);
+ }
+ }
+ else
+ {
+ Value = newValue;
+ await ValueChanged.InvokeAsync(Value);
+ }
+ await SelectedOptionChanged.InvokeAsync(SelectedOption);
+ }
}
}
@@ -323,9 +344,9 @@ protected override void OnParametersSet()
if (Multiple)
{
- if (SelectedOptions != null && _selectedOptions != SelectedOptions)
+ if (SelectedOptions != null && SelectedOptions.Any() && _selectedOptions != SelectedOptions)
{
- _selectedOptions = new List(SelectedOptions);
+ _selectedOptions = [.. SelectedOptions];
}
if (SelectedOptions == null && Items != null && OptionSelected != null)
@@ -501,8 +522,8 @@ this is FluentCombobox ||
SelectedOption = item;
- InternalValue = Value = value;
-
+ //InternalValue = Value = value;
+ InternalValue = value;
await RaiseChangedEventsAsync();
}
}
@@ -515,7 +536,10 @@ protected virtual async Task RaiseChangedEventsAsync()
{
if (SelectedOptionsChanged.HasDelegate)
{
- await SelectedOptionsChanged.InvokeAsync(_selectedOptions);
+ if (_selectedOptions.Count != 0)
+ {
+ await SelectedOptionsChanged.InvokeAsync(_selectedOptions);
+ }
}
}
else
@@ -525,9 +549,6 @@ protected virtual async Task RaiseChangedEventsAsync()
await SelectedOptionChanged.InvokeAsync(SelectedOption);
}
}
-
- // Calling ValueChanged is now done through FluentInputBase.SetCurrentValueAsync
- //StateHasChanged();
}
protected virtual async Task OnKeydownHandlerAsync(KeyboardEventArgs e)
@@ -536,7 +557,10 @@ protected virtual async Task OnKeydownHandlerAsync(KeyboardEventArgs e)
{
return;
}
-
+ if (e.ShiftKey == true || e.AltKey == true || e.CtrlKey == true)
+ {
+ return;
+ }
// This delay is needed for WASM to be able to get the updated value of the active descendant.
// Without it, the value sometimes lags behind and you then need two keypresses to move to the next/prev option.
await Task.Delay(1);