asciitorium
Version:
an ASCII ui framework for web + cli
68 lines (67 loc) • 2.29 kB
JavaScript
export class VerticalLayoutStrategy {
constructor(options) {
this.fit = options?.fit ?? false;
}
layout(parent, children) {
const borderPad = parent.border ? 1 : 0;
const innerWidth = parent.width - 2 * borderPad;
const innerHeight = parent.height - 2 * borderPad;
const count = children.length;
let currentY = borderPad;
for (const child of children) {
if (child.fixed) {
continue; // Skip positioning if component is fixed
}
if (this.fit && count > 0) {
child.height = Math.floor(innerHeight / count);
}
if (!child.width) {
child.width = innerWidth;
}
const { x } = this.resolveAlignment(child.align, innerWidth, child.height, child.width, child.height);
child.x = borderPad + x;
child.y = currentY;
currentY += child.height + child.gap;
}
}
resolveAlignment(align, parentWidth, _parentHeight, childWidth, _childHeight) {
let hAlign = 'left';
if (typeof align === 'string') {
// For vertical layout, alignment affects horizontal positioning
switch (align) {
case 'top-left':
case 'left':
case 'bottom-left':
hAlign = 'left';
break;
case 'top':
case 'center':
case 'bottom':
hAlign = 'center';
break;
case 'top-right':
case 'right':
case 'bottom-right':
hAlign = 'right';
break;
default:
hAlign = 'left';
break;
}
}
else if (typeof align === 'object' && align !== null) {
hAlign = align.x ?? 'left';
}
const padX = parentWidth - childWidth;
let x;
if (typeof hAlign === 'number')
x = hAlign;
else if (hAlign === 'center')
x = Math.floor(padX / 2);
else if (hAlign === 'right')
x = padX;
else
x = 0;
return { x, y: 0 };
}
}