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 = tableRef.value?.getPinnedState();// Restoreawait tableRef.value?.applyPinnedState(pinned);
TypeScript
Copy
// Saveconst pinned = this.tableRef.getAPI()?.getPinnedState();// Restoreawait this.tableRef.getAPI()?.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";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 columns={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 :columns="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 { AngularColumnDef, 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 [columns]="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: AngularColumnDef[] = 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 { AngularColumnDef } from "@simple-table/angular";333435export const columnPinningHeaders: AngularColumnDef[] = [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 columns={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 columns={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 columns: 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 { ColumnDef } from "simple-table-core";242526export const columnPinningHeaders: ColumnDef[] = [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
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. |