Search packages, repositories and app categories

chips_choice cover
Package detailsv3.0.1

chips_choice

Lite version of smart_select package, zero dependencies, an easy way to provide a single or multiple choice chips.

AndroidiOSWebmacOSWindowsLinux
30-day downloads
10.9K
Likes
337
Pub points
150

Install package

flutter pub add chips_choice

Package Overview

Package selection guidance compiled from public package information, community data, and project usage.

chips_choice is a lightweight, dependency-free Flutter package that simplifies the creation of single or multiple choice chips. Designed as a minimal alternative to smart_select, it offers a clean and efficient way to let users select options from a list of chips. Ideal for forms, filters, or preference pickers, it supports both single and multiple selections with customizable styling and callbacks. The package is compatible across all major platforms including Android, iOS, Web, macOS, Windows, and Linux.

Use cases

  • Form inputs with selectable options
  • Filtering data with chip choices
  • User preference selection
  • Simple dropdown alternatives
  • Dynamic tag selection

Key features

  • Zero external dependencies
  • Supports single and multiple selection
  • Lightweight and fast
  • Customizable chip appearance
  • Cross-platform compatibility
  • Simple API with callback support

Suitable for

  • Developers seeking minimal UI components
  • Projects requiring lightweight form controls
  • Apps needing platform-agnostic chip widgets
  • Fast prototyping of selection interfaces

Considerations

  • Limited to basic chip functionality
  • No built-in search or filtering
  • Not suitable for complex selection logic
  • Minimal customization beyond basic styling

Original README

Original README snapshot from the linked source repository. Visit the repository for the latest content.

Pub Version GitHub

Buy Me A Coffee

[!IMPORTANT]

Hi everyone,

I'm sorry to announce that I'm no longer maintaining the chips_choice package. It's been a great project, but it's become too difficult to maintain.

In its place, I've released a new package called choice. The combination to smart_select and chips_choice with cleaner, more flexible, and composable API for creating inline or prompted choice widgets with single or multiple selection.

I hope you'll check out choice. I think you'll find it to be a great replacement for chips_choice.

Thanks for your understanding.

Lite version of smart_select package, zero dependencies, an easy way to provide a single or multiple choice chips.

What's New in Version 3.x.x

  • Changed default chip to flexi_chip
  • C2Chip is alias to FlexiChip now
  • C2ChoiceStyle changed to C2ChipStyle and alias to FlexiChipStyle
  • Removed ChipsChoice.choiceActiveStyle and C2Choice.activeStyle since the C2ChipStyle can be an event driven properties
  • Removed C2ChoiceStyle.useCheckmark, changed to ChipsChoice.choiceCheckmark
  • Removed ChipsChoice.choiceAvatarBuilder
  • Added ChipsChoice.choiceLeadingBuilder
  • Added ChipsChoice.choiceTrailingBuilder
  • Added C2Choice.delete
  • Added C2Choice.avatarImage
  • Added C2Choice.avatarText
  • Fixed issue #26, add leading and trailing widget
  • Improved performance
  • More flexibility on styling

Demo

Preview

Preview

Demo

Features

  • Select single or multiple choice
  • Display in scrollable or wrapped list
  • Build choice items from any List
  • Customizable choice widget

Usage

For a complete usage, please see the example.

To read more about classes and other references used by chips_choice, see the API Reference.

Single Choice
// available configuration for single choice
ChipsChoice<T>.single({

  // The current value of the single choice widget.
  @required T value,

  // Called when single choice value changed
  @required C2Changed<T> onChanged,

  // choice item list
  @required List<C2Choice<T>> choiceItems,

  // Async loader of choice items
  C2ChoiceLoader<T> choiceLoader,

  // other available configuration
  // explained below
  ...,
  ...,

})

Simple usage

int tag = 1;
List<String> options = [
  'News', 'Entertainment', 'Politics',
  'Automotive', 'Sports', 'Education',
  'Fashion', 'Travel', 'Food', 'Tech',
  'Science',
];

@override
Widget build(BuildContext context) {
  return ChipsChoice<int>.single(
    value: tag,
    onChanged: (val) => setState(() => tag = val),
    choiceItems: C2Choice.listFrom<int, String>(
      source: options,
      value: (i, v) => i,
      label: (i, v) => v,
    ),
  );
}
Multiple Choice
// available configuration for multiple choice
ChipsChoice<T>.multiple({

  // The current value of the multiple choice widget.
  @required List<T> value,

  // Called when multiple choice value changed
  @required C2Changed<List<T>> onChanged,

  // choice item list
  @required List<C2Choice<T>> choiceItems,

  // Async loader of choice items
  C2ChoiceLoader<T> choiceLoader,

  // other available configuration
  // explained below
  ...,
  ...,

})

Simple usage

List<String> tags = [];
List<String> options = [
  'News', 'Entertainment', 'Politics',
  'Automotive', 'Sports', 'Education',
  'Fashion', 'Travel', 'Food', 'Tech',
  'Science',
];

@override
Widget build(BuildContext context) {
  return ChipsChoice<String>.multiple(
    value: tags,
    onChanged: (val) => setState(() => tags = val),
    choiceItems: C2Choice.listFrom<String, String>(
      source: options,
      value: (i, v) => v,
      label: (i, v) => v,
    ),
  );
}
Style Configuration

See the API References, to find out all of the parameters.

