UNPKG

tuix

Version:

A performant TUI framework for Bun with JSX and reactive state management

77 lines (66 loc) 2.14 kB
/** * Simple layout functions that properly compose views */ import { Effect } from "effect" import { stringWidth } from "@/utils/string-width.ts" import type { View } from "@/core/types.ts" /** * Simple vertical box that stacks views */ export const simpleVBox = (views: View[]): View => { if (views.length === 0) { return { render: () => Effect.succeed(""), width: 0, height: 0 } } return { render: () => Effect.gen(function* (_) { const rendered: string[] = [] for (const view of views) { const content = yield* _(view.render()) rendered.push(content) } return rendered.join('\n') }), width: Math.max(...views.map(v => v.width || 0)), height: views.reduce((sum, v) => sum + (v.height || 0), 0) } } /** * Simple horizontal box that joins views side by side */ export const simpleHBox = (views: View[]): View => { if (views.length === 0) { return { render: () => Effect.succeed(""), width: 0, height: 0 } } return { render: () => Effect.gen(function* (_) { // Render all views const rendered: string[][] = [] for (const view of views) { const content = yield* _(view.render()) rendered.push(content.split('\n')) } // Find max height const maxHeight = Math.max(...rendered.map(lines => lines.length)) // Pad all to same height for (let i = 0; i < rendered.length; i++) { while (rendered[i].length < maxHeight) { rendered[i].push('') } } // Join horizontally const result: string[] = [] for (let row = 0; row < maxHeight; row++) { const parts: string[] = [] for (let col = 0; col < rendered.length; col++) { const line = rendered[col][row] || '' const width = views[col].width || stringWidth(line) parts.push(line.padEnd(width)) } result.push(parts.join('')) } return result.join('\n') }), width: views.reduce((sum, v) => sum + (v.width || 0), 0), height: Math.max(...views.map(v => v.height || 0)) } }