DEV Community

Zoe
Zoe

Posted on

Building modern Flutter UIs with Hux: A comprehensive guide to Hux widgets

Hux UI is a modern Flutter package that provides a comprehensive set of beautifully designed, accessible, and customizable widgets.

In this technical deep-dive, we'll explore every widget in the Hux ecosystem, their implementation details, and how to leverage them in your Flutter applications.

Table of Contents

  1. Architecture & Design Philosophy
  2. Buttons
  3. Input Components
  4. Cards & Containers
  5. Navigation Components
  6. Feedback & Status
  7. Data Visualization
  8. Overlays & Dialogs
  9. Utility Components
  10. Theming System

Architecture & Design Philosophy

Hux UI is built on three core principles:

1. Design Token System

Hux uses a sophisticated token-based theming system via HuxTokens that provides semantic color values. These tokens automatically adapt to light/dark themes and respect custom Material 3 seed colors:

// Tokens automatically adapt to theme
HuxTokens.primary(context)          // Primary color (respects seed colors)
HuxTokens.surfacePrimary(context)   // Surface colors
HuxTokens.borderPrimary(context)    // Border colors
HuxTokens.textPrimary(context)      // Text colors
Enter fullscreen mode Exit fullscreen mode

2. WCAG AA Accessibility

All components meet WCAG 2.1 AA contrast requirements. The HuxWCAG utility class centralizes contrast calculations:

HuxWCAG.getContrastingTextColor(
  backgroundColor: myColor,
  context: context,
)
Enter fullscreen mode Exit fullscreen mode

3. Material 3 Integration

Hux seamlessly integrates with Flutter's Material 3 design system, supporting custom seed colors while maintaining backward compatibility.

Buttons

HuxButton

The HuxButton widget is one of the most feature-rich components in Hux, supporting multiple variants, sizes, and states.

Variants:

  • primary - Solid button with primary color background
  • secondary - Solid button with secondary styling
  • outline - Transparent background with border
  • ghost - Transparent background, no border

Sizes:

  • small - 32px height, compact padding
  • medium - 40px height, standard padding (default)
  • large - 48px height, generous padding

Width Behaviors:

  • hug - Adapts to content (default)
  • expand - Fills available width
  • fixed - Specific width via widthValue

Technical Implementation:

  • Theme-aware colors: Automatically uses HuxTokens.primary(context) or custom primaryColor
  • WCAG-compliant text: Automatically calculates contrasting text color
  • Custom hover effects: Uses HuxTokens.surfaceHover(context) for hover states
  • Icon support: Supports prefix icons with proper spacing
  • Loading states: Shows CircularProgressIndicator when isLoading is true
  • Icon-only mode: Square buttons when using icon with zero-width child
HuxButton(
  onPressed: () => print('Clicked'),
  variant: HuxButtonVariant.primary,
  size: HuxButtonSize.medium,
  width: HuxButtonWidth.expand,
  icon: LucideIcons.save,
  isLoading: false,
  primaryColor: Colors.deepOrange, // Optional custom color
  child: Text('Save Changes'),
)
Enter fullscreen mode Exit fullscreen mode

Input Components

HuxInput

Enhanced text input with consistent styling, validation support, and theme adaptation.

Features:

  • Automatic theme adaptation (light/dark)
  • Built-in validation support
  • Prefix and suffix icon support
  • Helper and error text
  • Consistent 40px height across all sizes
  • Customizable icon sizes and widths

Implementation Details:

The component uses Flutter's TextFormField with custom InputDecoration. It maintains consistent padding (18px horizontal, 12px vertical) and uses HuxTokens for all color values:

HuxInput(
  label: 'Email Address',
  hint: 'Enter your email',
  prefixIcon: Icon(LucideIcons.mail),
  keyboardType: TextInputType.emailAddress,
  validator: (value) {
    if (value?.isEmpty ?? true) return 'Email is required';
    if (!value!.contains('@')) return 'Invalid email format';
    return null;
  },
  onChanged: (value) => print('Email: $value'),
)
Enter fullscreen mode Exit fullscreen mode

HuxDateInput

Specialized date input with automatic formatting and integrated calendar picker.

Features:

  • Automatic date formatting (MM/DD/YYYY)
  • Integrated date picker dialog
  • Input validation
  • Theme-aware styling
HuxDateInput(
  label: 'Birth Date',
  initialDate: DateTime.now(),
  firstDate: DateTime(1900),
  lastDate: DateTime.now(),
  onDateSelected: (date) => print('Selected: $date'),
)
Enter fullscreen mode Exit fullscreen mode

HuxCheckbox

Interactive checkbox with custom styling, labels, and validation support.

Features:

  • Multiple sizes (small, medium, large)
  • Label and helper text support
  • Error state handling
  • WCAG AA compliant contrast ratios
  • Custom checkmark colors
HuxCheckbox(
  label: 'I agree to the terms',
  helperText: 'Required to continue',
  value: isChecked,
  onChanged: (value) => setState(() => isChecked = value!),
  size: HuxCheckboxSize.medium,
)
Enter fullscreen mode Exit fullscreen mode

HuxRadio

Radio button controls for single selection from groups, with support for different value types.

Features:

  • Consistent sizing across theme changes
  • Theme adaptation
  • Support for any value type (String, int, custom objects)
  • Grouped selection management
HuxRadio<String>(
  value: 'option1',
  groupValue: selectedValue,
  onChanged: (value) => setState(() => selectedValue = value),
  label: 'Option 1',
)
Enter fullscreen mode Exit fullscreen mode

HuxSwitch

Toggle switch with smooth animations between on/off states.

Features:

  • Smooth animation transitions
  • Theme-aware colors
  • Disabled state support
  • Custom on/off colors
HuxSwitch(
  value: isEnabled,
  onChanged: (value) => setState(() => isEnabled = value),
  label: 'Enable notifications',
)
Enter fullscreen mode Exit fullscreen mode

HuxToggle

Toggle button group for selecting multiple options or a single option from a set.

Features:

  • Single and multiple selection modes
  • Customizable sizes
  • Theme integration
  • Icon and text support
HuxToggle(
  options: ['Option A', 'Option B', 'Option C'],
  selectedOptions: ['Option A'],
  onSelectionChanged: (selected) => print(selected),
  allowMultiple: true,
)
Enter fullscreen mode Exit fullscreen mode

Cards & Containers

HuxCard

Flexible card component with optional header, title, subtitle, and action buttons.

Features:

  • Customizable padding and margins
  • Optional title, subtitle, and actions
  • Tap handling support
  • Theme-aware borders and backgrounds
  • Border radius: 12px

Technical Implementation:

Uses Card widget with custom styling. Background colors use HuxTokens.surfacePrimary(context) and borders use HuxTokens.borderPrimary(context).

HuxCard(
  title: 'Card Title',
  subtitle: 'Card subtitle with additional info',
  action: IconButton(
    icon: Icon(LucideIcons.moreVertical),
    onPressed: () => {},
  ),
  child: Text('Card content goes here'),
  onTap: () => print('Card tapped'),
)
Enter fullscreen mode Exit fullscreen mode

Navigation Components

HuxTabs

Organize content into multiple panels with tab navigation. Three visual variants:

  1. Default - Underline indicator
  2. Pill - Background indicator
  3. Minimal - No indicator

Features:

  • Icons, badges, and custom content support
  • Multiple sizes (small, medium, large)
  • Scrollable tabs for mobile
  • Full accessibility support
  • Built-in theme integration

Implementation:

Uses Flutter's TabController with custom tab bar styling. Tab tokens include:

  • tabActiveBackground / tabInactiveBackground
  • tabActiveText / tabInactiveText
  • tabHoverBackground
  • tabIndicator
HuxTabs(
  variant: HuxTabsVariant.pill,
  size: HuxTabsSize.medium,
  tabs: [
    HuxTab(label: 'Home', icon: LucideIcons.home),
    HuxTab(label: 'Settings', icon: LucideIcons.settings),
  ],
  children: [
    HomeView(),
    SettingsView(),
  ],
)
Enter fullscreen mode Exit fullscreen mode

HuxSidebar

Complete navigation sidebar component for app-wide navigation.

Features:

  • HuxSidebarItem with automatic selection state
  • Optional header and footer sections
  • Customizable width and padding
  • Theme-aware styling with hover states
  • Perfect for dashboard applications
HuxSidebar(
  header: Text('My App'),
  items: [
    HuxSidebarItem(
      label: 'Dashboard',
      icon: LucideIcons.layoutDashboard,
      onTap: () => navigate('/dashboard'),
    ),
    HuxSidebarItem(
      label: 'Settings',
      icon: LucideIcons.settings,
      onTap: () => navigate('/settings'),
    ),
  ],
  footer: HuxSidebarItem(
    label: 'Logout',
    icon: LucideIcons.logOut,
    onTap: () => logout(),
  ),
)
Enter fullscreen mode Exit fullscreen mode

HuxBreadcrumbs

Hierarchical navigation component with theme-aware styling.

Features:

  • Two variants: default_ (text /) and icon (chevron)
  • Three sizes: small, medium, large
  • Overflow handling with maxItems
  • Custom overflowIndicator support
HuxBreadcrumbs(
  items: ['Home', 'Products', 'Electronics', 'Laptops'],
  variant: HuxBreadcrumbsVariant.icon,
  onItemTap: (index, item) => print('Tapped: $item'),
  maxItems: 3,
)
Enter fullscreen mode Exit fullscreen mode

Feedback & Status

HuxBadge

Status indicators and notification counters with semantic variants.

Variants:

  • primary, secondary, success, warning, destructive
  • Sizes: small, medium, large

Implementation:

Uses WCAG AA contrast ratios automatically calculated via HuxWCAG.getContrastingTextColor().

HuxBadge(
  label: 'New',
  variant: HuxBadgeVariant.success,
  size: HuxBadgeSize.medium,
)
Enter fullscreen mode Exit fullscreen mode

HuxAlert

Persistent alert messages with semantic variants and dismissal support.

Variants:

  • info, success, warning, destructive

Features:

  • Optional icons
  • Dismissible alerts
  • Theme-aware colors
HuxAlert(
  variant: HuxAlertVariant.success,
  title: 'Success!',
  message: 'Operation completed successfully.',
  showIcon: true,
  onDismiss: () => print('Alert dismissed'),
)
Enter fullscreen mode Exit fullscreen mode

HuxSnackbar

Temporary notification messages (typically 3-5 seconds) with semantic variants.

Implementation:

Provides a convenient extension method on BuildContext:

context.showHuxSnackbar(
  variant: HuxSnackbarVariant.success,
  message: 'Changes saved successfully!',
  action: SnackBarAction(
    label: 'Undo',
    onPressed: () => undo(),
  ),
)
Enter fullscreen mode Exit fullscreen mode

HuxTooltip

Contextual help and information with customizable positioning and timing.

Features:

  • Automatic light/dark theme adaptation
  • Customizable positioning (preferBelow, verticalOffset)
  • Support for any icon library
  • Custom colors and timing
HuxTooltip(
  message: 'This is a helpful tooltip',
  icon: LucideIcons.info,
  preferBelow: false,
  verticalOffset: 16.0,
  child: Icon(LucideIcons.helpCircle),
)
Enter fullscreen mode Exit fullscreen mode

Data Visualization

HuxChart

Data visualization component with line and bar chart support.

Chart Types:

  • Line Charts: HuxChart.line() - Time series, trends, continuous data
  • Bar Charts: HuxChart.bar() - Categorical data, comparisons

Features:

  • Integration with cristalyse (or custom chart libraries)
  • Customizable colors
  • Title and subtitle support
  • Animated transitions
  • Responsive sizing

Technical Implementation:

The chart widget accepts data as a list of maps with specified xField and yField keys. It handles data transformation and rendering internally.

HuxChart.line(
  data: [
    {'x': 1, 'y': 10},
    {'x': 2, 'y': 20},
    {'x': 3, 'y': 15},
  ],
  xField: 'x',
  yField: 'y',
  title: 'Sales Over Time',
  subtitle: 'Monthly data',
  primaryColor: HuxTokens.primary(context),
)
Enter fullscreen mode Exit fullscreen mode

Overlays & Dialogs

HuxDialog

General-purpose dialog with modern design and multiple size variants.

Features:

  • Built-in close button with ghost styling
  • Support for title, subtitle, content, and actions
  • Size variants: small, medium, large, fullscreen
  • Consistent Hux design system integration

Implementation:

Uses Flutter's Dialog widget with custom styling. Close button uses HuxButton with ghost variant.

showHuxDialog(
  context: context,
  title: 'Confirm Action',
  subtitle: 'This action cannot be undone',
  content: Text('Are you sure you want to proceed?'),
  actions: [
    HuxButton(
      onPressed: () => Navigator.of(context).pop(false),
      variant: HuxButtonVariant.secondary,
      child: Text('Cancel'),
    ),
    HuxButton(
      onPressed: () => Navigator.of(context).pop(true),
      child: Text('Confirm'),
    ),
  ],
);
Enter fullscreen mode Exit fullscreen mode

showHuxDatePickerDialog

Modern date picker dialog with month/year selection.

Features:

  • Month/year navigation
  • Theme-aware styling
  • Responsive calendar grid
  • Smart date range validation
final DateTime? selectedDate = await showHuxDatePickerDialog(
  context: context,
  initialDate: DateTime.now(),
  firstDate: DateTime(2020),
  lastDate: DateTime(2030),
);
Enter fullscreen mode Exit fullscreen mode

showHuxTimePickerDialog

Clean time picker with hour/minute dropdowns.

Features:

  • Hour/minute dropdown selectors
  • 12/24 hour format support
  • Theme integration
final TimeOfDay? selectedTime = await showHuxTimePickerDialog(
  context: context,
  initialTime: TimeOfDay.now(),
);
Enter fullscreen mode Exit fullscreen mode

HuxContextMenu

Right-click context menus with smart positioning.

Components:

  • HuxContextMenu - Main container
  • HuxContextMenuItem - Individual menu items
  • HuxContextMenuDivider - Visual separators

Features:

  • Smart positioning (avoids screen edges)
  • Cross-platform support
  • Proper web context menu handling
  • Icon support
  • Disabled and destructive states

Technical Implementation:

Uses Flutter's GestureDetector for right-click detection and custom overlay for positioning. On web, properly handles context menu events.

HuxContextMenu(
  menuItems: [
    HuxContextMenuItem(
      text: 'Copy',
      icon: LucideIcons.copy,
      onTap: () => copyToClipboard(),
    ),
    HuxContextMenuItem(
      text: 'Paste',
      icon: LucideIcons.clipboard,
      onTap: () => pasteFromClipboard(),
      isDisabled: true,
    ),
    const HuxContextMenuDivider(),
    HuxContextMenuItem(
      text: 'Delete',
      icon: LucideIcons.trash2,
      onTap: () => delete(),
      isDestructive: true,
    ),
  ],
  child: Container(
    padding: EdgeInsets.all(20),
    child: Text('Right-click me!'),
  ),
)
Enter fullscreen mode Exit fullscreen mode

HuxDropdown

Dropdown menu component with search, multi-select, and custom item widgets.

Features:

  • Single and multi-select modes
  • Search/filter functionality
  • Custom item widgets
  • Theme-aware styling
  • Keyboard navigation

Advanced Feature:

The useItemWidgetAsValue parameter allows displaying custom widgets as the selected value, enabling rich content in selections (icons, badges, custom layouts).

HuxDropdown<String>(
  items: ['Option 1', 'Option 2', 'Option 3'],
  value: selectedValue,
  onChanged: (value) => setState(() => selectedValue = value),
  label: 'Select an option',
  searchable: true,
)
Enter fullscreen mode Exit fullscreen mode

Utility Components

HuxLoading

Customizable loading indicators with theme awareness.

Variants:

  • HuxLoading - Simple spinner
  • HuxLoadingOverlay - Full-screen overlay

Sizes:

  • small - 16px
  • medium - 24px (default)
  • large - 32px
// Simple loading indicator
HuxLoading(size: HuxLoadingSize.medium)

// Loading overlay
HuxLoadingOverlay(
  isLoading: true,
  message: 'Loading data...',
  child: YourContent(),
)
Enter fullscreen mode Exit fullscreen mode

HuxAvatar

Circular user images with initials fallback and gradient variants.

Features:

  • Network image support with caching
  • Initials fallback
  • Custom colors
  • Beautiful gradient variants
  • Multiple sizes
HuxAvatar(
  name: 'John Doe',
  imageUrl: 'https://example.com/avatar.jpg',
  size: HuxAvatarSize.medium,
  useGradient: true,
  gradientVariant: HuxAvatarGradient.bluePurple,
)
Enter fullscreen mode Exit fullscreen mode

HuxAvatarGroup

Display multiple avatars with overlapping or spaced layouts.

Features:

  • Overlap or spaced layouts
  • maxVisible limit with overflow indicator
  • Consistent sizing
HuxAvatarGroup(
  avatars: [
    HuxAvatar(name: 'Alice'),
    HuxAvatar(name: 'Bob'),
    HuxAvatar(name: 'Charlie'),
  ],
  overlap: true,
  maxVisible: 3,
)
Enter fullscreen mode Exit fullscreen mode

HuxPagination

Navigate through pages with intelligent ellipsis handling.

Features:

  • Previous/next arrow buttons with disabled states
  • Configurable maximum pages to show
  • Theme-aware styling
  • WCAG AA compliant contrast ratios
  • Compact button design
