Skip to content

Action Sheet ​

An action sheet is a dialog that slides up from the bottom of the screen and offers a set of options. The user has to pick one or dismiss it before going back to the app.

IonActionSheet is the declarative component. IonActionSheetController creates the same sheet from code. See Overlays for where overlays render, what has to be in place, and how dismiss results work.

Basic usage ​

Show the sheet with IsOpen. Buttons takes a list of IonActionSheetButton. The first button with role cancel is moved into a separate group at the bottom; any further cancel buttons are not rendered. Tapping a button, tapping the backdrop, or pressing the system back button closes the sheet. With BackdropDismiss="false", only the buttons close it.

razor
<IonButton OnClick="@(() => _isOpen = true)">Open action sheet</IonButton>

<IonActionSheet @bind-IsOpen="_isOpen"
                Header="Albums"
                Buttons="@_buttons" />

@code {
    private bool _isOpen;

    // The cancel-role button is pulled into its own group at the bottom.
    private readonly IReadOnlyList<IonActionSheetButton> _buttons =
    [
        new() { Text = "Delete", Role = "destructive" },
        new() { Text = "Share" },
        new() { Text = "Favorite" },
        new() { Text = "Cancel", Role = "cancel" },
    ];
}

Buttons and results ​

OnDidDismiss reports the tapped button's Role and Data. A backdrop tap reports role "backdrop" and a back press role "back", both with null data.

A button's Role also styles it: destructive uses the theme's destructive color, selected is bold, and cancel gets the cancel weight. Icon takes an Ionicons name and draws it before the text. Handler runs before the sheet closes. Disabled dims a non-cancel button and makes it ignore taps.

razor
<IonButton OnClick="@(() => _isOpen = true)">Photo options</IonButton>
<p>Chosen: @(_chosen ?? "nothing")</p>

<IonActionSheet @bind-IsOpen="_isOpen"
                Header="Photo"
                SubHeader="IMG_0042.jpg"
                Buttons="@_buttons"
                OnDidDismiss="OnDismissed" />

@code {
    private bool _isOpen;
    private string? _chosen;

    private readonly IReadOnlyList<IonActionSheetButton> _buttons =
    [
        new() { Text = "Copy", Icon = Ionicons.Copy, Data = "copy" },
        new() { Text = "Edit", Icon = Ionicons.Pencil, Data = "edit" },
        new() { Text = "Archive", Icon = Ionicons.Archive, Data = "archive" },
        new() { Text = "Delete", Icon = Ionicons.TrashOutline, Role = "destructive", Data = "delete" },
        new() { Text = "Cancel", Icon = Ionicons.Close, Role = "cancel" },
    ];

    // Role is the tapped button's role ("cancel", "destructive", null), "backdrop" or "back";
    // Data is the tapped button's Data (null for the backdrop and the back button).
    private void OnDismissed(IonOverlayDismissEventArgs e)
        => _chosen = e.IsCancel ? null : e.Data as string;
}

Using the controller ​

IonActionSheetController.CreateAsync takes an IonActionSheetOptions with the same header, buttons, and BackdropDismiss settings. OnDidDismissAsync() completes with the same role and data as OnDidDismiss.

razor
@inject IonActionSheetController ActionSheetController

<IonButton OnClick="ShowAsync">Sort by…</IonButton>
<p>Sorted by: @_sort</p>

@code {
    private string _sort = "date";

    private async Task ShowAsync()
    {
        var sheet = await ActionSheetController.CreateAsync(new IonActionSheetOptions
        {
            Header = "Sort by",
            Buttons =
            [
                new() { Text = "Date", Data = "date" },
                new() { Text = "Name", Data = "name" },
                new() { Text = "Size", Data = "size" },
                new() { Text = "Cancel", Role = "cancel" },
            ],
        });
        await sheet.PresentAsync();

        var result = await sheet.OnDidDismissAsync();
        if (result.Data is string sort)
            _sort = sort;
    }
}

API ​

