Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

Accordion

Sections that open and close with no script.

An interactive page: C# runs over a Blazor Server connection.

Usage

razor
<Accordion>
    <AccordionItem Title="How do refunds work?" Open>
        Refunds go back to the original card within 5 business days.
    </AccordionItem>
    <AccordionItem Title="Can I change my plan later?">
        Yes. Changes apply from your next billing date.
    </AccordionItem>
</Accordion>

Each item is a native details element, so the browser opens and closes it, with JavaScript off too. Use it for sections people open one by one, such as FAQs or settings; for a single "show more", use a Collapsible, and for views people switch between, Tabs.

Variants

Use Variant to draw the items as separate cards (the default), as one bordered box, or flush with the page.

Preview

Separated

How do refunds work?
Refunds go back to the original card within 5 business days.
Can I change my plan later?
Yes. Changes apply from your next billing date.

Bordered

How do refunds work?
Refunds go back to the original card within 5 business days.
Can I change my plan later?
Yes. Changes apply from your next billing date.

Flush

How do refunds work?
Refunds go back to the original card within 5 business days.
Can I change my plan later?
Yes. Changes apply from your next billing date.

Code

Variants.razor
<Stack Gap="6" Grow>
    @foreach (var variant in Enum.GetValues<AccordionVariant>())
    {
        <Stack Gap="2">
            <TextBlock Size="TextSize.Sm" Color="Color.Muted">@variant</TextBlock>
            <Accordion Variant="variant">
                <AccordionItem Title="How do refunds work?" Icon="Lucide.CreditCard">
                    Refunds go back to the original card within 5 business days.
                </AccordionItem>
                <AccordionItem Title="Can I change my plan later?">
                    Yes. Changes apply from your next billing date.
                </AccordionItem>
            </Accordion>
        </Stack>
    }
</Stack>

One open at a time

Use Exclusive to keep one item open: opening another closes it, by the browser, with no script. Disabled stops an item opening.

Preview

Shipping
Orders ship within two business days.
Returns
Return anything within 30 days, in its original box.
Warranty
Two years on all hardware, parts and labor.
Gift cards
Coming soon.

Code

Exclusive.razor
<Accordion Exclusive Variant="AccordionVariant.Bordered" Grow>
    <AccordionItem Title="Shipping" Open>Orders ship within two business days.</AccordionItem>
    <AccordionItem Title="Returns">Return anything within 30 days, in its original box.</AccordionItem>
    <AccordionItem Title="Warranty">Two years on all hardware, parts and labor.</AccordionItem>
    <AccordionItem Title="Gift cards" Disabled>Coming soon.</AccordionItem>
</Accordion>

Exclusive items share a name; set Name yourself to group several accordions, so one item is open across all of them.

Rich headers and content

Use an AccordionHeader for a title with more than text, such as a badge, and Icon for an icon before it; the content is a column with a gap, so text, buttons and lists need no wrapper.

Preview

Getting started 2 steps left

Create a project, then invite your team.

You can change these settings later.

Usage this month
Builds
132 of 500
Storage
4.1 GB of 10 GB

Code

Content.razor
<Accordion Variant="AccordionVariant.Bordered" Grow>
    <AccordionItem Open>
        <AccordionHeader>Getting started <Badge Status="Status.Info" Pill>2 steps left</Badge></AccordionHeader>
        <TextBlock>Create a project, then invite your team.</TextBlock>
        <TextBlock Size="TextSize.Sm" Color="Color.Muted">You can change these settings later.</TextBlock>
        <Row Gap="2">
            <Button Size="ControlSize.Sm">Create project</Button>
            <Button Size="ControlSize.Sm" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral">Read the guide</Button>
        </Row>
    </AccordionItem>
    <AccordionItem Title="Usage this month">
        <DescriptionList Divided>
            <DescriptionItem Term="Builds">132 of 500</DescriptionItem>
            <DescriptionItem Term="Storage">4.1 GB of 10 GB</DescriptionItem>
        </DescriptionList>
    </AccordionItem>
</Accordion>

ContentPadding and ContentGap change the content's spacing for every item, or on one item; ContentPadding="0" runs a table or image edge to edge.

Sizes

Use Size to scale the titles and spacing together: Sm for sidebars and dense pages, Lg for FAQ pages.

Preview

Billing
Invoices go out on the 1st of the month.
Security
Two-factor sign-in is on.
Billing
Invoices go out on the 1st of the month.
Security
Two-factor sign-in is on.

Code

Sizes.razor
<Grid Columns="new() { Base = 1, Md = 2 }" Gap="6" Align="Align.Start" Grow>
    <Accordion Size="ControlSize.Sm" Variant="AccordionVariant.Bordered">
        <AccordionItem Title="Billing" Icon="Lucide.CreditCard" Open>Invoices go out on the 1st of the month.</AccordionItem>
        <AccordionItem Title="Security" Icon="Lucide.Shield">Two-factor sign-in is on.</AccordionItem>
    </Accordion>
    <Accordion Size="ControlSize.Lg" Variant="AccordionVariant.Bordered">
        <AccordionItem Title="Billing" Icon="Lucide.CreditCard" Open>Invoices go out on the 1st of the month.</AccordionItem>
        <AccordionItem Title="Security" Icon="Lucide.Shield">Two-factor sign-in is on.</AccordionItem>
    </Accordion>
