view method

  1. @override
String view()
override

Renders the current model state for display.

This method is called after every update to refresh the screen. It should return either a String or a View object.

Guidelines

  • Keep view functions pure - no side effects
  • View should only depend on model state
  • Use string interpolation or StringBuffer for complex views
  • Consider terminal width/height for responsive layouts

Example

@override
String view() {
  final buffer = StringBuffer();

  // Header
  buffer.writeln('╔════════════════════════════╗');
  buffer.writeln('║      My Application        ║');
  buffer.writeln('╚════════════════════════════╝');
  buffer.writeln();

  // Content
  if (loading) {
    buffer.writeln('Loading...');
  } else {
    for (final item in items) {
      final prefix = item == selectedItem ? '▸ ' : '  ';
      buffer.writeln('$prefix$item');
    }
  }

  buffer.writeln();

  // Footer
  buffer.writeln('↑/↓: Navigate  Enter: Select  q: Quit');

  return buffer.toString();
}

Implementation

@override
String view() {
  final buf = StringBuffer();

  // Prompt + input line.
  buf.write(styles.title.render(prompt));
  buf.write(' ');
  if (_rawInput.isEmpty) {
    buf.write(
      styles.placeholder.render(placeholder.isNotEmpty ? placeholder : '...'),
    );
  } else {
    buf.write(styles.value.render(_rawInput));
  }
  buf.writeln();

  // Dropdown.
  final allMatches = matches;
  if (allMatches.isNotEmpty) {
    final end = (_firstVisible + scroll).clamp(0, allMatches.length);
    for (var i = _firstVisible; i < end; i++) {
      final isHighlighted = (i == _highlighted);
      if (isHighlighted) {
        buf.write('  ');
        buf.write(styles.highlighted.render(styles.pointer));
        buf.write(' ');
        buf.writeln(styles.highlighted.render(allMatches[i]));
      } else {
        buf.write('    ');
        buf.writeln(styles.suggestion.render(allMatches[i]));
      }
    }
    // Scroll indicator.
    if (allMatches.length > scroll) {
      final remaining = allMatches.length - (_firstVisible + scroll);
      if (remaining > 0) {
        buf.writeln(styles.dimmed.render('  ... $remaining more'));
      }
    }
  }

  // Hint line.
  if (hint.isNotEmpty) {
    buf.writeln(styles.hint.render('  $hint'));
  }

  // Help.
  if (showHelp) {
    final helpText = keyMap
        .shortHelp()
        .where((b) => b.help.hasContent)
        .map((b) => '${b.help.key} ${b.help.desc}')
        .join('  ');
    buf.writeln(styles.dimmed.render('  $helpText'));
  }

  return buf.toString();
}