theme_extensions_gen 0.1.2
theme_extensions_gen: ^0.1.2 copied to clipboard
Generate Flutter ThemeExtensions from annotated templates with context accessors and no boilerplate.

theme_extensions_gen #
A modular, annotation-based code generation system for scalable theming in Flutter using
ThemeExtension
.
#
π₯ Features #
- β
Declarative
@ThemeExtensionTemplate()
interface for theme structure - β
@ThemeExtensionImpl()
for centralized theme value lists - β
Auto-generated:
copyWith
,lerp
, equality, and mixinsBuildContext
extensions- Merged
ThemeExtension
lists forThemeData
debugFillProperties()
ifDiagnosticable
is 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
,==
,hashCode
debugFillProperties()
ifDiagnosticable
is used in the mixinsBuildContext
extensions 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
group
are merged into a default file. - Lists with
group
are 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;
π Example Project #
See the
example/
for:
- 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! π¨