Table

A powerful and flexible table component for displaying tabular data with sorting, filtering, and pagination capabilities.

Quick start

import { Table, Container, Title } from '@clickhouse/click-ui'

function MyTable() {
const headers = [
  { label: 'Name' },
  { label: 'Email' },
  { label: 'Role' },
]

const rows = [
  {
    id: 1,
    items: [
      { label: 'John Doe' },
      { label: 'john@example.com' },
      { label: 'Admin' },
    ],
  },
  {
    id: 2,
    items: [
      { label: 'Jane Smith' },
      { label: 'jane@example.com' },
      { label: 'User' },
    ],
  },
]

return (
  <Container orientation='vertical' gap='md'>
    <Title size='lg'>Users</Title>
    <Table headers={headers} rows={rows} />
  </Container>
)
}

Example

Company
Contact
Country
Company
Alfreds Futterkiste
Contact
Maria Anders
Country
Germany
Company
Centro comercial Moctezuma
Contact
Francisco Chang
Country
Mexico
Company
Alfreds Futterkiste
Contact
Maria Anders
Country
Germany
Company
Centro comercial Moctezuma
Contact
Francisco Chang
Country
Mexico

Props

Prop
Type
Default value
Description
Prop
headers *
Type
Array<TableHeaderType>
Default value
[]
Description
Array of header definitions. Each header must have a label property. Required.
Prop
rows *
Type
Array<TableRowType>
Default value
[]
Description
Array of row data. Each row must have an id and items array. Required.
Prop
isSelectable
Type
boolean
Default value
false
Description
Whether rows can be selected with checkboxes
Prop
selectedIds
Type
Array<number | string>
Default value
[]
Description
Array of selected row IDs. Used with isSelectable.
Prop
onSelect
Type
(selectedItems: Array<{index: number, item: TableRowType}>) => void
Default value
undefined
Description
Callback when rows are selected. Receives array of selected items with index and item data.
Prop
onDelete
Type
(item: TableRowType, index: number) => void
Default value
undefined
Description
Callback when delete action is triggered on a row
Prop
onEdit
Type
(item: TableRowType, index: number) => void
Default value
undefined
Description
Callback when edit action is triggered on a row
Prop
onSort
Type
(direction: 'asc' | 'desc', header: TableHeaderType, headerIndex: number) => void
Default value
undefined
Description
Callback when a column header is clicked for sorting
Prop
loading
Type
boolean
Default value
false
Description
Whether the table is in a loading state. Shows loading indicator.
Prop
noDataMessage
Type
ReactNode
Default value
undefined
Description
Custom message to display when table has no data
Prop
size
Type
"sm" | "md"
Default value
"sm"
Description
Size variant of the table cells
Prop
showHeader
Type
boolean
Default value
true
Description
Whether to show the table header row
Prop
rowHeight
Type
string
Default value
undefined
Description
Custom height for table rows (e.g., "40px")

* denotes required field

Type definitions

TableHeaderType

interface TableHeaderType {
label: ReactNode // The header text or content
isSortable?: boolean // Whether the column can be sorted
sortDir?: 'asc' | 'desc' // Current sort direction
sortPosition?: 'left' | 'right' // Position of sort icon
width?: string // Column width (e.g., "200px")
}

TableRowType

interface TableRowType {
id: number | string // Unique identifier for the row (required)
items: Array<{ label: ReactNode }> // Array of cell content (required)
isActive?: boolean // Whether the row is in active state
isDeleted?: boolean // Whether the row is marked as deleted
isIndeterminate?: boolean // For checkbox indeterminate state
}
  • Pagination: Use with Table for paginated data navigation
  • Title: Use above Table for page headers
  • Container: Use to layout Table with other components
  • Button: Use for table actions (edit, delete, etc.)
  • Dialog: Use for edit/create forms related to table data

Common use cases

Basic data display

import { Table } from '@clickhouse/click-ui'

const headers = [
{ label: 'Product' },
{ label: 'Price' },
{ label: 'Stock' },
]

const rows = [
{
  id: 1,
  items: [
    { label: 'Widget A' },
    { label: '$19.99' },
    { label: '50' },
  ],
},
]

<Table headers={headers} rows={rows} />

With sorting

import { Table } from '@clickhouse/click-ui'
import { useState } from 'react'

function SortableTable() {
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')

const headers = [
  { 
    label: 'Name',
    isSortable: true,
    sortDir: sortDir,
  },
  { label: 'Email' },
]

const handleSort = (direction: 'asc' | 'desc') => {
  setSortDir(direction)
  // Implement your sorting logic
}

return (
  <Table
    headers={headers}
    rows={rows}
    onSort={handleSort}
  />
)
}

With row selection

import { Table } from '@clickhouse/click-ui'
import { useState } from 'react'

function SelectableTable() {
const [selectedIds, setSelectedIds] = useState<Array<number | string>>([])

const handleSelect = (selectedItems: Array<{index: number, item: any}>) => {
  const ids = selectedItems.map(item => item.item.id)
  setSelectedIds(ids)
}

return (
  <Table
    headers={headers}
    rows={rows}
    isSelectable={true}
    selectedIds={selectedIds}
    onSelect={handleSelect}
  />
)
}

With actions (edit/delete)

import { Table } from '@clickhouse/click-ui'

function TableWithActions() {
const handleEdit = (item: any, index: number) => {
  console.log('Edit item:', item)
}

const handleDelete = (item: any, index: number) => {
  console.log('Delete item:', item)
}

return (
  <Table
    headers={headers}
    rows={rows}
    onEdit={handleEdit}
    onDelete={handleDelete}
  />
)
}

See also

© 2026 ClickHouse, Inc. HQ in the Bay Area, CA and Amsterdam, NL.