Skip to content

Commit

Permalink
[HxSearchBox} Keyboard navigation adjustments + HightLightFirstSugges…
Browse files Browse the repository at this point in the history
…tion #348
  • Loading branch information
Harvey1214 committed Sep 5, 2022
1 parent 7cdcf99 commit 8f5179a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -19,6 +19,7 @@ static HxSearchBox()
ClearIcon = BootstrapIcon.XLg,
MinimumLength = 2,
Delay = 300,
HighlightFirstSuggestion = true
};
}
}
Expand Down
Expand Up @@ -201,6 +201,12 @@ public partial class HxSearchBox<TItem> : IAsyncDisposable
/// </summary>
[Parameter] public RenderFragment InputGroupEndTemplate { get; set; }

/// <summary>
/// If true, the first suggestion is highlighted until another is chosen by the user.
/// </summary>
[Parameter] public bool? HighlightFirstSuggestion { get; set; }
protected bool HighlightFirstSuggestionEffective => this.HighlightFirstSuggestion ?? GetSettings()?.HighlightFirstSuggestion ?? GetDefaults()?.HighlightFirstSuggestion ?? throw new InvalidOperationException(nameof(HighlightFirstSuggestion) + " default for " + nameof(HxSearchBox) + " has to be set.");

private string dropdownToggleElementId = "hx" + Guid.NewGuid().ToString("N");
private string dropdownId = "hx" + Guid.NewGuid().ToString("N");
private List<TItem> searchResults = new();
Expand Down Expand Up @@ -276,7 +282,15 @@ protected async Task UpdateSuggestionsAsync()

dataProviderInProgress = false;

focusedItemIndex = default; // KeyboardNavigation
// KeyboardNavigation
if (HighlightFirstSuggestionEffective)
{
focusedItemIndex = 0; // First item in the searchResults collection.
}
else
{
focusedItemIndex = InputKeyboardNavigationIndex;
}

searchResults = result?.Data.ToList();

Expand Down Expand Up @@ -329,18 +343,23 @@ protected async Task HandleTextQueryValueChanged(string newTextQuery)
private const string EnterKeyCode = "Enter";
private const string NumpadEnterKeyCode = "NumpadEnter";

/// <summary>
/// Input's index for the keyboard navigation. If this is the current index, then no item is selected.
/// </summary>
private const int InputKeyboardNavigationIndex = -1;

private bool HasItemFocus(TItem item)
{
TItem focusedItem = GetItemByIndex(focusedItemIndex);

if ((focusedItem is not null) && (!focusedItem.Equals(default)))
{
return item.Equals(focusedItem);
}
else
if (focusedItemIndex > InputKeyboardNavigationIndex && focusedItemIndex < GetFreeTextItemIndex())
{
return false;
TItem focusedItem = GetItemByIndex(focusedItemIndex);
if ((focusedItem is not null) && (!focusedItem.Equals(default)))
{
return item.Equals(focusedItem);
}
}

return false;
}

private bool HasFreeTextItemFocus()
Expand Down Expand Up @@ -368,15 +387,15 @@ private async Task UpdateFocusedItem(KeyboardEventArgs keyboardEventArgs)
if (keyboardEventArgs.Code == ArrowUpKeyCode)
{
int previousItemIndex = focusedItemIndex - 1;
if (previousItemIndex >= -1) // If the index is -1, no item is focused.
if (previousItemIndex >= InputKeyboardNavigationIndex) // If the index equals InputKeyboardNavigationIndex, no item is focused.
{
focusedItemIndex = previousItemIndex;
}
}
else if (keyboardEventArgs.Code == ArrowDownKeyCode)
{
int nextItemIndex = focusedItemIndex + 1;
if (nextItemIndex < GetFreeTextItemIndex()) // If the index equals GetFreeTextItemIndex(), then the freetext item is selected.
if (nextItemIndex <= GetFreeTextItemIndex()) // If the index equals GetFreeTextItemIndex(), then the freetext item is selected.
{
focusedItemIndex = nextItemIndex;
}
Expand Down
Expand Up @@ -44,4 +44,9 @@ public class SearchBoxSettings
/// Additional CSS classes for the search box input.
/// </summary>
public string InputCssClass { get; set; }

/// <summary>
/// If true, the first suggestion is highlighted until another is chosen by the user.
/// </summary>
public bool? HighlightFirstSuggestion { get; set; }
}

0 comments on commit 8f5179a

Please sign in to comment.