Overlays

Modal dialogs, toast notifications, popup menus, and context menus.

Kraft provides three overlay systems that share the same pattern: a manager you access from any component, a stage that renders the overlays, and handles for controlling individual overlays. All three are registered automatically when you call semanticUI() in your app setup.

val app = kraftApp {
    semanticUI()  // registers modals, toasts, and popups with SemanticUI styling
}

Each system is accessible from any component via a delegated property:

class MyComponent(ctx: Ctx<Props>) : Component<Props>(ctx) {
    override fun VDom.render() {
        // modals, toasts, and popups are available on every component
        modals.show { handle -> /* ... */ }
        toasts.info("Saved")
        popups.showContextMenu(event) { handle -> /* ... */ }
    }
}
Every framework ends up reinventing modals. We tried to keep the API small and get out of your way.

Modals

Show a modal by calling modals.show with a render function. You receive a Handle that lets you close the modal and register close callbacks:

modals.show { handle ->
    div {
        h2 { +"Confirm deletion" }
        p { +"This cannot be undone." }
        ui.red.button {
            onClick {
                performDelete()
                handle.close()
            }
            +"Delete"
        }
        ui.button {
            onClick { handle.close() }
            +"Cancel"
        }
    }
}.onClose {
    // called after the modal closes, regardless of how
}

Close all open modals at once:

modals.closeAll()

OkCancelModal

For the common confirm/cancel pattern, use the built-in OkCancelModal. It comes in three sizes:

modals.show { handle ->
    OkCancelModal.mini(
        handle = handle,
        header = { ui.header { +"Are you sure?" } },
        content = { +"This action cannot be undone." },
        okText = { +"Delete" },
        cancelText = { +"Cancel" },
    ) { result ->
        when (result) {
            OkCancelModal.Result.Ok -> performDelete()
            OkCancelModal.Result.Cancel -> { /* nothing */ }
        }
    }
}

// Also available:
// OkCancelModal.tiny(...)
// OkCancelModal.small(...)

Toasts

Toast notifications appear in the top-right corner and auto-dismiss after a configurable duration (default: 7 seconds). Three convenience methods cover the common types:

toasts.info("Changes saved")
toasts.warning("Session expires in 5 minutes")
toasts.error("Failed to save — check your connection")

Control the duration per toast, or pass null to keep it visible until clicked:

import kotlin.time.Duration.Companion.seconds

toasts.info("Quick note", duration = 3.seconds)
toasts.error("Read this carefully", duration = null)  // stays until clicked

Custom toast settings

Configure defaults when setting up the app:

val app = kraftApp {
    semanticUI {
        // this block configures the ToastsManager.Builder
        defaultDuration = 5.seconds
    }
}

Appending messages

For API responses that return typed Message objects, append them directly:

// Single message
toasts.append(Message.Type.info, "Item created")

// From a Messages collection (e.g. from an API response)
toasts.append(apiResponse.messages)

Popups & Context Menus

Context menus appear near the triggering element. Pass a UIEvent and the menu renders at the event position:

ui.button {
    onClick { evt ->
        popups.showContextMenu(evt, PopupsManager.Positioning.BottomLeft) { handle ->
            ui.vertical.menu {
                noui.item A {
                    onClick { handle.close() }
                    +"Edit"
                }
                noui.item A {
                    onClick { handle.close() }
                    +"Delete"
                }
            }
        }
    }
    +"Actions"
}

Positioning

Six positioning options control where the popup appears relative to the anchor:

Value Position
Positioning.TopLeft Above, left-aligned
Positioning.TopCenter Above, centered
Positioning.TopRight Above, right-aligned
Positioning.BottomLeft Below, left-aligned
Positioning.BottomCenter Below, centered
Positioning.BottomRight Below, right-aligned

Hover popups

For tooltips that appear on hover, use the showHoverPopup helpers. These attach to an element and manage show/hide automatically:

ui.blue.label {
    popups.showHoverPopup.topCenter(this) {
        +"This is a tooltip"
    }
    +"Hover me"
}

Close all open popups programmatically:

popups.closeAll()

See it in action

Modals

Popups & Context Menus

Toasts