Skip to main content

liquidify 0.1.0 copy "liquidify: ^0.1.0" to clipboard
liquidify: ^0.1.0 copied to clipboard

PlatformiOSmacOS

Seamless Liquid Glass extension for standard Flutter widgets. Transform standard Material & Cupertino widgets into Apple-style Liquid Glass with .liquidGlass().

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:liquidify/liquidify.dart';

void main() {
  runApp(const LiquidifyExampleApp());
}

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

  @override
  State<LiquidifyExampleApp> createState() => _LiquidifyExampleAppState();
}

class _LiquidifyExampleAppState extends State<LiquidifyExampleApp> {
  ThemeMode _themeMode = ThemeMode.dark;
  bool _forceLiquidGlass = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Liquidify Showcase',
      debugShowCheckedModeBanner: false,
      themeMode: _themeMode,
      theme: ThemeData(
        brightness: Brightness.light,
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF007AFF),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF0A84FF),
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      home: LiquidifyShowcaseScreen(
        isDarkMode: _themeMode == ThemeMode.dark,
        forceGlass: _forceLiquidGlass,
        onToggleTheme: () {
          setState(() {
            _themeMode = _themeMode == ThemeMode.dark
                ? ThemeMode.light
                : ThemeMode.dark;
          });
        },
        onToggleForce: (val) {
          setState(() {
            _forceLiquidGlass = val;
          });
        },
      ),
    );
  }
}

class LiquidifyShowcaseScreen extends StatefulWidget {
  final bool isDarkMode;
  final bool forceGlass;
  final VoidCallback onToggleTheme;
  final ValueChanged<bool> onToggleForce;

  const LiquidifyShowcaseScreen({
    super.key,
    required this.isDarkMode,
    required this.forceGlass,
    required this.onToggleTheme,
    required this.onToggleForce,
  });

  @override
  State<LiquidifyShowcaseScreen> createState() =>
      _LiquidifyShowcaseScreenState();
}

class _LiquidifyShowcaseScreenState extends State<LiquidifyShowcaseScreen> {
  int _currentIndex = 0;
  bool _switchValue = true;
  double _sliderValue = 65.0;
  Set<int> _selectedSegment = {0};
  final TextEditingController _textController = TextEditingController(
    text: 'Steve Jobs',
  );

  @override
  void dispose() {
    _textController.dispose();
    super.dispose();
  }

  void _showLiquidDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Liquid Glass Dialog'),
        content: const Text(
          'This dialog was converted smoothly using .liquidGlass() without changing any constructor properties!',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Cancel'),
          ).liquidGlass(),
          ElevatedButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Confirm'),
          ).liquidGlass(
            options: LiquidGlassOptions(
              force: widget.forceGlass,
              tint: const Color(0xFF007AFF).withValues(alpha: 0.35),
            ),
          ),
        ],
      ).liquidGlass(options: LiquidGlassOptions(force: widget.forceGlass)),
    );
  }

  @override
  Widget build(BuildContext context) {
    final opts = LiquidGlassOptions(force: widget.forceGlass);

    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        title: const Text(
          'Liquidify',
          style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: -0.5),
        ),
        actions: [
          IconButton(
            icon: Icon(widget.isDarkMode ? Icons.light_mode : Icons.dark_mode),
            tooltip: 'Toggle Theme',
            onPressed: widget.onToggleTheme,
          ).liquidGlass(options: opts),
          const SizedBox(width: 8.0),
        ],
      ).liquidGlass(options: opts),
      body: Stack(
        children: [
          // Background rich decorative gradient bubbles to highlight frosted glass
          Positioned.fill(
            child: Container(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: widget.isDarkMode
                      ? [
                          const Color(0xFF0F172A),
                          const Color(0xFF1E1B4B),
                          const Color(0xFF311042),
                        ]
                      : [
                          const Color(0xFFE0E7FF),
                          const Color(0xFFFCE7F3),
                          const Color(0xFFFEF3C7),
                        ],
                ),
              ),
            ),
          ),
          Positioned(
            top: 100,
            left: -40,
            child: Container(
              width: 250,
              height: 250,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                gradient: RadialGradient(
                  colors: [
                    const Color(0xFF6366F1).withValues(alpha: 0.6),
                    Colors.transparent,
                  ],
                ),
              ),
            ),
          ),
          Positioned(
            bottom: 140,
            right: -50,
            child: Container(
              width: 300,
              height: 300,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                gradient: RadialGradient(
                  colors: [
                    const Color(0xFFEC4899).withValues(alpha: 0.5),
                    Colors.transparent,
                  ],
                ),
              ),
            ),
          ),

          // Main scrollable content
          SafeArea(
            bottom: false,
            child: ListView(
              padding: const EdgeInsets.fromLTRB(20.0, 16.0, 20.0, 120.0),
              children: [
                // Quick settings card
                Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            const Text(
                              'Force Liquid Glass',
                              style: TextStyle(
                                fontWeight: FontWeight.w600,
                                fontSize: 16.0,
                              ),
                            ),
                            Switch(
                              value: widget.forceGlass,
                              onChanged: widget.onToggleForce,
                            ).liquidGlass(options: opts),
                          ],
                        ),
                        const SizedBox(height: 8.0),
                        Text(
                          'When active, forces Apple Liquid Glass rendering on Android, Web, and Desktop.',
                          style: TextStyle(
                            fontSize: 13.0,
                            color: Theme.of(
                              context,
                            ).colorScheme.onSurface.withValues(alpha: 0.6),
                          ),
                        ),
                      ],
                    ),
                  ),
                ).liquidGlass(options: opts),

                const SizedBox(height: 18.0),

                // Search Bar
                SearchBar(
                  hintText: 'Search liquid components...',
                  leading: const Icon(Icons.search),
                ).liquidGlass(options: opts),

                const SizedBox(height: 18.0),

                // Segmented Button
                Center(
                  child: SegmentedButton<int>(
                    segments: const [
                      ButtonSegment(value: 0, label: Text('Frosted')),
                      ButtonSegment(value: 1, label: Text('Crystal')),
                      ButtonSegment(value: 2, label: Text('Smoke')),
                    ],
                    selected: _selectedSegment,
                    onSelectionChanged: (val) {
                      setState(() => _selectedSegment = val);
                    },
                  ).liquidGlass(options: opts),
                ),

                const SizedBox(height: 24.0),

                // Input Field
                TextField(
                  controller: _textController,
                  decoration: const InputDecoration(
                    labelText: 'User Name',
                    prefixIcon: Icon(Icons.person_outline),
                  ),
                ).liquidGlass(options: opts),

                const SizedBox(height: 24.0),

                // Sliders & Controls Card
                Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            const Text(
                              'Glass Fluidity',
                              style: TextStyle(fontWeight: FontWeight.w600),
                            ),
                            Text('${_sliderValue.toInt()}%'),
                          ],
                        ),
                        const SizedBox(height: 8.0),
                        Slider(
                          value: _sliderValue,
                          min: 0,
                          max: 100,
                          divisions: 100,
                          onChanged: (val) =>
                              setState(() => _sliderValue = val),
                        ).liquidGlass(options: opts),
                        const Divider(height: 28.0),
                        SwitchListTile(
                          title: const Text('Dynamic Haptics'),
                          subtitle: const Text(
                            'Subtle micro-feedback on touch',
                          ),
                          value: _switchValue,
                          onChanged: (val) =>
                              setState(() => _switchValue = val),
                        ).liquidGlass(options: opts),
                      ],
                    ),
                  ),
                ).liquidGlass(options: opts),

                const SizedBox(height: 24.0),

                // Chips Row
                Wrap(
                  spacing: 8.0,
                  runSpacing: 8.0,
                  children: [
                    Chip(
                      avatar: const Icon(Icons.star, size: 16.0),
                      label: const Text('Featured'),
                    ).liquidGlass(options: opts),
                    FilterChip(
                      label: const Text('Interactive'),
                      selected: true,
                      onSelected: (_) {},
                    ).liquidGlass(options: opts),
                    ActionChip(
                      avatar: const Icon(Icons.open_in_new, size: 16.0),
                      label: const Text('Dialog Demo'),
                      onPressed: () => _showLiquidDialog(context),
                    ).liquidGlass(options: opts),
                  ],
                ),

                const SizedBox(height: 24.0),

                // Buttons Row
                Row(
                  children: [
                    Expanded(
                      child: ElevatedButton(
                        onPressed: () => _showLiquidDialog(context),
                        child: const Text('Open Dialog'),
                      ).liquidGlass(options: opts),
                    ),
                    const SizedBox(width: 12.0),
                    Expanded(
                      child: FilledButton(
                        onPressed: () {},
                        child: const Text('Save Action'),
                      ).liquidGlass(options: opts),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) => setState(() => _currentIndex = index),
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.widgets_outlined),
            activeIcon: Icon(Icons.widgets),
            label: 'Showcase',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.palette_outlined),
            activeIcon: Icon(Icons.palette),
            label: 'Styles',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings_outlined),
            activeIcon: Icon(Icons.settings),
            label: 'Settings',
          ),
        ],
      ).liquidGlass(options: opts),
    );
  }
}
7
likes
150
points
612
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Seamless Liquid Glass extension for standard Flutter widgets. Transform standard Material & Cupertino widgets into Apple-style Liquid Glass with .liquidGlass().

Repository (GitHub)
View/report issues

Topics

#ui #glassmorphism #liquid-glass #ios #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on liquidify

Packages that implement liquidify