Harlock.Viewport (harlock v0.3.0)

Copy Markdown View Source

Helpers for the viewport element.

The viewport renders a child taller than its allocated region and blits a window starting at offset. The application owns the offset (same TEA discipline as text_input); this module gives you a pure function to translate scroll keys into a new offset.

Example

def init(_), do: %{items: build_items(500), offset: 0, viewport_h: 20}

def update({:key, key, _mods}, m) do
  offset =
    Harlock.Viewport.apply_key(
      m.offset,
      length(m.items),
      m.viewport_h,
      key
    )

  %{m | offset: offset}
end

def view(m) do
  viewport(
    child: vbox(children: Enum.map(m.items, &text(content: &1))),
    offset: m.offset,
    content_height: length(m.items)
  )
end

:up/:down move one row, :page_up/:page_down move by viewport_h - 1 (leaves one row of context like most pagers), :home/:end jump to the extremes. Any other key returns the offset unchanged.

Summary

Functions

Apply a scroll-key event to the current offset.

Types

key()

@type key() :: :up | :down | :page_up | :page_down | :home | :end | term()

Functions

apply_key(offset, content_height, viewport_h, key)

@spec apply_key(integer(), non_neg_integer(), non_neg_integer(), key()) ::
  non_neg_integer()

Apply a scroll-key event to the current offset.

content_height is the total height of the scrollable content; viewport_h is the visible height. The result is clamped to 0..max(0, content_height - viewport_h).