class

TUI::ArrayTableSource(T)

Inherits TUI::TableDataSource < TUI::ListDataSource < Reference < Object

Generic TableDataSource over an in-memory Array(T) — a substring filter on one derived string per row, plus symbol-keyed sort comparators, covers every hand-written array-backed TableDataSource this library's own examples needed. Anything needing a richer filter (multi-field, fuzzy) or a data source backed by something other than a plain in-memory Array should still hand-write its own TableDataSource — this covers the common case, not every case.

sort_keys maps a Symbol to a (T, T) -> Int32 comparator rather than a key-extractor (T -> _), since Crystal can't compare two values pulled from a Hash whose value type is a union across heterogeneous field types (e.g. String for one sort key, Float64 for another) — a two-argument comparator sidesteps that entirely.

Constructors

new(all : Array(T), title : String, columns : Array(TableColumn), filter_text : T -> String, row : T -> TableRow, sort_keys : Hash(Symbol, T, T -> Int32) = {} of Symbol => (T, T -> Int32))
Source

Instance methods

columns
Source
item_at(index : Int32) : T

The currently-filtered row's underlying model — the generic replacement for a hand-written source's own xxx_at(index).

Source
reload(filter : String, sort : Symbol) : Nil
Source
row(index : Int32) : TableRow
Source
size
Source
sort_keys
Source
title(filter : String, sort_key : Symbol) : String
Source

Macros

define(name, model_type, &block)

Block-DSL sugar over ArrayTableSource(T) construction. Unlike Form.define, this macro does NOT auto-assign a constant to the built source — Crystal disallows declaring a class inside a def body ("can't define class inside def"), so a caller wanting a fresh ArrayTableSource per call (e.g. one per page, so Table view and Split window don't share filter/sort state) must call this macro once at the top level to declare a named builder class, then call that class's own .build(all) from a plain function whenever it needs a new instance:

TUI::ArrayTableSource.define(PackageSourceBuilder, Package) do title "Packages" filter_by :name column :name, "Name", width: 10..20, expand: true column :size_mb, "Size (MB)", width: 6..10, align: :right, sort: true end

def build_package_source : TUI::ArrayTableSource(Package) PackageSourceBuilder.build(FAKE_PACKAGES) end

Column cell styling avoids macro-time type introspection (Crystal's instance_vars reflection only works inside a def body, not at macro-expansion time of a single column call) by generating a runtime value.class.name.downcase lookup instead — e.g. Float64.name.downcase == "float64", matching TypeStyle's own case-when keys exactly. sort: true still generates a two-argument comparator (a.prop <=> b.prop || 0), not a key-extractor, per ArrayTableSource(T)'s own comparator-based sort_keys contract.

Source