Lumeo

Overlay Service

A programmatic service for opening dialogs, sheets, drawers, and alert dialogs imperatively from code.

Installation

dotnet add package Lumeo

One-time app setup (AddLumeo(), CSS & JS) is covered in the installation guide.

Open a dialog containing a dynamic component and await its result.

Open a sheet panel from any side with a dynamic component.

Open a bottom drawer with a dynamic component.

Show a confirmation dialog and await the user's choice.

API Reference

OverlayService

Method Signature Description
ShowDialogAsync ShowDialogAsync<TComponent>(title?, parameters?, options?) Opens a Dialog containing the given component. Returns a Task<OverlayResult>.
ShowSheetAsync ShowSheetAsync<TComponent>(title?, side, size, parameters?, options?) Opens a Sheet panel. Side defaults to Right. Returns a Task<OverlayResult>.
ShowDrawerAsync ShowDrawerAsync<TComponent>(title?, parameters?, options?) Opens a Drawer from the bottom. Returns a Task<OverlayResult>.
ShowAlertDialogAsync ShowAlertDialogAsync(alertOptions) Shows a confirmation alert dialog. Returns a Task<OverlayResult>.
Close Close(overlayId, result?) Closes an overlay and resolves its task with the given result data.
Cancel Cancel(overlayId) Cancels an overlay, resolving its task with a cancelled result.

OverlayResult

Member Type Description
Cancelled bool True when the user dismissed the overlay without confirming.
Data object? The result value passed to Close().
GetData<T>() T? Casts and returns the result data as T.

OverlayReference

Member Type Description
Id string Unique identifier for this overlay instance.
Parameters OverlayParameters? The parameters passed when the overlay was opened.
Close(result?) void Closes the overlay and resolves with optional result data.
Cancel() void Cancels the overlay, setting Cancelled = true on the result.

OverlayParameters

Method Signature Description
Add Add(name, value) → OverlayParameters Adds a named parameter. Returns itself for chaining.
Get<T> Get<T>(name) → T? Retrieves a parameter by name cast to type T.
ToDictionary ToDictionary() → Dictionary<string, object> Returns all parameters as a dictionary for DynamicComponent use.

OverlayOptions

Property Type Default Description
Class string? null Additional CSS class for the overlay container.
PreventClose bool false When true, the close button and backdrop click are disabled.
SheetSide SheetSide Right Which side the sheet slides in from.
Size OverlaySize Default Dialog & Sheet (3.6.0). Unified size knob. For a Dialog it maps to a max-w-* preset (Smmax-w-sm, Defaultmax-w-lg, Lgmax-w-2xl, Xlmax-w-4xl, Full→near-viewport) — so you can enlarge a service Dialog without a Class override. For a Sheet it controls width on Left/Right or height on Top/Bottom; Full on Bottom + SwipeToClose=true gives the mobile-fullscreen sheet.
SheetSize deprecated SheetSize Default Legacy Sheet-only alias for Size (1:1 mapping). Kept for source compatibility — prefer Size in new code.
SwipeToClose bool false Sheet-only (2.1.1). Pipes the SwipeToClose flag through to the rendered SheetContent so programmatically-opened sheets can be dismissed by swiping in the direction matching SheetSide. Default false to keep existing programmatic-open behaviour. Drawers already swipe-close by default.
MobileBreakpoint int? 768 Sheet-only (2.1.3). Viewport width threshold (CSS px) below which the Mobile* overrides activate. Default 768 = Tailwind md. Set to null to disable responsive switching entirely.
MobileSheetSide SheetSide? null Sheet-only (2.1.3). Side override used when the viewport is below MobileBreakpoint. Typical pattern: Lumeo.Side.Right on desktop, Lumeo.Side.Bottom on mobile. null keeps SheetSide at every size.
MobileSize OverlaySize? null Dialog & Sheet (3.6.0). Size override used below MobileBreakpoint. Pair with MobileSheetSide=Bottom + MobileSize=Full for the mobile-fullscreen bottom-sheet pattern. null keeps Size at every viewport.
MobileSheetSize deprecated SheetSize? null Legacy alias for MobileSize (1:1 mapping, null round-trips). Prefer MobileSize.
MobileSwipeToClose bool? null Sheet-only (2.1.3). SwipeToClose override below MobileBreakpoint. Typical: false on desktop side panel, true on mobile bottom sheet so the pull-down dismiss is available.

