render method

  1. @override
void render(
  1. Rect area,
  2. Buffer buffer,
  3. RenderContext ctx
)
override

Implementation

@override
void render(Rect area, Buffer buffer, RenderContext ctx) {
  if (area.isEmpty) return;
  final isFocused = ctx.isFocused(id);
  final theme = ctx.theme;

  if (state.submitted && lockOnSubmit) {
    _renderSubmitted(area, buffer, ctx);
    return;
  }

  final hasError = state.error != null;
  final prefix =
      state.submitted ? successPrefix : (hasError ? errorPrefix : askPrefix);
  final prefixStyle = state.submitted
      ? (successPrefixStyle ?? Style(fg: theme.colors.success, bold: true))
      : (hasError
          ? (errorPrefixStyle ?? Style(fg: theme.colors.error, bold: true))
          : (askPrefixStyle ?? Style(fg: theme.colors.primary, bold: true)));

  final mStyle = messageStyle ?? theme.text.body;
  final iStyle = inputStyle ??
      (isFocused
          ? theme.text.body.copyWith(fg: theme.colors.primary)
          : theme.text.body);
  final dStyle = defaultValueStyle ?? theme.text.caption;

  var x = area.x;
  buffer.writeText(x, area.y, prefix,
      style: prefixStyle, maxWidth: area.right - x);
  x += prefix.length + 1;
  buffer.writeText(x, area.y, message,
      style: mStyle, maxWidth: area.right - x);
  x += message.length;

  if (_hasDefault && state.value.isEmpty) {
    final hint = ' (${defaultValue!})';
    buffer.writeText(x, area.y, hint,
        style: dStyle, maxWidth: area.right - x);
    x += hint.length;
  }
  buffer.writeText(x, area.y, ' ', style: iStyle, maxWidth: 1);
  x += 1;

  final inputStart = x;
  final inputWidth = area.right - inputStart;
  if (inputWidth > 0) {
    final showPlaceholder =
        state.value.isEmpty && (placeholder?.isNotEmpty ?? false);
    final display = showPlaceholder
        ? placeholder!
        : (obscure ? '*' * state.value.length : state.value);
    final displayStyle = showPlaceholder ? theme.text.caption : iStyle;
    buffer.writeText(inputStart, area.y, display,
        style: displayStyle, maxWidth: inputWidth);

    if (isFocused) {
      final cur = state.cursor.clamp(0, state.value.length);
      final cx = inputStart + cur;
      if (cx >= inputStart && cx < area.right) {
        final c = cur < state.value.length ? state.value[cur] : ' ';
        final ch = obscure && cur < state.value.length ? '*' : c;
        buffer.setChar(cx, area.y, ch, style: const Style(reverse: true));
      }
    }
  }

  if (hasError && area.height >= 2) {
    final eStyle = errorStyle ?? Style(fg: theme.colors.error);
    final indent = prefix.length + 1;
    buffer.writeText(area.x + indent, area.y + 1, state.error!,
        style: eStyle, maxWidth: area.width - indent);
  }
}