Liquid Glass Widgets

repository·main·Indexed 18 days ago

https://github.com/sdegenaar/liquid_glass_widgets

A Flutter library that implements the iOS 26 Liquid Glass aesthetic, featuring shader-based blur, physics-driven jelly animations, and dynamic lighting. It provides a comprehensive suite of glass-styled components including GlassScaffold, GlassAppBar, GlassButton, and GlassTextField. The package supports adaptive rendering across iOS, Android (via Impeller), Web (via CanvasKit), and desktop platforms (via Skia), with a centralized theme system for managing blur, thickness, and rendering quality.

Tokens
37.8K
Snippets
100
Records
161
Agent score
55%

What's inside liquid_glass_widgets

  1. Overview of available Liquid Glass widgets

    main

    The package provides a variety of widgets categorized by their function:

    Containers

    • GlassContainer: The foundational glass container.
    • GlassCard: Card-style containers with default 16px padding.
    • GlassPanel: Large surface area containers with 24px padding.

    Interactive

    • GlassButton: Touch-responsive buttons with glow effects and stretch animations.
    • GlassSegmentedControl: Segmented control with jelly physics, drag support, and an animated glass indicator.
    • GlassSwitch: Toggle switches with iOS-style spring animations.

    Surfaces

    • GlassAppBar: Navigation bar with leading/trailing actions and centered title support.
    • GlassBottomBar: Bottom navigation featuring a draggable indicator with jelly physics and rubber band resistance.

    Input

    • GlassTextField: Text input supporting prefix/suffix icons, multiline mode, and custom shapes.
  2. Key Features of Liquid Glass Widgets

    main

    The liquid_glass_widgets library provides several core capabilities demonstrated in the showcase app:

    • Quality inheritance patterns: Managed via AdaptiveLiquidGlassLayer to ensure visual consistency.
    • Centralized theme system: Allows for consistent glass styling across an entire application.
    • Real-world UI components: Ready-to-use patterns for navigation, forms, and booking flows.
  3. Design Philosophy: Glass vs Content

    main

    Following the iOS 26 design language, glass should be reserved for the navigation and control layer (the floating UI), while content areas should remain opaque.

    ✅ Use glass for❌ Keep opaque
    Navigation bars, tab bars, toolbarsList cells, table rows
    Floating action buttonsFull-screen backgrounds
    Sheets, popovers, menusScrollable content cards
    Toggles, sliders, segmented controlsArticle tiles, media players

    Typical screen composition:

    • GlassAppBar (glass) at the top.
    • Opaque content area (standard Flutter widgets like ListView) in the middle.
    • GlassBottomBar (glass) at the bottom.
  4. Use the hasHandedOff latch for seamless closing

    main

    When closing a menu, the spring overshoots past 0.0 (the rubber-band bounce). To prevent the real trigger from appearing too early and looking jittery, use the hasHandedOff property.

    The Pattern:

    1. While _morph.isShowing is true, show a 'ghost' version of the trigger (Blob A) using state.anchorScale.
    2. The hasHandedOff property becomes true exactly when the spring first crosses 0.0 during a close animation.
    3. Use !_morph.hasHandedOff to determine when to swap the ghost trigger for the real, interactive trigger. This ensures the real trigger only appears once the animation has settled at value = 0.
  5. Use the `GlassModalSheet` system

    main

    The GlassModalSheet is a comprehensive modal implementation that supports three interactive states: peek, half, and full. It uses spring physics for transitions and features asymmetric geometry that morphs from a rounded floating pill to a sharp-bottomed full-screen container using LiquidVerticalRoundedSuperellipse.

    Key features include:

    • Device-Aware Adaptive Radius: Automatically matches glass curvature to device hardware (e.g., Dynamic Island vs. Notch).
    • Pulse System: Coordinated saturation and lighting pulses during high-velocity interactions.
    • suppressInteractionOnChildren: Prevents 'double-reacting' artifacts where both a child button and the parent sheet scale simultaneously. Child buttons can suppress the parent's scaling and glow effects when tapped.
  6. Override interaction glow colors in `GlassBottomBar`

    main

    When using GlassBottomBar or GlassSearchableBottomBar, the interactionGlowColor (the highlight color during a press interaction) follows this resolution order:

    1. Explicit interactionGlowColor parameter on the widget.
    2. GlassThemeData.glowColors(context).primary from the ancestor tree.
    3. Internal fallback.

    This allows you to globally theme the interaction highlights for all bottom bars by configuring your GlassThemeData.

  7. How widgets and layers work: Grouped vs Standalone modes

    main

    The liquid_glass_widgets package uses a layering system to manage glass effects. You can implement widgets using two patterns:

    For better performance, wrap multiple glass widgets in a single AdaptiveLiquidGlassLayer. This allows all child widgets to share the same layer and settings.

    Standalone Mode

    If a widget needs to exist independently, you can set useOwnLayer: true. In this mode, the widget creates and manages its own dedicated layer.

    Note: Use Grouped Mode whenever possible to optimize rendering performance.

    // Grouped Mode
    AdaptiveLiquidGlassLayer(
      settings: LiquidGlassSettings(...),
      child: Column(
        children: [
          GlassButton(...),
          GlassCard(...),
        ],
      ),
    )
    
    // Standalone Mode
    GlassButton(
      useOwnLayer: true,
      settings: LiquidGlassSettings(...),
      ...
    )
  8. Manage interaction stability with suppressInteractionOnChildren

    main

    The suppressInteractionOnChildren parameter controls how the sheet reacts to touches on its internal widgets (like buttons or cards):

    • false (Default): Touching a child triggers the sheet's "squeeze" scale effect. This creates a fluid, "jiggly" feel.
    • true: Touching a child only triggers the child's own effect. The sheet remains stable. Recommended for complex forms or Map-style UIs.
  9. Understand the Liquid Glass Widgets Semver Commitment

    main

    The project follows Semantic Versioning (Semver) to communicate the impact of updates:

    • Patch (1.0.x): Contains only bug fixes.
    • Minor (1.x.0): Includes new widgets, new parameters, and other non-breaking additions.
    • Major (2.0.0): Includes breaking changes such as widget removal, parameter renaming, or behavioral changes.
  10. Platform support and rendering engines

    main

    The package is compatible with all Flutter platforms and uses adaptive rendering based on the available engine:

    • iOS & Android: Uses Impeller for a full shader pipeline including texture capture and chromatic aberration.
    • Web: Uses CanvasKit with per-widget shader instances.
    • macOS, Windows, Linux: Uses Skia with high-performance lightweight fragment shaders.

    Platform detection is automatic; no manual configuration is required to switch between these rendering modes.

  11. Glass Composition Rule: Glass is a Platter, Not a Wrapper

    main

    Widgets like GlassCard, GlassContainer, and GlassGroupedSection are base surfaces meant to sit beneath content. They are not intended to be used as styling wrappers for other interactive glass controls.

    Do not nest interactive glass widgets inside glass containers.

    ✅ Place inside GlassCard / GlassContainer❌ Do not place inside GlassCard / GlassContainer
    Text, Icon, ListTile, CupertinoListTileGlassSegmentedControl, GlassSlider, GlassSwitch
    GlassListTile, GlassDividerGlassButton, GlassChip, GlassIconButton
    Standard Flutter form widgetsAny other refractive glass widget

    Reasoning: Nesting glass widgets causes visual degradation because GlassContainer sets avoidsRefraction: true on its children. Additionally, interactive glass controls (like GlassSlider) provide their own surface appearance via backgroundColor and indicatorColor, making an outer container redundant.

  12. Compare Impeller vs Skia rendering capabilities

    main

    The visual fidelity of liquid_glass_widgets depends heavily on whether the Flutter engine is using Impeller (the modern rendering engine) or Skia (the legacy engine).

    Impeller (iOS, Android, macOS)

    Impeller supports the full suite of high-end glass effects. The following features are only available with GlassQuality.premium on Impeller:

    • True refraction (refract())
    • Specular highlights
    • Chromatic aberration
    • SDF metaball blend

    Impeller also supports GlassQuality.standard for lightweight shader blur.

    Skia / CanvasKit / Windows / Linux / Web

    Skia-based environments are more limited. They do not support true refraction, specular highlights, chromatic aberration, or SDF metaball blending.

    Supported on Skia:

    • GlassQuality.standard (Lightweight shader blur)
    • GlassQuality.minimal (BackdropFilter fallback)