feat(tui): Two-column layout with detail preview#42
Conversation
Single-character codes for compact list display: - Types: M(ilestone), E(pic), B(ug), F(eature), T(ask) - Statuses: D(raft), T(odo), I(n-progress), C(ompleted), S(crapped) Refs: beans-t0tv
- Type column: 3 chars (M/E/B/F/T) - Status column: 3 chars (D/T/I/C/S) - Updated CalculateResponsiveColumns base width calculation (40 -> 20) - Updated tree headers to use "T" and "S" instead of "TYPE" and "STATUS" - Frees up ~20 chars per row for title Refs: beans-t0tv
Lightweight component for two-column layout right pane: - Shows bean ID, title, status, type, priority - Renders markdown body (truncated to fit) - Shows 'No bean selected' when empty Refs: beans-t0tv
- TwoColumnMinWidth: 120 columns - LeftPaneWidth: 55 characters - isTwoColumnMode() helper method Refs: beans-t0tv
- Add preview previewModel field to App struct - Initialize preview in New() with newPreviewModel(nil, 0, 0) Refs: beans-t0tv
- View() checks isTwoColumnMode() before rendering - renderTwoColumnView() composes list + preview horizontally - ViewConstrained() renders list with constrained width - Falls back to single-column for narrow terminals Refs: beans-t0tv 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
- cursorChangedMsg emitted when list cursor moves - App updates preview on cursor change - Preview initialized when beans are loaded Refs: beans-t0tv
- Update preview dimensions on window resize - Handle empty list state in preview - Add 'enter' shortcut to help overlay Refs: beans-t0tv
Refs: beans-t0tv
- Footer now app-global, spanning full terminal width - Right pane capped at 80 chars max (left pane gets remaining space) - Preview height properly constrained to prevent overflow - Detail view linked beans show full type/status names Refs: beans-m3mq, beans-tbtr
When markdown content caused line wrapping within the preview pane, lipgloss rendered more lines than expected. Our truncation was cutting off the bottom border. Now we preserve the bottom border when truncating. Also fixed height calculation in ViewConstrained() - was using -4 (for footer) instead of -2 (no footer in two-column mode). Refs: beans-t0tv
|
That's a very cool change, thanks for taking it on! I have a few suggestions, let me know what you think.
|
This one is easy. I'll implement it.
This one is a bit trickier. Initially I wanted to get rid of the detail view, but then
I had a dirty version of the drill down feature. I did not feel good and I did not know how I would use it. So I did not implement a proper version. This feature would potentially benefit from implementing proper filtering first, see #41 If it's ok with you, I would not implement this feature here, but we can open a dedicated ticket for it. |
Show full type/status names (e.g., "feature", "in-progress") when terminal is ≥120 columns wide, single-letter abbreviations (F, I) when space is tight. - Add UseFullTypeStatus to ResponsiveColumns struct - Set flag and wider column widths when width >= 120 - Pass setting to RenderBeanRow via list delegate Refs: beans-vn93
|
I really like the idea of just getting rid of the extra detail view screen, it's probably obsolete if you can see the full selected bean anyway. Some thoughts:
But these are just some suggestions. Ultimately I would always lean towards simplifying where possible. |
|
Ok, I'll try something and open a sep. PR that sits on top of this one. I'm not fully convinced yet :) |
|
FWIW, I didn't intend to push more work onto you -- if you like, we can wrap up this PR and merge it, and I can do some experimentation around this stuff some time soon. |
|
All good, using the additional claude code tokens for this, and experimenting with a a beans/superpowers integration :) I think this PR could be merged (after a review, I'm no bubbletea expert). But let's wait a bit till I have the experiment for the unified detail view ready. |
|
Hi and sorry for only getting back to you and this PR now, over the last two weeks other projects and also some family stuff required my attention. I'm intending to spend some time with Beans this weekend -- would you say this PR here is in a state that I could/should merge? You mentioned in the other PR that you weren't happy with the changes there. I'd be happy to merge this PR here and then iterate a little over the TUI myself if that's fine with you. |
|
No worries! Try out both PRs and decide for yourself. This one is easier. The other one follows your initial design more closely (I think), but touches more code (and is less human curated). Your call! |
hmans
left a comment
There was a problem hiding this comment.
Let's merge this -- thanks for the PR!
* origin/main: feat(tui): Two-column layout with detail preview (hmans#42) feat: add ETag support for optimistic concurrency control (hmans#59) feat(plugin): improve OpenCode plugin robustness with availability checks (hmans#58) feat(cli): Add --prefix flag to create command (hmans#56) chore: clean up README.md docs: only push prime if it exists (hmans#52) fix: normalise short IDs when storing relationship links (hmans#50)





Implements a two-column TUI layout that shows bean details alongside the list, enabling quick scanning without opening each bean individually.
Summary
Layout
Key Design Decisions
Changes
Testing
Refs: beans-t0tv, beans-m3mq, beans-tbtr
Examples
On a bit screen:

On a medium bit screen:

On a small screen:

Detail view is unchanged:
