askill
haze-usage

haze-usageSafety 100Repository

Use Haze features for blur effects in Compose Multiplatform. Covers hazeSource, hazeEffect, blurEffect, styling, progressive blurs, masking, overlapping effects, and common UI patterns.

2 stars
1.2k downloads
Updated 2/5/2026

Package Files

Loading files...
SKILL.md

Using Haze

Haze provides blur (glassmorphism) effects for Compose Multiplatform using two main modifiers: hazeSource and hazeEffect.

Core Concepts

HazeState

A state holder that manages blur rendering. Share between source and effect:

val hazeState = rememberHazeState()

hazeSource vs hazeEffect

  • hazeSource: Marks content that can be blurred by effects elsewhere
  • hazeEffect: Applies the blur effect, drawing blurred content from marked sources

Basic Background Blur

The most common pattern - blur content behind a UI element:

val hazeState = rememberHazeState()

Box {
    // Content to blur (e.g., scrolling list)
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .hazeSource(state = hazeState)
    ) {
        items(100) { Text("Item $it") }
    }

    // Blurred app bar
    TopAppBar(
        colors = TopAppBarDefaults.topAppBarColors(Color.Transparent),
        modifier = Modifier
            .hazeEffect(state = hazeState) {
                blurEffect {
                    style = HazeMaterials.thin()
                }
            }
    )
}

Foreground Blur

Blur content within a composable itself (no HazeState needed):

Box(
    modifier = Modifier
        .hazeEffect {
            blurEffect {
                blurRadius = 20.dp
            }
        }
) {
    // This content will be blurred
    Image(painter = painterResource(id = R.drawable.photo), ...)
}

Blur Styling

Using Pre-built Materials

// Material Design styles
blurEffect { style = HazeMaterials.thin() }
blurEffect { style = HazeMaterials.regular() }
blurEffect { style = HazeMaterials.thick() }

// iOS/Apple styles
blurEffect { style = CupertinoMaterials.thin() }
blurEffect { style = CupertinoMaterials.regular() }

// Windows/Fluent styles
blurEffect { style = FluentMaterials.thin() }

Custom Styling

Set properties directly in blurEffect {}:

blurEffect {
    blurRadius = 25.dp           // Blur strength
    tints = listOf(              // Color overlays
        HazeTint(Color.Black.copy(alpha = 0.2f)),
        HazeTint(Color.Blue.copy(alpha = 0.1f))
    )
    noiseFactor = 0.15f          // Texture noise (0f to disable)
}

Or create a reusable HazeStyle:

val customStyle = HazeStyle(
    blurRadius = 15.dp,
    tints = listOf(HazeTint(Color.Black.copy(alpha = 0.2f))),
    noiseFactor = 0.1f
)

blurEffect { style = customStyle }

Styling Resolution Order

  1. Value set directly in blurEffect {}
  2. Value from style property
  3. Value from LocalHazeStyle composition local
  4. Default value

Progressive (Gradient) Blurs

Vary blur intensity across a dimension:

blurEffect {
    progressive = HazeProgressive.verticalGradient(
        startIntensity = 1f,  // Full blur at top
        endIntensity = 0f     // No blur at bottom
    )
}

Progressive Types

// Vertical gradient
progressive = HazeProgressive.verticalGradient(startIntensity = 1f, endIntensity = 0f)

// Horizontal gradient
progressive = HazeProgressive.horizontalGradient(startIntensity = 1f, endIntensity = 0f)

// Radial gradient
progressive = HazeProgressive.RadialGradient()

// Custom brush
progressive = HazeProgressive.Brush(brush = Brush.verticalGradient(...))

Masking

Apply any Brush as an opacity mask (faster than progressive blur):

blurEffect {
    mask = Brush.verticalGradient(
        colors = listOf(Color.Black, Color.Transparent)
    )
}

Dynamic Styling

Update blur based on scroll state:

val listState = rememberLazyListState()

TopAppBar(
    modifier = Modifier.hazeEffect(state = hazeState) {
        blurEffect {
            alpha = if (listState.firstVisibleItemIndex == 0) {
                val firstItem = listState.layoutInfo.visibleItemsInfo.firstOrNull()
                firstItem?.let { (it.offset / it.size.height.toFloat()).absoluteValue } ?: 1f
            } else {
                1f
            }
        }
    }
)

Scaffold Pattern

Blur both top and bottom bars:

val hazeState = rememberHazeState()

Scaffold(
    topBar = {
        TopAppBar(
            colors = TopAppBarDefaults.topAppBarColors(Color.Transparent),
            modifier = Modifier.hazeEffect(state = hazeState) {
                blurEffect { style = HazeMaterials.thin() }
            }
        )
    },
    bottomBar = {
        NavigationBar(
            containerColor = Color.Transparent,
            modifier = Modifier.hazeEffect(state = hazeState) {
                blurEffect { style = HazeMaterials.thin() }
            }
        )
    }
) { padding ->
    LazyColumn(
        contentPadding = padding,
        modifier = Modifier.hazeSource(state = hazeState)
    ) {
        // content
    }
}