// available configuration for single and multiple choice
ChipsChoice<T>.[single|multiple]({

  // other available configuration
  // explained below
  ...,
  ...,

  // Choice item style
  C2ChipStyle choiceStyle,

  // other available configuration
  // explained below
  ...,
  ...,

})
Custom Builder
// available configuration for single and multiple choice
ChipsChoice<T>.[single|multiple]({

  // other available configuration
  // explained below
  ...,
  ...,

  // Builder for custom choice item label
  C2Builder<T> choiceLabelBuilder,

  // Builder for custom widget to display prior to the chip's [label].
  C2Builder<T>? choiceLeadingBuilder;

  // Builder for custom widget to display next to the chip's [label].
  C2Builder<T>? choiceTrailingBuilder;

  // Builder for custom choice item
  C2Builder<T> choiceBuilder,

  // Builder for spinner widget
  WidgetBuilder spinnerBuilder,

  // Builder for placeholder widget
  WidgetBuilder placeholderBuilder,

  // Builder for error widget
  WidgetBuilder errorBuilder,

  // other available configuration
  // explained below
  ...,
  ...,

})
Container Configuration
// available configuration for single and multiple choice
ChipsChoice<T>.[single|multiple]({

  // other available configuration
  // explained below
  ...,
  ...,

  // Whether the chips is wrapped or scrollable
  bool wrapped,

  // Container padding
  EdgeInsetsGeometry padding,

  // The direction to use as the main axis.
  Axis direction,

  // Determines the order to lay children out vertically and how to interpret start and end in the vertical direction.
  VerticalDirection verticalDirection,

  // Determines the order to lay children out horizontally and how to interpret start and end in the horizontal direction.
  TextDirection textDirection,

  // if [wrapped] is [false], How the scroll view should respond to user input.
  ScrollPhysics scrollPhysics,

  // if [wrapped] is [false], How much space should be occupied in the main axis.
  MainAxisSize mainAxisSize,

  // if [wrapped] is [false], How the children should be placed along the main axis.
  MainAxisAlignment mainAxisAlignment,

  // if [wrapped] is [false], How the children should be placed along the cross axis.
  CrossAxisAlignment crossAxisAlignment,

  // if [wrapped] is [true], how the children within a run should be aligned relative to each other in the cross axis.
  WrapCrossAlignment wrapCrossAlignment,

  // if [wrapped] is [true], determines how wrap will align the objects
  WrapAlignment alignment,

  // if [wrapped] is [true], how the runs themselves should be placed in the cross axis.
  WrapAlignment runAlignment,

  // if [wrapped] is [true], how much space to place between children in a run in the main axis.
  double spacing,

  // if [wrapped] is [true], how much space to place between the runs themselves in the cross axis.
  double runSpacing,

  // Clip behavior
  Clip clipBehavior,

  // String to display when choice items is empty
  String placeholder,

  // placeholder text style
  TextStyle placeholderStyle,

  // placeholder text align
  TextAlign placeholderAlign,

  // error text style
  TextStyle errorStyle,

  // error text align
  TextAlign errorAlign,

  // spinner size
  double spinnerSize,

  // spinner color
  Color spinnerColor,

  // spinner thickness
  double spinnerThickness,

  // other available configuration
  // explained below
  ...,
  ...,

})
Build Choice List

choiceItems property is List<C2Choice<T>>, it can be input directly as in the example below, more info about C2Choice can be found on the API Reference

ChipsChoice<T>.[single|multiple](
  ...,
  ...,
  choiceItems: <C2Choice<T>>[
    C2Choice<T>(value: 1, label: 'Entertainment'),
    C2Choice<T>(value: 2, label: 'Education'),
    C2Choice<T>(value: 3, label: 'Fashion'),
  ],
);

choiceItems also can be created from any list using helper provided by this package, like the example below

List<Map<String, String>> days = [
  { 'value': 'mon', 'title': 'Monday' },
  { 'value': 'tue', 'title': 'Tuesday' },
  { 'value': 'wed', 'title': 'Wednesday' },
  { 'value': 'thu', 'title': 'Thursday' },
  { 'value': 'fri', 'title': 'Friday' },
  { 'value': 'sat', 'title': 'Saturday' },
  { 'value': 'sun', 'title': 'Sunday' },
];

ChipsChoice<T>.[single|multiple](
  ...,
  ...,
  choiceItems: C2Choice.listFrom<T, Map<String, String>>(
    source: days,
    value: (index, item) => item['value'],
    label: (index, item) => item['title'],
  ),
);

Use choiceLoader to easily load choice items from async function

import 'package:dio/dio.dart';

String value;

Future<List<C2Choice<String>>> getChoices() async {
  String url = "https://randomuser.me/api/?inc=gender,name,nat,picture,email&results=25";
  Response res = await Dio().get(url);
  return C2Choice.listFrom<String, dynamic>(
    source: res.data['results'],
    value: (index, item) => item['email'],
    label: (index, item) => item['name']['first'] + ' ' + item['name']['last'],
    meta: (index, item) => item,
  )..insert(0, C2Choice<String>(value: 'all', label: 'All'));
}

@override
Widget build(BuildContext context) {
  return ChipsChoice<String>.single(
    value: value,
    onChanged: (val) => setState(() => value = val),
    choiceItems: null,
    choiceLoader: getChoices,
  );
}

Categories

Dependencies

Dependency list 2 items

  • async^2.8.2
  • flexi_chip^1.0.7

Source repository

Projects using this package

No data available yet.