Skip to content
Kappa
Table
@dicehub/kappav0.4.2

Table

Semantic tabular data with dense states, selection, and scroll-aware columns.

Project activity · 3 projects
ProjectOwnerStatusUpdated
Project AtlasMina ChenRunning2m ago
Beacon APIOwen HartReady18m ago
Cinder workerSofia BellPaused1h ago
<script setup>
import { Table } from "@dicehub/kappa/components/table";
</script>

<template>
  <Table aria-label="Recent projects">
    <Table.Caption>Project activity · 3 projects</Table.Caption>
    <Table.Header>
      <Table.Row>
        <Table.Head scope="col">Project</Table.Head>
        <Table.Head scope="col">Owner</Table.Head>
        <Table.Head scope="col">Status</Table.Head>
      </Table.Row>
    </Table.Header>
    <Table.Body>
      <Table.Row>
        <Table.Cell>Project Atlas</Table.Cell>
        <Table.Cell>Mina Chen</Table.Cell>
        <Table.Cell>Running</Table.Cell>
      </Table.Row>
    </Table.Body>
  </Table>
</template>

Installation

Table is part of the main Kappa package. It uses native table semantics and adds no behavior primitive dependency.

Barrel

import { Table } from "@dicehub/kappa";

Granular

import { Table } from "@dicehub/kappa/components/table";

Usage

Start with Header, Row, Head, and Cell. Add a caption when the table needs a visible context or a screen-reader description. Captions appear below the rows. Headers use sentence case and the same text size as cells; compact headers reduce vertical padding and add a subtle surface. Default rows alternate softly, while selected rows use a stronger tint.

RunEnvironmentResult
release-241productionPassed
<Table aria-label="Deployment queue">
  <Table.Header variant="compact">
    <Table.Row>
      <Table.Head scope="col">Run</Table.Head>
      <Table.Head scope="col">Environment</Table.Head>
      <Table.Head scope="col">Result</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    <Table.Row>
      <Table.Cell>release-241</Table.Cell>
      <Table.Cell>production</Table.Cell>
      <Table.Cell>Passed</Table.Cell>
    </Table.Row>
  </Table.Body>
</Table>

Composition

Typical part hierarchy
Table.Root <table>
├── Table.Caption (optional)
├── Table.Header <thead>
│   └── Table.Row
│       ├── Table.Head
│       └── Table.CheckHead (optional)
├── Table.Body <tbody>
│   └── Table.Row
│       ├── Table.Cell
│       ├── Table.CheckCell (optional)
│       └── Table.ResizeHandle (inside a head, optional)
└── Table.Footer (optional)

The compound parts follow the native HTML table structure. The layout supports selected rows, sticky columns, checkbox cells, and resize handles. Ark UI has no table behavior primitive, so Kappa keeps the native HTML model.

  • Use a real caption, scope, and header structure for data tables.
  • Wrap wide tables in an overflow container. Use sticky only inside a constrained scrolling parent.
  • Use layout="fixed" with colgroup when column widths are part of the contract.
  • Keep sorting, filtering, pagination, and data fetching in the application or a headless table adapter.

Examples

Compact

Add compact to Table for 12px text, 4px vertical padding, and 8px horizontal padding across all cells. Single-line rows are about 24px high. Selection and sticky columns remain available. The header variant only controls the header surface and padding.

1 of 3 projects selected
ProjectOwnerStatus
Project AtlasMina ChenRunning
Beacon APIOwen HartReady
Cinder workerSofia BellPaused
<Table compact aria-label="Projects">
  <Table.Header variant="compact">
    <Table.Row>
      <Table.Head scope="col">Project</Table.Head>
      <Table.Head scope="col">Owner</Table.Head>
      <Table.Head scope="col">Status</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    <Table.Row>
      <Table.Cell>Project Atlas</Table.Cell>
      <Table.Cell>Mina Chen</Table.Cell>
      <Table.Cell>Running</Table.Cell>
    </Table.Row>
  </Table.Body>
</Table>

Selection

Use the checkbox parts for row and select-all behavior.

1 of 3 projects selected
ProjectOwnerStatus
Project AtlasMina ChenRunning
Beacon APIOwen HartReady
Cinder workerSofia BellPaused
<script setup lang="ts">
import { ref } from "vue";
import { Table, type TableCheckboxChangeDetails } from "@dicehub/kappa/components/table";

const selected = ref<string[]>([]);
const toggle = (id: string, details: TableCheckboxChangeDetails) => {
  selected.value = details.checked
    ? [...selected.value, id]
    : selected.value.filter((value) => value !== id);
};
</script>

<Table.CheckHead
  :checked="selected.length === rows.length"
  :indeterminate="selected.length > 0 && selected.length < rows.length"
  @checked-change="(details) => selectAll(details.checked)"
/>
<Table.CheckCell
  v-for="row in rows"
  :key="row.id"
  :checked="selected.includes(row.id)"
  :label="`Select ${row.name}`"
  @checked-change="(details) => toggle(row.id, details)"
/>

Fixed Layout

Use fixed layout with colgroup when column widths must stay predictable.

