Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 179 additions & 34 deletions src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.razor

Large diffs are not rendered by default.

Large diffs are not rendered by default.

255 changes: 237 additions & 18 deletions src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.scss

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ public class BitDropdownClassStyles
/// </summary>
public string? Chips { get; set; }

/// <summary>
/// Custom CSS classes/styles for the overflow chip of the BitDropdown.
/// </summary>
public string? OverflowChip { get; set; }

/// <summary>
/// Custom CSS classes/styles for the chips's remove button of the BitDropdown.
/// </summary>
public string? ChipsRemoveButton { get; set; }

/// <summary>
/// Custom CSS classes/styles for the chips's remove icon of the BitDropdown.
/// </summary>
Expand All @@ -112,6 +122,31 @@ public class BitDropdownClassStyles
/// </summary>
public string? SearchBoxClearIcon { get; set; }

/// <summary>
/// Custom CSS classes/styles for the select all item container of the multi-select BitDropdown.
/// </summary>
public string? SelectAllContainer { get; set; }

/// <summary>
/// Custom CSS classes/styles for the select all item button of the multi-select BitDropdown.
/// </summary>
public string? SelectAllButton { get; set; }

/// <summary>
/// Custom CSS classes/styles for the select all item check box of the multi-select BitDropdown.
/// </summary>
public string? SelectAllCheckBox { get; set; }

/// <summary>
/// Custom CSS classes/styles for the select all item check icon of the multi-select BitDropdown.
/// </summary>
public string? SelectAllCheckIcon { get; set; }

/// <summary>
/// Custom CSS classes/styles for the select all item text of the multi-select BitDropdown.
/// </summary>
public string? SelectAllText { get; set; }

/// <summary>
/// Custom CSS classes/styles for the scroll container of the BitDropdown.
/// </summary>
Expand Down Expand Up @@ -152,11 +187,36 @@ public class BitDropdownClassStyles
/// </summary>
public string? ItemText { get; set; }

/// <summary>
/// Custom CSS classes/styles for the highlighted part of the item text of the BitDropdown.
/// </summary>
public string? ItemHighlight { get; set; }

/// <summary>
/// Custom CSS classes/styles for the item divider of the BitDropdown.
/// </summary>
public string? ItemDivider { get; set; }

/// <summary>
/// Custom CSS classes/styles for the empty state content of the BitDropdown.
/// </summary>
public string? EmptyContent { get; set; }

/// <summary>
/// Custom CSS classes/styles for the loading state container of the BitDropdown.
/// </summary>
public string? LoadingContainer { get; set; }

/// <summary>
/// Custom CSS classes/styles for the loading state text of the BitDropdown.
/// </summary>
public string? LoadingText { get; set; }

/// <summary>
/// Custom CSS classes/styles for the loading spinner of the BitDropdown.
/// </summary>
public string? Spinner { get; set; }

/// <summary>
/// Custom CSS classes/styles for the dropdown's prefix container.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Bit.BlazorUI;

public enum BitDropdownSearchMode
{
/// <summary>
/// An item matches when its text contains the search text.
/// </summary>
Contains,

/// <summary>
/// An item matches when its text starts with the search text.
/// </summary>
StartsWith,

/// <summary>
/// An item matches when its text ends with the search text.
/// </summary>
EndsWith,

/// <summary>
/// An item matches when its text is equal to the search text.
/// </summary>
ExactMatch
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,22 @@
var id = Dropdown.GetId(Item);
var text = Dropdown.GetText(Item);
var isHidden = Dropdown.GetIsHidden(Item);
var isEnabled = Dropdown.GetIsEnabled(Item);
var isSelected = itemType == BitDropdownItemType.Normal ? Dropdown.GetIsSelected(Item) : false;
var isDisabled = itemType == BitDropdownItemType.Normal && Dropdown.GetIsItemDisabled(Item);

// The part of the item text that matched the search, so it can be emphasized. It is rendered as
// three separate pieces of text rather than as markup, so the item text is never treated as HTML.
// The markup below is repeated in both branches on purpose: holding it in a local RenderFragment
// would hand Blazor a new delegate on every render, which re-creates the item subtree and with it
// the click handler of the button that contains it.
var highlightIndex = itemType == BitDropdownItemType.Normal ? Dropdown.GetHighlightIndex(text) : -1;
var highlightLength = Dropdown.GetHighlightLength();
var highlighted = highlightIndex >= 0 && highlightLength > 0 && text is not null;
}

<div style="@Dropdown.GetStyle(Item)" class="@Dropdown.GetClass(Item)">
@* The wrappers carry the per-item style and layout only; marking them presentational keeps the option
elements as the direct children of the listbox for assistive technologies. *@
<div role="presentation" style="@Dropdown.GetStyle(Item)" class="@Dropdown.GetClass(Item)">
@if (itemType == BitDropdownItemType.Header)
{
@if (Dropdown.HeaderTemplate is not null)
Expand All @@ -31,14 +42,22 @@
{
@if (Dropdown.MultiSelect)
{
<div style="@(isHidden ? "display: none" : "") @Dropdown.Styles?.ItemWrapper"
<div role="presentation"
style="@(isHidden ? "display: none" : "") @Dropdown.Styles?.ItemWrapper"
class="@Dropdown.GetItemWrapperCssClasses(Item) @Dropdown.Classes?.ItemWrapper">
<button @onclick="@(() => Dropdown.HandleOnItemClick(Item))"
id="@id"
type="button"
role="option"
title="@Dropdown.GetTitle(Item)"
disabled=@isDisabled
style="@Dropdown.Styles?.ItemButton"
class="bit-drp-mcn @Dropdown.Classes?.ItemButton">
class="bit-drp-mcn @Dropdown.Classes?.ItemButton"
aria-label="@Dropdown.GetAriaLabel(Item)"
aria-setsize="@Dropdown.GetTotalItems()"
aria-disabled="@isDisabled"
aria-selected="@(isSelected ? "true" : "false")"
aria-posinset="@Dropdown.GetItemPosInSet(Item)">
<div style="@Dropdown.Styles?.ItemCheckBox"
class="bit-drp-chb @Dropdown.Classes?.ItemCheckBox">
<i aria-hidden="true"
Expand All @@ -58,9 +77,17 @@
<i style="@Dropdown.Styles?.ItemIcon"
class="bit-drp-iic @itemIcon.GetCssClasses() @Dropdown.Classes?.ItemIcon" />
}
<span style="@Dropdown.Styles?.ItemText"
class="bit-drp-itx @Dropdown.Classes?.ItemText">
@text
<span style="@Dropdown.Styles?.ItemText" class="bit-drp-itx @Dropdown.Classes?.ItemText">
@if (highlighted)
{
@text!.Substring(0, highlightIndex)
<span style="@Dropdown.Styles?.ItemHighlight" class="bit-drp-hlt @Dropdown.Classes?.ItemHighlight">@text!.Substring(highlightIndex, highlightLength)</span>
@text!.Substring(highlightIndex + highlightLength)
}
else
{
@text
}
</span>
}
</button>
Expand All @@ -73,13 +100,13 @@
type="button"
role="option"
title="@Dropdown.GetTitle(Item)"
disabled=@(isEnabled is false)
tabindex="@(isEnabled ? 0 : -1)"
disabled=@isDisabled
tabindex="@(isDisabled ? -1 : 0)"
style="@(isHidden ? "display:none" : "") @Dropdown.Styles?.ItemButton"
class="bit-drp-itm@(isSelected ? " bit-drp-sel" : "") @Dropdown.Classes?.ItemButton"
aria-label="@Dropdown.GetAriaLabel(Item)"
aria-setsize="@Dropdown.GetTotalItems()"
aria-disabled="@(isEnabled is false)"
aria-disabled="@isDisabled"
aria-selected="@(isSelected ? "true" : "false")"
aria-posinset="@Dropdown.GetItemPosInSet(Item)">
@if (Dropdown.ItemTemplate is not null)
Expand All @@ -94,9 +121,17 @@
<i style="@Dropdown.Styles?.ItemIcon"
class="bit-drp-iic @itemIcon.GetCssClasses() @Dropdown.Classes?.ItemIcon" />
}
<span style="@Dropdown.Styles?.ItemText"
class="@Dropdown.Classes?.ItemText">
@text
<span style="@Dropdown.Styles?.ItemText" class="bit-drp-itx @Dropdown.Classes?.ItemText">
@if (highlighted)
{
@text!.Substring(0, highlightIndex)
<span style="@Dropdown.Styles?.ItemHighlight" class="bit-drp-hlt @Dropdown.Classes?.ItemHighlight">@text!.Substring(highlightIndex, highlightLength)</span>
@text!.Substring(highlightIndex + highlightLength)
}
else
{
@text
}
</span>
}
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Bit.BlazorUI;

internal static class DropdownsJsRuntimeExtensions
{
internal static ValueTask BitDropdownsSetup(this IJSRuntime jsRuntime, string id, string calloutId)
{
return jsRuntime.InvokeVoid("BitBlazorUI.Dropdowns.setup", id, calloutId);
}

internal static ValueTask BitDropdownsDispose(this IJSRuntime jsRuntime, string id)
{
return jsRuntime.InvokeVoid("BitBlazorUI.Dropdowns.dispose", id);
}

internal static ValueTask BitDropdownsFocusItem(this IJSRuntime jsRuntime, string calloutId, string mode, string? character, bool virtualize)
{
return jsRuntime.InvokeVoid("BitBlazorUI.Dropdowns.focusItem", calloutId, mode, character, virtualize);
}
}
Loading
Loading