dependents 0.2.0 copy "dependents: ^0.2.0" to clipboard
dependents: ^0.2.0 copied to clipboard

Flutter widgets for reactive UI and state management: rebuild or trigger actions on dependency changes.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:dependents/dependents.dart';

void main() => runApp(const App());

class App extends StatefulWidget {
  const App({super.key});

  static AppState of(BuildContext context) {
    return context.findAncestorStateOfType<AppState>()!;
  }

  @override
  State<App> createState() => AppState();
}

class AppState extends State<App> {
  bool isDark = false;

  void toggleTheme() {
    setState(() {
      isDark = !isDark;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: isDark ? ThemeMode.dark : ThemeMode.light,
      home: const ExampleScreen(
      ),
    );
  }
}

///
///
///
class ExampleScreen extends StatefulWidget {

  const ExampleScreen({super.key});

  @override
  State<ExampleScreen> createState() => _ExampleScreenState();
}

class _ExampleScreenState extends State<ExampleScreen> {
  final userValueNotifier = ValueNotifier<User>(User(name: 'Dep', age: 22));
  final notifier1 = ValueNotifier<int>(0);
  final notifier2 = ValueNotifier<int>(100);

  @override
  void dispose() {
    userValueNotifier.dispose();
    notifier1.dispose();
    notifier2.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text.rich(
              TextSpan(text: '', children: [
                TextSpan(text: 'dependents', style: TextStyle(fontWeight: FontWeight.bold)),
                TextSpan(text: ' package example'),
              ]),
            ),
            TextButton(
                onPressed: () => launchUrl(Uri.parse("https://github.com/dartius-dev/dependents/blob/main/example/lib/main.dart")),
                child: const Text('source'),
            ),
          ],
        ),
      ),
      body: Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 600),
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                Expanded(
                  child: ListView(
                    shrinkWrap: false,
                    children: [
                      //
                      // Greeting based on theme and user name
                      //
                      Center(
                        child: DependentBuilder<(bool, String)>(
                          listenable: userValueNotifier,
                          dependency: (context) {
                            final isLight = Theme.of(context).colorScheme.brightness == Brightness.light;
                            final name = userValueNotifier.value.name;
                            return (isLight, name);
                          },
                          builder: (context, _) {
                            final tuple = DependentBuilder.dependencyOf<(bool, String)>(context);
                            final isLight = tuple?.$1 ?? false;
                            final name = tuple?.$2 ?? '';
                            return Text('Good ${isLight ? 'morning' : 'evening'}, $name!', 
                              style: Theme.of(context).textTheme.headlineMedium);
                          },
                        ),
                      ),
                      const SizedBox(height: 36),
                            
                      //
                      // Theme brightness example
                      //
                      Row(
                        children: [
                          Expanded(
                            child: DependentBuilder<bool>(
                            dependency: (context) => Theme.of(context).colorScheme.onPrimary.computeLuminance() > 0.5,
                            builder: (context, _) {
                              final light = DependentBuilder.dependencyOf<bool>(context);
                              return Text(light == true ? 'LIGHT' : 'DARK', style: TextStyle(fontWeight: FontWeight.bold));
                            },
                          ),
                          ),
                          const SizedBox(width: 16),
                          Expanded(
                            child: ElevatedButton(
                              onPressed: App.of(context).toggleTheme,
                              child: DependentBuilder<bool>(
                                dependency: (context) => Theme.of(context).brightness==Brightness.light,
                                builder: (context, _) {
                                  final isLight = DependentBuilder.dependencyOf<bool>(context)!;
                                  return Text(isLight ? 'Switch to Dark Theme' : 'Switch to Light Theme');
                                },
                              ),
                            ),
                          ),
                            
                        ],
                      ),
                      const SizedBox(height: 16),
                      Row(
                        children: [
                        Expanded(
                          child: Text("Theme brightness:"),
                        ),
                        const SizedBox(width: 16),
                        Expanded(
                          child: DependentBuilder<Brightness>(
                              dependency: (context) => Theme.of(context).colorScheme.brightness,
                              builder: (context, _) => Text(
                                '${DependentBuilder.dependencyOf<Brightness>(context)}',
                                style: const TextStyle(fontSize: 16),
                              ),
                            ),
                        ),
                        ],
                      ),   
                      const SizedBox(height: 36),
                            
                      //
                      // User name
                      //
                      Row(
                        children: [
                        Expanded(
                          child: DependentBuilder<String>(
                            listenable: userValueNotifier,
                            dependency: (context) => userValueNotifier.value.name,
                            builder: (context, _) => Text(
                              'User: ${userValueNotifier.value.name}',
                              style: const TextStyle(fontSize: 16),
                            ),
                          ),
                        ),
                        const SizedBox(width: 16),
                        Expanded(
                          child: TextFormField(
                            initialValue: userValueNotifier.value.name,
                            decoration: const InputDecoration(labelText: 'Change user name', helperText: 'Type "Dracula"'),
                            onChanged: (value) {
                              userValueNotifier.value = User(name: value, age: userValueNotifier.value.age);
                            },
                          ),
                        ),
                        ],
                      ),
                      const SizedBox(height: 16),
                            
                            
                      //
                      // User age
                      //
                      Row(
                        children: [
                          Expanded(
                            child: DependentBuilder<int>(
                              listenable: userValueNotifier,
                              dependency: (context) => userValueNotifier.value.age,
                              builder: (context, _) => Text(
                                'Age: ${userValueNotifier.value.age}',
                                style: const TextStyle(fontSize: 16),
                              ),
                            ),
                          ),
                          const SizedBox(width: 16),
                          Expanded(
                            child: Row(
                              children: [
                                ElevatedButton(
                                  onPressed: () {
                                    final user = userValueNotifier.value;
                                    userValueNotifier.value = User(name: user.name, age: user.age - 1);
                                  },
                                  child: const Text('-'),
                                ),
                                const SizedBox(width: 8),
                                ElevatedButton(
                                  onPressed: () {
                                    final user = userValueNotifier.value;
                                    userValueNotifier.value = User(name: user.name, age: user.age + 1);
                                  },
                                  child: const Text('+'),
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 36),
                            
                      //
                      // Multiple dependency: sum of two notifiers
                      //
                      Row(
                        children: [
                        Expanded(
                          child: DependentBuilder<int>(
                            listenableList: [notifier1, notifier2],
                            dependency: (_) => notifier1.value + notifier2.value,
                            builder: (_, _) => Text('Sum: ${notifier1.value + notifier2.value}'),
                          ),
                        ),
                        const SizedBox(width: 16),
                        Expanded(
                          child: Row(
                          children: [
                            ElevatedButton(
                            onPressed: () => notifier1.value++,
                            child: ListenableBuilder(
                                listenable: notifier1,
                                builder: (_, _) => Text('${notifier1.value} ++')
                              ),
                            ),
                            const SizedBox(width: 8),
                            ElevatedButton(
                            onPressed: () => notifier2.value++,
                            child: ListenableBuilder(
                                listenable: notifier2,
                                builder: (_, _) => Text('${notifier2.value} ++')
                              ),
                            ),
                          ],
                          ),
                        ),
                        ],
                      ),
                            
                      //
                      // Reaction on name and age changes
                      //
                      DependencyListener<bool>(
                        listenable: userValueNotifier,
                        dependency: (context) {
                          return (userValueNotifier.value.name.toLowerCase().contains('dracula') 
                            || userValueNotifier.value.age > 100 || userValueNotifier.value.age < 1
                            ) && Theme.of(context).brightness == Brightness.light;
                        },
                        listener: (toDark) {
                          if (toDark==true) App.of(context).toggleTheme();
                        },
                        child: const SizedBox.shrink(),
                      ),
                            
                  
                      // bottom      
                      const SizedBox(height: 36),                        
                    ],
                  ),
                ),
                Align(
                  alignment: Alignment.bottomCenter,
                  child: TextButton(
                    onPressed: () => launchUrl(Uri.parse("https://pub.flutter-io.cn/packages/dependents")),
                    child: Text.rich(TextSpan(text: '', children: [
                      TextSpan(text: 'dependents', style: const TextStyle(fontWeight: FontWeight.bold)),
                      const TextSpan(text: ' on pub.flutter-io.cn'),
                    ])),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}


///
/// User model
///
class User {
  final String name;
  final int age;
  const User({required this.name, required this.age});
}
1
likes
150
points
148
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter widgets for reactive UI and state management: rebuild or trigger actions on dependency changes.

Repository (GitHub)
View/report issues

Topics

#reactive #builder #listener #state-management #dependency

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on dependents