Guides

Adding Theme Properties

Extend Forui themes with application-specific properties using Flutter's ThemeExtension system.

Create a Theme Extension

Theme extensions must extend ThemeExtension and implement copyWith() and lerp(). Extensions to FTypography or FTypeface must instead extend FScalableExtension which has an additional scale(...) method.

To add brand colors to your theme, create a BrandColors extension:

1import 'package:flutter/material.dart';
2
3class BrandColors extends ThemeExtension<BrandColors> {
4 final Color accent;
5 final Color accentForeground;
6
7 const BrandColors({required this.accent, required this.accentForeground});
8
9 @override
10 BrandColors copyWith({Color? accent, Color? accentForeground}) => BrandColors(
11 accent: accent ?? this.accent,
12 accentForeground: accentForeground ?? this.accentForeground,
13 );
14
15 @override
16 BrandColors lerp(BrandColors? other, double t) {
17 if (other is! BrandColors) {
18 return this;
19 }
20
21 return BrandColors(
22 accent: .lerp(accent, other.accent, t)!,
23 accentForeground: .lerp(accentForeground, other.accentForeground, t)!,
24 );
25 }
26}
27

Then add it to FColors via its extensions parameter:

1FColors(
2 brightness: .light,
3 systemOverlayStyle: .dark,
4 barrier: const Color(0x33000000),
5 background: const Color(0xFFFFFFFF),
6 foreground: const Color(0xFF0A0A0A),
7 primary: const Color(0xFF171717),
8 primaryForeground: const Color(0xFFFAFAFA),
9 secondary: const Color(0xFFF5F5F5),
10 secondaryForeground: const Color(0xFF171717),
11 muted: const Color(0xFFF5F5F5),
12 mutedForeground: const Color(0xFF737373),
13 destructive: const Color(0xFFE7000B),
14 destructiveForeground: const Color(0xFFFAFAFA),
15 error: const Color(0xFFE7000B),
16 errorForeground: const Color(0xFFFAFAFA),
17 card: const Color(0xFFFFFFFF),
18 border: const Color(0xFFE5E5E5),
19 extensions: [
20 const BrandColors(
21 accent: Color(0xFF6366F1),
22 accentForeground: Color(0xFFFFFFFF),
23 ),
24 ],
25);
26

You can also add extensions to existing themes using copyWith(...):

1final colors = FThemes.neutral.light.touch.colors.copyWith(
2 extensions: [
3 const BrandColors(
4 accent: Color(0xFF6366F1),
5 accentForeground: Color(0xFFFFFFFF),
6 ),
7 ],
8);
9

Both patterns also work on FThemeData, FTypography, and FStyle.

Accessing the Properties

Retrieve your custom theme extension via extension<T>() on the container it was added to:

1@override
2Widget build(BuildContext context) {
3 final brand = context.theme.colors.extension<BrandColors>();
4 return DecoratedBox(
5 decoration: BoxDecoration(
6 color: brand.accent,
7 border: .all(color: brand.accentForeground),
8 ),
9 );
10}
11

We recommend creating a getter on that container:

1extension BrandColorsExtension on FColors {
2 BrandColors get brand => extension<BrandColors>();
3
4 // Alternatively, you can create a getter to access extension fields directly.
5 Color get accent => extension<BrandColors>().accent;
6}
7

On this page