app_wide_search 0.1.1 copy "app_wide_search: ^0.1.1" to clipboard
app_wide_search: ^0.1.1 copied to clipboard

A high-performance Flutter package for implementing app-wide search with grouped results, offline caching, and deep-link support.

example/lib/main.dart

import 'package:app_wide_search/app_wide_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';

/// Entry point for the app_wide_search quickstart example.
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Hive.initFlutter();
  Hive.registerAdapter(SearchItemAdapter());
  Hive.registerAdapter(SearchGroupAdapter());
  Hive.registerAdapter(SearchHistoryItemAdapter());

  runApp(
    ProviderScope(
      overrides: [
        searchProviderProvider.overrideWithValue(
          InMemorySearchProvider(_demoItems),
        ),
      ],
      child: const SearchExampleApp(),
    ),
  );
}

/// Root widget that configures the demo MaterialApp.
class SearchExampleApp extends StatelessWidget {
  /// Creates the example application shell.
  const SearchExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'app_wide_search — quickstart',
      theme: ThemeData(colorSchemeSeed: Colors.deepPurple, useMaterial3: true),
      home: const _HomePage(),
    );
  }
}

/// Demonstrates launching the search flow from a button.
class _HomePage extends ConsumerWidget {
  const _HomePage();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('App-wide search quickstart')),
      body: Center(
        child: ElevatedButton.icon(
          icon: const Icon(Icons.search),
          label: const Text('Open search'),
          onPressed: () => _showSearch(context, ref),
        ),
      ),
    );
  }

  Future<void> _showSearch(BuildContext context, WidgetRef ref) async {
    late final AppWideSearchDelegate delegate;

    Widget buildSuggestions(BuildContext context, List<String> suggestions) {
      return ListView.separated(
        padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
        itemCount: suggestions.length,
        itemBuilder: (context, index) {
          final suggestion = suggestions[index];
          return ListTile(
            leading: const Icon(Icons.history),
            title: Text(suggestion),
            onTap: () {
              delegate.query = suggestion;
              delegate.showResults(context);
            },
          );
        },
        separatorBuilder: (context, index) => const Divider(height: 1),
      );
    }

    Widget buildResults(BuildContext context, SearchResult result) {
      final items = result.items;
      if (items.isEmpty) {
        return const Center(child: Text('Try another keyword'));
      }

      return ListView.separated(
        padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
        itemCount: items.length,
        separatorBuilder: (context, index) => const Divider(height: 1),
        itemBuilder: (context, index) {
          final item = items[index];
          final groupLabel = _groupLabels[item.groupId] ?? 'All';
          final initials = item.title.isNotEmpty
              ? item.title.substring(0, 1).toUpperCase()
              : '?';

          return ListTile(
            leading: CircleAvatar(child: Text(initials)),
            title: Text(item.title),
            subtitle: Text('${item.subtitle} · $groupLabel'),
            onTap: () {
              delegate.close(context, item);
              ref.read(searchProviderProvider).onItemSelected(item);
              ScaffoldMessenger.of(
                context,
              ).showSnackBar(SnackBar(content: Text('Selected ${item.title}')));
            },
          );
        },
      );
    }

    delegate = AppWideSearchDelegate(
      ref: ref,
      hintText: 'Search demo content…',
      suggestionBuilder: buildSuggestions,
      resultBuilder: buildResults,
    );

    await showSearch<SearchItem?>(context: context, delegate: delegate);
  }
}

final Map<String, String> _groupLabels = {
  'productivity': 'Productivity',
  'communication': 'Communication',
  'shortcuts': 'Shortcuts',
};

final List<SearchItem> _demoItems = [
  SearchItem(
    id: 'calendar',
    title: 'Calendar',
    subtitle: 'Jump to upcoming events',
    groupId: 'productivity',
    description: 'Open the shared calendar and review scheduling conflicts.',
  ),
  SearchItem(
    id: 'tasks',
    title: 'My Tasks',
    subtitle: 'Review open action items',
    groupId: 'productivity',
    description: 'Sort and filter outstanding tasks by priority.',
  ),
  SearchItem(
    id: 'inbox',
    title: 'Inbox',
    subtitle: 'Check unread messages',
    groupId: 'communication',
    description: 'Open the message center with unread filters applied.',
  ),
  SearchItem(
    id: 'compose',
    title: 'Compose message',
    subtitle: 'Send a new direct message',
    groupId: 'communication',
  ),
  SearchItem(
    id: 'new-document',
    title: 'Create document',
    subtitle: 'Start with a collaborative doc template',
    groupId: 'shortcuts',
  ),
];
1
likes
160
points
215
downloads

Publisher

unverified uploader

Weekly Downloads

A high-performance Flutter package for implementing app-wide search with grouped results, offline caching, and deep-link support.

Repository (GitHub)
View/report issues

Topics

#search #ui #widget #navigation #offline

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_riverpod, go_router, hive, hive_flutter, intl, json_annotation, path_provider, riverpod, riverpod_annotation

More

Packages that depend on app_wide_search