Skip to content

WindowDialog

WindowDialog is a window-level dialog component. It renders using platform Dialog and does not require Scaffold or COUIPopupHost. It supports large-screen optimized animations, system back gesture dismissal, and a composition local to request dismiss from inside content.

TIP

This component is independent of Scaffold and can be used in any composable scope.

Import

kotlin
import io.github.suqi8.coui.kmp.window.WindowDialog
import io.github.suqi8.coui.kmp.theme.LocalDismissState

Basic Usage

kotlin
var showDialog by remember { mutableStateOf(false) }

TextButton(
    text = "Open",
    onClick = { showDialog = true }
)

WindowDialog(
    title = "WindowDialog",
    summary = "A basic window-level dialog",
    show = showDialog,
    onDismissRequest = { showDialog = false }
) {
    val dismiss = LocalDismissState.current
    TextButton(
        text = "Confirm",
        onClick = { dismiss?.invoke() },
        modifier = Modifier.fillMaxWidth()
    )
}

Properties

WindowDialog Properties

Property NameTypeDescriptionDefault ValueRequired
showBooleanWhether to show the dialog-Yes
modifierModifierRoot content modifierModifierNo
titleString?Dialog titlenullNo
titleColorColorTitle colorDialogDefaults.titleColor()No
summaryString?Dialog summarynullNo
summaryColorColorSummary colorDialogDefaults.summaryColor()No
backgroundColorColorDialog background colorDialogDefaults.backgroundColor()No
enableWindowDimBooleanWhether to enable dimming layertrueNo
onDismissRequest(() -> Unit)?Called when the user requests dismissal (outside tap or back)nullNo
onDismissFinished(() -> Unit)?Invoked after the hide animation completes; not invoked if the hide is cancelled mid-flight (e.g., show toggled back to true)nullNo
outsideMarginDpSizeOuter margin (window edges)DialogDefaults.outsideMarginNo
insideMarginDpSizeMargin for the built-in title/summary texts (width = horizontal padding, height = padding above the title); the content slot is unpaddedDialogDefaults.insideMarginNo
defaultWindowInsetsPaddingBooleanApply default insets padding (IME, nav, caption)trueNo
maxWidthDpMaximum dialog content widthDialogDefaults.MaxWidthNo
largeScreenBoolean?Override for the large-screen presentation (centered scale/fade instead of bottom slide-in); if null, detected from the window sizenullNo
cornerRadiusDp?Corner radius override; if null, DialogDefaults.CornerRadius for the centered presentation, or derived from the screen corner radius (clamped to 32dp..48dp) when bottom-attachednullNo
content@Composable () -> UnitDialog content-Yes

DialogDefaults

Properties

NameTypeDescription
CornerRadiusDpDialog panel corner radius (19.dp)
MaxWidthDpMaximum dialog content width (392.dp)
outsideMarginDpSizeDefault outer margin for dialog (16, 24)
insideMarginDpSizeDefault margin for the built-in title/summary texts (24, 24); the content slot is unpadded
ButtonBarMinHeightDpMin height of a horizontal dialog button bar (58.dp)
ButtonBarInsideMarginPaddingValuesPaddings of a button in a horizontal bar (24dp horizontal, 12dp top, 22dp bottom); the panel bottom inset is carried by the buttons
ButtonBarDividerThicknessDpThickness of the divider between horizontal bar buttons (1.dp)
ButtonBarDividerInsetTopDpTop inset of the divider between horizontal bar buttons (17.dp)
ButtonBarDividerInsetBottomDpBottom inset of the divider between horizontal bar buttons (21.dp)

Functions

NameReturn TypeDescription
titleColor()ColorGet default title color
summaryColor()ColorGet default summary color
backgroundColor()ColorGet default dialog background color

LocalDismissState

Provides a (() -> Unit)? function to close the current popup from within the content. This is a unified dismiss state provided by all overlay components.

kotlin
val dismiss = LocalDismissState.current
TextButton(
    text = "Close",
    onClick = { dismiss?.invoke() }
)

Advanced Usage

Presentation Overrides

By default the dialog is bottom-attached on compact windows and centered on large windows (>= 840dp x 480dp). Use largeScreen, cornerRadius and maxWidth to override the presentation:

kotlin
var showDialog by remember { mutableStateOf(false) }

WindowDialog(
    show = showDialog,
    title = "Custom Presentation",
    summary = "Forced centered presentation with custom shape",
    largeScreen = true,   // always use the centered scale/fade presentation
    cornerRadius = 24.dp, // override the panel corner radius
    maxWidth = 320.dp,    // narrower content width cap
    onDismissRequest = { showDialog = false }
) {
    val dismiss = LocalDismissState.current
    TextButton(
        text = "OK",
        onClick = { dismiss?.invoke() },
        modifier = Modifier.fillMaxWidth()
    )
}

Changelog

Released under the Apache-2.0 License