-
Notifications
You must be signed in to change notification settings - Fork 417
FluentAutoComplete: Single item enhancements #3571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
FluentAutoComplete: Single item enhancements #3571
Conversation
@StevenRasmussen wouldn't it make more sence to provide an itemprovider to the But I agree the current behaviour for single items within |
@MarvinKlein1508 - That might work if you only have a small list of items. However, when working with large datasets and you want to be able to search/filter items then the AutoComplete allows you to do this with the |
@dvoituron - Thanks for the feedback :). Regarding your points:
|
…epending on the current name.
@@ -1,5 +1,5 @@ | |||
|
|||
<div class=" fluent-autocomplete-multiselect" style="width: 100%;" b-hg72r5b4ox=""> | |||
<div class=" fluent-autocomplete-multiselect item-selected" style="width: 100%;" b-hg72r5b4ox=""> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dvoituron - Is this an acceptable modification to the logic and thus the unit test? A new class is being added if the count of the SelectedOptions > 0
. This shouldn't break anyone since the main class name is un-changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nop. It's not acceptable to change all Unit Tests.
You can do the "inverse": you can add an attribute single-selection
only for you feature. And adapt the CSS in this case= .fluent-autocomplete-multiselect[single-selection] { ... }
<div class="fluent-autocomplete-multiselect" single-selection> ...
if (ReadOnly || Disabled) | ||
if (MaximumSelectedOptions == 1) | ||
{ | ||
<FluentLabel aria-label="@GetOptionText(item)" role="checkbox" aria-checked="true">@text</FluentLabel> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dvoituron - I'm not sure if you think it appropriate to include a tab stop here or not. I left it out but could add it back in if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dvoituron - I believe adding the tab stop is what you are looking for as far as accessibility goes. I have added it so that you can see what the result is. Let me know if you still want other changes or if you still think we should pursue allowing Multiple
= false;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check this out, but having a Multiple=false is still useful for people who want to keep the previous behavior.
@@ -79,7 +79,7 @@ | |||
Width="12px" | |||
Style="cursor: pointer;" | |||
Slot="end" | |||
Title="@AccessibilityIconDismiss" | |||
Title="@(MaximumSelectedOptions == 1 ? string.Format(AccessibilityRemoveItem, GetOptionText(SelectedOption)) : AccessibilityIconDismiss)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dvoituron - When this is a single select (MaximumSelectedOptions == 1
) then the accessibility text for the Clear
button becomes the AccessibilityRemoveItem
text which is something like Remove {0}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change the current Title result: DismissTitle="@(string.Format(AccessibilityRemoveItem, text))"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was an attempt to improve the "accessibility" of the component. Since you can no longer remove the individual item, I felt it might be good for the 'Clear' button to include the name of the selected option and so I just updated it to use the same text as if you were removing a single item. I'm happy to change it back if you don't feel like this is a helpful update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an option to add additional information in this case. But my biggest accessibility problem is that the component must “read” (with NVDA) all the elements present on the screen. This is still not the case when an item is selected, the user must be able to position himself on the component (focusable) and NVDA must announce something like “ selected”.
To move forward with this PR (and to be compatible with what already exists), it would probably be simpler to allow the Multiple=false
parameter, which would activate your functionality. If Multiple=true
, everything would work as it does now, and Accessibility would be compatbile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about this idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this by making the following changes:
However, the control did not seem to work. It wouldn't allow me to select anything. I'm not opposed to this idea, I'm just not sure what else would be required to get it to work. At the end of the day, I'm simply looking for a way to only allow a single item to be selected and also have the UI styled in such a way that is optimal for a single item. As it stands, I believe this PR accomplishes that and does it in a way that does not break anything existing and is hopefully acceptable from an accessibility perspective with the latest change I pushed.
Here are a few websites to explain Accessibility:
The best solution is to use a tool such as NVDA to validate the result. |
@dvoituron - Thanks for the pointers regarding accessibility. I introduced changes that I believe have addressed your concern. That being said, I feel a bit like I'm blindfolded and trying to hit a dart board... I'm not quite sure what an acceptable solution is for accessibility. Please let me know if additional changes need to be made, otherwise I feel like the PR is ready for review again. Thanks! |
@dvoituron - I wanted to check-in to see if you needed any additional changes to this PR. Thanks! |
@@ -79,7 +79,7 @@ | |||
Width="12px" | |||
Style="cursor: pointer;" | |||
Slot="end" | |||
Title="@AccessibilityIconDismiss" | |||
Title="@(MaximumSelectedOptions == 1 ? string.Format(AccessibilityRemoveItem, GetOptionText(SelectedOption)) : AccessibilityIconDismiss)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an option to add additional information in this case. But my biggest accessibility problem is that the component must “read” (with NVDA) all the elements present on the screen. This is still not the case when an item is selected, the user must be able to position himself on the component (focusable) and NVDA must announce something like “ selected”.
To move forward with this PR (and to be compatible with what already exists), it would probably be simpler to allow the Multiple=false
parameter, which would activate your functionality. If Multiple=true
, everything would work as it does now, and Accessibility would be compatbile.
&& SelectedOptions?.Count() > 0 | ||
&& !(AdditionalAttributes?.TryGetValue("single-select", out var isSingleSelect) ?? false)) | ||
{ | ||
var additionalAttributes = (AdditionalAttributes is not null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to update the AdditionalAttributes
. You can add an attribute in the razor file like this:
<FluentTextField role="combobox" single-select="@GetSingleSelect()" ... >
private bool GetSingleSelect() => MaximumSelectedOptions == 1 && SelectedOptions?.Any() && Multiple == false;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
…f directly putting the attribute on the element and evaluating with a function.
With this improvement (thanks! really important) Is there also a way to have a two-way simple binding to one single object it MaximumSelectedOptions = 1 to perform a simple two-way binding to an object's property referring to the selected object? |
No. By default, this component is dedicated to bind multiple items. Including when you set |
Pull Request
📖 Description
When the
MaximumSelectedOptions == 1
, the control is rendered less than ideal due to the inherent nature that the control is expecting more than one item to be selected. This PR seeks to improve both the UI and UX of the FluentAutoComplete when only 1 item is desired.🎫 Issues
Here is how the control renders like when the
MaximumSelectedOptions == 1
Here is how the control renders with this PR:
✅ Checklist
General
Component-specific