flutter_theme_orchestrator 0.1.2
flutter_theme_orchestrator: ^0.1.2 copied to clipboard
A powerful Flutter theme management system with support for dynamic colors, theme scheduling, transitions, and persistence.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_theme_orchestrator/flutter_theme_orchestrator.dart';
void main() {
runApp(
ThemeOrchestrator(
child: const MyApp(),
initialTheme: ThemeData.light(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Theme Orchestrator Demo',
theme: ThemeOrchestrator.of(context).currentTheme,
darkTheme: ThemeOrchestrator.of(context).darkTheme,
themeMode: ThemeOrchestrator.of(context).themeMode,
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isDynamicColorsEnabled = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Theme Orchestrator Demo'),
actions: [
IconButton(
icon: const Icon(Icons.brightness_6),
onPressed: () {
ThemeOrchestrator.of(context).toggleTheme();
},
),
],
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildCard(
'Theme Preview',
Column(
children: [
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {},
child: const Text('Elevated Button'),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: () {},
child: const Text('Outlined Button'),
),
const SizedBox(height: 8),
TextButton(
onPressed: () {},
child: const Text('Text Button'),
),
const SizedBox(height: 8),
const TextField(
decoration: InputDecoration(
labelText: 'Text Field',
hintText: 'Enter text',
),
),
],
),
),
const SizedBox(height: 16),
_buildCard(
'Dynamic Colors',
SwitchListTile(
title: const Text('Enable Dynamic Colors'),
subtitle: const Text('Uses system colors on supported platforms'),
value: _isDynamicColorsEnabled,
onChanged: (value) {
setState(() {
_isDynamicColorsEnabled = value;
ThemeOrchestrator.of(context)
.setDynamicColorsEnabled(_isDynamicColorsEnabled);
});
},
),
),
const SizedBox(height: 16),
_buildCard(
'Theme Colors',
Wrap(
spacing: 8,
runSpacing: 8,
children: [
_buildColorButton(Colors.blue),
_buildColorButton(Colors.red),
_buildColorButton(Colors.green),
_buildColorButton(Colors.purple),
_buildColorButton(Colors.orange),
_buildColorButton(Colors.teal),
],
),
),
const SizedBox(height: 16),
_buildCard(
'Theme Scheduling',
Column(
children: [
ListTile(
title: const Text('Light Theme'),
subtitle: const Text('6:00 AM - 5:00 PM'),
leading: const Icon(Icons.wb_sunny),
onTap: () => _scheduleTheme(
const TimeOfDay(hour: 6, minute: 0),
const TimeOfDay(hour: 17, minute: 0),
ThemeData.light(),
),
),
ListTile(
title: const Text('Dark Theme'),
subtitle: const Text('5:00 PM - 6:00 AM'),
leading: const Icon(Icons.nightlight_round),
onTap: () => _scheduleTheme(
const TimeOfDay(hour: 17, minute: 0),
const TimeOfDay(hour: 6, minute: 0),
ThemeData.dark(),
),
),
],
),
),
],
),
);
}
Widget _buildCard(String title, Widget content) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
content,
],
),
),
);
}
Widget _buildColorButton(Color color) {
return InkWell(
onTap: () {
final theme = ThemeOrchestrator.of(context).createTheme(
primaryColor: color,
useDynamicColors: _isDynamicColorsEnabled,
);
ThemeOrchestrator.of(context).setTheme(
theme,
duration: const Duration(milliseconds: 500),
);
},
child: Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
),
);
}
void _scheduleTheme(TimeOfDay startTime, TimeOfDay endTime, ThemeData theme) {
ThemeOrchestrator.of(context).scheduleTheme(
ThemeSchedule(
startTime: startTime,
endTime: endTime,
theme: theme,
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Theme scheduled from ${startTime.format(context)} to ${endTime.format(context)}',
),
),
);
}
}