liquid_glass_widgets 0.7.16
liquid_glass_widgets: ^0.7.16 copied to clipboard
A Flutter UI kit implementing the iOS 26 Liquid Glass design language. Features shader-based glassmorphism, physics-driven jelly animations, and dynamic lighting.
0.7.16 #
Bug Fixes #
- FIX:
GlassSearchableBottomBar— memory leak whencontrollerwas swapped at runtime. The old controller's listener was never removed before attaching to the new controller. Now correctly removed indidUpdateWidget. - FIX:
DraggableIndicatorPhysics— velocity NaN/Infinity guard. A zero-size render box (e.g. during widget tree warm-up) could produceInfinityorNaNforvelocityX, which propagated into the spring physics and caused erratic snapping. Now clamped to 0 when the box has no size.
Refactor (zero breaking changes) #
- REFACTOR: Extracted
GlassSearchBarConfigfromglass_searchable_bottom_bar.dartinto a dedicated filelib/widgets/surfaces/shared/glass_search_bar_config.dart. Resolves a circular import between the public widget and its internal sub-widgets.GlassSearchBarConfigis re-exported from the barrel file — no consumer-facing API change. - REFACTOR: Extracted
_TabIndicator/_TabIndicatorStatefromglass_bottom_bar.dartintoshared/bottom_bar_internal.dartasTabIndicator/TabIndicatorState(package-internal, not exported). Follows the same pattern used forGlassSearchableBottomBar.glass_bottom_bar.dartreduced from 1,406 → ~895 lines. - REFACTOR: Extracted
_TabBarContent,_TabBarContentState, and_TabItemfromglass_tab_bar.dartintoshared/tab_bar_internal.dart.glass_tab_bar.dartreduced from 728 → ~310 lines. Architecture is now consistent across all bar-family widgets.
Test Coverage #
- TEST: Reached 91.85% effective coverage (up from 89.6% in 0.7.15 — excluding GPU/shader renderer paths that are physically untestable in a headless VM). Total: 1,031 tests, all passing, 0 analyzer warnings.
- TEST: New
test/widgets/surfaces/glass_bottom_bar_drag_test.dart— 7 regression tests covering_onDragEndphysics snapping,_onDragCancel(mid-drag and no-drag), slow drags, fast flings, and full-bar sweeps. These paths are the highest-risk regressions in navigation UX.
0.7.15 #
Bug Fixes #
- FIX:
lib/theme/glass_theme_settings.dartwas accidentally omitted from version control in 0.7.14. All consumers ofGlassThemeSettingsreceived a compile error (type 'GlassThemeSettings' is not a subtype). This release commits the missing file. No API change —GlassThemeSettingswas already exported fromliquid_glass_widgets.dart. - FIX:
GlassPerformanceMonitor._emitWarning— division-by-zero crash whenrasterBudgetwas sub-millisecond (< 1 ms). Protected with amax(1, ...)guard.
Refactor (zero breaking changes) #
- REFACTOR: Consolidated 18 quality-resolution chains (
widgetQuality ?? inherited?.quality ?? themeData.qualityFor(context) ?? GlassQuality.standard) into a single canonical helper:GlassThemeHelpers.resolveQuality(context, widgetQuality: ..., fallback: ...). Surface widgets (GlassAppBar,GlassToolbar,GlassBottomBar,GlassSearchableBottomBar,GlassSideBar) passfallback: GlassQuality.premiumto preserve their documented defaults. All other widgets default toGlassQuality.standard. - REFACTOR: Extracted
_buildIconShadowsfromBottomBarTabItemto a@visibleForTestingtop-level functionbuildIconShadows(...)inbottom_bar_internal.dart. No behaviour change — enables isolated unit testing of the shadow-outline geometry.
Test Coverage #
- TEST: Reached 90%+ effective test coverage (90.15% — excluding
src/rendererGPU/shader layer where headless simulation is impossible). Total: 949 tests, all passing. - TEST: New
test/theme/glass_theme_helpers_test.dart— 5 widget tests covering all 4 priority levels ofGlassThemeHelpers.resolveQuality(). - TEST: New
test/widgets/surfaces/build_icon_shadows_test.dart— 6 unit tests coveringbuildIconShadows(): null thickness, active-icon suppression, shadow count, 45° offset math, and color propagation. - TEST: Added
test/theme/,test/renderer/,test/types/,test/constants/,test/utils/, andtest/widgets/test suites (committed for the first time — these were written during the 0.7.13–0.7.14 coverage push but never staged).
0.7.14 #
Bug Fixes #
- FIX:
GlassSearchableBottomBar—extraButtonnow fades out smoothly when search activates instead of being visually clipped/shrunk between the collapsing tab pill and the expanding search pill. Layout space is still reserved during the morph (no pills jump), only the visual opacity transitions. Taps on the extra button are also correctly blocked while hidden. Fades in when search closes. - FIX:
GlassSearchableBottomBar— spring morph animations no longer produce a visible jump when reversing direction. Previously the three spring controllers (tabW,searchLeft,searchW) were each started in separateaddPostFrameCallbackcalls, introducing a 1-frame desync at reversal. All three are now started in a single batched callback, so the morph is perfectly synchronized in both directions. - FIX: Indicator fade animation in
GlassBottomBar/GlassSearchableBottomBar— replacedOpacitywrapper withLiquidGlassSettings.visibilityfading. Wrapping aBackdropFilterinOpacitycomposites into an offscreen buffer, breaking backdrop sampling and causing the indicator to snap in/out instead of fading. Thevisibilitypath is a single GPU pass — no offscreen buffer — improving drag animation performance and working uniformly for allblurvalues. - FIX:
GlassBottomBar,GlassSearchableBottomBar,GlassAppBar,GlassToolbar, andGlassSideBarresolved toGlassQuality.standardinstead of their documentedGlassQuality.premiumdefault. Fixed by settingquality: nullin the built-in light/dark variants so each widget's documented default is respected. - FIX: Setting any property in
GlassThemeVariant.settingssilently zeroed out all unset properties (e.g. setting onlythickness: 50also resetglassColorto fully transparent). Fixed by introducingGlassThemeSettings: a parallel class with all-nullable fields that merges onto each widget's own defaults. Only the fields you explicitly set are applied; everything else inherits from the widget.GlassThemeVariant.settingsnow acceptsGlassThemeSettings?. - FIX:
GlassSearchableBottomBar— multiple layout-math regressions in the morph animation corrected:- Reserved layout width now correctly scales to
min(size, searchBarHeight)during search, eliminating the bloated gap whensearchBarHeight < barHeight. - Extra button rendered width now matches the layout reserve (
extraTargetW), preventing a 14 px overflow into the search pill whensearchBarHeight < barHeight. - Restored
+ widget.spacingintargetSearchLeft; an erroneoustabToNextGapvariable had suppressed the gap between the tab pill and search pill when no extra button was present. collapseOnSearchFocusnow exclusively controls visibility/opacity — it no longer affects layout geometry. Toggling it mid-animation no longer triggers the spring or causes the button to jump inside the collapsed tab circle.
- Reserved layout width now correctly scales to
- FIX:
BottomBarTabItem— removed a fixedvertical: 4padding wrapping the tab column. The padding consumed constraint space beforeFittedBoxcould scale, causing a 2 pxRenderFlexoverflow when the bar morphed tosearchBarHeight.
New #
- NEW:
GlassThemeSettings— a partial settings type for use inGlassThemeVariant. Accepts the same parameters asLiquidGlassSettingsbut all are nullable. Only non-null fields override the target widget's defaults, enabling precise single-property theme overrides without disturbing others. - NEW:
GlassTabPillAnchorenum +GlassSearchableBottomBar.tabPillAnchor— controls how the tab pill is anchored during the morph animation.GlassTabPillAnchor.start(default) preserves existing left-anchor behaviour.GlassTabPillAnchor.centermakes both edges collapse symmetrically from the pill's centre for a more balanced look. The search pill position adjusts automatically in center mode. - NEW:
GlassSearchBarConfig.showsCancelButtonnow defaults totrue. Tapping the dismiss pill unfocuses the keyboard and collapses search, matching the system-level behaviour seen across iOS apps (Weather, App Store, Apple News). PassshowsCancelButton: falseto opt out. - NEW:
GlassSearchBarConfig.collapsedTabWidthis now nullable. When omitted, the collapsed tab pill automatically matchesGlassSearchableBottomBar.searchBarHeight, ensuring it morphs into a geometric circle with no leftover horizontal margin. Pass an explicit value to override. - NEW:
GlassBottomBarExtraButton.collapseOnSearchFocus(defaulttrue) — controls whether the extra button collapses when the search field is focused. Whentrue, the button fades out and its layout space spring-animates to zero, giving the search input the full available width (matching native iOS behaviour). Whenfalse, the button remains fully visible and tappable alongside the search input — useful for contextually relevant actions like a Filter button that applies to search results. - EXAMPLE:
searchable_bar_repro.dartadded to the example app — exercisesGlassSearchableBottomBaredge cases (extra-button fade, spring desync, bar-height scale, dismiss pill) in isolation. Run standalone:flutter run -t example/lib/searchable_bar_repro.dart.
0.7.13 #
New — GlassQuality.minimal #
-
FEAT:
GlassQuality.minimal— third quality tier: a crisp frosted glass surface with zero custom fragment shader execution on any platform. UsesBackdropFilterblur- Rec. 709 saturation matrix + a light-angle specular rim stroke. No refraction warping or chromatic aberration — a deliberately flat, clean aesthetic that looks excellent on any background and never adds GPU shader cost.
Two distinct use cases:
Device fallback — for hardware where even [standard] is too heavy: very old Android devices with limited shader driver support, or any device where
ImageFilter.isShaderFilterSupportedreturnsfalse.GPU budget management — for shader-dense screens: use [minimal] for background panels, list cards, and decorative containers while keeping [standard] or [premium] on the focal element. A screen with 15 glass list cards running [minimal] fires zero shader invocations during scroll — only
BackdropFiltercompositing.AdaptiveGlass( quality: GlassQuality.minimal, child: child, ) -
FEAT:
GlassThemeVariant.minimal— static preset that applies.minimalquality globally viaGlassThemeData:GlassTheme( data: GlassThemeData( light: GlassThemeVariant.minimal, dark: GlassThemeVariant.minimal, ), child: child, )
New — GlassPerformanceMonitor #
-
FEAT: Debug/profile-only performance monitor that watches raster frame durations while
GlassQuality.premiumsurfaces are active. When frames exceed the GPU budget for 60 consecutive frames, a singleFlutterErroris emitted with actionable guidance (specific widget parameters, device compatibility notes, and alternative quality tiers).Zero production overhead — the monitor never registers a callback in release builds. Enabled by default in debug/profile builds via
LiquidGlassWidgets.initialize():// Default: auto-enabled in debug/profile, zero-cost in release await LiquidGlassWidgets.initialize(); // Opt out: await LiquidGlassWidgets.initialize(enablePerformanceMonitor: false); // Custom thresholds (advanced): GlassPerformanceMonitor.rasterBudget = const Duration(microseconds: 8333); // 120 fps GlassPerformanceMonitor.sustainedFrameThreshold = 120; // 2 seconds at 60 fpsThe monitor correctly attributes slowdowns to premium glass by counting active
GlassQuality.premiumsurfaces. It stays silent when no premium widgets are mounted, avoiding false positives from other parts of the app.
0.7.12 #
Bug Fixes #
-
FIX: Interactive blend-group stretch asymmetry —
LiquidStretchnow expands geometry symmetrically from the widget centre, fixing the left-leans-in / right-resists imbalance during touch-drag on button groups. -
FIX: Erroneous highlight bias — removed a legacy shader hack that skewed surface normals horizontally. Normals are now derived accurately from the SDF gradient, eliminating optical hotspots that made straight groups look crooked.
-
PERF: Zero-jitter animation bounds — geometry texture mapping is now strictly bound to the physical size it was rasterised for, stopping frame-lag wobble when buttons change scale during interactive drags.
-
FIX: Theme quality cascade — audited 15+ widgets (
GlassBottomBar,GlassSwitch,GlassTextField, and others) that were silently overriding the globalGlassThemeVariantquality setting withGlassQuality.premium. All widgets now correctly inherit and respect the global quality profile, protecting frame rate and thermal limits on older devices (e.g. iPhone 12 and below). -
FIX: Zero-thickness blur — setting
thickness: 0no longer makes the glass fully transparent. Backdrop blur now renders correctly on glass surfaces regardless of geometric thickness, restoring backward-compatible behaviour. -
FEAT:
GlassSearchBarConfig.focusNode— optionalFocusNodeforGlassSearchBarConfig. When provided, the caller has full programmatic focus control (requestFocus(),unfocus(),addListener()) independent ofautoFocusOnExpand. The widget adopts the caller-provided node without disposing it (caller owns lifecycle), matching Flutter's ownTextField.focusNodecontract. -
FEAT:
GlassSearchBar.focusNode— sameFocusNodesupport added to the standaloneGlassSearchBarfor consistency.GlassTextFieldalready had this. -
FIX:
ExtraButtonPosition— new enum onGlassBottomBarExtraButton. Set.position = ExtraButtonPosition.afterSearchto pin the extra button to the right of the search pill. Spring geometry calculations reserve space correctly to preventRenderFlexoverflows during expand/collapse. Default isExtraButtonPosition.beforeSearch— fully backwards-compatible. -
FIX: Windows / SkSL shader compilation — eliminated all dynamic array index expressions from
sdf.glsl. The previousgetShapeSDFFromArray(int index)computed offsets at runtime, which SkSL/glslang on Windows rejects with "index expression must be constant". Replaced with literal-indexedsdf0()…sdf15()helpers and a fully-unrolledsceneSDFfor 1–16 shapes.MAX_SHAPESstays 16; no API or visual change. -
TOOLING:
scripts/validate_shaders.sh— macOS script that validates all shaders against Windows/SkSL compiler rules usingglslangValidator. Runbash scripts/validate_shaders.shbefore releasing. Requiresbrew install glslang(one-time).
0.7.11 #
Bug Fixes #
-
FIX: Windows/Android build failure — three shader compilation errors on the SPIR-V/glslang path: loop bounds must be compile-time constants;
dFdx/dFdyon a scalarfloatis rejected by glslang (geometry shader now uses#ifdef IMPELLER_TARGET_METALto keep hardware derivatives on iOS/macOS and fall back to ±0.5 px finite differences on Vulkan/OpenGL ES); global non-constant initialisers at file scope inliquid_glass_final_render.fragmoved intomain(). -
FIX: Blend-group asymmetry — the liquid-glass merge neck between grouped buttons leaned toward the left button. Fixed with a bidirectional smooth-union pass (L→R + R→L, averaged 50/50) that cancels the directional bias exactly.
0.7.10 #
Bug Fixes #
- FIX: Windows build (
flutter build windows) — two shader issues fatal on SkSL/glslang but silently accepted on Metal:no match for min(int, int)(replaced with a ternary) and global non-constant initialisers (moved intomain()). No visual change on any platform.
0.7.9 #
Bug Fixes #
- FIX: Windows build failure —
uShapeData[MAX_SHAPES * 6]was passed as a by-value function parameter, which glslang rejects. Fixed by accessing it as a global uniform. No visual change.
Tweaks #
- TWEAK:
GlassSearchableBottomBariOS 26 Apple News parity — animated inline×clear button replaces microphone when text is present; simplified hit-testing layout replacesOverlaylayers; guaranteed GPU liquid-glass merging between the search and dismiss pills in a single shader pass.
0.7.8 #
Tweaks #
- TWEAK:
GlassThemeVariant.lightnow defaults to a cool-tintedglassColor(Color(0x32D2DCF0)), strongerrefractiveIndex, and boostedambientStrengthto ensure premium specular rendering and visible refraction on flat white backgrounds.
Examples #
- Apple News demo — replaced
Image.networkcalls with pre-sized bundled assets (example/assets/news_images/) to fix Impeller GPU command-buffer overflow on iOS 26 physical devices. - Apple News demo —
collapsedLogoBuildernow mirrors the active tab icon instead of a static badge.
0.7.7 #
Refactor #
- Internal: Removed
GlassIndicatorTapMixinand migratedGlassTabBarandGlassSegmentedControlfully to rawListenerpointer events, matchingGlassBottomBar's robust drag-cancel and press-and-hold handling. No API change.
0.7.6 #
Bug Fixes #
-
FIX:
LiquidGlassBlendGroupasymmetry — left buttons attracted their neighbours more strongly than right buttons in groups of 3+. Fixed with a bidirectional smooth-union pass (L→R + R→L, averaged 50/50). Two-shape groups are mathematically identical to before. -
FIX:
GlassButtonGroup— glass effect could bleed as a dark rectangle on Impeller withGlassQuality.premiumanduseOwnLayer: true. AClipRRect(antiAlias)now hard-clips the bleed at the superellipse boundary without forcing a quality downgrade.
0.7.5 #
Bug Fixes #
-
FIX:
GlassBottomBar/GlassSearchableBottomBar— addedHitTestBehavior.opaqueto the rootGestureDetectorso the full bar height reliably consumes pointer events on simulator and desktop. -
FIX:
GlassSearchableBottomBar— keyboard no longer flickers on physical devices; focus is requested after the expansion animation completes. -
FIX:
GlassSearchableBottomBar— dead zone at expanded search pill edges resolved; the full glass surface now claims taps and routes them to the search field.
New — GlassSearchBarConfig parameters #
Seven new parameters (all backwards-compatible):
| Parameter | Type | Default | Description |
|---|---|---|---|
autoFocusOnExpand |
bool |
false |
Keyboard opens automatically on expand. |
trailingBuilder |
WidgetBuilder? |
null |
Replaces the mic icon with any custom widget. |
textInputAction |
TextInputAction? |
null |
Keyboard action key (search, done, go, …). |
keyboardType |
TextInputType? |
null |
Keyboard layout (url, emailAddress, …). |
autocorrect |
bool |
true |
Disable for codes, usernames, etc. |
enableSuggestions |
bool |
true |
Controls QuickType bar on iOS. |
onTapOutside |
TapRegionCallback? |
null |
Called when user taps outside the field. |
0.7.4 #
New Components #
GlassSearchableBottomBar—GlassBottomBarwith a morphing search pill that shares the sameAdaptiveLiquidGlassLayeras the tab pill, producing iOS 26 liquid-merge blending. WhenisSearchActiveistruethe tab pill collapses and the search pill expands via spring animation. Configured viaGlassSearchBarConfig.
Examples #
- Apple News demo (
example/lib/apple_news/apple_news_demo.dart) — iOS 26 Apple News replica showcasingGlassSearchableBottomBar.
Visual Fixes #
- FIX: Default glow color on press changed from iOS system blue to a brightness-adaptive neutral white (~35% light / ~22% dark), matching iOS 26 glass press behaviour.
0.7.3 #
Performance #
- PERF: Deleted unused
rotate2d()fromrender.glsl— it was compiled into every shader binary but never called. - PERF: Eliminated a redundant
normalize()ininteractive_indicator.fragby reusing an already-computed length. - PERF: Removed a no-op
canvas.save()/canvas.restore()pair inGlassGlowpaint.
Bug Fixes #
- FIX:
GlassGlowtracking — glow gradient is now correctly recreated each frame whenglowOffsetchanges, fixing the spotlight freezing at its initial position. - FIX: Glow on Skia/Web —
LightweightLiquidGlassnow wraps inGlassGlowLayer, giving the Skia path the same light-follows-touch behaviour as Impeller. - FIX: Glow on first touch — spotlight now appears immediately at the tap position instead of sliding in from the widget's top-left corner.
- FIX: Glow tracking inside button groups — converted from widget-local to global coordinates so the spotlight correctly follows touches regardless of nesting depth.
- FIX: Glow radius on wide buttons — switched from
shortestSideto√(width × height)so the spotlight scales proportionally to the button area.
0.7.2 #
Performance & Polish #
- PERF: Lightweight shader (
lightweight_glass.frag) — reduced ALU instruction count ~10–15 ops per fragment; restored thenormalZFresnel ramp tosqrt(1 − dot(n,n)). - PERF: Impeller final render shader — eliminated
length()/normalize()from anisotropic specular; madegetHeight()fully branchless; collapsed fourstep()multiplications into one. - PERF: Dart side — cached light direction trig in
LiquidGlassRenderObject(only recomputed whenlightAnglechanges); changedGlassGroupLink.shapeEntriesfromListtoIterableto eliminate per-frame heap allocation. - FIX: Adjusted
GlassBottomBar,GlassTabBar, andGlassSegmentedControlspring from 500msbouncySpringto 350mssnappySpring, matching iOS 26 segment-indicator physics.
0.7.1 #
Bug Fixes #
- FIX:
GlassBottomBar,GlassTabBar,GlassSegmentedControl— rapid taps no longer prematurely snap the indicator, killing spring physics. Removed pixel-snapping fromonHorizontalDragDownso taps correctly use spatial distance for the iOS 26 jump animation.
0.7.0 #
New Components #
GlassDivider— iOS 26-style hairline separator, horizontal and vertical. Theme-adaptive opacity (dark: 20% white / light: 10% black).GlassListTile— iOS 26 Settings-style row with leading icon, title, subtitle, trailing widget, and automatic grouped dividers. Use inside a zero-paddingGlassCard. Convenience constants:GlassListTile.chevron,GlassListTile.infoButton.GlassStepper— iOS 26UIStepperequivalent. Compact−/+glass pill with auto-repeat on hold,min/maxclamping,wrapscycling, fractionalstep, and haptic feedback.GlassWizard+GlassWizardStep— multi-step flow with numbered indicators, checkmarks, and expandable step content.
Accessibility #
GlassAccessibilityScope— reads platform Reduce Motion and Reduce Transparency preferences and propagates them to all glass widgets in its subtree:- Reduce Motion: spring animations snap instantly.
- Reduce Transparency: replaces the full glass shader pipeline with a plain
BackdropFilter(blur)+ frosted container.
- Semantics updated across all remaining widgets to match iOS
UIAccessibilityconventions.
Performance #
- PERF:
GlassSpecularSharpnessenum — replacespow(lightCatch, exponent)(two transcendentals per fragment) with a pure squaring chain inlightweight_glass.frag. Zero transcendentals. Default:.medium. - PERF:
pow(x, 1.5)→x·√xin Impeller edge lighting —sqrt()is a single hardware SFU instruction. - PERF: Anisotropic specular and Fresnel rim brightening ported from the Impeller path to
lightweight_glass.frag, closing the largest visual gap between rendering paths. - PERF: Content-adaptive glass strength — intensity auto-adjusts based on backdrop luminance on Impeller, or
MediaQuery.platformBrightnesson Skia/Web.
Developer Experience #
GlassRefractionSource— renamed fromLiquidGlassBackgroundto better reflect its role.LiquidGlassBackgroundremains as a deprecatedtypedef(removed in 1.0.0).- Synchronous background capture — rebuilt using
boundary.toImageSync()on native (zero CPU↔GPU readback) and asynctoImage()on web.
0.6.1 #
Visual Quality #
- FIX: True surface normal storage in geometry texture — the geometry pass now stores the SDF-gradient-derived surface normal instead of the refraction displacement vector. The render shader decodes and recomputes displacement via
refract(). Specular highlights on blended glass shapes (e.g. two overlapping pills) now correctly follow true surface curvature rather than the refraction direction. Single-shape surfaces are visually identical to 0.6.0. - FIX: Anisotropic specular highlights (Impeller) — specular lobe stretched 20% along the surface tangent, producing the horizontal oval highlight that matches iOS 26.
- FIX: Fresnel edge luminosity ramp (Impeller) — gentle brightness ramp at grazing angles matching iOS 26's centre-to-edge luminosity gradient.
- FIX: Luminosity-preserving glass tint in lightweight shader — replaced additive tint with the same
applyGlassColor()model as the Impeller path: achromatic glass lifts toward white, chromatic glass shifts hue while preserving luminance.
Performance #
- PERF: Branchless
smoothUnion— eliminated a conditional branch that caused warp divergence when glass shapes transition between merged and separate. - PERF:
if/else ifdispatch in shape SDF — GPU now short-circuits after the first type match; default changed to0.0for a clearly visible failure mode. - PERF: Single texture fetch when chromatic aberration is disabled —
interactive_indicator.fragpreviously sampled the background three times unconditionally; 66% fewer texture reads in the common case. - PERF: Flat-interior early-exit in final render shader — pixels where
normalXY ≈ 0skiprefract()and all texture samples, replaced with a single background sample. Lossless.
0.6.0 #
Breaking Changes #
LiquidGlassLayer.useBackdropGroupremoved. Glass layers now automatically detect aBackdropGroupancestor. RemoveuseBackdropGroup: truefrom anyLiquidGlassLayer(...)calls.
New Features #
LiquidGlassWidgets.wrap()— wraps your app in aGlassBackdropScopein one line:runApp(LiquidGlassWidgets.wrap(const MyApp()));GlassMotionScope— drives glass specular angle from anyStream<double>(e.g. device gyroscope). No new dependencies required.
Performance #
- PERF:
GlassBackdropScopeauto-activation — glass layers automatically share a single GPU backdrop capture when a scope ancestor is present. - PERF: Local-space geometry rasterization — geometry texture cached until pill size or shape changes, eliminating per-frame rebuilds during animation.
- PERF: Shader UV bounds check — discards fragments where geometry UV falls outside
[0, 1], preventing the thin "protruding line" artifact during jelly-physics expansion.
Visual #
- FIX: Refraction UV — uses
uSizeuniform (always valid on first frame) instead oftextureSize()which returns(0,0)on the first frame in Impeller. - FIX:
precision highp floatin final render shader (wasmediump, risking colour banding on mobile). - FIX: iOS 26 glass tint model — preserves backdrop luminance while shifting chroma. Replaces Photoshop Overlay mode.
- FIX: Leading-dot rim artifact —
x / (1 + x)soft-clamping on highlight intensity prevents bright corner artifact during drag. - FIX: Impeller indicator clipping — jelly physics animations no longer clip at the static bounding box (
clipExpansionparameter added). - FIX: Web & WASM — removed
dart:ioimports from shader resolution logic.
Dependencies #
- Removed
motordependency — replaced with self-containedglass_spring.dart. Zero third-party runtime dependencies beyond the Flutter SDK.
0.5.0 #
Breaking Changes #
LiquidGlass removed from the public API.
It was inadvertently exposed and silently renders nothing on Skia/Web. Use AdaptiveGlass instead:
// Before
LiquidGlass(settings: LiquidGlassSettings(...), child: ...)
// After
AdaptiveGlass(settings: LiquidGlassSettings(...), child: ...)
LiquidGlassLayer, LiquidGlassBlendGroup, LiquidGlassSettings, LiquidShape, GlassGlow, and debugPaintLiquidGlassGeometry remain public.
New Features #
GlassBackdropScope— halves GPU blur capture cost when multiple glass surfaces are on screen simultaneously. Wrap yourMaterialApporScaffoldto activate:
GlassBackdropScope(
child: MaterialApp(
home: Scaffold(
appBar: GlassAppBar(...),
bottomNavigationBar: GlassBottomBar(...),
),
),
)
Renderer #
The renderer from liquid_glass_renderer (whynotmake.it, MIT) is now vendored directly, giving full control over the rendering pipeline with no user-facing API changes.
0.4.1 #
Bug Fixes #
- FIX:
GlassBottomBarand other surfaces now correctly respond to dynamicglassSettingschanges onGlassQuality.standard—AdaptiveGlassin grouped mode now inherits settings fromInheritedLiquidGlassinstead of using empty defaults. - FIX: Luminance-aware ambient floor for white glass on
GlassQuality.standard— high-opacity white glass no longer renders as dark grey.
New #
- FEAT:
GlassBottomBar.iconLabelSpacing— configurable vertical gap between tab icon and label (default:4.0). Thanks @baneizalfe (#11).
Breaking Changes #
Library-wide IconData → Widget API migration. All icon parameters now accept any Widget:
// Before
GlassButton(icon: CupertinoIcons.heart, onTap: () {})
// After
GlassButton(icon: Icon(CupertinoIcons.heart), onTap: () {})
// Or any custom widget:
GlassButton(icon: SvgPicture.asset('assets/heart.svg'), onTap: () {})
GlassBottomBarTab.selectedIcon renamed to activeIcon to match Flutter's BottomNavigationBarItem convention.
0.4.0 #
New Components #
GlassMenu/GlassMenuItem/GlassPullDownButton— iOS 26 morphing context menu with spring physics and position-aware expansion.GlassButtonGroup— joined-style container for related actions (e.g. Bold/Italic/Underline toolbar).GlassFormField/GlassPasswordField/GlassTextArea/GlassPicker— full iOS 26 input suite.GlassSideBar— vertical navigation surface with header, footer, and scrollable items.GlassToolbar— standard iOS-style action toolbar.GlassTabBar— horizontal tab navigation bar with animated indicator and scrollable mode for 5+ tabs.GlassProgressIndicator— circular and linear variants (indeterminate and determinate), iOS 26 specs.GlassToast/GlassSnackBar— 5 notification types, 3 positions, auto-dismiss, swipe-to-dismiss.GlassBadge— count and dot status badges, 4 positions.GlassActionSheet— iOS-style bottom-anchored action list.
Performance #
- Universal Platform Support —
AdaptiveGlassandAdaptiveLiquidGlassLayerintroduced. All 26 widgets deliver consistent glass quality on Web, Skia, and Impeller. - Batch-blur optimisation — glass containers share a single
BackdropFilter(was: one per widget). ~5× faster in common multi-widget layouts. - Impeller pipeline warm-up — shaders pre-compile at startup to eliminate first-frame jank.
Theme System #
GlassTheme/GlassThemeData/GlassThemeVariant— global styling and quality inheritance across all widgets. Set once, inherited everywhere.
0.3.0 — 0.1.0 #
Early access and preview releases establishing the core widget library, initial glass rendering pipeline (LiquidGlass, LiquidGlassLayer, LiquidGlassBlendGroup), and foundational components (GlassBottomBar, GlassButton, GlassSwitch, GlassCard, GlassSearchBar, GlassSlider, GlassChip, GlassSegmentedControl, GlassSheet, GlassDialog, GlassIconButton).