FreeGridv1.6.0한국어

Pinning and column groups

Pinned columns stay visible while the middle section scrolls horizontally. Users can pin and unpin from the column menu. Columns with children become…

Live demoPinned columns

Pin columns left or right; they stay put while you scroll.

Code for this demo
import { createGrid } from '@freegridjs/core';
import { demoColumns, makeRows } from '../data';
import { button, tr, type DemoContext } from '../ui';

export default function mount(ctx: DemoContext) {
  const { lang } = ctx;
  // demoColumns pins ID and Name to the left and Total to the right.
  const grid = createGrid(ctx.host, { columns: demoColumns(lang, 12), data: makeRows(3000, 12), locale: lang });

  const pin = (colId: string, pinned: 'left' | 'right' | null) => {
    const state = grid.getColumnState().map(s => (s.colId === colId ? { ...s, pinned } : s));
    grid.applyColumnState(state);
    ctx.log(`${colId} → ${pinned ?? 'unpinned'}`);
  };
  button(ctx, tr(lang, { en: 'Pin Email left', ko: '이메일 왼쪽 고정' }), () => pin('email', 'left'));
  button(ctx, tr(lang, { en: 'Pin Status right', ko: '상태 오른쪽 고정' }), () => pin('status', 'right'));
  button(ctx, tr(lang, { en: 'Unpin Name', ko: '이름 고정 해제' }), () => pin('name', null));
  button(ctx, tr(lang, { en: 'Reset', ko: '초기화' }), () => grid.resetColumnState());
  return grid;
}

Live demoColumn groups

Nest headers to any depth with column groups.

Code for this demo
import { createGrid, type ColumnDef } from '@freegridjs/core';
import { makeRows } from '../data';
import { tr, type DemoContext } from '../ui';

export default function mount(ctx: DemoContext) {
  const { lang } = ctx;
  const h = (en: string, ko: string) => tr(lang, { en, ko });
  const money = { type: 'number', format: '#,##0', width: 100 } as const;
  // Three header levels: Year → Half → Quarter.
  const columns: ColumnDef[] = [
    { field: 'id', header: 'ID', width: 70, type: 'number', format: '0', pinned: 'left' },
    { header: h('Customer', '고객'), children: [
      { field: 'name', header: h('Name', '이름'), width: 160 },
      { field: 'company', header: h('Company', '회사'), width: 130 },
      { field: 'country', header: h('Country', '국가'), width: 140 },
    ] },
    { header: h('Revenue 2026', '2026년 매출'), children: [
      { header: h('First half', '상반기'), children: [
        { field: 'q1', header: 'Q1', ...money },
        { field: 'q2', header: 'Q2', ...money },
      ] },
      { header: h('Second half', '하반기'), children: [
        { field: 'q3', header: 'Q3', ...money },
        { field: 'q4', header: 'Q4', ...money },
      ] },
    ] },
    { field: 'total', header: h('Total', '합계'), ...money, width: 120, pinned: 'right' },
  ];
  return createGrid(ctx.host, { columns, data: makeRows(2000), locale: lang });
}

Pinned columns stay visible while the middle section scrolls horizontally. Users can pin and unpin from the column menu. Columns with children become group headers, nested as deep as you like; a group split across pinned sections shows its header in each.

const columns = [
  { field: 'name', header: 'Name', pinned: 'left' },
  { header: 'Revenue 2026', children: [
    { header: 'First half', children: [{ field: 'q1' }, { field: 'q2' }] },
    { header: 'Second half', children: [{ field: 'q3' }, { field: 'q4' }] },
  ] },
  { field: 'total', header: 'Total', pinned: 'right' },
];