liquid_glass_ui_kit 0.1.2 copy "liquid_glass_ui_kit: ^0.1.2" to clipboard
liquid_glass_ui_kit: ^0.1.2 copied to clipboard

An accessible, customizable Liquid Glass design system for Flutter with translucent themes and ready-made widgets for mobile, web, and desktop.

example/lib/main.dart

import 'package:flutter/cupertino.dart' show CupertinoIcons;
import 'package:flutter/material.dart';
import 'package:liquid_glass_ui_kit/liquid_glass_ui_kit.dart';

void main() => runApp(const DemoApp());

class DemoApp extends StatefulWidget {
  const DemoApp({super.key});

  @override
  State<DemoApp> createState() => _DemoAppState();
}

class _DemoAppState extends State<DemoApp> {
  bool _dark = true;
  int _tab = 0;
  bool _switchOn = true;
  bool _animateIndicator = true;
  bool _animateBounce = true;
  bool _showLabels = true;
  double _sliderValue = 0.53;
  String _segment = 'for-you';
  String _city = 'Jakarta';

  static String _cityLabel(String city) => city;

  void _openSheet(BuildContext context) {
    showGlassBottomSheet(
      context: context,
      title: 'Share',
      builder: (context) => Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Text('Choose how you want to share this item.'),
          const SizedBox(height: 20),
          GlassButton(
            label: 'Copy link',
            icon: Icons.link_rounded,
            variant: GlassButtonVariant.glass,
            expand: true,
            onPressed: () => Navigator.pop(context),
          ),
          const SizedBox(height: 12),
          GlassButton(
            label: 'Done',
            variant: GlassButtonVariant.filled,
            expand: true,
            onPressed: () => Navigator.pop(context),
          ),
        ],
      ),
    );
  }

  void _openDialog(BuildContext context) {
    showGlassDialog(
      context: context,
      title: 'Delete item?',
      message: 'This action cannot be undone.',
      actions: [
        GlassDialogAction(
          label: 'Cancel',
          isDefault: true,
          onPressed: () => Navigator.pop(context),
        ),
        GlassDialogAction(
          label: 'Delete',
          isDestructive: true,
          onPressed: () => Navigator.pop(context),
        ),
      ],
    );
  }

  void _openMenu(BuildContext context) {
    showGlassActionMenu(
      context: context,
      items: [
        const GlassMenuItem(label: 'Edit', icon: Icons.edit_outlined),
        const GlassMenuItem(label: 'Duplicate', icon: Icons.copy_rounded),
        const GlassMenuItem(label: 'Share', icon: Icons.ios_share_rounded),
        const GlassMenuItem(
          label: 'Delete',
          icon: Icons.delete_outline_rounded,
          isDestructive: true,
        ),
      ],
    );
  }

  static const _items = [
    GlassNavItem(icon: Icons.home_rounded, label: 'Home'),
    GlassNavItem(icon: Icons.sports_esports_rounded, label: 'Arcade'),
    GlassNavItem(icon: Icons.group_rounded, label: 'Friends'),
    GlassNavItem(icon: Icons.inventory_2_rounded, label: 'Library'),
    GlassNavItem(icon: Icons.search_rounded, label: 'Search'),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Liquid Glass UI',
      home: GlassTheme(
        data: _dark ? GlassThemeData.dark() : GlassThemeData.light(),
        child: Builder(
          builder: (context) {
            final theme = GlassTheme.of(context);
            return GlassScaffold(
              // A colorful backdrop so the glass has something to refract.
              background: const _Backdrop(),
              appBar: const GlassAppBar(
                title: Text('Liquid Glass'),
                leading: Icon(Icons.arrow_back_ios_new_rounded, size: 20),
              ),
              bottomNavigationBar: GlassBottomNavBar(
                currentIndex: _tab,
                onTap: (i) => setState(() => _tab = i),
                items: _items,
                animateIndicator: _animateIndicator,
                animateBounce: _animateBounce,
                showLabels: _showLabels,
              ),
              body: ListView(
                padding: const EdgeInsets.fromLTRB(16, 120, 16, 150),
                children: [
                  const Wrap(
                    spacing: 8,
                    runSpacing: 8,
                    children: [
                      GlassPill(
                        label: 'Now Available',
                        icon: Icons.bolt_rounded,
                      ),
                      GlassPill(label: 'iOS 26.4', selected: true),
                      GlassPill(label: 'Glassmorphism'),
                    ],
                  ),
                  const SizedBox(height: 20),
                  GlassCard(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Autocomplete + dropdown',
                          style: theme.typography.title3,
                        ),
                        const SizedBox(height: 8),
                        Text(
                          'A macOS-style combo box accepts a suggested or '
                          'custom value.',
                          style: theme.typography.subheadline,
                        ),
                        const SizedBox(height: 16),
                        GlassComboBox<String>(
                          label: 'Favorite City:',
                          placeholder: 'Enter a city',
                          helperText:
                              'Choose a suggestion or type another city.',
                          options: const [
                            'Jakarta',
                            'London',
                            'San Francisco',
                            'Singapore',
                            'Tokyo',
                          ],
                          initialSelection: 'Jakarta',
                          displayStringForOption: _cityLabel,
                          onChanged: (value) => setState(() => _city = value),
                          onSelected: (value) => setState(() => _city = value),
                        ),
                        const SizedBox(height: 12),
                        Text(
                          'Current value: $_city',
                          style: theme.typography.footnote,
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),
                  GlassCard(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Text fields', style: theme.typography.title3),
                        const SizedBox(height: 16),
                        GlassTextField(
                          label: 'Email',
                          placeholder: 'name@example.com',
                          prefix: const Icon(CupertinoIcons.mail),
                          keyboardType: TextInputType.emailAddress,
                          textInputAction: TextInputAction.next,
                          autofillHints: const [AutofillHints.email],
                        ),
                        const SizedBox(height: 16),
                        GlassTextField(
                          label: 'Password',
                          placeholder: 'Required',
                          prefix: const Icon(CupertinoIcons.lock),
                          obscureText: true,
                          autocorrect: false,
                          enableSuggestions: false,
                          autofillHints: const [AutofillHints.password],
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),
                  GlassCard(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Liquid controls', style: theme.typography.title3),
                        const SizedBox(height: 20),
                        LayoutBuilder(
                          builder: (context, constraints) => GlassSlider(
                            width: constraints.maxWidth,
                            value: _sliderValue,
                            activeColor: const Color(0xFF0A84FF),
                            semanticLabel: 'Playback position',
                            onChanged: (value) =>
                                setState(() => _sliderValue = value),
                          ),
                        ),
                        const SizedBox(height: 20),
                        LayoutBuilder(
                          builder: (context, constraints) =>
                              GlassSegmentedControl<String>(
                            width: constraints.maxWidth,
                            children: const {
                              'for-you': Text('For You'),
                              'library': Text('Library'),
                            },
                            selectedValue: _segment,
                            onValueChanged: (value) =>
                                setState(() => _segment = value),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),
                  GlassCard(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Toggle settings', style: theme.typography.title3),
                        const SizedBox(height: 8),
                        Text(
                          'Each switch controls one clearly identified '
                          'on-or-off setting.',
                          style: theme.typography.subheadline,
                        ),
                        const SizedBox(height: 16),
                        GlassToggleRow(
                          label: 'Dark appearance',
                          value: _dark,
                          onChanged: (v) => setState(() => _dark = v),
                        ),
                        const SizedBox(height: 4),
                        GlassToggleRow(
                          label: 'Notifications',
                          description: 'Allow alerts about new activity.',
                          value: _switchOn,
                          onChanged: (v) => setState(() => _switchOn = v),
                        ),
                        const SizedBox(height: 4),
                        GlassToggleRow(
                          label: 'Nav: slide indicator',
                          value: _animateIndicator,
                          onChanged: (v) =>
                              setState(() => _animateIndicator = v),
                        ),
                        const SizedBox(height: 4),
                        GlassToggleRow(
                          label: 'Nav: bounce icon',
                          value: _animateBounce,
                          onChanged: (v) => setState(() => _animateBounce = v),
                        ),
                        const SizedBox(height: 4),
                        GlassToggleRow(
                          label: 'Nav: show labels',
                          value: _showLabels,
                          onChanged: (v) => setState(() => _showLabels = v),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),
                  GlassButton(
                    label: 'Filled action',
                    icon: Icons.arrow_forward_rounded,
                    variant: GlassButtonVariant.filled,
                    expand: true,
                    onPressed: () {},
                  ),
                  const SizedBox(height: 12),
                  GlassButton(
                    label: 'Glass action',
                    variant: GlassButtonVariant.glass,
                    expand: true,
                    onPressed: () {},
                  ),
                  const SizedBox(height: 12),
                  Center(
                    child: GlassButton(
                      label: 'Plain action',
                      variant: GlassButtonVariant.plain,
                      onPressed: () {},
                    ),
                  ),
                  const SizedBox(height: 24),
                  GlassButton(
                    label: 'Bottom sheet',
                    icon: Icons.vertical_align_bottom_rounded,
                    variant: GlassButtonVariant.glass,
                    expand: true,
                    onPressed: () => _openSheet(context),
                  ),
                  const SizedBox(height: 12),
                  GlassButton(
                    label: 'Popup dialog',
                    icon: Icons.chat_bubble_outline_rounded,
                    variant: GlassButtonVariant.glass,
                    expand: true,
                    onPressed: () => _openDialog(context),
                  ),
                  const SizedBox(height: 12),
                  Builder(
                    builder: (buttonContext) => GlassButton(
                      label: 'Action menu',
                      icon: Icons.more_horiz_rounded,
                      variant: GlassButtonVariant.glass,
                      expand: true,
                      onPressed: () => _openMenu(buttonContext),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

/// A simple colorful gradient so the glass blur is visible.
class _Backdrop extends StatelessWidget {
  const _Backdrop();

  @override
  Widget build(BuildContext context) {
    return const DecoratedBox(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: [
            Color(0xFF3A1C71),
            Color(0xFFD76D77),
            Color(0xFF2E8B8B),
          ],
        ),
      ),
    );
  }
}
1
likes
160
points
64
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

An accessible, customizable Liquid Glass design system for Flutter with translucent themes and ready-made widgets for mobile, web, and desktop.

Repository (GitHub)
View/report issues

Topics

#ui #theme #glassmorphism #ios #cupertino

License

MIT (license)

Dependencies

flutter

More

Packages that depend on liquid_glass_ui_kit