render method
Renders the component as a string.
Implementation
@override
String render() {
final lines = _normalizeLines(content);
final effectiveBorderStyle = renderConfig.configureStyle(
borderStyle ?? Style().dim(),
);
final titleStyle = renderConfig.configureStyle(Style().bold());
String border(String s) => effectiveBorderStyle.render(s);
String titleFn(String s) => titleStyle.render(s);
// Calculate width
final contentWidth = lines
.map((l) => Style.visibleLength(l))
.fold<int>(0, (m, v) => v > m ? v : m);
final titleWidth = title != null ? Style.visibleLength(title!) + 4 : 0;
final minWidth = [
contentWidth,
titleWidth,
10,
].reduce((a, b) => a > b ? a : b);
// Ensure minBound doesn't exceed maxBound for clamp
final minBound = minWidth + padding * 2 + 2;
final maxBound = renderConfig.terminalWidth;
final boxWidth = (width ?? minBound).clamp(
minBound < maxBound ? minBound : maxBound,
maxBound,
);
final innerWidth = boxWidth - 2;
final buffer = StringBuffer();
final pad = ' ' * padding;
// Top border with optional title
if (title != null) {
final styledTitle = ' ${titleFn(title!)} ';
final titleLen = Style.visibleLength(styledTitle);
final remainingWidth = innerWidth - titleLen;
String topLine;
switch (titleAlign) {
case PanelAlignment.left:
final rightFill = chars.horizontal * (remainingWidth - 1);
topLine =
'${chars.topLeft}${chars.horizontal}$styledTitle$rightFill${chars.topRight}';
case PanelAlignment.center:
final leftFill = chars.horizontal * (remainingWidth ~/ 2);
final rightFill =
chars.horizontal * (remainingWidth - remainingWidth ~/ 2);
topLine =
'${chars.topLeft}$leftFill$styledTitle$rightFill${chars.topRight}';
case PanelAlignment.right:
final leftFill = chars.horizontal * (remainingWidth - 1);
topLine =
'${chars.topLeft}$leftFill$styledTitle${chars.horizontal}${chars.topRight}';
}
buffer.writeln(border(topLine));
} else {
buffer.writeln(
border(
'${chars.topLeft}${chars.horizontal * innerWidth}${chars.topRight}',
),
);
}
// Content lines
for (final line in lines) {
final visible = Style.visibleLength(line);
final available = innerWidth - padding * 2;
final fill = available - visible;
String paddedLine;
switch (contentAlign) {
case PanelAlignment.left:
paddedLine = '$pad$line${' ' * (fill > 0 ? fill : 0)}$pad';
case PanelAlignment.center:
final leftPad = ' ' * (fill ~/ 2);
final rightPad = ' ' * (fill - fill ~/ 2);
paddedLine = '$pad$leftPad$line$rightPad$pad';
case PanelAlignment.right:
paddedLine = '$pad${' ' * (fill > 0 ? fill : 0)}$line$pad';
}
buffer.writeln(
'${border(chars.vertical)}$paddedLine${border(chars.vertical)}',
);
}
// Bottom border
buffer.write(
border(
'${chars.bottomLeft}${chars.horizontal * innerWidth}${chars.bottomRight}',
),
);
return buffer.toString();
}