app_theme_picker 0.1.3
app_theme_picker: ^0.1.3 copied to clipboard
A Flutter package template.
App Theme Picker #
A beautiful and customizable Flutter package for theme selection with support for multiple color schemes and theme modes (light, dark, system). Built with Flutter Riverpod for state management and FlexColorScheme for beautiful color schemes.
Features #
✨ Beautiful Theme Selection UI: Elegant interface for picking color schemes
🎨 Multiple Color Schemes: Support for all FlexColorScheme color schemes
🌙 Theme Mode Support: Light, Dark, and System theme modes
💾 Persistent Settings: Theme preferences are saved automatically
🌍 Internationalization: Built-in localization support (English, Japanese, Korean, Chinese)
⚡ State Management: Powered by Flutter Riverpod for reactive state management
🎯 Customizable: Configurable button sizes and available color schemes
Screenshots #
The theme picker provides an intuitive interface with:
- Theme mode buttons (Light/Dark/System) at the top
- Grid of colorful theme buttons showing available color schemes
- Real-time preview of selected themes
- Persistent theme selection across app restarts
Installation #
Add this package to your pubspec.yaml:
dependencies:
app_theme_picker: ^0.0.1
Then run:
flutter pub get
Dependencies #
This package requires the following dependencies (automatically installed):
flutter_riverpod: ^2.6.1- State managementflex_color_scheme: ^8.2.0- Beautiful color schemeseasy_localization: ^3.0.7- Internationalizationriverpod_helper: ^0.0.3- Riverpod utilities
Quick Start #
1. Basic Setup #
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:app_theme_picker/app_theme_picker.dart';
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeAsync = ref.watch(themePodProvider);
final themeModeAsync = ref.watch(themeModePodProvider);
return MaterialApp(
title: 'Theme Picker Demo',
theme: themeAsync.when(
data: (flexScheme) => FlexThemeData.light(scheme: flexScheme),
loading: () => FlexThemeData.light(scheme: FlexScheme.sakura),
error: (_, __) => FlexThemeData.light(scheme: FlexScheme.sakura),
),
darkTheme: themeAsync.when(
data: (flexScheme) => FlexThemeData.dark(scheme: flexScheme),
loading: () => FlexThemeData.dark(scheme: FlexScheme.sakura),
error: (_, __) => FlexThemeData.dark(scheme: FlexScheme.sakura),
),
themeMode: themeModeAsync.when(
data: (mode) => mode,
loading: () => ThemeMode.light,
error: (_, __) => ThemeMode.light,
),
home: HomeScreen(),
);
}
}
2. Add Theme Picker Page #
import 'package:app_theme_picker/app_theme_picker.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('My App')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PickThemePage(
size: 60.0, // Button size
),
),
);
},
child: Text('Choose Theme'),
),
),
);
}
}
3. Using Theme Picker Tile #
For a more compact interface, use the ThemePickTile:
import 'package:app_theme_picker/app_theme_picker.dart';
ListTile(
title: Text('Theme'),
subtitle: ThemePickTile(
size: 40.0,
availableSchemes: {'sakura', 'material', 'blue'}, // Optional: limit schemes
),
)
Advanced Usage #
Custom Available Schemes #
You can limit which color schemes are available:
PickThemePage(
size: 60.0,
availableSchemes: {
'material',
'materialHc',
'blue',
'indigo',
'sakura',
'mandyRed',
},
)
Individual Theme Components #
Use individual components for custom layouts:
// Theme mode buttons
Row(
children: [
ThemeModeButton(mode: ThemeMode.light),
ThemeModeButton(mode: ThemeMode.system),
ThemeModeButton(mode: ThemeMode.dark),
],
)
// Individual color button
ThemeColorButton(
schemeData: FlexColor.schemes[FlexScheme.sakura]!,
onTap: () {
ref.read(themePodProvider.notifier).changeTheme(FlexScheme.sakura);
},
size: 50.0,
selected: currentScheme == FlexScheme.sakura,
)
Accessing Theme State #
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Watch current theme
final currentTheme = ref.watch(themePodProvider);
final currentThemeMode = ref.watch(themeModePodProvider);
// Programmatically change theme
void changeToSakura() {
ref.read(themePodProvider.notifier).changeTheme(FlexScheme.sakura);
}
void changeToDarkMode() {
ref.read(themeModePodProvider.notifier).changeThemeMode(ThemeMode.dark);
}
return YourWidget();
}
}
Localization #
The package supports multiple languages out of the box:
- English (en-US)
- Japanese (ja-JP)
- Korean (ko)
- Chinese (zh-CN)
To enable localization in your app, set up easy_localization:
import 'package:easy_localization/easy_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en', 'US'),
Locale('ja', 'JP'),
Locale('ko'),
Locale('zh', 'CN'),
],
path: 'assets/localizations',
fallbackLocale: Locale('en', 'US'),
child: ProviderScope(child: MyApp()),
),
);
}
Testing with Mocks #
The package provides mock implementations for testing purposes. These are useful when you need to override theme providers in your tests.
Available Theme Mocks #
All 69 FlexScheme themes have corresponding mock classes:
import 'package:app_theme_picker/app_theme_picker.dart';
// Material Design themes
MaterialThemeMock()
MaterialHcThemeMock()
BlueThemeMock()
IndigoThemeMock()
// Color-based themes
SakuraThemeMock()
MandyRedThemeMock()
RedThemeMock()
RedWineThemeMock()
// ... and 60+ more theme mocks
// Custom theme
CustomThemeMock()
Available Theme Mode Mocks #
import 'package:app_theme_picker/app_theme_picker.dart';
// Theme mode mocks
LightThemeModeMock() // Returns ThemeMode.light
DarkThemeModeMock() // Returns ThemeMode.dark
Using Mocks in Tests #
You can override providers with mocks in your widget tests:
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:app_theme_picker/app_theme_picker.dart';
void main() {
testWidgets('Test with sakura theme', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
// Override theme provider with mock
themePodProvider.overrideWith((ref) => SakuraThemeMock()),
// Override theme mode provider with mock
themeModePodProvider.overrideWith((ref) => DarkThemeModeMock()),
],
child: MyApp(),
),
);
// Your test code here
});
}
Example: Testing Different Theme Combinations #
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:app_theme_picker/app_theme_picker.dart';
void main() {
group('Theme Tests', () {
testWidgets('Test with Material theme in light mode', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
themePodProvider.overrideWith((ref) => MaterialThemeMock()),
themeModePodProvider.overrideWith((ref) => LightThemeModeMock()),
],
child: MyApp(),
),
);
// Verify light theme is applied
// Your assertions here
});
testWidgets('Test with Sakura theme in dark mode', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
themePodProvider.overrideWith((ref) => SakuraThemeMock()),
themeModePodProvider.overrideWith((ref) => DarkThemeModeMock()),
],
child: MyApp(),
),
);
// Verify dark theme is applied
// Your assertions here
});
});
}
Using Pre-defined Overrides #
For convenience, the package provides pre-defined override variables that make testing even easier:
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:app_theme_picker/app_theme_picker.dart';
void main() {
testWidgets('Test with pre-defined overrides', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
// Use pre-defined override variables
sakuraThemeOverride,
darkThemeOverride,
],
child: MyApp(),
),
);
// Your test code here
});
}
Available Pre-defined Overrides #
Theme Mode Overrides:
lightThemeOverride // Sets theme mode to light
darkThemeOverride // Sets theme mode to dark
Theme Overrides:
All 69 FlexScheme themes have corresponding override variables following the pattern {schemeName}ThemeOverride:
// Material Design
materialThemeOverride
materialHcThemeOverride
materialBaselineThemeOverride
// Blue variants
blueThemeOverride
indigoThemeOverride
hippieBlueThemeOverride
aquaBlueThemeOverride
brandBlueThemeOverride
deepBlueThemeOverride
// ... and more
// Popular themes
sakuraThemeOverride
mandyRedThemeOverride
redThemeOverride
greenThemeOverride
goldThemeOverride
// Material 3 colors
redM3ThemeOverride
pinkM3ThemeOverride
blueM3ThemeOverride
// ... all M3 colors
// Shadcn inspired
shadBlueThemeOverride
shadGrayThemeOverride
shadGreenThemeOverride
// ... all shad variants
customThemeOverride
Complete List of Theme Mocks #
Click to expand all 69 theme mocks
Material Design Themes:
MaterialThemeMock- Material Design guide exampleMaterialHcThemeMock- Material high contrastMaterialBaselineThemeMock- Material 3 baseline
Blue Themes:
BlueThemeMock,IndigoThemeMock,HippieBlueThemeMock,AquaBlueThemeMockBrandBlueThemeMock,DeepBlueThemeMock,BahamaBlueThemeMock,SanJuanBlueThemeMockBlumineBlueThemeMock,BlueWhaleThemeMock,EbonyClayThemeMock,BigStoneThemeMock
Red/Pink Themes:
SakuraThemeMock,MandyRedThemeMock,RedThemeMock,RedWineThemeMockBarossaThemeMock,DamaskThemeMock,RosewoodThemeMock
Purple/Brown Themes:
PurpleBrownThemeMock,DeepPurpleThemeMock
Green Themes:
GreenThemeMock,MoneyThemeMock,JungleThemeMock,MallardGreenThemeMockVerdunHemlockThemeMock,DellGenoaThemeMock
Yellow/Gold/Orange Themes:
GoldThemeMock,MangoThemeMock,AmberThemeMock,VesuviusBurnThemeMock
Grey/Neutral Themes:
GreyLawThemeMock,WasabiThemeMock,SharkThemeMock,EspressoThemeMockOuterSpaceThemeMock
Special Themes:
FlutterDashThemeMock- Based on Flutter Dash mascot
Material 3 Color Themes:
RedM3ThemeMock,PinkM3ThemeMock,PurpleM3ThemeMock,IndigoM3ThemeMockBlueM3ThemeMock,CyanM3ThemeMock,TealM3ThemeMock,GreenM3ThemeMockLimeM3ThemeMock,YellowM3ThemeMock,OrangeM3ThemeMock,DeepOrangeM3ThemeMock
Monochrome Themes:
BlackWhiteThemeMock,GreysThemeMock,SepiaThemeMock
Shadcn Inspired Themes:
ShadBlueThemeMock,ShadGrayThemeMock,ShadGreenThemeMock,ShadNeutralThemeMockShadOrangeThemeMock,ShadRedThemeMock,ShadRoseThemeMock,ShadSlateThemeMockShadStoneThemeMock,ShadVioletThemeMock,ShadYellowThemeMock,ShadZincThemeMock
Custom:
CustomThemeMock- Placeholder for custom themes
API Reference #
PickThemePage #
Main theme selection page widget.
| Parameter | Type | Description | Default |
|---|---|---|---|
size |
double |
Size of theme color buttons | Required |
availableSchemes |
Set<String>? |
Limit available color schemes | null (all schemes) |
ThemePickTile #
Compact theme selection tile widget.
| Parameter | Type | Description | Default |
|---|---|---|---|
size |
double |
Size of theme color buttons | 40.0 |
availableSchemes |
Set<String>? |
Limit available color schemes | null (all schemes) |
ThemeColorButton #
Individual color scheme button.
| Parameter | Type | Description | Default |
|---|---|---|---|
schemeData |
FlexSchemeData |
Color scheme data | Required |
onTap |
VoidCallback |
Tap callback | Required |
selected |
bool |
Whether button is selected | Required |
size |
double |
Button size | 50.0 |
ThemeModeButton #
Individual theme mode button (Light/Dark/System).
| Parameter | Type | Description | Default |
|---|---|---|---|
mode |
ThemeMode |
Theme mode | Required |
State Providers #
themePodProvider: Current color scheme (AsyncValue<FlexScheme>)themeModePodProvider: Current theme mode (AsyncValue<ThemeMode>)
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Author #
Normidar
Support #
If you find this package helpful, please consider:
- ⭐ Starring the repository
- 🐛 Reporting bugs
- 💡 Suggesting new features
- ☕ Sponsoring the developer
Changelog #
See CHANGELOG.md for a detailed list of changes.