</Grid>

Forms in sections

Use Open on an item to open it from the server, such as the section whose form just posted.

Preview

Profile
Notifications

Code

Settings.razor
@using System.ComponentModel.DataAnnotations

@* Each section's form posts on its own. A static page renders the accordion again with every
   post, so the section that posted, saved or not, is opened from the server with Open. *@
<Accordion Variant="AccordionVariant.Bordered" Grow MaxWidth="32.Rem">
    <AccordionItem Title="Profile" Open="_posted.Contains(Section.Profile)">
        <Form Model="Profile" FormName="accordion-profile" OnValidSubmit="() => Saved(Section.Profile)" OnInvalidSubmit="() => _posted.Add(Section.Profile)">
            <TextField @bind-Value="Profile!.DisplayName" />
            <FormActions><Button Submit Size="ControlSize.Sm">Save profile</Button></FormActions>
        </Form>
    </AccordionItem>
    <AccordionItem Title="Notifications" Open="_posted.Contains(Section.Notifications)">
        <Form Model="Notifications" FormName="accordion-notifications" OnValidSubmit="() => Saved(Section.Notifications)" OnInvalidSubmit="() => _posted.Add(Section.Notifications)">
            <Switch @bind-Value="Notifications!.WeeklySummary" />
            <FormActions><Button Submit Size="ControlSize.Sm">Save notifications</Button></FormActions>
        </Form>
    </AccordionItem>
</Accordion>
@if (_saved is not null)
{
    <TextBlock Size="TextSize.Sm" Color="Color.Muted" MarginTop="3">@_saved</TextBlock>
}

@code {
    [SupplyParameterFromForm(FormName = "accordion-profile")]
    private ProfileSettings? Profile { get; set; }

    [SupplyParameterFromForm(FormName = "accordion-notifications")]
    private NotificationSettings? Notifications { get; set; }

    // Sections that have posted. Only ever added to, so on an interactive page Open never turns
    // false and closes a section the reader left open.
    private readonly HashSet<Section> _posted = [];
    private string? _saved;

    protected override void OnInitialized()
    {
        Profile ??= new();
        Notifications ??= new();
    }

    private void Saved(Section section)
    {
        _posted.Add(section);
        _saved = section == Section.Profile
            ? $"Saved your name as {Profile!.DisplayName}."
            : $"Saved: {(Notifications!.WeeklySummary ? "with" : "without")} the weekly summary.";
    }
}

Live: Saving runs C# with no page load, and every section stays as you left it.

The browser keeps which items are open, not the server, so on a static page every post or reload draws them as Open says and closes the rest. Open the section that posted, as here, whether it saved or not (OnInvalidSubmit too), so its message or errors are in view.

Following it from C#

Use @bind-Open on an AccordionItem to know in C# whether it's open, and to open or close it from C#, on an interactive page.

Preview

Release notes
Version 2.4 adds dark mode to the dashboard and speeds up search.

C# has it closed

Code

Bound.razor
@* The item opens and closes in every mode; on an interactive page C# follows it. *@
<Stack Gap="3" Grow>
    <Accordion>
        <AccordionItem Title="Release notes" @bind-Open="_notesOpen">
            Version 2.4 adds dark mode to the dashboard and speeds up search.
        </AccordionItem>
    </Accordion>
    <TextBlock Size="TextSize.Sm" Color="Color.Muted">C# has it <Code>@(_notesOpen ? "open" : "closed")</Code></TextBlock>
</Stack>

@code {
    private bool _notesOpen;
}

Live: @bind-Open tells C# each time the item opens or closes.

Parts

Written inside Accordion. The API page lists their parameters.

  • AccordionItem: one section of an Accordion: a native <details> with the title in its <summary>.
  • AccordionHeader: Heading content for an AccordionItem in place of its Title, such as a title with a badge.

Mode support

What works in each mode, Accordion
FeatureOffStaticLive
Items open and close, one at a time with ExclusiveYesYesYes
An item's Open bound to C#NoNoYes

Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).

Accessibility

  • Each item's summary takes Enter and Space and is announced as expanded or collapsed by the browser, with JavaScript off too.
  • Tab moves from item to item; there are no arrow-key or Home/End shortcuts.
  • The title isn't a heading, so items don't appear in a screen reader's list of headings. AccordionHeader is drawn inside the summary: keep it to inline content, with no links or buttons.
  • A Disabled item sets aria-disabled on its summary and leaves the tab order; the script also stops it from toggling.

Parameters

Accordion parameters
PropTypeDefault
ExclusiveKeeps only one item open at a time.boolfalse
VariantHow the items are drawn.AccordionVariantAccordionVariant.Separated
SizeSpacing and title size: ControlSize.Sm for sidebars and dense pages, ControlSize.Lg for FAQ pages.ControlSizeControlSize.Md
ContentPaddingPadding inside every item's content, in spacing steps.Responsive<int>
ContentGapSpace between the children of every item's content, in spacing steps.Responsive<int>
NameThe shared name for exclusive items.string?
ChildContentThe AccordionItems.RenderFragment?

See also

  • Collapsible: one "show more" section.
  • Tabs: panels that switch with no script, or links to pages.