theme_extensions_gen 0.1.0
theme_extensions_gen: ^0.1.0 copied to clipboard
Theme Extensions Generator
theme_extensions_gen #
Code generation for strongly-typed, modular Flutter ThemeExtensions.
Define your visual theme structure with annotations — generate boilerplate-free implementations, context extensions, and theme lists.
🔥 Features #
- ✅ Declarative
@ThemeExtensionTemplate()interface for theme structure - ✅
@ThemeExtensionImpl()for centralized theme value lists - ✅ Auto-generated:
copyWith,lerp, equality, and mixinsBuildContextextensions- Merged
ThemeExtensionlists forThemeData debugFillProperties()ifDiagnosticableis used
- ✅ Group-based output (
light,dark, etc.) - ✅ Fully configurable via
build.yaml
📸 Before / After #
| Hand-written ThemeExtension | With @ThemeExtensionTemplate |
|---|---|
![]() |
![]() |
🧩 Annotations #
@ThemeExtensionTemplate() #
Marks an abstract interface as a ThemeExtension template. The generator creates:
- A concrete class with a factory constructor
copyWith,lerp,==,hashCodedebugFillProperties()ifDiagnosticableis used in the mixinsBuildContextextensions with accessors likecontext.brandedButtonTheme
Example:
@ThemeExtensionTemplate()
abstract interface class BrandedButtonTheme
extends ThemeExtension<BrandedButtonTheme>
with _$BrandedButtonThemeMixin, Diagnosticable {
const factory BrandedButtonTheme({
required Decoration decoration,
required TextStyle textStyle,
required EdgeInsets padding,
}) = _$BrandedButtonTheme;
}
@ThemeExtensionImpl({ String? group }) #
Marks a List<ThemeExtension> as a named implementation group to be collected into a generated file.
- Lists without
groupare merged into a default file. - Lists with
groupare merged into a separate file (e.g. fordark,light, etc.).
@ThemeExtensionImpl()
List<ThemeExtension> get someFeatureThemeExtensions => const [
BrandedCardTheme(/* ... */),
BrandedButtonTheme(/* ... */),
];
@ThemeExtensionImpl(group: 'dark')
List<ThemeExtension> get someFeatureThemeExtensions => const [
BrandedCardTheme(/* ... */),
BrandedButtonTheme(/* ... */),
];
⚙️ Configuration (build.yaml) #
targets:
$default:
builders:
themeExtensionsImplCombiner:
options:
default_output:
path: "lib/generated/theme_extensions/theme_extensions.dart"
list_name: "themeExtensions"
groups:
dark:
path: "lib/generated/theme_extensions/theme_extensions_dark.dart"
list_name: "themeExtensionsDark"
contextExtensionsGenerator:
options:
output_path: "lib/generated/theme_extensions/context_extensions.dart"
To disable contextExtensionsGenerator, use:
builders:
contextExtensionsGenerator:
enabled: false
🚀 Example Usage #
final theme = Theme.of(context).extension<BrandedCardTheme>();
// or
final theme = context.brandedCardTheme;
Works with all generated extensions automatically.
📁 Example Project #
The /example directory demonstrates:
- Shared ThemeExtension templates
- Light and dark theme implementations
- Runtime theme switching
- Organized resource files (
app_colors.dart,app_text_styles.dart, etc.)
🙏 Acknowledgements #
Special thanks to
Vladyslav Ulianytskyi
for inspiration, technical discussions, and early feedback.
Happy theming! 🎨

