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

A modern Flutter UI package with beautiful, customizable components

example/lib/main.dart

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hux UI Demo',
      theme: HuxTheme.lightTheme,
      darkTheme: HuxTheme.darkTheme,
      themeMode: ThemeMode.system,
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _scrollController = ScrollController();
  bool _isLoading = false;
  
  // Theme state
  String _selectedTheme = 'white';
  Color get _currentPrimaryColor => HuxColors.getPresetColor(_selectedTheme);
  
  // Button size state
  HuxButtonSize _selectedButtonSize = HuxButtonSize.medium;
  
  // Global keys for each section
  final _buttonsKey = GlobalKey();
  final _textFieldsKey = GlobalKey();
  final _cardsKey = GlobalKey();
  final _chartsKey = GlobalKey();
  final _loadingKey = GlobalKey();

  // Navigation items
  late final List<NavigationItem> _navigationItems;

  @override
  void initState() {
    super.initState();
    _navigationItems = [
      NavigationItem(
        title: 'Buttons',
        icon: Icons.smart_button,
        key: _buttonsKey,
      ),
      NavigationItem(
        title: 'Text Fields',
        icon: Icons.text_fields,
        key: _textFieldsKey,
      ),
      NavigationItem(
        title: 'Cards',
        icon: Icons.credit_card,
        key: _cardsKey,
      ),
      NavigationItem(
        title: 'Charts',
        icon: Icons.analytics,
        key: _chartsKey,
      ),
      NavigationItem(
        title: 'Loading',
        icon: Icons.refresh,
        key: _loadingKey,
      ),
    ];
  }

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  void _scrollToSection(GlobalKey key) {
    final context = key.currentContext;
    if (context != null) {
      Scrollable.ensureVisible(
        context,
        duration: const Duration(milliseconds: 800),
        curve: Curves.easeInOut,
      );
    }
  }

  void _toggleLoading() {
    setState(() {
      _isLoading = !_isLoading;
    });
    
    if (_isLoading) {
      Future.delayed(const Duration(seconds: 2), () {
        if (mounted) {
          setState(() {
            _isLoading = false;
          });
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          // Left Navigation Sidebar
          Container(
            width: 250,
            decoration: BoxDecoration(
              color: Theme.of(context).brightness == Brightness.dark 
                  ? HuxColors.black90 
                  : HuxColors.white,
              border: Border(
                right: BorderSide(
                  color: Theme.of(context).brightness == Brightness.dark 
                      ? HuxColors.white20 
                      : HuxColors.black20,
                ),
              ),
            ),
            child: Column(
              children: [
                // Header
                Container(
                  padding: const EdgeInsets.all(16),
                  decoration: BoxDecoration(
                    border: Border(
                      bottom: BorderSide(
                        color: Theme.of(context).brightness == Brightness.dark 
                            ? HuxColors.white20 
                            : HuxColors.black20,
                      ),
                    ),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Hux UI',
                        style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                          fontWeight: FontWeight.bold,
                          color: Theme.of(context).brightness == Brightness.dark 
                              ? HuxColors.white 
                              : HuxColors.black,
                        ),
                      ),
                      const SizedBox(height: 4),
                      Text(
                        'Component Library',
                        style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                          color: Theme.of(context).brightness == Brightness.dark 
                              ? HuxColors.white60 
                              : HuxColors.black60,
                        ),
                      ),
                    ],
                  ),
                                 ),
                 
                 // Theme Selector
                 Container(
                   padding: const EdgeInsets.all(16),
                   decoration: BoxDecoration(
                     border: Border(
                       bottom: BorderSide(
                         color: Theme.of(context).brightness == Brightness.dark 
                             ? HuxColors.white20 
                             : HuxColors.black20,
                       ),
                     ),
                   ),
                   child: Column(
                     crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                       Text(
                         'Button Theme',
                         style: Theme.of(context).textTheme.labelMedium?.copyWith(
                           fontWeight: FontWeight.w600,
                           color: Theme.of(context).brightness == Brightness.dark 
                               ? HuxColors.white80 
                               : HuxColors.black80,
                         ),
                       ),
                       const SizedBox(height: 8),
                       Container(
                         width: double.infinity,
                         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                         decoration: BoxDecoration(
                           color: Theme.of(context).brightness == Brightness.dark 
                               ? HuxColors.black70 
                               : HuxColors.white5,
                           borderRadius: BorderRadius.circular(8),
                           border: Border.all(
                             color: Theme.of(context).brightness == Brightness.dark 
                                 ? HuxColors.white20 
                                 : HuxColors.black20,
                           ),
                         ),
                         child: DropdownButtonHideUnderline(
                           child: DropdownButton<String>(
                             value: _selectedTheme,
                             isExpanded: true,
                             dropdownColor: Theme.of(context).brightness == Brightness.dark 
                                 ? HuxColors.black80 
                                 : HuxColors.white,
                             style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                               color: Theme.of(context).brightness == Brightness.dark 
                                   ? HuxColors.white80 
                                   : HuxColors.black80,
                             ),
                             icon: Icon(
                               Icons.keyboard_arrow_down,
                               color: Theme.of(context).brightness == Brightness.dark 
                                   ? HuxColors.white60 
                                   : HuxColors.black60,
                             ),
                             onChanged: (String? newValue) {
                               if (newValue != null) {
                                 setState(() {
                                   _selectedTheme = newValue;
                                 });
                               }
                             },
                             items: HuxColors.availablePresetColors.map<DropdownMenuItem<String>>((String colorName) {
                               final color = HuxColors.getPresetColor(colorName);
                               return DropdownMenuItem<String>(
                                 value: colorName,
                                 child: Row(
                                   children: [
                                     Container(
                                       width: 16,
                                       height: 16,
                                       decoration: BoxDecoration(
                                         color: color,
                                         borderRadius: BorderRadius.circular(4),
                                         border: Border.all(
                                           color: Theme.of(context).brightness == Brightness.dark 
                                               ? HuxColors.white30 
                                               : HuxColors.black30,
                                           width: 0.5,
                                         ),
                                       ),
                                     ),
                                     const SizedBox(width: 8),
                                     Text(
                                       colorName[0].toUpperCase() + colorName.substring(1),
                                       style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                                         color: Theme.of(context).brightness == Brightness.dark 
                                             ? HuxColors.white80 
                                             : HuxColors.black80,
                                       ),
                                     ),
                                   ],
                                 ),
                               );
                             }).toList(),
                           ),
                         ),
                       ),
                     ],
                   ),
                 ),
                 
                 // Navigation Items
                 Expanded(
                  child: ListView.builder(
                    padding: const EdgeInsets.symmetric(vertical: 16),
                    itemCount: _navigationItems.length,
                    itemBuilder: (context, index) {
                      final item = _navigationItems[index];
                      return Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
                        child: Material(
                          color: Colors.transparent,
                          child: InkWell(
                            borderRadius: BorderRadius.circular(8),
                            onTap: () => _scrollToSection(item.key),
                            child: Container(
                              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(8),
                              ),
                              child: Row(
                                children: [
                                  Icon(
                                    item.icon,
                                    size: 20,
                                    color: Theme.of(context).brightness == Brightness.dark 
                                        ? HuxColors.white70 
                                        : HuxColors.black70,
                                  ),
                                  const SizedBox(width: 12),
                                  Text(
                                    item.title,
                                    style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                                      fontWeight: FontWeight.w500,
                                      color: Theme.of(context).brightness == Brightness.dark 
                                          ? HuxColors.white70 
                                          : HuxColors.black70,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
          
          // Main Content Area
          Expanded(
            child: HuxLoadingOverlay(
              isLoading: _isLoading,
              message: 'Processing...',
              child: SingleChildScrollView(
                controller: _scrollController,
                padding: const EdgeInsets.all(32),
                child: Form(
                  key: _formKey,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      // Buttons Section
                      Container(
                        key: _buttonsKey,
                                                 child: HuxCard(
                           title: 'Buttons',
                           subtitle: 'Different button variants and sizes',
                           child: Column(
                             children: [
                               const SizedBox(height: 16),
                               
                               // Size Selector Tabs
                               Container(
                                 decoration: BoxDecoration(
                                   color: Theme.of(context).brightness == Brightness.dark 
                                       ? HuxColors.black70 
                                       : HuxColors.white5,
                                   borderRadius: BorderRadius.circular(8),
                                   border: Border.all(
                                     color: Theme.of(context).brightness == Brightness.dark 
                                         ? HuxColors.white20 
                                         : HuxColors.black20,
                                   ),
                                 ),
                                 child: Row(
                                   children: [
                                     Expanded(
                                       child: _buildSizeTab('Small', HuxButtonSize.small),
                                     ),
                                     Expanded(
                                       child: _buildSizeTab('Medium', HuxButtonSize.medium),
                                     ),
                                     Expanded(
                                       child: _buildSizeTab('Large', HuxButtonSize.large),
                                     ),
                                   ],
                                 ),
                               ),
                               
                               const SizedBox(height: 20),
                               
                               // Button Variants - Fixed Height Container
                               SizedBox(
                                 height: 48, // Fixed height to prevent layout shifts
                                 child: Center(
                                   child: Wrap(
                                     spacing: 12,
                                     runSpacing: 12,
                                     children: [
                                       HuxButton(
                                         onPressed: () => _showSnackBar('Primary pressed'),
                                         primaryColor: _currentPrimaryColor,
                                         size: _selectedButtonSize,
                                         child: const Text('Primary'),
                                       ),
                                       HuxButton(
                                         onPressed: () => _showSnackBar('Secondary pressed'),
                                         variant: HuxButtonVariant.secondary,
                                         size: _selectedButtonSize,
                                         child: const Text('Secondary'),
                                       ),
                                       HuxButton(
                                         onPressed: () => _showSnackBar('Outline pressed'),
                                         variant: HuxButtonVariant.outline,
                                         size: _selectedButtonSize,
                                         child: const Text('Outline'),
                                       ),
                                       HuxButton(
                                         onPressed: () => _showSnackBar('Ghost pressed'),
                                         variant: HuxButtonVariant.ghost,
                                         size: _selectedButtonSize,
                                         child: const Text('Ghost'),
                                       ),
                                     ],
                                   ),
                                 ),
                               ),
                               
                               const SizedBox(height: 16),
                               const Divider(),
                               const SizedBox(height: 16),
                               
                               // With Icon Example - Fixed Height Container
                               SizedBox(
                                 height: 48, // Fixed height to prevent layout shifts
                                 child: Center(
                                   child: HuxButton(
                                     onPressed: _toggleLoading,
                                     primaryColor: _currentPrimaryColor,
                                     size: _selectedButtonSize,
                                     icon: FeatherIcons.upload,
                                     child: const Text('With Icon'),
                                   ),
                                 ),
                               ),
                             ],
                           ),
                         ),
                      ),
                      
                      const SizedBox(height: 32),
                      
                      // Text Fields Section
                      Container(
                        key: _textFieldsKey,
                        child: HuxCard(
                          title: 'Text Fields',
                          subtitle: 'Input components with validation',
                          child: Column(
                            children: [
                              const SizedBox(height: 16),
                              HuxTextField(
                                controller: _emailController,
                                label: 'Email',
                                hint: 'Enter your email address',
                                prefixIcon: const Icon(FeatherIcons.mail),
                                keyboardType: TextInputType.emailAddress,
                                validator: (value) {
                                  if (value == null || value.isEmpty) {
                                    return 'Please enter your email';
                                  }
                                  if (!value.contains('@')) {
                                    return 'Please enter a valid email';
                                  }
                                  return null;
                                },
                              ),
                              const SizedBox(height: 16),
                              HuxTextField(
                                controller: _passwordController,
                                label: 'Password',
                                hint: 'Enter your password',
                                prefixIcon: const Icon(FeatherIcons.lock),
                                suffixIcon: const Icon(FeatherIcons.eye),
                                obscureText: true,
                                validator: (value) {
                                  if (value == null || value.isEmpty) {
                                    return 'Please enter your password';
                                  }
                                  if (value.length < 6) {
                                    return 'Password must be at least 6 characters';
                                  }
                                  return null;
                                },
                              ),
                              const SizedBox(height: 16),
                              const Row(
                                children: [
                                  Expanded(
                                    child: HuxTextField(
                                      label: 'Small',
                                      size: HuxTextFieldSize.small,
                                      hint: 'Small text field',
                                    ),
                                  ),
                                  SizedBox(width: 8),
                                  Expanded(
                                    child: HuxTextField(
                                      label: 'Large',
                                      size: HuxTextFieldSize.large,
                                      hint: 'Large text field',
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                      
                      const SizedBox(height: 32),
                      
                      // Cards Section  
                      Container(
                        key: _cardsKey,
                        child: const HuxCard(
                          title: 'Cards',
                          subtitle: 'Container components for content organization',
                          child: Column(
                            children: [
                              SizedBox(height: 16),
                              Row(
                                children: [
                                  Expanded(
                                    child: HuxCard(
                                      title: 'Simple Card',
                                      child: Text('This is a simple card with just a title and content.'),
                                    ),
                                  ),
                                  SizedBox(width: 16),
                                  Expanded(
                                    child: HuxCard(
                                      title: 'Card with Subtitle',
                                      subtitle: 'This card has both title and subtitle',
                                      child: Text('Cards can have optional subtitles for additional context.'),
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                      
                      const SizedBox(height: 32),
                      
                      // Charts Section
                      Container(
                        key: _chartsKey,
                        child: HuxCard(
                          title: 'Charts',
                          subtitle: 'Data visualization with cristalyse',
                          child: Column(
                            children: [
                              const SizedBox(height: 16),
                              
                              // Sample chart data
                              Row(
                                children: [
                                  Expanded(
                                    child: HuxChart(
                                      data: _getSampleLineData(),
                                      type: HuxChartType.line,
                                      xField: 'day',
                                      yField: 'calories',
                                      title: 'Daily Calories',
                                      subtitle: 'Calorie tracking over time',
                                      size: HuxChartSize.small,
                                      primaryColor: _currentPrimaryColor,
                                    ),
                                  ),
                                  const SizedBox(width: 16),
                                  Expanded(
                                    child: HuxChart(
                                      data: _getSampleBarData(),
                                      type: HuxChartType.bar,
                                      xField: 'product',
                                      yField: 'revenue',
                                      title: 'Product Revenue',
                                      subtitle: 'Revenue by product',
                                      size: HuxChartSize.small,
                                      primaryColor: _currentPrimaryColor,
                                    ),
                                  ),
                                ],
                              ),
                              

                            ],
                          ),
                        ),
                      ),
                      
                      const SizedBox(height: 32),
                      
                      // Loading Section
                      Container(
                        key: _loadingKey,
                        child: HuxCard(
                          title: 'Loading Indicators',
                          subtitle: 'Different loading states and sizes',
                          child: Column(
                            children: [
                              const SizedBox(height: 16),
                              const Row(
                                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                children: [
                                  Column(
                                    children: [
                                      HuxLoading(size: HuxLoadingSize.small),
                                      SizedBox(height: 8),
                                      Text('Small'),
                                    ],
                                  ),
                                  Column(
                                    children: [
                                      HuxLoading(size: HuxLoadingSize.medium),
                                      SizedBox(height: 8),
                                      Text('Medium'),
                                    ],
                                  ),
                                  Column(
                                    children: [
                                      HuxLoading(size: HuxLoadingSize.large),
                                      SizedBox(height: 8),
                                      Text('Large'),
                                    ],
                                  ),
                                  Column(
                                    children: [
                                      HuxLoading(size: HuxLoadingSize.extraLarge),
                                      SizedBox(height: 8),
                                      Text('XL'),
                                    ],
                                  ),
                                ],
                              ),
                              const SizedBox(height: 16),
                              HuxButton(
                                onPressed: _toggleLoading,
                                variant: HuxButtonVariant.outline,
                                child: Text(_isLoading ? 'Stop Loading' : 'Show Loading Overlay'),
                              ),
                            ],
                          ),
                        ),
                      ),
                      
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  // Sample data generators for charts
  List<Map<String, dynamic>> _getSampleLineData() {
    return [
      {'day': 1, 'calories': 520, 'type': 'Daily Goal'},
      {'day': 2, 'calories': 480, 'type': 'Daily Goal'},
      {'day': 3, 'calories': 440, 'type': 'Daily Goal'},
      {'day': 4, 'calories': 580, 'type': 'Daily Goal'},
      {'day': 5, 'calories': 520, 'type': 'Daily Goal'},
      {'day': 6, 'calories': 610, 'type': 'Daily Goal'},
      {'day': 7, 'calories': 490, 'type': 'Daily Goal'},
      {'day': 8, 'calories': 550, 'type': 'Daily Goal'},
      {'day': 9, 'calories': 580, 'type': 'Daily Goal'},
      {'day': 10, 'calories': 470, 'type': 'Daily Goal'},
      {'day': 11, 'calories': 620, 'type': 'Daily Goal'},
      {'day': 12, 'calories': 540, 'type': 'Daily Goal'},
      {'day': 13, 'calories': 510, 'type': 'Daily Goal'},
      {'day': 14, 'calories': 590, 'type': 'Daily Goal'},
    ];
  }

  List<Map<String, dynamic>> _getSampleBarData() {
    return [
      {'product': 'Mobile', 'revenue': 450},
      {'product': 'Tablet', 'revenue': 320},
      {'product': 'Laptop', 'revenue': 580},
      {'product': 'Desktop', 'revenue': 290},
      {'product': 'Watch', 'revenue': 180},
    ];
  }



  void _showSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        behavior: SnackBarBehavior.floating,
      ),
    );
  }

  Widget _buildSizeTab(String label, HuxButtonSize size) {
    final isSelected = _selectedButtonSize == size;
    
    return GestureDetector(
      onTap: () {
        setState(() {
          _selectedButtonSize = size;
        });
      },
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
        decoration: BoxDecoration(
          color: isSelected 
              ? (Theme.of(context).brightness == Brightness.dark 
                  ? HuxColors.white20 
                  : HuxColors.black10)
              : Colors.transparent,
          borderRadius: BorderRadius.circular(4),
        ),
        child: Center(
          child: Text(
            label,
            style: Theme.of(context).textTheme.bodySmall?.copyWith(
              fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500,
              color: isSelected 
                  ? (Theme.of(context).brightness == Brightness.dark 
                      ? HuxColors.white 
                      : HuxColors.black)
                  : (Theme.of(context).brightness == Brightness.dark 
                      ? HuxColors.white60 
                      : HuxColors.black60),
            ),
          ),
        ),
      ),
    );
  }
}

class NavigationItem {
  final String title;
  final IconData icon;
  final GlobalKey key;

  NavigationItem({
    required this.title,
    required this.icon,
    required this.key,
  });
}
51
likes
0
points
820
downloads

Publisher

verified publisherthehuxdesign.com

Weekly Downloads

A modern Flutter UI package with beautiful, customizable components

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

cristalyse, flutter, flutter_feather_icons, google_fonts

More

Packages that depend on hux