Run DurationRegion
release-24118m 42seu-central
release-24021m 05sus-east
<Table layout="fixed" aria-label="Deployment runs">
  <colgroup>
    <col style="width: 42%" />
    <col style="width: 28%" />
    <col style="width: 30%" />
  </colgroup>
  <Table.Header>
    <Table.Row>
      <Table.Head scope="col">Run</Table.Head>
      <Table.Head scope="col">Duration</Table.Head>
      <Table.Head scope="col">Region</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body><!-- rows --></Table.Body>
</Table>

Sticky Columns

Pin important columns while the surrounding table scrolls horizontally.

ProjectOwnerEnvironmentLast commitHealth
Project AtlasMina Chenproduction9f31c2a · 2m agoNominal
Beacon APIOwen Hartproduction9f31c2a · 18m agoNominal
Cinder workerSofia Bellproduction9f31c2a · 1h agoNominal
<div class="table-scroll" tabindex="0">
  <Table layout="fixed" aria-label="Project health">
    <Table.Header sticky variant="compact">
      <Table.Row>
        <Table.Head sticky="left" scope="col">Project</Table.Head>
        <Table.Head scope="col">Owner</Table.Head>
        <Table.Head scope="col">Environment</Table.Head>
        <Table.Head sticky="right" scope="col">Health</Table.Head>
      </Table.Row>
    </Table.Header>
    <Table.Body><!-- rows --></Table.Body>
  </Table>
</div>

States

Mark loading, invalid, empty, selected, and disabled rows with native or data attributes.

Selected
Project AtlasReady for review
Loading and invalid
Refreshing metrics…Pending
Worker CinderConnection failed
Empty
No runs match the current filters.
<Table aria-label="Run states">
  <Table.Body>
    <Table.Row data-loading aria-busy="true">
      <Table.Cell>Refreshing metrics...</Table.Cell>
    </Table.Row>
    <Table.Row data-invalid aria-invalid="true">
      <Table.Cell>Connection failed</Table.Cell>
    </Table.Row>
    <Table.Row data-empty>
      <Table.Cell :colspan="2">No runs match the filters.</Table.Cell>
    </Table.Row>
  </Table.Body>
</Table>

Accessibility

  • Use scope="col" or scope="row" when header relationships are not obvious.
  • Give each table an accessible name with a caption, aria-label, or aria-labelledby.
  • Checkbox parts provide a default label, but use label or aria-label for row-specific names.
  • Keep keyboard focus visible on nested controls. ResizeHandle is a button and does not implement a resize algorithm.
  • Use aria-selected, aria-busy, and aria-invalid when those states have semantic meaning.

API Reference

Table

Native table root. Attributes and events pass to the table element.

PropTypeDefaultDescription
compactbooleanfalseReduces text size and padding across the whole table, including selection cells and captions.
layout"auto" | "fixed""auto"Selects the native table layout algorithm.

Table.Header

PropTypeDefaultDescription
variant"default" | "compact""default"Chooses the header surface and vertical padding. Use Table compact to reduce all rows.
stickybooleanfalsePins header cells to the top of a scrolling parent.

Table.Row

PropTypeDefaultDescription
variant"default" | "selected""default"Sets the row surface. Native aria-selected and data attributes also style states.

Table.Head / Table.Cell

PropTypeDefaultDescription
sticky"left" | "right"—Pins a head or body cell to the corresponding scroll edge.

Table.CheckHead / Table.CheckCell

Checkbox selection parts. Both emit checkedChange, update:checked, and legacy valueChange.

PropTypeDefaultDescription
checkedboolean—Controlled checkbox state.
indeterminatebooleanfalseDisplays the mixed selection state.
disabledbooleanfalseDisables the nested checkbox.
labelstring—Accessible checkbox name; aria-label is used when label is omitted.

Data Slots

SlotElementDescription
tabletableNative table root.
table-captioncaptionOptional table caption.
table-headertheadHeader section.
table-bodytbodyBody section.
table-footertfootFooter section.
table-rowtrRow.
table-headthHeader cell.
table-celltdBody cell.
table-resize-handlebuttonColumn resize affordance.

Data Attributes

AttributeValueDescription
data-compactpresentReduced text size and padding for the whole table.
data-layout"auto" | "fixed"Resolved table layout.
data-variant"default" | "selected" | "compact"Resolved row or header variant.
data-sticky"left" | "right"Resolved sticky column or header state.
data-selectedpresentOptional selected-row styling hook.
data-loadingpresentOptional loading-row styling hook.
data-invalidpresentOptional invalid-row styling hook.
data-emptypresentOptional empty-row styling hook.

Exports

ExportDescription
TableNative semantic table compound component.
Table.CaptionOptional caption rendered as caption.
Table.Header / Body / FooterNative table section parts.
Table.Row / Head / CellNative rows and cells with state and sticky styling.
Table.CheckHead / CheckCellCheckbox selection parts with checked-change events.
Table.ResizeHandleKeyboard-focusable resize affordance for headless table integrations.
TABLE_VARIANTSReadonly metadata for layout, row, and sticky options.
TableLayout / TableRowVariant / TableStickyColumnPublic option unions.
TableCheckboxChangeDetailsSelection event payload with checkbox details.
isTable* / resolveTable*Runtime guards and safe option resolvers.