refactor(office): generalize DataTable layout and document TUI table skill
Unify project/user flex column layout into layoutFlexTable with per-subject policy in model. Add office-tui-table skill and AGENTS notes; fix CI go mod tidy drift and test matrix Go version to match go.mod 1.25. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: office-tui-table
|
||||
description: >-
|
||||
Build and fix Bubble Tea list tables in cmd/office (DataTable, column layout,
|
||||
lipgloss cell rendering, pane width). Use when changing office center-pane
|
||||
tables, column widths, ANSI styling, or list toolbar alignment.
|
||||
---
|
||||
# office TUI table (`cmd/office/ui`)
|
||||
|
||||
## Architecture
|
||||
|
||||
| Piece | File | Role |
|
||||
|-------|------|------|
|
||||
| `DataTable` | `table.go` | cursor, sort, viewport, header/row render |
|
||||
| Column layout | `table_layout.go` | flex vs horizontal-scroll policies |
|
||||
| Flex policy | `model/table_layout.go` | per-subject flex column key + min width |
|
||||
| Cell render | `table_render.go` | bubbles/table pattern + ANSI-safe padding |
|
||||
| Subject row style | `table_projects.go` | optional per-subject cell styles |
|
||||
| Pane sizing | `scroll.go` | `paneContentWidth`, `paneLipglossWidth` |
|
||||
| Scrollbar pad | `scrollbar.go` | `padANSIWidth` for styled lines |
|
||||
|
||||
## Layout policies
|
||||
|
||||
1. **Flex (all columns visible)** — register in `model.TableFlexLayoutFor`:
|
||||
- fixed columns keep `TableColumn.Width`
|
||||
- one `FlexColumnKey` (e.g. `title`, `email`) absorbs remainder
|
||||
- `layoutFlexTable` shrinks fixed cols down to `minFixedColumnWidth` before flex min
|
||||
|
||||
2. **Scrolling (default)** — `layoutScrollingTable`:
|
||||
- horizontal `colScroll`; subset of columns visible
|
||||
- `distributeColumnWidths` fills pane width
|
||||
|
||||
Add a new flex subject: one entry in `TableFlexLayoutFor` only — do **not** copy `layoutProjectTable`/`layoutUserTable` per subject.
|
||||
|
||||
## Cell rendering (required pattern)
|
||||
|
||||
Never `style.Width(w).Padding(0,1).Render(text)` on styled cells — padding doubles display width and breaks `JoinHorizontal`.
|
||||
|
||||
Use `renderTableCell` from `table_render.go` (matches `charmbracelet/bubbles/table`):
|
||||
|
||||
```go
|
||||
renderTableCell(outerStyle, plainText, columnWidth)
|
||||
```
|
||||
|
||||
- truncate **plain** text with `runewidth.Truncate` inside `renderTableCell`
|
||||
- inner box: `Width(innerW).Inline(true)` where `innerW = width - outer.GetHorizontalFrameSize()`
|
||||
- outer style carries padding, background, foreground
|
||||
|
||||
## ANSI rules
|
||||
|
||||
- **Never** `runewidth.Truncate` / `padDisplayWidth` on strings that already contain lipgloss ANSI codes — corrupts escapes and shows garbage like lone `ID`.
|
||||
- Use `padANSIWidth` (`charmbracelet/x/ansi`) for styled lines (headers, toolbar, scrollbar rows).
|
||||
- Do not wrap an already full-width styled header in another `lipgloss.Width()` — pad once.
|
||||
|
||||
## Pane width
|
||||
|
||||
Lipgloss bordered panes render **2 cells wider** than `Style.Width`:
|
||||
|
||||
- `paneLipglossWidth(rendered) = rendered - 2` for `.Width()` on pane style
|
||||
- `paneContentWidth(rendered) = rendered - 4` for table/viewport inner size (border + padding)
|
||||
|
||||
Pass `paneContentWidth(pw.List)` to `DataTable.SetSize` and list toolbar.
|
||||
|
||||
## Tests to add when touching tables
|
||||
|
||||
- `layoutFlexTable` width sum equals pane width
|
||||
- `TestProjectTableHeaderFitsPaneWidth` / per-line width at 68, 40, 30
|
||||
- `TestPadANSIWidthPreservesStyledLine`
|
||||
- `TestThreePaneRenderedWidthMatchesTerminal` top border + table lines ≤ inner width
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- Per-subject duplicate layout files (`table_foo.go` with copy-pasted shrink loops)
|
||||
- Skipping truncation on selected rows (causes multi-line rows in viewport)
|
||||
- Using `bubbles/table` widget directly — office needs column cursor, multi-select, subject-specific row styles
|
||||
Reference in New Issue
Block a user