Skip to main content

expressive_kit 0.0.8 copy "expressive_kit: ^0.0.8" to clipboard
expressive_kit: ^0.0.8 copied to clipboard

A modern Flutter design system providing Material 3 Expressive components, spring motions, tactile feedback, and unified theme styles.

Expressive Kit #

pub package pub points code factor analysis codecov Star on GitHub License: MIT Buy Me A Coffee

A modern, cohesive Flutter design system implementing Material 3 Expressive guidelines. expressive_kit brings vibrant UI components, authentic spring motion curves, tactile haptic feedback, wavy progress indicators, curated variable fonts, and full dark/light theme support into your Flutter applications.


Features #

  • 🎨 Material 3 Expressive Design: Styled according to the latest M3 Expressive specifications with 24dp+ rounded corners, organic pill indicators, and vibrant tonal color mapping.
  • ⚡ Authentic Spring Motion: Built-in motion tokens (ExpressiveMotion.springBouncy, springGentle, and emphasized) for natural, energetic physical feedback.
  • 🌊 Wavy Progress Indicators: Sinusoidal linear and circular progress indicators for both determinate and indeterminate loading states with track spacing.
  • 🔤 Curated Variable Fonts: Bundled typography presets via ExpressiveFonts (Google Sans Flex, Montserrat, Roboto, Open Sans, Orbitron, and more).
  • 🌍 Built-in Localization: Out-of-the-box localizations for theme modes, colors, and languages across 6 languages (en, es, it, de, fr, pt).
  • 📱 Interactive Controls: Buttons with loading states, split buttons with contextual dropdowns, segmented pickers, multi-shape icon buttons, switches, and sliders.
  • 🛡️ 100% Test Coverage: Production-ready, null-safe codebase tested with 100% unit and widget test coverage.
  • 🤖 AI Agent Ready: Includes a bundled SKILL.md skill guide for any AI coding assistant (Cursor, Antigravity, Claude Code, Copilot) to implement components or migrate existing codebases.

Getting Started #

Add expressive_kit and hugeicons to your pubspec.yaml:

dependencies:
  expressive_kit: ^0.0.8
  hugeicons: ^1.2.0

Import it in your Dart code:

import 'package:expressive_kit/expressive_kit.dart';
import 'package:hugeicons/hugeicons.dart';

Quick Theme Setup #

Initialize your application with the expressive theme generator:

MaterialApp(
  title: 'My Expressive App',
  theme: ExpressiveTheme.light(
    baseColor: ExpressiveColors.defaultColor,
    fontFamily: ExpressiveFonts.defaultFont,
  ),
  darkTheme: ExpressiveTheme.dark(
    baseColor: ExpressiveColors.defaultColor,
    fontFamily: ExpressiveFonts.defaultFont,
  ),
  themeMode: ExpressiveTheme.defaultTheme,
  localizationsDelegates: ExpressiveLocalizations.localizationsDelegates,
  supportedLocales: ExpressiveLocalizations.supportedLocales,
  home: const HomeScreen(),
);

🤖 AI Agent Skill & Migration Guide #

This repository includes a dedicated SKILL.md designed for AI coding assistants (such as Antigravity, Cursor, Windsurf, Claude Code, or GitHub Copilot).

You can prompt or point your agent to SKILL.md to:

  • Build new screens using authentic Material 3 Expressive components.
  • Configure themes, dynamic color schemes, and bundled variable fonts.
  • Migrate existing apps: Automatically replace legacy Flutter widgets (ElevatedButton, Switch, CircularProgressIndicator, AppBar, etc.) with expressive_kit equivalents using the included widget replacement matrix.

Component Showcase #

1. Controls Components #

Interactive input widgets and action triggers crafted with physical feedback and customizable shapes.

Controls Components

• ExpressiveButton

Versatile action buttons supporting filled, tonal, and outlined variants with built-in loading states and full-width expansion:

ExpressiveButton(
  label: 'With Icon',
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedStar, size: 20),
  variant: ExpressiveButtonVariant.filled,
  onPressed: () {},
)

ExpressiveButton(
  label: 'Loading State',
  isLoading: true,
  onPressed: () {},
)

