`module Row_id : Table_intf.Id with type t = Row.Id.t`
`module Column_id : Table_intf.Id with type t = Mesa_column.Id.t`

This isn't just an int so that if an app adds columns the sort is maintained properly by the app's own classification instead of index. But it can be an int.

`module Sort_spec : Table_intf.Sort_spec`
`module Sort_key = Sort_spec.Sort_key`
`module Sort_dir = Sort_spec.Sort_dir`
`module Sort_criteria : sig ... end`

A `'a Sort_criteria.t` specifies a list of columns by which to sort the rows of a table, in order of precedence from highest to lowest. Each column's sort criteria is made up of a direction and a value of type `'a`, which varies as the sort criteria goes through several rounds of processing.

`module Base_sort_criteria : sig ... end`
`module Html_id : sig ... end`
`module Column : sig ... end`
`module Key : sig ... end`

This is the key used for sorting functionality. Apps don't need to touch this to use this widget, it is only exposed in case apps need to do something involving sorting in the same way as the table will.

`module Model : sig ... end`
`module Derived_model : sig ... end`
`module Action : sig ... end`
`val current_key : _ Derived_model.t ‑> row_id:Row_id.t ‑> Key.t option`

`current_key d row_id` returns `row_id`'s `Key.t` associated with the current sort criteria of `d`. Returns `None` if `row_id` does not exist in `d`

Functions `scroll_*_into_scroll_region` and `scroll_*_to_position` will always work if the row heights in the model are correct (either because the row height estimate is correct for all rows, or because all rows have already been rendered and measured). If the row heights in the model are off, it may take multiple iterations of calling the scroll function and then remeasuring row heights in `update_visibility` before the specified element is successfully scrolled to its target.

`val scroll_row_into_scroll_region : Model.t ‑> _ Derived_model.t ‑> Row_id.t ‑> Table_intf.Scroll_result.t`
`val scroll_col_into_scroll_region : Model.t ‑> _ Derived_model.t ‑> Column_id.t ‑> Table_intf.Scroll_result.t`
`val scroll_focus_into_scroll_region : Model.t ‑> _ Derived_model.t ‑> Table_intf.Scroll_result.t`
`val scroll_row_to_position : ?⁠keep_in_scroll_region:unit ‑> Model.t ‑> _ Derived_model.t ‑> Row_id.t ‑> position:float ‑> Table_intf.Scroll_result.t`
`val scroll_col_to_position : ?⁠keep_in_scroll_region:unit ‑> Model.t ‑> _ Derived_model.t ‑> Column_id.t ‑> position:float ‑> Table_intf.Scroll_result.t`
`val scroll_focus_to_position : ?⁠keep_in_scroll_region:unit ‑> Model.t ‑> _ Derived_model.t ‑> position:(float * float) ‑> Table_intf.Scroll_result.t`

Functions `*_is_in_scroll_region` and `get_*_position` return `None` if the specified element is not found (e.g. there is no focus, or there is no row/column with the given id), or if the visibility measurements are not yet available.

By default, the model's scroll margin is used to compute the bounds of the scroll region. However, if a `scroll_margin` argument is given, that will be use instead.

`val row_is_in_scroll_region : ?⁠scroll_margin:Table_intf.Margin.t ‑> Model.t ‑> _ Derived_model.t ‑> Row_id.t ‑> bool option`
`val col_is_in_scroll_region : ?⁠scroll_margin:Table_intf.Margin.t ‑> Model.t ‑> _ Derived_model.t ‑> Column_id.t ‑> bool option`
`val focus_is_in_scroll_region : ?⁠scroll_margin:Table_intf.Margin.t ‑> Model.t ‑> _ Derived_model.t ‑> bool option`
`val get_row_position : _ Derived_model.t ‑> Row_id.t ‑> float option`
`val get_col_position : Model.t ‑> _ Derived_model.t ‑> Column_id.t ‑> float option`
`val get_focus_position : Model.t ‑> _ Derived_model.t ‑> float option * float option`
`val get_focus_rect : Model.t ‑> _ Derived_model.t ‑> float Incr_dom_widgets__.Import.Js_misc.Rect.t option`

Returns the bounding client rectangle of the currently focused cell, if any. This only returns a value if both the focus row and focus column are set.

`val find_row_by_position : Model.t ‑> _ Derived_model.t ‑> float ‑> [ `Before | `At of Row_id.t | `After ] option`

Finds the row id at a given vertical position on the page, or indicates that the position is before/after all the rows in the table. It only returns `None` if the model has no visibility info.

`val find_col_by_position : Model.t ‑> _ Derived_model.t ‑> float ‑> [ `Before | `At of Column_id.t | `After ] option`

Finds the column id at a given horizontal position on the page, or indicates that the position is before/after all the columns in the table. It only returns `None` if the model has no visibility info or if a call to `Dom_html.getElementById_opt` on a header cell id returns `None`.

`val on_display : old:Model.t ‑> Model.t ‑> _ Derived_model.t ‑> unit`

Used for scrolling to rows/columns upon focusing them

`val apply_action : Model.t ‑> _ Derived_model.t ‑> Action.t ‑> Model.t`

Used to handle sort column clicking

`val set_focus_row : Model.t ‑> Row_id.t option ‑> Model.t`
`val set_focus_col : Model.t ‑> Column_id.t option ‑> Model.t`
`val update_visibility : Model.t ‑> _ Derived_model.t ‑> Model.t`

Measures rows, table and viewport

`type 'a row_renderer``= row_id:Row_id.t ‑> row:'a Incr_dom_widgets__.Import.Incr.t ‑> Row_node_spec.t Incr_dom_widgets__.Import.Incr.t```

When constructing the row `Vdom.Node.t` (most likely using function `Vdom.Node.tr`), it is important to pass in the argument `~key:id`. Otherwise scrolling may have unexpected behavior.

`val view : ?⁠override_header_on_click:(Column_id.t ‑> Incr_dom_widgets__.Import.Dom_html.mouseEvent Incr_dom_widgets__.Import.Js.t ‑> Incr_dom_widgets__.Import.Vdom.Event.t) ‑> Model.t Incr_dom_widgets__.Import.Incr.t ‑> 'a Derived_model.t Incr_dom_widgets__.Import.Incr.t ‑> render_row:'a row_renderer ‑> inject:(Action.t ‑> Incr_dom_widgets__.Import.Vdom.Event.t) ‑> attrs:Incr_dom_widgets__.Import.Vdom.Attr.t list ‑> Incr_dom_widgets__.Import.Vdom.Node.t Incr_dom_widgets__.Import.Incr.t`

Returns a full partially-rendered <table> node with header. `render_row` function should render <tr> nodes.