multiSelect<T> method

Future<List<T>> multiSelect<T>(
  1. String message, {
  2. required List<T> options,
  3. List<T> defaults = const [],
  4. String display(
    1. T item
    )?,
  5. int? minSelections,
  6. int? maxSelections,
  7. int visibleCount = 5,
  8. bool filterable = false,
})

Lets the user pick multiple values from options. Space toggles each row; Enter submits.

Implementation

Future<List<T>> multiSelect<T>(
  String message, {
  required List<T> options,
  List<T> defaults = const [],
  String Function(T item)? display,
  int? minSelections,
  int? maxSelections,
  int visibleCount = 5,
  bool filterable = false,
}) {
  if (options.isEmpty) {
    throw ArgumentError.value(options, 'options', 'must not be empty');
  }

  final state = tui_select.SelectState<T>();
  bool submitted = false;
  List<T>? pending;

  return runOneShot<List<T>>(
    (ctx, submit) {
      if (submitted) {
        final labels = (pending ?? const [])
            .map((e) => display?.call(e) ?? e.toString())
            .join(', ');
        _drawCompactAnswer(ctx, message, labels.isEmpty ? '(none)' : labels);
        submit(pending ?? const []);
        return;
      }

      final widget = tui_select.Select<T>(
        id: Key.symbol(#__inline_multi),
        items: options,
        state: state,
        defaultValues: defaults,
        mode: tui_select.SelectionMode.multi,
        minSelections: minSelections,
        maxSelections: maxSelections,
        visibleCount: visibleCount,
        filterable: filterable,
        builder: (item, itemState) {
          final label = display?.call(item) ?? item.toString();
          final mark = itemState.isSelected ? '☒' : '☐';
          return Text(
            ' $mark $label',
            style: itemState.isActive ? const Style(bold: true) : null,
          );
        },
        onSubmit: (list) {
          pending = list;
          submitted = true;
        },
      );

      _drawWithHeader(ctx, message, widget,
          bodyHeight:
              _selectBodyHeight(options.length, visibleCount, filterable));
    },
    theme: _theme,
    terminal: _terminal(),
    allowNonInteractive: _allowNonInteractive,
  );
}