Skip to main content

smart_search_dropdown_pro 1.0.3 copy "smart_search_dropdown_pro: ^1.0.3" to clipboard
smart_search_dropdown_pro: ^1.0.3 copied to clipboard

A production-ready, highly customizable, and searchable Flutter dropdown package supporting single/multi-selection, remote API search, grouping, custom filtering, accessibility, and 16+ UI variations.

SmartSearchDropdown Pro #

A production-ready, type-safe, highly customizable, and searchable Flutter dropdown package. Designed to provide ONE unified widget API for over 16+ dropdown UI experiencesโ€”ranging from simple selectors to multi-select chips, grouped lists, remote API searching with debouncing, infinite scroll pagination, tags, recent items, and dark mode theme adaptation.

Pub Version License: MIT Flutter Platform


๐Ÿ“ธ Visual Showcase & Assets #

SmartSearchDropdown comes with rich UI capabilities out of the box. Below is the visual preview showcasing various presentation modes and design variations.

SmartSearchDropdown Pro Showcase

Asset Path: assets/smart_search_dropdown_pro_showcase.png

Includes variations for single select, multi-select chips, grouped options, custom avatars, status badges, adaptive bottom sheets, and dark mode.

๐Ÿ’ก About This Package #

smart_search_dropdown_pro was created to solve the fragmentation in Flutter dropdown implementations. Instead of bringing in separate packages for multi-select chips, search filtering, remote API calls, or mobile bottom sheets, SmartSearchDropdown unifies all of them into a single, cohesive, performant component.

Key Highlights #

  • ๐ŸŽฏ Single & Multi-Select Modes: Seamless toggle between single-item selection and multi-select chip tags with Select All / Clear All support.
  • โšก Type-Safe Generic (<T>): Works natively with String, int, enum, or custom Dart models (User, Facility, Product, etc.).
  • ๐Ÿ” Flexible Search Strategies: Instant local search matching with support for contains, startsWith, fuzzy, and custom search functions.
  • ๐ŸŒ Remote API & Async Search: Built-in debouncing, loading states, error handling, infinite scroll pagination, and load-more callbacks.
  • ๐Ÿ“ฑ Adaptive Responsive Presentation: Automatically switches between anchored overlay popups on Desktop/Web/Tablet and BottomSheet/Modal Dialog on Mobile devices (<600px width).
  • ๐Ÿ“ Flutter Form Field Integration: Built-in SmartSearchDropdownFormField<T> for seamless integration with Flutter Form, validation rules, and autovalidateMode.
  • ๐ŸŽฎ Programmatic Controller: Full control via SmartDropdownController<T> to open, close, toggle, select, deselect, clear, or update state programmatically.
  • ๐ŸŽจ Material 3 & Dark Theme Ready: Automatically inherits colors, typography, and border radius from Flutter Theme.of(context), with full override options via SmartDropdownThemeData.
  • โ™ฟ Keyboard & Accessibility Support: Keyboard navigation, focus nodes, tab traversal, and semantics support.

๐Ÿ“ฆ Installation #

Add smart_search_dropdown_pro to your pubspec.yaml:

dependencies:
  smart_search_dropdown_pro: ^1.0.3

Include the assets in your pubspec.yaml if you want to use package showcase graphics or bundled assets:

flutter:
  assets:
    - assets/smart_search_dropdown_pro_showcase.png

Import the library in your Dart file:

import 'package:smart_search_dropdown_pro/smart_search_dropdown.dart';

๐Ÿš€ Quick Start #

Here is the minimal code needed to render a type-safe searchable dropdown:

import 'package:flutter/material.dart';
import 'package:smart_search_dropdown_pro/smart_search_dropdown.dart';

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

  @override
  State<QuickStartExample> createState() => _QuickStartExampleState();
}

class _QuickStartExampleState extends State<QuickStartExample> {
  String? selectedFacility;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('SmartSearchDropdown Quick Start')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: SmartSearchDropdown<String>(
          items: const [
            'Sunshine Hospital',
            'Everest Hospital',
            'City Care Hospital',
            'Metro Health Clinic',
          ],
          value: selectedFacility,
          hintText: 'Select Facility',
          onChanged: (value) {
            setState(() {
              selectedFacility = value;
            });
          },
        ),
      ),
    );
  }
}

๐ŸŽจ 16 UI Variations & Code Examples #

Every variation below uses the same flexible SmartSearchDropdown<T> API with configuration objects.

1. Basic Searchable Dropdown #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

2. Searchable Dropdown with Icons #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  itemIconBuilder: (f) => Icon(f.icon),
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

3. Searchable Dropdown with Subtitles #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  itemSubtitleBuilder: (f) => '${f.category} โ€ข ${f.location}',
  itemIconBuilder: (f) => Icon(f.icon),
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

4. Searchable Dropdown with Avatars #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  itemAvatarBuilder: (f) => CircleAvatar(
    backgroundColor: f.color,
    radius: 14,
    child: Text(f.name[0]),
  ),
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

5. Grouped Items Dropdown #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  groupBy: (f) => f.category,
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

6. Multi-Select Dropdown with Chips #

SmartSearchDropdown<Facility>.multi(
  items: facilities,
  selectedItems: selectedFacilities,
  itemLabelBuilder: (f) => f.name,
  hintText: 'Select Facilities',
  onMultiChanged: (list) => setState(() => selectedFacilities = list),
)

7. Select All & Clear All Controls #

SmartSearchDropdown<Facility>.multi(
  items: facilities,
  selectedItems: selectedFacilities,
  itemLabelBuilder: (f) => f.name,
  showSelectAll: true,
  showClearAll: true,
  hintText: 'Select Facilities',
  onMultiChanged: (list) => setState(() => selectedFacilities = list),
)
SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  recent: SmartDropdownRecentConfig(
    enabled: true,
    recentItems: recentFacilities,
    popularItems: popularFacilities,
  ),
  hintText: 'Select Facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

9. Custom Status Badges & Tags #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  itemStatusBuilder: (f) => Container(
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
    decoration: BoxDecoration(
      color: f.statusColor.withOpacity(0.2),
      borderRadius: BorderRadius.circular(12),
    ),
    child: Text(
      f.status,
      style: TextStyle(color: f.statusColor, fontWeight: FontWeight.bold, fontSize: 11),
    ),
  ),
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

10. Infinite Scroll & Lazy Loading #

SmartSearchDropdown<Facility>(
  items: initialFacilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  pagination: SmartDropdownPaginationConfig(
    enabled: true,
    onLoadMore: (page) async {
      return await apiRepository.fetchFacilities(page: page);
    },
  ),
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

11. Create New Option On-the-Fly #

SmartSearchDropdown<String>(
  items: facilityNames,
  value: selectedName,
  hintText: 'Type to search or create...',
  onCreateOption: (query) async {
    final newName = await apiRepository.createNewFacility(query);
    setState(() {
      facilityNames.add(newName);
      selectedName = newName;
    });
    return newName;
  },
  onChanged: (name) => setState(() => selectedName = name),
)

12. Custom Header Filters #

SmartSearchDropdown<Facility>(
  items: filteredFacilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  filters: SmartDropdownFilterConfig(
    enabled: true,
    builder: (context, controller) {
      return Padding(
        padding: const EdgeInsets.all(8.0),
        child: DropdownButton<String>(
          value: activeCategoryFilter,
          isExpanded: true,
          items: categoryOptions,
          onChanged: (category) {
            setState(() => activeCategoryFilter = category!);
          },
        ),
      );
    },
  ),
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

13. Custom Item Builder (Rich Custom UI) #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  itemBuilder: (context, facility, state) {
    return Container(
      padding: const EdgeInsets.all(12),
      color: state.isSelected ? Colors.blue.withOpacity(0.1) : null,
      child: Row(
        children: [
          Icon(facility.icon, color: state.isSelected ? Colors.blue : Colors.grey),
          const SizedBox(width: 12),
          Expanded(child: Text(facility.name, style: TextStyle(fontWeight: state.isSelected ? FontWeight.bold : FontWeight.normal))),
          if (state.isSelected) const Icon(Icons.check_circle, color: Colors.blue),
        ],
      ),
    );
  },
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

14. Theme Customization & Dark Mode #

SmartSearchDropdownTheme(
  data: SmartDropdownThemeData(
    primaryColor: Colors.teal,
    surfaceColor: const Color(0xFF1E293B),
    borderRadius: BorderRadius.circular(16),
  ),
  child: SmartSearchDropdown<Facility>(
    items: facilities,
    itemLabelBuilder: (f) => f.name,
    onChanged: (f) {},
  ),
)

15. Custom Empty Builder #

SmartSearchDropdown<Facility>(
  items: const [],
  emptyBuilder: (context) => const Center(
    child: Padding(
      padding: EdgeInsets.all(24.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.search_off_rounded, size: 48, color: Colors.grey),
          SizedBox(height: 8),
          Text('No matching facilities found', style: TextStyle(color: Colors.grey)),
        ],
      ),
    ),
  ),
  onChanged: (f) {},
)

16. Adaptive Mobile BottomSheet Presentation #

SmartSearchDropdown<Facility>(
  items: facilities,
  value: selectedFacility,
  itemLabelBuilder: (f) => f.name,
  popup: const SmartDropdownPopupConfig(
    presentation: DropdownPresentation.adaptive, // Uses BottomSheet on mobile (<600px width)
    mobileTitle: 'Choose Facility',
  ),
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

๐Ÿ“ Form Validation Integration #

Use SmartSearchDropdownFormField<T> inside Flutter Form widgets for out-of-the-box validation:

final _formKey = GlobalKey<FormState>();

Form(
  key: _formKey,
  child: Column(
    children: [
      SmartSearchDropdownFormField<Facility>(
        items: facilities,
        itemLabelBuilder: (f) => f.name,
        hintText: 'Select required facility',
        validator: (val) {
          if (val == null) return 'Please select a facility';
          return null;
        },
        onSaved: (val) => savedFacility = val,
      ),
      ElevatedButton(
        onPressed: () {
          if (_formKey.currentState!.validate()) {
            _formKey.currentState!.save();
          }
        },
        child: const Text('Submit'),
      ),
    ],
  ),
)

Pass an asyncSearch callback to automatically query remote REST or GraphQL APIs with debouncing:

SmartSearchDropdown<Facility>(
  asyncSearch: (query) async {
    final response = await http.get(Uri.parse('https://api.example.com/facilities?q=$query'));
    return parseFacilities(response.body);
  },
  search: const SmartDropdownSearchConfig(
    hintText: 'Search remote API...',
    debounceDuration: Duration(milliseconds: 300),
  ),
  hintText: 'Search facility',
  onChanged: (facility) => setState(() => selectedFacility = facility),
)

๐ŸŽฎ Programmatic Controller API #

Use SmartDropdownController<T> to programmatically manage state:

final controller = SmartDropdownController<Facility>();

// Open dropdown popup
controller.open();

// Close dropdown popup
controller.close();

// Toggle open/close
controller.toggle();

// Programmatically select item
controller.select(facility);

// Deselect item
controller.deselect(facility);

// Select all items
controller.selectAll(facilities);

// Clear all selections
controller.clearAll();

// Update search query programmatically
controller.setSearchQuery('Everest');

โš™๏ธ Configuration Reference #

Config Object Key Properties Description
SmartDropdownSearchConfig enabled, hintText, autoFocus, debounceDuration, searchMode, minChars, highlightMatches, customSearch Controls search input behavior, debouncing, and matching logic.
SmartDropdownSelectionConfig mode, showSelectAll, showClearAll, selectAllText, clearAllText, maxSelections, minSelections, allowChipRemoval Controls single/multi-selection modes and chip display.
SmartDropdownPopupConfig presentation, maxHeight, width, elevation, mobileTitle, borderRadius, mobileBreakpoint, offset Configures popup overlay presentation, height, and responsiveness.
SmartDropdownFilterConfig enabled, builder Renders custom filter headers inside the dropdown popup.
SmartDropdownPaginationConfig enabled, scrollThreshold, onLoadMore, pageSize, loadingFooterBuilder Configures infinite scroll and paged remote API loading.
SmartDropdownCreateOptionConfig enabled, onCreate, createLabelBuilder, builder Configures creation of new options when search query matches no items.
SmartDropdownRecentConfig enabled, recentItems, popularItems, recentTitle, popularTitle, storage Displays recent and popular item sections inside the dropdown.

๐Ÿ“œ License #

This project is licensed under the MIT License - see the LICENSE file for details.

4
likes
0
points
412
downloads

Publisher

unverified uploader

Weekly Downloads

A production-ready, highly customizable, and searchable Flutter dropdown package supporting single/multi-selection, remote API search, grouping, custom filtering, accessibility, and 16+ UI variations.

Repository (GitHub)
View/report issues

Topics

#dropdown #search #multi-select #form #ui

License

unknown (license)

Dependencies

flutter

More

Packages that depend on smart_search_dropdown_pro