Component

BOBAccordion

Vertically stacked, expandable panels. Choose between multi-open, single-open, or always-one-open modes.

API reference ↗

Basic usage

General settings appear here. Click again to collapse.
Advanced configuration. In the default Multiple mode you can keep both panels open.
Diagnostic tools and logs.
RAZOR
<BOBAccordion>
    <BOBAccordionItem Id="general">
        <Header>General</Header>
        <ChildContent>General settings appear here. Click again to collapse.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="advanced">
        <Header>Advanced</Header>
        <ChildContent>Advanced configuration. In the default Multiple mode you can keep both panels open.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="diagnostics">
        <Header>Diagnostics</Header>
        <ChildContent>Diagnostic tools and logs.</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Single mode

Only one panel can be open at a time. Click an open panel to collapse it.

Plan selection content.
Billing form.
Final review.
RAZOR
<BOBAccordion Mode="BOBAccordionMode.Single">
    <BOBAccordionItem Id="step-1">
        <Header>Step 1 — Pick a plan</Header>
        <ChildContent>Plan selection content.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="step-2">
        <Header>Step 2 — Add billing</Header>
        <ChildContent>Billing form.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="step-3">
        <Header>Step 3 — Confirm</Header>
        <ChildContent>Final review.</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Always one open

The first panel auto-expands and at least one panel is always visible.

Auto-expanded on first render.
Click to swap which panel is open.
RAZOR
<BOBAccordion Mode="BOBAccordionMode.SingleStrict">
    <BOBAccordionItem Id="overview">
        <Header>Overview</Header>
        <ChildContent>Auto-expanded on first render.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="features">
        <Header>Features</Header>
        <ChildContent>Click to swap which panel is open.</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Disabled item

This panel works as usual.
Unreachable.
Keyboard arrow navigation skips disabled items.
RAZOR
<BOBAccordion>
    <BOBAccordionItem Id="active">
        <Header>Active</Header>
        <ChildContent>This panel works as usual.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="locked" Disabled="true">
        <Header>Locked (disabled)</Header>
        <ChildContent>Unreachable.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="next">
        <Header>Next</Header>
        <ChildContent>Keyboard arrow navigation skips disabled items.</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Gap + border

Default gap is 0 (items flush). Combine Gap with a Border preset for a card-like grouping.

Items separated by 0.5rem and grouped inside a rounded border.
The border is on the parent. Individual items never carry their own border.
Try other presets: BOBBorderPresets.Subtle, .Pill, .RoundedLarge...
RAZOR
<BOBAccordion Gap="0.5rem" Border="@BOBBorderPresets.Rounded">
    <BOBAccordionItem Id="gap-a">
        <Header>Item A</Header>
        <ChildContent>Items separated by 0.5rem and grouped inside a rounded border.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="gap-b">
        <Header>Item B</Header>
        <ChildContent>The border is on the parent. Individual items never carry their own border.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="gap-c">
        <Header>Item C</Header>
        <ChildContent>Try other presets: BOBBorderPresets.Subtle, .Pill, .RoundedLarge...</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Custom separator

Render any markup between items via the Separator slot. Combine with Gap=0 for a hairline divider.

Content one.
Content two.
Content three.
RAZOR
<BOBAccordion>
    <Separator>
        <hr style="border: none; border-top: 1px solid var(--palette-border); margin: 0;" />
    </Separator>
    <ChildContent>
        <BOBAccordionItem Id="sep-a">
            <Header>Section one</Header>
            <ChildContent>Content one.</ChildContent>
        </BOBAccordionItem>
        <BOBAccordionItem Id="sep-b">
            <Header>Section two</Header>
            <ChildContent>Content two.</ChildContent>
        </BOBAccordionItem>
        <BOBAccordionItem Id="sep-c">
            <Header>Section three</Header>
            <ChildContent>Content three.</ChildContent>
        </BOBAccordionItem>
    </ChildContent>
</BOBAccordion>

Custom expand icon

Override the icon per item. Default Plus rotates 45° on open; for chevrons set --_accordion-icon-rotation: 180deg in your CSS.

Custom chevron icon.
More content.
RAZOR
<BOBAccordion>
    <BOBAccordionItem Id="info" ExpandIcon="@BOBIconKeys.UI.ChevronDown" InitiallyExpanded="true">
        <Header>Info</Header>
        <ChildContent>Custom chevron icon.</ChildContent>
    </BOBAccordionItem>
    <BOBAccordionItem Id="more" ExpandIcon="@BOBIconKeys.UI.ChevronDown">
        <Header>More</Header>
        <ChildContent>More content.</ChildContent>
    </BOBAccordionItem>
</BOBAccordion>

Properties

BOBAccordion

9 rows.
PropertyTypeDefaultDescription
ChildContentRenderFragment?Markup that emits the accordion items (typically &lt;BOBAccordionItem&gt; children).
SeparatorRenderFragment?/// Optional content rendered between consecutive items. When (default), /// items stack flush with no divider. ///
Gapstring"0"/// CSS gap between items (and between items and separators). Accepts any valid CSS length /// (e.g. "0", "0.5rem", "8px"). Defaults to "0". ///
ModeBOBAccordionModeBOBAccordionMode.MultipleDetermines how many items can be expanded at the same time. Defaults to .
ExpandedItemsIReadOnlyList<string>?/// Identifiers of currently expanded items. When non-, the accordion runs in /// controlled mode: the internal state mirrors this list on every render and /// is ignored. ///
ExpandedItemsChangedEventCallback<IReadOnlyList<string>>Raised whenever the set of expanded items changes. Provides the full new snapshot.
OnExpandedChangedEventCallback<BOBAccordionItemToggle>/// Raised for the item whose expanded state was toggled by the user (click or keyboard). /// Other items collapsed implicitly by Single/SingleStrict modes do not trigger this callback. ///
SizeBOBSizeBOBSize.MediumVisual size of the accordion.
BorderBorderStyle?BOBBorderPresets.None/// Border applied to the accordion container. Defaults to .None; /// individual items never carry a border of their own. ///

BOBAccordionItem

7 rows.
PropertyTypeDefaultDescription
Idstring?Stable identifier for the item. Used to track expanded state. Required.
HeaderRenderFragment?Markup rendered inside the header button. Required.
ChildContentRenderFragment?Body content rendered when the item is expanded.
DisabledboolWhen , the item is non-interactive and cannot be expanded or collapsed by the user.
ExpandIconIconKey?/// Icon rendered next to the header. Defaults to .UI.Plus (rotates 45° to "x" when expanded). /// If you set a directional icon (e.g. ChevronDown), override --_accordion-icon-rotation /// in your CSS to a value that matches the glyph (180deg for chevrons). ///
ExpandIconColorstring?Color applied to the expand icon. Accepts any valid CSS color value.
InitiallyExpandedbool/// When , the item starts expanded the first time it registers with its parent. /// Subsequent changes to this parameter are ignored — control expanded state through the parent's /// binding. ///