run method

List<T> run({
  1. void renderCell(
    1. FrameContext ctx,
    2. T item,
    3. int index,
    4. bool isFocused,
    5. bool isSelected,
    6. int cellWidth,
    )?,
  2. String itemLabel(
    1. T item
    )?,
  3. KeyBindings? extraBindings,
  4. bool showCellSeparators = true,
  5. bool showRowSeparators = true,
})

Runs the grid prompt.

renderCell - Custom cell renderer. If null, uses default style. itemLabel - Converts item to string for display. extraBindings - Additional key bindings. cellSeparator - Separator between cells (default: │). rowSeparator - Whether to show row separators.

Returns selected items on confirm, empty list on cancel.

Implementation

List<T> run({
  void Function(
    FrameContext ctx,
    T item,
    int index,
    bool isFocused,
    bool isSelected,
    int cellWidth,
  )? renderCell,
  String Function(T item)? itemLabel,
  KeyBindings? extraBindings,
  bool showCellSeparators = true,
  bool showRowSeparators = true,
}) {
  if (items.isEmpty) return [];

  _initState();

  if (extraBindings != null) {
    _bindings = _bindings + extraBindings;
  }

  final frame = FrameView(
    title: title,
    theme: theme,
    bindings: _bindings,
  );

  final colSep = showCellSeparators ? '${theme.gray}│${theme.reset}' : '';

  void render(RenderOutput out) {
    // Recompute columns if auto
    if (columns <= 0) {
      _recomputeLayout();
      _grid.columns = _computedColumns;
    }

    final rows = _grid.rows;

    frame.render(out, (ctx) {
      for (int r = 0; r < rows; r++) {
        final buffer = StringBuffer(ctx.lb.gutter());

        for (int c = 0; c < _computedColumns; c++) {
          final idx = r * _computedColumns + c;

          if (idx >= items.length) {
            // Empty slot for alignment
            buffer.write(''.padRight(_computedCellWidth));
          } else {
            final isFocused = _grid.isFocused(idx);
            final isSelected = _selection.isSelected(idx);

            if (renderCell != null) {
              // Custom rendering - need to capture to string
              final cellContent = _renderCellToString(
                items[idx],
                idx,
                isFocused,
                isSelected,
                itemLabel,
              );
              buffer.write(cellContent);
            } else {
              // Default rendering
              final label =
                  itemLabel?.call(items[idx]) ?? items[idx].toString();
              buffer.write(_defaultCellRenderer(
                label,
                isFocused,
                isSelected,
              ));
            }
          }

          if (c != _computedColumns - 1) {
            buffer.write(colSep);
          }
        }

        ctx.line(buffer.toString());

        // Row separator
        if (showRowSeparators && r != rows - 1) {
          final rowLine = List.generate(
            _computedColumns,
            (i) => '${theme.gray}${'─' * _computedCellWidth}${theme.reset}',
          ).join('${theme.gray}┼${theme.reset}');
          ctx.gutterLine(rowLine);
        }
      }
    });
  }

  final runner = PromptRunner(hideCursor: true);
  final result = runner.runWithBindings(
    render: render,
    bindings: _bindings,
  );

  if (_cancelled || result == PromptResult.cancelled) {
    return [];
  }

  return _selection.getSelectedMany(
    items,
    fallbackIndex: _grid.focusedIndex,
  );
}