best_theme 0.0.4 copy "best_theme: ^0.0.4" to clipboard
best_theme: ^0.0.4 copied to clipboard

Theme management package for Flutter with light and dark mode support.

Best Theme #


Best Theme is a powerful Flutter package designed to simplify theme management within your applications. It provides an intuitive way to define and switch between light and dark modes while allowing you to add your own custom colors with seamless context-based access. ac

Table of Contents #

Features #

  • Easy Theme Management: Effortlessly manage themes for your Flutter application.
  • Custom Color Support: Add your own colors with defined light and dark variations.
  • Theme Mode Toggling: Easily toggle between different theme modes, including System, Light, and Dark.
  • Context-based Access: Access colors and theme functions directly through BuildContext extensions.
  • GoRouter Support: Full support for declarative routing solutions like GoRouter.
  • Automatic Theme Switching: Seamless theme switching with real-time updates.

Installation #

To install the Best Theme package, run the following commands in your terminal:

flutter pub add best_theme
flutter pub add best_theme_annotation
dart pub add best_theme_generator
dart pub add dev:build_runner

Usage #

1. Create Theme File with Colors and Class Definition #

Create a theme file (e.g., my_theme.dart) and define your colors along with the theme class:

import 'package:best_theme/best_theme.dart';
import 'package:best_theme_annotation/best_theme_annotation.dart';
import 'package:flutter/material.dart';

part 'my_theme.g.dart';

// Define your colors first
List<BestColor> dataColor = [
  const BestColor(name: 'primary', light: Colors.blue, dark: Colors.indigo),
  const BestColor(name: 'text', light: Colors.black87, dark: Colors.white70),
  const BestColor(name: 'color1', light: Color(0xffFCB949), dark: Color(0xffEBED6B)),
  const BestColor(name: 'color2', light: Color(0xff10161C), dark: Colors.white),
];

// Create theme class with vars based on your defined colors
@BestTheme(vars: [
  'primary',
  'text',
  'color1',
  'color2',
])
class MyTheme extends _$MyTheme {
  MyTheme() : super(myColors: dataColor, mode: ThemeMode.system);
}

After creating your theme file, run the code generation:

dart run build_runner build
# or for continuous generation
dart run build_runner watch
# or to resolve conflicts
dart run build_runner watch --delete-conflicting-outputs

2. Wrap Your App with BestTheme #

Use the context to wrap your app with BestTheme:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return context.BestTheme(
      materialApp: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

3. Using Custom Colors #

Access your custom colors directly through the context:

Container(
  width: 100,
  height: 100,
  decoration: BoxDecoration(
    color: context.myColors.primary,
    border: Border.all(color: context.myColors.color1),
  ),
  child: Text(
    'Example',
    style: TextStyle(color: context.myColors.text),
  ),
);

All your defined colors are available through context.myColors.[colorName]:

  • context.myColors.primary
  • context.myColors.text
  • context.myColors.color1
  • context.myColors.color2

4. Theme Control #

Toggle and control themes using context extensions:

// Toggle between light and dark
context.toggleTheme();

// Set specific theme modes
context.toDarkTheme();
context.toLightTheme();
context.toSystemTheme();

// Advanced toggle with specific mode
context.advanceToggle(ThemeMode.dark);

// Check current theme state
bool isDarkMode = context.isDark;

5. Theme Toggle Switch Example #

Switch(
  value: context.isDark,
  onChanged: (value) {
    context.toggleTheme();
  },
);

6. Complete Example with Custom Colors #

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: context.myColors.primary,
        title: Text(
          'Best Theme Demo',
          style: TextStyle(color: Colors.white),
        ),
        actions: [
          Switch(
            value: context.isDark,
            onChanged: (value) => context.toggleTheme(),
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: context.myColors.color1,
                borderRadius: BorderRadius.circular(8),
                border: Border.all(color: context.myColors.color2),
              ),
              child: Text(
                'This container adapts to your theme!',
                style: TextStyle(color: context.myColors.text),
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              style: ElevatedButton.styleFrom(
                backgroundColor: context.myColors.color1,
              ),
              onPressed: () {},
              child: Text('Accent Button'),
            ),
          ],
        ),
      ),
    );
  }
}

