Liking cljdoc? Tell your friends :D

x-table-cell

A stateless table cell Web Component. Works standalone today and coordinates with future x-table-row / x-table components via bubbling events.

<x-table-cell>Cell content</x-table-cell>

<x-table-cell type="header" sortable sort-direction="asc">
  Name
</x-table-cell>

Attributes

AttributeTypeDefaultDescription
type"data" \| "header""data"Cell semantic type. "header" maps to columnheader/rowheader ARIA role; "data" maps to cell.
scope"col" \| "row" \| "colgroup" \| "rowgroup""col"Header scope. Determines whether a header is a columnheader or rowheader. Meaningful only when type="header".
align"start" \| "center" \| "end""start"Horizontal content alignment.
valign"top" \| "middle" \| "bottom""middle"Vertical content alignment.
col-spanpositive integer1Number of grid columns the cell spans. Sets style.gridColumn="span N" on the host for CSS Grid parents.
row-spanpositive integer1Number of grid rows the cell spans. Sets style.gridRow="span N" on the host.
truncateboolean (presence)falseTruncates overflowing text with an ellipsis.
sticky"none" \| "start" \| "end""none"Sticky column. "start" sticks to the inline-start edge; "end" to the inline-end edge. Requires an opaque --x-table-cell-sticky-bg.
sortableboolean (presence)falseShows the sort button. Only effective when type="header".
sort-direction"none" \| "asc" \| "desc""none"Current sort state. Updates the sort icon and aria-sort.
disabledboolean (presence)falseDisables interactions and applies reduced opacity.

Properties

PropertyTypeReflectsDefault
typestringtype attribute"data"
scopestringscope attribute"col"
alignstringalign attribute"start"
valignstringvalign attribute"middle"
colSpannumbercol-span attribute1
rowSpannumberrow-span attribute1
truncatebooleantruncate attributefalse
stickystringsticky attribute"none"
sortablebooleansortable attributefalse
sortDirectionstringsort-direction attribute"none"
disabledbooleandisabled attributefalse

Events

x-table-cell-sort

Fired when the sort button is activated. The component is stateless — the consumer must update the sort-direction attribute to reflect the new state.

PropertyValue
Bubblestrue
Composedtrue
Cancelabletrue

Detail:

{
  direction: "asc" | "desc" | "none";  // the next direction
  previousDirection: "none" | "asc" | "desc";
}

Calling event.preventDefault() cancels the action; the attribute will not be updated externally.

x-table-cell-connected

Fired on every connectedCallback. Consumed by future x-table-row to discover and track cells.

PropertyValue
Bubblestrue
Composedtrue
Cancelablefalse

Detail: { type, scope, colSpan, rowSpan, align }

x-table-cell-disconnected

Fired on every disconnectedCallback.

PropertyValue
Bubblestrue
Composedtrue
Cancelablefalse

Detail: {}


Slots

NameDescription
(default)Cell content
sort-iconCustom sort icon; replaces the default inline SVG arrows.

Parts

PartElementDescription
celldivOuter layout wrapper; receives padding, background, border.
contentspanContent area wrapping the default slot.
sort-btnbuttonSort interaction button (visible for header+sortable cells only).
sort-icon-defaultspanDefault inline SVG sort icon (neutral/ascending/descending).

CSS Custom Properties

Layout

PropertyDefaultDescription
--x-table-cell-padding0.5rem 0.75remCell padding.
--x-table-cell-border-width1pxBorder width (bottom border).
--x-table-cell-min-width0Minimum cell width.
--x-table-cell-max-widthnoneMaximum cell width.

Colors

PropertyDefault (light)Default (dark)Description
--x-table-cell-bgtransparenttransparentData cell background.
--x-table-cell-header-bgrgba(0,0,0,0.04)rgba(255,255,255,0.06)Header cell background.
--x-table-cell-border-colorrgba(0,0,0,0.1)rgba(255,255,255,0.1)Border color.
--x-table-cell-colorinheritinheritData cell text color.
--x-table-cell-header-colorinheritinheritHeader cell text color.
--x-table-cell-sort-colorrgba(0,0,0,0.4)rgba(255,255,255,0.4)Sort icon default color.
--x-table-cell-sort-hover-colorrgba(0,0,0,0.7)rgba(255,255,255,0.7)Sort icon hover color.
--x-table-cell-sticky-bg#ffffff#1f2937Sticky cell background (must be opaque).
--x-table-cell-focus-ringrgba(59,130,246,0.5)sameSort button focus ring.

Typography

PropertyDefaultDescription
--x-table-cell-font-sizeinheritCell font size.
--x-table-cell-header-font-weight600Header cell font weight.

Motion

PropertyDefaultDescription
--x-table-cell-transition-duration150msSort button color transition duration.

State

PropertyDefaultDescription
--x-table-cell-disabled-opacity0.45Opacity when disabled.

Accessibility

ARIA Role Mapping

typescoperole on host
"data"any"cell"
"header""col" (default)"columnheader"
"header""colgroup""columnheader"
"header""row""rowheader"
"header""rowgroup""rowheader"

aria-sort

Set on the host element when either sortable is present or sort-direction is not "none":

sort-directionaria-sort
"none""none"
"asc""ascending"
"desc""descending"

When neither sortable nor a non-"none" direction is set, aria-sort is removed.

aria-disabled

Set to "true" on the host when disabled is present.

Sort Button

The sort button's aria-label describes the action that will occur on activation, not the current state:

Current sort-directionButton aria-label
"none""Sort ascending"
"asc""Sort descending"
"desc""Remove sort"

Keyboard

KeyTargetAction
Enter / SpaceSort buttonActivates sort, fires x-table-cell-sort

Sort Cycling

The component is stateless — clicking the sort button fires x-table-cell-sort and does nothing else. The consumer must update the sort-direction attribute:

cell.addEventListener('x-table-cell-sort', (e) => {
  // e.detail.direction is the next direction
  cell.setAttribute('sort-direction', e.detail.direction);
});

Direction cycles: "none""asc""desc""none".

To cancel a sort action (e.g. for async validation):

cell.addEventListener('x-table-cell-sort', (e) => {
  e.preventDefault();  // sort-direction is not updated
});

Grid Span (col-span / row-span)

When x-table-cell is placed in a CSS Grid context (as provided by a future x-table-row), setting col-span and row-span drives the cell's grid placement:

  • col-span="2"style.gridColumn = "span 2" on the host
  • row-span="3"style.gridRow = "span 3" on the host
  • Value 1 clears the inline style (no span)
<!-- Spans 2 columns in an x-table-row grid -->
<x-table-cell col-span="2">Wide cell</x-table-cell>

Sticky Positioning

Sticky cells require an opaque background. The --x-table-cell-sticky-bg custom property controls this:

x-table-cell {
  --x-table-cell-sticky-bg: #ffffff; /* or match your row background */
}
<x-table-cell sticky="start">Frozen first column</x-table-cell>

Note: sticky positioning requires a scrollable ancestor container.


Parent Coordination Events

When x-table-row and x-table are implemented, they will consume the x-table-cell-connected and x-table-cell-disconnected events to track cells. The cell fires these unconditionally — no configuration needed.


Examples

Basic data cell

<x-table-cell>Hello world</x-table-cell>

Header cell with sort

<x-table-cell type="header" sortable sort-direction="none">
  Name
</x-table-cell>

<script>
  document.querySelector('x-table-cell').addEventListener('x-table-cell-sort', (e) => {
    e.target.setAttribute('sort-direction', e.detail.direction);
  });
</script>

Truncated cell

<x-table-cell truncate style="width: 150px;">
  This is a very long text that will be truncated
</x-table-cell>

Spanning cells (in a CSS Grid row)

<div style="display: grid; grid-template-columns: repeat(4, 1fr);">
  <x-table-cell col-span="2">Spans two columns</x-table-cell>
  <x-table-cell>Col 3</x-table-cell>
  <x-table-cell>Col 4</x-table-cell>
</div>

Sticky first column

<x-table-cell sticky="start"
              style="--x-table-cell-sticky-bg: #fff;">
  Row label
</x-table-cell>

Custom sort icon via slot

<x-table-cell type="header" sortable>
  Status
  <svg slot="sort-icon" width="16" height="16" viewBox="0 0 16 16">
    <path d="M8 4l4 8H4l4-8z" fill="currentColor"/>
  </svg>
</x-table-cell>

JavaScript API

const cell = document.querySelector('x-table-cell');

// Property access
cell.type = 'header';
cell.sortable = true;
cell.sortDirection = 'asc';
cell.colSpan = 2;
cell.disabled = false;

// Events
cell.addEventListener('x-table-cell-sort', (e) => {
  cell.sortDirection = e.detail.direction;
});

ClojureScript / Hiccup

[:x-table-cell {:type "header" :sortable "" :sort-direction "none"
                :on-x-table-cell-sort #(set! (.-sortDirection (.-target %))
                                             (.-direction (.-detail %)))}
 "Column Name"]

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close