Liking cljdoc? Tell your friends :D

com.blockether.vis.ext.channel-tui.boxed-table

Bordered, scrollable, single-selection data table for TUI dialogs.

Composes the lower-level table border/row primitives with scrollbar so callers don't repeat the same boilerplate (top border + header row + middle separator + N body rows + selection marker gutter + scrollbar) at every dialog site.

Geometry rules

Given a dialog bounds ({:left :inner-w}) the layout reserves:

col left+1 → table left border (flush to dialog edge) col left+3 → selection marker, INSIDE the first column cols left+1 .. R-1 → boxed table (own borders included) col R → scrollbar (right of right table border)

where R = left + inner-w. This guarantees the scrollbar never overpaints the table's right border.

The selection marker lives INSIDE the first column: the first data column is internally widened by p/SELECTION_WIDTH, its cell text is indented by that many cols, and the marker glyph is painted over the reserved gutter (matching the Ctrl+G navigator). Callers size their columns against the reported :table-content-w, which already excludes the marker reserve — no caller-side change needed.

Row layout (relative to caller-provided :top)

top+0 ┌── top border ──┐ top+1 │ header row │ top+2 ├── separator ──┤ top+3 │ first body row │ … top+2+body-h │ last body row │ top+3+body-h └── bottom ──┘ (only when :closed? true)

By default the table is open at the bottom; callers usually follow the body with a divider + status line and don't want a closing └┘ cap. Pass :closed? true to draw the closing border (matches the navigator-style boxed picker).

Bordered, scrollable, single-selection data table for TUI dialogs.

Composes the lower-level `table` border/row primitives with
`scrollbar` so callers don't repeat the same boilerplate (top
border + header row + middle separator + N body rows + selection
marker gutter + scrollbar) at every dialog site.

Geometry rules
--------------
Given a dialog `bounds` ({:left :inner-w}) the layout reserves:

  col `left+1`            → table `│` left border (flush to dialog edge)
  col `left+3`            → selection marker, INSIDE the first column
  cols `left+1 .. R-1`    → boxed table (own `│` borders included)
  col `R`                 → scrollbar (right of right table border)

where `R = left + inner-w`. This guarantees the scrollbar never
overpaints the table's right `│` border.

The selection marker lives INSIDE the first column: the first data
column is internally widened by `p/SELECTION_WIDTH`, its cell text
is indented by that many cols, and the marker glyph is painted over
the reserved gutter (matching the Ctrl+G navigator). Callers size
their columns against the reported `:table-content-w`, which already
excludes the marker reserve — no caller-side change needed.

Row layout (relative to caller-provided `:top`)
-----------------------------------------------
  top+0  ┌── top border ──┐
  top+1  │ header row     │
  top+2  ├── separator  ──┤
  top+3  │ first body row │
  …
  top+2+body-h │ last body row │
  top+3+body-h └── bottom ──┘  (only when `:closed? true`)

By default the table is open at the bottom; callers usually follow
the body with a divider + status line and don't want a closing
`└┘` cap. Pass `:closed? true` to draw the closing border (matches
the navigator-style boxed picker).
raw docstring

draw!clj

(draw! g
       {:keys [bounds top body-h headers widths total scroll selected cell-fn
               empty-cells empty-message aligns closed?]
        :or {empty-message "No items." aligns (repeat :left) closed? false}})

Render a bordered scrollable table in one call.

Positional arg matches scrollbar/draw!: ^TextGraphics g — the live dialog graphics surface.

Required opts: :bounds {:left :inner-w} (from draw-dialog-chrome!) :top first row to paint (top border lands here) :body-h visible body rows :headers vector of header strings (count must match :widths) :widths per-column widths in cells (from caller's sizing fn) :total total row count in the data set :scroll current scroll offset (0-based row index) :selected current selection (0-based row index) :cell-fn (fn [idx] -> seq of strings) for row at absolute idx

Optional opts: :empty-cells per-column cells painted when total = 0; defaults to blanks with :empty-message in column 1 :empty-message string shown in the default empty row :aligns per-column alignment vec (default (repeat :left)) :closed? when true, paint a closing └──┘ border one row below the last body row (default false)

Returns the full layout map (merge of layout + rows) so callers can place mode lines, hint bars, hit-tests, etc.

Render a bordered scrollable table in one call.

Positional arg matches `scrollbar/draw!`:
  `^TextGraphics g` — the live dialog graphics surface.

Required opts:
  :bounds       {:left :inner-w} (from `draw-dialog-chrome!`)
  :top          first row to paint (top border lands here)
  :body-h       visible body rows
  :headers      vector of header strings (count must match :widths)
  :widths       per-column widths in cells (from caller's sizing fn)
  :total        total row count in the data set
  :scroll       current scroll offset (0-based row index)
  :selected     current selection (0-based row index)
  :cell-fn      (fn [idx] -> seq of strings) for row at absolute idx

Optional opts:
  :empty-cells   per-column cells painted when total = 0; defaults to
                 blanks with `:empty-message` in column 1
  :empty-message string shown in the default empty row
  :aligns        per-column alignment vec (default `(repeat :left)`)
  :closed?       when true, paint a closing `└──┘` border one row
                 below the last body row (default false)

Returns the full layout map (merge of `layout` + `rows`) so callers
can place mode lines, hint bars, hit-tests, etc.
sourceraw docstring

hit-rowclj

(hit-row {:keys [table-x rendered-w table-content-w]} top body-h scroll mx my)

Map a mouse (mx, my) into a body row index, or nil if outside the table body. geom is (layout bounds), top and body-h match the draw! call, scroll is the current scroll offset.

Map a mouse `(mx, my)` into a body row index, or nil if outside the
table body. `geom` is `(layout bounds)`, `top` and `body-h` match the
`draw!` call, `scroll` is the current scroll offset.
sourceraw docstring

layoutclj

(layout {:keys [left inner-w]})

Compute table geometry inside a dialog bounds ({:left :inner-w}). Pure: no drawing. Useful for mouse hit-testing before draw!.

Compute table geometry inside a dialog `bounds` ({:left :inner-w}).
Pure: no drawing. Useful for mouse hit-testing before `draw!`.
sourceraw docstring

rowsclj

(rows top body-h)

Resolve the absolute row indices for each painted line, given the caller-supplied top and body-h.

Resolve the absolute row indices for each painted line, given the
caller-supplied `top` and `body-h`.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close