PleasantDrawer

April 9, 2026 · View on GitHub

A panel that slides in from an edge of the screen, overlaying the main content. Supports light-dismiss (click outside to close), optional title, close button, and all four positions (Left, Right, Top, Bottom).

Basic usage

<PleasantDrawer Title="Settings"
                Position="Right"
                PanelWidth="400">
    <StackPanel Spacing="10">
        <TextBlock Text="Drawer content" />
        <CheckBox Content="Enable feature" />
        <Button Content="Save" />
    </StackPanel>
</PleasantDrawer>
await drawer.ShowAsync(window);

Properties

PropertyTypeDefaultDescription
Titlestring?Title shown in the drawer header
PositionDrawerPositionRightWhich edge the drawer slides in from (Left, Right, Top, Bottom)
CanLightDismissbooltrueWhether clicking the overlay background closes the drawer
IsModalboolfalseWhether the drawer blocks interaction with the rest of the UI
PanelWidthdoubleWidth of the drawer panel (for Left/Right positions)
PanelHeightdoubleHeight of the drawer panel (for Top/Bottom positions)
FooterContentobject?Optional footer content (e.g. action buttons) shown at the bottom
OpenAnimationAnimation?Slide-in animation applied to the drawer panel
CloseAnimationAnimation?Slide-out animation applied to the drawer panel
ShowOverlayAnimationAnimation?Fade-in animation for the overlay background
HideOverlayAnimationAnimation?Fade-out animation for the overlay background

Events

EventDescription
OpenedRaised when the drawer has fully opened
ClosedRaised when the drawer has fully closed

Methods

MethodDescription
ShowAsync(TopLevel)Shows the drawer on the specified TopLevel
ShowAsync<T>(TopLevel)Shows the drawer and returns a typed result when it closes
CloseAsync(object? result)Closes the drawer, optionally passing a result value

Positions

Control which edge the drawer slides from:

<!-- Right side (default) -->
<PleasantDrawer Position="Right" PanelWidth="400" />

<!-- Left side -->
<PleasantDrawer Position="Left" PanelWidth="400" />

<!-- Top edge -->
<PleasantDrawer Position="Top" PanelHeight="300" />

<!-- Bottom edge -->
<PleasantDrawer Position="Bottom" PanelHeight="300" />

Light dismiss

By default, clicking the overlay (outside the drawer) closes it. Disable this behavior:

<PleasantDrawer CanLightDismiss="False" />

Make the drawer modal to block interaction with the rest of the UI:

<PleasantDrawer IsModal="True" />

Add action buttons or other content at the bottom of the drawer:

<PleasantDrawer Title="Confirm">
    <TextBlock Text="Are you sure?" />
    
    <PleasantDrawer.FooterContent>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="8">
            <Button Content="Cancel" />
            <Button Content="Confirm" Theme="{DynamicResource AccentButtonTheme}" />
        </StackPanel>
    </PleasantDrawer.FooterContent>
</PleasantDrawer>

Returning a result

Show the drawer and wait for a result:

var result = await drawer.ShowAsync<string>(window);
if (result == "confirmed")
{
    // User confirmed
}

Close with a result:

await drawer.CloseAsync("confirmed");

Custom animations

Provide custom open/close animations:

<PleasantDrawer>
    <PleasantDrawer.OpenAnimation>
        <Animation Duration="0:0:0.3">
            <KeyFrame Cue="0.0">
                <Setter Property="TranslateTransform.X" Value="400" />
            </KeyFrame>
            <KeyFrame Cue="1.0">
                <Setter Property="TranslateTransform.X" Value="0" />
            </KeyFrame>
        </Animation>
    </PleasantDrawer.OpenAnimation>
</PleasantDrawer>

Events

Handle open/close events:

drawer.Opened += (sender, e) => { /* Drawer opened */ };
drawer.Closed += (sender, e) => { /* Drawer closed */ };