Documentation
Column Pinning
Column pinning (also known as freezing or sticking) allows you to keep important columns visible while horizontally scrolling through wide tables, making it easier to maintain context.
React TSX
Copy
1import {SimpleTable} from "@simple-table/react";import type { Theme } from "@simple-table/react";2import { columnPinningConfig } from "./column-pinning.demo-data";3import "@simple-table/react/styles.css";45const ColumnPinningDemo = ({6 height = "400px",7 theme,8}: {9 height?: string | number;10 theme?: Theme;11}) => {12 return (13 <SimpleTable14 defaultHeaders={columnPinningConfig.headers}15 rows={columnPinningConfig.rows}16 height={height}17 theme={theme}18 columnResizing={columnPinningConfig.tableProps.columnResizing}19 />20 );21};2223export default ColumnPinningDemo;
Vue SFC
Copy
1<template>2 <SimpleTable3 :default-headers="columnPinningConfig.headers"4 :rows="columnPinningConfig.rows"5 :height="height"6 :theme="theme"7 :column-resizing="columnPinningConfig.tableProps.columnResizing"8 />9</template>1011<script setup lang="ts">12import {SimpleTable} from "@simple-table/vue";import type { Theme } from "@simple-table/vue";13import { columnPinningConfig } from "./column-pinning.demo-data";14import "@simple-table/vue/styles.css";1516withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {17 height: "400px",18});19</script>
Angularcolumn-pinning-demo.component.ts
Copy
1import { Component, Input } from "@angular/core";2import {SimpleTableComponent} from "@simple-table/angular";import type { AngularHeaderObject, Row, Theme } from "@simple-table/angular";3import { columnPinningConfig } from "./column-pinning.demo-data";4import "@simple-table/angular/styles.css";56@Component({7 selector: "column-pinning-demo",8 standalone: true,9 imports: [SimpleTableComponent],10 template: `11 <simple-table12 [rows]="rows"13 [defaultHeaders]="headers"14 [height]="height"15 [theme]="theme"16 [columnResizing]="columnResizing"17 ></simple-table>18 `,19})20export class ColumnPinningDemoComponent {21 @Input() height: string | number = "400px";22 @Input() theme?: Theme;2324 readonly rows: Row[] = columnPinningConfig.rows;25 readonly headers: AngularHeaderObject[] = columnPinningConfig.headers;26 readonly columnResizing = columnPinningConfig.tableProps.columnResizing;27}282930// column-pinning.demo-data.ts31// Self-contained demo table setup for this example.32import type { AngularHeaderObject } from "@simple-table/angular";333435export const columnPinningHeaders: AngularHeaderObject[] = [36 { accessor: "name", label: "Name", width: 132, pinned: "left", type: "string" },37 { accessor: "email", label: "Email", width: 220, type: "string" },38 { accessor: "role", label: "Role", width: 150, type: "string" },39 { accessor: "department", label: "Department", width: 150, type: "string" },40 { accessor: "location", label: "Location", width: 150, type: "string" },41 { accessor: "joinDate", label: "Join Date", width: 120, type: "date" },42 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },43 { accessor: "manager", label: "Manager", width: 180, type: "string" },44 { accessor: "status", label: "Status", width: 120, type: "string" },45 { accessor: "projects", label: "Projects", width: 100, align: "right", pinned: "right", type: "number" },46];4748export const columnPinningData = [49 { id: 1, name: "Zara Nakamura", email: "zara.n@pixelstudio.game", role: "Lead Game Designer", department: "Game Design", location: "Tokyo", joinDate: "2019-03-12", salary: 145000, manager: "Hiroshi Tanaka", status: "Active", projects: 7 },50 { id: 2, name: "Phoenix Rodriguez", email: "phoenix.r@pixelstudio.game", role: "3D Artist", department: "Art & Animation", location: "Montreal", joinDate: "2020-11-08", salary: 98000, manager: "Elena Volkov", status: "Active", projects: 4 },51 { id: 3, name: "Kai Thompson", email: "kai.t@pixelstudio.game", role: "Senior Programmer", department: "Engineering", location: "San Francisco", joinDate: "2018-05-15", salary: 135000, manager: "Nova Singh", status: "Active", projects: 6 },52 { id: 4, name: "Luna Martinez", email: "luna.m@pixelstudio.game", role: "UI/UX Designer", department: "User Experience", location: "Barcelona", joinDate: "2021-08-23", salary: 89000, manager: "River Chen", status: "Active", projects: 3 },53 { id: 5, name: "Atlas Williams", email: "atlas.w@pixelstudio.game", role: "Audio Engineer", department: "Sound Design", location: "Nashville", joinDate: "2020-01-17", salary: 92000, manager: "Echo Davis", status: "Active", projects: 5 },54 { id: 6, name: "Sage Kumar", email: "sage.k@pixelstudio.game", role: "QA Lead", department: "Quality Assurance", location: "Bangalore", joinDate: "2019-09-30", salary: 78000, manager: "Orion Lee", status: "Active", projects: 8 },55 { id: 7, name: "River Petrov", email: "river.p@pixelstudio.game", role: "Producer", department: "Production", location: "London", joinDate: "2018-12-05", salary: 125000, manager: "Nova Singh", status: "Active", projects: 4 },56 { id: 8, name: "Nova Hassan", email: "nova.h@pixelstudio.game", role: "Community Manager", department: "Marketing", location: "Los Angeles", joinDate: "2022-04-14", salary: 75000, manager: "Zara Nakamura", status: "Active", projects: 2 },57 { id: 9, name: "Echo Fernandez", email: "echo.f@pixelstudio.game", role: "Narrative Designer", department: "Storytelling", location: "Prague", joinDate: "2021-02-28", salary: 87000, manager: "Atlas Williams", status: "Active", projects: 3 },58 { id: 10, name: "Orion Silva", email: "orion.s@pixelstudio.game", role: "Backend Developer", department: "Engineering", location: "São Paulo", joinDate: "2020-07-11", salary: 101000, manager: "Kai Thompson", status: "Active", projects: 5 },59 { id: 11, name: "Aria Kim", email: "aria.k@pixelstudio.game", role: "Character Artist", department: "Art & Animation", location: "Seoul", joinDate: "2022-01-19", salary: 94000, manager: "Phoenix Rodriguez", status: "Active", projects: 2 },60 { id: 12, name: "Zenith Okafor", email: "zenith.o@pixelstudio.game", role: "Technical Director", department: "Engineering", location: "Stockholm", joinDate: "2017-10-02", salary: 165000, manager: "CEO", status: "Active", projects: 9 },61];6263export const columnPinningConfig = {64 headers: columnPinningHeaders,65 rows: columnPinningData,66 tableProps: { columnResizing: true },67} as const;68
Svelte
Copy
1<script lang="ts">2 import {SimpleTable} from "@simple-table/svelte"; import type { Theme } from "@simple-table/svelte";3 import { columnPinningConfig } from "./column-pinning.demo-data";4 import "@simple-table/svelte/styles.css";56 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();7</script>89<SimpleTable10 defaultHeaders={columnPinningConfig.headers}11 rows={columnPinningConfig.rows}12 {height}13 {theme}14 columnResizing={columnPinningConfig.tableProps.columnResizing}15/>
Solid TSX
Copy
1import {SimpleTable} from "@simple-table/solid";import type { Theme } from "@simple-table/solid";2import { columnPinningConfig } from "./column-pinning.demo-data";3import "@simple-table/solid/styles.css";45export default function ColumnPinningDemo(props: { height?: string | number; theme?: Theme }) {6 return (7 <SimpleTable8 defaultHeaders={columnPinningConfig.headers}9 rows={columnPinningConfig.rows}10 height={props.height ?? "400px"}11 theme={props.theme}12 columnResizing={columnPinningConfig.tableProps.columnResizing}13 />14 );15}
TypeScriptColumnPinningDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { Theme } from "simple-table-core";3import { columnPinningConfig } from "./column-pinning.demo-data";4import "simple-table-core/styles.css";56export function renderColumnPinningDemo(7 container: HTMLElement,8 options?: { height?: string | number; theme?: Theme },9): SimpleTableVanilla {10 const table = new SimpleTableVanilla(container, {11 defaultHeaders: columnPinningConfig.headers,12 rows: columnPinningConfig.rows,13 height: options?.height ?? "400px",14 theme: options?.theme,15 columnResizing: columnPinningConfig.tableProps.columnResizing,16 });17 return table;18}192021// column-pinning.demo-data.ts22// Self-contained demo table setup for this example.23import type { HeaderObject } from "simple-table-core";242526export const columnPinningHeaders: HeaderObject[] = [27 { accessor: "name", label: "Name", width: 132, pinned: "left", type: "string" },28 { accessor: "email", label: "Email", width: 220, type: "string" },29 { accessor: "role", label: "Role", width: 150, type: "string" },30 { accessor: "department", label: "Department", width: 150, type: "string" },31 { accessor: "location", label: "Location", width: 150, type: "string" },32 { accessor: "joinDate", label: "Join Date", width: 120, type: "date" },33 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },34 { accessor: "manager", label: "Manager", width: 180, type: "string" },35 { accessor: "status", label: "Status", width: 120, type: "string" },36 { accessor: "projects", label: "Projects", width: 100, align: "right", pinned: "right", type: "number" },37];3839export const columnPinningData = [40 { id: 1, name: "Zara Nakamura", email: "zara.n@pixelstudio.game", role: "Lead Game Designer", department: "Game Design", location: "Tokyo", joinDate: "2019-03-12", salary: 145000, manager: "Hiroshi Tanaka", status: "Active", projects: 7 },41 { id: 2, name: "Phoenix Rodriguez", email: "phoenix.r@pixelstudio.game", role: "3D Artist", department: "Art & Animation", location: "Montreal", joinDate: "2020-11-08", salary: 98000, manager: "Elena Volkov", status: "Active", projects: 4 },42 { id: 3, name: "Kai Thompson", email: "kai.t@pixelstudio.game", role: "Senior Programmer", department: "Engineering", location: "San Francisco", joinDate: "2018-05-15", salary: 135000, manager: "Nova Singh", status: "Active", projects: 6 },43 { id: 4, name: "Luna Martinez", email: "luna.m@pixelstudio.game", role: "UI/UX Designer", department: "User Experience", location: "Barcelona", joinDate: "2021-08-23", salary: 89000, manager: "River Chen", status: "Active", projects: 3 },44 { id: 5, name: "Atlas Williams", email: "atlas.w@pixelstudio.game", role: "Audio Engineer", department: "Sound Design", location: "Nashville", joinDate: "2020-01-17", salary: 92000, manager: "Echo Davis", status: "Active", projects: 5 },45 { id: 6, name: "Sage Kumar", email: "sage.k@pixelstudio.game", role: "QA Lead", department: "Quality Assurance", location: "Bangalore", joinDate: "2019-09-30", salary: 78000, manager: "Orion Lee", status: "Active", projects: 8 },46 { id: 7, name: "River Petrov", email: "river.p@pixelstudio.game", role: "Producer", department: "Production", location: "London", joinDate: "2018-12-05", salary: 125000, manager: "Nova Singh", status: "Active", projects: 4 },47 { id: 8, name: "Nova Hassan", email: "nova.h@pixelstudio.game", role: "Community Manager", department: "Marketing", location: "Los Angeles", joinDate: "2022-04-14", salary: 75000, manager: "Zara Nakamura", status: "Active", projects: 2 },48 { id: 9, name: "Echo Fernandez", email: "echo.f@pixelstudio.game", role: "Narrative Designer", department: "Storytelling", location: "Prague", joinDate: "2021-02-28", salary: 87000, manager: "Atlas Williams", status: "Active", projects: 3 },49 { id: 10, name: "Orion Silva", email: "orion.s@pixelstudio.game", role: "Backend Developer", department: "Engineering", location: "São Paulo", joinDate: "2020-07-11", salary: 101000, manager: "Kai Thompson", status: "Active", projects: 5 },50 { id: 11, name: "Aria Kim", email: "aria.k@pixelstudio.game", role: "Character Artist", department: "Art & Animation", location: "Seoul", joinDate: "2022-01-19", salary: 94000, manager: "Phoenix Rodriguez", status: "Active", projects: 2 },51 { id: 12, name: "Zenith Okafor", email: "zenith.o@pixelstudio.game", role: "Technical Director", department: "Engineering", location: "Stockholm", joinDate: "2017-10-02", salary: 165000, manager: "CEO", status: "Active", projects: 9 },52];5354export const columnPinningConfig = {55 headers: columnPinningHeaders,56 rows: columnPinningData,57 tableProps: { columnResizing: true },58} as const;59
Basic Implementation
To pin columns, simply add the pinned property to your header objects:
Column Pinning Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
HeaderObject.pinned | Optional | Pins the column to the left or right side of the table, keeping it visible during horizontal scrolling. Options: left right |
Essential columns
To lock columns so users cannot hide them or unpin them from an edge, and to keep them in a fixed leading group when reordering inside each pin section, set isEssential on the column's header object.
Saving pin layout
Use tableRef.getPinnedState() and tableRef.applyPinnedState(...) to read and restore left / main / right accessor lists (TableAPI).