[READ-ONLY] Mirror of https://github.com/bombshell-dev/tty. Platform independent 2D layout engine for terminal applications based on Clay
5

Configure Feed

Select the types of activity you want to include in your feed.

🎨 example(term): simplify layout and fall back to space for empty input

Charles Lowell (Jul 2, 2026, 6:29 PM +0300) ddd8e9df a7d47a05

+14 -58
+14 -58
examples/text-input/index.ts
··· 12 12 rgba, 13 13 text, 14 14 } from "../../mod.ts"; 15 - import { 16 - alternateBuffer, 17 - progressiveInput, 18 - settings, 19 - } from "../../settings.ts"; 15 + import { alternateBuffer, progressiveInput, settings } from "../../settings.ts"; 20 16 import { useInput } from "../use-input.ts"; 21 17 import { useStdin } from "../use-stdin.ts"; 22 18 23 19 const bg = rgba(20, 20, 30); 24 20 const inputBg = rgba(35, 35, 50); 25 - const border = rgba(80, 100, 160); 26 21 const label = rgba(180, 180, 200); 27 22 const hint = rgba(80, 80, 100); 28 23 ··· 97 92 }); 98 93 99 94 function frame(value: string, caret: number): Op[] { 100 - let ops: Op[] = []; 101 - 102 - ops.push( 95 + return [ 103 96 open("root", { 104 97 layout: { 105 98 width: grow(), 106 99 height: grow(), 107 100 direction: "ttb", 108 - alignX: "center", 109 - alignY: "center", 110 - padding: { left: 4, right: 4, top: 2, bottom: 2 }, 101 + padding: { left: 2, right: 2, top: 1, bottom: 1 }, 102 + gap: 1, 111 103 }, 112 104 bg, 113 105 }), 114 - ); 115 - 116 - // Input row: "Name:" label + input box 117 - ops.push( 118 - open("input-row", { 119 - layout: { 120 - direction: "ltr", 121 - gap: 2, 122 - height: fixed(3), 123 - alignY: "center", 124 - }, 125 - }), 126 - ); 127 - 128 - ops.push( 129 - open("label", { 130 - layout: { 131 - width: fixed(6), 132 - height: fixed(1), 133 - alignX: "right", 134 - alignY: "center", 135 - }, 136 - }), 106 + open("label", { layout: { height: fixed(1) } }), 137 107 text("Name:", { color: label }), 138 108 close(), 139 - ); 140 - 141 - ops.push( 142 109 open("input-box", { 143 110 layout: { 144 111 width: fixed(40), 145 112 height: fixed(1), 146 113 padding: { left: 1, right: 1 }, 147 - alignY: "center", 148 114 }, 149 115 bg: inputBg, 150 - border: { color: border, left: 1, right: 1, top: 1, bottom: 1 }, 151 116 }), 152 - text(value, { color: label, caret }), 117 + // A single space stands in for an empty value: Clay does not emit a 118 + // text render command for an empty string, which means the renderer 119 + // cannot resolve the caret's cell when the field is empty. The space 120 + // is invisible against the input background. When the renderer 121 + // gains a fallback for empty-text carets, drop the `|| " "`. 122 + text(value || " ", { color: label, caret }), 153 123 close(), 154 - ); 155 - 156 - ops.push(close()); // input-row 157 - 158 - // Hint line 159 - ops.push( 160 - open("hint", { 161 - layout: { 162 - height: fixed(1), 163 - padding: { top: 1 }, 164 - }, 165 - }), 124 + open("hint", { layout: { height: fixed(1) } }), 166 125 text("← → move Backspace delete Esc or Ctrl+C exit", { color: hint }), 167 126 close(), 168 - ); 169 - 170 - ops.push(close()); // root 171 - 172 - return ops; 127 + close(), 128 + ]; 173 129 } 174 130 175 131 function terminalSize(): { columns: number; rows: number } {