[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.

feat(border): update TS types to CSS border-style keywords with 4-byte per-side style encoding

Nate Moore (May 29, 2026, 12:55 AM EDT) b6303dba 3af42812

+32 -25
+12 -11
ops.ts
··· 13 13 14 14 const encoder = new TextEncoder(); 15 15 16 + // groove/ridge/inset/outset alias to solid (terminal can't do 3D) 17 + const styleMap: Record<string, number> = { 18 + solid: 0, 19 + double: 1, 20 + dotted: 2, 21 + dashed: 3, 22 + groove: 0, 23 + ridge: 0, 24 + inset: 0, 25 + outset: 0, 26 + }; 27 + 16 28 function packAxis(view: DataView, offset: number, axis: SizingAxis): number { 17 29 let o = offset; 18 30 switch (axis.type) { ··· 146 158 true, 147 159 ); 148 160 o += 4; 149 - // groove/ridge/inset/outset alias to solid (terminal can't do 3D) 150 - const styleMap: Record<string, number> = { 151 - solid: 0, 152 - double: 1, 153 - dotted: 2, 154 - dashed: 3, 155 - groove: 0, 156 - ridge: 0, 157 - inset: 0, 158 - outset: 0, 159 - }; 160 161 // Pack as 4 per-side style bytes (left|right<<8|top<<16|bottom<<24). 161 162 // All four are the same value today; this layout reserves space for 162 163 // future per-side style support without a protocol change.
+11 -4
src/clayterm.c
··· 397 397 int right = b->width.right > 0; 398 398 uint8_t style = (uint8_t)b->width.betweenChildren; 399 399 400 - /* map border style (0=single,1=double,2=bold) → junction style (1=single,3=double,2=bold) */ 401 - static const uint8_t smap[] = {1, 3, 2}; 402 - uint8_t js = style < 3 ? smap[style] : 1; 400 + /* width >= 2 on any side → bold/thick chars; dotted/dashed fall back to single */ 401 + uint8_t js; 402 + if (b->width.top >= 2 || b->width.left >= 2 || 403 + b->width.right >= 2 || b->width.bottom >= 2) { 404 + js = 2; /* bold */ 405 + } else if (style == 1) { 406 + js = 3; /* double */ 407 + } else { 408 + js = 1; /* solid/dotted/dashed/groove/… → single */ 409 + } 403 410 404 - int rounded = (style == 0) && 411 + int rounded = (js == 1) && 405 412 (b->cornerRadius.topLeft > 0 || b->cornerRadius.topRight > 0 || 406 413 b->cornerRadius.bottomLeft > 0 || b->cornerRadius.bottomRight > 0); 407 414
+9 -10
test/term.test.ts
··· 125 125 ╚══════════════════════════════════════╝`.trim()); 126 126 }); 127 127 128 - it("renders bold border style", () => { 128 + it("renders bold border style (width: 2)", () => { 129 129 let out = print( 130 130 decode( 131 131 term.render([ ··· 133 133 layout: { width: grow(), height: grow() }, 134 134 border: { 135 135 color: rgba(255, 255, 255), 136 - left: 1, 137 - right: 1, 138 - top: 1, 139 - bottom: 1, 140 - style: "bold", 136 + left: 2, 137 + right: 2, 138 + top: 2, 139 + bottom: 2, 141 140 }, 142 141 }), 143 142 close(), ··· 216 215 expect(out).toMatch(/^│\s+│\s+│$/m); 217 216 }); 218 217 219 - it("renders T-junctions for bold-style borders", () => { 218 + it("renders T-junctions for bold-style borders (width: 2)", () => { 220 219 let out = print( 221 220 decode( 222 221 term.render([ 223 222 open("root", { 224 223 layout: { width: grow(), height: grow(), direction: "ltr" }, 225 - border: { color: rgba(255, 255, 255), left: 1, right: 1, top: 1, bottom: 1, style: "bold" }, 224 + border: { color: rgba(255, 255, 255), left: 2, right: 2, top: 2, bottom: 2 }, 226 225 }), 227 226 open("left", { 228 227 layout: { width: fixed(10), height: grow() }, 229 - border: { color: rgba(255, 255, 255), right: 1, style: "bold" }, 228 + border: { color: rgba(255, 255, 255), right: 2 }, 230 229 }), 231 230 close(), 232 231 open("right", { layout: { width: grow(), height: grow() } }), ··· 280 279 }), 281 280 open("left", { 282 281 layout: { width: fixed(10), height: grow() }, 283 - border: { color: rgba(255, 255, 255), right: 1, style: "single" }, 282 + border: { color: rgba(255, 255, 255), right: 1, style: "solid" }, 284 283 }), 285 284 close(), 286 285 open("right", { layout: { width: grow(), height: grow() } }),