juice 1.2.0 copy "juice: ^1.2.0" to clipboard
juice: ^1.2.0 copied to clipboard

Opinionated reactive state management for Flutter. Combines Clean Architecture use cases with BLoC pattern for predictable async workflows and scalable, team-friendly development.

example/example.dart

// ignore_for_file: avoid_print, must_be_immutable
import 'package:juice/juice.dart';

// --- State ---
class CounterState extends BlocState {
  final int count;

  const CounterState({this.count = 0});

  CounterState copyWith({int? count}) =>
      CounterState(count: count ?? this.count);
}

// --- Events ---
class IncrementEvent extends EventBase {}

class DecrementEvent extends EventBase {}

// --- Use Cases ---
class IncrementUseCase extends BlocUseCase<CounterBloc, IncrementEvent> {
  @override
  Future<void> execute(IncrementEvent event) async {
    emitUpdate(
      newState: bloc.state.copyWith(count: bloc.state.count + 1),
      groupsToRebuild: {'counter'},
    );
  }
}

class DecrementUseCase extends BlocUseCase<CounterBloc, DecrementEvent> {
  @override
  Future<void> execute(DecrementEvent event) async {
    emitUpdate(
      newState: bloc.state.copyWith(count: bloc.state.count - 1),
      groupsToRebuild: {'counter'},
    );
  }
}

// --- BLoC ---
class CounterBloc extends JuiceBloc<CounterState> {
  CounterBloc()
      : super(
          const CounterState(),
          [
            () => UseCaseBuilder(
                  typeOfEvent: IncrementEvent,
                  useCaseGenerator: () => IncrementUseCase(),
                ),
            () => UseCaseBuilder(
                  typeOfEvent: DecrementEvent,
                  useCaseGenerator: () => DecrementUseCase(),
                ),
          ],
        );
}

// --- Widget ---
class CounterWidget extends StatelessJuiceWidget<CounterBloc> {
  CounterWidget({super.key, super.groups = const {'counter'}});

  @override
  Widget onBuild(BuildContext context, StreamStatus status) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Count: ${bloc.state.count}',
            style: const TextStyle(fontSize: 24)),
        const SizedBox(height: 16),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => bloc.send(DecrementEvent()),
              child: const Text('-'),
            ),
            const SizedBox(width: 16),
            ElevatedButton(
              onPressed: () => bloc.send(IncrementEvent()),
              child: const Text('+'),
            ),
          ],
        ),
      ],
    );
  }
}

// --- App ---
void main() {
  // Register bloc with BlocScope
  BlocScope.register<CounterBloc>(
    () => CounterBloc(),
    lifecycle: BlocLifecycle.permanent,
  );

  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Juice Counter')),
        body: Center(child: CounterWidget()),
      ),
    ),
  );
}
6
likes
150
points
305
downloads

Publisher

verified publishernuovea.com

Weekly Downloads

Opinionated reactive state management for Flutter. Combines Clean Architecture use cases with BLoC pattern for predictable async workflows and scalable, team-friendly development.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#bloc #reactive #clean-architecture #state-management

Documentation

Documentation
API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

cupertino_icons, flutter, flutter_test, logger, rxdart

More

Packages that depend on juice