{"id":14956404,"url":"https://github.com/abdullahchauhan/custom-dropdown","last_synced_at":"2025-04-09T07:05:40.992Z","repository":{"id":37731346,"uuid":"432152213","full_name":"AbdullahChauhan/custom-dropdown","owner":"AbdullahChauhan","description":"Custom dropdown widget allows to add highly customizable dropdown widget in your projects. Features includes Search on list data, Network search, Multi-selection and many more.","archived":false,"fork":false,"pushed_at":"2024-09-26T15:50:28.000Z","size":7393,"stargazers_count":166,"open_issues_count":37,"forks_count":80,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-09T07:05:27.200Z","etag":null,"topics":["dart","dartlang","dropdown","dropdownlist","flutter","flutter-package","flutter-widget","spinner","ui","widget"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/animated_custom_dropdown","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AbdullahChauhan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["buymeacoffee.com/abdullahchauhan"]}},"created_at":"2021-11-26T11:19:20.000Z","updated_at":"2025-03-25T14:11:18.000Z","dependencies_parsed_at":"2024-01-16T18:59:43.589Z","dependency_job_id":"6fccbb5a-52cd-4c09-8fb2-fd4894613ffc","html_url":"https://github.com/AbdullahChauhan/custom-dropdown","commit_stats":{"total_commits":233,"total_committers":9,"mean_commits":25.88888888888889,"dds":0.2145922746781116,"last_synced_commit":"725950c7afa49db0ebd14721f268786c2b452f37"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdullahChauhan%2Fcustom-dropdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdullahChauhan%2Fcustom-dropdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdullahChauhan%2Fcustom-dropdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdullahChauhan%2Fcustom-dropdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AbdullahChauhan","download_url":"https://codeload.github.com/AbdullahChauhan/custom-dropdown/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247994119,"owners_count":21030050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dartlang","dropdown","dropdownlist","flutter","flutter-package","flutter-widget","spinner","ui","widget"],"created_at":"2024-09-24T13:12:59.150Z","updated_at":"2025-04-09T07:05:40.972Z","avatar_url":"https://github.com/AbdullahChauhan.png","language":"Dart","funding_links":["buymeacoffee.com/abdullahchauhan","https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20pizza\u0026emoji=","https://www.buymeacoffee.com/abdullahchauhan"],"categories":[],"sub_categories":[],"readme":"# Custom Dropdown\n\n**Custom Dropdown** package lets you add customizable animated dropdown widget.\n\n[![pub.dev](https://img.shields.io/pub/v/animated_custom_dropdown.svg?style=flat?logo=dart)](https://pub.dev/packages/animated_custom_dropdown)\n[![likes](https://img.shields.io/pub/likes/animated_custom_dropdown)](https://pub.dev/packages/animated_custom_dropdown/score)\n[![popularity](https://img.shields.io/pub/popularity/animated_custom_dropdown)](https://pub.dev/packages/animated_custom_dropdown/score)\n[![pub points](https://img.shields.io/pub/points/animated_custom_dropdown)](https://pub.dev/packages/animated_custom_dropdown/score)\n\n[![buy me a coffee](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20pizza\u0026emoji=🍕\u0026slug=abdullahchauhan\u0026button_colour=FF8838\u0026font_colour=ffffff\u0026font_family=Poppins\u0026outline_colour=000000\u0026coffee_colour=ffffff')](https://www.buymeacoffee.com/abdullahchauhan)\n\n### If you like this package, please leave a like on [pub.dev](https://pub.dev/packages/animated_custom_dropdown) and star on [GitHub](https://github.com/AbdullahChauhan/custom-dropdown).\n\n## Features\n\nLots of properties to use and customize dropdown widget as per your need. Also usable under Form widget for required validation.\n\n- Custom dropdown using constructor CustomDropdown\u003cT\u003e().\n- Custom dropdown with search field using named constructor CustomDropdown\u003cT\u003e.search().\n- Custom dropdown with search request field using named constructor CustomDropdown\u003cT\u003e.searchRequest().\n- Multi select custom dropdown using named constructor CustomDropdown\u003cT\u003e.multiSelect().\n- Multi select custom dropdown with search field using named constructor CustomDropdown\u003cT\u003e.multiSelectSearch().\n- Multi select custom dropdown with search request field using named constructor CustomDropdown\u003cT\u003e.multiSelectSearchRequest().\n\n## Preview\n\n\u003cimg src=\"https://raw.githubusercontent.com/AbdullahChauhan/custom-dropdown/master/readme_assets/preview.gif\" width=\"300\"/\u003e\n\n\u003chr\u003e\n\n## Getting started\n\n1. Add the latest version of package to your `pubspec.yaml` (and run `flutter pub get`):\n\n```dart\ndependencies:\n  animated_custom_dropdown: 3.1.1\n```\n\n2. Import the package and use it in your Flutter App.\n\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\n```\n\n\u003chr\u003e\n\n## Example usage\n\n### **1. Custom dropdown**\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cString\u003e _list = [\n    'Developer',\n    'Designer',\n    'Consultant',\n    'Student',\n  ];\n\nclass SimpleDropdown extends StatelessWidget {\n  const SimpleDropdown({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cString\u003e(\n      hintText: 'Select job role',\n      items: _list,\n      initialItem: _list[0],\n      onChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n\n### **2. Custom dropdown with custom type model**\nLet's start with the type of object we are going to work with:\n```dart\nclass Job {\n  final String name;\n  final IconData icon;\n  const Job(this.name, this.icon);\n\n  @override\n  String toString() {\n    return name;\n  }\n}\n```\nWhenever you are going to work with custom type model `T`, your model must override the default `toString()` method and return the property inside that you want to display as list item otherwise the dropdown list item would show `Instance of [model name]`.\n\nNow the widget:\n\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cJob\u003e _list = [\n    Job('Developer', Icons.developer_mode),\n    Job('Designer', Icons.design_services),\n    Job('Consultant', Icons.account_balance),\n    Job('Student', Icons.school),\n  ];\n\nclass SimpleDropdown extends StatelessWidget {\n  const SimpleDropdown({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cJob\u003e(\n      hintText: 'Select job role',\n      items: _list,\n      onChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n### **3. Custom dropdown with multiple selection**\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cJob\u003e _list = [\n    Job('Developer', Icons.developer_mode),\n    Job('Designer', Icons.design_services),\n    Job('Consultant', Icons.account_balance),\n    Job('Student', Icons.school),\n  ];\n\nclass MultiSelectDropDown extends StatelessWidget {\n  const MultiSelectDropDown({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cJob\u003e.multiSelect(\n        items: _jobItems,\n        initialItems: _jobItems.take(1).toList(),\n        onListChanged: (value) {\n          log('changing value to: $value');\n        },\n      );\n  }\n}\n```\n\n### **4. Custom dropdown with search:** *A custom dropdown with the possibility to filter the items.*\nFirst, let's enhance our Job model with more functionality:\n```dart\nclass Job with CustomDropdownListFilter {\n  final String name;\n  final IconData icon;\n  const Job(this.name, this.icon);\n\n  @override\n  String toString() {\n    return name;\n  }\n\n  @override\n  bool filter(String query) {\n    return name.toLowerCase().contains(query.toLowerCase());\n  }\n}\n```\nIf the filter on the object is more complex, you can add the `CustomDropdownListFilter` mixin to it, which gives you access to the `filter(query)` method, and by this the items of the list will be filtered.\n\nNow the widgets:\n\n#### SearchDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cJob\u003e _list = [\n    Job('Developer', Icons.developer_mode),\n    Job('Designer', Icons.design_services),\n    Job('Consultant', Icons.account_balance),\n    Job('Student', Icons.school),\n  ];\n\nclass SearchDropdown extends StatelessWidget {\n  const SearchDropdown({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cJob\u003e.search(\n      hintText: 'Select job role',\n      items: _list,\n      excludeSelected: false,\n      onChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n\n#### MultiSelectSearchDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cJob\u003e _list = [\n    Job('Developer', Icons.developer_mode),\n    Job('Designer', Icons.design_services),\n    Job('Consultant', Icons.account_balance),\n    Job('Student', Icons.school),\n  ];\n\nclass MultiSelectSearchDropdown extends StatelessWidget {\n  const SearchDropdown({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cJob\u003e.multiSelectSearch(\n      hintText: 'Select job role',\n      items: _list,\n      onListChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n\n### **5. Custom dropdown with search request:** *A custom dropdown with a search request to load the items.*\nLet's use a personalized object for the items:\n```dart\nclass Pair {\n  final String text;\n  final IconData icon;\n  const Pair(this.text, this.icon);\n\n  @override\n  String toString() {\n    return text;\n  }\n}\n```\n\nNow the widgets:\n\n#### SearchRequestDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cPair\u003e _list = [\n    Pair('Developer', Icons.developer_board),\n    Pair('Designer', Icons.deblur_sharp),\n    Pair('Consultant', Icons.money_off),\n    Pair('Student', Icons.edit),\n  ];\n\nclass SearchRequestDropdown extends StatelessWidget {\n  const SearchRequestDropdown({Key? key}) : super(key: key);\n\n  // This should be a call to the api or service or similar\n  Future\u003cList\u003cPair\u003e\u003e _getFakeRequestData(String query) async {\n    return await Future.delayed(const Duration(seconds: 1), () {\n      return _list.where((e) {\n        return e.text.toLowerCase().contains(query.toLowerCase());\n      }).toList();\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cPair\u003e.searchRequest(\n      futureRequest: _getFakeRequestData,\n      hintText: 'Search job role',\n      items: _list,\n      onChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n\n#### MultiSelectSearchRequestDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cPair\u003e _list = [\n    Pair('Developer', Icons.developer_board),\n    Pair('Designer', Icons.deblur_sharp),\n    Pair('Consultant', Icons.money_off),\n    Pair('Student', Icons.edit),\n  ];\n\nclass MultiSelectSearchRequestDropdown extends StatelessWidget {\n  const MultiSelectSearchRequestDropdown({Key? key}) : super(key: key);\n\n  // This should be a call to the api or service or similar\n  Future\u003cList\u003cPair\u003e\u003e _getFakeRequestData(String query) async {\n    return await Future.delayed(const Duration(seconds: 1), () {\n      return _list.where((e) {\n        return e.text.toLowerCase().contains(query.toLowerCase());\n      }).toList();\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return CustomDropdown\u003cPair\u003e.multiSelectSearchRequest(\n      futureRequest: _getFakeRequestData,\n      hintText: 'Search job role',\n      onListChanged: (value) {\n        log('changing value to: $value');\n      },\n    );\n  }\n}\n```\n\n### **6. Custom dropdown with validation:** *A custom dropdown with validation.*\n\n#### ValidationDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cString\u003e _list = [\n    'Developer',\n    'Designer',\n    'Consultant',\n    'Student',\n  ];\n\nclass ValidationDropdown extends StatelessWidget {\n  ValidationDropdown({Key? key}) : super(key: key);\n\n  final _formKey = GlobalKey\u003cFormState\u003e();\n\n  @override\n  Widget build(BuildContext context) {\n    return Form(\n      key: _formKey,\n      child: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: [\n          CustomDropdown\u003cString\u003e(\n            hintText: 'Select job role',\n            items: _list,\n            onChanged: (value) {\n              log('changing value to: $value');\n            },\n            // Run validation on item selected\n            validateOnChange: true,\n            // Function to validate if the current selected item is valid or not\n            validator: (value) =\u003e value == null ? \"Must not be null\" : null,\n          ),\n          const SizedBox(height: 16),\n          SizedBox(\n            width: double.infinity,\n            child: ElevatedButton(\n              onPressed: () {\n                if (!_formKey.currentState!.validate()) return;\n              },\n              child: const Text(\n                'Submit',\n                style: TextStyle(fontWeight: FontWeight.w600),\n              ),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\n#### MultiSelectValidationDropdown\n```dart\nimport 'package:animated_custom_dropdown/custom_dropdown.dart';\nimport 'package:flutter/material.dart';\nimport 'dart:developer';\n\nconst List\u003cString\u003e _list = [\n    'Developer',\n    'Designer',\n    'Consultant',\n    'Student',\n  ];\n\nclass MultiSelectValidationDropdown extends StatelessWidget {\n  MultiSelectValidationDropdown({Key? key}) : super(key: key);\n\n  final _formKey = GlobalKey\u003cFormState\u003e();\n\n  @override\n  Widget build(BuildContext context) {\n    return Form(\n      key: _formKey,\n      child: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: [\n          CustomDropdown\u003cString\u003e.multiSelect(\n            hintText: 'Select job role',\n            items: _list,\n            onListChanged: (value) {\n              log('changing value to: $value');\n            },\n            listValidator: (value) =\u003e value.isEmpty ? \"Must not be null\" : null,\n          ),\n          const SizedBox(height: 16),\n          SizedBox(\n            width: double.infinity,\n            child: ElevatedButton(\n              onPressed: () {\n                if (!_formKey.currentState!.validate()) return;\n              },\n              child: const Text(\n                'Submit',\n                style: TextStyle(fontWeight: FontWeight.w600),\n              ),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\n## Customization\nFor a complete customization of the package, go to the [example](https://github.com/AbdullahChauhan/custom-dropdown/blob/master/example).\n\n## Contributors\n\n[![](https://contrib.rocks/image?repo=AbdullahChauhan/custom-dropdown)](https://github.com/AbdullahChauhan/custom-dropdown/graphs/contributors)\n\n## Issues \u0026 Feedback\n\nPlease file an [issue](https://github.com/AbdullahChauhan/custom-dropdown/issues) to send feedback or report a bug. PRs are always welcome. Thank you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdullahchauhan%2Fcustom-dropdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdullahchauhan%2Fcustom-dropdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdullahchauhan%2Fcustom-dropdown/lists"}