< 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 > Table is part of the main Kappa package. It uses native table semantics and adds no behavior primitive dependency.
import { Table } from "@dicehub/kappa" ; import { Table } from "@dicehub/kappa/components/table" ; 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.
< 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 > 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. 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.
< 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 > Use the checkbox parts for row and select-all behavior.
< 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)"
/> Use fixed layout with colgroup when column widths must stay predictable.
< 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 > Pin important columns while the surrounding table scrolls horizontally.
< 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 > Mark loading, invalid, empty, selected, and disabled rows with native or data attributes.
Selected Project Atlas Ready for review
Loading and invalid Refreshing metrics… Pending Worker Cinder Connection 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 > 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. Native table root. Attributes and events pass to the table element.
Prop Type Default Description compactbooleanfalseReduces text size and padding across the whole table, including selection cells and captions. layout"auto" | "fixed""auto"Selects the native table layout algorithm.
Prop Type Default Description 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.
Prop Type Default Description variant"default" | "selected""default"Sets the row surface. Native aria-selected and data attributes also style states.
Prop Type Default Description sticky"left" | "right"—Pins a head or body cell to the corresponding scroll edge.
Checkbox selection parts. Both emit checkedChange, update:checked, and legacy valueChange.
Prop Type Default Description 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.
Slot Element Description 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.
Attribute Value Description 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.
Export Description 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.