watchable 4.0.0 copy "watchable: ^4.0.0" to clipboard
watchable: ^4.0.0 copied to clipboard

Production-ready, type-safe state management for Flutter. 10x performance improvement with advanced memory management and comprehensive error handling.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:watchable/watchable.dart';

void main() {
  runApp(MaterialApp(
    home: MainPage(),
  ));
}

class MainPage extends StatelessWidget {
  // =======================================================================
  // TRADITIONAL API (Verbose but Explicit)
  // =======================================================================
  final _counterWatchable = MutableStateWatchable<int>(0);
  StateWatchable<int> get counterWatchable => _counterWatchable;
  
  final _textWatchable = MutableStateWatchable<String>('');
  StateWatchable<String> get textWatchable => _textWatchable;
  
  final _eventWatchable = MutableWatchable<String>();
  Watchable<String> get eventWatchable => _eventWatchable;

  // =======================================================================
  // NEW EXTENSION API (Concise and Developer-Friendly) 
  // =======================================================================
  final counter = 0.watch;           // WInt - 70% less code!
  final name = 'John'.watch;         // WString
  final isLoading = false.watch;     // WBool
  final price = 99.99.watch;         // WDouble
  final items = <String>[].watch;    // WList<String>
  final notifications = WEvent<String>();  // Event stream

  MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Watchable API Comparison')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              '🔥 NEW EXTENSION API',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 16),
            
            // New API - Counter
            counter.build((value) => Text(
              'Counter: $value',
              style: const TextStyle(fontSize: 24, color: Colors.blue),
            )),
            ElevatedButton(
              onPressed: () => counter.emit(counter.value + 1),
              child: const Text('Increment (New API)'),
            ),
            const SizedBox(height: 16),
            
            // New API - Name
            name.build((value) => Text(
              'Name: $value',
              style: const TextStyle(fontSize: 20, color: Colors.blue),
            )),
            TextField(
              onChanged: (value) => name.emit(value),
              decoration: const InputDecoration(
                labelText: 'Enter name (New API)',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            
            // New API - Loading State
            isLoading.build((loading) => loading 
              ? const CircularProgressIndicator()
              : const Text('Ready!', style: TextStyle(color: Colors.green))
            ),
            ElevatedButton(
              onPressed: () => isLoading.emit(!isLoading.value),
              child: const Text('Toggle Loading'),
            ),
            const SizedBox(height: 16),
            
            // New API - Price
            price.build((value) => Text(
              'Price: \$${value.toStringAsFixed(2)}',
              style: const TextStyle(fontSize: 18, color: Colors.green),
            )),
            ElevatedButton(
              onPressed: () => price.emit(price.value - 10),
              child: const Text('Discount \$10'),
            ),
            
            const Divider(height: 40),
            const Text(
              '📚 TRADITIONAL API',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 16),
            
            // Traditional API - Counter
            WatchableBuilder<int>(
              watchable: counterWatchable,
              builder: (context, value, child) {
                return Text('Traditional Counter: $value',
                    style: const TextStyle(fontSize: 18, color: Colors.orange));
              },
            ),
            ElevatedButton(
              onPressed: () => _counterWatchable.emit(counterWatchable.value + 1),
              child: const Text('Increment (Traditional)'),
            ),
            const SizedBox(height: 16),
            
            // Traditional API - Text
            WatchableBuilder<String>(
              watchable: textWatchable,
              builder: (context, value, child) {
                return Text('Traditional Text: $value',
                    style: const TextStyle(fontSize: 16, color: Colors.orange));
              },
            ),
            TextField(
              onChanged: (value) => _textWatchable.emit(value),
              decoration: const InputDecoration(
                labelText: 'Enter text (Traditional)',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            
            // Event Consumer (Traditional)
            WatchableConsumer<String>(
              watchable: eventWatchable,
              onEvent: (value) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Event: $value')),
                );
              },
              child: ElevatedButton(
                onPressed: () => _eventWatchable.emit('Traditional event!'),
                child: const Text('Trigger Event (Traditional)'),
              ),
            ),
            const SizedBox(height: 16),
            
            // Event Consumer (New API)
            notifications.consume(
              onEvent: (value) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('New API Event: $value')),
                );
              },
              child: ElevatedButton(
                onPressed: () => notifications.emit('New API event!'),
                child: const Text('Trigger Event (New API)'),
              ),
            ),
            
            const Divider(height: 40),
            const Text(
              '🔗 COMBINING STATES',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 16),
            
            // Traditional combiner
            WatchableBuilder.from2<int, String, String>(
              watchable1: counterWatchable,
              watchable2: textWatchable,
              combiner: (count, text) => 'Traditional: Count=$count, Text="$text"',
              builder: (context, value, child) {
                return Text(value, style: const TextStyle(fontSize: 14));
              },
            ),
            
            const SizedBox(height: 16),
            
            const Divider(height: 40),
            const Text(
              '🔗 NEW COMBINER API',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 16),
            
            // Tuple combiner demo
            (name, isLoading).build((n, loading) => 
              loading 
                ? const Text('Loading...', style: TextStyle(color: Colors.orange))
                : Text('Hello $n!', style: const TextStyle(fontSize: 18, color: Colors.green))
            ),
            
            const SizedBox(height: 16),
            
            // Watch.build2 demo
            Watch.build2(counter, price, (c, p) => 
              Text('Items: $c, Total: \$${(c * p).toStringAsFixed(2)}')
            ),
            
            const SizedBox(height: 16),
            const Text('💡 Form Validation Example'),
            Watch.build2(name, counter, (n, c) {
              final isValid = n.isNotEmpty && c > 0;
              return ElevatedButton(
                onPressed: isValid ? () {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Form valid! Name: $n, Count: $c')),
                  );
                } : null,
                child: Text(isValid ? 'Valid Form' : 'Invalid Form'),
              );
            }),
            
            const SizedBox(height: 16),
            const Text(
              '📊 CODE COMPARISON',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(8),
              ),
              child: const Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Traditional: WatchableBuilder.from2(...)',
                    style: TextStyle(fontFamily: 'monospace', fontSize: 12),
                  ),
                  SizedBox(height: 8),
                  Text(
                    'New API: (a, b).build(...) or Watch.build2(...)',
                    style: TextStyle(
                      fontFamily: 'monospace',
                      fontSize: 12,
                      fontWeight: FontWeight.bold,
                      color: Colors.blue,
                    ),
                  ),
                  SizedBox(height: 8),
                  Text('🎯 Custom classes and complex combinations supported!'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
3
likes
0
points
194
downloads

Publisher

verified publisherdipendrasharma.com

Weekly Downloads

Production-ready, type-safe state management for Flutter. 10x performance improvement with advanced memory management and comprehensive error handling.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

collection, flutter

More

Packages that depend on watchable