• ExpressiveSplitButton

Seamless primary action combined with an expandable secondary dropdown:

ExpressiveSplitButton(
  label: 'Save File',
  leadingIcon: const HugeIcon(icon: HugeIcons.strokeRoundedFloppyDisk, size: 20),
  variant: ExpressiveButtonVariant.filled,
  onPressed: () => print('Primary save tapped'),
  onTrailingPressed: () => print('Open secondary dropdown menu'),
)

• ExpressiveButtonGroup (Segmented Picker)

Segmented button group with a sliding pill indicator animated with spring physics:

ExpressiveButtonGroup<String>(
  selectedValue: 'Daily',
  onSelected: (value) => print('Selected: $value'),
  items: const [
    ExpressiveButtonGroupItem(
      value: 'Daily',
      label: 'Daily',
      icon: HugeIcon(icon: HugeIcons.strokeRoundedCalendar01, size: 18),
    ),
    ExpressiveButtonGroupItem(
      value: 'Weekly',
      label: 'Weekly',
      icon: HugeIcon(icon: HugeIcons.strokeRoundedCalendar02, size: 18),
    ),
    ExpressiveButtonGroupItem(
      value: 'Monthly',
      label: 'Monthly',
      icon: HugeIcon(icon: HugeIcons.strokeRoundedCalendar03, size: 18),
    ),
  ],
)

• ExpressiveIconButton

Expressive icon buttons available in three distinctive geometry styles: circle, squircle, and roundedRectangle, featuring optional badge text and notification dots:

ExpressiveIconButton.circle(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedFavourite),
  variant: ExpressiveIconButtonVariant.filled,
  onPressed: () {},
)

ExpressiveIconButton.squircle(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedCamera01),
  variant: ExpressiveIconButtonVariant.tonal,
  onPressed: () {},
)

ExpressiveIconButton.circle(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedMail01),
  badgeText: '9+',
  onPressed: () {},
)

• ExpressiveSwitch

Capsule-track toggle switch displaying animated check and cross icons in the sliding thumb:

ExpressiveSwitch(
  value: isEnabled,
  onChanged: (val) => setState(() => isEnabled = val),
)

• ExpressiveSlider

Continuous and discrete sliders featuring thick capsule tracks and animated spring thumb:

ExpressiveSlider(
  value: sliderValue,
  min: 0,
  max: 100,
  title: 'Sound Volume',
  subtitle: 'Media and notifications',
  onChanged: (val) => setState(() => sliderValue = val),
)

2. Content & Layout Components #

Structured data containers, media carousels, and settings groups inspired by Google Pixel OS design.

Content Components

• ExpressiveSearchBar

Pill-shaped 28dp radius search container with embedded leading icon, customizable trailing actions, and read-only support:

ExpressiveSearchBar(
  hintText: 'Search components, colors, or settings...',
  trailing: ExpressiveIconButton.circle(
    icon: const HugeIcon(icon: HugeIcons.strokeRoundedMic01, size: 20),
    onPressed: () {},
  ),
  onSubmitted: (query) => print('Search: $query'),
)

• ExpressiveCarousel

Smooth horizontal multi-browse carousel with 24dp adaptive corners and spring physics:

ExpressiveCarousel(
  height: 160,
  itemExtent: 220,
  items: [
    ExpressiveCarouselItem(
      onTap: () {},
      child: Container(
        decoration: BoxDecoration(
          gradient: const LinearGradient(
            colors: [Color(0xFF1E88E5), Color(0xFF42A5F5)],
          ),
          borderRadius: BorderRadius.circular(24),
        ),
        padding: const EdgeInsets.all(16),
        child: const Text('Expressive Card Item'),
      ),
    ),
  ],
)

• ExpressiveCardGroup & ExpressiveListTile

Pixel Settings-style grouped cards with vibrant circular badges, split dividers, and secondary action toggles:

ExpressiveCardGroup(
  title: 'Connectivity Preferences',
  children: [
    ExpressiveListTile(
      leading: const ExpressiveBadge(
        icon: HugeIcon(
          icon: HugeIcons.strokeRoundedWifi01,
          color: Colors.white,
          size: 20,
        ),
        backgroundColor: Color(0xFF1E88E5),
      ),
      title: const Text('Internet & network'),
      subtitle: const Text('Home Wi-Fi 5GHz connected'),
      trailing: const HugeIcon(icon: HugeIcons.strokeRoundedArrowRight01, size: 20),
      onTap: () {},
    ),
    ExpressiveListTile(
      leading: const ExpressiveBadge(
        icon: HugeIcon(
          icon: HugeIcons.strokeRoundedMoon02,
          color: Colors.white,
          size: 20,
        ),
        backgroundColor: Color(0xFFEF6C00),
      ),
      title: const Text('Dark theme'),
      subtitle: const Text('Toggle appearance'),
      showSplitDivider: true,
      secondaryTrailing: ExpressiveSwitch(
        value: isDark,
        onChanged: (val) => toggleTheme(),
      ),
    ),
  ],
)

• ExpressiveCard

Elevated standalone surface with 24dp rounded corners, smooth hover effects, and tactile touch feedback:

ExpressiveCard(
  onTap: () => print('Card pressed'),
  child: Row(
    children: [
      const ExpressiveBadge(
        icon: HugeIcon(icon: HugeIcons.strokeRoundedStar, color: Colors.black87),
        backgroundColor: Colors.amber,
      ),
      const SizedBox(width: 16),
      const Text('Expressive Experience'),
    ],
  ),
)

3. Progress & Motion Components #

Fluid sinusoidal wave loaders and authentic spring physics curves.

Progress Components

• ExpressiveLinearProgressIndicator

Sinusoidal wavy progress indicator supporting determinate progress with end gap or continuous indeterminate waves:

// Determinate with percentage
ExpressiveLinearProgressIndicator(
  value: 0.65,
)

// Indeterminate moving wave
const ExpressiveLinearProgressIndicator()

• ExpressiveCircularProgressIndicator

Circular loader rendering geometric wave contours around its perimeter with smooth phase shifting:

// Determinate circular wave
ExpressiveCircularProgressIndicator(
  value: 0.75,
  size: 64,
)

// Indeterminate circular wave
const ExpressiveCircularProgressIndicator(
  size: 64,
)

• ExpressiveMotion

Physical tokens for spring transitions and tactile animations:

Token Description Curve / Specification
ExpressiveMotion.springBouncy Smooth overshoot with snappy settling Cubic(0.34, 1.35, 0.64, 1.0)
ExpressiveMotion.springGentle Gentle progressive damping without overshoot Cubic(0.2, 0.0, 0.0, 1.0)
ExpressiveMotion.emphasized Standard state transition & element morphing Curves.easeInOutCubicEmphasized

• ExpressivePressable

Spring tactile feedback wrapper that gracefully compresses and restores when tapped:

ExpressivePressable(
  onTap: () => print('Tactile press!'),
  child: Container(
    padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(
      color: Theme.of(context).colorScheme.primaryContainer,
      borderRadius: BorderRadius.circular(16),
    ),
    child: const Text('Tap for physical spring feedback'),
  ),
)

4. Navigation & Floating Action Buttons #

Navigation bars, adaptive top app bars, and animated expandable speed dials.

Navigation Components

• ExpressiveFab & ExpressiveExtendedFab

Floating action buttons available in three standard Material 3 Expressive sizes plus an extended variant:

// Small (44dp)
ExpressiveFab(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
  size: ExpressiveFabSize.small,
  onPressed: () {},
)

// Regular (56dp)
ExpressiveFab(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedEdit02),
  size: ExpressiveFabSize.regular,
  onPressed: () {},
)

// Large (80dp)
ExpressiveFab(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedPaintBrush01),
  size: ExpressiveFabSize.large,
  onPressed: () {},
)

// Extended with label
ExpressiveExtendedFab(
  icon: const HugeIcon(icon: HugeIcons.strokeRoundedTaskAdd01),
  label: 'New Task',
  onPressed: () {},
)

• ExpressiveFabMenu

Expandable speed dial floating menu with spring physics expansion and backdrop blur:

ExpressiveFabMenu(
  items: [
    ExpressiveFabMenuItem(
      icon: const HugeIcon(icon: HugeIcons.strokeRoundedShare01),
      label: 'Share',
      onTap: () => print('Share tapped'),
    ),
    ExpressiveFabMenuItem(
      icon: const HugeIcon(icon: HugeIcons.strokeRoundedBookmark02),
      label: 'Save',
      onTap: () => print('Save tapped'),
    ),
    ExpressiveFabMenuItem(
      icon: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
      label: 'New item',
      onTap: () => print('New item tapped'),
    ),
  ],
)

• ExpressiveNavigationBar

Bottom navigation bar featuring smooth pill indicator transitions, animated icons, notification dots, and cross-platform safe area padding consistency:

ExpressiveNavigationBar(
  selectedIndex: currentIndex,
  onDestinationSelected: (index) => setState(() => currentIndex = index),
  destinations: const [
    ExpressiveNavigationDestination(
      icon: HugeIcon(icon: HugeIcons.strokeRoundedCursorPointer01),
      label: 'Controls',
    ),
    ExpressiveNavigationDestination(
      icon: HugeIcon(icon: HugeIcons.strokeRoundedGridTable),
      selectedIcon: HugeIcon(icon: HugeIcons.strokeRoundedDashboardSquare01),
      label: 'Content',
    ),
    ExpressiveNavigationDestination(
      icon: HugeIcon(icon: HugeIcons.strokeRoundedDashboardSpeed01),
      label: 'Progress',
    ),
    ExpressiveNavigationDestination(
      icon: HugeIcon(icon: HugeIcons.strokeRoundedNavigation03),
      label: 'Navigation',
      showBadgeDot: true,
    ),
  ],
)

• ExpressiveTopAppBar

Modern top bar supporting standard and large title display, action slots, and automatic adaptive pop buttons:

// Standard app bar
ExpressiveTopAppBar(
  title: const Text('Page Title'),
  actions: [
    ExpressiveIconButton.circle(
      icon: const HugeIcon(icon: HugeIcons.strokeRoundedNotification01),
      onPressed: () {},
    ),
  ],
)

// Large title app bar
ExpressiveTopAppBar.large(
  titleText: 'Large Heading',
  actions: [
    ExpressiveIconButton.circle(
      icon: const HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle),
      onPressed: () {},
    ),
  ],
)

5. Typography & Variable Fonts #

Curated variable fonts bundled locally with zero network requests, optical weight variations, and live global theme switching.

Typography Components

• ExpressiveFonts

Easily apply bundled variable fonts to your themes or individual text styles:

// Apply to global theme
MaterialApp(
  theme: ExpressiveTheme.light(
    baseColor: const Color(0xFF1E88E5),
    fontFamily: ExpressiveFonts.googleSansFlex,
  ),
  home: const HomeScreen(),
);

// Apply to individual TextStyles
Text(
  'Expressive Heading',
  style: TextStyle(
    fontFamily: ExpressiveFonts.orbitron,
    fontWeight: FontWeight.bold,
  ),
);

// Inspect all available font families
final fontsMap = ExpressiveFonts.availableFonts;
Family Constant Typeface Name Style Category
ExpressiveFonts.googleSansFlex Google Sans Flex Sans-Serif • Clean UI / Modern (Default)
ExpressiveFonts.merriweather Merriweather Serif • Editorial Reading
ExpressiveFonts.montserrat Montserrat Geometric Sans • Punchy Branding
ExpressiveFonts.nunito Nunito Rounded Sans • Friendly & Approachable
ExpressiveFonts.openSans Open Sans Humanist Sans • Neutral Mobile
ExpressiveFonts.orbitron Orbitron Display • Futuristic / Sci-Fi / Numbers
ExpressiveFonts.playfairDisplay Playfair Display High-Contrast Serif • Classical Elegance
ExpressiveFonts.roboto Roboto Neo-Grotesque Sans • Natural Reading
ExpressiveFonts.sourceCodePro Source Code Pro Monospace • Code & Terminals

6. Colors & Localization #

• ExpressiveColors

Standardized 19-color dynamic palette with key-based resolution and default color:

// Predefined default color
final defaultColor = ExpressiveColors.defaultColor; // Colors.teal

// Lookup color by key
final redColor = ExpressiveColors.fromKey('RED');
final colorKey = ExpressiveColors.toKey(Colors.teal); // 'TEAL'

// Access the complete palette
final allColors = ExpressiveColors.palette;

• Built-in Localization (ExpressiveLocalizations)

Provides localized labels for themes, colors, and languages across 6 locales: English (en), Spanish (es), Italian (it), German (de), French (fr), and Portuguese (pt).

// Convenient extension methods
final themeName = ThemeMode.system.localizedName(context);       // e.g. "Sistema" / "System"
final languageName = const Locale('it').localizedName(context);  // e.g. "Italiano" / "Italian"
final colorName = Colors.teal.localizedName(context);            // e.g. "Turquesa" / "Teal"

• ExpressiveLanguages

Standardized supported locales and language utilities:

// Default locale
final defaultLocale = ExpressiveLanguages.defaultLocale; // Locale('en', 'US')

// Predefined supported locales list ready for MaterialApp
final locales = ExpressiveLanguages.supportedLocales;
// [ Locale('en', 'US'), Locale('es', 'ES'), Locale('it', 'IT'), ... ]

// Resolve locale from code
final locale = ExpressiveLanguages.fromLanguageCode('es'); // Locale('es', 'ES')

• Theme Persistence (ExpressiveTheme / ThemeHelper)

Standardized serialization and deserialization for saving user theme selection to local storage (e.g. SharedPreferences, Hive):

// Serialize to store in local storage ('LIGHT', 'DARK', 'SYSTEM')
final key = ExpressiveTheme.toKey(ThemeMode.dark); // 'DARK'

// Direct extension getter
final themeKey = ThemeMode.system.key; // 'SYSTEM'

// Deserialize from stored string
final theme = ExpressiveTheme.fromKey(savedKey); // ThemeMode (fallback: defaultTheme)

// Compatibility helpers & ThemeHelper alias
final name = ThemeHelper.getThemeName(themeMode); // 'LIGHT' | 'DARK' | 'SYSTEM'
final loadedTheme = ThemeHelper.getThemeByName(storedKey, fallback: ThemeMode.light);

7. Cross-Cutting Models #

Unified, immutable data models built with Equatable for sharing device and package metadata across your Flutter ecosystem:

• AppDeviceInfo

Captures hardware and platform specifications (ID, brand, model, Android SDK/release, RAM capacities, low-RAM flags, and processor):

final deviceInfo = AppDeviceInfo(
  id: 'device_01',
  model: 'Pixel 9 Pro',
  brand: 'Google',
  versionRelease: '14',
  sdkInt: 34,
  processor: 'Tensor G4',
  physicalRamSize: 17179869184,
  availableRamSize: 8589934592,
  isLowRamDevice: false,
  isPhysicalDevice: true,
);

// Serialization and copying
final json = deviceInfo.toJson();
final restored = AppDeviceInfo.fromJson(json);
final modified = deviceInfo.copyWith(isLowRamDevice: true);

• AppPackageInfo

Encapsulates runtime application package metadata with UTC ISO 8601 timestamps:

final packageInfo = AppPackageInfo(
  appName: 'My App',
  version: '1.0.0',
  buildNumber: '1',
  updateTime: DateTime.now(),
);

// Serialization and copying
final json = packageInfo.toJson(); // updateTime formatted as ISO 8601 UTC
final restored = AppPackageInfo.fromJson(json);
final modified = packageInfo.copyWith(version: '1.0.1');

Contributing #

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

1
likes
160
points
435
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A modern Flutter design system providing Material 3 Expressive components, spring motions, tactile feedback, and unified theme styles.

Repository (GitHub)
View/report issues

Topics

#design-system #material3 #ui-components #expressive #widget

License

GPL-3.0 (license)

Dependencies

equatable, flutter, flutter_localizations, hugeicons, intl, material_ui

More

Packages that depend on expressive_kit