Files
sufi-blazor/docs/components/overlays/SbDialog.md
T
2026-05-18 15:53:59 +03:30

7.0 KiB

SbDialog

A modal dialog component built on the native HTML <dialog> element with header, body, and footer slots.

Parameters

Parameter Type Default Description
Open bool false Whether the dialog is open
Title string? null Dialog title displayed in header
Size SbDialogSize Md Dialog size preset
Width string? null Override width; value applied as-is to CSS (e.g. "800px", "80%")
MaxWidth string? null Override max-width; value applied as-is to CSS (e.g. "800px", "80%")
Height string? null Override height; value applied as-is to CSS (e.g. "80vh", "600px", "80%")
MaxHeight string? null Override max-height; value applied as-is to CSS (e.g. "90vh", "800px", "80%")
CloseOnEscape bool true Whether to close on Escape key
CloseOnBackdropClick bool true Whether to close when clicking backdrop
ShowCloseButton bool true Whether to show the close button
OnCloseButtonClick EventCallback - Optional. When set, the header close (X) button invokes this instead of the default close (e.g. pass your modal's Hide so @bind-Open stays in sync)
Class string? null Additional CSS classes
Style string? null Inline styles
AdditionalAttributes Dictionary<string, object>? null Additional HTML attributes

Events

Event Type Description
OpenChanged EventCallback<bool> Fired when open state changes
OnClose EventCallback<SbDialogCloseReason> Fired when dialog closes with reason

Templates / Slots

Slot Type Description
Header RenderFragment Custom header content (replaces Title)
ChildContent RenderFragment Dialog body content
Footer RenderFragment Footer content for action buttons

SbDialogSize Enum

public enum SbDialogSize
{
    Sm,         // 400px max-width
    Md,         // 600px max-width
    Lg,         // 800px max-width
    Xl,         // 1024px max-width
    FullScreen  // Full screen
}

SbDialogCloseReason Enum

public enum SbDialogCloseReason
{
    Escape,       // User pressed Escape key
    Backdrop,     // User clicked the backdrop
    CloseButton,  // User clicked the close button
    Programmatic  // Closed via code
}

CSS Classes

  • sb-dialog - Base class
  • sb-dialog--sm|md|lg|xl|fullscreen - Size variants
  • sb-dialog__container - Inner container
  • sb-dialog__header - Header section
  • sb-dialog__title - Title text
  • sb-dialog__close-btn - Close button
  • sb-dialog__body - Body content
  • sb-dialog__footer - Footer section

Accessibility

  • Uses native <dialog> element
  • aria-labelledby links to title
  • aria-modal="true" indicates modal
  • Close button has aria-label="Close"

Examples

Basic Usage

<SbButton OnClick="() => isOpen = true">Open Dialog</SbButton>

<SbDialog @bind-Open="isOpen" Title="Hello">
    <p>This is the dialog content.</p>
</SbDialog>

@code {
    private bool isOpen = false;
}
<SbDialog @bind-Open="isOpen" Title="Save Changes?">
    <ChildContent>
        <p>You have unsaved changes. Would you like to save them?</p>
    </ChildContent>
    <Footer>
        <SbStack Direction="SbStackDirection.Row" Gap="2" Justify="SbJustify.End">
            <SbButton Variant="SbButtonVariant.Outline" OnClick="() => isOpen = false">
                Discard
            </SbButton>
            <SbButton OnClick="Save">Save Changes</SbButton>
        </SbStack>
    </Footer>
</SbDialog>

Different Sizes

<SbDialog @bind-Open="smallOpen" Title="Small Dialog" Size="SbDialogSize.Sm">
    Small content
</SbDialog>

<SbDialog @bind-Open="largeOpen" Title="Large Dialog" Size="SbDialogSize.Lg">
    Large content
</SbDialog>

<SbDialog @bind-Open="fullOpen" Title="Full Screen" Size="SbDialogSize.FullScreen">
    Full screen content
</SbDialog>

Custom Dimensions (Width, MaxWidth, Height, MaxHeight)

Override the Size preset with inline dimensions. Inline styles override the size class (e.g. sb-dialog--lg):

<SbDialog @bind-Open="isOpen" Title="Wide Modal" Width="900px" MaxWidth="80%">
    Content with custom width
</SbDialog>

<SbDialog @bind-Open="tallOpen" Title="Tall Modal" Height="80vh" MaxHeight="90vh">
    Content with custom height
</SbDialog>

Custom Header

<SbDialog @bind-Open="isOpen">
    <Header>
        <SbStack Direction="SbStackDirection.Row" Align="SbAlign.Center" Gap="2">
            <SbIcon Name="warning" Color="SbColor.Warning" />
            <h2>Warning</h2>
        </SbStack>
    </Header>
    <ChildContent>
        <p>This action cannot be undone.</p>
    </ChildContent>
</SbDialog>

Prevent Accidental Close

<SbDialog @bind-Open="isOpen" 
          Title="Important Form"
          CloseOnEscape="false"
          CloseOnBackdropClick="false"
          ShowCloseButton="false">
    <SbForm Model="@model" OnValidSubmit="Submit">
        <SbTextField Label="Name" @bind-Value="model.Name" />
        <Footer>
            <SbButton Type="submit">Submit</SbButton>
        </Footer>
    </SbForm>
</SbDialog>

Custom Close Button Handler (e.g. for @bind-Open in a wrapper modal)

When the dialog is used inside a modal that binds Open from a parent, the header X should call the same close logic as Cancel so the binding stays in sync:

<SbDialog @bind-Open="Open" OnCloseButtonClick="Hide" Title="Create Item">
    <ChildContent>...</ChildContent>
</SbDialog>

@code {
    [Parameter] public bool Open { get; set; }
    [Parameter] public EventCallback<bool> OpenChanged { get; set; }
    private void Hide() => OpenChanged.InvokeAsync(false);
}

Handle Close Reason

<SbDialog @bind-Open="isOpen" 
          Title="Form"
          OnClose="HandleClose">
    <p>Content</p>
</SbDialog>

@code {
    private void HandleClose(SbDialogCloseReason reason)
    {
        Console.WriteLine($"Dialog closed: {reason}");
        if (reason == SbDialogCloseReason.Backdrop)
        {
            // Show warning about unsaved changes
        }
    }
}

Form Dialog

<SbDialog @bind-Open="isOpen" Title="Add User" Size="SbDialogSize.Md">
    <ChildContent>
        <SbStack Gap="4">
            <SbTextField Label="Name" @bind-Value="user.Name" />
            <SbTextField Label="Email" @bind-Value="user.Email" />
            <SbSelect Label="Role" @bind-Value="user.Role">
                <SbSelectOption Value="user">User</SbSelectOption>
                <SbSelectOption Value="admin">Admin</SbSelectOption>
            </SbSelect>
        </SbStack>
    </ChildContent>
    <Footer>
        <SbStack Direction="SbStackDirection.Row" Gap="2" Justify="SbJustify.End">
            <SbButton Variant="SbButtonVariant.Ghost" OnClick="() => isOpen = false">
                Cancel
            </SbButton>
            <SbButton OnClick="SaveUser">Add User</SbButton>
        </SbStack>
    </Footer>
</SbDialog>