Table

Responsive data table with optional striping, borders, hover rows, sticky header, and sortable columns.

import { ... } from '@corndev/ui'
NameRoleStatus
AliceEngineerActive
BobDesignerActive
CarolProductOn leave
DaveMarketingActive

HTML

No JavaScript required — these classes are the whole component.

<div class="corn-table-wrapper">
  <table class="corn-table" data-striped data-hoverable>
    <thead><tr><th>Name</th></tr></thead>
    <tbody><tr><td>Ada</td></tr></tbody>
  </table>
</div>

Classes

ClassDescription
.corn-tableBase table styles
.corn-table-wrapperScroll container — always wrap the table in this
.corn-table-th

Attributes

OnAttributeValues
.corn-tabledata-hoverablepresent or absent
.corn-tabledata-stripedpresent or absent
.corn-tabledata-borderedpresent or absent
.corn-tabledata-sticky-headerpresent or absent
.corn-table-thdata-sortablepresent or absent
.corn-table-thdata-sortasc|desc

Vanilla JS

Optional. createTable only adds and removes the classes and attributes above, so the HTML is equivalent. Reach for it when you need to change options at runtime.

import { createTable } from '@corndev/ui';
import '@corndev/ui/theme';

const el = document.querySelector('#target');
const instance = createTable(el, { /* options */ });

Options

OptionTypeDefaultDescription
stripedbooleanfalseAlternate the background of even rows.
borderedbooleanfalseBorder every cell rather than only the rows.
hoverablebooleanfalseHighlight the row under the pointer.
stickyHeaderbooleanfalsePin <thead> during vertical scroll. Needs an ancestor that actually scrolls — .corn-table-wrapper only scrolls horizontally, so give it a max-height for this to have any effect.

React

Table, TableSortHeader — from @corndev/ui-react.

Props

PropTypeDefaultDescription
stripedbooleanfalseAlternate the background of even rows.
borderedbooleanfalseBorder every cell rather than only the rows.
hoverablebooleanfalseHighlight the row under the pointer.
stickyHeaderbooleanfalsePin <thead> during vertical scroll. Needs an ancestor that actually scrolls — give the wrapper a max-height, since on its own it only scrolls horizontally.
wrapperbooleantrueRender the scroll container. Turn it off only when you are supplying your own.
wrapperClassNamestringundefinedClass for the scroll container. className goes on the <table>.
childrenReact.ReactNodeundefined
classNamestringundefined

<TableSortHeader> props

a sortable header cell rendering the indicator and aria-sort for the state you pass

PropTypeDefaultDescription
sort'asc'|'desc'|nullnullWhich indicator to show. null shows the neutral, sortable arrow.
childrenReact.ReactNodeundefined
classNamestringundefined

Basic usage

Wrap <table> in .corn-table-wrapper to enable horizontal scroll on small screens.

import '@corndev/ui/theme';

<div class="corn-table-wrapper">
  <table class="corn-table">
    <thead>
      <tr>
        <th>Name</th>
        <th>Role</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Alice</td>
        <td>Engineer</td>
        <td>Active</td>
      </tr>
      <tr>
        <td>Bob</td>
        <td>Designer</td>
        <td>Active</td>
      </tr>
    </tbody>
  </table>
</div>

Hoverable rows

<table class="corn-table" data-hoverable>...</table>

Striped rows

<table class="corn-table" data-striped>...</table>

Bordered

<table class="corn-table" data-bordered>...</table>

Keeps the <thead> visible when the table scrolls. Apply to the table inside a height-constrained wrapper.

<div class="corn-table-wrapper" style="max-height: 320px; overflow-y: auto;">
  <table class="corn-table" data-sticky-header>...</table>
</div>

Sortable columns

Add data-sortable to any <th> to show a sort affordance. Set data-sort="asc" or data-sort="desc" to indicate the active sort direction.

<thead>
  <tr>
    <th class="" data-sortable data-sort="asc">Name</th>
    <th class="" data-sortable>Date</th>
    <th>Status</th>
  </tr>
</thead>

Combining modifiers

<table class="corn-table" data-hoverable data-striped data-sticky-header>
  ...
</table>