dropx 0.0.2 copy "dropx: ^0.0.2" to clipboard
dropx: ^0.0.2 copied to clipboard

A highly customizable, theme-aware dropdown widget for Flutter with full keyboard navigation, search functionality, and auto-positioning.

DropX #

A fully customizable dropdown package for Flutter with keyboard navigation support.

pub package License style: flutter_lints

Screenshots #

Basic Dropdown Search & Filter Clear Button
Basic Dropdown Search & Filter Clear Button
Custom Styling Form Validation
Custom Styling Form Validation

πŸ’‘ Try it yourself! Run the example app to see all features in action:

cd example && flutter run

Features #

  • ✨ Full keyboard navigation - Arrow keys, Enter, Escape
  • πŸ” Built-in search and filtering - With custom filter support and debouncing
  • πŸ“ Smart auto-positioning - Shows above/below based on available space
  • 🎨 Fully customizable styling - Every color and dimension configurable
  • 🌈 Theme-aware - Automatically adapts to your app's theme
  • ⚑ Loading states - Built-in loading indicator support
  • 🎯 Custom item builders - Complete control over item rendering
  • πŸ“± Responsive - Works on all screen sizes
  • β™Ώ Accessible - Semantic labels and focus management
  • πŸ–±οΈ Click outside to close - Dropdown closes when clicking outside
  • πŸ”„ Dynamic updates - Items automatically update when data changes
  • ❌ Clear button - Optional clear button to reset selection
  • πŸ“ Form validation - Built-in FormField wrapper for easy form integration
  • ⏱️ Search debouncing - Optimize performance for large lists

Installation #

dependencies:
  dropx: ^0.0.2

Usage #

import 'package:dropx/dropx.dart';

Dropx<String>(
  items: ['Apple', 'Banana', 'Cherry'],
  focusNode: FocusNode(),
  hint: 'Select a fruit',
  onSelected: (value) => print(value),
)

Custom styling #

Dropx<String>(
  items: items,
  focusNode: focusNode,
  hint: 'Select',
  onSelected: (value) => print(value),
  config: DropxConfig(
    maxHeight: 400,
    borderRadius: BorderRadius.circular(16),
    showItemDividers: true,
    style: DropxStyle(
      overlayBackgroundColor: Colors.blue.shade50,
      selectedItemBackgroundColor: Colors.blue.shade200,
    ),
  ),
)

Custom items #

Dropx<User>(
  items: users,
  focusNode: focusNode,
  hint: 'Select user',
  displayText: (user) => user.name,
  itemBuilder: (user, isSelected) {
    return ListTile(
      leading: CircleAvatar(child: Text(user.initials)),
      title: Text(user.name),
      subtitle: Text(user.email),
    );
  },
  onSelected: (user) => print(user.name),
)

Custom filter #

Dropx<Product>(
  items: products,
  focusNode: focusNode,
  displayText: (product) => product.name,
  customFilter: (product, query) {
    return product.name.contains(query) || product.sku.contains(query);
  },
  onSelected: (product) => print(product.name),
)

Clear button #

Dropx<String>(
  items: items,
  focusNode: focusNode,
  hint: 'Select',
  onSelected: (value) => print(value),
  showClearButton: true,
  onClear: () => print('Selection cleared'),
)

Form validation #

Form(
  key: formKey,
  child: DropxFormField<String>(
    items: ['Option 1', 'Option 2', 'Option 3'],
    hint: 'Select an option',
    validator: (value) {
      if (value == null) return 'Please select an option';
      return null;
    },
    onSaved: (value) => print('Saved: $value'),
  ),
)

Search debouncing #

Dropx<String>(
  items: largeItemList,
  focusNode: focusNode,
  hint: 'Search...',
  onSelected: (value) => print(value),
  config: DropxConfig(
    searchDebounce: Duration(milliseconds: 300),
  ),
)

Async loading #

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  List<String> items = [];
  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadItems();
  }

  Future<void> _loadItems() async {
    // Simulate API call
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      items = ['Item 1', 'Item 2', 'Item 3'];
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Dropx<String>(
      items: items,
      focusNode: FocusNode(),
      hint: 'Select item',
      onSelected: (value) => print(value),
      isLoading: isLoading,
    );
  }
}

API Reference #

Dropx Parameters #

Parameter Type Description Default
items List<T> List of items to display Required
focusNode FocusNode Focus node for keyboard navigation Required
onSelected Function(T) Callback when item is selected Required
hint String? Placeholder text null
initialValue T? Initial selected value null
displayText String Function(T)? Custom text extractor toString()
itemBuilder Widget Function(T, bool)? Custom item widget builder null
customFilter bool Function(T, String)? Custom filter function null
config DropxConfig? Configuration options DropxConfig()
header Widget? Widget shown at top of dropdown null
footer Widget? Widget shown at bottom of dropdown null
emptyWidget Widget? Widget shown when no items Default message
isLoading bool Show loading indicator false
enabled bool Enable/disable dropdown true
enableSearch bool Enable search functionality true
showClearButton bool Show clear button when value selected false
onClear VoidCallback? Callback when clear button pressed null
onChanged ValueChanged<String>? Callback when text changes null
semanticLabel String? Accessibility label null

DropxConfig Options #

See ARCHITECTURE.md for complete configuration options.

Performance Tips #

  • Use const constructors where possible
  • Provide displayText for complex objects to avoid repeated toString() calls
  • Use customFilter for optimized filtering logic
  • Consider pagination for very large lists (>1000 items)

Accessibility #

DropX includes built-in accessibility features:

  • Semantic labels for screen readers
  • Keyboard navigation support
  • Focus management
  • High contrast support through theme integration

More #

See ARCHITECTURE.md for package details and example/ for more examples.

Contributing #

Contributions are welcome! Please read CONTRIBUTING.md for details.

License #

MIT License - see LICENSE file.

2
likes
160
points
90
downloads

Publisher

unverified uploader

Weekly Downloads

A highly customizable, theme-aware dropdown widget for Flutter with full keyboard navigation, search functionality, and auto-positioning.

Repository (GitHub)
View/report issues
Contributing

Topics

#dropdown #widget #ui #keyboard-navigation #search

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on dropx