SmartSelect allows you to easily convert your usual form select or dropdown into dynamic page, popup dialog, or sliding bottom sheet with various choices input such as radio, checkbox, switch, chips, or even custom input. Supports single and multiple choice.
No Data
SmartSelect allows you to easily convert your usual form select or dropdown into dynamic page, popup dialog, or sliding bottom sheet with various choices input such as radio, checkbox, switch, chips, or even custom input. Supports single and multiple choice. Inspired by Smart Select component from Framework7.
copyWithand
merge
StatefulWidgetas state management
modalValidationfunction nows should return
Stringto indicates the changes value is not valid and
nullor empty
Stringto indicates the changes value is valid
To display tile with chips use param
S2Tile.bodyand
S2TileChips, instead of
S2ChipsTile
The parameter
optionsis removed, instead use
choiceItems
Simplify class name and enum
SmartSelectTileto
S2Tile
SmartSelectOptionto
S2Choice
SmartSelectChoiceConfigto
S2ChoiceConfig
SmartSelectChoiceStyleto
S2ChoiceStyle
SmartSelectChoiceTypeto
S2ChoiceType
SmartSelectModalConfigto
S2ModalConfig
SmartSelectModalStyleto
S2ModalStyle
SmartSelectModalHeaderStyleto
S2ModalHeaderStyle
SmartSelectModalTypeto
S2ModalType
The parameter
buildernow is a collection of builder (
S2SingleBuilderor
S2MultiBuilder), instead use
tileBuilderto create trigger tile widget.
The parameters
dense,
enabled,
isLoading,
isTwoLine,
leading,
loadingText,
padding,
selected,
trailingis removed from
SmartSelectclass, instead use
builder.tileor
tileBuilderand return
S2Tilewidget, it's has all these parameters.
The parameter
onChangenows return
S2SingleState stateor
S2MultiState stateinstead of
T valueor
List value
The parameter
choiceConfig.useWrapis removed, instead use
choiceConfig.layout = S2ChoiceLayout.wrap
The parameter
choiceConfig.buildermoved to
builder.choiceor
choiceBuilder
The parameter
choiceConfig.titleBuildermoved to
builder.choiceTitleor
choiceTitleBuilder
The parameter
choiceConfig.subtitleBuildermoved to
builder.choiceSubtitleor
choiceSubtitleBuilder
The parameter
choiceConfig.secondaryBuildermoved to
builder.choiceSecondaryor
choiceSecondaryBuilder
The parameter
choiceConfig.dividerBuildermoved to
builder.choiceDivideror
choiceDividerBuilder
The parameter
choiceConfig.emptyBuildermoved to
builder.choiceEmptyor
choiceEmptybuilder
The parameter
choiceConfig.glowingOverscrollIndicatorColoris removed, instead use
choiceConfig.overscrollColor
The parameter
choiceConfig.spacingand
choiceConfig.runSpacingmoved to
choiceConfig.style.spacingand
choiceConfig.style.runSpacing
The parameter
choiceConfig.useCheckmarkmoved to
choiceConfig.style.showCheckmark
The parameter
choiceConfig.paddingmoved to
choiceConfig.style.wrapperPadding
The default of grouped choice is not using sticky header now, instead use
groupBuilderlike this:
dependencies: sticky_headers: "^0.1.8"
import 'package:sticky_headers/sticky_headers.dart';SmartSelect.single/multiple( ..., ..., choiceGroupBuilder: (context, header, choices) { return StickyHeader( header: header, content: choices, ); }, );
List
For a complete usage, please see the example.
To read more about classes and other references used by
smart_select, see the API Reference.
// available configuration for single choice SmartSelect.single({// The primary content of the widget. // Used in trigger widget and header option String title,
// The text displayed when the value is null String placeholder = 'Select one',
// The current value of the single choice widget. @required T value,
// Called when single choice value changed @required ValueChanged> onChange,
// choice item list List> choiceItems,
// other available configuration // explained below ..., ...,
})
// simple usageString value = 'flutter'; List> options = [ S2Choice(value: 'ion', title: 'Ionic'), S2Choice(value: 'flu', title: 'Flutter'), S2Choice(value: 'rea', title: 'React Native'), ];
@override Widget build(BuildContext context) { return SmartSelect.single( title: 'Frameworks', value: value, choiceItems: options, onChange: (state) => setState(() => value = state.value) ); }
// available configuration for multiple choice SmartSelect.multiple({// The primary content of the widget. // Used in trigger widget and header option String title,
// The text displayed when the value is null String placeholder = 'Select one',
// The current value of the single choice widget. @required List value,
// Called when single choice value changed @required ValueChanged> onChange,
// choice item list List> choiceItems,
// other available configuration // explained below ..., ...,
})
// a simple usageList value = [2]; List> frameworks = [ S2Choice(value: 1, title: 'Ionic'), S2Choice(value: 2, title: 'Flutter'), S2Choice(value: 3, title: 'React Native'), ];
@override Widget build(BuildContext context) { return SmartSelect.multiple( title: 'Frameworks', value: value, choiceItems: options, onChange: (state) => setState(() => value = state.value), ); }
// configuration SmartSelect.[single|multiple]({// other configuration ..., ...,
// choice item list List> choiceItems,
// other configuration ..., ...,
});
choiceItemscan be input directly as in the example below, more info about
S2Choicecan be found on the API Reference
SmartSelect.[single|multiple]( ..., ..., choiceItems: >[ S2Choice(value: 1, title: 'Ionic'), S2Choice(value: 2, title: 'Flutter'), S2Choice(value: 3, title: 'React Native'), ], );
choiceItemsalso can be created from any list using helper provided by this package, like the example below
List
Please follow these example
More info about
S2ModalConfigcan be found on the API Reference
// available configuration SmartSelect.[single|multiple]({// other configuration ..., ...,
// Modal validation of single choice widget ValidationCallback modalValidation,
// Modal configuration S2ModalConfig modalConfig,
// Configure modal style // shortcut to [modalConfig.style] S2ModalStyle modalStyle,
// Configure modal header style // shortcut to [modalConfig.headerStyle] S2ModalHeaderStyle modalHeaderStyle,
// Modal type to display choices // shortcut to [modalConfig.type] S2ModalType modalType,
// Use different title with the trigger widget title // shortcut to [modalConfig.title] String modalTitle,
// Whether the option list need to confirm // to return the changed value // shortcut to [modalConfig.useConfirm] bool modalConfirm,
// Whether the options list modal use header or not // shortcut to [modalConfig.useHeader] bool modalHeader,
// Whether the option list is filterable or not // shortcut to [modalConfig.useFilter] bool modalFilter,
// Whether the filter is autocomplete or need confirmation // shortcut to [modalConfig.filterAuto] bool modalFilterAuto,
// Custom searchbar hint // shortcut to [modalConfig.filterHint] String modalFilterHint,
// other configuration ..., ...,
});
By default SmartSelect will open choices modal in full page. You can change it by changing with this value:
// Available option enum S2ModalType {// open in full page fullPage,
// open in popup dialog popupDialog,
// open in sliding bottom sheet bottomSheet,
}
// Available option to configure modal style S2ModalStyle({// Modal border shape // used in popup dialog and bottom sheet ShapeBorder shape,
// Modal elevation // used in popup dialog and bottom sheet double elevation,
// Modal background color Color backgroundColor,
// Modal clip behavior Clip clipBehavior,
})
// Available option to configure modal header style S2ModalHeaderStyle({// Header border shape ShapeBorder shape,
// Header elevation double elevation,
// Header background color Color backgroundColor,
// Header brightness Brightness brightness,
// Whether the header title is centered bool centerTitle,
// Whether the header use automaticallyImplyLeading or not bool useLeading,
// Header text style // used by title and search field TextStyle textStyle,
// Header icon theme IconThemeData iconTheme,
// Header actions icon theme IconThemeData actionsIconTheme,
})
More info about
S2ChoiceConfigcan be found on the API Reference
// Available option to configure choices SmartSelect.[single|multiple]({// other configuration ..., ...,
// choice configuration S2ChoiceConfig choiceConfig,
// configure choice style // shortcut to [choiceConfig.style] S2ChoiceStyle choiceStyle,
// configure choices group header style // shortcut to [choiceConfig.headerStyle] S2ChoiceHeaderStyle choiceHeaderStyle,
// choice widget type // shortcut to [choiceConfig.type] S2ChoiceType choiceType,
// choice layout to display items // shortcut to [choiceConfig.layout] S2ChoiceLayout choiceLayout,
// choice list scroll direction // currently only support when // [layout] is [S2ChoiceLayout.wrap] // shortcut to [choiceConfig.direction] Axis choiceDirection,
// Whether the choices list is grouped // shortcut to [choiceConfig.isGrouped] bool choiceGrouped,
// Whether the choices item use divider or not // shortcut to [choiceConfig.useDivider] bool choiceDivider,
// For grid choice layout // shortcut to [choiceConfig.gridDelegate] SliverGridDelegate choiceGrid,
// other configuration ..., ...,
});
By default SmartSelect will use
radiosfor single choice and
checkboxesfor multiple choice, but it can change by changing with this value:
// Type of choice input enum S2ChoiceType {// use radio widget // for single choice radios,
// use checkbox widget // for multiple choice checkboxes,
// use switch widget // for multiple choice switches,
// use chip widget // for single and multiple choice chips,
}
By default SmartSelect will use
list, but it can change by changing with this value:
// Layout of choice item enum S2ChoiceLayout {// use list view widget list,
// use wrap view widget wrap,
// use grid view widget grid,
}
// Available option to configure choice style S2ChoiceStyle({// How much space to place between children in a run in the main axis. // When use [SmartSelectChoiceType.chips] or [useWrap] is [true] double spacing,
// How much space to place between the runs themselves in the cross axis. // When use [SmartSelectChoiceType.chips] or [useWrap] is [true] double runSpacing,
// choices wrapper padding EdgeInsetsGeometry wrapperPadding,
// Choices item padding EdgeInsetsGeometry padding,
// choices item title style TextStyle titleStyle,
// choices item subtitle style TextStyle subtitleStyle,
// whether the chips use checkmark or not bool showCheckmark,
// Where to place the control in widgets that use // [ListTile] to position a control next to a label. S2ChoiceControl control,
// Highlight color Color highlightColor,
// Primary color of selected choice item Color activeColor,
// Primary color of unselected choice item Color color,
// Secondary color of selected choice item Color activeAccentColor,
// Secondary color of unselected choice item Color accentColor,
// Brightness for selected Chip Brightness activeBrightness,
// Brightness for unselected Chip Brightness brightness,
// Opacity for selected Chip border, only effect when // [activeBrightness] is [Brightness.light] double activeBorderOpacity,
// Opacity for unselected chip border, only effect when // [brightness] is [Brightness.light] double borderOpacity,
// Shape clip behavior Clip clipBehavior,
})
// Available option to configure choices group header widget style S2ChoiceHeaderStyle({// Group header background color Color backgroundColor,
// Highlight color Color highlightColor,
// Group header text style TextStyle textStyle,
// Group header padding EdgeInsetsGeometry padding,
// Group header height double height,
})
// available builder configuration // for single choice SmartSelect.single({// other configuration ..., ...,
// Builder collection of single choice widget S2SingleBuilder builder,
// Builder for custom tile widget // shortcut to [builder.tile] S2WidgetBuilder> tileBuilder,
// Builder for custom modal widget // shortcut to [builder.modal] S2WidgetBuilder> modalBuilder,
// Builder for custom modal header widget // shortcut to [builder.modalHeader] S2WidgetBuilder> modalHeaderBuilder,
// Builder for custom modal actions widget // shortcut to [builder.modalActions] S2ListWidgetBuilder> modalActionsBuilder,
// Builder for custom modal confirm action widget // shortcut to [builder.modalConfirm] S2WidgetBuilder> modalConfirmBuilder,
// Builder for divider widget between header, body, and footer modal // shortcut to [builder.modalDivider] S2WidgetBuilder> modalDividerBuilder,
// Builder for custom footer widget // shortcut to [builder.modalFooter] S2WidgetBuilder> modalFooterBuilder,
// other configuration ..., ...,
});
// available builder configuration // for multiple choice SmartSelect.multiple({// other configuration ..., ...,
// Builder collection of single choice widget S2MultiBuilder builder,
// Builder for custom tile widget // shortcut to [builder.tile] S2WidgetBuilder> tileBuilder,
// Builder for custom modal widget // shortcut to [builder.modal] S2WidgetBuilder> modalBuilder,
// Builder for custom modal header widget // shortcut to [builder.modalHeader] S2WidgetBuilder> modalHeaderBuilder,
// Builder for custom modal actions widget // shortcut to [builder.modalActions] S2ListWidgetBuilder> modalActionsBuilder,
// Builder for custom modal confirm action widget // shortcut to [builder.modalConfirm] S2WidgetBuilder> modalConfirmBuilder,
// Builder for divider widget between header, body, and footer modal // shortcut to [builder.modalDivider] S2WidgetBuilder> modalDividerBuilder,
// Builder for custom footer widget // shortcut to [builder.modalFooter] S2WidgetBuilder> modalFooterBuilder,
// other configuration ..., ...,
});
// another builder configuration SmartSelect.[single|multiple]({// other configuration ..., ...,
// Builder for modal filter widget // shortcut to [builder.modalFilter] S2WidgetBuilder modalFilterBuilder,
// Builder for modal filter toggle widget // shortcut to [builder.modalFilterToggle] S2WidgetBuilder modalFilterToggleBuilder,
// Builder for each custom choices item widget // shortcut to [builder.choice] S2ChoiceBuilder choiceBuilder,
// Builder for each custom choices item title widget // shortcut to [builder.choiceTitle] S2ChoiceBuilder choiceTitleBuilder,
// Builder for each custom choices item subtitle widget // shortcut to [builder.choiceSubtitle] S2ChoiceBuilder choiceSubtitleBuilder,
// Builder for each custom choices item secondary widget // shortcut to [builder.choiceSecondary] S2ChoiceBuilder choiceSecondaryBuilder,
/// Builder for custom divider widget between choices item // shortcut to [builder.choiceDivider] IndexedWidgetBuilder choiceDividerBuilder,
// Builder for custom empty display // shortcut to [builder.choiceEmpty] S2WidgetBuilder choiceEmptyBuilder,
// A widget builder for custom choices group // shortcut to [builder.choiceGroup] S2ChoiceGroupBuilder choiceGroupBuilder,
// A widget builder for custom header choices group // shortcut to [builder.choiceHeader] S2ChoiceHeaderBuilder choiceHeaderBuilder,
// other configuration ..., ...,
});
// Default tile/trigger widget S2Tile({// The value of the selected option. String value,
// The primary content of the list tile. Widget title,
// A widget to display before the title. // Typically an [Icon] or a [CircleAvatar] widget. Widget leading,
// A widget to display after the title. // Typically an [Icon] widget. Widget trailing,
// Whether this list tile is intended to display loading stats. bool isLoading,
// String text used as loading text String loadingText,
// Whether this list tile is intended to display two lines of text. bool isTwoLine,
// Whether this list tile is interactive. bool enabled,
// If this tile is also [enabled] then icons and text are rendered with the same color. bool selected,
// Whether this list tile is part of a vertically dense list. bool dense,
// Whether the [value] is displayed or not bool hideValue,
// The tile's internal padding. EdgeInsetsGeometry padding,
// Called when the user taps this list tile. GestureTapCallback onTap,
// widget to display below the tile // usually used to display chips with S2TileChips Widget body,
})
// usage example SmartSelect.single( ..., ..., tileBuilder: (context, state) { return S2Tile( title: state.titleWidget, value: state.valueDisplay, onTap: state.showModal, isLoading: true, ); }, );// usage example from state SmartSelect.multiple( ..., ..., tileBuilder: (context, state) { return S2Tile.fromState( state, isLoading: true, ); }, );
// Chips tile/trigger widget S2TileChips({// List of value of the selected choices. int chipLength,
// Widget builder for chip label item IndexedWidgetBuilder chipLabelBuilder,
// Widget builder for chip avatar item IndexedWidgetBuilder chipAvatarBuilder,
// Widget builder for chip item IndexedWidgetBuilder chipBuilder,
// Called when the user delete the chip item. ValueChanged chipOnDelete,
// Chip color Color chipColor,
// Chip border opacity double chipBorderOpacity,
// Chip brightness Brightness chipBrightness,
// Chip delete button color Color chipDeleteColor,
// Chip delete button icon Icon chipDeleteIcon,
// Chip spacing double chipSpacing,
// Chip run spacing double chipRunSpacing,
// Chip shape border ShapeBorder chipShape,
// The [Widget] displayed when the [values] is null Widget placeholder,
// Whether the chip list is scrollable or not bool scrollable,
// Chip list padding EdgeInsetsGeometry padding,
})
/// usage example SmartSelect.multiple( ..., ..., value: users, tileBuilder: (context, state) { return S2Tile.fromState( state, hideValue: true, body: S2TileChips( chipLength: state.valueObject.length, chipLabelBuilder: (context, i) { return Text(state.valueObject[i].title); }, chipAvatarBuilder: (context, i) { return CircleAvatar( backgroundImage: NetworkImage(state.valueObject[i].meta['picture']['thumbnail']) ); }, chipOnDelete: (i) { setState(() => users.remove(state.valueObject[i].value)); }, chipColor: Colors.blue, chipBrightness: Brightness.dark, chipBorderOpacity: .5, ), ); }, );
Copyright (c) 2020 Irfan Vigma TaufikPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.