HuxPagination(
  currentPage: 5,
  totalPages: 20,
  onPageChanged: (page) => print('Page $page'),
  maxPagesToShow: 7,
)
Enter fullscreen mode Exit fullscreen mode

HuxCommand

Powerful command palette for quick access to actions and navigation.

Features:

  • Keyboard shortcuts (CMD+K on Mac, Ctrl+K on Windows/Linux)
  • Real-time search and filtering
  • Keyboard navigation (arrow keys, Enter)
  • Customizable commands with icons, shortcuts, categories
  • Global keyboard shortcuts via HuxCommandShortcuts.wrapper

Technical Implementation:

The command palette uses a searchable list with fuzzy matching. It maintains focus management and handles keyboard events for navigation and execution.

final commands = [
  HuxCommandItem(
    id: 'toggle-theme',
    label: 'Toggle Theme',
    description: 'Switch between light and dark mode',
    shortcut: '⌘⇧T',
    icon: LucideIcons.sun,
    category: 'View',
    onExecute: () => toggleTheme(),
  ),
  HuxCommandItem(
    id: 'settings',
    label: 'Settings',
    description: 'Open application settings',
    shortcut: '⌘,',
    icon: LucideIcons.settings,
    category: 'Preferences',
    onExecute: () => openSettings(),
  ),
];

// Show command palette
showHuxCommand(
  context: context,
  commands: commands,
  placeholder: 'Type a command or search...',
);

// Or wrap app for global shortcuts
HuxCommandShortcuts.wrapper(
  commands: commands,
  child: MaterialApp(home: MyHomePage()),
)
Enter fullscreen mode Exit fullscreen mode

Theming System

HuxTheme

Pre-configured light and dark themes with Material 3 seed color support.

Setup:

MaterialApp(
  theme: HuxTheme.lightTheme,
  darkTheme: HuxTheme.darkTheme,
  themeMode: ThemeMode.system,
  home: MyHomePage(),
)
Enter fullscreen mode Exit fullscreen mode

Custom Seed Colors

Hux automatically detects and uses Material 3 seed colors:

MaterialApp(
  theme: HuxTheme.lightTheme.copyWith(
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.deepPurple,
    ),
  ),
  // All Hux components automatically use the custom primary color
)
Enter fullscreen mode Exit fullscreen mode

HuxTokens

Semantic design tokens that adapt to themes:

// Color tokens
HuxTokens.primary(context)
HuxTokens.surfacePrimary(context)
HuxTokens.borderPrimary(context)
HuxTokens.textPrimary(context)
HuxTokens.textSecondary(context)

// Component-specific tokens
HuxTokens.buttonPrimaryHover(context)
HuxTokens.tabActiveBackground(context)
HuxTokens.surfaceHover(context)
Enter fullscreen mode Exit fullscreen mode

HuxColors

Comprehensive color palette with semantic names:

HuxColors.primary
HuxColors.success
HuxColors.warning
HuxColors.destructive
HuxColors.black90
HuxColors.white
// ... and many more
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Always Use HuxTokens

When building custom components that integrate with Hux, use HuxTokens instead of hardcoded colors:

Container(
  color: HuxTokens.surfacePrimary(context), // ✅ Good
  // color: Colors.white, // ❌ Bad - won't adapt to dark mode
)
Enter fullscreen mode Exit fullscreen mode

2. Leverage WCAG Utilities

Use HuxWCAG for custom contrast calculations:

final textColor = HuxWCAG.getContrastingTextColor(
  backgroundColor: myCustomColor,
  context: context,
);
Enter fullscreen mode Exit fullscreen mode

3. Consistent Sizing

Follow Hux's sizing patterns:

  • Buttons: 32px (small), 40px (medium), 48px (large)
  • Inputs: 40px (all sizes)
  • Icons: 16px (small), 18px (medium), 20px (large)

4. Theme-Aware Development

Always test components in both light and dark themes. Hux components automatically adapt, but custom code should too.

Wrap up

Hux UI gives you a full set of production-ready components that already do things right: proper accessibility, consistent theming, and layouts that just work.

You can build real products with it, not just prototypes. Whether it’s a small form or a complex dashboard, Hux handles the boring parts so you can focus on the logic.

If you care about accessibility, want your app to look good in both light and dark mode, and don’t want to rebuild buttons ever again, give it a try!

flutter pub add hux
Enter fullscreen mode Exit fullscreen mode

💡 Resources

And if you end up using it, tell me what you built, or what’s missing.
Always happy to make Hux better for teams shipping products faster.

Top comments (0)