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 -> /* ... */ }
}
} 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()