Documentation
Nested Headers
Group related columns under parent headers for clearer structure.
Group columns with children
Add a children array to a parent column. The parent is a header group (no cell data); leaf columns hold the values and can use sorting, filtering, and other column props as usual. Parent width spans its children.
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Test Scores",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },{ accessor: "english", label: "English", width: 80, type: "number" },],}
Multiple levels
Nest further by adding children on a child column.
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
TypeScript
Copy
{label: "Academics",children: [{label: "STEM",children: [{ accessor: "math", label: "Math", width: 80, type: "number" },{ accessor: "science", label: "Science", width: 80, type: "number" },],},{ accessor: "english", label: "English", width: 80, type: "number" },],}
Example
React TSX
Copy
1import {SimpleTable} from "@simple-table/react";import type { Theme } from "@simple-table/react";2import { nestedHeadersConfig } from "./nested-headers.demo-data";3import "@simple-table/react/styles.css";45const NestedHeadersDemo = ({6 height = "400px",7 theme8}: {9 height?: string | number;10 theme?: Theme;11}) => {12 return (13 <SimpleTable14 columns={nestedHeadersConfig.headers}15 rows={nestedHeadersConfig.rows}16 height={height}17 theme={theme}18 columnResizing={nestedHeadersConfig.tableProps.columnResizing}19 getRowId={({ row }) => row.id}20 />21 );22};2324export default NestedHeadersDemo;
Angularnested-headers-demo.component.ts
Copy
1import { Component, Input } from "@angular/core";2import {SimpleTableComponent} from "@simple-table/angular";import type { AngularColumnDef, GetRowIdParams, Theme } from "@simple-table/angular";3import { nestedHeadersConfig } from "./nested-headers.demo-data";4import "@simple-table/angular/styles.css";5import type { StudentScores } from "./nested-headers.demo-data";67@Component({8 selector: "nested-headers-demo",9 standalone: true,10 imports: [SimpleTableComponent],11 template: `12 <simple-table13 [getRowId]="getRowId"14 [rows]="rows"15 [columns]="headers"16 [height]="height"17 [theme]="theme"18 [columnResizing]="columnResizing"19 ></simple-table>20 `,21})22export class NestedHeadersDemoComponent {23 @Input() height: string | number = "400px";24 @Input() theme?: Theme;2526 readonly rows: StudentScores[] = nestedHeadersConfig.rows;27 readonly headers: AngularColumnDef<StudentScores>[] = nestedHeadersConfig.headers;28 readonly columnResizing = nestedHeadersConfig.tableProps.columnResizing;2930 getRowId = ({ row }: GetRowIdParams<StudentScores>) => row.id;31}323334// nested-headers.demo-data.ts35// Self-contained demo table setup for this example.36import type { AngularColumnDef } from "@simple-table/angular";3738export interface StudentScores {39 id: number;40 name: string;41 mathScore: number;42 scienceScore: number;43 historyScore: number;44 grade: string;45}4647export const nestedHeadersHeaders: AngularColumnDef<StudentScores>[] = [48 { accessor: "id", label: "ID", width: 80, sortable: true, type: "number" },49 { accessor: "name", label: "Name", width: "1fr", sortable: true, type: "string" },50 {51 accessor: "score",52 label: "Test Scores",53 width: 300,54 sortable: false,55 type: "number",56 children: [57 { accessor: "mathScore", label: "Math", width: 100, sortable: true, type: "number", align: "right" },58 { accessor: "scienceScore", label: "Science", width: 100, sortable: true, type: "number", align: "right" },59 { accessor: "historyScore", label: "History", width: 100, sortable: true, type: "number", align: "right" },60 ],61 },62 { accessor: "grade", label: "Overall Grade", width: 120, sortable: true, type: "string", align: "center" },63];6465export const nestedHeadersData: StudentScores[] = [66 { id: 1, name: "Aria Chen", mathScore: 94, scienceScore: 89, historyScore: 92, grade: "A" },67 { id: 2, name: "Kai Rodriguez", mathScore: 81, scienceScore: 85, historyScore: 78, grade: "B" },68 { id: 3, name: "Luna Nakamura", mathScore: 96, scienceScore: 94, historyScore: 93, grade: "A" },69 { id: 4, name: "Phoenix Williams", mathScore: 72, scienceScore: 75, historyScore: 69, grade: "C" },70 { id: 5, name: "River Martinez", mathScore: 87, scienceScore: 91, historyScore: 83, grade: "B" },71 { id: 6, name: "Sage Thompson", mathScore: 79, scienceScore: 74, historyScore: 82, grade: "B" },72 { id: 7, name: "Nova Patel", mathScore: 93, scienceScore: 88, historyScore: 95, grade: "A" },73 { id: 8, name: "Atlas Kim", mathScore: 86, scienceScore: 82, historyScore: 89, grade: "B" },74 { id: 9, name: "Zara Hassan", mathScore: 91, scienceScore: 97, historyScore: 87, grade: "A" },75 { id: 10, name: "Orion Singh", mathScore: 77, scienceScore: 73, historyScore: 80, grade: "B" },76 { id: 11, name: "Echo Volkov", mathScore: 95, scienceScore: 92, historyScore: 98, grade: "A" },77];7879export const nestedHeadersConfig = {80 headers: nestedHeadersHeaders,81 rows: nestedHeadersData,82 tableProps: { columnResizing: true },83};84
Vue SFC
Copy
1<template>2 <SimpleTable3 :columns="nestedHeadersConfig.headers"4 :rows="nestedHeadersConfig.rows"5 :get-row-id="getRowId"6 :height="height"7 :theme="theme"8 :column-resizing="nestedHeadersConfig.tableProps.columnResizing"9 />10</template>1112<script setup lang="ts">13import { SimpleTable } from "@simple-table/vue";14import type { Theme, GetRowIdParams } from "@simple-table/vue";15import { nestedHeadersConfig } from "./nested-headers.demo-data";16import type { StudentScores } from "./nested-headers.demo-data";17import "@simple-table/vue/styles.css";1819withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {20 height: "400px",21});2223const getRowId = ({ row }: GetRowIdParams<StudentScores>) => row.id;24</script>
Svelte
Copy
1<script lang="ts">2 import { SimpleTable } from "@simple-table/svelte";3 import type { Theme, GetRowIdParams } from "@simple-table/svelte";4 import { nestedHeadersConfig } from "./nested-headers.demo-data";5 import type { StudentScores } from "./nested-headers.demo-data";6 import "@simple-table/svelte/styles.css";78 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();910 const getRowId = ({ row }: GetRowIdParams<StudentScores>) => row.id;11</script>1213<SimpleTable14 columns={nestedHeadersConfig.headers}15 rows={nestedHeadersConfig.rows}16 getRowId={getRowId}17 {height}18 {theme}19 columnResizing={nestedHeadersConfig.tableProps.columnResizing}20/>
Solid TSX
Copy
1import {SimpleTable} from "@simple-table/solid";import type { Theme } from "@simple-table/solid";2import { nestedHeadersConfig } from "./nested-headers.demo-data";3import "@simple-table/solid/styles.css";45export default function NestedHeadersDemo(props: { height?: string | number; theme?: Theme }) {6 return (7 <SimpleTable8 columns={nestedHeadersConfig.headers}9 getRowId={({ row }) => row.id}10 rows={nestedHeadersConfig.rows}11 height={props.height ?? "400px"}12 theme={props.theme}13 columnResizing={nestedHeadersConfig.tableProps.columnResizing}14 />15 );16}
TypeScriptNestedHeadersDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { StudentScores } from "./nested-headers.demo-data";3import type { Theme, GetRowIdParams } from "simple-table-core";4import { nestedHeadersConfig } from "./nested-headers.demo-data";5import "simple-table-core/styles.css";678const getRowId = ({ row }: GetRowIdParams<StudentScores>) => row.id;9export function renderNestedHeadersDemo(10 container: HTMLElement,11 options?: { height?: string | number; theme?: Theme }12): SimpleTableVanilla<StudentScores> {13 const table = new SimpleTableVanilla(container, {14 getRowId,15 columns: nestedHeadersConfig.headers,16 rows: nestedHeadersConfig.rows,17 height: options?.height ?? "400px",18 theme: options?.theme,19 columnResizing: nestedHeadersConfig.tableProps.columnResizing,20 });21 return table;22}232425// nested-headers.demo-data.ts26// Self-contained demo table setup for this example.27import type { ColumnDef } from "simple-table-core";2829export interface StudentScores {30 id: number;31 name: string;32 mathScore: number;33 scienceScore: number;34 historyScore: number;35 grade: string;36}3738export const nestedHeadersHeaders: ColumnDef<StudentScores>[] = [39 { accessor: "id", label: "ID", width: 80, sortable: true, type: "number" },40 { accessor: "name", label: "Name", width: "1fr", sortable: true, type: "string" },41 {42 accessor: "score",43 label: "Test Scores",44 width: 300,45 sortable: false,46 type: "number",47 children: [48 { accessor: "mathScore", label: "Math", width: 100, sortable: true, type: "number", align: "right" },49 { accessor: "scienceScore", label: "Science", width: 100, sortable: true, type: "number", align: "right" },50 { accessor: "historyScore", label: "History", width: 100, sortable: true, type: "number", align: "right" },51 ],52 },53 { accessor: "grade", label: "Overall Grade", width: 120, sortable: true, type: "string", align: "center" },54];5556export const nestedHeadersData: StudentScores[] = [57 { id: 1, name: "Aria Chen", mathScore: 94, scienceScore: 89, historyScore: 92, grade: "A" },58 { id: 2, name: "Kai Rodriguez", mathScore: 81, scienceScore: 85, historyScore: 78, grade: "B" },59 { id: 3, name: "Luna Nakamura", mathScore: 96, scienceScore: 94, historyScore: 93, grade: "A" },60 { id: 4, name: "Phoenix Williams", mathScore: 72, scienceScore: 75, historyScore: 69, grade: "C" },61 { id: 5, name: "River Martinez", mathScore: 87, scienceScore: 91, historyScore: 83, grade: "B" },62 { id: 6, name: "Sage Thompson", mathScore: 79, scienceScore: 74, historyScore: 82, grade: "B" },63 { id: 7, name: "Nova Patel", mathScore: 93, scienceScore: 88, historyScore: 95, grade: "A" },64 { id: 8, name: "Atlas Kim", mathScore: 86, scienceScore: 82, historyScore: 89, grade: "B" },65 { id: 9, name: "Zara Hassan", mathScore: 91, scienceScore: 97, historyScore: 87, grade: "A" },66 { id: 10, name: "Orion Singh", mathScore: 77, scienceScore: 73, historyScore: 80, grade: "B" },67 { id: 11, name: "Echo Volkov", mathScore: 95, scienceScore: 92, historyScore: 98, grade: "A" },68];6970export const nestedHeadersConfig = {71 headers: nestedHeadersHeaders,72 rows: nestedHeadersData,73 tableProps: { columnResizing: true },74};75
Props
Nested Headers Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
ColumnDef.children | Optional | Child columns grouped under this parent header. Creates a hierarchical header structure. |