UNPKG

asciitorium

Version:

an ASCII ui framework for web + cli

67 lines (66 loc) 2.28 kB
export class HorizontalLayoutStrategy { constructor(options) { this.fit = options?.fit ?? false; } layout(parent, children) { const borderPad = parent.border ? 1 : 0; const innerHeight = parent.height - 2 * borderPad; const innerWidth = parent.width - 2 * borderPad; const count = children.length; let currentX = borderPad; for (const child of children) { if (child.fixed) continue; // Skip positioning if component is fixed if (this.fit && count > 0) { child.width = Math.floor(innerWidth / count); } if (!child.height) { child.height = innerHeight; } const { y } = this.resolveAlignment(child.align, child.width, innerHeight, child.width, child.height); child.x = currentX; child.y = borderPad + y; currentX += child.width + child.gap; } } resolveAlignment(align, _parentWidth, parentHeight, _childWidth, childHeight) { let vAlign = 'top'; if (typeof align === 'string') { // For horizontal layout, alignment affects vertical positioning switch (align) { case 'top-left': case 'top': case 'top-right': vAlign = 'top'; break; case 'left': case 'center': case 'right': vAlign = 'middle'; break; case 'bottom-left': case 'bottom': case 'bottom-right': vAlign = 'bottom'; break; default: vAlign = 'top'; break; } } else if (typeof align === 'object' && align !== null) { vAlign = align.y ?? 'top'; } const padY = parentHeight - childHeight; let y; if (typeof vAlign === 'number') y = vAlign; else if (vAlign === 'middle') y = Math.floor(padY / 2); else if (vAlign === 'bottom') y = padY; else y = 0; return { x: 0, y }; } }