Style Generation Tools and Packages

Content

  1. An example of organizing and working with topics through context

  2. A little bit about code generation

How to work with themes

Flutter has a built-in tool for working with themes – ThemeData. It stores all styles for all entities. For example, you can override TextTheme and customize the fonts in the app or change the background for Scaffold. But what if 12 text styles are not enough for you?

Store themes in BuildContext

If you don't have enough fields in TextTheme or you want to add more colors to the app, use ThemeExtension. ThemeExtension Allows you to store your own theme properties.

Let's look at the example of text styles
First, you need to create a file that will inherit ThemeExtension. In our case it will be AppThemeTextStyles. You need to add the necessary text styles immediately.

  1. Constructor

  2. copyWith method

  3. The lerp method

class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles>{

final TextStyle header;  
final TextStyle body;  
  
const AppThemeTextStyles({  
  required this.header,  
  required this.body,  
});

@override  
$AppThemeTextStyles copyWith({  
  TextStyle? header,  
  TextStyle? body,  
}) {  
  return AppThemeTextStyles(  
    header: header ?? this.header,  
    body: body ?? this.body,  
  );  
}  
  
@override  
AppThemeTextStyles lerp(  
    ThemeExtension<AppThemeTextStyles>? other, double t) {  
  if (other is! AppThemeTextStyles) return this;  
  return AppThemeTextStyles(  
    header: TextStyle.lerp(header, other.header, t)!,  
    body: TextStyle.lerp(body, other.body, t)!,  
  );  
}
}

Great, now we can create darkTextStyle, lightTextStyle, blueTextStyle or any other TextStyle.

static const AppThemeTextStyles darkTextStyle = AppThemeTextStyles(  
  header: TextStyle(  
  fontSize: 24,  
  fontWeight: FontWeight.bold,  
  color: Colors.black,  
),  
  body: TextStyle(  
  fontSize: 16,  
  fontWeight: FontWeight.normal,  
  color: Colors.black,  
),  
);  
static const AppThemeTextStyles lightTextStyle = AppThemeTextStyles(  
  header: TextStyle(  
  fontSize: 24,  
  fontWeight: FontWeight.bold,  
  color: Colors.blue,  
),  
  body: TextStyle(  
  fontSize: 16,  
  fontWeight: FontWeight.normal,  
  color: Colors.blue,  
),  
);  
static const AppThemeTextStyles blueTextStyle = AppThemeTextStyles(  
  header: TextStyle(  
  fontSize: 16,  
  fontWeight: FontWeight.normal,  
  color: Colors.black,  
),  
  body: TextStyle(  
  fontSize: 24,  
  fontWeight: FontWeight.bold,  
  color: Colors.white,  
);

Now we need to add our extension to the theme.

ThemeData createLightTheme(){  
  return ThemeData(  
    extensions: const <ThemeExtension<dynamic>>[  
      lightTextStyle,  
    ],  
  );  
}

ThemeData createDarkTheme(){  
  return ThemeData(  
    extensions: const <ThemeExtension<dynamic>>[  
      darkTextStyle,  
    ],  
  );  
}

And to add style data to BuildContext you just need to create an extension (extension).

extension BuildContextExtention on BuildContext {  
  AppThemeTextStyles get appText =>  
      Theme.of(this).extension<AppThemeTextStyles>()!;  

}

And that's it. Now you can access text styles via context.appText.header. The style will depend on the selected application theme. You can add anything: colors, text styles – anything that may depend on the selected theme.

Is it really that convenient?

Yes, but to add style you need to enter it in several places in ThemeExtension.

Is it possible to automate this somehow?

Yes, there is a package for working with themes. theme_tailor.

And I wrote a small code generator: extension_theme_generator. It generates a file for text styles and colors. It works simply:

  • We mark the decorator @TextStyleAnnotation() all text styles.

  • We mark the decorator @ColorAnnotation() classes with flowers.

// Пример для работы с цветами
@ColorAnnotation()  
class LightColors {  
  static const Color primary = Color(0xFFFFFFFF);  
  static const Color secondary = Color(0xFFEEEEEE);  
  static const Color background = Color(0xFFEDF6F6);  
}  
  
@ColorAnnotation()  
class DarkColors {  
  static const Color primary = Color(0xFF000000);  
  static const Color secondary = Color(0xFF111111);  
  static const Color textColor = Color(0xFF111111);  // Также создастся, но для `LightColors` будет красным.
  
  static const Color background = Color(0xFF015D60);  
  
}
  • Run the command flutter pub run build_runner build.

  • Profit! It remains to add the created ones AppThemeColors And AppTextStyles in your topics.

Example with code generator

Full example here

//example/lib/theme
import 'package:flutter/material.dart';  
import 'package:extension_theme_generator/extension_theme_generator.dart';  
  
part 'text_styles.dart'; // Тут все текстовые стили 
part 'app_colors.dart';  /// тут все для цветов
  
part 'theme.g.dart'; /// путь до выходного файла
//example/lib/theme/text_styles.dart
part of 'theme.dart';  
  
@TextStyleAnnotation()  
class DarkTextStyle {  
  static const TextStyle header = TextStyle(  
    fontSize: 24,  
    fontWeight: FontWeight.bold,  
    color: Colors.white,  
  );  
}  
  
  
@TextStyleAnnotation()  
class LightTextStyle {  
  static const TextStyle header = TextStyle(  
    fontSize: 24,  
    fontWeight: FontWeight.bold,  
    color: Colors.black,  
  );  
}  
// example/lib/theme/app_colors.dart
part of 'theme.dart';  
  
@ColorAnnotation()  
class LightColors {  
  static const Color primary = Color(0xFFFFFFFF);  
  static const Color secondary = Color(0xFFEEEEEE);  
}  
  
@ColorAnnotation()  
class DarkColors {  
  static const Color primary = Color(0xFF000000);  
  static const Color secondary = Color(0xFF111111);  
  
}  
  

Visit the author's telegram channel you can visit here

Give the programmer some coffeehe still has to feed the dog,

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *