Skip to content

Theme Binding

View raw .md

Theme binding allows you to sync your Wind configuration with Flutter's native ThemeData system. This ensures that standard Material widgets automatically reflect your Wind tokens, creating a cohesive visual experience across your entire application.

On this page

Why Bind Themes?#

By default, Wind manages its own styling tokens (colours, spacing, typography). However, Flutter's built-in widgets (like AppBar, FloatingActionButton, or TextField) rely on the standard Theme.of(context) to determine their appearance.

Binding the two systems ensures:

  • Consistency: A button using bg-primary-500 matches a standard ElevatedButton.
  • Inheritance: Standard Flutter widgets automatically pick up your Wind font families and colours.
  • Automation: Toggling dark mode in Wind automatically updates the brightness of your standard Material theme.

Reactive Binding#

To ensure your entire application rebuilds when the theme changes (e.g., switching to dark mode), use the builder pattern. This provides a WindThemeController that dynamically generates a new ThemeData whenever the state updates.

Preview core-concepts/theme_binding A live demo of this example follows. theme_binding.dart View source Open demo
dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final windTheme = WindThemeData(
      colors: {
        'primary': Colors.indigo,
        'secondary': Colors.teal,
      },
    );

    return WindTheme(
      data: windTheme,
      builder: (context, controller) {
        // controller.toThemeData() produces a standard Flutter ThemeData
        return MaterialApp(
          theme: controller.toThemeData(),
          home: const HomePage(),
        );
      },
    );
  }
}

Toggling Themes#

When using the reactive builder pattern, you can trigger a global theme update from anywhere in the widget tree. This will automatically update both Wind utilities and standard Material widgets.

dart
// Toggle between Light and Dark mode
context.windTheme.toggleTheme();

Static Binding#

If you do not need dynamic theme switching at runtime, you can bind the theme once during initialisation. This is useful for apps with a fixed brand identity or forced dark/light modes.

dart
final windTheme = WindThemeData(
  brightness: Brightness.dark,
  syncWithSystem: false,
  colors: {'primary': Colors.purple},
);

return WindTheme(
  data: windTheme,
  child: MaterialApp(
    theme: windTheme.toThemeData(),
    home: const HomePage(),
  ),
);

Mapping Reference#

The toThemeData() method intelligently maps Wind tokens to their standard Flutter counterparts:

Wind Token Flutter Theme Property
colors['primary'] colorScheme.primary
colors['secondary'] colorScheme.secondary
colors['error'] colorScheme.error
colors['background'] scaffoldBackgroundColor
brightness brightness
fontFamilies['sans'] textTheme.fontFamily

Three rows have a fallback. colors['primary'] only repaints Material widgets when it differs from Wind's seeded default (the blue swatch); otherwise the Material layer keeps its indigo baseline. colors['secondary'] defaults to teal. Without colors['background'], scaffoldBackgroundColor reads the bg-[#hex] in your bg-surface alias (dark:bg-[#hex] in dark mode) and then falls back to white in light mode and gray-900 in dark mode.

This mapping ensures that your utility-first styles and native widgets stay perfectly in sync.

esc

Search index did not load.

No match for "".

Try a class like rounded-lg or a widget like WButton.