Every component also accepts Class (extra CSS classes), Style (an inline Style object) and Id (the root element's id) — see Conventions.

IonActionSheet ​

ParameterTypeDefaultDescription
BackdropDismissbooltrueIf true (default), tapping the backdrop or pressing the system back button dismisses the sheet.
ButtonsIReadOnlyList<IonActionSheetButton>[]The buttons to show. The first cancel-role button is pulled into a separate bottom group; further cancel-role buttons are not rendered.
Headerstring?nullThe optional title shown above the buttons.
IsOpenboolfalseWhether the sheet is presented. Bind two-way with IsOpenChanged. Two-way bindable: @bind-IsOpen.
OverlayIdstring?nullOptional stable identifier used by the root overlay registry.
SubHeaderstring?nullThe optional sub-title shown under the header.
Triggerstring?nullId of the element that opens the sheet when clicked (Ionic trigger), e.g. <IonButton Id="open-sheet">. Opening sets IsOpen and raises IsOpenChanged. The page must be inside an IonApp.
EventTypeDescription
IsOpenChangedEventCallback<bool>Raised with the new open state when the sheet opens/closes.
OnDidDismissEventCallback<IonOverlayDismissEventArgs>Raised when the sheet dismisses, with the tapped button's role and data, or role "backdrop" / "back" (null data) for a backdrop tap / system back press.

Types ​

IonActionSheetButton ​

A single action-sheet button. Mirrors Ionic's ActionSheetButton interface. The Role drives styling and placement: the first "cancel" button is pulled into its own bottom group; "destructive" buttons render in the destructive (danger) color; "selected" renders bold. Every button — cancel included — runs its Handler on tap and then dismisses the sheet with its role and Data.

PropertyTypeDefaultDescription
Textstring?nullThe button label.
Rolestring?nullOptional role: "cancel", "destructive", "selected", or a custom string. Stamped as action-sheet-{role}.
Iconstring?nullOptional leading icon (an Ionicons name).
CssClassstring?nullExtra CSS class(es) to add to the button.
Dataobject?nullArbitrary data returned with the dismiss event when this button is tapped.
DisabledboolfalseWhen true, the button is drawn dimmed and tapping it does nothing. Ignored for cancel buttons, as in Ionic.
HandlerAction?nullOptional handler run when the button is tapped, before the sheet dismisses.
IsCancelboolfalseTrue when Role is "cancel" (case-insensitive). (read-only)

IonActionSheetOptions ​

Options for IonActionSheetController.CreateAsync. Each property maps to the IonActionSheet parameter of the same name.

PropertyTypeDefaultDescription
Headerstring?nullThe optional title shown above the buttons.
SubHeaderstring?nullThe optional sub-title shown under the header.
ButtonsIReadOnlyList<IonActionSheetButton>[]The buttons to show.
BackdropDismissbooltrueIf true (default), a backdrop tap or the system back button dismisses the sheet.
CssClassstring?nullExtra CSS class(es) for the sheet host (its Class).

IonActionSheetController ​

Creates action sheets from code (Ionic's actionSheetController). Inject it; AddIonic() registers it.

MethodReturnsDescription
CreateAsync(IonActionSheetOptions options)Task<IonOverlayReference>Creates an action sheet from options. Call IonOverlayReference.PresentAsync on the result to show it.

Styling ​

Theme tokens ​

Theme token IonicTheme.ActionSheet (ActionSheetToken). Assign only the values you want to change — the rest keep the mode defaults below. App-wide: builder.AddIonic(o => o.Theme.ActionSheet = new ActionSheetToken { … }); for one subtree: a ConfigProvider. See Theming.

TokenTypemdios
BackdropColorColor#000000#000000
BackdropOpacityfloat0.320.4
BackgroundColor#ffffff#f9f9f9
BorderRadiusfloat013
ButtonBorderColorColortransparentrgba(0, 0, 0, 0.08)
ButtonColorColor#262626#0054e9
ButtonFontSizefloat1620
ButtonHeightfloat5256
ButtonJustifyJustifyContentJustifyContent.FlexStartJustifyContent.Center
ButtonPaddingXfloat1614
ButtonPaddingYfloat1214
CancelFontWeightFontWeightFontWeight.NormalFontWeight.SemiBold
ContainerPaddingXfloat08
DestructiveColorColor#c5000f#c5000f
EnterDurationfloat0.40.4
GroupMarginBottomfloat010
GroupMarginTopfloat010
IconFontSizefloat2428
LeaveDurationfloat0.450.45
MaxWidthfloat500500
SubTitleFontSizefloat1413
TextAlignTextAlignTextAlign.LeftTextAlign.Center
TitleColorColorrgba(0, 0, 0, 0.54)#999999
TitleFontSizefloat1613
TitlePaddingXfloat1610
TitlePaddingYfloat2014

IonicTheme.ActionSheet.BackdropColor also colors the backdrop of IonLoading.

CSS classes ​

App stylesheet rules always win over Ionic's own rules (see Theming), so these classes can be targeted directly from GlobalStyles.cs.

SelectorElement
.ion-action-sheetThe full-screen host. Also carries the mode (md / ios) and the state classes below.
.action-sheet-openThe sheet is open (drives the slide-up and backdrop fade).
.action-sheet-mountedOpen or still animating out: the host takes taps.
.overlay-hiddenClosed and settled: the host ignores taps.
.action-sheet-backdropThe dim layer behind the sheet (also .ion-backdrop).
.action-sheet-wrapperThe sliding panel at the bottom edge.
.action-sheet-containerThe column holding the button groups.
.action-sheet-groupA button group; .action-sheet-group-cancel is the separate cancel group.
.action-sheet-title, .action-sheet-sub-titleHeader and SubHeader.
.action-sheet-buttonOne button; .action-sheet-button-inner is its icon + label row, .action-sheet-icon the icon.
.action-sheet-{role}A button's Role, e.g. .action-sheet-destructive, .action-sheet-cancel, .action-sheet-selected.

A button's CssClass and the sheet's Class (or IonActionSheetOptions.CssClass) add your own classes:

csharp
// GlobalStyles.cs — <IonActionSheet Class="compact" …>
[".ion-action-sheet.compact .action-sheet-button"] = new()
{
    MinHeight = Length.Px(44),
},

Released under the MIT License.