Sizing overlays (3.6.0)

OverlayOptions.Size is a single, unified knob that sizes both Dialogs and Sheets — no Class override needed. To make a service-opened Dialog larger, just pass a Size:

// A wide dialog — Lg → max-w-2xl, Xl → max-w-4xl, Full → near-viewport
await Overlay.ShowDialogAsync<MyForm>(
    title: "Edit user",
    options: new OverlayOptions { Size = OverlaySize.Lg });

The same Size drives Sheets (width on Left/Right, height on Top/Bottom). The old Sheet-only SheetSize property still works as a 1:1 alias but is deprecated — prefer Size.

Responsive sheets (2.1.3)

A single ShowSheetAsync call can switch between a side panel on desktop and a fullscreen bottom sheet on mobile, including SwipeToClose behaviour. OverlayProvider subscribes to IResponsiveService.ViewportChanged and re-renders the effective Side/Size/SwipeToClose when the viewport crosses MobileBreakpoint — works mid-flight (user rotates a tablet, sheet flips correctly).

// In any component:
@inject OverlayService Overlay

private async Task ShowResponsive()
{
    await Overlay.ShowSheetAsync<MyForm>(
        title: "Edit user",
        side: Lumeo.Side.Right,                      // desktop default
        size: SheetSize.Default,
        options: new OverlayOptions
        {
            // Below 768px, switch to a fullscreen bottom sheet with swipe-down dismiss
            MobileSheetSide    = Lumeo.Side.Bottom,
            MobileSize         = OverlaySize.Full,   // unified Size — drives Dialog & Sheet
            MobileSwipeToClose = true,
            // MobileBreakpoint defaults to 768 (md) — set to null to disable
        });
}

If you need finer-grained mobile detection (e.g. to change the rendered content, not just overlay sizing), inject IResponsiveService directly. See the IResponsiveService API below.

IResponsiveService (2.1.3)

Reactive viewport/breakpoint service. One JS resize listener per circuit (debounced 100ms), Tailwind-v4-aligned Breakpoint enum, plus IsMobile/IsTablet/IsDesktop convenience flags and a ViewportChanged event for components that need to react to the live viewport.

Member Type Description
Width double Current viewport width in CSS pixels (window.innerWidth). 0 until the first interop sync — call EnsureInitialisedAsync from OnAfterRenderAsync(firstRender: true) or subscribe to ViewportChanged.
Height double Current viewport height in CSS pixels.
Current Breakpoint Tailwind-aligned breakpoint. Values: Xs (<640), Sm ([640,768)), Md ([768,1024)), Lg ([1024,1280)), Xl ([1280,1536)), Xxl (>=1536).
IsMobile bool True when Current is Xs or Sm. Same boundary the default MobileBreakpoint=768 on OverlayOptions checks.
IsTablet bool True when Current is Md.
IsDesktop bool True when Current is Lg, Xl, or Xxl.
ViewportChanged event Action<ViewportInfo> Fires on every (debounced) resize. ViewportInfo carries Width, Height, Current. Unsubscribe in DisposeAsync.
EnsureInitialisedAsync() ValueTask Lazily attaches the JS resize listener + pulls the initial viewport. Call eagerly from OnAfterRenderAsync(firstRender: true) to avoid the first-render zero-value read.
@inject IResponsiveService Responsive
@implements IAsyncDisposable

@if (Responsive.IsMobile)
{
    <BottomNav />
}
else
{
    <Sidebar />
}

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await Responsive.EnsureInitialisedAsync();
            Responsive.ViewportChanged += OnVp;
        }
    }

    private void OnVp(ViewportInfo vp) => InvokeAsync(StateHasChanged);

    public ValueTask DisposeAsync()
    {
        Responsive.ViewportChanged -= OnVp;
        return ValueTask.CompletedTask;
    }
}

AlertDialogOptions

Property Type Default Description
Title string "Are you sure?" The dialog heading text.
Description string? null Optional body text below the title.
ConfirmText string "Continue" Label for the confirm button.
CancelText string "Cancel" Label for the cancel button.
IsDestructive bool false When true, the confirm button uses destructive styling.