Default — small (400px)

Icon + title + body + footer

razor
<Button Variant="primary" Text="Open modal" OnClick="() => showDefault = true" /> <Modal @bind-IsOpen="showDefault" Title="Add labels to project" Description="Labels help organize projects." Size="sm"> <Icon> <svg>...tag icon...</svg> </Icon> <ChildContent> <InputField Placeholder="Search for label" /> </ChildContent> <Footer> <Button Variant="secondary" Text="Cancel" OnClick="() => showDefault = false" /> <Button Variant="primary" Text="Add labels" OnClick="() => showDefault = false" /> </Footer> </Modal> @code { private bool showDefault; }

Sizes

Four preset widths

razor
@* Sizes: sm (400), md (480), lg (560), xl (640) *@ <Modal @bind-IsOpen="showMd" Size="md" Title="Medium modal"> <ChildContent>...</ChildContent> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Confirm" /> </Footer> </Modal>

Destructive confirmation

Use primary-destructive for both trigger and confirm

razor
<Button Variant="primary-destructive" Text="Delete project" OnClick="() => showDestructive = true" /> <Modal @bind-IsOpen="showDestructive" Title="Delete project" Description="This action cannot be undone." Size="sm"> <Icon> <svg>...trash icon...</svg> </Icon> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary-destructive" Text="Delete" /> </Footer> </Modal>

Without icon

Omit the Icon slot for a text-only header

razor
<Modal @bind-IsOpen="showNoIcon" Title="Edit workspace name" Description="Rename your workspace to something meaningful." Size="sm"> <ChildContent> <InputField Label="Workspace name" Value="Design System" /> </ChildContent> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Save changes" /> </Footer> </Modal>

Footer with status message

Validation error on the left, actions on the right

razor
<Modal @bind-IsOpen="showValidation" Title="Edit workspace" Size="md" StatusType="error" StatusMessage="Please fix 2 fields before saving"> <ChildContent> <InputField Label="Workspace name" Value="" /> <InputField Label="Contact email" Value="not-an-email" /> </ChildContent> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Save changes" /> </Footer> </Modal>

Success status — auto-saved indicator

razor
<Modal @bind-IsOpen="showSaved" Title="Edit workspace" Size="md" StatusType="success" StatusMessage="Last saved a moment ago"> <ChildContent>...</ChildContent> <Footer> <Button Variant="secondary" Text="Close" /> <Button Variant="primary" Text="Done" /> </Footer> </Modal> @* StatusType options: neutral | info | success | warning | error *@

Custom FooterStatus slot — loading spinner

razor
<Modal @bind-IsOpen="showSaving" Title="Edit workspace" Size="md"> <FooterStatus> @* Custom slot — render anything (spinner, count badge, link) *@ <span class="modal-footer__status-icon"> <svg style="animation: spin 0.8s linear infinite;">...</svg> </span> <span class="modal-footer__status-text">Saving changes…</span> </FooterStatus> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Save" Disabled /> </Footer> </Modal>

Footer actions layout

ActionsLayout="split" — full-width buttons (default when no status)

razor
<Modal @bind-IsOpen="showSplit" Title="Confirm action" Size="md" ActionsLayout="split"> <ChildContent>...</ChildContent> <Footer> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Confirm" /> </Footer> </Modal> @* ActionsLayout values: auto (default) | split | end *@

ActionsLayout="end" — content-sized, right-aligned

razor
<Modal @bind-IsOpen="showEnd" Title="Review changes" Size="md" ActionsLayout="end"> <ChildContent>...</ChildContent> <Footer> <Button Variant="tertiary" Text="Save draft" /> <Button Variant="secondary" Text="Cancel" /> <Button Variant="primary" Text="Publish" /> </Footer> </Modal> @* Use "end" when you have 3+ buttons, or when stretched labels look awkward. Buttons keep their natural width. *@
An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.