Table
@xui/tableA data table. Layout is flex rather than table-layout, so a column can grow while the rest stay sized to their content, and the row parts stay addressable for striping and selection.
Install
pnpm add @xui/table Add the barrel to a standalone component's imports:
import { XuiTableImports } from '@xui/table';
@Component({
imports: [XuiTableImports],
// …
})Examples
Default
<xui-table class="w-80">
<xui-caption>List of users</xui-caption>
<xui-tr>
<xui-th class="grow">Name</xui-th>
<xui-th>Gender</xui-th>
<xui-th>Weight</xui-th>
</xui-tr>
<xui-tr>
<xui-td class="grow">John</xui-td>
<xui-td>Male</xui-td>
<xui-td>70kg</xui-td>
</xui-tr>
<xui-tr data-state="selected">
<xui-td class="grow">John</xui-td>
<xui-td>Male</xui-td>
<xui-td>70kg</xui-td>
</xui-tr>
<xui-tr>
<xui-td class="grow">John</xui-td>
<xui-td>Male</xui-td>
<xui-td>70kg</xui-td>
</xui-tr>
</xui-table>Modifiers
<xui-table class="w-96" striped bordered interactive compact>
<xui-tr>
<xui-th class="grow">Name</xui-th>
<xui-th class="w-24">Role</xui-th>
<xui-th class="w-24">Status</xui-th>
</xui-tr>
<xui-tr>
<xui-td class="grow">Ada Lovelace</xui-td>
<xui-td class="w-24">Owner</xui-td>
<xui-td class="w-24">Active</xui-td>
</xui-tr>
<xui-tr>
<xui-td class="grow">Alan Turing</xui-td>
<xui-td class="w-24">Admin</xui-td>
<xui-td class="w-24">Active</xui-td>
</xui-tr>
<xui-tr>
<xui-td class="grow">Grace Hopper</xui-td>
<xui-td class="w-24">Editor</xui-td>
<xui-td class="w-24">Invited</xui-td>
</xui-tr>
</xui-table>Cdktable
Source only — this one needs a component of its own to run, so there is nothing to render here.
<x-table
xuiTable
stickyHeader
[dataSource]="users()"
[displayedColumns]="columns.displayedColumns()"
[trackBy]="trackBy"
>
<x-column-def name="name" class="w-40">
<xui-th *xHeaderDef>Name</xui-th>
<xui-td truncate *xCellDef="let user">{{ user.name }}</xui-td>
</x-column-def>
<x-column-def name="gender" class="w-40 justify-center">
<xui-th *xHeaderDef>Gender</xui-th>
<xui-td truncate *xCellDef="let user">{{ user.gender }}</xui-td>
</x-column-def>
<x-column-def name="weight">
<xui-th *xHeaderDef>Weight</xui-th>
<xui-td *xCellDef="let user">{{ user.weight }}</xui-td>
</x-column-def>
</x-table>
<ng-template
xPaginator
[xPaginatorTotalElements]="totalElements()"
[xPaginatorPageSize]="pageSize()"
(xPaginatorStateChange)="onStateChange($event)"
let-ctx
>
<div class="mt-2 flex items-center justify-between">
<span class="text-sm tabular-nums">
Showing entries {{ ctx.state().startIndex + 1 }} - {{ ctx.state().endIndex + 1 }} of {{ totalElements() }}
</span>
<div class="flex">
<select
[ngModel]="pageSize()"
(ngModelChange)="pageSize.set($event)"
xuiInput
size="sm"
class="mr-1 inline-flex pr-8"
>
<option [value]="size" *ngFor="let size of availablePageSizes">{{ size === 10000 ? 'All' : size }}</option>
</select>
<div class="flex space-x-1">
<button size="sm" variant="outline" xuiButton [disabled]="!ctx.decrementable()" (click)="ctx.decrement()">
Previous
</button>
<button size="sm" variant="outline" xuiButton [disabled]="!ctx.incrementable()" (click)="ctx.increment()">
Next
</button>
</div>
</div>
</div>
</ng-template>API
The table's accessible name.
Inputs
hiddenbooleanTake the caption off screen while keeping it as the table's accessible name. Use it when the surrounding page already carries a visible heading.falseclassClassValueExtra classes, merged into the component's own rather than replacing them.''Styles the headless <x-table> by writing the xUI Tailwind classes into its tableClasses/headerRowClasses/bodyRowClasses model inputs: <x-table xuiTable>. A consumer binding those inputs itself wins, since the input binding is applied after this constructor runs.
A table laid out with flex rather than table-layout, so a column can grow while the rest stay sized to their content and the row parts stay addressable for striping and selection.
Variants
stripedfalseborderedfalseinteractivefalsecompactfalseInputs
classClassValueExtra classes, merged into the component's own rather than replacing them.''stripedbooleanAlternate row background.this.config.stripedborderedbooleanOuter border plus dividers between cells.this.config.borderedinteractivebooleanShow a pointer cursor on rows for clickable tables.this.config.interactivecompactbooleanTighter cell padding.this.config.compactlabeledByInputstring | null | undefinedId of the element naming the table. Usually left alone: a projected xui-caption sets this itself.undefinedOne body cell of a xui-table.
Inputs
truncatebooleanClip overflowing content to one line with an ellipsis, instead of letting the cell grow.falseclassClassValueExtra classes, merged into the component's own rather than replacing them.''One header cell of a xui-table.
Inputs
truncatebooleanClip an overlong heading to one line with an ellipsis, instead of letting the header row grow.falseclassClassValueExtra classes, merged into the component's own rather than replacing them.''One row of a xui-table, header or body.
Inputs
classClassValueExtra classes, merged into the component's own rather than replacing them.''