Sticky Headers

For LazyColumn sticky headers, use hazeSource on items (not the column):

val hazeState = rememberHazeState()

LazyColumn {
    stickyHeader {
        Header(
            modifier = Modifier.hazeEffect(state = hazeState) {
                blurEffect { style = HazeMaterials.thin() }
            }
        )
    }

    items(list) { item ->
        ItemRow(
            modifier = Modifier.hazeSource(hazeState)
        )
    }
}

Overlapping Effects

Multiple cards that both draw and serve as blur sources:

val hazeState = rememberHazeState()

Box {
    Background(modifier = Modifier.hazeSource(hazeState, zIndex = 0f))

    // Rear card - draws background
    Card(
        modifier = Modifier
            .hazeSource(hazeState, zIndex = 1f)
            .hazeEffect(hazeState) { blurEffect { } }
    )

    // Middle card - draws background + rear card
    Card(
        modifier = Modifier
            .hazeSource(hazeState, zIndex = 2f)
            .hazeEffect(hazeState) { blurEffect { } }
    )

    // Front card - draws all previous layers
    Card(
        modifier = Modifier
            .hazeSource(hazeState, zIndex = 3f)
            .hazeEffect(hazeState) { blurEffect { } }
    )
}

Filtering Layers

Control which layers are included:

Modifier
    .hazeSource(hazeState, zIndex = 2f, key = "card-2")
    .hazeEffect(hazeState) {
        canDrawArea = { area -> area.key != "card-2" }  // Exclude self
        blurEffect { }
    }

Dialogs

Blur dialog backgrounds over content:

val hazeState = rememberHazeState()
var showDialog by remember { mutableStateOf(false) }

Box {
    LazyColumn(modifier = Modifier.hazeSource(state = hazeState)) { }

    if (showDialog) {
        Dialog(onDismissRequest = { showDialog = false }) {
            Surface(
                color = MaterialTheme.colorScheme.surface.copy(alpha = 0.2f),
                modifier = Modifier.hazeEffect(state = hazeState) {
                    blurEffect { style = HazeMaterials.regular() }
                }
            ) {
                // Dialog content
            }
        }
    }
}

Input Scale (Performance)

Render blur at lower resolution for better performance:

Modifier.hazeEffect(state = hazeState) {
    inputScale = HazeInputScale.Auto  // Platform defaults
    // or
    inputScale = HazeInputScale.Fixed(0.5f)  // 50% resolution

    blurEffect { }
}

Values:

  • HazeInputScale.None - No scaling (default, highest quality)
  • HazeInputScale.Auto - Automatic platform-optimized scaling
  • HazeInputScale.Fixed(0.66f) - Custom scale (0.0-1.0)

Deep Hierarchies

Use CompositionLocal to avoid passing HazeState through many levels:

val LocalHazeState = compositionLocalOf { HazeState() }

@Composable
fun App() {
    val hazeState = rememberHazeState()
    CompositionLocalProvider(LocalHazeState provides hazeState) {
        MainContent()
    }
}

@Composable
fun DeepChild() {
    Box(modifier = Modifier.hazeEffect(state = LocalHazeState.current) {
        blurEffect { }
    })
}

Enabling/Disabling Blur

Conditionally enable blur:

blurEffect {
    blurEnabled = isBlurSupported && userPrefersBlur
}

HazeEffectScope Properties

Common properties (outside blurEffect {}):

PropertyDescription
inputScalePerformance optimization for resolution
drawContentBehindDraw source content before effect (default: true)
canDrawAreaFilter which source layers to include
clipToAreasBoundsClip effect to area bounds

BlurVisualEffect Properties

Properties inside blurEffect {}:

PropertyDescription
blurRadiusBlur strength (default: 20.dp)
tintsList of color overlays
noiseFactorVisual texture (0-1, default: 0.15)
progressiveGradient blur
maskOpacity mask brush
stylePre-built HazeStyle
alphaOverall effect opacity
blurEnabledToggle blur on/off
backgroundColorBackground for tint calculation
fallbackTintTint when blur unavailable

References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

88/100Analyzed 2/19/2026

Comprehensive technical reference for the Haze blur library in Compose Multiplatform. Excellent coverage of core concepts (HazeState, hazeSource vs hazeEffect), extensive code examples for 10+ patterns including background blur, foreground blur, progressive blurs, masking, scaffold patterns, sticky headers, overlapping effects, dialogs, and performance optimization. Well-structured with clear sections, properly formatted code blocks, and reference tables. While path depth suggests potential internal storage, the content is generic and highly reusable for any developer using Haze."

100
90
88
92
90

Metadata

Licenseunknown
Version-
Updated2/5/2026
Publisherbenoberkfell

Tags

github