Skip to content

Add BitDropdown component - #102

Merged
albx merged 15 commits into
mainfrom
feature/54-bitdropdown-component
Jul 28, 2026
Merged

Add BitDropdown component#102
albx merged 15 commits into
mainfrom
feature/54-bitdropdown-component

Conversation

@albx

@albx albx commented Jul 25, 2026

Copy link
Copy Markdown
Owner

This pull request introduces a new, highly customizable BitDropdown component for the BitBlazor library, along with its supporting types and styles. The implementation includes both the dropdown menu and individual dropdown items, with a strong focus on accessibility, keyboard navigation, and flexible theming. The main changes are organized as follows:

New Dropdown Component Implementation

  • Added the BitDropdown component, which supports custom activator templates, menu positioning, color themes, menu widths, and item sizing. It manages open/close state, focus management, and accessibility attributes. (BitDropdown.razor, BitDropdown.razor.cs) [1] [2]
  • Introduced the ActivatorContext class to encapsulate the activator button's state and behavior, including keyboard event handling and accessibility attributes. (ActivatorContext.cs)

Dropdown Item Component

  • Added the BitDropdownItem component, which represents an interactive or navigational item within the dropdown. It supports disabled and active states, custom content, keyboard navigation, and focus management. (BitDropdownItem.razor, BitDropdownItem.razor.cs) [1] [2]

Theming and Customization

  • Introduced supporting enums for dropdown customization: DropdownPosition, DropdownMenuColor, DropdownMenuWidth, and DropdownItemSize, enabling flexible positioning, appearance, and sizing of the dropdown and its items. (DropdownPosition.cs, DropdownMenuColor.cs, DropdownMenuWidth.cs, DropdownItemSize.cs) [1] [2] [3] [4]

Styling

  • Added CSS to ensure the dropdown container shrink-wraps to the activator button for correct menu placement, and basic styling for dropdown items. (BitDropdown.razor.css, BitDropdownItem.razor.css) [1] [2]

@albx albx linked an issue Jul 25, 2026 that may be closed by this pull request
@albx
albx requested a review from Copilot July 25, 2026 15:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new BitDropdown component to the BitBlazor library, including a companion BitDropdownItem, supporting customization enums, styles, Storybook stories, and bUnit tests to validate rendering and interactive behaviors.

Changes:

  • Introduces BitDropdown + ActivatorContext for templated activators and keyboard-driven open/close/focus behavior.
  • Adds BitDropdownItem with active/disabled states, optional navigation (Href), and keyboard navigation within the menu.
  • Adds enums + CSS + Storybook stories and test coverage for rendering/behavior scenarios.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/BitBlazor.Test/Components/Dropdown/BitDropdownTest.Rendering.razor Rendering-focused bUnit tests validating generated markup for common dropdown configurations.
tests/BitBlazor.Test/Components/Dropdown/BitDropdownTest.Behaviors.cs Behavior-focused bUnit tests validating toggling, placement attributes, and keyboard interactions.
stories/BitBlazor.Stories/Components/Stories/Components/BitDropdown.stories.razor Storybook coverage for default/custom activators and visual variants (position, width, color, item size).
src/BitBlazor/Components/Dropdown/BitDropdown.razor Dropdown markup composition (container, activator template, menu wrapper, cascading context).
src/BitBlazor/Components/Dropdown/BitDropdown.razor.cs Dropdown state management, placement attributes, item registration, focus navigation, and close behavior.
src/BitBlazor/Components/Dropdown/BitDropdown.razor.css Styling to shrink-wrap dropdown container for correct menu positioning without JS/Popper.
src/BitBlazor/Components/Dropdown/ActivatorContext.cs Activator state + attributes + keyboard handler logic exposed to custom activator templates.
src/BitBlazor/Components/Dropdown/BitDropdownItem.razor Dropdown item markup (interactive anchor element with attributes, click, and key handling).
src/BitBlazor/Components/Dropdown/BitDropdownItem.razor.cs Dropdown item behaviors (disabled/active, click vs navigate, arrow key focus movement, escape-to-close).
src/BitBlazor/Components/Dropdown/BitDropdownItem.razor.css Minimal dropdown item cursor styling.
src/BitBlazor/Components/Dropdown/DropdownPosition.cs Enum for menu placement relative to the activator.
src/BitBlazor/Components/Dropdown/DropdownMenuColor.cs Enum for menu theme variants.
src/BitBlazor/Components/Dropdown/DropdownMenuWidth.cs Enum for menu width variants.
src/BitBlazor/Components/Dropdown/DropdownItemSize.cs Enum for dropdown item size variants.

