Liquid Glass Widgets logo

Liquid Glass Widgets

Community
sdegenaar
liquid-glass-widgets

Mastery guide and architectural rules for liquid_glass_widgets. Trigger whenever generating, refactoring, or reviewing Flutter UI code using liquid glass, iOS 26/27 aesthetics, GlassScaffold, GlassTabBar, GlassModalSheet, or any Glass* components.

Overview

Publishersdegenaar
Repositoryliquid_glass_widgets
Skill nameliquid-glass-widgets
Stars
731
Forks
109
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by sdegenaar on GitHub. Read the source before you install it.

Installation

Install the Liquid Glass Widgets AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/sdegenaar/liquid_glass_widgets/tree/main/skills/liquid-glass-widgets
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/sdegenaar/liquid_glass_widgets.git /tmp/liquid_glass_widgets
mkdir -p .claude/skills
cp -r /tmp/liquid_glass_widgets/skills/liquid-glass-widgets .claude/skills/liquid-glass-widgets
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Liquid Glass Widgets in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Liquid Glass Widgets on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Liquid Glass Widgets is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Liquid Glass Widgets — AI Agent Guide

This skill defines the architecture, design principles, API dictionary, and strict implementation rules for building Flutter applications with liquid_glass_widgets.

Follow this guide strictly when writing, refactoring, or reviewing UI code to ensure high visual fidelity, 60/120 fps GPU performance, and zero hallucinations.


1. Golden Architectural Rules (Mandatory)

Rule 1: Glass is a Platter, Not a Wrapper

Glass in the iOS 26 design system is reserved for the navigation and control layer — floating chrome that sits above content.

  • DO use glass for: Navigation bars (GlassAppBar), tab bars (GlassTabBar), floating buttons (GlassButton, GlassIconButton), toolbars, modal sheets (GlassModalSheet), dialogs (GlassDialog), and standalone floating cards (GlassCard).
  • DO NOT use glass for: Full-screen backgrounds, dense list view items, video players, image galleries, or text article bodies. Backgrounds should be rich wallpapers or gradients; content cards should be clean and readable.

Rule 2: NEVER Nest Refractive Glass inside Refractive Glass

Placing refractive glass widgets inside another refractive glass container is an optical and performance anti-pattern.

  • CRITICAL ANTI-PATTERN: Placing GlassButton, GlassIconButton, GlassSegmentedControl, GlassSlider, or GlassSwitch inside a GlassCard, GlassGroupedSection, or GlassContainer.
  • Why? Interactive glass controls provide their own refractive surface. Nesting creates severe double-refraction distortion, clips spring jelly animations, and wastes GPU fill-rate.
  • Correct Pattern:
    • In a GlassCard or GlassGroupedSection: Use standard text, icons, and non-refractive controls (or GlassListTile which is specifically designed without an internal glass layer).
    • Outside the card / on the page platter: Use GlassSegmentedControl, GlassButton, GlassSlider, or standalone GlassSwitch(useOwnLayer: true).

Rule 3: Single Public Import

  • ALWAYS: import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
  • NEVER import package:liquid_glass_widgets/src/....
  • NEVER instantiate LiquidGlass(...) directly — it is an internal Impeller-only renderer. Always use AdaptiveGlass or the high-level Glass* widgets.

Rule 4: Ban Obsolete Pre-1.0 APIs

  • GlassBottomBar and GlassSearchableBottomBar were deleted in v1.0.0.
  • ALWAYS USE: GlassTabBar.bottom(...) or GlassTabBar.searchable(...).

Rule 5: Honor Quality Tiers

  • GlassQuality.standard: Default for 95% of controls, cards, and input fields. Uses a highly optimized single-pass fragment shader.
  • GlassQuality.premium: Multi-pass Impeller shader with chromatic dispersion, realistic refraction, and dynamic specular highlights. Reserved for persistent navigation bars (GlassAppBar, GlassTabBar) and hero surfaces. GlassScaffold automatically promotes its bars to premium.
  • GlassQuality.minimal: Lightweight shader-free fallback (BackdropFilter only). Use for ultra-dense scrolling lists or low-power modes.

2. App Lifecycle & Initialization

In main.dart, always initialize the shader pipeline before runApp(), and wrap the application with LiquidGlassWidgets.wrap().

dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Pre-warms fragment shaders in parallel to prevent first-frame white flashes or shader jank
  await LiquidGlassWidgets.initialize();

  runApp(
    LiquidGlassWidgets.wrap(
      adaptiveQuality: true, // Dynamically benchmarks device raster budget and scales quality
      respectSystemAccessibility: true, // Automatically degrades on Reduce Motion / Reduce Transparency

      // CRITICAL FOR MATERIAL APPS: Bridges Material ThemeMode without importing flutter/material in the engine
      brightnessResolver: Theme.maybeBrightnessOf,

      // GlassThemeData.simple is the recommended constructor — applies the same settings to
      // both light and dark, overlaid on the library's built-in per-mode defaults.
      // Use GlassThemeData(light: ..., dark: ...) only for fine-grained per-mode control.
      theme: GlassThemeData.simple(
        blur: 12,
        thickness: 25,
        quality: GlassQuality.standard,
      ),
      child: const MyApp(),
    ),
  );
}

3. Screen Architecture: GlassScaffold

For any screen featuring liquid glass navigation bars or floating surfaces, always use GlassScaffold instead of Flutter's built-in Scaffold.

GlassScaffold solves complex compositing challenges automatically:

  1. Guaranteed Z-Ordering: App bars and bottom bars paint above scrolling body content, preventing body cards from overlapping navigation buttons.
  2. Edge Fading: Content fades smoothly as it scrolls under bars (.scrollEdgeEffectStyle(.soft) matching iOS 26).
  3. Content-Aware Brightness: Dynamically flips app bar icons and typography between light and dark depending on the luminosity of the content scrolling underneath.
  4. Auto-Padding: Automatically accounts for safe areas and bar heights.
dart
class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedTab = 0;

  @override
  Widget build(BuildContext context) {
    return GlassScaffold(
      // 1. Wallpaper background (image, gradient, or solid)
      background: Image.asset('assets/wallpaper.jpg', fit: BoxFit.cover),
      contentAwareBrightness: true,

      // 2. Navigation Bar
      // GlassAppBar uses `actions` (List<Widget>), not `trailing`.
      appBar: GlassAppBar(
        title: const Text('Dashboard'),
        actions: [
          GlassIconButton(
            icon: const Icon(CupertinoIcons.bell_fill),
            onPressed: () => _openNotifications(),
          ),
        ],
      ),

      // 3. Unified Bottom Tab Bar
      bottomBar: GlassTabBar.bottom(
        selectedIndex: _selectedTab,
        onTabSelected: (index) => setState(() => _selectedTab = index),
        tabs: const [
          GlassTab(icon: Icon(CupertinoIcons.house_fill), label: 'Home'),
          GlassTab(icon: Icon(CupertinoIcons.chart_bar_fill), label: 'Stats'),
          GlassTab(icon: Icon(CupertinoIcons.gear_alt_fill), label: 'Settings'),
        ],
      ),

      // 4. Scrollable Body Content
      body: ListView(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
        children: [
          // Content cards stay opaque or use GlassCard for grouping
          GlassGroupedSection(
            header: const Text('ACCOUNT'),
            children: [
              GlassListTile(
                leading: const Icon(CupertinoIcons.person_fill),
                title: const Text('Profile'),
                trailing: GlassListTile.chevron,
                onTap: () {},
              ),
              GlassListTile(
                leading: const Icon(CupertinoIcons.lock_shield_fill),
                title: const Text('Privacy & Security'),
                trailing: GlassListTile.chevron,
                onTap: () {},
              ),
            ],
          ),
        ],
      ),
    );
  }
}

4. Component Dictionary & Substitution Table

When generating Flutter UI, replace standard Flutter widgets with their native liquid glass counterparts:

Flutter Standard WidgetLiquid Glass ReplacementKey Usage Notes
ScaffoldGlassScaffoldHandles z-order, edge fading, content-aware brightness.
AppBar / CupertinoNavigationBarGlassAppBarTransparent iOS 26 style by default. Supports .pinned for gel morph.
BottomNavigationBar / CupertinoTabBarGlassTabBar.bottomUnified glass navigation pill. GlassBottomBar is deleted.
Bottom nav that collapses to selected tab on scrollGlassTabBar.minimizableMinimizes to a single pill on scroll; supports an optional trailing action button.
ElevatedButton / CupertinoButtonGlassButtonRefractive button with squeeze & stretch physics and touch glow.
IconButtonGlassIconButtonRefractive circular/squircle button with onPressed.
PopupMenuButton / Context MenuGlassPullDownButtonCombined trigger button and GlassMenu.
CupertinoSegmentedControlGlassSegmentedControl<T>Fluid animated glass indicator with jelly physics. Do NOT wrap in GlassCard.
Switch / CupertinoSwitchGlassSwitchFluid spring jump animation. Use useOwnLayer: true when standalone.
Slider / CupertinoSliderGlassSliderGlass track with draggable jelly thumb and haptic snaps.
CardGlassCardGlass container for grouping content. Content inside stays opaque.
Grouped ListViewGlassGroupedSectionInset grouped list container with automatic dividers between GlassListTiles.
ListTileGlassListTileGrouped row item. Shares parent glass layer inside GlassGroupedSection.
DividerGlassDividerRefractive subtle separator line.
TextField / CupertinoTextFieldGlassTextFieldInput field with glowing refractive focus border.
showModalBottomSheetGlassModalSheet.showMulti-detent fluid sheet (peek, half, full) with spring physics.
showDialog / CupertinoAlertDialogGlassDialog.showLiquid glass modal alert with GlassDialogAction buttons.
SnackBar / BannerGlassToastFloating glass HUD banner.

5. Overlays: Modal Sheets, Dialogs & Transitions

GlassModalSheet

Presents an iOS 26 fluid modal sheet with detents:

dart
GlassModalSheet.show(
  context: context,
  initialState: GlassSheetState.half,
  halfSize: 0.5,
  peekSize: 90.0,
  builder: (sheetContext) {
    return ListView(
      padding: const EdgeInsets.all(20),
      children: const [
        Text(
          'Modal Sheet Content',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
      ],
    );
  },
);

GlassDialog

Presents a native alert dialog:

dart
GlassDialog.show(
  context: context,
  title: 'Discard Draft?',
  message: 'This action cannot be reversed.',
  actions: [
    GlassDialogAction(
      label: 'Cancel',
      onPressed: () => Navigator.of(context).pop(),
    ),
    GlassDialogAction(
      label: 'Discard',
      isDestructive: true,
      onPressed: () {
        Navigator.of(context).pop();
        _discardDraft();
      },
    ),
  ],
);

GlassMenu Submenus

Give a GlassMenuItem a submenu list to open a native iOS-style card over the parent (the parent recedes and dims; tapping the card's header or the exposed parent collapses one level). Submenus nest. Works in GlassMenu and GlassPullDownButton:

dart
GlassPullDownButton(
  icon: const Icon(CupertinoIcons.ellipsis_circle),
  items: [
    GlassMenuItem(
      title: 'Share…',
      icon: const Icon(CupertinoIcons.share),
      // onTap is required but never called on a submenu row:
      // activating it opens the card instead.
      onTap: () {},
      submenu: [
        GlassMenuItem(title: 'Messages', icon: const Icon(CupertinoIcons.chat_bubble_fill), onTap: _sendMessage),
        GlassMenuItem(title: 'Mail', icon: const Icon(CupertinoIcons.mail_solid), onTap: _sendMail),
      ],
    ),
    const GlassMenuDivider(),
    GlassMenuItem(title: 'Delete', icon: const Icon(CupertinoIcons.trash), isDestructive: true, onTap: _delete),
  ],
)
  • A submenu row shows a chevron automatically unless you pass trailing.
  • Do not build nested menus by opening a second GlassMenu from an item's onTap; use submenu.

GlassMaterialize

For widgets appearing or disappearing dynamically, use GlassMaterialize to match iOS 26's progressive defogging transition:

dart
GlassMaterialize(
  visible: _showFilterPill,
  // GlassChip.label is a String, not a Widget
  child: GlassChip(
    label: 'Active Filters',
    onDeleted: () => setState(() => _showFilterPill = false),
  ),
)

6. Advanced Navigation: Gel Morph with GlassNavigationShell

To achieve the signature iOS 26 navigation bar transition — where the capsule swells, bounces, and cross-fades icons between routes:

  1. Wrap the Navigator in GlassNavigationShell (typically in CupertinoApp.builder):
dart
CupertinoApp(
  builder: (context, child) => GlassNavigationShell(
    swipeCommitTransition: GlassSwipeCommitTransition.crossFade, // optional: plain cross-fade on back-swipe
    verticalBarBehavior: GlassVerticalBarBehavior.automatic,     // optional: iPhone Duo vertical strip
    child: child!,
  ),
  home: const HomeScreen(),
)
  1. Use GlassAppBar.pinned on destination screens. Items are declared as GlassBarItem data (not arbitrary widgets), which allows the shell to hoist them above the Navigator and morph them across routes:
dart
GlassAppBar.pinned(
  title: const Text('Detail'),
  actions: [
    // GlassBarItem.icon uses `onTap` (not `onPressed`)
    GlassBarItem.icon(
      icon: const Icon(CupertinoIcons.square_and_arrow_up),
      onTap: () => _share(),
    ),
    // Tinted capsule (iOS 26 prominent action): set tintColor + separate background.
    // The capsule fills with the colour; foreground icon auto-flips to white/black.
    GlassBarItem.icon(
      icon: const Icon(CupertinoIcons.checkmark),
      onTap: _save,
      background: GlassBarItemBackground.separate,
      tintColor: CupertinoColors.activeBlue,
    ),
  ],
)

Note: Without GlassNavigationShell, GlassAppBar.pinned falls back gracefully — items render inside the bar in-route, so all screens work either way.

iPhone Duo: Under the shell, pinned bars, GlassTabBar.bottom / .searchable, GlassToolbar and GlassLargeTitle move into the vertical bar strip on their own; pass a large title's controller to its GlassAppBar.pinned, which draws the title there. A GlassAppBar.pinned inside a GlassModalSheet follows the sheet, whose placement mirrors presentationPlacement(_:). Use GlassBarItem.custom(axisBehavior: GlassBarItemAxisBehavior.verticalPreferred) for custom content that should go with them, and read GlassVerticalBar.maybeOf(context) to fit a bar the package does not draw.


7. Common Agent Pitfalls (Checklist before outputting code)

  • Did you import the public API only? (import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';). Never import src/.
  • Did you call await LiquidGlassWidgets.initialize() in main()? Shaders must be pre-warmed.
  • Did you wrap your app in LiquidGlassWidgets.wrap()? Required for theme and accessibility scaling.
  • Are you using GlassScaffold instead of Scaffold? Prevents z-index glitches with glass nav bars.
  • Did you avoid nesting glass in glass? Never put GlassButton, GlassSlider, or GlassSwitch directly inside GlassCard or GlassGroupedSection.
  • Did you use GlassTabBar.bottom instead of GlassBottomBar? GlassBottomBar is deleted.
  • GlassButton uses onTap, not onPressed. (GlassButton(onTap: () {})) — the opposite of ElevatedButton.
  • GlassIconButton uses onPressed, not onTap. (GlassIconButton(onPressed: () {})).
  • GlassAppBar uses actions: [...] (a List), not trailing:. There is no trailing parameter.
  • GlassChip.label is a String, not a Widget. Pass label: 'text', not label: Text('text').
  • GlassBarItem.icon uses onTap (required), not onPressed.
  • Nested menus use GlassMenuItem(submenu: [...]). The parent row still needs onTap: () {} (required, never called). Don't open a second GlassMenu from onTap.
  • tintColor on GlassBarItem requires background: GlassBarItemBackground.separate. A shared-background item cannot be tinted (asserts in debug mode). The foreground icon colour is flipped automatically — do not also set a manual Icon(color:) on the child.

Frequently asked questions

What does the Liquid Glass Widgets AI skill do?

Mastery guide and architectural rules for liquid_glass_widgets. Trigger whenever generating, refactoring, or reviewing Flutter UI code using liquid glass, iOS 26/27 aesthetics, GlassScaffold, GlassTabBar, GlassModalSheet, or any Glass* components.

Why use Liquid Glass Widgets on TypingMind?

Because you install it once and use it with any model. Liquid Glass Widgets is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Liquid Glass Widgets in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/sdegenaar/liquid_glass_widgets/tree/main/skills/liquid-glass-widgets. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Liquid Glass Widgets?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Liquid Glass Widgets?

As many as you like. As long as a model supports skills, you can use Liquid Glass Widgets with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Liquid Glass Widgets AI skill free?

Yes. It is published on GitHub by sdegenaar under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