Key-event helpers for the Harlock.Elements.table/1 widget.
A table has two movable things, and which one the arrows should move depends on how its rows were supplied:
- enumerable rows — the row set is known, the visible window auto-centres
on
:focused_row, and moving the focus is what a user means. Useselect_key/3, which yields{:select, row_id}. - a window function — there is no row set to walk and no index to centre
on, so
:offsetis what moves. Usescroll_key/4, which yields{:scroll, offset}.
The runtime picks between them automatically for a focused table, delivering
{:harlock_select, focus_id, row_id} or {:harlock_scroll, focus_id, offset}
respectively — both messages that already existed.
Neither wraps. A table is read top-down and is often long, so jumping from the
last row to the first reads as a glitch. menu wraps because its lists are
short and cyclic movement is the convention there; this is a deliberate
difference, not an inconsistency.
Summary
Functions
Move :offset for a window-function table.
Move :focused_row through a known list of row ids.
Types
@type row_id() :: any()
Functions
@spec scroll_key({:key, any(), [atom()]}, non_neg_integer(), pos_integer(), boolean()) :: {:scroll, non_neg_integer()} | :noop
Move :offset for a window-function table.
body_h is the number of rows the body can draw, and at_end? says whether
the last fetch returned fewer rows than it was asked for.
That flag is doing real work. A window function is never asked how many rows
exist — with keyset pagination the total may be genuinely unknown — so there is
no maximum offset to clamp against. Without it, :down at the bottom would
keep incrementing forever and scroll into empty space. A short fetch is the
only available end-of-data signal, so the renderer reports it and this refuses
to advance past it.
:end is :noop for the same reason: jumping to the last row requires knowing
where it is.
Move :focused_row through a known list of row ids.
Returns :noop when the focus would not move, so the key falls through to
update/2 instead of arriving as a message selecting what is already selected.