Comment thread src/BitBlazor/Components/Dropdown/BitDropdown.razor Outdated
Comment thread src/BitBlazor/Components/Dropdown/ActivatorContext.cs
Comment thread src/BitBlazor/Components/Dropdown/ActivatorContext.cs
Comment thread src/BitBlazor/Components/Dropdown/ActivatorContext.cs
Comment thread src/BitBlazor/Components/Dropdown/BitDropdownItem.razor Outdated
@albx
albx marked this pull request as ready for review July 27, 2026 05:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

src/BitBlazor/Components/Dropdown/BitDropdownItem.razor:4

  • Disabled dropdown items currently still render href unconditionally. In non-interactive (static SSR) rendering the @onclick handler won't run, so a disabled item with Href would still navigate when clicked. To make Disabled effective in all render modes, omit the href attribute when the item is disabled.
    <a href="@Href" class="@ComputeLinkCssClass()" tabindex="@(Disabled ? "-1" : "0")" @ref="itemAnchorRef" @attributes="AdditionalAttributes" @onclick="ClickAsync" @onclick:preventDefault="@RendererInfo.IsInteractive" @onkeydown="OnKeyDownAsync">

src/BitBlazor/Components/Dropdown/BitDropdownItem.razor.cs:91

  • SetDisabled mutates AdditionalAttributes["role"] for the disabled state and then removes role when re-enabled. This can unintentionally overwrite or remove a consumer-provided role attribute on the item anchor, and role="button" on an <a> is generally not appropriate here (the item already has correct keyboard handling via tabindex + key handlers). Consider only managing aria-disabled and leaving role untouched so consumers can set it deliberately when needed.
        if (Disabled)
        {
            AdditionalAttributes["aria-disabled"] = "true";
            AdditionalAttributes["role"] = "button";
        }

src/BitBlazor/Components/Dropdown/ActivatorContext.cs:58

  • HandleKeyDownAsync only handles ArrowUp/ArrowDown, but the XML docs currently state that Enter/Space toggles the dropdown and also say "wire the following four directives" (while the sample lists more behavior/attributes elsewhere). This mismatch makes it hard for consumers to understand what ActivatorContext actually guarantees. Please align the docs with the implemented behavior and clarify that Enter/Space comes from native <button> behavior (or must be handled by non-button activators).
    /// Handles keyboard events on the activator element.
    /// <list type="bullet">
    ///   <item><description><c>Enter</c> / <c>Space</c> — toggles the dropdown open or closed, keeping focus on the activator.</description></item>
    ///   <item><description><c>ArrowDown</c> — opens the dropdown and moves focus to the first enabled item.</description></item>
    ///   <item><description><c>ArrowUp</c> — opens the dropdown and moves focus to the last enabled item.</description></item>

docs/components/dropdown.md:136

  • This section says to wire "all five directives", but the table below lists six (including @onkeydown:preventDefault), and the snippet itself omits @onkeydown:preventDefault. That inconsistency is likely to confuse consumers copying the example. Please either update the snippet to include the missing directive and adjust the count, or remove it from the table if it’s only optional guidance.
When replacing the default button, you must wire all five directives to preserve full keyboard accessibility and correct ARIA state:

```razor
<BitDropdown ActivatorId="custom-activator" ActivatorLabel="Actions">
    <ActivatorTemplate Context="ctx">

@albx
albx merged commit e906afb into main Jul 28, 2026
4 checks passed
@albx
albx deleted the feature/54-bitdropdown-component branch July 29, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Implement BitDropdown component

2 participants