render method
Renders the component as a string.
Implementation
@override
String render() {
final content = _content.isEmpty ? [''] : _content;
// Calculate content width
var contentWidth = 0;
for (final line in content) {
final len = Style.visibleLength(line);
if (len > contentWidth) contentWidth = len;
}
// Account for title width
var titleWidth = 0;
if (_title != null) {
titleWidth = Style.visibleLength(_title!) + 4; // spaces and padding
}
// Calculate inner width
var innerWidth = contentWidth;
if (titleWidth > innerWidth) innerWidth = titleWidth;
// Apply width constraints
if (_minWidth != null && innerWidth < _minWidth!) {
innerWidth = _minWidth!;
}
if (_maxWidth != null && innerWidth > _maxWidth!) {
innerWidth = _maxWidth!;
}
if (_width != null) {
innerWidth = _width! - 2 - _paddingLeft - _paddingRight;
}
// Total inner width including padding
final totalInnerWidth = innerWidth + _paddingLeft + _paddingRight;
final buffer = StringBuffer();
final b = _border;
// Helper to style border characters
String styleBorder(String text) {
if (_borderStyle == null) return text;
return _renderConfig.configureStyle(_borderStyle!).render(text);
}
// Helper to style title
String styleTitle(String text) {
if (_titleStyle == null) return text;
return _renderConfig.configureStyle(_titleStyle!).render(text);
}
// Helper to style content
String styleContent(String text, int lineIndex) {
if (_contentStyleFunc != null) {
final style = _contentStyleFunc!(text, lineIndex);
if (style != null) {
return _renderConfig.configureStyle(style).render(text);
}
return text;
}
if (_contentStyle != null) {
return _renderConfig.configureStyle(_contentStyle!).render(text);
}
return text;
}
// Build top border
if (_title != null) {
final styledTitle = ' ${styleTitle(_title!)} ';
final titleLen = Style.visibleLength(styledTitle);
final remaining = totalInnerWidth - titleLen;
String topLine;
switch (_titleAlign) {
case PanelAlignment.left:
final rightFill = b.top * (remaining - 1);
topLine = '${b.topLeft}${b.top}$styledTitle$rightFill${b.topRight}';
case PanelAlignment.center:
final leftFill = b.top * (remaining ~/ 2);
final rightFill = b.top * (remaining - remaining ~/ 2);
topLine = '${b.topLeft}$leftFill$styledTitle$rightFill${b.topRight}';
case PanelAlignment.right:
final leftFill = b.top * (remaining - 1);
topLine = '${b.topLeft}$leftFill$styledTitle${b.top}${b.topRight}';
}
buffer.writeln(styleBorder(topLine));
} else {
buffer.writeln(
styleBorder('${b.topLeft}${b.top * totalInnerWidth}${b.topRight}'),
);
}
// Add top padding lines
for (var i = 0; i < _paddingTop; i++) {
buffer.writeln(
'${styleBorder(b.left)}${' ' * totalInnerWidth}${styleBorder(b.right)}',
);
}
// Content lines
for (var i = 0; i < content.length; i++) {
final line = content[i];
final visible = Style.visibleLength(line);
final fill = innerWidth - visible;
String alignedContent;
switch (_contentAlign) {
case PanelAlignment.left:
alignedContent = '$line${' ' * (fill > 0 ? fill : 0)}';
case PanelAlignment.center:
final leftPad = ' ' * (fill ~/ 2);
final rightPad = ' ' * (fill - fill ~/ 2);
alignedContent = '$leftPad$line$rightPad';
case PanelAlignment.right:
alignedContent = '${' ' * (fill > 0 ? fill : 0)}$line';
}
final styledContent = styleContent(alignedContent, i);
final leftPad = ' ' * _paddingLeft;
final rightPad = ' ' * _paddingRight;
buffer.writeln(
'${styleBorder(b.left)}$leftPad$styledContent$rightPad${styleBorder(b.right)}',
);
}
// Add bottom padding lines
for (var i = 0; i < _paddingBottom; i++) {
buffer.writeln(
'${styleBorder(b.left)}${' ' * totalInnerWidth}${styleBorder(b.right)}',
);
}
// Bottom border
buffer.write(
styleBorder(
'${b.bottomLeft}${b.bottom * totalInnerWidth}${b.bottomRight}',
),
);
return buffer.toString();
}