easy_theme_extension 0.1.0+1 copy "easy_theme_extension: ^0.1.0+1" to clipboard
easy_theme_extension: ^0.1.0+1 copied to clipboard

A zero-boilerplate code generator for Flutter ThemeExtension classes.

easy_theme_extension #

A zero-boilerplate generator for Flutter ThemeExtension classes.

Define your theme as an annotated abstract class. The generator creates the full immutable implementation with constructor, fields, copyWith, lerp and more.

Before After
before after

Installation #

flutter pub add \
  easy_theme_extension \
  dev:easy_theme_extension_builder \
  dev:build_runner

Usage #

1. Define your theme contract #

part 'my_colors.g.dart';

@easyTheme
abstract class _MyColors {
  Color get primary;
  Color get secondary;
  Color get textBody;
  Color get textTitle;
  Color get textLabel;
}

2. Run the generator #

dart run build_runner build
my_colors.g.dart
part of 'my_colors.dart';

@immutable
class MyColors extends ThemeExtension<MyColors> with Diagnosticable implements _MyColors {
  const MyColors({
    required this.primary,
    required this.secondary,
    required this.textBody,
    required this.textTitle,
    required this.textLabel,
  });

  @override
  final Color primary;

  @override
  final Color secondary;

  @override
  final Color textBody;

  @override
  final Color textTitle;

  @override
  final Color textLabel;

  @override
  MyColors copyWith({
    Color? primary,
    Color? secondary,
    Color? textBody,
    Color? textTitle,
    Color? textLabel,
  }) => MyColors(
    primary: primary ?? this.primary,
    secondary: secondary ?? this.secondary,
    textBody: textBody ?? this.textBody,
    textTitle: textTitle ?? this.textTitle,
    textLabel: textLabel ?? this.textLabel,
  );

  @override
  MyColors lerp(MyColors? other, double t) {
    if (other is! MyColors) return this;
    return MyColors(
      primary: Color.lerp(primary, other.primary, t)!,
      secondary: Color.lerp(secondary, other.secondary, t)!,
      textBody: Color.lerp(textBody, other.textBody, t)!,
      textTitle: Color.lerp(textTitle, other.textTitle, t)!,
      textLabel: Color.lerp(textLabel, other.textLabel, t)!,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (other.runtimeType != runtimeType) return false;
    return other is MyColors &&
        other.primary == primary &&
        other.secondary == secondary &&
        other.textBody == textBody &&
        other.textTitle == textTitle &&
        other.textLabel == textLabel;
  }

  @override
  int get hashCode => Object.hash(
    runtimeType,
    primary,
    secondary,
    textBody,
    textTitle,
    textLabel,
  );

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties
      ..add(DiagnosticsProperty<Color>('primary', primary))
      ..add(DiagnosticsProperty<Color>('secondary', secondary))
      ..add(DiagnosticsProperty<Color>('textBody', textBody))
      ..add(DiagnosticsProperty<Color>('textTitle', textTitle))
      ..add(DiagnosticsProperty<Color>('textLabel', textLabel));
  }
}

extension MyColorsBuildContextExtension on BuildContext {
  MyColors get myColors => Theme.of(this).extension<MyColors>()!;
}

3. Use the generated extension #

return MaterialApp(
  theme: ThemeData(
    extensions: const [
      MyColors(
        primary: Colors.blue,
        secondary: Colors.red,
        textBody: Colors.black,
        textTitle: Colors.black,
        textLabel: Colors.grey,
      ),
    ],
  ),
);

// Context extension
context.myColors.secondary;

Default Instance #

If all fields provide values, the generator creates a static $default instance.

@easyTheme
abstract class _AppColors {
  Color get primary => Colors.blue;
  Color get textColor => Colors.orange;
}

You can use it directly when configuring the theme:

return MaterialApp(
  theme: ThemeData(
    extensions: const [
      AppColors.$default, // instance with default values
    ],
  ),
);

Annotation Options #

@EasyTheme(contextExtensionName: 'color')
abstract class _MyColors { ... }
Option Type Default Description
contextExtension bool? true Generates an extension on BuildContext for accessing the theme.
contextExtensionName String? <className> Custom name for the generated BuildContext accessor.
defaultStaticInstance bool? true Generates a static default instance ($default).
defaultStaticInstanceAsConst bool? true Generates a static default instance ($default) as const.
diagnosticable bool? true Mixes in Diagnosticable on the generated class.
equals bool? true Generates == and hashCode implementations.

Supported Types #

See the example app for the full list of supported types and current limitations here.


Contributing #

Contributions, issues, and suggestions are welcome. Open an issue or submit a pull request on GitHub

Package page on pub.dev

License #

Released under the MIT License

0
likes
160
points
586
downloads

Documentation

API reference

Publisher

verified publisheralbinpk.dev

Weekly Downloads

A zero-boilerplate code generator for Flutter ThemeExtension classes.

Repository (GitHub)
View/report issues
Contributing

Topics

#theming #theme-extension #code-generation #build-runner #source-gen

License

MIT (license)

Dependencies

meta

More

Packages that depend on easy_theme_extension