Panels: draw only some border sides - #74
Merged
Merged
Conversation
A border was all four sides or nothing. Anything else meant a divider plus
manual padding, which gives you no corner joins and no way to say "just a
top rule" -- the thing you reach for building a header strip, a sidebar
rail, or a footer that should not look boxed in.
ui.panel({ title: "Header", border: "single", sides: ["top"] }, ...)
`sides` takes "all" (the default), "none", or a list. The interior follows
the sides actually drawn, so a top-only panel costs one row rather than two.
The bit vocabulary the collapse work left behind did most of it, as #59
guessed it would. A corner belongs to the two sides that meet there, so it
exists only when both are drawn; where one is, the rule runs straight
through the cell the corner would have occupied. That is borderGlyph with
the bits for the sides present, falling back to the plain rule when only one
edge is set -- a single edge has no glyph of its own because that cell is
part of a run, not a corner.
A title and a subtitle live on the top rule and a footer on the bottom, so
none of them are drawn when their rule is absent: painting a title over the
first row of content is worse than leaving it out.
All six ports. Defaulting to all four sides keeps every existing frame
identical, which the suites confirm: TypeScript 249, Rust green, Go both
packages, Python 36, Zig 17/17, C and C++ 9/9.
Closes #59
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy
Both new files imported describe/expect from "bun:test". Every other test in the package uses node:test with assert, and for a reason: CI runs the suite twice, once under bun and once as `node --test`, and bun:test does not exist in the second. They passed locally and failed seven jobs. The justify file went in with #73 before its checks came back, which is on me; it is fixed here alongside the one it would have broken. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy
ralyodio
force-pushed
the
feat/partial-borders
branch
from
September 8, 2026 21:43
eb742e8 to
3a33c3d
Compare
c_conformance segfaulted. The ctypes mirror of hq_box_options is passed by value, so a field missing from it shifts every field after it and the C side reads whatever is next on the stack -- for this struct, the title, subtitle and footer pointers. `collapse` was already missing, from before this branch. It happened not to crash: the shifted reads landed on zeroes. Adding `sides` moved the window far enough that they did not, which is the only reason anybody found out. Both fields are in the mirror now, and the comment says what it has to stay in step with. 10/10 ctest, including the conformance run that CI does and a local build-fix directory did not have. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #59.
A border was all four sides or nothing. Anything else meant a
divider()plusmanual padding, which gives you no corner joins and no way to say "just a top
rule" — the thing you reach for building a header strip, a sidebar rail, or a
footer that should not look boxed in.
sidestakes"all"(the default),"none", or a list. The interior followsthe sides actually drawn, so a top-only panel costs one row rather than two:
The collapse work already had the vocabulary
As the issue guessed,
borderGlyph/borderBitsspeak in edge bits, which isexactly what this needs. A corner belongs to the two sides that meet there, so
it exists only when both are drawn; where one is, the rule runs straight
through the cell the corner would have occupied. That falls out of asking for
the glyph with the bits for the sides present, with the plain rule standing in
when only one edge is set — a single edge has no glyph of its own, because that
cell is part of a run, not a corner.
Labels need the rule they sit on
A title and a subtitle live on the top rule, a footer on the bottom. None is
drawn when its rule is absent: painting a title over the first row of content is
worse than leaving it out.
Verified
All six ports, with
"all"as the default so every existing frame isidentical — which is what the suites check:
The new tests cover each side alone, adjacent pairs getting exactly one corner,
three sides,
none, the empty list, the interior cost per rule, the title rule,and a check that every border style renders byte-for-byte as before when
sidesis
"all".🤖 Generated with Claude Code
https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy