Documentation
Column Pinning
Keep important columns visible while scrolling wide tables horizontally.
Pin to the left
Set pinned: "left" so the column stays visible while scrolling horizontally.
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
TypeScript
Copy
{accessor: "id",label: "ID",width: 80,pinned: "left",}
Pin to the right
Use pinned: "right" for actions or status columns that should stay on the trailing edge.
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
TypeScript
Copy
{accessor: "actions",label: "Actions",width: 120,pinned: "right",}
Essential columns
Set essential: true to prevent hide/unpin and keep the column in a fixed leading group within its pin section. See ColumnDef.
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
TypeScript
Copy
{accessor: "name",label: "Name",width: "1fr",pinned: "left",essential: true,}
Save and restore pin layout
Use getPinnedState and applyPinnedState on TableAPI to read and restore left / main / right accessor lists.
TypeScript
Copy
// Saveconst pinned = tableRef.current?.getPinnedState();// Restoreawait tableRef.current?.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = this.tableRef.getAPI()?.getPinnedState();// Restoreawait this.tableRef.getAPI()?.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = tableRef.value?.getPinnedState();// Restoreawait tableRef.value?.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = tableRef.getAPI()?.getPinnedState();// Restoreawait tableRef.getAPI()?.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = tableRef.getPinnedState();// Restoreawait tableRef.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = table.getPinnedState();// Restoreawait table.applyPinnedState(pinned);
Example
Scroll horizontally — left and right pinned columns stay in place.
React TSX
Copy
1import { SimpleTable } from "@simple-table/react";2import type { Theme } from "@simple-table/react";3import { columnPinningConfig } from "./column-pinning.demo-data";4import "@simple-table/react/styles.css";56const ColumnPinningDemo = ({7 height = "400px",8 theme9}: {10 height?: string | number;11 theme?: Theme;12}) => {13 return (14 <SimpleTable15 columns={columnPinningConfig.headers}16 getRowId={({ row }) => row.id}17 rows={columnPinningConfig.rows}18 height={height}19 theme={theme}20 columnResizing={columnPinningConfig.tableProps.columnResizing}21 />22 );23};2425export default ColumnPinningDemo;
Angularcolumn-pinning-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 { columnPinningConfig } from "./column-pinning.demo-data";4import "@simple-table/angular/styles.css";5import type { ColumnPinningEmployee } from "./column-pinning.demo-data";67@Component({8 selector: "column-pinning-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 ColumnPinningDemoComponent {23 @Input() height: string | number = "400px";24 @Input() theme?: Theme;2526 readonly rows: ColumnPinningEmployee[] = columnPinningConfig.rows;27 readonly headers: AngularColumnDef<ColumnPinningEmployee>[] = columnPinningConfig.headers;28 readonly columnResizing = columnPinningConfig.tableProps.columnResizing;2930 getRowId = ({ row }: GetRowIdParams<ColumnPinningEmployee>) => row.id;31}323334// column-pinning.demo-data.ts35// Self-contained demo table setup for this example.36import type { AngularColumnDef } from "@simple-table/angular";3738export interface ColumnPinningEmployee {39 id: number;40 name: string;41 email: string;42 role: string;43 department: string;44 location: string;45 joinDate: string;46 salary: number;47 manager: string;48 status: string;49 projects: number;50}5152export const columnPinningHeaders: AngularColumnDef<ColumnPinningEmployee>[] = [53 { accessor: "name", label: "Name", width: 132, pinned: "left", type: "string" },54 { accessor: "email", label: "Email", width: 220, type: "string" },55 { accessor: "role", label: "Role", width: 150, type: "string" },56 { accessor: "department", label: "Department", width: 150, type: "string" },57 { accessor: "location", label: "Location", width: 150, type: "string" },58 { accessor: "joinDate", label: "Join Date", width: 120, type: "date" },59 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },60 { accessor: "manager", label: "Manager", width: 180, type: "string" },61 { accessor: "status", label: "Status", width: 120, type: "string" },62 { accessor: "projects", label: "Projects", width: 100, align: "right", pinned: "right", type: "number" },63];6465export const columnPinningData: ColumnPinningEmployee[] = [66 { 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 },67 { 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 },68 { 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 },69 { 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 },70 { 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 },71 { 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 },72 { 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 },73 { 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 },74 { 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 },75 { 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 },76 { 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 },77 { 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 },78];7980export const columnPinningConfig = {81 headers: columnPinningHeaders,82 rows: columnPinningData,83 tableProps: { columnResizing: true },84};85
Vue SFC
Copy
1<template>2 <SimpleTable3 :columns="columnPinningConfig.headers"4 :rows="columnPinningConfig.rows"5 :get-row-id="getRowId"6 :height="height"7 :theme="theme"8 :column-resizing="columnPinningConfig.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 { columnPinningConfig } from "./column-pinning.demo-data";16import type { ColumnPinningEmployee } from "./column-pinning.demo-data";17import "@simple-table/vue/styles.css";1819withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {20 height: "400px",21});2223const getRowId = ({ row }: GetRowIdParams<ColumnPinningEmployee>) => 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 { columnPinningConfig } from "./column-pinning.demo-data";5 import type { ColumnPinningEmployee } from "./column-pinning.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<ColumnPinningEmployee>) => row.id;11</script>1213<SimpleTable14 columns={columnPinningConfig.headers}15 rows={columnPinningConfig.rows}16 getRowId={getRowId}17 {height}18 {theme}19 columnResizing={columnPinningConfig.tableProps.columnResizing}20/>
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 columns={columnPinningConfig.headers}9 getRowId={({ row }) => row.id}10 rows={columnPinningConfig.rows}11 height={props.height ?? "400px"}12 theme={props.theme}13 columnResizing={columnPinningConfig.tableProps.columnResizing}14 />15 );16}
TypeScriptColumnPinningDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { ColumnPinningEmployee } from "./column-pinning.demo-data";3import type { Theme, GetRowIdParams } from "simple-table-core";4import { columnPinningConfig } from "./column-pinning.demo-data";5import "simple-table-core/styles.css";678const getRowId = ({ row }: GetRowIdParams<ColumnPinningEmployee>) => row.id;9export function renderColumnPinningDemo(10 container: HTMLElement,11 options?: { height?: string | number; theme?: Theme },12): SimpleTableVanilla<ColumnPinningEmployee> {13 const table = new SimpleTableVanilla(container, {14 getRowId,15 columns: columnPinningConfig.headers,16 rows: columnPinningConfig.rows,17 height: options?.height ?? "400px",18 theme: options?.theme,19 columnResizing: columnPinningConfig.tableProps.columnResizing,20 });21 return table;22}232425// column-pinning.demo-data.ts26// Self-contained demo table setup for this example.27import type { ColumnDef } from "simple-table-core";2829export interface ColumnPinningEmployee {30 id: number;31 name: string;32 email: string;33 role: string;34 department: string;35 location: string;36 joinDate: string;37 salary: number;38 manager: string;39 status: string;40 projects: number;41}4243export const columnPinningHeaders: ColumnDef<ColumnPinningEmployee>[] = [44 { accessor: "name", label: "Name", width: 132, pinned: "left", type: "string" },45 { accessor: "email", label: "Email", width: 220, type: "string" },46 { accessor: "role", label: "Role", width: 150, type: "string" },47 { accessor: "department", label: "Department", width: 150, type: "string" },48 { accessor: "location", label: "Location", width: 150, type: "string" },49 { accessor: "joinDate", label: "Join Date", width: 120, type: "date" },50 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },51 { accessor: "manager", label: "Manager", width: 180, type: "string" },52 { accessor: "status", label: "Status", width: 120, type: "string" },53 { accessor: "projects", label: "Projects", width: 100, align: "right", pinned: "right", type: "number" },54];5556export const columnPinningData: ColumnPinningEmployee[] = [57 { 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 },58 { 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 },59 { 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 },60 { 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 },61 { 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 },62 { 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 },63 { 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 },64 { 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 },65 { 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 },66 { 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 },67 { 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 },68 { 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 },69];7071export const columnPinningConfig = {72 headers: columnPinningHeaders,73 rows: columnPinningData,74 tableProps: { columnResizing: true },75};76
Props
Column Pinning Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
ColumnDef.pinned | Optional | Pins the column to the left or right edge so it stays visible during horizontal scroll. Options: left right | |
ColumnDef.essential | Optional | Locks the column against hide/unpin and keeps it in a fixed leading group within its pin section. |