7. Custom Font Support #

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return context.BestTheme(
      materialApp: MaterialApp(
        title: 'My App',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: context.myColors.primary),
          scaffoldBackgroundColor: context.myColors.background,
          useMaterial3: true,
          fontFamily: 'MyCustomFont',
        ),
        darkTheme: ThemeData.dark().copyWith(
          colorScheme: ColorScheme.fromSeed(seedColor: context.myColors.primary),
          scaffoldBackgroundColor: context.myColors.background,
          textTheme: ThemeData.dark().textTheme.apply(fontFamily: 'MyCustomFont'),
        ),
        home: const HomePage(),
      ),
    );
  }
}

8. GoRouter Support #

For apps using GoRouter or other declarative routing solutions:

class MyApp extends StatelessWidget {
  final GoRouter router = GoRouter(
    routes: [
      GoRoute(
        path: '/',
        builder: (context, state) => const HomePage(),
      ),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return context.BestThemeRouter(
      materialApp: MaterialApp.router(
        routerConfig: router,
        title: 'My App with GoRouter',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: context.myColors.primary),
          useMaterial3: true,
        ),
      ),
    );
  }
}

API Reference #

Context Extensions #

Extension Method Description
context.myColors.[colorName] Access any defined custom color
context.isDark Check if current mode is dark
context.toggleTheme() Toggle between light and dark themes
context.toDarkTheme() Switch to dark theme
context.toLightTheme() Switch to light theme
context.toSystemTheme() Switch to system theme
context.advanceToggle(ThemeMode mode) Advanced toggle with specified mode
context.BestTheme(materialApp: ...) Wrap app with BestTheme
context.BestThemeRouter(materialApp: ...) Wrap router app with BestTheme

Available Properties #

Access these properties through the generated instance:

Property Description
isDark Check if current mode is dark
typeOfThemes Return all theme mode types
currentTheme Return current theme mode
myColors Return all defined colors

Additional Methods #

Method Description
toggle() Toggle theme
toSystem(context) Switch to system theme
toLight() Switch to light theme
toDark() Switch to dark theme
adanceToggle(context: context, mode: ThemeMode.?) Advanced toggle with specified mode

Short Methods for Theme Colors #

Method Description
theme(context) Get the current theme context
primaryColor(context) Access the primary color
scaffoldBackgroundColor(context) Access the scaffold background color
primaryColorScheme(context) Access the primary color scheme
secondaryColorScheme(context) Access the secondary color scheme
cardColor(context) Access the card color
primaryColorDark(context) Access the primary dark color
primaryColorLight(context) Access the primary light color

Migration from Previous Version #

If you're migrating from the previous version:

Access to Colors #

Old way:

myTheme.BestThemeBuilder(
  builder: (theme, context) {
    return Container(
      color: theme.color1,
      child: Text('Example'),
    );
  },
);

New way:

Container(
  color: context.myColors.color1,
  child: Text('Example'),
);

Toggle Theme #

Old way:
First need to create an object from MyTheme like:

MyTheme myTheme = MyTheme();
Switch(
  value: myTheme.isDark,
  onChanged: (value) {
    myTheme.toggle();
  },
);

New way:

Switch(
  value: context.isDark,
  onChanged: (value) {
    context.toggleTheme();
  },
);

The new version eliminates the need for BestThemeBuilder wrapper and provides direct access through context extensions and an object from MyTheme. Old Documentation 0.0.3

Contributing #

We welcome contributions to the Best Theme package! Here's how you can help:

  1. Report Issues: Found a bug? Open an issue
  2. Request Features: Have an idea? Share it with us!

About the Developer #

This package was developed by Dosty Pshtiwan, a passionate Flutter developer dedicated to creating tools that make Flutter development easier and more enjoyable.

Connect with Dosty #


Made with ❤️ by Dosty Pshtiwan

If you find this package helpful, please consider giving it a ⭐ on GitHub!

3
likes
160
points
158
downloads

Publisher

verified publisherdostypshtiwan.com

Weekly Downloads

Theme management package for Flutter with light and dark mode support.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on best_theme