Table

<k.Table> draws one row per row of a result and the columns you list. Use it when the reader needs the exact figures. A total row is marked with a yes/no column (strong) and stays at the foot. For the same measures repeated per group of columns, use GroupedTable.

Example

regions.sql:

-- Sales, orders and share per region, with a total row
select 'North' as region, 120 as sales, 14 as orders, 22.4 as share, 0 as is_total
union all select 'South', 95, 9, 17.8, 0
union all select 'East', 180, 16, 33.6, 0
union all select 'West', 140, 11, 26.2, 0
union all select 'Total', 535, 50, 100.0, 1

In report.tsx:

import regions from "./regions.sql?raw"

type Row = { region: string; sales: number; orders: number; share: number; is_total: number }

// in defineReport({ … })
queries: { regions: query<Row>(regions) },
blocks: (k) => [
  <k.Table
    key="regions"
    series="regions"
    title="Regions"
    strong="is_total"
    copy
    download="regions"
    columns={[
      { key: "region", label: "Region", format: "text" },
      { key: "sales", label: "Sales" },
      { key: "orders", label: "Orders" },
      { key: "share", label: "Share", format: "percent" },
    ]}
    info={{ what: "Sales and orders per region.", sql: ["regions"] }}
  />,
],

Props

Also key, description, span (default 2) and info: see Props every block takes.

NameTypeRequiredDefaultMeaning
seriesquery nameyesThe query the rows come from
columnslist of columns, or a function of the datayesThe columns, in order; the first names the row
titletextnoThe heading; leave it out inside a tab
strongcolumnnoA yes/no column: the row is a total, set in medium weight and kept at the foot
mutedcolumnnoA yes/no column: the row is set muted
borderyes/nononoDraws the table in a card with a hairline edge; without it the table sits open on the page
tagcolumnnoA text column: a muted word after the first cell, such as "Default"
firstWidthwidthnoThe first column's width ("10rem", "18%"), so stacked tables line up
formatColumncolumnnoA text column naming each row's format, for rows that are measures in their own units
notecolumnnoA text column: the first cell's definition, on hover
estimatecolumnnoA column: the row is an estimate, a clock after its first cell with the column's text on hover
stickytrue/falsenofalseThe first column stays put while the rest scroll sideways
copytrue/falsenofalseA copy button: the table as text and HTML on the clipboard
downloadfile name stemnoAn Excel button in the header; the file is named from the stem, the inputs in force and today
pickertrue/false or a textnoA "Columns" button: which columns show and in what order, kept in the URL (?cols=); a text names the URL key (picker="sales" uses ?sales_cols=)
sorttrue/falsenofalseWith picker: the reader may also sort by a column (?sort=)
drillslist of drillsnoA row's click opens the first drill with a key for the row

A column

KeyTypeRequiredMeaning
keycolumnyes, unless metricThe column printed
labeltextnoThe header
format, prefix, suffix, decimalsformatnoHow the cells print; format: "text" for a text column
metricmetric namenoA named metric: its label and format, and its value when key is left out
sharecolumnnoPrinted small and muted after the value
shareFormatformatnoThe share's format
subcolumnnoA second, muted line under the value
subFormatformatnoThe second line's format
alignleft or rightnoNumbers align right, text left, unless set
widetrue/false or "xl"noDropped on narrow screens (below lg, or below xl)
strongtrue/falsenoThe column's cells in medium weight, for a total column
widthwidthnoThe column's width: "7rem", "96px" or "12%"
notetextnoThe header's definition on hover
shorttextnoA few words beside the name in the column picker
hiddentrue/falsenoLeft out until the reader picks it
sortabletrue/falsenofalse: the picker cannot sort by it
unit"muted"noA percent's "%" printed small and muted

Checks

A series that is not one of the report's queries, or a column it names that the query's rows do not have, fails the typecheck, as does a missing required prop or a value of the wrong type.