felangel / bloc

A predictable state management library that helps implement the BLoC design pattern

Home Page:https://bloclibrary.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feat: provide a BlocSearchDelegate as a handy component

nerder opened this issue · comments

Description

For the first time in my app I've had the need to use SearchDelegate, this works quite differently from how other widgets works and I've had hard time figuring out how to make it work using bloc. Until after a short google search i've found this amazing resource (of course maded by the one and only @felangel) that helped me quite a lot.

Within that gist you can find also a reusable nice solution that i've implemented in my code and expanded a bit. It might be interesting to add it to bloc as a list of handy widgets ready to use and maybe attach some documentation to it.

Desired Solution

An example of implementation is the following, of course it's a very rough draft and NOT production ready™ :

class BlocSearchDelegate<B extends StateStreamableSource<S>, S> extends SearchDelegate<S?> {
  BlocSearchDelegate({
    required this.builder,
    required this.bloc,
    this.buildWhen,
    this.onQuery,
    super.searchFieldLabel,
    super.searchFieldStyle,
    super.searchFieldDecorationTheme,
    super.keyboardType,
    super.textInputAction = TextInputAction.search,
  });

  final BlocWidgetBuilder<S> builder;
  final B bloc;
  final BlocBuilderCondition<S>? buildWhen;
  final Function(B, String)? onQuery;

  @override
  List<Widget>? buildActions(BuildContext context) {
    return [
      IconButton(
        onPressed: () {
          if (query.isEmpty) {
            (bloc as Bloc).close();
            return close(context, null);
          }
          query = '';
        },
        icon: const Icon(Icons.close),
      ),
    ];
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    onQuery?.call(bloc, query);
    return BlocProvider.value(
      value: bloc,
      child: BlocBuilder<B, S>(
        builder: builder,
        buildWhen: buildWhen,
      ),
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    onQuery?.call(bloc, query);
    return BlocProvider.value(
      value: bloc,
      child: BlocBuilder<B, S>(
        builder: builder,
        buildWhen: buildWhen,
      ),
    );
  }

  @override
  Widget? buildLeading(BuildContext context) =>
      IconButton(
        onPressed: () {
          (bloc as Bloc).close();
          close(context, null);
        },
        icon: const Icon(Icons.arrow_back),
      );
}

Let me know what do you think, and if there is (or has been) any other conversation in that matter.

Hey @nerder 👋
Thanks for opening an issue and glad you found the example useful! Since this is a very feature-specific widget, I'm not sure it makes sense to include in package:flutter_bloc but might make more sense to be included in a separate package (e.g. flutter_bloc_search or something? Let me know what you think?

Closing for now since I don't think there are any actionable next steps here but if you have additional comments/thoughts lmk and I'm happy to continue the discussion 👍