Flutter Artist Theme - Create a custom theme
Changing your app’s appearance is not just about colors; it’s about shaping the entire user experience. With FlutterArtist Theme, you get a flexible system that allows you to define your own design language in a structured and scalable way.
1. Create a custom Theme
Let’s start by creating a custom theme by extending FaTheme. This is the foundation where you gain full control over your Design Tokens.
LeantekTheme
class LeantekTheme extends FaTheme {
@override
String get name => FaThemeHub.defaultThemeName;
@override
IconData get icon => Icons.business_center_outlined;
@override
Color get seedColor => const Color(0xFF056AB4);
@override
Brightness get brightness => Brightness.light;
@override
String? get fontFamily => null;
@override
FaThemeTokens createThemeTokens() {
final colors = const FaColorTokens(
primary: Color(0xFF056AB4),
onPrimary: Colors.white,
secondary: Color(0xFFFF9900),
onSecondary: Colors.black,
tertiary: Color(0xFF22C55E),
onTertiary: Colors.white,
error: Color(0xFFDC2626),
onError: Colors.white,
background: Color(0xFFE7F0FC),
surface: Colors.white,
onSurface: Color(0xFF10324A),
onSurfaceVariant: Color(0xFF5F6B7A),
surfaceContainerLowest: Color(0xFFFFFFFF),
surfaceContainerLow: Color(0xFFF1F7FE),
surfaceContainer: Color(0xFFE1EDF9),
surfaceContainerHigh: Color(0xFFD6E4F2),
surfaceContainerHighest: Color(0xFFCCD9E7),
textPrimary: Color(0xFF10324A),
textSecondary: Color(0xFF5F6B7A),
border: Color(0xFFCCD9E7),
outline: Color(0xFFB8C6D8),
outlineVariant: Color(0xFFCCD9E7),
shadow: Colors.black,
scrim: Colors.black54,
inverseSurface: Color(0xFF1B2A38),
onInverseSurface: Colors.white,
inversePrimary: Color(0xFF9CCBFF),
divider: Color(0xFFCCD9E7),
);
return FaThemeTokens(
colors: colors,
spacing: const FaSpacingTokens(xs: 4, sm: 8, md: 12, lg: 16, xl: 24),
elevation: const FaElevationTokens(level1: 2, level2: 4, level3: 6),
radius: const FaRadiusTokens(sm: 4, md: 8, lg: 12, xl: 16),
typography: FaTypographyTokens(),
components: const FaComponentTokens(),
layout: const FaLayoutTokens(
metrics: FaLayoutMetricsTokens(),
colors: FaLayoutColorTokens(
sidebarSurface: Color(0xFF10324A),
onSidebarSurface: Colors.white,
topbarSurface: Colors.white,
onTopbarSurface: Color(0xFF056AB4),
),
),
motion: const FaMotionTokens(),
);
}
}
To better understand how tokens work together, consider reading:
2. FaColorTokens
FaColorTokens allows you to override colors generated automatically from the seedColor. By default, the system generates a complete color palette (primary, secondary, surface, etc.). However, you can override any part when needed.
Simple Override
Only override what you actually care about.
FaColorTokens(
primary: Color(0xFF056AB4),
onPrimary: Colors.white,
);No ADS
Advanced Override
When working with pixel-perfect UI/UX designs, you can fully control the color system.
FaColorTokens(
primary: Color(0xFF056AB4),
onPrimary: Colors.white,
secondary: Color(0xFFFF9900),
onSecondary: Colors.black,
// Override more tokens as needed
surfaceContainerLow: Color(0xFFF1F7FE),
border: Color(0xFFCCD9E7),
);FlutterArtist is designed so you can get started quickly…while still giving you full control when you need it.
3. FaTypographyTokens
Typography is more than just choosing a font — it determines how users “read” and “understand” your interface. In FlutterArtist, FaTypographyTokens allows you to control your entire type system consistently and scientifically.
The Flutter Typography System
Flutter provides 15 standard text styles based on Material Design, covering every possible display scenario.
- Display: Large, Medium, Small
- Headline: Large, Medium, Small
- Title: Large, Medium, Small
- Body: Large, Medium, Small
- Label: Large, Medium, Small
But in Reality...
You won’t use all 15 styles in most applications. In most cases, only a few styles are used consistently across the app.
- titleMedium: Used for Card titles, Dialogs or lists. Not as large as a headline, but still prominent enough for information hierarchy.
- bodyMedium: The core content style. Used for descriptions and articles, optimized for long-term readability.
- labelLarge: Action labels. Used for buttons and short labels, often with a higher font-weight to draw focus to actions.
No ADS
Customization Example
You can override only these critical styles instead of reconfiguring the entire system.
FaTypographyTokens(
titleMedium: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
bodyMedium: const TextStyle(
fontSize: 14,
height: 1.5,
fontWeight: FontWeight.w400,
),
labelLarge: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 0.5,
),
);4. FaLayoutTokens
Layout is more than just dimensions — it determines how users navigate and perceive your app's structure. In FlutterArtist, FaLayoutTokens empowers you to control key layout components like the Sidebar and Topbar with consistency and flexibility.
The Structure of FaLayoutTokens
The layout system is divided into two distinct parts, allowing you to separate spatial logic from aesthetic design:
- metrics: Manages dimensions and geometric structure
- colors: Manages specific colors for layout components.
FaLayoutTokens Example
FaLayoutTokens(
metrics: FaLayoutMetricsTokens(
sidebarWidth: 260,
contentMaxWidth: null,
),
colors: FaLayoutColorTokens(
sidebarSurface: Color(0xFF10324A),
onSidebarSurface: Colors.white,
topbarSurface: Colors.white,
onTopbarSurface: Color(0xFF056AB4),
),
);5. What to do after having a custom theme?
After successfully creating a custom FaTheme and registering it, there’s one important thing to keep in mind:
- Not every value you define will automatically reflect in your UI.
Some of the properties you define will be overridden by ColorScheme and TextTheme, and Flutter will immediately apply them to standard elements such as Scaffold, AppBar, Button or Text, etc.
However, many other parts of your system — especially Theme Extensions like FaRadiusTokens, FaSpacingTokens, or layout tokens — will remain unused unless you explicitly apply them in your UI.
In other words: You’ve built a powerful design system—but you still need to activate it.
A Practical Example
Imagine you're building an Access Control Panel with a message and two action buttons.
Container(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Text("Are you sure you want to grant permission?"),
ElevatedButton(onPressed: () {}, child: Text("Cancel")),
ElevatedButton(onPressed: () {}, child: Text("Confirm")),
],
),
)Why is this not good enough?
At first glance, it may seem “good enough,” but in a real interface, something will feel slightly off. This layout lacks visual cohesion. The Container has no background to separate it from surrounding elements, making the whole block feel like it is “floating” in space.
Both “Cancel” and “Confirm” buttons are using the same default styling (colorScheme.primary for the background and colorScheme.onPrimary for the text). Even if you have customized colors in MyCustomTheme, having both buttons look so similar makes it hard for users to identify the primary action.
From a UX perspective, the “Confirm” button should stand out more—through color, weight, or contrast—to guide the user’s attention and support quicker, more confident decisions.
No ADS
The Professional Way with FaColorUtils
To make the interface look professional, we need to:
- Apply a slightly different background color to the Container than the main background.
- Use a more eye-catching color for the "Confirm" button.
- Use a softer color for the "Cancel" button.
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: FaColorUtils.surfaceContainerLow(context),
borderRadius: BorderRadius.circular(context.faTokens.radius.md),
),
child: Row(
children: [
Expanded(
child: Text(
"Are you sure you want to grant access?",
style: TextStyle(
color: FaColorUtils.primaryContent(context),
),
),
),
ElevatedButton(
onPressed: () {},
child: Text(
"Cancel",
style: TextStyle(
color: FaColorUtils.infoText(context),
),
),
),
const SizedBox(width: 8),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: FaColorUtils.primaryHighlight(context),
foregroundColor: FaColorUtils.onHighlightText(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
context.faTokens.radius.sm,
),
),
),
onPressed: () {},
child: const Text("Confirm"),
),
],
),
)Creating a custom FaTheme is like building a comprehensive resource warehouse. But to turn those resources into actual products, you must still "work" by using FaColorUtils and accessing Tokens (like FaRadiusTokens) to apply them to specific Widgets.
Don't let your sophisticated settings stay hidden in the code. Master how to bring them into the real world in our next post:
No ADS
FlutterArtist
- Basic concepts in Flutter Artist
- FlutterArtist Block ex1
- FlutterArtist Filter Example
- FlutterArtist FilterModel MultiOptFilterCriterion ex1
- FlutterArtist FilterInput Example 1
- FlutterArtist Form ex1
- The idea of designing filter models in FlutterArtist
- FlutterArtist FormModel.patchFormFields() Ex1
- FlutterArtist BlockQuickItemUpdateAction Example
- FlutterArtist BlockNumberPagination Ex1
- FlutterArtist GridView Infinite Scroll Example
- FlutterArtist BlockQuickMultiItemCreationAction Example
- FlutterArtist ListView Infinite Scroll Pagination Example
- FlutterArtist Pagination
- FlutterArtist Sort DropdownSortPanel Example
- FlutterArtist Dio
- FlutterArtist BlockBackendAction Example
- FlutterArtist BackgroundWebDownloadAction Example
- FlutterArtist StorageBackendAction ex1
- FlutterArtist Block External Shelf Event Example
- FlutterArtist Filter FormBuilderMultiDropDown Ex1
- FlutterArtist Master-detail Blocks ex1
- FlutterArtist Scalar ex1
- FlutterArtist Pagination Davi table Infinite Scroll Ex1
- FlutterArtist Filter Tree FormBuilderField ex1
- FlutterArtist Filter FormBuilderRadioGroup ex1
- FlutterArtist Form Parent-child MultiOptFormProp ex1
- FlutterArtist Manual Sorting ReorderableGridView Example
- FlutterArtist Manual Sorting ReorderableListView
- FlutterArtist Scalar External Shelf Event Example
- FlutterArtist Code Flow Viewer
- FlutterArtist Log Viewer
- FlutterArtist config
- FlutterArtist StorageStructure
- FlutterArtist Debug Storage Viewer
- FlutterArtist DebugMenu
- FlutterArtist Debug UI Components Viewer
- FlutterArtist Debug Shelf Structure Viewer
- FlutterArtist Context Provider Views
- FlutterArtist FilterModelStructure ex1
- FlutterArtist FilterModelStructure ex2
- FlutterArtist FilterModelStructure ex3
- FlutterArtist Internal Shelf Event ex1
- FlutterArtist Deferring External Shelf Events Example
- FlutterArtist DropdownSortPanel
- Overview of FlutterArtist Theme
- FlutterArtist Theme Design Tokens Architecture
- FlutterArtist Themes FaColorUtils
- Flutter Artist Theme - Create a custom theme
Show More