Select2dot1
Introduction
Select2dot1 give you a customizable single/multiple select box with support for searching, group option, extra info and avatar. Select2dot1 works using overlay (web, desktop) and modal (mobile) and is fully customizable by settings and builder.
Demo web example: https://select2dot1.site
Author site: https://romanjrdykyj.site
Screenshots
Desktop Example | Mobile Example |
---|---|
Table of Contents
- Introduction
- Features
- Components and Settings
- Components View
- Component Pillbox Configuration 1
- Component Pillbox Configuration 2
- Component Pillbox Configuration 3
- Component Pillbox Configuration 4
- Component Dropdown Overlay Configuration 1
- Component Dropdown Overlay Configuration 2
- Component Dropdown Modal Configuration 1
- Component Dropdown Modal Configuration 2
- TreeView Components with Settings
- Components View
- Customization
- Model Structur Data
- Controllers
- Contributing
- Q&A
- FAQ
- License
Platform Support
Android | iOS | Web | Linux | macOS | Windows |
---|---|---|---|---|---|
✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Installation
- Add following dependency in pubspec.yaml file.
flutter pub add select2dot1
- Add this import to your file.
import 'package:select2dot1/select2dot1.dart';
- Now you can use Select2dot1 widget. Go to Usage section and see how to use it.
Usage
- On the first step you need to create a list of data that you want to display in.
static const List<SingleCategoryModel> exampleData = [
SingleCategoryModel(
nameCategory: 'Team Leader',
singleItemCategoryList: [
SingleItemCategoryModel(
nameSingleItem: 'David Eubanks',
extraInfoSingleItem: 'Full time',
avatarSingleItem: CircleAvatar(
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
backgroundImage: AssetImage('assets/images/avatar1.jpg'),
),
),
SingleItemCategoryModel(
nameSingleItem: 'Stuart Resch',
extraInfoSingleItem: 'Part time',
avatarSingleItem: CircleAvatar(
backgroundColor: Colors.blue,
child: Text('SR', style: TextStyle(color: Colors.white)),
),
),
],
),
];
- Use Select2dot1 widget and pass your data to it. You can also pass scrollController if you want to use it.
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
scrollController: scrollController,
),
Features
Scroll Controller
ScrollController is used to control anchor position of dropdown menu. You can pass your own ScrollController to Select2dot1 widget.
Fully Customizable
All components of Select2dot1 are fully customizable by settings and builder. If you want to change something that is not available in settings, let's make yor own component by builder. Check Customization section for more information.
Components and Settings
Components View
In this section you can see how components of Select2dot1 widget look like and see hierarchy. You can also see how to customize them by settings and builder. For more details hierarchy of components , go to Tree View Components with Settings section.
Component Pillbox Configuration 1
- Pillbox
- PillboxTitle
- PillboxContent
- PillboxContentMulti / PillboxContentSingle
- SelectEmptyInfo
- PillboxIcon
Component Pillbox Configuration 2
- Pillbox
- PillboxTitle
- PillboxContent
- PillboxContentMulti
- SelectChip
- PillboxIcon
Component Pillbox Configuration 3
- Pillbox
- PillboxTitle
- PillboxContent
- PillboxContentMulti
- SelectOverloadInfo
- PillboxIcon
Component Pillbox Configuration 4
- Pillbox
- PillboxTitle
- PillboxContent
- PillboxContentSingle
- SelectSingle
- PillboxIcon
Component Dropdown Overlay Configuration 1
- DropdownOverlay, DropdownContentOverlay
- SearchBarOverlay
- ListDataViewOverlay
- CategoryNameOverlay
- CategoryItemOverlay
Component Dropdown Overlay Configuration 2
- DropdownOverlay, DropdownContentOverlay
- SearchBarOverlay
- SearchEmptyOverlay
Component Dropdown Modal Configuration 1
- showModalBottomSheet, DropdownModal, DropdownContentModal
- TitleModal
- ButtonModal
- SearchBarModal
- ListDataViewModal
- CategoryNameModal
- CategoryItemModal
Component Dropdown Modal Configuration 2
- DropdownOverlay, DropdownContent
- TitleModal
- ButtonModal
- SearchBarModal
- SearchEmptyModal
Tree View Components with Settings
You can see TreeView components with settings there. Tree View was created by Miro. If you want customize components of Select2dot1 widget, you can use Tree View to see all components and settings. The most helpful site - You must see it.
Customization
If you want to customize Select2dot1 widget you can do it by settings and builder. First try to use settings to customize, if you can't find what you need, use builder.
By Settings
Use global settings to customize all components of Select2dot1 widget
You can pass global settings to Select2dot1 widget. Global settings will be used by all components of Select2dot1 widget.
In this example we will customize mainColor and fontFamily for all components of Select2dot1 widget.
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
globalSettings: const GlobalSettings(
fontFamily: 'Roboto',
mainColor: Colors.blue,
),
);
Use single component settings to customize only one component of Select2dot1 widget
You can pass single component settings to Select2dot1 widget. Single component settings will be used only by one component of Select2dot1 widget.
In this example we will customize only CategoryNameOverlay component and CategoryItemOverlay component in Dropdown (change visible only on desktop overlay).
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
categoryNameOverlaySettings: CategoryNameOverlaySettings(
constraints: const BoxConstraints(minHeight: 27),
textStyle: const TextStyle(
color: Color(0xFF6B7893),
fontSize: 14,
fontWeight: FontWeight.w500,
),
defaultDecoration: const BoxDecoration(color: Colors.transparent),
hoverDecoration:
BoxDecoration(color: const Color(0xFF00183D).withOpacity(0.5)),
),
categoryItemOverlaySettings: CategoryItemOverlaySettings(
constraints: const BoxConstraints(minHeight: 35),
defaultTextStyle: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500,
),
selectedTextStyle: const TextStyle(
color: Color(0xFF1DEDB2),
fontSize: 14,
fontWeight: FontWeight.w500,
),
iconSize: 14,
iconSelectedColor: const Color(0xFF1DEDB2),
defaultDecoration: const BoxDecoration(color: Colors.transparent),
hoverDecoration:
BoxDecoration(color: const Color(0xFF00183D).withOpacity(0.5)),
showExtraInfo: extraInfoInDropdown,
),
);
By Builder
In builder you can customize all components of Select2dot1 widget. You can use your own components or use default components that are available in Select2dot1 widget.
Create your completly own component
You can create your own component by using Select2dot1Builder class. You have to pass your own component to Select2dot1Builder class and then pass this class to Select2dot1 widget. In builder you have access to all data that you need to create your own component.
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
selectChipBuilder: (context, selectChipDetails) {
return Container(
height: 29,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
constraints: const BoxConstraints(maxWidth: 200),
decoration: BoxDecoration(
color: const Color(0xFF001029),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.white),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
selectChipDetails.singleItemCategory.getNameSingleItem,
softWrap: false,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.white),
),
),
Padding(
padding: const EdgeInsets.only(top: 1.0, left: 2.0),
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
selectChipDetails.selectDataController
.removeSingleSelectedChip(
selectChipDetails.singleItemCategory,
);
},
child: const Icon(
Icons.clear,
color: Colors.white,
size: 14,
),
),
),
)
],
),
);
},
),
Use default components
If you want change layout of component which includes a lot of other components, you can use default components that are available in Select2dot1 widget. You can use them by passing them to Select2dot1Builder class. Remember that when using this builder, you must ensure the correctness of the written code yourself.
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
pillboxTitleSettings:
const PillboxTitleSettings(title: 'Example use builder'),
pillboxBuilder: (context, pillboxDetails) => Material(
color: Colors.transparent,
child: InkWell(
onTap: pillboxDetails.showDropdown,
mouseCursor: SystemMouseCursors.click,
onHover: (hoverState) => mounted
? setState(() => pillboxDetails.hover = hoverState)
: null,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
focusColor: Colors.transparent,
child: Row( // In this builder I changed layout of pillbox (Column to Row)
mainAxisSize: MainAxisSize.min,
children: [
pillboxDetails.pillboxTitle(),
const SizedBox(width: 8),
Expanded(child: pillboxDetails.pillboxContent()),
],
),
),
),
);
Model Structur Data
To use Select2dot1 widget you have to pass data to SelectDataController. Data must be in list of SingleCategoryModel.
SingleCategoryModel is a model that contains data about single category. Parameters:
- nameCategory - name of category (It is optional if you don't want to show group select)
- singleItemCategoryList - list of SingleItemCategoryModel (It is required)
SingleItemCategoryModel is a model that contains data about single item in category. Parameters:
- nameSingleItem - visible name of single item (It is required)
- value - value of single item (It is optional)
- extraInfoSingleItem - extra info about single item (It is optional)
- avatarSingleItem - avatar of single item (It is optional)
Value parametr in SingleItemCategoryModel
It used to get specific id of single item. It's necessary when you want to distinguish between single items with the same nameSingleItem.
static const List<SingleCategoryModel> exampleData = [
SingleCategoryModel(
singleItemCategoryList: [
SingleItemCategoryModel(nameSingleItem: 'Alabama', value: 'Alabama1'),
SingleItemCategoryModel(nameSingleItem: 'Alabama', value: 'Alabama2'),
SingleItemCategoryModel(nameSingleItem: 'Arkansas'),
SingleItemCategoryModel(nameSingleItem: 'Illonois'),
],
),
];
Example data
static const List<SingleCategoryModel> exampleData = [
SingleCategoryModel(
nameCategory: 'Team Leader',
singleItemCategoryList: [
SingleItemCategoryModel(
nameSingleItem: 'David Eubanks',
extraInfoSingleItem: 'Full time',
avatarSingleItem: CircleAvatar(
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
backgroundImage: AssetImage('assets/images/avatar1.jpg'),
),
),
SingleItemCategoryModel(
nameSingleItem: 'Stuart Resch',
extraInfoSingleItem: 'Part time',
avatarSingleItem: CircleAvatar(
backgroundColor: Colors.blue,
child: Text('SR', style: TextStyle(color: Colors.white)),
),
),
],
),
SingleCategoryModel(
nameCategory: 'UX Designer',
singleItemCategoryList: [
SingleItemCategoryModel(
nameSingleItem: 'Jan Foxstein',
extraInfoSingleItem: 'Full time',
),
SingleItemCategoryModel(
nameSingleItem: 'Jhony Steward',
extraInfoSingleItem: 'Part time',
avatarSingleItem: CircleAvatar(
backgroundColor: Colors.blue,
child: Text('JS', style: TextStyle(color: Colors.white)),
),
),
],
),
];
Controllers
SelectDataController
SelectDataController is a controller that is used to manage data in Select2dot1 widget. You can use it to add, remove, select and deselect data. All data that you want to display in Select2dot1 widget must be added to SelectDataController. Remember that when isMultiple is false, you can add only one position to initialSelectedData.
In SelectDataController you can also set:
- inital selected data
- is multiple select or single select
Select2dot1(
selectDataController:
SelectDataController(
data: exampleData,
isMultiple: false,
initialSelectedData: [ // Remember that when isMultiple is false, you can add only one position to initialSelectedData.
SingleItemCategoryModel(
nameSingleItem: 'Stuart Resch',
value: 'Stuart Resch 1',
),
],
),
);
Contributing
Pull requests (pull request template is available) are welcome. For major changes, please open an issue first to discuss what you would like to change. More information about contributing you can find here. Remember to follow the code of conduct.
Issues
If you find any issues (bug, feature, performance or other), please report them here.
Please do not ask questions in the issue tracker. Use Q&A section instead.
Please do not report security vulnerabilities on the public issue tracker. The SECURITY page details the procedure for disclosing security issues.
Security
If you discover any security related issues, please go to SECURITY page.
Contributors
- Roman Dykyj (@romanjrdykyj)
QA
If you have any questions, feel free to ask them here.
FAQ
How to get selected item?
Use 'onChanged' Callback Function
You can pass callback function to Select2dot1 widget. This function will be called every time when user select an item.
Select2dot1(
selectDataController: SelectDataController(data: exampleData),
onChanged: (value) {
print(value); // value is a list of selected items
},
),
How to init selected data?
Select2dot1(
selectDataController: SelectDataController(data: exampleData,
initialSelectedData: [
SingleItemCategoryModel(
nameSingleItem: 'Alabama',
),
SingleItemCategoryModel(
nameSingleItem: 'California',
),
],
),
),
How to used only overlay or modal mode on all platforms?
It is not possible to use only overlay or modal mode on all platforms. It is automatically set by the package. Overlay mode is used on desktop and modal mode is used on mobile.
How to set NO group select?
If you dont want to group select, you dont need to use name parameter in SingleCategoryModel.
static const List<SingleCategoryModel> exampleData3 = [
SingleCategoryModel(
nameCategory: null, // If you dont want to group select, you dont need to use name parameter in SingleCategoryModel or set it to null.
singleItemCategoryList: [
SingleItemCategoryModel(nameSingleItem: 'Alabama',),
SingleItemCategoryModel(nameSingleItem: 'Arkansas'),
SingleItemCategoryModel(nameSingleItem: 'Illonois'),
],
),
];
License
This package is licensed under the MIT license. To see the full license text, see the LICENSE file.