Table
Data tables with typed columns. Supports clickable rows, empty state, horizontal scroll, and vertical scroll with sticky header.
| Input | Type | Default | Description |
|---|---|---|---|
columns | NgOatTableColumn[] | required | Column definitions |
data | Record<string, any>[] | required | Row data |
clickable | boolean | false | Enable row click styling |
emptyText | string | 'No data available.' | Text shown when data is empty |
scrollX | boolean | false | Enable horizontal scroll — table overflows horizontally on small screens |
scrollY | string | '' | Enable vertical scroll with a sticky header. Pass any CSS length: '300px', '50vh' |
| Output | Type | Description |
|---|---|---|
rowClick | Record<string, any> | Emitted when a row is clicked |
Import & Usage
typescript
import { Component } from '@angular/core';
import { NgOatTable, type NgOatTableColumn } from '@letsprogram/ng-oat';
@Component({
selector: 'app-example',
imports: [NgOatTable],
template: `
<ng-oat-table
[columns]="columns"
[data]="users"
[scrollX]="true"
[clickable]="true"
(rowClick)="onRowClick($event)" />
`,
})
export class ExampleComponent {
columns: NgOatTableColumn[] = [
{ key: 'name', label: 'Name' },
{ key: 'role', label: 'Role' },
];
users = [
{ name: 'Alice', role: 'Engineer' },
{ name: 'Bob', role: 'Designer' },
];
onRowClick(row: any) {
console.log('Clicked:', row);
}
}Basic Table
| Name | Role | Status |
|---|---|---|
| Alice | Engineer | Active |
| Bob | Designer | Away |
| Carol | PM | Active |
| Dave | QA | Active |
html
<ng-oat-table
[columns]="[
{ key: 'name', label: 'Name' },
{ key: 'role', label: 'Role' },
{ key: 'status', label: 'Status' }
]"
[data]="users"
[scrollX]="true" />Clickable Rows
| Name | Role | Status |
|---|---|---|
| Alice | Engineer | Active |
| Bob | Designer | Away |
| Carol | PM | Active |
| Dave | QA | Active |
html
<ng-oat-table
[columns]="columns"
[data]="users"
[scrollX]="true"
[clickable]="true"
(rowClick)="onRowClick($event)" />Horizontal Scroll
Use [scrollX]="true" so wide tables stay within the layout and scroll horizontally on small screens instead of overflowing.
| Full Name | Role | Department | Location | Date Joined | Status | |
|---|---|---|---|---|---|---|
| Alice Johnson | alice@example.com | Engineer | Platform | New York | 2021-03-15 | Active |
| Bob Martinez | bob@example.com | Designer | Product | Austin | 2022-07-01 | Away |
| Carol Singh | carol@example.com | PM | Operations | London | 2020-11-22 | Active |
| Dave Kim | dave@example.com | QA | Quality | Toronto | 2023-01-10 | Active |
html
<ng-oat-table
[columns]="wideColumns"
[data]="wideData"
[scrollX]="true" />Vertical Scroll + Sticky Header
Use [scrollY]="'260px'" to cap the table height. The header row stays fixed while the body scrolls.
| Name | Role | Status |
|---|---|---|
| Alice | Engineer | Active |
| Bob | Designer | Away |
| Carol | PM | Active |
| Dave | QA | Active |
| Eve | DevOps | Away |
| Frank | Engineer | Active |
| Grace | Designer | Active |
| Hank | QA | Away |
| Iris | PM | Active |
| Jack | Engineer | Active |
| Karen | DevOps | Away |
| Leo | Designer | Active |
html
<ng-oat-table
[columns]="columns"
[data]="manyUsers"
[scrollX]="true"
scrollY="260px" />Empty State
| Name | Role | Status |
|---|---|---|
| No users found. Try adjusting your filters. | ||
html
<ng-oat-table
[columns]="columns"
[data]="[]"
[scrollX]="true"
emptyText="No users found." />Product Inventory
| Product | Price | In Stock | Category |
|---|---|---|---|
| Wireless Keyboard | $49.99 | 142 | Electronics |
| USB-C Hub | $29.99 | 58 | Accessories |
| Monitor Stand | $79.99 | 23 | Furniture |
html
<ng-oat-table
[columns]="[
{ key: 'name', label: 'Product', width: '40%' },
{ key: 'price', label: 'Price' },
{ key: 'stock', label: 'In Stock' },
{ key: 'category', label: 'Category' }
]"
[data]="products"
[scrollX]="true" />