mediaQuery

Function
Common
@ExperimentalMediaQueryApi
inline fun CompositionLocalAccessorScope.mediaQuery(query: UiMediaScope.() -> Boolean): Boolean

Evaluates a boolean query against the current UiMediaScope from a CompositionLocalAccessorScope.

If called within a snapshot-aware context, the specific property reads within the query will be tracked, and the scope will be invalidated when any of those properties change.

Parameters

query A lambda expression with UiMediaScope as its receiver, representing the condition to check.

Returns

The immediate boolean result of the query.
Common
@ExperimentalMediaQueryApi
inline fun CompositionLocalConsumerModifierNode.mediaQuery(
    query: UiMediaScope.() -> Boolean
): Boolean

Evaluates a boolean query against the current UiMediaScope from a Modifier.Node.

This function is designed to be used within a Modifier.Node that implements CompositionLocalConsumerModifierNode.

If called within a snapshot-aware context like LayoutModifierNode.measure or DrawModifierNode.draw callbacks, the reads within the query will be tracked, and the scope will be invalidated when the properties change.

Parameters

query A lambda expression with UiMediaScope as its receiver, representing the condition to check.

Returns

The immediate boolean result of the query.

Code Examples

AdaptiveStylesSample

@OptIn(ExperimentalFoundationStyleApi::class)
@Composable
fun AdaptiveStylesSample() {
    // Create a styleable clickable box
    @Composable
    fun ClickableStyleableBox(
        onClick: () -> Unit,
        modifier: Modifier = Modifier,
        style: Style = Style,
    ) {
        val interactionSource = remember { MutableInteractionSource() }
        val styleState = remember { MutableStyleState(interactionSource) }
        Box(
            modifier =
                modifier
                    .clickable(interactionSource = interactionSource, onClick = onClick)
                    .styleable(styleState, style)
        )
    }
    ClickableStyleableBox(
        onClick = {},
        style = {
            background(Color.Green)
            // Dynamic size based on window Size
            if (mediaQuery { windowWidth > 600.dp && windowHeight > 400.dp }) {
                size(200.dp)
            } else {
                size(150.dp)
            }
            // Hover state for fine pointer input
            if (mediaQuery { pointerPrecision == PointerPrecision.Fine }) {
                hovered { background(Color.Yellow) }
            }
            pressed { background(Color.Red) }
        },
    )
}

MediaQueryModifierNodeSample

@Composable
fun MediaQueryModifierNodeSample() {
    // Example of a custom padding modifier that uses [mediaQuery] within a [Modifier.Node].
    class AdaptivePaddingNode :
        Modifier.Node(), LayoutModifierNode, CompositionLocalConsumerModifierNode {
        override fun MeasureScope.measure(
            measurable: Measurable,
            constraints: Constraints,
        ): MeasureResult {
            val isLargeScreen = mediaQuery { windowWidth > 600.dp && windowHeight > 400.dp }
            // Adjust padding or size based on the query result
            val extraPadding = if (isLargeScreen) 80.dp.roundToPx() else 16.dp.roundToPx()
            val totalPaddingOnAxis = 2 * extraPadding
            // Measure the content with added padding
            val placeable =
                measurable.measure(constraints.offset(-totalPaddingOnAxis, -totalPaddingOnAxis))
            val width = constraints.constrainWidth(placeable.width + totalPaddingOnAxis)
            val height = constraints.constrainHeight(placeable.height + totalPaddingOnAxis)
            return layout(width, height) { placeable.place(extraPadding, extraPadding) }
        }
    }
    class AdaptivePaddingElement : ModifierNodeElement<AdaptivePaddingNode>() {
        override fun create() = AdaptivePaddingNode()
        override fun update(node: AdaptivePaddingNode) {}
        override fun equals(other: Any?) = other === this
        override fun hashCode() = 0
    }
    @Stable fun Modifier.adaptivePadding(): Modifier = this.then(AdaptivePaddingElement())
    Box(Modifier.adaptivePadding().background(Color.Blue).size(400.dp))
}