Getting StartedInstallation and setup guides 6
LayoutWorkflow and structural layout components 8
OverlayModal and floating layer surfaces 3
FeedbackStatus, empty, progress, and loading placeholder patterns 5
FormInput and selection components 25
UtilityGeneral-purpose interface utilities 7
NavigationMenu surfaces and hierarchical actions 7

Table styling

Table styling is wrapper-first. Use CSS variables for component-scoped layout changes such as scroll height, overflow, table width, and header background. Use stable data-slot hooks for shared global CSS.

HookUse
[data-slot='table-scroll'] Outer border, radius, background, max height, and scroll wrapper state. Reflects data-scroll-axis and data-sticky-header.
[data-slot='table']Typography, table layout, min width, density, and hover mode state.
[data-slot='table-header-cell']Header background, sort affordance, focus ring, and sticky presentation.
[data-slot='table-cell']Body cell padding, borders, alignment, truncation, and hover state.
[data-slot='table-state-cell']Loading, error, and empty states.

Row and cell styling

For data-driven styling, attach your own classes through the rowClass input and the column-level cellClass / headerClass hooks. For component-scoped dynamic styling, use rowStyle, cellStyle, and headerStyle; these apply inline styles and CSS custom properties directly to the internal table elements.

Class hooks are best for global CSS, Tailwind utilities, or shared library classes. Style hooks are the component-CSS-friendly path because Angular scoped styles cannot select the table's internal rows and cells without ::ng-deep.

HookApplies to
rowClass(row, index)Extra classes for each body <tr>, evaluated per row.
rowStyle(row, index) Inline styles/custom properties for each body <tr>. Use --tng-table-row-bg for row backgrounds.
column.cellClass Body cells of one column (static or a (row, value, index) predicate).
column.cellStyleInline styles for body cells of one column (static or predicate).
column.headerClassThe header cell of a leaf or group column.
column.headerStyleInline styles for a leaf or group header cell.
[data-group-position] Row attribute (first | middle | last | single) for styling groupBy blocks, e.g. dividers between groups.
// component.ts
protected rowStyle = (row: Order) =>
  row.status === 'overdue'
    ? { '--tng-table-row-bg': 'var(--orders-overdue-row-bg)' }
    : null;

protected columns: TngTableColumn<Order>[] = [
  { id: 'name', label: 'Name' },
  {
    id: 'total',
    label: 'Total',
    align: 'end',
    cellStyle: (_row, value) =>
      Number(value) < 0 ? { color: 'var(--orders-negative-fg)' } : null,
  },
];

/* component.css */
tng-table {
  --orders-overdue-row-bg: color-mix(
    in srgb,
    var(--tng-semantic-accent-danger) 12%,
    var(--tng-semantic-background-surface)
  );
  --orders-negative-fg: var(--tng-semantic-accent-danger);
}

Scroll and sizing

scrollAxis enables the primitive scroll axes. CSS variables define the wrapper constraints and the native table's minimum width.

<!-- component.html -->
<tng-table
  class="statement-preview-table"
  scrollAxis="both"
  [stickyHeader]="true"
  [columns]="columns"
  [items]="rows"
/>

/* component.css */
.statement-preview-table {
  --tng-table-scroll-max-height: min(14rem, 30vh);
  --tng-table-min-width: 84rem;
  --tng-table-header-bg: var(--tng-semantic-background-surface);
}

CSS starter

tng-table {
  --tng-table-border: var(--tng-semantic-border-subtle);
  --tng-table-radius: 0.75rem;
  --tng-table-cell-px: 1rem;
  --tng-table-cell-py: 0.75rem;
  --tng-table-header-bg: var(--tng-semantic-background-muted);
  --tng-table-scroll-max-height: none;
  --tng-table-scroll-overflow-x: auto;
  --tng-table-scroll-overflow-y: auto;
  --tng-table-min-width: 100%;
  --tng-table-header-z-index: 2;
}