`type t`````
`include sig ... end`
`val compare : t ‑> t ‑> int`
`val sexp_of_t : t ‑> Base.Sexp.t`
`val create : scroll_margin:Margin.t ‑> scroll_region:Scroll_region.Id.t ‑> float_header:Float_type.t ‑> float_first_col:Float_type.t ‑> height_guess:float ‑> ?⁠id:Incr_dom_widgets.Table_id.t ‑> ?⁠initial_sort:Base_sort_criteria.t ‑> ?⁠initial_focus_row:Row_id.t ‑> ?⁠initial_focus_col:Column_id.t ‑> unit ‑> t`
`val id : t ‑> Incr_dom_widgets.Table_id.t`
`val focus_row : t ‑> Row_id.t option`
`val focus_col : t ‑> Column_id.t option`
`val sort_criteria : t ‑> Base_sort_criteria.t`
`val sort_columns : t ‑> Column_id.t list`
`val sort_dirs : t ‑> Sort_dir.t list`
`val scroll_margin : t ‑> Margin.t`
`val set_sort_criteria : t ‑> Base_sort_criteria.t ‑> t`
`val set_float_header : t ‑> Float_type.t ‑> t`

`cycle_sorting` computes and sets new sort criteria based on the current criteria. If the given column id already exists in the sort criteria, the column's sort direction is updated by calling `next_dir` on its current sort direction. Otherwise, the sort direction is computed by calling `next_dir` on `None`. If the new direction is `None`, the column id is removed from the sort criteria.

If `keep_existing_cols` is passed in as an argument, all existing column ids are kept in the sort criteria, and the given column id is added or promoted to the front of the sort criteria list (i.e. given the highest precedence).

If `keep_existing_cols` is not passed in, all column ids apart from the given one are removed from the sort criteria.

`val cycle_sorting : ?⁠keep_existing_cols:unit ‑> t ‑> Column_id.t ‑> next_dir:(Sort_dir.t option ‑> Sort_dir.t option) ‑> t`
`val get_tbody_rect : t ‑> float Incr_dom_widgets__.Import.Js_misc.Rect.t option`

Returns the bounding client rectangle of the table body.